Skip to content

Commit b831a7d

Browse files
hpoettkerfmbenhassine
authored andcommitted
Add integration tests for PagingQueryProvider
Adds testcontainers based tests for DB2, MySQL, MariaDB, Postgres, Sql Server and Oracle Database, as well as standard tests for HSQL and SQLite.
1 parent 8f1b24a commit b831a7d

11 files changed

+690
-66
lines changed

spring-batch-infrastructure/pom.xml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,84 @@
347347
<version>${derby.version}</version>
348348
<scope>test</scope>
349349
</dependency>
350+
<dependency>
351+
<groupId>org.testcontainers</groupId>
352+
<artifactId>junit-jupiter</artifactId>
353+
<version>${testcontainers.version}</version>
354+
<scope>test</scope>
355+
</dependency>
356+
<dependency>
357+
<groupId>com.mysql</groupId>
358+
<artifactId>mysql-connector-j</artifactId>
359+
<version>${mysql-connector-j.version}</version>
360+
<scope>test</scope>
361+
</dependency>
362+
<dependency>
363+
<groupId>org.testcontainers</groupId>
364+
<artifactId>mysql</artifactId>
365+
<version>${testcontainers.version}</version>
366+
<scope>test</scope>
367+
</dependency>
368+
<dependency>
369+
<groupId>org.testcontainers</groupId>
370+
<artifactId>oracle-xe</artifactId>
371+
<version>${testcontainers.version}</version>
372+
<scope>test</scope>
373+
</dependency>
374+
<dependency>
375+
<groupId>com.oracle.database.jdbc</groupId>
376+
<artifactId>ojdbc10</artifactId>
377+
<version>${oracle.version}</version>
378+
<scope>test</scope>
379+
</dependency>
380+
<dependency>
381+
<groupId>org.mariadb.jdbc</groupId>
382+
<artifactId>mariadb-java-client</artifactId>
383+
<version>${mariadb-java-client.version}</version>
384+
<scope>test</scope>
385+
</dependency>
386+
<dependency>
387+
<groupId>org.testcontainers</groupId>
388+
<artifactId>mariadb</artifactId>
389+
<version>${testcontainers.version}</version>
390+
<scope>test</scope>
391+
</dependency>
392+
<dependency>
393+
<groupId>org.postgresql</groupId>
394+
<artifactId>postgresql</artifactId>
395+
<version>${postgresql.version}</version>
396+
<scope>test</scope>
397+
</dependency>
398+
<dependency>
399+
<groupId>org.testcontainers</groupId>
400+
<artifactId>postgresql</artifactId>
401+
<version>${testcontainers.version}</version>
402+
<scope>test</scope>
403+
</dependency>
404+
<dependency>
405+
<groupId>com.ibm.db2</groupId>
406+
<artifactId>jcc</artifactId>
407+
<version>${db2.version}</version>
408+
<scope>test</scope>
409+
</dependency>
410+
<dependency>
411+
<groupId>org.testcontainers</groupId>
412+
<artifactId>db2</artifactId>
413+
<version>${testcontainers.version}</version>
414+
<scope>test</scope>
415+
</dependency>
416+
<dependency>
417+
<groupId>org.testcontainers</groupId>
418+
<artifactId>mssqlserver</artifactId>
419+
<version>${testcontainers.version}</version>
420+
<scope>test</scope>
421+
</dependency>
422+
<dependency>
423+
<groupId>com.microsoft.sqlserver</groupId>
424+
<artifactId>mssql-jdbc</artifactId>
425+
<version>${sqlserver.version}</version>
426+
<scope>test</scope>
427+
</dependency>
350428
<dependency>
351429
<groupId>com.thoughtworks.xstream</groupId>
352430
<artifactId>xstream</artifactId>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.batch.item.database.support;
17+
18+
import java.util.HashMap;
19+
import java.util.List;
20+
import java.util.Map;
21+
import javax.sql.DataSource;
22+
23+
import org.junit.jupiter.api.Test;
24+
import org.springframework.batch.item.database.Order;
25+
import org.springframework.jdbc.core.JdbcTemplate;
26+
import org.springframework.jdbc.core.RowMapper;
27+
28+
import static org.junit.jupiter.api.Assertions.assertEquals;
29+
30+
/**
31+
* @author Henning Pöttker
32+
*/
33+
abstract class AbstractPagingQueryProviderIntegrationTests {
34+
35+
private final JdbcTemplate jdbcTemplate;
36+
37+
private final AbstractSqlPagingQueryProvider queryProvider;
38+
39+
AbstractPagingQueryProviderIntegrationTests(DataSource dataSource, AbstractSqlPagingQueryProvider queryProvider) {
40+
this.jdbcTemplate = new JdbcTemplate(dataSource);
41+
this.queryProvider = queryProvider;
42+
}
43+
44+
@Test
45+
void testWithoutGrouping() {
46+
queryProvider.setSelectClause("ID, STRING");
47+
queryProvider.setFromClause("TEST_TABLE");
48+
Map<String, Order> sortKeys = new HashMap<>();
49+
sortKeys.put("ID", Order.ASCENDING);
50+
queryProvider.setSortKeys(sortKeys);
51+
52+
List<Item> firstPage = jdbcTemplate.query(queryProvider.generateFirstPageQuery(2), MAPPER);
53+
assertEquals(List.of(new Item(1, "Spring"), new Item(2, "Batch")), firstPage);
54+
55+
List<Item> secondPage = jdbcTemplate.query(queryProvider.generateRemainingPagesQuery(2), MAPPER, 2);
56+
assertEquals(List.of(new Item(3, "Infrastructure")), secondPage);
57+
}
58+
59+
@Test
60+
void testWithGrouping() {
61+
queryProvider.setSelectClause("STRING");
62+
queryProvider.setFromClause("GROUPING_TEST_TABLE");
63+
queryProvider.setGroupClause("STRING");
64+
Map<String, Order> sortKeys = new HashMap<>();
65+
sortKeys.put("STRING", Order.ASCENDING);
66+
queryProvider.setSortKeys(sortKeys);
67+
68+
List<String> firstPage = jdbcTemplate.queryForList(queryProvider.generateFirstPageQuery(2), String.class);
69+
assertEquals(List.of("Batch", "Infrastructure"), firstPage);
70+
71+
List<String> secondPage = jdbcTemplate.queryForList(queryProvider.generateRemainingPagesQuery(2), String.class,
72+
"Infrastructure");
73+
assertEquals(List.of("Spring"), secondPage);
74+
}
75+
76+
private record Item(Integer id, String string) {
77+
}
78+
79+
private static final RowMapper<Item> MAPPER = (rs, rowNum) -> new Item(rs.getInt("id"), rs.getString("string"));
80+
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.batch.item.database.support;
17+
18+
import javax.sql.DataSource;
19+
20+
import com.ibm.db2.jcc.DB2SimpleDataSource;
21+
import org.springframework.beans.factory.annotation.Autowired;
22+
import org.springframework.context.annotation.Bean;
23+
import org.springframework.context.annotation.Configuration;
24+
import org.springframework.test.context.jdbc.Sql;
25+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
26+
import org.testcontainers.containers.Db2Container;
27+
import org.testcontainers.junit.jupiter.Container;
28+
import org.testcontainers.junit.jupiter.Testcontainers;
29+
import org.testcontainers.utility.DockerImageName;
30+
31+
import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.BEFORE_TEST_CLASS;
32+
33+
/**
34+
* @author Henning Pöttker
35+
*/
36+
@Testcontainers(disabledWithoutDocker = true)
37+
@SpringJUnitConfig
38+
@Sql(scripts = "query-provider-fixture.sql", executionPhase = BEFORE_TEST_CLASS)
39+
class Db2PagingQueryProviderIntegrationTests extends AbstractPagingQueryProviderIntegrationTests {
40+
41+
// TODO find the best way to externalize and manage image versions
42+
private static final DockerImageName DB2_IMAGE = DockerImageName.parse("ibmcom/db2:11.5.5.1");
43+
44+
@Container
45+
public static Db2Container db2 = new Db2Container(DB2_IMAGE).acceptLicense();
46+
47+
Db2PagingQueryProviderIntegrationTests(@Autowired DataSource dataSource) {
48+
super(dataSource, new Db2PagingQueryProvider());
49+
}
50+
51+
@Configuration
52+
static class TestConfiguration {
53+
54+
@Bean
55+
public DataSource dataSource() throws Exception {
56+
DB2SimpleDataSource dataSource = new DB2SimpleDataSource();
57+
dataSource.setDatabaseName(db2.getDatabaseName());
58+
dataSource.setUser(db2.getUsername());
59+
dataSource.setPassword(db2.getPassword());
60+
dataSource.setDriverType(4);
61+
dataSource.setServerName(db2.getHost());
62+
dataSource.setPortNumber(db2.getMappedPort(Db2Container.DB2_PORT));
63+
dataSource.setSslConnection(false);
64+
return dataSource;
65+
}
66+
67+
}
68+
69+
}

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/support/DerbyPagingQueryProviderIntegrationTests.java

Lines changed: 18 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -15,84 +15,36 @@
1515
*/
1616
package org.springframework.batch.item.database.support;
1717

18-
import java.util.HashMap;
19-
import java.util.List;
20-
import java.util.Map;
18+
import javax.sql.DataSource;
2119

22-
import org.junit.jupiter.api.AfterAll;
23-
import org.junit.jupiter.api.BeforeAll;
24-
import org.junit.jupiter.api.Test;
25-
import org.springframework.batch.item.database.Order;
26-
import org.springframework.jdbc.core.JdbcTemplate;
27-
import org.springframework.jdbc.core.RowMapper;
28-
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
20+
import org.springframework.beans.factory.annotation.Autowired;
21+
import org.springframework.context.annotation.Bean;
22+
import org.springframework.context.annotation.Configuration;
2923
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
3024
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
31-
32-
import static org.junit.jupiter.api.Assertions.assertEquals;
25+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
3326

3427
/**
3528
* @author Henning Pöttker
3629
*/
37-
class DerbyPagingQueryProviderIntegrationTests {
38-
39-
private static EmbeddedDatabase embeddedDatabase;
40-
41-
private static JdbcTemplate jdbcTemplate;
42-
43-
@BeforeAll
44-
static void setUp() {
45-
embeddedDatabase = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.DERBY)
46-
.addScript("/org/springframework/batch/item/database/support/query-provider-fixture.sql")
47-
.generateUniqueName(true)
48-
.build();
49-
jdbcTemplate = new JdbcTemplate(embeddedDatabase);
50-
}
51-
52-
@AfterAll
53-
static void tearDown() {
54-
if (embeddedDatabase != null) {
55-
embeddedDatabase.shutdown();
56-
}
57-
}
58-
59-
@Test
60-
void testWithoutGrouping() {
61-
var queryProvider = new DerbyPagingQueryProvider();
62-
queryProvider.setSelectClause("ID, STRING");
63-
queryProvider.setFromClause("TEST_TABLE");
64-
Map<String, Order> sortKeys = new HashMap<>();
65-
sortKeys.put("ID", Order.ASCENDING);
66-
queryProvider.setSortKeys(sortKeys);
30+
@SpringJUnitConfig
31+
class DerbyPagingQueryProviderIntegrationTests extends AbstractPagingQueryProviderIntegrationTests {
6732

68-
List<Item> firstPage = jdbcTemplate.query(queryProvider.generateFirstPageQuery(2), MAPPER);
69-
assertEquals(List.of(new Item(1, "Spring"), new Item(2, "Batch")), firstPage);
70-
71-
List<Item> secondPage = jdbcTemplate.query(queryProvider.generateRemainingPagesQuery(2), MAPPER, 2);
72-
assertEquals(List.of(new Item(3, "Infrastructure")), secondPage);
33+
DerbyPagingQueryProviderIntegrationTests(@Autowired DataSource dataSource) {
34+
super(dataSource, new DerbyPagingQueryProvider());
7335
}
7436

75-
@Test
76-
void testWithGrouping() {
77-
var queryProvider = new DerbyPagingQueryProvider();
78-
queryProvider.setSelectClause("STRING");
79-
queryProvider.setFromClause("GROUPING_TEST_TABLE");
80-
queryProvider.setGroupClause("STRING");
81-
Map<String, Order> sortKeys = new HashMap<>();
82-
sortKeys.put("STRING", Order.ASCENDING);
83-
queryProvider.setSortKeys(sortKeys);
84-
85-
List<String> firstPage = jdbcTemplate.queryForList(queryProvider.generateFirstPageQuery(2), String.class);
86-
assertEquals(List.of("Batch", "Infrastructure"), firstPage);
37+
@Configuration
38+
static class TestConfiguration {
8739

88-
List<String> secondPage = jdbcTemplate.queryForList(queryProvider.generateRemainingPagesQuery(2), String.class,
89-
"Infrastructure");
90-
assertEquals(List.of("Spring"), secondPage);
91-
}
40+
@Bean
41+
public DataSource dataSource() throws Exception {
42+
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.DERBY)
43+
.addScript("/org/springframework/batch/item/database/support/query-provider-fixture.sql")
44+
.generateUniqueName(true)
45+
.build();
46+
}
9247

93-
private record Item(Integer id, String string) {
9448
}
9549

96-
private static final RowMapper<Item> MAPPER = (rs, rowNum) -> new Item(rs.getInt("id"), rs.getString("string"));
97-
9850
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.batch.item.database.support;
17+
18+
import javax.sql.DataSource;
19+
20+
import org.springframework.beans.factory.annotation.Autowired;
21+
import org.springframework.context.annotation.Bean;
22+
import org.springframework.context.annotation.Configuration;
23+
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
24+
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
25+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
26+
27+
/**
28+
* @author Henning Pöttker
29+
*/
30+
@SpringJUnitConfig
31+
class HsqlPagingQueryProviderIntegrationTests extends AbstractPagingQueryProviderIntegrationTests {
32+
33+
HsqlPagingQueryProviderIntegrationTests(@Autowired DataSource dataSource) {
34+
super(dataSource, new HsqlPagingQueryProvider());
35+
}
36+
37+
@Configuration
38+
static class TestConfiguration {
39+
40+
@Bean
41+
public DataSource dataSource() throws Exception {
42+
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL)
43+
.addScript("/org/springframework/batch/item/database/support/query-provider-fixture.sql")
44+
.generateUniqueName(true)
45+
.build();
46+
}
47+
48+
}
49+
50+
}

0 commit comments

Comments
 (0)