Skip to content

Commit af4e63d

Browse files
authored
Migrate query JDBC, cancel and system tables ITs, cleanup and refactor helper classes (#18805)
* Stage 1: move QueryErrorTest, create a base class for the convenience * Migrate query retry on missing segments test * Don't use parametrize test, duplicate usage instead * Fix checkstyle issue * Migreate system table query test * Migrate JDBC test
1 parent fa9914b commit af4e63d

24 files changed

+329
-1572
lines changed

.github/workflows/cron-job-its.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ jobs:
8888
strategy:
8989
fail-fast: false
9090
matrix:
91-
testing_group: [ query, query-retry, query-error, security ]
91+
testing_group: [ query, security ]
9292
uses: ./.github/workflows/reusable-standard-its.yml
9393
needs: build
9494
with:

.github/workflows/standard-its.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
strategy:
7979
fail-fast: false
8080
matrix:
81-
testing_group: [query, query-retry, query-error, security, centralized-datasource-schema]
81+
testing_group: [query, security, centralized-datasource-schema]
8282
uses: ./.github/workflows/reusable-standard-its.yml
8383
if: ${{ needs.changes.outputs.core == 'true' || needs.changes.outputs.common-extensions == 'true' }}
8484
with:

integration-tests/src/test/java/org/apache/druid/tests/query/ITJdbcQueryTest.java renamed to embedded-tests/src/test/java/org/apache/druid/testing/embedded/query/JdbcQueryTest.java

Lines changed: 50 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,15 @@
1717
* under the License.
1818
*/
1919

20-
package org.apache.druid.tests.query;
20+
package org.apache.druid.testing.embedded.query;
2121

2222
import com.google.common.collect.ImmutableList;
23-
import com.google.inject.Inject;
2423
import org.apache.calcite.avatica.AvaticaSqlException;
25-
import org.apache.druid.https.SSLClientConfig;
2624
import org.apache.druid.java.util.common.StringUtils;
2725
import org.apache.druid.java.util.common.logger.Logger;
28-
import org.apache.druid.testing.guice.DruidTestModuleFactory;
29-
import org.apache.druid.testing.tools.IntegrationTestingConfig;
30-
import org.apache.druid.testing.utils.DataLoaderHelper;
31-
import org.apache.druid.tests.TestNGGroup;
32-
import org.testng.Assert;
33-
import org.testng.annotations.BeforeMethod;
34-
import org.testng.annotations.Guice;
35-
import org.testng.annotations.Test;
26+
import org.junit.jupiter.api.Assertions;
27+
import org.junit.jupiter.api.Test;
28+
3629

3730
import java.sql.Connection;
3831
import java.sql.DatabaseMetaData;
@@ -47,69 +40,40 @@
4740
import java.util.Properties;
4841
import java.util.Set;
4942

50-
@Test(groups = {TestNGGroup.QUERY, TestNGGroup.CENTRALIZED_DATASOURCE_SCHEMA})
51-
@Guice(moduleFactory = DruidTestModuleFactory.class)
52-
public class ITJdbcQueryTest
43+
/**
44+
* JDBC query integration tests.
45+
* Note: we need to correspond queries with TLS support to fullfill the conversion
46+
*/
47+
public class JdbcQueryTest extends QueryTestBase
5348
{
54-
private static final Logger LOG = new Logger(ITJdbcQueryTest.class);
55-
private static final String WIKIPEDIA_DATA_SOURCE = "wikipedia_editstream";
49+
private static final Logger LOG = new Logger(JdbcQueryTest.class);
5650
private static final String CONNECTION_TEMPLATE = "jdbc:avatica:remote:url=%s/druid/v2/sql/avatica/";
5751
private static final String TLS_CONNECTION_TEMPLATE =
5852
"jdbc:avatica:remote:url=%s/druid/v2/sql/avatica/;truststore=%s;truststore_password=%s;keystore=%s;keystore_password=%s;key_password=%s";
5953

6054
private static final String QUERY_TEMPLATE =
61-
"SELECT \"user\", SUM(\"added\"), COUNT(*)" +
62-
"FROM \"wikipedia\" " +
63-
"WHERE \"__time\" >= CURRENT_TIMESTAMP - INTERVAL '99' YEAR AND \"language\" = %s" +
64-
"GROUP BY 1 ORDER BY 3 DESC LIMIT 10";
65-
private static final String QUERY = StringUtils.format(QUERY_TEMPLATE, "'en'");
66-
67-
private static final String QUERY_PARAMETERIZED = StringUtils.format(QUERY_TEMPLATE, "?");
55+
"SELECT \"item\", SUM(\"value\"), COUNT(*) "
56+
+ "FROM \"%s\" "
57+
+ "WHERE \"__time\" >= CURRENT_TIMESTAMP - INTERVAL '99' YEAR AND \"value\" < %s \n"
58+
+ "GROUP BY 1 ORDER BY 3 DESC LIMIT 10";
6859

6960
private String[] connections;
7061
private Properties connectionProperties;
7162

72-
@Inject
73-
private IntegrationTestingConfig config;
74-
75-
@Inject
76-
SSLClientConfig sslConfig;
63+
private String dataSourceName;
7764

78-
@Inject
79-
private DataLoaderHelper dataLoaderHelper;
80-
81-
@BeforeMethod
82-
public void before()
65+
@Override
66+
protected void beforeAll()
8367
{
8468
connectionProperties = new Properties();
8569
connectionProperties.setProperty("user", "admin");
8670
connectionProperties.setProperty("password", "priest");
8771
connections = new String[]{
88-
StringUtils.format(CONNECTION_TEMPLATE, config.getRouterUrl()),
89-
StringUtils.format(CONNECTION_TEMPLATE, config.getBrokerUrl()),
90-
StringUtils.format(
91-
TLS_CONNECTION_TEMPLATE,
92-
config.getRouterTLSUrl(),
93-
sslConfig.getTrustStorePath(),
94-
sslConfig.getTrustStorePasswordProvider().getPassword(),
95-
sslConfig.getKeyStorePath(),
96-
sslConfig.getKeyStorePasswordProvider().getPassword(),
97-
sslConfig.getKeyManagerPasswordProvider().getPassword()
98-
),
99-
StringUtils.format(
100-
TLS_CONNECTION_TEMPLATE,
101-
config.getBrokerTLSUrl(),
102-
sslConfig.getTrustStorePath(),
103-
sslConfig.getTrustStorePasswordProvider().getPassword(),
104-
sslConfig.getKeyStorePath(),
105-
sslConfig.getKeyStorePasswordProvider().getPassword(),
106-
sslConfig.getKeyManagerPasswordProvider().getPassword()
107-
)
108-
};
109-
// ensure that wikipedia segments are loaded completely
110-
dataLoaderHelper.waitUntilDatasourceIsReady(WIKIPEDIA_DATA_SOURCE);
111-
dataLoaderHelper.waitUntilDatasourceIsReady("wikipedia");
112-
dataLoaderHelper.waitUntilDatasourceIsReady("twitterstream");
72+
StringUtils.format(CONNECTION_TEMPLATE, getServerUrl(router)),
73+
StringUtils.format(CONNECTION_TEMPLATE, getServerUrl(broker)),
74+
};
75+
76+
dataSourceName = ingestBasicData();
11377
}
11478

11579
@Test
@@ -126,7 +90,7 @@ public void testJdbcMetadata()
12690
catalogs.add(catalog);
12791
}
12892
LOG.info("catalogs %s", catalogs);
129-
Assert.assertEquals(catalogs, ImmutableList.of("druid"));
93+
Assertions.assertEquals(catalogs, ImmutableList.of("druid"));
13094

