From 058a2b7e720f010a9b57b292ff546ca62c591a83 Mon Sep 17 00:00:00 2001 From: mgodwan Date: Thu, 25 Jan 2024 17:51:38 +0530 Subject: [PATCH] Trial: bwc test enablement logic Signed-off-by: mgodwan --- .github/workflows/test_bwc.yml | 60 ++++++ build.gradle | 174 ++++++++++++++++++ scripts/bwctest.sh | 31 ++++ .../codec/customcodecs/bwc/SampleBWCIT.java | 83 +++++++++ 4 files changed, 348 insertions(+) create mode 100644 .github/workflows/test_bwc.yml create mode 100644 scripts/bwctest.sh create mode 100644 src/test/java/org/opensearch/index/codec/customcodecs/bwc/SampleBWCIT.java diff --git a/.github/workflows/test_bwc.yml b/.github/workflows/test_bwc.yml new file mode 100644 index 0000000..b73b418 --- /dev/null +++ b/.github/workflows/test_bwc.yml @@ -0,0 +1,60 @@ +name: Test Custom Codecs BWC +on: + push: + branches: + - "*" + pull_request: + branches: + - "*" + +jobs: + Get-CI-Image-Tag: + uses: opensearch-project/opensearch-build/.github/workflows/get-ci-image-tag.yml@main + with: + product: opensearch + + Build-custom-codecs-linux: + needs: Get-CI-Image-Tag + strategy: + matrix: + java: [11,17,21] + fail-fast: false + + name: Test Custom Codecs BWC + runs-on: ubuntu-latest + container: + # using the same image which is used by opensearch-build team to build the OpenSearch Distribution + # this image tag is subject to change as more dependencies and updates will arrive over time + image: ${{ needs.Get-CI-Image-Tag.outputs.ci-image-version-linux }} + # need to switch to root so that github actions can install runner binary on container without permission issues. + options: --user root + + steps: + - name: Setup Java ${{ matrix.java }} + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: ${{ matrix.java }} + + # custom-codecs + - name: Checkout Custom codecs + uses: actions/checkout@v3 + + - name: Assemble custom-codecs + run: | + plugin_version=`./gradlew properties -q | grep "opensearch_build:" | awk '{print $2}'` + chown -R 1000:1000 `pwd` + echo plugin_version $plugin_version + su `id -un 1000` -c "./gradlew assemble" + echo "Creating ./src/test/resources/org/opensearch/customcodecs/bwc/custom-codecs/custom-codecs/$plugin_version ..." + su `id -un 1000` -c "mkdir -p ./src/test/resources/org/opensearch/customcodecs/bwc/custom-codecs/$plugin_version" + echo "Copying ./build/distributions/*.zip to ./src/test/resources/org/opensearch/customcodecs/bwc/custom-codecs/$plugin_version ..." + ls ./build/distributions/ + su `id -un 1000` -c "cp ./build/distributions/*.zip ./src/test/resources/org/opensearch/customcodecs/bwc/custom-codecs/$plugin_version" + echo "Copied ./build/distributions/*.zip to ./src/test/resources/org/opensearch/customcodecs/bwc/custom-codecs/$plugin_version ..." + ls ./src/test/resources/org/opensearch/customcodecs/bwc/custom-codecs/$plugin_version + - name: Run Custom Codecs Backwards Compatibility Tests + run: | + echo "Running backwards compatibility tests ..." + chown -R 1000:1000 `pwd` + su `id -un 1000` -c "./gradlew bwcTestSuite -Dtests.security.manager=false" diff --git a/build.gradle b/build.gradle index 00de61c..2670357 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,6 @@ +import java.util.concurrent.Callable +import org.opensearch.gradle.testclusters.StandaloneRestIntegTestTask + /* * SPDX-License-Identifier: Apache-2.0 * @@ -15,6 +18,17 @@ buildscript { opensearch_version = System.getProperty("opensearch.version", "3.0.0-SNAPSHOT") isSnapshot = "true" == System.getProperty("build.snapshot", "true") buildVersionQualifier = System.getProperty("build.version_qualifier", "") + + bwcVersionShort = "2.11.0" + bwcVersion = bwcVersionShort + ".0" + //https://github.com/opensearch-project/custom-codecs/archive/refs/tags/2.11.0.0.zip +// bwcOpenSearchCustomCodecsDownload = 'https://ci.opensearch.org/ci/dbc/distribution-build-opensearch/' + bwcVersionShort + '/latest/linux/x64/tar/builds/' + +// 'opensearch/plugins/custom-codecs-' + bwcVersion + '.zip' + + bwcOpenSearchCustomCodecsDownload = 'https://github.com/opensearch-project/custom-codecs/archive/refs/tags/' + bwcVersion + '.zip' + baseName = "customCodecsBwcCluster" + bwcFilePath = "src/test/resources/org/opensearch/customcodecs/bwc/" + bwcCustomCodecsPath = bwcFilePath + "custom-codecs/" } repositories { @@ -185,6 +199,12 @@ integTest { systemProperty "https", System.getProperty("https") systemProperty "user", System.getProperty("user") systemProperty "password", System.getProperty("password") + + if (System.getProperty("tests.rest.bwcsuite") == null) { + filter { + excludeTestsMatching "org.opensearch.index.codecs.customcodecs.bwc.*IT" + } + } } testClusters.integTest { @@ -192,6 +212,160 @@ testClusters.integTest { plugin(project.tasks.bundlePlugin.archiveFile) } +2.times {i -> + testClusters { + "${baseName}$i" { + testDistribution = "ARCHIVE" + versions = [bwcVersionShort, opensearch_version] + numberOfNodes = 3 + plugin(provider(new Callable(){ + @Override + RegularFile call() throws Exception { + return new RegularFile() { + @Override + File getAsFile() { + if (new File("$project.rootDir/$bwcFilePath/custom-codecs/$bwcVersion").exists()) { + project.delete(files("$project.rootDir/$bwcFilePath/custom-codecs/$bwcVersion")) + } + project.mkdir bwcCustomCodecsPath + bwcVersion + ant.get(src: bwcOpenSearchCustomCodecsDownload, + dest: bwcCustomCodecsPath + bwcVersion, + httpusecaches: false) + return fileTree(bwcCustomCodecsPath + bwcVersion).getSingleFile() + } + } + } + })) + setting 'path.repo', "${buildDir}/cluster/shared/repo/${baseName}" + setting 'http.content_type.required', 'true' + } + } +} + +List> plugins = [ + provider(new Callable(){ + @Override + RegularFile call() throws Exception { + return new RegularFile() { + @Override + File getAsFile() { + return configurations.zipArchive.asFileTree.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.index.codecs.customcodecs.bwc.*IT" + } + systemProperty 'tests.rest.bwcsuite', 'old_cluster' + systemProperty 'tests.rest.bwcsuite_round', 'old' + systemProperty 'tests.plugin_bwc_version', bwcVersion + 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".upgradeNodeAndPluginToNextVersion(plugins) + } + filter { + includeTestsMatching "org.opensearch.index.codecs.customcodecs.bwc.*IT" + } + systemProperty 'tests.rest.bwcsuite', 'mixed_cluster' + systemProperty 'tests.rest.bwcsuite_round', 'first' + systemProperty 'tests.plugin_bwc_version', bwcVersion + 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".upgradeNodeAndPluginToNextVersion(plugins) + } + filter { + includeTestsMatching "org.opensearch.index.codecs.customcodecs.bwc.*IT" + } + systemProperty 'tests.rest.bwcsuite', 'mixed_cluster' + systemProperty 'tests.rest.bwcsuite_round', 'second' + systemProperty 'tests.plugin_bwc_version', bwcVersion + 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".upgradeNodeAndPluginToNextVersion(plugins) + } + filter { + includeTestsMatching "org.opensearch.index.codecs.customcodecs.bwc.*IT" + } + mustRunAfter "${baseName}#mixedClusterTask" + systemProperty 'tests.rest.bwcsuite', 'mixed_cluster' + systemProperty 'tests.rest.bwcsuite_round', 'third' + systemProperty 'tests.plugin_bwc_version', bwcVersion + 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".upgradeAllNodesAndPluginsToNextVersion(plugins) + } + filter { + includeTestsMatching "org.opensearch.index.codecs.customcodecs.bwc.*IT" + } + systemProperty 'tests.rest.bwcsuite', 'upgraded_cluster' + systemProperty 'tests.plugin_bwc_version', bwcVersion + 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") +} + +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 +} + tasks.withType(PublishToMavenRepository) { def predicate = provider { publication.name == "pluginZip" diff --git a/scripts/bwctest.sh b/scripts/bwctest.sh new file mode 100644 index 0000000..6361e38 --- /dev/null +++ b/scripts/bwctest.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -e + +function usage() { + echo "" + echo "This script is used to run Backwards Compatibility tests" + echo "--------------------------------------------------------------------------" + echo "Usage: $0 [args]" + echo "" + echo "Required arguments:" + echo "None" + echo "" + echo -e "-h\tPrint this message." + echo "--------------------------------------------------------------------------" +} + +while getopts ":h" arg; do + case $arg in + h) + usage + exit 1 + ;; + ?) + echo "Invalid option: -${OPTARG}" + exit 1 + ;; + esac +done + +./gradlew bwcTestSuite -Dtests.security.manager=false \ No newline at end of file diff --git a/src/test/java/org/opensearch/index/codec/customcodecs/bwc/SampleBWCIT.java b/src/test/java/org/opensearch/index/codec/customcodecs/bwc/SampleBWCIT.java new file mode 100644 index 0000000..6b8c1c6 --- /dev/null +++ b/src/test/java/org/opensearch/index/codec/customcodecs/bwc/SampleBWCIT.java @@ -0,0 +1,83 @@ +package org.opensearch.index.codec.customcodecs.bwc; + +import org.junit.Before; +import org.opensearch.common.settings.Settings; +import org.opensearch.test.rest.OpenSearchRestTestCase; + +import java.util.ArrayList; +import java.util.List; + +public class SampleBWCIT extends OpenSearchRestTestCase { + + private static final ClusterType CLUSTER_TYPE = ClusterType.parse(System.getProperty("tests.rest.bwcsuite")); +// private static final String CLUSTER_NAME = System.getProperty("tests.clustername"); +// private static final String MIXED_CLUSTER_TEST_ROUND = System.getProperty("tests.rest.bwcsuite_round"); + private String dataIndexName = "test_data_for_ad_plugin"; + private int detectionIntervalInMinutes = 1; + private int windowDelayIntervalInMinutes = 1; + private String aggregationMethod = "sum"; + private int totalDocsPerCategory = 10_000; + private int categoryFieldSize = 2; + private List runningRealtimeDetectors; + private List historicalDetectors; + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + this.runningRealtimeDetectors = new ArrayList<>(); + this.historicalDetectors = new ArrayList<>(); + } + + @Override + protected final boolean preserveIndicesUponCompletion() { + return true; + } + + @Override + protected final boolean preserveReposUponCompletion() { + return true; + } + + @Override + protected boolean preserveTemplatesUponCompletion() { + return true; + } + + @Override + protected final Settings restClientSettings() { + return Settings + .builder() + .put(super.restClientSettings()) + // increase the timeout here to 90 seconds to handle long waits for a green + // cluster health. the waits for green need to be longer than a minute to + // account for delayed shards + .put(OpenSearchRestTestCase.CLIENT_SOCKET_TIMEOUT, "90s") + .build(); + } + + private enum ClusterType { + OLD, + MIXED, + UPGRADED; + + public static ClusterType parse(String value) { + switch (value) { + case "old_cluster": + return OLD; + case "mixed_cluster": + return MIXED; + case "upgraded_cluster": + return UPGRADED; + default: + throw new AssertionError("unknown cluster type: " + value); + } + } + } + + + @SuppressWarnings("unchecked") + public void testBackwardsCompatibility() throws Exception { + logger.info("Cluster type ::: -> " + CLUSTER_TYPE); + } +}