2424
2525import org.opensearch.gradle.test.RestIntegTestTask
2626import org.opensearch.gradle.testclusters.StandaloneRestIntegTestTask
27+ import org.opensearch.gradle.testclusters.OpenSearchCluster
2728
29+ import groovy.xml.XmlParser
30+ import java.nio.file.Paths
2831import java.util.concurrent.Callable
2932import java.util.stream.Collectors
3033
5558 projectSubstitutions = [:]
5659 licenseFile = rootProject. file(' LICENSE.TXT' )
5760 noticeFile = rootProject. file(' NOTICE' )
61+
62+ getSecurityPluginDownloadLink = { ->
63+ var repo = " https://aws.oss.sonatype.org/content/repositories/snapshots/org/opensearch/plugin/" +
64+ " opensearch-security/$opensearch_build /"
65+ var metadataFile = Paths . get(projectDir. toString(), " build" , " maven-metadata.xml" ). toAbsolutePath(). toFile()
66+ download. run {
67+ src repo + " maven-metadata.xml"
68+ dest metadataFile
69+ }
70+ def metadata = new XmlParser (). parse(metadataFile)
71+ def securitySnapshotVersion = metadata. versioning. snapshotVersions[0 ]. snapshotVersion[0 ]. value[0 ]. text()
72+
73+ return repo + " opensearch-security-${ securitySnapshotVersion} .zip"
74+ }
75+
76+ File downloadedSecurityPlugin = null
77+
78+ configureSecurityPlugin = { OpenSearchCluster cluster ->
79+
80+ cluster. getNodes(). forEach { node ->
81+ var creds = node. getCredentials()
82+ if (creds. isEmpty()) {
83+ creds. add(Map . of(' useradd' , ' admin' , ' -p' , ' admin' ))
84+ } else {
85+ creds. get(0 ). putAll(Map . of(' useradd' , ' admin' , ' -p' , ' admin' ))
86+ }
87+ }
88+
89+ var projectAbsPath = projectDir. getAbsolutePath()
90+
91+ // add a check to avoid re-downloading multiple times during single test run
92+ if (downloadedSecurityPlugin == null ) {
93+ downloadedSecurityPlugin = Paths . get(projectAbsPath, ' bin' , ' opensearch-security-snapshot.zip' ). toFile()
94+ download. run {
95+ src getSecurityPluginDownloadLink()
96+ dest downloadedSecurityPlugin
97+ }
98+ }
99+
100+ // Config below including files are copied from security demo configuration
101+ [' esnode.pem' , ' esnode-key.pem' , ' root-ca.pem' ]. forEach { file ->
102+ File local = Paths . get(projectAbsPath, ' bin' , file). toFile()
103+ download. run {
104+ src " https://raw.githubusercontent.com/opensearch-project/security/main/bwc-test/src/test/resources/security/" + file
105+ dest local
106+ overwrite false
107+ }
108+ cluster. extraConfigFile file, local
109+ }
110+ [
111+ // config copied from security plugin demo configuration
112+ ' plugins.security.ssl.transport.pemcert_filepath' : ' esnode.pem' ,
113+ ' plugins.security.ssl.transport.pemkey_filepath' : ' esnode-key.pem' ,
114+ ' plugins.security.ssl.transport.pemtrustedcas_filepath' : ' root-ca.pem' ,
115+ ' plugins.security.ssl.transport.enforce_hostname_verification' : ' false' ,
116+ // https is disabled to simplify test debugging
117+ ' plugins.security.ssl.http.enabled' : ' false' ,
118+ ' plugins.security.ssl.http.pemcert_filepath' : ' esnode.pem' ,
119+ ' plugins.security.ssl.http.pemkey_filepath' : ' esnode-key.pem' ,
120+ ' plugins.security.ssl.http.pemtrustedcas_filepath' : ' root-ca.pem' ,
121+ ' plugins.security.allow_unsafe_democertificates' : ' true' ,
122+
123+ ' plugins.security.allow_default_init_securityindex' : ' true' ,
124+ ' plugins.security.authcz.admin_dn' : ' CN=kirk,OU=client,O=client,L=test,C=de' ,
125+ ' plugins.security.audit.type' : ' internal_opensearch' ,
126+ ' plugins.security.enable_snapshot_restore_privilege' : ' true' ,
127+ ' plugins.security.check_snapshot_restore_write_privileges' : ' true' ,
128+ ' plugins.security.restapi.roles_enabled' : ' ["all_access", "security_rest_api_access"]' ,
129+ ' plugins.security.system_indices.enabled' : ' true'
130+ ]. forEach { name , value ->
131+ cluster. setting name, value
132+ }
133+
134+ cluster. plugin provider((Callable<RegularFile > ) (() -> (RegularFile ) (() -> downloadedSecurityPlugin)))
135+ }
58136}
59137
60138tasks. withType(licenseHeaders. class) {
@@ -97,6 +175,7 @@ dependencies {
97175 testImplementation group : ' com.h2database' , name : ' h2' , version : ' 2.2.220'
98176 testImplementation group : ' org.xerial' , name : ' sqlite-jdbc' , version : ' 3.41.2.2'
99177 testImplementation group : ' com.google.code.gson' , name : ' gson' , version : ' 2.8.9'
178+ testCompileOnly ' org.apiguardian:apiguardian-api:1.1.2'
100179}
101180
102181dependencyLicenses. enabled = false
@@ -113,21 +192,28 @@ compileTestJava {
113192}
114193
115194testClusters. all {
116- testDistribution = ' archive'
117-
118195 // debug with command, ./gradlew opensearch-sql:run -DdebugJVM. --debug-jvm does not work with keystore.
119196 if (System . getProperty(" debugJVM" ) != null ) {
120197 jvmArgs ' -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005'
121198 }
122199}
123200
124- testClusters. integTest {
125- plugin " :opensearch-sql-plugin"
126- setting " plugins.query.datasources.encryption.masterkey" , " 1234567812345678"
127- }
128-
129201testClusters {
202+ integTest {
203+ testDistribution = ' archive'
204+ plugin " :opensearch-sql-plugin"
205+ setting " plugins.query.datasources.encryption.masterkey" , " 1234567812345678"
206+ }
130207 remoteCluster {
208+ testDistribution = ' archive'
209+ plugin " :opensearch-sql-plugin"
210+ }
211+ integTestWithSecurity {
212+ testDistribution = ' archive'
213+ plugin " :opensearch-sql-plugin"
214+ }
215+ remoteIntegTestWithSecurity {
216+ testDistribution = ' archive'
131217 plugin " :opensearch-sql-plugin"
132218 }
133219}
@@ -208,6 +294,65 @@ task integJdbcTest(type: RestIntegTestTask) {
208294 }
209295}
210296
297+ task integTestWithSecurity (type : RestIntegTestTask ) {
298+ useCluster testClusters. integTestWithSecurity
299+ useCluster testClusters. remoteIntegTestWithSecurity
300+
301+ systemProperty " cluster.names" ,
302+ getClusters(). stream(). map(cluster -> cluster. getName()). collect(Collectors . joining(" ," ))
303+
304+ getClusters(). forEach { cluster ->
305+ configureSecurityPlugin(cluster)
306+ }
307+
308+ useJUnitPlatform()
309+ dependsOn ' :opensearch-sql-plugin:bundlePlugin'
310+ testLogging {
311+ events " passed" , " skipped" , " failed"
312+ }
313+ afterTest { desc , result ->
314+ logger. quiet " ${ desc.className} .${ desc.name} : ${ result.resultType} ${ (result.getEndTime() - result.getStartTime())/1000} s"
315+ }
316+
317+ systemProperty ' tests.security.manager' , ' false'
318+ systemProperty ' project.root' , project. projectDir. absolutePath
319+
320+ // Set default query size limit
321+ systemProperty ' defaultQuerySizeLimit' , ' 10000'
322+
323+ // Tell the test JVM if the cluster JVM is running under a debugger so that tests can use longer timeouts for
324+ // requests. The 'doFirst' delays reading the debug setting on the cluster till execution time.
325+ doFirst {
326+ systemProperty ' cluster.debug' , getDebug()
327+ getClusters(). forEach { cluster ->
328+
329+ String allTransportSocketURI = cluster. nodes. stream(). flatMap { node ->
330+ node. getAllTransportPortURI(). stream()
331+ }. collect(Collectors . joining(" ," ))
332+ String allHttpSocketURI = cluster. nodes. stream(). flatMap { node ->
333+ node. getAllHttpSocketURI(). stream()
334+ }. collect(Collectors . joining(" ," ))
335+
336+ systemProperty " tests.rest.${ cluster.name} .http_hosts" , " ${ -> allHttpSocketURI} "
337+ systemProperty " tests.rest.${ cluster.name} .transport_hosts" , " ${ -> allTransportSocketURI} "
338+ }
339+
340+ systemProperty " https" , " false"
341+ systemProperty " user" , " admin"
342+ systemProperty " password" , " admin"
343+ }
344+
345+ if (System . getProperty(" test.debug" ) != null ) {
346+ jvmArgs ' -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005'
347+ }
348+
349+ // NOTE: this IT config discovers only junit5 (jupiter) tests.
350+ // https://github.com/opensearch-project/sql/issues/1974
351+ filter {
352+ includeTestsMatching ' org.opensearch.sql.security.CrossClusterSearchIT'
353+ }
354+ }
355+
211356// Run PPL ITs and new, legacy and comparison SQL ITs with new SQL engine enabled
212357integTest {
213358 useCluster testClusters. remoteCluster
@@ -290,8 +435,8 @@ integTest {
290435 // Exclude JDBC related tests
291436 exclude ' org/opensearch/sql/jdbc/**'
292437
293- // Exclude this IT until running IT with security plugin enabled is ready
294- exclude ' org/opensearch/sql/ppl/CrossClusterSearchIT.class '
438+ // Exclude this IT, because they executed in another task (:integTestWithSecurity)
439+ exclude ' org/opensearch/sql/security/** '
295440}
296441
297442
0 commit comments