Skip to content

Commit d17c8cf

Browse files
authored
Add compatibility testing for JDBC driver (#60430)
This commit adds compatibility testing of our JDBC driver against different Elasticsearch versions. Although we are really testing the forwards compatibility nature of the JDBC driver we model the testing the same as we do existing BWC tests, that is, with the current branch fetching the earlier versions of the artifact that is to be tested. In this case, that's the JDBC driver itself. Because the tests include the JDBC driver jar on it's classpath we had to change the packaging of the driver jar in order to avoid jarhell and other conflicting dependency issues when using an old JDBC driver with later branches. For this we simply relocate all driver dependencies in the shadow jar under a "shadowed" package. This allows the JDBC driver to use the correct version of Elasticsearch libs classes, while the tests themselves use their versions. Since this required a change to the driver jar compatibility testing can only go back as far as that version which at the time of this commit is 7.8.1.
1 parent ee191a6 commit d17c8cf

File tree

11 files changed

+160
-102
lines changed

11 files changed

+160
-102
lines changed

buildSrc/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ dependencies {
9999
api 'com.netflix.nebula:gradle-info-plugin:7.1.3'
100100
api 'org.apache.rat:apache-rat:0.11'
101101
api "org.elasticsearch:jna:5.5.0"
102-
api 'com.github.jengelman.gradle.plugins:shadow:5.1.0'
102+
api 'com.github.jengelman.gradle.plugins:shadow:6.0.0'
103103
api 'de.thetaphi:forbiddenapis:3.0'
104104
api 'com.avast.gradle:gradle-docker-compose-plugin:0.12.1'
105105
api 'org.apache.maven:maven-model:3.6.2'

distribution/bwc/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,11 @@ BuildParams.bwcVersions.forPreviousUnreleased { BwcVersions.UnreleasedVersionInf
293293
createBuildBwcTask(projectName, "${baseDir}/${projectName}", projectArtifact)
294294
}
295295

296+
// Create build tasks for the JDBC driver used for compatibility testing
297+
String jdbcProjectDir = 'x-pack/plugin/sql/jdbc'
298+
File jdbcProjectArtifact = file("${checkoutDir}/${jdbcProjectDir}/build/distributions/x-pack-sql-jdbc-${bwcVersion}-SNAPSHOT.jar")
299+
createBuildBwcTask('jdbc', jdbcProjectDir, jdbcProjectArtifact)
300+
296301
createRunBwcGradleTask("resolveAllBwcDependencies") {
297302
args 'resolveAllDependencies'
298303
}

gradle/bwc-test.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ tasks.named("check").configure {
2828
dependsOn(bwcTestSnapshots)
2929
}
3030

31-
test.enabled = false
31+
tasks.findByName("test")?.enabled = false

x-pack/plugin/sql/jdbc/build.gradle

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,19 @@ tasks.named("dependencyLicenses").configure {
3535
}
3636

3737
shadowJar {
38-
relocate 'com.fasterxml', 'org.elasticsearch.fasterxml'
38+
relocate 'com.fasterxml', 'shadow.fasterxml'
39+
relocate('org.elasticsearch', 'shadow.org.elasticsearch') {
40+
// Don't relocate the JDBC driver classes themselves as that's (mostly) public API
41+
exclude 'org.elasticsearch.xpack.sql.jdbc.*'
42+
}
3943
}
4044

4145
thirdPartyAudit.ignoreMissingClasses(
4246
'com.fasterxml.jackson.databind.ObjectMapper',
4347
'com.fasterxml.jackson.databind.cfg.MapperBuilder'
4448
)
49+
50+
tasks.named("test").configure {
51+
// reset the unit test classpath as using the shadow jar won't work due to relocated packages
52+
classpath = sourceSets.test.runtimeClasspath
53+
}
Lines changed: 82 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,103 @@
1+
import org.elasticsearch.gradle.BwcVersions.UnreleasedVersionInfo
2+
import org.elasticsearch.gradle.Version
3+
import org.elasticsearch.gradle.VersionProperties
4+
import org.elasticsearch.gradle.info.BuildParams
5+
import org.elasticsearch.gradle.test.RestIntegTestTask
6+
17
description = 'Integration tests for SQL JDBC driver'
2-
apply plugin: 'elasticsearch.build'
8+
apply plugin: 'elasticsearch.java'
39

410
// Avoid circular dependency
5-
group = "org.elasticsearch.x-pack.qa.sql.jdbc"
11+
group = 'org.elasticsearch.x-pack.qa.sql.jdbc'
612

713
dependencies {
8-
api project(":test:framework")
14+
api project(':test:framework')
15+
implementation xpackProject('plugin:sql:sql-proto')
916

10-
// JDBC testing dependencies
11-
api project(path: xpackModule('sql:jdbc'))
17+
// Actual tests will use the shadow jar
18+
compileOnly(project(path: xpackModule('sql:jdbc'))) {
19+
// Since dependencies will be relocated in the shadow jar, don't attempt to compile against them
20+
transitive = false
21+
}
1222
}
1323

14-
/* disable unit tests because these are all integration tests used
15-
* other qa projects. */
24+
// disable unit tests because these are all integration tests used other qa projects
1625
test.enabled = false
1726

18-
tasks.named("dependencyLicenses").configure { it.enabled = false }
19-
dependenciesInfo.enabled = false
27+
subprojects {
28+
if (subprojects.isEmpty()) {
29+
// leaf project
30+
apply plugin: 'elasticsearch.standalone-rest-test'
31+
apply from: "$rootDir/gradle/bwc-test.gradle"
32+
} else {
33+
apply plugin: 'elasticsearch.java'
34+
}
2035

21-
// the main files are actually test files, so use the appropriate forbidden api sigs
22-
tasks.named('forbiddenApisMain').configure {
23-
replaceSignatureFiles 'es-all-signatures', 'es-test-signatures'
24-
}
36+
repositories {
37+
maven {
38+
// Repository for downloading BWC compatible JDBC driver releases
39+
url = 'https://artifacts.elastic.co/maven'
40+
}
41+
}
2542

26-
// just a test fixture: we aren't using this jars in releases and H2GIS requires disabling a lot of checks
27-
thirdPartyAudit.enabled = false
43+
configurations {
44+
jdbcDriver
45+
}
2846

29-
subprojects {
30-
if (subprojects.isEmpty()) {
31-
// leaf project
32-
apply plugin: 'elasticsearch.standalone-rest-test'
33-
} else {
34-
apply plugin: 'elasticsearch.build'
35-
}
47+
dependencies {
48+
testImplementation(xpackProject('plugin:sql:qa:jdbc'))
3649

37-
dependencies {
38-
/* Since we're a standalone rest test we actually get transitive
39-
* dependencies but we don't really want them because they cause
40-
* all kinds of trouble with the jar hell checks. So we suppress
41-
* them explicitly for non-es projects. */
42-
testImplementation(xpackProject('plugin:sql:qa:jdbc')) {
43-
transitive = false
44-
}
45-
testImplementation project(":test:framework")
50+
// We use the shadowjar for testing since that's the actual artifact we deliver to users
51+
testCompileOnly project(path: xpackModule('sql:jdbc'), configuration: 'shadow')
52+
jdbcDriver project(path: xpackModule('sql:jdbc'), configuration: 'shadow')
53+
}
4654

47-
testRuntimeOnly project(path: xpackModule('sql:jdbc'))
55+
if (project.name != 'security') {
56+
// The security project just configures its subprojects
57+
apply plugin: 'elasticsearch.testclusters'
58+
apply plugin: 'elasticsearch.rest-test'
59+
60+
testClusters.all {
61+
testDistribution = 'DEFAULT'
62+
setting 'xpack.ml.enabled', 'false'
63+
setting 'xpack.watcher.enabled', 'false'
64+
}
65+
66+
integTest {
67+
runner {
68+
classpath += configurations.jdbcDriver
69+
systemProperty 'jdbc.driver.version', VersionProperties.elasticsearch
70+
}
4871
}
4972

50-
if (project.name != 'security') {
51-
// The security project just configures its subprojects
52-
apply plugin: 'elasticsearch.testclusters'
53-
apply plugin: 'elasticsearch.rest-test'
73+
// Configure compatibility testing tasks
74+
for (Version bwcVersion : BuildParams.bwcVersions.indexCompatible) {
75+
// Compatibility testing for JDBC driver started with version 7.9.0
76+
if (bwcVersion.onOrAfter(Version.fromString("7.9.0")) && (bwcVersion.equals(VersionProperties.elasticsearchVersion) == false)) {
77+
String baseName = "v${bwcVersion}"
78+
UnreleasedVersionInfo unreleasedVersion = BuildParams.bwcVersions.unreleasedInfo(bwcVersion)
79+
Configuration driverConfiguration = configurations.create("jdbcDriver${baseName}")
80+
Object driverDependency = null
81+
82+
if (unreleasedVersion) {
83+
// For unreleased snapshot versions, build them from source
84+
driverDependency = files(project(unreleasedVersion.gradleProjectPath).tasks.named('buildBwcJdbc'))
85+
} else {
86+
// For released versions, download it
87+
driverDependency = "org.elasticsearch.plugin:x-pack-sql-jdbc:${bwcVersion}"
88+
}
89+
90+
dependencies {
91+
"jdbcDriver${baseName}"(driverDependency)
92+
}
5493

55-
testClusters.integTest {
56-
testDistribution = 'DEFAULT'
57-
setting 'xpack.ml.enabled', 'false'
58-
setting 'xpack.watcher.enabled', 'false'
94+
tasks.create(bwcTaskName(bwcVersion), RestIntegTestTask) {
95+
runner {
96+
classpath += driverConfiguration
97+
systemProperty 'jdbc.driver.version', bwcVersion.toString()
98+
}
5999
}
100+
}
60101
}
102+
}
61103
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
description = 'Run SQL JDBC tests against multiple nodes'
22

3-
testClusters.integTest {
4-
numberOfNodes = 2
5-
setting 'xpack.security.enabled', 'false'
6-
setting 'xpack.license.self_generated.type', 'trial'
3+
testClusters.all {
4+
numberOfNodes = 2
5+
setting 'xpack.security.enabled', 'false'
6+
setting 'xpack.license.self_generated.type', 'trial'
77
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
testClusters.integTest {
2-
setting 'xpack.security.enabled', 'false'
3-
setting 'xpack.license.self_generated.type', 'trial'
1+
testClusters.all {
2+
setting 'xpack.security.enabled', 'false'
3+
setting 'xpack.license.self_generated.type', 'trial'
44
}
Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,61 @@
1+
import org.elasticsearch.gradle.testclusters.RestTestRunnerTask
2+
13
dependencies {
2-
testImplementation project(':x-pack:plugin:core')
4+
testImplementation project(':x-pack:plugin:core')
35
}
46

57
Project mainProject = project
68

79
configurations.create('testArtifacts')
810

911
TaskProvider testJar = tasks.register("testJar", Jar) {
10-
appendix 'test'
11-
from sourceSets.test.output
12+
appendix 'test'
13+
from sourceSets.test.output
1214
}
1315

1416
artifacts {
15-
testArtifacts testJar
17+
testArtifacts testJar
1618
}
1719

18-
// Tests are pushed down to subprojects and will be checked there.
19-
testingConventions.enabled = false
20-
2120
subprojects {
22-
// Use tests from the root security qa project in subprojects
23-
configurations.create('testArtifacts')
24-
25-
dependencies {
26-
testImplementation project(":x-pack:plugin:core")
27-
testArtifacts project(path: mainProject.path, configuration: 'testArtifacts')
28-
}
29-
30-
testClusters.integTest {
31-
testDistribution = 'DEFAULT'
32-
// Setup auditing so we can use it in some tests
33-
setting 'xpack.security.audit.enabled', 'true'
34-
setting 'xpack.security.enabled', 'true'
35-
setting 'xpack.license.self_generated.type', 'trial'
36-
// Setup roles used by tests
37-
extraConfigFile 'roles.yml', mainProject.file('roles.yml')
38-
/* Setup the one admin user that we run the tests as.
39-
* Tests use "run as" to get different users. */
40-
user username: "test_admin", password: "x-pack-test-password"
41-
}
42-
43-
File testArtifactsDir = project.file("$buildDir/testArtifacts")
44-
TaskProvider copyTestClasses = tasks.register("copyTestClasses", Copy) {
45-
dependsOn configurations.testArtifacts
46-
from { zipTree(configurations.testArtifacts.singleFile) }
47-
into testArtifactsDir
48-
}
49-
50-
integTest.runner {
51-
dependsOn copyTestClasses
52-
testClassesDirs += project.files(testArtifactsDir)
53-
classpath += configurations.testArtifacts
54-
nonInputProperties.systemProperty 'tests.audit.logfile',
55-
"${-> testClusters.integTest.singleNode().getAuditLog()}"
56-
nonInputProperties.systemProperty 'tests.audit.yesterday.logfile',
57-
"${-> testClusters.integTest.singleNode().getAuditLog().getParentFile()}/integTest_audit-${new Date().format('yyyy-MM-dd')}.json"
58-
}
59-
60-
testingConventions.enabled = false
21+
// Use tests from the root security qa project in subprojects
22+
configurations.create('testArtifacts')
23+
24+
dependencies {
25+
testImplementation project(":x-pack:plugin:core")
26+
testArtifacts project(path: mainProject.path, configuration: 'testArtifacts')
27+
}
28+
29+
testClusters.all {
30+
testDistribution = 'DEFAULT'
31+
// Setup auditing so we can use it in some tests
32+
setting 'xpack.security.audit.enabled', 'true'
33+
setting 'xpack.security.enabled', 'true'
34+
setting 'xpack.license.self_generated.type', 'trial'
35+
// Setup roles used by tests
36+
extraConfigFile 'roles.yml', mainProject.file('roles.yml')
37+
/* Setup the one admin user that we run the tests as.
38+
* Tests use "run as" to get different users. */
39+
user username: "test_admin", password: "x-pack-test-password"
40+
}
41+
42+
File testArtifactsDir = project.file("$buildDir/testArtifacts")
43+
TaskProvider copyTestClasses = tasks.register("copyTestClasses", Copy) {
44+
dependsOn configurations.testArtifacts
45+
from { zipTree(configurations.testArtifacts.singleFile) }
46+
into testArtifactsDir
47+
}
48+
49+
50+
tasks.withType(RestTestRunnerTask).configureEach {
51+
dependsOn copyTestClasses
52+
testClassesDirs += project.files(testArtifactsDir)
53+
classpath += configurations.testArtifacts
54+
nonInputProperties.systemProperty 'tests.audit.logfile',
55+
"${-> testClusters.integTest.singleNode().getAuditLog()}"
56+
nonInputProperties.systemProperty 'tests.audit.yesterday.logfile',
57+
"${-> testClusters.integTest.singleNode().getAuditLog().getParentFile()}/integTest_audit-${new Date().format('yyyy-MM-dd')}.json"
58+
}
59+
60+
testingConventions.enabled = false
6161
}

x-pack/plugin/sql/qa/jdbc/security/with-ssl/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
apply plugin: 'elasticsearch.test-with-ssl'
22

3-
testClusters.integTest {
3+
testClusters.all {
44
// The setup that we actually want
55
setting 'xpack.license.self_generated.type', 'trial'
66
setting 'xpack.security.http.ssl.enabled', 'true'
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
integTest.runner {
2-
systemProperty 'tests.ssl.enabled', 'false'
1+
import org.elasticsearch.gradle.testclusters.RestTestRunnerTask
2+
3+
tasks.withType(RestTestRunnerTask).configureEach {
4+
systemProperty 'tests.ssl.enabled', 'false'
35
}
46

5-
testClusters.integTest {
6-
setting 'xpack.license.self_generated.type', 'trial'
7+
testClusters.all {
8+
setting 'xpack.license.self_generated.type', 'trial'
79
}

0 commit comments

Comments
 (0)