13195
Set<String> schemas = new HashSet<>();
13296
ResultSet schemasMetadata = metadata.getSchemas("druid", null);
@@ -136,7 +100,7 @@ public void testJdbcMetadata()
136100
}
137101
LOG.info("'druid' catalog schemas %s", schemas);
138102
// maybe more schemas than this, but at least should have these
139-
Assert.assertTrue(schemas.containsAll(ImmutableList.of("INFORMATION_SCHEMA", "druid", "lookup", "sys")));
103+
Assertions.assertTrue(schemas.containsAll(ImmutableList.of("INFORMATION_SCHEMA", "druid", "lookup", "sys")));
140104

141105
Set<String> druidTables = new HashSet<>();
142106
ResultSet tablesMetadata = metadata.getTables("druid", "druid", null, null);
@@ -145,83 +109,90 @@ public void testJdbcMetadata()
145109
druidTables.add(table);
146110
}
147111
LOG.info("'druid' schema tables %s", druidTables);
148-
// maybe more tables than this, but at least should have these
149-
Assert.assertTrue(
150-
druidTables.containsAll(ImmutableList.of("twitterstream", "wikipedia", WIKIPEDIA_DATA_SOURCE))
112+
// There may be more tables than this, but at least should have @tableName
113+
Assertions.assertTrue(
114+
druidTables.containsAll(ImmutableList.of(dataSourceName))
151115
);
152116

153117
Set<String> wikiColumns = new HashSet<>();
154-
ResultSet columnsMetadata = metadata.getColumns("druid", "druid", WIKIPEDIA_DATA_SOURCE, null);
118+
ResultSet columnsMetadata = metadata.getColumns("druid", "druid", dataSourceName, null);
155119
while (columnsMetadata.next()) {
156120
final String column = columnsMetadata.getString(4);
157121
wikiColumns.add(column);
158122
}
159-
LOG.info("'%s' columns %s", WIKIPEDIA_DATA_SOURCE, wikiColumns);
123+
LOG.info("'%s' columns %s", dataSourceName, wikiColumns);
160124
// a lot more columns than this, but at least should have these
161-
Assert.assertTrue(
162-
wikiColumns.containsAll(ImmutableList.of("added", "city", "delta", "language"))
125+
Assertions.assertTrue(
126+
wikiColumns.containsAll(ImmutableList.of("__time", "item", "value"))
163127
);
164128
}
165129
catch (SQLException throwables) {
166-
Assert.fail(throwables.getMessage());
130+
Assertions.fail(throwables.getMessage());
167131
}
168132
}
169133
}
170134

