diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4bd5645b2..2484f7505 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -40,7 +40,7 @@ jobs: - name: Run k-NN Backwards Compatibility Tests run: | echo "Running backwards compatibility tests ..." - ./gradlew bwcTestSuite -Dtests.security.manager=false + ./gradlew :qa:bwc:bwcTestSuite - name: Upload Coverage Report uses: codecov/codecov-action@v1 diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index 18213fa9d..0bee05109 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -250,17 +250,15 @@ Additionally, it is possible to attach one debugger to the cluster JVM and anoth The purpose of Backwards Compatibility Testing and different types of BWC tests are explained [here](https://github.com/opensearch-project/opensearch-plugins/blob/main/TESTING.md#backwards-compatibility-testing) Use these commands to run BWC tests for k-NN: - -1. Mixed cluster test: `./gradlew knnBwcCluster#mixedClusterTask -Dtests.security.manager=false` -2. Rolling upgrade tests: `./gradlew knnBwcCluster#rollingUpgradeClusterTask -Dtests.security.manager=false` -3. Full restart upgrade tests: `./gradlew knnBwcCluster#fullRestartClusterTask -Dtests.security.manager=false` -4. `./gradlew bwcTestSuite -Dtests.security.manager=false` is used to run all the above bwc tests together. +1. Rolling upgrade tests: `./gradlew :qa:bwc:testRollingUpgrade` +2. Full restart upgrade tests: `./gradlew :qa:bwc:testRestartUpgrade` +3. `./gradlew :qa:bwc:bwcTestSuite` is used to run all the above bwc tests together. Use this command to run BWC tests for a given Backwards Compatibility Version: ``` -./gradlew bwcTestSuite -Dbwc.version=1.0.0.0-SNAPSHOT +./gradlew :qa:bwc:bwcTestSuite -Dbwc.version=1.0.0 ``` -Here, we are testing BWC Tests with BWC version of plugin as 1.0.0.0. Make sure to add the binary file of that version in the bwc directory in resources. +Here, we are testing BWC Tests with BWC version of plugin as 1.0.0. ### Adding new tests diff --git a/RELEASING.md b/RELEASING.md index d0c776fde..326a02326 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -29,6 +29,11 @@ Do not creating branches in the upstream repo, use your fork, for the exception Repositories create consistent release labels, such as `v1.0.0`, `v1.1.0` and `v2.0.0`, as well as `backport`. Use release labels to target an issue or a PR for a given release. See [MAINTAINERS](MAINTAINERS.md#triage-open-issues) for more information on triaging issues. +## Backwards Compatibility + +[The backwards compatibility test suite](qa/bwc) is used to ensure upgrades to the current version are successful. +When releasing a new version, update the `bwc.version` to the latest, previous minor version in [gradle.properties](gradle.properties). + ## Releasing The release process is standard across repositories in this org and is run by a release manager volunteering from amongst [MAINTAINERS](MAINTAINERS.md). diff --git a/build-tools/knnplugin-coverage.gradle b/build-tools/knnplugin-coverage.gradle index 30129c0db..57a0eeeec 100644 --- a/build-tools/knnplugin-coverage.gradle +++ b/build-tools/knnplugin-coverage.gradle @@ -59,19 +59,15 @@ jacocoTestReport { } } +afterEvaluate { + jacocoTestReport.dependsOn integTest -allprojects{ - afterEvaluate { - jacocoTestReport.dependsOn integTest - - testClusters.integTest { - jvmArgs " ${dummyIntegTest.jacoco.getAsJvmArg()}".replace('javaagent:','javaagent:/') - systemProperty 'com.sun.management.jmxremote', "true" - systemProperty 'com.sun.management.jmxremote.authenticate', "false" - systemProperty 'com.sun.management.jmxremote.port', "7777" - systemProperty 'com.sun.management.jmxremote.ssl', "false" - systemProperty 'java.rmi.server.hostname', "127.0.0.1" - } + testClusters.integTest { + jvmArgs " ${dummyIntegTest.jacoco.getAsJvmArg()}".replace('javaagent:','javaagent:/') + systemProperty 'com.sun.management.jmxremote', "true" + systemProperty 'com.sun.management.jmxremote.authenticate', "false" + systemProperty 'com.sun.management.jmxremote.port', "7777" + systemProperty 'com.sun.management.jmxremote.ssl', "false" + systemProperty 'java.rmi.server.hostname', "127.0.0.1" } } - diff --git a/build-tools/repositories.gradle b/build-tools/repositories.gradle index 7314b8403..6b829ed78 100644 --- a/build-tools/repositories.gradle +++ b/build-tools/repositories.gradle @@ -4,6 +4,9 @@ */ repositories { + mavenLocal() + maven { url "https://aws.oss.sonatype.org/content/repositories/snapshots" } mavenCentral() + maven { url "https://plugins.gradle.org/m2/" } } diff --git a/build.gradle b/build.gradle index 24ea5c022..a14386a0b 100644 --- a/build.gradle +++ b/build.gradle @@ -3,8 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import java.util.concurrent.Callable -import org.opensearch.gradle.testclusters.StandaloneRestIntegTestTask import org.opensearch.gradle.test.RestIntegTestTask buildscript { @@ -12,9 +10,7 @@ buildscript { // build.version_qualifier parameter applies to knn plugin artifacts only. OpenSearch version must be set // explicitly as 'opensearch.version' property, for instance opensearch.version=2.0.0-alpha1-SNAPSHOT opensearch_version = System.getProperty("opensearch.version", "2.0.0-alpha1-SNAPSHOT") - knn_bwc_version = System.getProperty("bwc.version", "1.2.0.0-SNAPSHOT") version_qualifier = System.getProperty("build.version_qualifier", "alpha1") - opensearch_bwc_version = "${knn_bwc_version}" - ".0-SNAPSHOT" opensearch_group = "org.opensearch" } @@ -37,42 +33,23 @@ buildscript { plugins { id 'java-library' - id 'nebula.ospackage' version "8.3.0" apply false + id 'java-test-fixtures' id 'idea' id 'jacoco' id "com.diffplug.spotless" version "6.3.0" apply false } -repositories { - mavenLocal() - maven { url "https://aws.oss.sonatype.org/content/repositories/snapshots" } - mavenCentral() - maven { url "https://plugins.gradle.org/m2/" } -} - apply from: 'gradle/formatting.gradle' apply plugin: 'opensearch.opensearchplugin' apply plugin: 'opensearch.rest-test' -def usingRemoteCluster = System.properties.containsKey('tests.rest.cluster') || System.properties.containsKey('tests.cluster') -def usingMultiNode = project.properties.containsKey('numNodes') -// Only apply jacoco test coverage if we are running a local single node cluster -def integTestDependOnJniLib = false -if (!usingRemoteCluster) { - integTestDependOnJniLib = true - if (!usingMultiNode) { - apply from: 'build-tools/knnplugin-coverage.gradle' - } -} - ext { isSnapshot = "true" == System.getProperty("build.snapshot", "true") projectSubstitutions = [:] - licenseFile = rootProject.file('LICENSE.TXT') - noticeFile = rootProject.file('NOTICE.TXT') } allprojects { + group = 'org.opensearch' version = opensearch_version.tokenize('-')[0] + '.0' if (version_qualifier) { @@ -81,12 +58,39 @@ allprojects { if (isSnapshot) { version += "-SNAPSHOT" } - apply from: 'build-tools/repositories.gradle' + apply from: rootProject.file('build-tools/repositories.gradle').absoluteFile plugins.withId('java') { sourceCompatibility = targetCompatibility = "11" } + + afterEvaluate { + if (project.name != "qa") { + project.dependencyLicenses.enabled = false + project.thirdPartyAudit.enabled = false + project.loggerUsageCheck.enabled = false + project.forbiddenApis.ignoreFailures = true + project.forbiddenPatterns { + setEnabled(false) + } + project.testingConventions.enabled = false + project.validateNebulaPom.enabled = false + project.licenseFile = rootProject.file('LICENSE.txt') + project.noticeFile = rootProject.file('NOTICE.txt') + project.forbiddenApis.ignoreFailures = true + } + } } +def usingRemoteCluster = System.properties.containsKey('tests.rest.cluster') || System.properties.containsKey('tests.cluster') +def usingMultiNode = project.properties.containsKey('numNodes') +// Only apply jacoco test coverage if we are running a local single node cluster +def integTestDependOnJniLib = false +if (!usingRemoteCluster) { + integTestDependOnJniLib = true + if (!usingMultiNode) { + apply from: 'build-tools/knnplugin-coverage.gradle' + } +} jacoco { toolVersion = "0.8.5" @@ -110,7 +114,7 @@ tasks.named("integTest").configure { } task release(type: Copy, group: 'build') { - dependsOn allprojects*.tasks.build + dependsOn project.tasks.build from(zipTree(project.tasks.bundlePlugin.outputs.files.getSingleFile())) into "build/plugins/opensearch-knn" includeEmptyDirs = false @@ -127,13 +131,9 @@ dependencies { api group: 'com.google.guava', name: 'failureaccess', version:'1.0.1' api group: 'com.google.guava', name: 'guava', version:'30.0-jre' api group: 'commons-lang', name: 'commons-lang', version: '2.6' - testImplementation "org.opensearch.test:framework:${opensearch_version}" + testFixturesImplementation "org.opensearch.test:framework:${opensearch_version}" } -licenseHeaders.enabled = true -dependencyLicenses.enabled = false -thirdPartyAudit.enabled = false -loggerUsageCheck.enabled = false def opensearch_tmp_dir = rootProject.file('build/private/opensearch_tmp').absoluteFile opensearch_tmp_dir.mkdirs() @@ -170,12 +170,6 @@ integTest { systemProperty "user", System.getProperty("user") systemProperty "password", System.getProperty("password") - if (System.getProperty("tests.rest.bwcsuite_cluster") == null) { - filter { - excludeTestsMatching "org.opensearch.knn.bwc.*IT" - } - } - doFirst { // Tell the test JVM if the cluster JVM is running under a debugger so that tests can // use longer timeouts for requests. @@ -228,174 +222,10 @@ task integTestRemote(type: RestIntegTestTask) { if (System.getProperty("tests.rest.cluster") != null) { filter { includeTestsMatching "org.opensearch.knn.*IT" - excludeTestsMatching "org.opensearch.knn.bwc.*IT" - } - } -} - -// bwcFilePath contains the gradlew assemble binary files of k-NN plugins -String baseName = "knnBwcCluster" -String bwcFilePath = "src/test/resources/org/opensearch/knn/bwc/" - -// Creates two test clusters of previous version and loads k-NN plugin of bwcVersion -2.times { i -> - testClusters { - "${baseName}$i" { - testDistribution = "ARCHIVE" - versions = [opensearch_bwc_version, opensearch_version] //Opensearch Cluster Versions - numberOfNodes = 3 - plugin(provider(new Callable() { - @Override - RegularFile call() throws Exception { - return new RegularFile() { - @Override - File getAsFile() { - return fileTree(bwcFilePath + knn_bwc_version).getSingleFile() - } - } - } - })) - setting 'path.repo', "${buildDir}/cluster/shared/repo/${baseName}" - setting 'http.content_type.required', 'true' - environment "LD_LIBRARY_PATH", "${rootDir}/build/testclusters/${baseName}$i-0/distro/${opensearch_bwc_version}-ARCHIVE/plugins/opensearch-knn/knnlib" - systemProperty "java.library.path", "${rootDir}/src/test/resources/org/opensearch/knn/bwc/lib:${rootDir}/build/testclusters/${baseName}$i-0/distro/${opensearch_bwc_version}-ARCHIVE/plugins/opensearch-knn/knnlib" - } - } -} - -// upgradeNodeAndPluginToNextVersion(plugins) upgrades plugin on the upgraded node with project.version binary file in bwcFilePath -// upgradeAllNodesAndPluginsToNextVersion(plugins) upgrades plugins on all the 3 nodes after upgrading the nodes -List> plugins = [ - provider(new Callable(){ - @Override - RegularFile call() throws Exception { - return new RegularFile() { - @Override - File getAsFile() { - return fileTree(bwcFilePath + project.version).getSingleFile() - } - } - } - }) -] - -// Creates 2 test clusters with 3 nodes of the old version. -2.times { i -> - task "${baseName}#oldVersionClusterTask$i"(type: StandaloneRestIntegTestTask) { - useCluster testClusters."${baseName}$i" - filter { - includeTestsMatching "org.opensearch.knn.bwc.*IT" } - systemProperty 'tests.rest.bwcsuite_cluster', 'old_cluster' - systemProperty 'tests.rest.bwcsuite_round', 'old' - systemProperty 'tests.plugin_bwc_version', knn_bwc_version - nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}$i".allHttpSocketURI.join(",")}") - nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}$i".getName()}") } } -// Upgrades 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".getNodes().getAt("${baseName}0" + "-0").environment("LD_LIBRARY_PATH", "") - testClusters."${baseName}0".getNodes().getAt("${baseName}0" + "-0").systemProperty("java.library.path", "$rootDir/jni/release") - testClusters."${baseName}0".upgradeNodeAndPluginToNextVersion(plugins) - } - filter { - includeTestsMatching "org.opensearch.knn.bwc.*IT" - } - systemProperty 'tests.rest.bwcsuite_cluster', 'mixed_cluster' - systemProperty 'tests.rest.bwcsuite_round', 'first' - systemProperty 'tests.plugin_bwc_version', knn_bwc_version - nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}0".allHttpSocketURI.join(",")}") - nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}0".getName()}") -} - -// Upgrades 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".getNodes().getAt("${baseName}0" + "-1").environment("LD_LIBRARY_PATH", "") - testClusters."${baseName}0".getNodes().getAt("${baseName}0" + "-1").systemProperty("java.library.path", "$rootDir/jni/release") - testClusters."${baseName}0".upgradeNodeAndPluginToNextVersion(plugins) - } - filter { - includeTestsMatching "org.opensearch.knn.bwc.*IT" - } - systemProperty 'tests.rest.bwcsuite_cluster', 'mixed_cluster' - systemProperty 'tests.rest.bwcsuite_round', 'second' - systemProperty 'tests.plugin_bwc_version', knn_bwc_version - nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}0".allHttpSocketURI.join(",")}") - nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}0".getName()}") -} - -// Upgrades 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".getNodes().getAt("${baseName}0" + "-2").environment("LD_LIBRARY_PATH", "") - testClusters."${baseName}0".getNodes().getAt("${baseName}0" + "-2").systemProperty("java.library.path", "$rootDir/jni/release") - testClusters."${baseName}0".upgradeNodeAndPluginToNextVersion(plugins) - } - filter { - includeTestsMatching "org.opensearch.knn.bwc.*IT" - } - mustRunAfter "${baseName}#mixedClusterTask" - systemProperty 'tests.rest.bwcsuite_cluster', 'mixed_cluster' - systemProperty 'tests.rest.bwcsuite_round', 'third' - systemProperty 'tests.plugin_bwc_version', knn_bwc_version - nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${baseName}0".allHttpSocketURI.join(",")}") - nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${baseName}0".getName()}") -} - -// Upgrades 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".environment("LD_LIBRARY_PATH", "") - testClusters."${baseName}1".systemProperty("java.library.path", "$rootDir/jni/release") - testClusters."${baseName}1".upgradeAllNodesAndPluginsToNextVersion(plugins) - } - filter { - includeTestsMatching "org.opensearch.knn.bwc.*IT" - } - systemProperty 'tests.rest.bwcsuite_cluster', 'upgraded_cluster' - systemProperty 'tests.rest.bwcsuite_round', 'fullrestart' - systemProperty 'tests.plugin_bwc_version', knn_bwc_version - 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) { - dependsOn "copyLatestSnapshot" - exclude '**/*Test*' - exclude '**/*IT*' - dependsOn tasks.named("${baseName}#mixedClusterTask") - dependsOn tasks.named("${baseName}#rollingUpgradeClusterTask") - dependsOn tasks.named("${baseName}#fullRestartClusterTask") -} - -task copyLatestSnapshot(type: Copy){ - dependsOn 'assemble' - mkdir "$bwcFilePath$project.version" - from "$buildDir/distributions" - include "*.zip" - into "$bwcFilePath$project.version" -} - run { useCluster project.testClusters.integTest dependsOn buildJniLib @@ -407,80 +237,3 @@ run { } } } - - -//TODO fix these -forbiddenApis.ignoreFailures = true -forbiddenPatterns { - setEnabled(false) -} - -// We don't need to follow OpenSearch testing naming conventions. -// see https://github.com/opensearch-project/OpenSearch/blob/main/buildSrc/src/main/java/org/opensearch/gradle/precommit/TestingConventionsTasks.java -// enable testingConventions check will cause errors like: "Classes ending with [Tests] must subclass [LuceneTestCase]" -testingConventions.enabled = false -validateNebulaPom.enabled = false -apply plugin: 'nebula.ospackage' - -// This is afterEvaluate because the bundlePlugin ZIP task is updated afterEvaluate and changes the ZIP name to match the plugin name -afterEvaluate { - ospackage { - packageName = "${name}" - release = isSnapshot ? "0.1" : '1' - version = "${project.version}" - - into '/usr/share/opensearch/plugins' - from(zipTree(bundlePlugin.archivePath)) { - into opensearchplugin.name - } - - user 'root' - permissionGroup 'root' - fileMode 0644 - dirMode 0755 - - requires('opensearch', versions.opensearch, EQUAL) - //TODO: Use default knn lib version for now, fix will be compare with version that is used in build step. - requires("opensearch-knnlib", version, EQUAL) - packager = 'Amazon' - vendor = 'Amazon' - os = 'LINUX' - prefix '/usr' - - license 'ASL-2.0' - maintainer 'OpenSearch ' - url 'https://opensearch.org/downloads.html' - summary ''' - KNN plugin for OpenSearch. - '''.stripIndent().replace('\n', ' ').trim() - } - - buildRpm { - arch = 'NOARCH' - dependsOn 'assemble' - finalizedBy 'renameRpm' - task renameRpm(type: Copy) { - from("$buildDir/distributions") - into("$buildDir/distributions") - include archiveName - rename archiveName, "${packageName}-${version}.rpm" - doLast { delete file("$buildDir/distributions/$archiveName") } - } - } - buildDeb { - arch = 'all' - dependsOn 'assemble' - finalizedBy 'renameDeb' - task renameDeb(type: Copy) { - from("$buildDir/distributions") - into("$buildDir/distributions") - include archiveName - rename archiveName, "${packageName}-${version}.deb" - doLast { delete file("$buildDir/distributions/$archiveName") } - } - } - - task buildPackages(type: GradleBuild) { - tasks = ['build', 'buildRpm', 'buildDeb'] - } -} diff --git a/gradle.properties b/gradle.properties index 86e266f28..94c6ea934 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,6 +4,7 @@ # version=1.0.0 +systemProp.bwc.version=1.3.1 org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \ diff --git a/qa/bwc/build.gradle b/qa/bwc/build.gradle new file mode 100644 index 000000000..0a18c13a3 --- /dev/null +++ b/qa/bwc/build.gradle @@ -0,0 +1,185 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import org.opensearch.gradle.testclusters.StandaloneRestIntegTestTask + +apply plugin: 'opensearch.testclusters' +apply plugin: 'opensearch.build' +apply plugin: 'opensearch.rest-test' + +// Disable a few tasks that come with build +build.enabled = false +integTest.enabled = false +test.enabled = false +assemble.enabled = false +dependenciesInfo.enabled = false + +dependencies { + api "org.opensearch:opensearch:${opensearch_version}" + compileOnly "org.opensearch.plugin:opensearch-scripting-painless-spi:${versions.opensearch}" + api group: 'commons-lang', name: 'commons-lang', version: '2.6' + + api "org.apache.logging.log4j:log4j-api:${versions.log4j}" + api "org.apache.logging.log4j:log4j-core:${versions.log4j}" + + testImplementation "org.opensearch.test:framework:${opensearch_version}" + testImplementation(testFixtures(rootProject)) +} + + +def tmp_dir = project.file('build/private/artifact_tmp').absoluteFile +tmp_dir.mkdirs() +String knn_bwc_version = System.getProperty("bwc.version") + +// Task to pull k-NN plugin from archive +task pullBwcPlugin { + doFirst { + delete java.nio.file.Path.of(tmp_dir.absolutePath, "opensearch-*") + } + + doLast { + ant.get( + src: "https://artifacts.opensearch.org/releases/bundle/opensearch/${knn_bwc_version}/opensearch-${knn_bwc_version}-linux-x64.tar.gz", + dest: tmp_dir.absolutePath, + httpusecaches: false + ) + copy { + from tarTree(java.nio.file.Path.of(tmp_dir.absolutePath, "opensearch-${knn_bwc_version}-linux-x64.tar.gz")) + into tmp_dir.absolutePath + } + copy { + from(java.nio.file.Path.of(tmp_dir.absolutePath, "opensearch-${knn_bwc_version}", "plugins", "opensearch-knn")) + into java.nio.file.Path.of(tmp_dir.absolutePath, "opensearch-knn") + } + delete java.nio.file.Path.of(tmp_dir.absolutePath, "opensearch-${knn_bwc_version}"), java.nio.file.Path.of(tmp_dir.absolutePath, "opensearch-${knn_bwc_version}-linux-x64.tar.gz") + } +} + +// Task to zip plugin from archive +task zipBwcPlugin(type: Zip) { + dependsOn "pullBwcPlugin" + from(java.nio.file.Path.of(tmp_dir.absolutePath, "opensearch-knn")) + destinationDirectory = tmp_dir + archiveFileName = "opensearch-knn-${knn_bwc_version}.zip" + doLast { + delete java.nio.file.Path.of(tmp_dir.absolutePath, "opensearch-knn") + } +} + +String baseName = "knnBwcCluster" +def clusterNames = [baseName + "-rolling", baseName + "-restart"] as String[] + +// Creates two test clusters of previous version and loads k-NN plugin of bwcVersion +2.times { i -> + testClusters { + "${clusterNames[i]}" { + testDistribution = "ARCHIVE" + versions = [knn_bwc_version, opensearch_version] + numberOfNodes = 3 + plugin(project.tasks.zipBwcPlugin.archiveFile) + setting 'path.repo', "${buildDir}/cluster/shared/repo/${clusterNames[i]}" + setting 'http.content_type.required', 'true' + environment "LD_LIBRARY_PATH", "${buildDir}/testclusters/${clusterNames[i]}-0/distro/${knn_bwc_version}-ARCHIVE/plugins/opensearch-knn/knnlib" + systemProperty "java.library.path", "${buildDir}/testclusters/${clusterNames[i]}-0/distro/${knn_bwc_version}-ARCHIVE/plugins/opensearch-knn/knnlib" + } + } +} + +// Creates 2 tasks to run BWC tests against the old clusters +2.times { i -> + task "${clusterNames[i]}#testAgainstOldCluster"(type: StandaloneRestIntegTestTask) { + dependsOn "zipBwcPlugin" + useCluster testClusters."${clusterNames[i]}" + systemProperty 'tests.rest.bwcsuite_cluster', 'old_cluster' + systemProperty 'tests.rest.bwcsuite_round', 'old' + systemProperty 'tests.plugin_bwc_version', knn_bwc_version + nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${clusterNames[i]}".allHttpSocketURI.join(",")}") + nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${clusterNames[i]}".getName()}") + systemProperty 'tests.security.manager', 'false' + } +} + +// Part of rolling upgrade. Upgrades 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. +task testAgainstOneThirdUpgradedCluster (type: StandaloneRestIntegTestTask) { + useCluster testClusters."${clusterNames[0]}" + dependsOn rootProject.tasks.buildJniLib + dependsOn rootProject.tasks.assemble + dependsOn "${clusterNames[0]}#testAgainstOldCluster" + doFirst { + testClusters."${clusterNames[0]}".getNodes().getAt("${clusterNames[0]}" + "-0").environment("LD_LIBRARY_PATH", "$rootDir/jni/release") + testClusters."${clusterNames[0]}".getNodes().getAt("${clusterNames[0]}" + "-0").systemProperty("java.library.path", "$rootDir/jni/release") + testClusters."${clusterNames[0]}".upgradeNodeAndPluginToNextVersion([rootProject.tasks.bundlePlugin.archiveFile]) + } + systemProperty 'tests.rest.bwcsuite_cluster', 'mixed_cluster' + systemProperty 'tests.rest.bwcsuite_round', 'first' + systemProperty 'tests.plugin_bwc_version', knn_bwc_version + nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${clusterNames[0]}".allHttpSocketURI.join(",")}") + nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${clusterNames[0]}".getName()}") + systemProperty 'tests.security.manager', 'false' +} + +// Part of rolling upgrade. Upgrades 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. +task testAgainstTwoThirdsUpgradedCluster(type: StandaloneRestIntegTestTask) { + dependsOn "testAgainstOneThirdUpgradedCluster" + useCluster testClusters."${clusterNames[0]}" + doFirst { + testClusters."${clusterNames[0]}".getNodes().getAt("${clusterNames[0]}" + "-1").environment("LD_LIBRARY_PATH", "$rootDir/jni/release") + testClusters."${clusterNames[0]}".getNodes().getAt("${clusterNames[0]}" + "-1").systemProperty("java.library.path", "$rootDir/jni/release") + testClusters."${clusterNames[0]}".upgradeNodeAndPluginToNextVersion([rootProject.tasks.bundlePlugin.archiveFile]) + } + systemProperty 'tests.rest.bwcsuite_cluster', 'mixed_cluster' + systemProperty 'tests.rest.bwcsuite_round', 'second' + systemProperty 'tests.plugin_bwc_version', knn_bwc_version + nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${clusterNames[0]}".allHttpSocketURI.join(",")}") + nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${clusterNames[0]}".getName()}") + systemProperty 'tests.security.manager', 'false' +} + +// Part of rolling upgrade. Upgrades the third node to new OpenSearch version with upgraded plugin version after the +// second node is upgraded. This results in a fully upgraded cluster. +task testRollingUpgrade(type: StandaloneRestIntegTestTask) { + dependsOn "testAgainstTwoThirdsUpgradedCluster" + useCluster testClusters."${clusterNames[0]}" + doFirst { + testClusters."${clusterNames[0]}".getNodes().getAt("${clusterNames[0]}" + "-2").environment("LD_LIBRARY_PATH", "$rootDir/jni/release") + testClusters."${clusterNames[0]}".getNodes().getAt("${clusterNames[0]}" + "-2").systemProperty("java.library.path", "$rootDir/jni/release") + testClusters."${clusterNames[0]}".upgradeNodeAndPluginToNextVersion([rootProject.tasks.bundlePlugin.archiveFile]) + } + mustRunAfter "testAgainstOneThirdUpgradedCluster" + systemProperty 'tests.rest.bwcsuite_cluster', 'mixed_cluster' + systemProperty 'tests.rest.bwcsuite_round', 'third' + systemProperty 'tests.plugin_bwc_version', knn_bwc_version + nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${clusterNames[0]}".allHttpSocketURI.join(",")}") + nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${clusterNames[0]}".getName()}") + systemProperty 'tests.security.manager', 'false' +} + +// Part of restart cluster tests. First, tests run against old cluster. Then, all nodes are upgraded and tests are +// re-ran +task testRestartUpgrade(type: StandaloneRestIntegTestTask) { + dependsOn "${clusterNames[1]}#testAgainstOldCluster" + dependsOn rootProject.tasks.buildJniLib + dependsOn rootProject.tasks.assemble + useCluster testClusters."${clusterNames[1]}" + doFirst { + testClusters."${clusterNames[1]}".environment("LD_LIBRARY_PATH", "$rootDir/jni/release") + testClusters."${clusterNames[1]}".systemProperty("java.library.path", "$rootDir/jni/release") + testClusters."${clusterNames[1]}".upgradeAllNodesAndPluginsToNextVersion([rootProject.tasks.bundlePlugin.archiveFile]) + } + systemProperty 'tests.rest.bwcsuite_cluster', 'upgraded_cluster' + systemProperty 'tests.rest.bwcsuite_round', 'fullrestart' + systemProperty 'tests.plugin_bwc_version', knn_bwc_version + nonInputProperties.systemProperty('tests.rest.cluster', "${-> testClusters."${clusterNames[1]}".allHttpSocketURI.join(",")}") + nonInputProperties.systemProperty('tests.clustername', "${-> testClusters."${clusterNames[1]}".getName()}") + systemProperty 'tests.security.manager', 'false' +} + +// Task to run both fullRestartClusterTests and rollingUpgradeClusterTests +task bwcTestSuite { + dependsOn "testRestartUpgrade" + dependsOn "testRollingUpgrade" +} diff --git a/src/test/java/org/opensearch/knn/bwc/KNNBackwardsCompatibilityIT.java b/qa/bwc/src/test/java/org/opensearch/knn/bwc/KNNBackwardsCompatibilityIT.java similarity index 100% rename from src/test/java/org/opensearch/knn/bwc/KNNBackwardsCompatibilityIT.java rename to qa/bwc/src/test/java/org/opensearch/knn/bwc/KNNBackwardsCompatibilityIT.java diff --git a/settings.gradle b/settings.gradle index 45910bf87..de861d3dd 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,3 +5,4 @@ rootProject.name = 'opensearch-knn' +include ":qa:bwc" diff --git a/src/test/resources/org/opensearch/knn/bwc/1.0.0.0-SNAPSHOT/opensearch-knn-1.0.0.0.zip b/src/test/resources/org/opensearch/knn/bwc/1.0.0.0-SNAPSHOT/opensearch-knn-1.0.0.0.zip deleted file mode 100644 index 7bdcf6faf..000000000 Binary files a/src/test/resources/org/opensearch/knn/bwc/1.0.0.0-SNAPSHOT/opensearch-knn-1.0.0.0.zip and /dev/null differ diff --git a/src/test/resources/org/opensearch/knn/bwc/1.1.0.0-SNAPSHOT/opensearch-knn-1.1.0.0.zip b/src/test/resources/org/opensearch/knn/bwc/1.1.0.0-SNAPSHOT/opensearch-knn-1.1.0.0.zip deleted file mode 100644 index c64e567ba..000000000 Binary files a/src/test/resources/org/opensearch/knn/bwc/1.1.0.0-SNAPSHOT/opensearch-knn-1.1.0.0.zip and /dev/null differ diff --git a/src/test/resources/org/opensearch/knn/bwc/1.2.0.0-SNAPSHOT/opensearch-knn-1.2.0.0-linux-x64.zip b/src/test/resources/org/opensearch/knn/bwc/1.2.0.0-SNAPSHOT/opensearch-knn-1.2.0.0-linux-x64.zip deleted file mode 100644 index c3e8d5f13..000000000 Binary files a/src/test/resources/org/opensearch/knn/bwc/1.2.0.0-SNAPSHOT/opensearch-knn-1.2.0.0-linux-x64.zip and /dev/null differ diff --git a/src/test/resources/org/opensearch/knn/bwc/lib/libKNNIndexV2_0_11.so b/src/test/resources/org/opensearch/knn/bwc/lib/libKNNIndexV2_0_11.so deleted file mode 100644 index 6db6a9da2..000000000 Binary files a/src/test/resources/org/opensearch/knn/bwc/lib/libKNNIndexV2_0_11.so and /dev/null differ diff --git a/src/test/java/org/opensearch/knn/KNNRestTestCase.java b/src/testFixtures/java/org/opensearch/knn/KNNRestTestCase.java similarity index 100% rename from src/test/java/org/opensearch/knn/KNNRestTestCase.java rename to src/testFixtures/java/org/opensearch/knn/KNNRestTestCase.java diff --git a/src/test/java/org/opensearch/knn/KNNResult.java b/src/testFixtures/java/org/opensearch/knn/KNNResult.java similarity index 100% rename from src/test/java/org/opensearch/knn/KNNResult.java rename to src/testFixtures/java/org/opensearch/knn/KNNResult.java diff --git a/src/test/java/org/opensearch/knn/ODFERestTestCase.java b/src/testFixtures/java/org/opensearch/knn/ODFERestTestCase.java similarity index 100% rename from src/test/java/org/opensearch/knn/ODFERestTestCase.java rename to src/testFixtures/java/org/opensearch/knn/ODFERestTestCase.java diff --git a/src/test/java/org/opensearch/knn/TestUtils.java b/src/testFixtures/java/org/opensearch/knn/TestUtils.java similarity index 100% rename from src/test/java/org/opensearch/knn/TestUtils.java rename to src/testFixtures/java/org/opensearch/knn/TestUtils.java