24
24
25
25
import org.opensearch.gradle.test.RestIntegTestTask
26
26
import org.opensearch.gradle.testclusters.StandaloneRestIntegTestTask
27
+ import org.opensearch.gradle.testclusters.OpenSearchCluster
27
28
29
+ import groovy.xml.XmlParser
30
+ import java.nio.file.Paths
28
31
import java.util.concurrent.Callable
29
32
import java.util.stream.Collectors
30
33
57
60
projectSubstitutions = [:]
58
61
licenseFile = rootProject. file(' LICENSE.TXT' )
59
62
noticeFile = rootProject. file(' NOTICE' )
63
+
64
+ getSecurityPluginDownloadLink = { ->
65
+ var repo = " https://aws.oss.sonatype.org/content/repositories/snapshots/org/opensearch/plugin/" +
66
+ " opensearch-security/$opensearch_build /"
67
+ var metadataFile = Paths . get(projectDir. toString(), " build" , " maven-metadata.xml" ). toAbsolutePath(). toFile()
68
+ download. run {
69
+ src repo + " maven-metadata.xml"
70
+ dest metadataFile
71
+ }
72
+ def metadata = new XmlParser (). parse(metadataFile)
73
+ def securitySnapshotVersion = metadata. versioning. snapshotVersions[0 ]. snapshotVersion[0 ]. value[0 ]. text()
74
+
75
+ return repo + " opensearch-security-${ securitySnapshotVersion} .zip"
76
+ }
77
+
78
+ File downloadedSecurityPlugin = null
79
+
80
+ configureSecurityPlugin = { OpenSearchCluster cluster ->
81
+
82
+ cluster. getNodes(). forEach { node ->
83
+ var creds = node. getCredentials()
84
+ if (creds. isEmpty()) {
85
+ creds. add(Map . of(' useradd' , ' admin' , ' -p' , ' admin' ))
86
+ } else {
87
+ creds. get(0 ). putAll(Map . of(' useradd' , ' admin' , ' -p' , ' admin' ))
88
+ }
89
+ }
90
+
91
+ var projectAbsPath = projectDir. getAbsolutePath()
92
+
93
+ // add a check to avoid re-downloading multiple times during single test run
94
+ if (downloadedSecurityPlugin == null ) {
95
+ downloadedSecurityPlugin = Paths . get(projectAbsPath, ' bin' , ' opensearch-security-snapshot.zip' ). toFile()
96
+ download. run {
97
+ src getSecurityPluginDownloadLink()
98
+ dest downloadedSecurityPlugin
99
+ }
100
+ }
101
+
102
+ // Config below including files are copied from security demo configuration
103
+ [' esnode.pem' , ' esnode-key.pem' , ' root-ca.pem' ]. forEach { file ->
104
+ File local = Paths . get(projectAbsPath, ' bin' , file). toFile()
105
+ download. run {
106
+ src " https://raw.githubusercontent.com/opensearch-project/security/main/bwc-test/src/test/resources/security/" + file
107
+ dest local
108
+ overwrite false
109
+ }
110
+ cluster. extraConfigFile file, local
111
+ }
112
+ [
113
+ ' plugins.security.ssl.transport.pemcert_filepath' : ' esnode.pem' ,
114
+ ' plugins.security.ssl.transport.pemkey_filepath' : ' esnode-key.pem' ,
115
+ ' plugins.security.ssl.transport.pemtrustedcas_filepath' : ' root-ca.pem' ,
116
+ ' plugins.security.ssl.transport.enforce_hostname_verification' : ' false' ,
117
+ // https is disabled : because `OpenSearchCluster` is hardcoded to validate cluster health by http
118
+ // refer how IT framework implemented in security plugin and reuse/copy to activate https
119
+ ' plugins.security.ssl.http.enabled' : ' false' ,
120
+ ' plugins.security.ssl.http.pemcert_filepath' : ' esnode.pem' ,
121
+ ' plugins.security.ssl.http.pemkey_filepath' : ' esnode-key.pem' ,
122
+ ' plugins.security.ssl.http.pemtrustedcas_filepath' : ' root-ca.pem' ,
123
+ ' plugins.security.allow_unsafe_democertificates' : ' true' ,
124
+
125
+ ' plugins.security.allow_default_init_securityindex' : ' true' ,
126
+ // 'plugins.security.authcz.admin_dn' : 'CN=kirk,OU=client,O=client,L=test,C=de',
127
+ ' plugins.security.authcz.admin_dn' : ' CN=admin,OU=SSL,O=Test,L=Test,C=DE' ,
128
+ ' plugins.security.audit.type' : ' internal_opensearch' ,
129
+ ' plugins.security.enable_snapshot_restore_privilege' : ' true' ,
130
+ ' plugins.security.check_snapshot_restore_write_privileges' : ' true' ,
131
+ ' plugins.security.restapi.roles_enabled' : ' ["all_access", "security_rest_api_access"]' ,
132
+ ' plugins.security.system_indices.enabled' : ' true'
133
+ ]. forEach { name , value ->
134
+ cluster. setting name, value
135
+ }
136
+
137
+ cluster. plugin provider((Callable<RegularFile > ) (() -> (RegularFile ) (() -> downloadedSecurityPlugin)))
138
+ }
60
139
}
61
140
62
141
tasks. withType(licenseHeaders. class) {
@@ -103,6 +182,7 @@ dependencies {
103
182
testImplementation group : ' com.h2database' , name : ' h2' , version : ' 2.2.220'
104
183
testImplementation group : ' org.xerial' , name : ' sqlite-jdbc' , version : ' 3.41.2.2'
105
184
testImplementation group : ' com.google.code.gson' , name : ' gson' , version : ' 2.8.9'
185
+ testCompileOnly ' org.apiguardian:apiguardian-api:1.1.2'
106
186
107
187
// Needed for BWC tests
108
188
zipArchive group : ' org.opensearch.plugin' , name :' opensearch-sql-plugin' , version : " ${ bwcVersion} -SNAPSHOT"
@@ -123,21 +203,28 @@ compileTestJava {
123
203
}
124
204
125
205
testClusters. all {
126
- testDistribution = ' archive'
127
-
128
206
// debug with command, ./gradlew opensearch-sql:run -DdebugJVM. --debug-jvm does not work with keystore.
129
207
if (System . getProperty(" debugJVM" ) != null ) {
130
208
jvmArgs ' -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005'
131
209
}
132
210
}
133
211
134
- testClusters. integTest {
135
- plugin " :opensearch-sql-plugin"
136
- setting " plugins.query.datasources.encryption.masterkey" , " 1234567812345678"
137
- }
138
-
139
212
testClusters {
213
+ integTest {
214
+ testDistribution = ' archive'
215
+ plugin " :opensearch-sql-plugin"
216
+ setting " plugins.query.datasources.encryption.masterkey" , " 1234567812345678"
217
+ }
140
218
remoteCluster {
219
+ testDistribution = ' archive'
220
+ plugin " :opensearch-sql-plugin"
221
+ }
222
+ integTestWithSecurity {
223
+ testDistribution = ' archive'
224
+ plugin " :opensearch-sql-plugin"
225
+ }
226
+ remoteIntegTestWithSecurity {
227
+ testDistribution = ' archive'
141
228
plugin " :opensearch-sql-plugin"
142
229
}
143
230
}
@@ -218,6 +305,65 @@ task integJdbcTest(type: RestIntegTestTask) {
218
305
}
219
306
}
220
307
308
+ task integTestWithSecurity (type : RestIntegTestTask ) {
309
+ useCluster testClusters. integTestWithSecurity
310
+ useCluster testClusters. remoteIntegTestWithSecurity
311
+
312
+ systemProperty " cluster.names" ,
313
+ getClusters(). stream(). map(cluster -> cluster. getName()). collect(Collectors . joining(" ," ))
314
+
315
+ getClusters(). forEach { cluster ->
316
+ configureSecurityPlugin(cluster)
317
+ }
318
+
319
+ useJUnitPlatform()
320
+ dependsOn ' :opensearch-sql-plugin:bundlePlugin'
321
+ testLogging {
322
+ events " passed" , " skipped" , " failed"
323
+ }
324
+ afterTest { desc , result ->
325
+ logger. quiet " ${ desc.className} .${ desc.name} : ${ result.resultType} ${ (result.getEndTime() - result.getStartTime())/1000} s"
326
+ }
327
+
328
+ systemProperty ' tests.security.manager' , ' false'
329
+ systemProperty ' project.root' , project. projectDir. absolutePath
330
+
331
+ // Set default query size limit
332
+ systemProperty ' defaultQuerySizeLimit' , ' 10000'
333
+
334
+ // Tell the test JVM if the cluster JVM is running under a debugger so that tests can use longer timeouts for
335
+ // requests. The 'doFirst' delays reading the debug setting on the cluster till execution time.
336
+ doFirst {
337
+ systemProperty ' cluster.debug' , getDebug()
338
+ getClusters(). forEach { cluster ->
339
+
340
+ String allTransportSocketURI = cluster. nodes. stream(). flatMap { node ->
341
+ node. getAllTransportPortURI(). stream()
342
+ }. collect(Collectors . joining(" ," ))
343
+ String allHttpSocketURI = cluster. nodes. stream(). flatMap { node ->
344
+ node. getAllHttpSocketURI(). stream()
345
+ }. collect(Collectors . joining(" ," ))
346
+
347
+ systemProperty " tests.rest.${ cluster.name} .http_hosts" , " ${ -> allHttpSocketURI} "
348
+ systemProperty " tests.rest.${ cluster.name} .transport_hosts" , " ${ -> allTransportSocketURI} "
349
+ }
350
+
351
+ systemProperty " https" , " false"
352
+ systemProperty " user" , " admin"
353
+ systemProperty " password" , " admin"
354
+ }
355
+
356
+ if (System . getProperty(" test.debug" ) != null ) {
357
+ jvmArgs ' -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005'
358
+ }
359
+
360
+ // NOTE: this IT config discovers only junit5 (jupiter) tests.
361
+ // https://github.com/opensearch-project/sql/issues/1974
362
+ filter {
363
+ includeTestsMatching ' org.opensearch.sql.ppl.CrossClusterSearchIT'
364
+ }
365
+ }
366
+
221
367
// Run PPL ITs and new, legacy and comparison SQL ITs with new SQL engine enabled
222
368
integTest {
223
369
useCluster testClusters. remoteCluster
0 commit comments