171135
@Test
172136
public void testJdbcStatementQuery()
173137
{
138+
String query = StringUtils.format(QUERY_TEMPLATE, dataSourceName, "1000");
174139
for (String url : connections) {
175140
try (Connection connection = DriverManager.getConnection(url, connectionProperties)) {
176141
try (Statement statement = connection.createStatement()) {
177-
final ResultSet resultSet = statement.executeQuery(QUERY);
142+
final ResultSet resultSet = statement.executeQuery(query);
178143
int resultRowCount = 0;
179144
while (resultSet.next()) {
180145
resultRowCount++;
181146
LOG.info("%s,%s,%s", resultSet.getString(1), resultSet.getLong(2), resultSet.getLong(3));
182147
}
183-
Assert.assertEquals(resultRowCount, 10);
148+
Assertions.assertEquals(7, resultRowCount);
184149
resultSet.close();
185150
}
186151
}
187152
catch (SQLException throwables) {
188-
Assert.fail(throwables.getMessage());
153+
Assertions.fail(throwables.getMessage());
189154
}
190155
}
191156
}
192157

193158
@Test
194159
public void testJdbcPrepareStatementQuery()
195160
{
161+
String query = StringUtils.format(QUERY_TEMPLATE, dataSourceName, "?");
196162
for (String url : connections) {
197163
try (Connection connection = DriverManager.getConnection(url, connectionProperties)) {
198-
try (PreparedStatement statement = connection.prepareStatement(QUERY_PARAMETERIZED)) {
199-
statement.setString(1, "en");
164+
try (PreparedStatement statement = connection.prepareStatement(query)) {
165+
statement.setLong(1, 1000);
200166
final ResultSet resultSet = statement.executeQuery();
201167
int resultRowCount = 0;
202168
while (resultSet.next()) {
203169
resultRowCount++;
204170
LOG.info("%s,%s,%s", resultSet.getString(1), resultSet.getLong(2), resultSet.getLong(3));
205171
}
206-
Assert.assertEquals(resultRowCount, 10);
172+
Assertions.assertEquals(7, resultRowCount);
207173
resultSet.close();
208174
}
209175
}
210176
catch (SQLException throwables) {
211-
Assert.fail(throwables.getMessage());
177+
Assertions.fail(throwables.getMessage());
212178
}
213179
}
214180
}
215181

216-
@Test(expectedExceptions = AvaticaSqlException.class, expectedExceptionsMessageRegExp = ".* No value bound for parameter \\(position \\[1]\\)")
217-
public void testJdbcPrepareStatementQueryMissingParameters() throws SQLException
182+
@Test
183+
public void testJdbcPrepareStatementQueryMissingParameters()
218184
{
185+
String query = StringUtils.format(QUERY_TEMPLATE, dataSourceName, "?");
219186
for (String url : connections) {
220187
try (Connection connection = DriverManager.getConnection(url, connectionProperties);
221-
PreparedStatement statement = connection.prepareStatement(QUERY_PARAMETERIZED);
188+
PreparedStatement statement = connection.prepareStatement(query);
222189
ResultSet resultSet = statement.executeQuery()) {
223190
// This won't actually run as we expect the exception to be thrown before it gets here
224-
throw new IllegalStateException(resultSet.toString());
191+
Assertions.fail(resultSet.toString());
192+
}
193+
catch (SQLException e) {
194+
Assertions.assertInstanceOf(AvaticaSqlException.class, e);
195+
Assertions.assertTrue(e.getMessage().contains("No value bound for parameter (position [1])"));
225196
}
226197
}
227198
}

embedded-tests/src/test/java/org/apache/druid/testing/embedded/query/QueryErrorTest.java

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import org.apache.druid.query.http.SqlTaskStatus;
3030
import org.apache.druid.rpc.HttpResponseException;
3131
import org.apache.druid.testing.embedded.EmbeddedClusterApis;
32-
import org.apache.druid.testing.embedded.EmbeddedDruidCluster;
3332
import org.apache.druid.testing.embedded.msq.EmbeddedMSQApis;
3433
import org.hamcrest.MatcherAssert;
3534
import org.junit.jupiter.api.Assertions;
@@ -56,42 +55,22 @@
5655
public class QueryErrorTest extends QueryTestBase
5756
{
5857
// Introduce onAnyRouter(...) and use it; add TLS tests in the follow-up patches
59-
protected String tableName;
60-
61-
@Override
62-
protected EmbeddedDruidCluster createCluster()
63-
{
64-
overlord.addProperty("druid.manager.segments.pollDuration", "PT0.1s");
65-
indexer.setServerMemory(600_000_000)
66-
.addProperty("druid.worker.capacity", "4")
67-
.addProperty("druid.processing.numThreads", "2")
68-
.addProperty("druid.segment.handoff.pollDuration", "PT0.1s");
69-
70-
return EmbeddedDruidCluster.withEmbeddedDerbyAndZookeeper()
71-
.useLatchableEmitter()
72-
.addServer(overlord)
73-
.addServer(coordinator)
74-
.addServer(broker)
75-
.addServer(router)
76-
.addServer(indexer)
77-
.addServer(historical)
78-
.addExtension(ServerManagerForQueryErrorTestModule.class);
79-
}
58+
protected String testDataSourceName;
8059

8160
@Override
8261
protected void beforeAll()
8362
{
84-
tableName = EmbeddedClusterApis.createTestDatasourceName();
63+
testDataSourceName = EmbeddedClusterApis.createTestDatasourceName();
8564
EmbeddedMSQApis msqApi = new EmbeddedMSQApis(cluster, overlord);
8665
SqlTaskStatus ingestionStatus = msqApi.submitTaskSql(StringUtils.format(
8766
"REPLACE INTO %s\n"
8867
+ "OVERWRITE ALL\n"
8968
+ "SELECT CURRENT_TIMESTAMP AS __time, 1 AS d PARTITIONED BY ALL",
90-
tableName
69+
testDataSourceName
9170
));
9271

9372
cluster.callApi().waitForTaskToSucceed(ingestionStatus.getTaskId(), overlord);
94-
cluster.callApi().waitForAllSegmentsToBeAvailable(tableName, coordinator, broker);
73+
cluster.callApi().waitForAllSegmentsToBeAvailable(testDataSourceName, coordinator, broker);
9574
}
9675

9776
@Test
@@ -267,7 +246,7 @@ private static Map<String, Object> buildTestContext(String key)
267246
private ListenableFuture<String> sqlQueryFuture(BrokerClient b, String contextKey)
268247
{
269248
return b.submitSqlQuery(new ClientSqlQuery(
270-
StringUtils.format("SELECT * FROM %s LIMIT 1", tableName),
249+
StringUtils.format("SELECT * FROM %s LIMIT 1", testDataSourceName),
271250
null,
272251
false,
273252
false,
@@ -283,7 +262,7 @@ private ListenableFuture<String> sqlQueryFuture(BrokerClient b, String contextKe
283262
private ListenableFuture<String> nativeQueryFuture(BrokerClient b, String contextKey)
284263
{
285264
return b.submitNativeQuery(new Druids.ScanQueryBuilder()
286-
.dataSource(tableName)
265+
.dataSource(testDataSourceName)
287266
.eternityInterval()
288267
.limit(1)
289268
.context(buildTestContext(contextKey))

embedded-tests/src/test/java/org/apache/druid/testing/embedded/query/QueryRetryOnMissingSegmentsTest.java

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,11 @@
2020
package org.apache.druid.testing.embedded.query;
2121

2222
import com.fasterxml.jackson.core.type.TypeReference;
23-
import com.fasterxml.jackson.databind.ObjectMapper;
24-
import org.apache.druid.common.utils.IdUtils;
25-
import org.apache.druid.indexing.common.task.IndexTask;
2623
import org.apache.druid.java.util.common.ISE;
2724
import org.apache.druid.java.util.common.StringUtils;
2825
import org.apache.druid.java.util.common.jackson.JacksonUtils;
2926
import org.apache.druid.query.QueryContexts;
3027
import org.apache.druid.query.http.ClientSqlQuery;
31-
import org.apache.druid.testing.embedded.EmbeddedClusterApis;
32-
import org.apache.druid.testing.embedded.EmbeddedDruidCluster;
33-
import org.apache.druid.testing.embedded.indexing.MoreResources;
3428
import org.junit.jupiter.api.Assertions;
3529
import org.junit.jupiter.api.Test;
3630

@@ -69,41 +63,13 @@ private enum Expectation
6963
QUERY_FAILURE
7064
}
7165

72-
private ObjectMapper jsonMapper;
7366
private String tableName;
7467

75-
@Override
76-
protected EmbeddedDruidCluster createCluster()
77-
{
78-
overlord.addProperty("druid.manager.segments.pollDuration", "PT0.1s");
79-
coordinator.addProperty("druid.manager.segments.useIncrementalCache", "always");
80-
indexer.setServerMemory(400_000_000)
81-
.addProperty("druid.worker.capacity", "4")
82-
.addProperty("druid.processing.numThreads", "2")
83-
.addProperty("druid.segment.handoff.pollDuration", "PT0.1s");
84-
85-
return EmbeddedDruidCluster.withEmbeddedDerbyAndZookeeper()
86-
.useLatchableEmitter()
87-
.addServer(overlord)
88-
.addServer(coordinator)
89-
.addServer(broker)
90-
.addServer(router)
91-
.addServer(indexer)
92-
.addServer(historical)
93-
.addExtension(ServerManagerForQueryErrorTestModule.class);
94-
}
95-
9668
@Override
9769
public void beforeAll()
9870
{
9971
jsonMapper = overlord.bindings().jsonMapper();
100-
tableName = EmbeddedClusterApis.createTestDatasourceName();
101-
102-
final String taskId = IdUtils.getRandomId();
103-
final IndexTask task = MoreResources.Task.BASIC_INDEX.get().dataSource(tableName).withId(taskId);
104-
cluster.callApi().onLeaderOverlord(o -> o.runTask(taskId, task));
105-
cluster.callApi().waitForTaskToSucceed(taskId, overlord);
106-
cluster.callApi().waitForAllSegmentsToBeAvailable(tableName, coordinator, broker);
72+
tableName = ingestBasicData();
10773
}
10874

10975
@Test

0 commit comments

Comments
 (0)