/* * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ apply plugin: 'opensearch.opensearchplugin' apply plugin: 'opensearch.testclusters' apply plugin: 'opensearch.java-rest-test' import org.opensearch.gradle.test.RestIntegTestTask import org.opensearch.gradle.testclusters.StandaloneRestIntegTestTask import org.apache.tools.ant.taskdefs.condition.Os import java.util.concurrent.Callable opensearchplugin { name 'opensearch-job-scheduler-sample-extension' description 'Sample plugin that extends OpenSearch Job Scheduler plugin' classname 'org.opensearch.jobscheduler.sampleextension.SampleExtensionPlugin' extendedPlugins = ['opensearch-job-scheduler'] } ext { projectSubstitutions = [:] licenseFile = rootProject.file('LICENSE.txt') noticeFile = rootProject.file('NOTICE.txt') } repositories { mavenLocal() mavenCentral() maven { url "https://aws.oss.sonatype.org/content/repositories/snapshots" } } dependencies { compileOnly project(path: ":${rootProject.name}-spi", configuration: 'shadow') } def es_tmp_dir = rootProject.file('build/private/es_tmp').absoluteFile es_tmp_dir.mkdirs() File repo = file("$buildDir/testclusters/repo") def _numNodes = findProperty('numNodes') as Integer ?: 1 licenseHeaders.enabled = true validateNebulaPom.enabled = false testingConventions.enabled = false loggerUsageCheck.enabled = false javaRestTest.dependsOn(rootProject.assemble) javaRestTest { systemProperty 'tests.security.manager', 'false' } testClusters.javaRestTest { testDistribution = 'INTEG_TEST' } task integTest(type: RestIntegTestTask) { description = "Run tests against a cluster" testClassesDirs = sourceSets.test.output.classesDirs classpath = sourceSets.test.runtimeClasspath } tasks.named("check").configure { dependsOn(integTest) } integTest { if (project.hasProperty('excludeTests')) { project.properties['excludeTests']?.replaceAll('\\s', '')?.split('[,;]')?.each { exclude "${it}" } } systemProperty 'tests.security.manager', 'false' systemProperty 'java.io.tmpdir', es_tmp_dir.absolutePath systemProperty "https", System.getProperty("https") systemProperty "user", System.getProperty("user") systemProperty "password", System.getProperty("password") // Tell the test JVM if the cluster JVM is running under a debugger so that tests can use longer timeouts for // requests. The 'doFirst' delays reading the debug setting on the cluster till execution time. doFirst { // Tell the test JVM if the cluster JVM is running under a debugger so that tests can // use longer timeouts for requests. def isDebuggingCluster = getDebug() || System.getProperty("test.debug") != null systemProperty 'cluster.debug', isDebuggingCluster // Set number of nodes system property to be used in tests systemProperty 'cluster.number_of_nodes', "${_numNodes}" // There seems to be an issue when running multi node run or integ tasks with unicast_hosts // not being written, the waitForAllConditions ensures it's written getClusters().forEach { cluster -> cluster.waitForAllConditions() } } // The -Dcluster.debug option makes the cluster debuggable; this makes the tests debuggable if (System.getProperty("test.debug") != null) { jvmArgs '-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=8000' } if (System.getProperty("tests.rest.bwcsuite") == null) { filter { excludeTestsMatching "org.opensearch.jobscheduler.sampleextension.bwc.*IT" } } } project.getTasks().getByName('bundlePlugin').dependsOn(rootProject.tasks.getByName('build')) Zip bundle = (Zip) project.getTasks().getByName("bundlePlugin"); Zip rootBundle = (Zip) rootProject.getTasks().getByName("bundlePlugin"); integTest.dependsOn(bundle) integTest.getClusters().forEach{c -> { c.plugin(rootProject.getObjects().fileProperty().value(rootBundle.getArchiveFile())) c.plugin(project.getObjects().fileProperty().value(bundle.getArchiveFile())) }} testClusters.integTest { testDistribution = 'INTEG_TEST' // Cluster shrink exception thrown if we try to set numberOfNodes to 1, so only apply if > 1 if (_numNodes > 1) numberOfNodes = _numNodes // When running integration tests it doesn't forward the --debug-jvm to the cluster anymore // i.e. we have to use a custom property to flag when we want to debug OpenSearch JVM // since we also support multi node integration tests we increase debugPort per node if (System.getProperty("cluster.debug") != null) { def debugPort = 5005 nodes.forEach { node -> node.jvmArgs("-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=*:${debugPort}") debugPort += 1 } } setting 'path.repo', repo.absolutePath } String baseName = "jobSchedulerBwcCluster" String bwcOpenSearchVersion = "2.10.0" String bwcPluginVersion = bwcOpenSearchVersion + ".0" String bwcFilePath = "src/test/resources/bwc/job-scheduler/" bwcOpenSearchVersion += "-SNAPSHOT" String bwcFileName = "opensearch-job-scheduler-" + bwcPluginVersion + ".zip" String bwcDownloadUrl = "https://aws.oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=org.opensearch.plugin&a=opensearch-job-scheduler&v=$bwcPluginVersion-SNAPSHOT&p=zip" 2.times {i -> testClusters { "${baseName}$i" { testDistribution = "ARCHIVE" versions = [bwcOpenSearchVersion, opensearch_version] numberOfNodes = 3 plugin(provider(new Callable(){ @Override RegularFile call() throws Exception { return new RegularFile() { @Override File getAsFile() { File dir = new File(rootDir.path + "/sample-extension-plugin/" + bwcFilePath + bwcPluginVersion) if (!dir.exists()) { dir.mkdirs() } File f = new File(dir, bwcFileName) if (!f.exists()) { new URL(bwcDownloadUrl).withInputStream{ ins -> f.withOutputStream{ it << ins }} } return f } } } })) setting 'path.repo', "${buildDir}/cluster/shared/repo/${baseName}" setting 'http.content_type.required', 'true' } } } List> plugins = [] // Ensure the artifact for the current project version is available to be used for the bwc tests task prepareBwcTests { dependsOn bundle dependsOn rootBundle doLast { plugins = [ rootProject.getObjects().fileProperty().value(rootBundle.getArchiveFile()), project.getObjects().fileProperty().value(bundle.getArchiveFile()) ] } } // Create two test clusters with 3 nodes of the old version 2.times {i -> task "${baseName}#oldVersionClusterTask$i"(type: StandaloneRestIntegTestTask) { dependsOn 'prepareBwcTests' useCluster testClusters."${baseName}$i" filter { includeTestsMatching "org.opensearch.jobscheduler.sampleextension.bwc.*IT" } systemProperty 'tests.rest.bwcsuite', 'old_cluster' systemProperty 'tests.rest.bwcsuite_round', 'old' systemProperty 'tests.plugin_bwc_version', bwcPluginVersion nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}$i".allHttpSocketURI.join(",")}") nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}$i".getName()}") } } // Upgrade one node of the old cluster to new OpenSearch version with upgraded plugin version. // This results in a mixed cluster with 2 nodes on the old version and 1 upgraded node. // This is also used as a one third upgraded cluster for a rolling upgrade. task "${baseName}#mixedClusterTask"(type: StandaloneRestIntegTestTask) { useCluster testClusters."${baseName}0" dependsOn "${baseName}#oldVersionClusterTask0" doFirst { testClusters."${baseName}0".upgradeNodeAndPluginToNextVersion(plugins) } filter { includeTestsMatching "org.opensearch.jobscheduler.sampleextension.bwc.*IT" } systemProperty 'tests.rest.bwcsuite', 'mixed_cluster' systemProperty 'tests.rest.bwcsuite_round', 'first' systemProperty 'tests.plugin_bwc_version', bwcPluginVersion nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}0".allHttpSocketURI.join(",")}") nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}0".getName()}") } // Upgrade the second node to new OpenSearch version with upgraded plugin version after the first node is upgraded. // This results in a mixed cluster with 1 node on the old version and 2 upgraded nodes. // This is used for rolling upgrade. task "${baseName}#twoThirdsUpgradedClusterTask"(type: StandaloneRestIntegTestTask) { dependsOn "${baseName}#mixedClusterTask" useCluster testClusters."${baseName}0" doFirst { testClusters."${baseName}0".upgradeNodeAndPluginToNextVersion(plugins) } filter { includeTestsMatching "org.opensearch.jobscheduler.sampleextension.bwc.*IT" } systemProperty 'tests.rest.bwcsuite', 'mixed_cluster' systemProperty 'tests.rest.bwcsuite_round', 'second' systemProperty 'tests.plugin_bwc_version', bwcPluginVersion nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}0".allHttpSocketURI.join(",")}") nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}0".getName()}") } // Upgrade the third node to new OpenSearch version with upgraded plugin version after the second node is upgraded. // This results in a fully upgraded cluster. // This is used for rolling upgrade. task "${baseName}#rollingUpgradeClusterTask"(type: StandaloneRestIntegTestTask) { dependsOn "${baseName}#twoThirdsUpgradedClusterTask" useCluster testClusters."${baseName}0" doFirst { testClusters."${baseName}0".upgradeNodeAndPluginToNextVersion(plugins) } filter { includeTestsMatching "org.opensearch.jobscheduler.sampleextension.bwc.*IT" } mustRunAfter "${baseName}#mixedClusterTask" systemProperty 'tests.rest.bwcsuite', 'mixed_cluster' systemProperty 'tests.rest.bwcsuite_round', 'third' systemProperty 'tests.plugin_bwc_version', bwcPluginVersion nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}0".allHttpSocketURI.join(",")}") nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}0".getName()}") } // Upgrade all the nodes of the old cluster to new OpenSearch version with upgraded plugin version // at the same time resulting in a fully upgraded cluster. task "${baseName}#fullRestartClusterTask"(type: StandaloneRestIntegTestTask) { dependsOn "${baseName}#oldVersionClusterTask1" useCluster testClusters."${baseName}1" doFirst { testClusters."${baseName}1".upgradeAllNodesAndPluginsToNextVersion(plugins) } filter { includeTestsMatching "org.opensearch.jobscheduler.sampleextension.bwc.*IT" } systemProperty 'tests.rest.bwcsuite', 'upgraded_cluster' systemProperty 'tests.plugin_bwc_version', bwcPluginVersion nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}1".allHttpSocketURI.join(",")}") nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}1".getName()}") } // A bwc test suite which runs all the bwc tasks combined task bwcTestSuite(type: StandaloneRestIntegTestTask) { exclude '**/*Test*' exclude '**/*IT*' dependsOn tasks.named("${baseName}#mixedClusterTask") dependsOn tasks.named("${baseName}#rollingUpgradeClusterTask") dependsOn tasks.named("${baseName}#fullRestartClusterTask") } if (!(Os.isFamily(Os.FAMILY_MAC))) { tasks.named("check").configure {dependsOn(bwcTestSuite)} } run { doFirst { // There seems to be an issue when running multi node run or integ tasks with unicast_hosts // not being written, the waitForAllConditions ensures it's written getClusters().forEach { cluster -> cluster.waitForAllConditions() } } useCluster testClusters.integTest } // As of ES 7.7 the sample-extension-plugin is being added to the list of plugins for the testCluster during build before // the job-scheduler plugin is causing build failures. // The job-scheduler zip is added explicitly above but the sample-extension-plugin is added implicitly at some time during evaluation. // Will need to do a deep dive to find out exactly what task adds the sample-extension-plugin and add job-scheduler there but a temporary hack is to // reorder the plugins list after evaluation but prior to task execution when the plugins are installed. afterEvaluate { testClusters.javaRestTest.nodes.each { node -> def nodePlugins = node.plugins def firstPlugin = nodePlugins.get(0) if (firstPlugin.provider == project.bundlePlugin.archiveFile) { nodePlugins.remove(0) nodePlugins.add(firstPlugin) } } }