diff --git a/tests/data/opensearch-dashboards-1.3.0-test.yml b/tests/data/opensearch-dashboards-1.3.0-test.yml new file mode 100644 index 000000000..c26a0c3c0 --- /dev/null +++ b/tests/data/opensearch-dashboards-1.3.0-test.yml @@ -0,0 +1,14 @@ +--- +schema-version: '1.0' +name: OpenSearch Dashboards +components: + - name: functionalTestDashboards + integ-test: + test-configs: + - with-security + - without-security + - name: queryWorkbenchDashboards + bwc-test: + test-configs: + - with-security + - without-security diff --git a/tests/jenkins/TestCreateUploadTestReportManifest.groovy b/tests/jenkins/TestCreateUploadTestReportManifest.groovy new file mode 100644 index 000000000..337e1c70e --- /dev/null +++ b/tests/jenkins/TestCreateUploadTestReportManifest.groovy @@ -0,0 +1,47 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package jenkins.tests + +import org.junit.Test +import static com.lesfurets.jenkins.unit.MethodCall.callArgsToString +import static org.hamcrest.CoreMatchers.hasItems +import static org.hamcrest.MatcherAssert.assertThat + + +class TestCreateUploadTestReportManifest extends BuildPipelineTest { + + @Test + public void TestCreateUploadTestReportManifest() { + this.registerLibTester(new CreateUploadTestReportManifestLibTester( + 'tests/data/opensearch-1.3.0-test.yml', + 'tests/data/opensearch-1.3.0-build.yml', + 'tests/data/opensearch-dashboards-build-1.3.0.yml', + '1234', + 'integ-test', + '', + ) + ) + super.setUp() + super.testPipeline("tests/jenkins/jobs/CreateUploadTestReportManifest_Jenkinsfile") + assertThat(getShellCommands('sh', 'report.sh'), hasItems('./report.sh tests/data/opensearch-1.3.0-test.yml --artifact-paths opensearch=https://ci.opensearch.org/ci/dbc/distribution-build-opensearch/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar --test-run-id 1234 --test-type integ-test --base-path DUMMY_PUBLIC_ARTIFACT_URL/dummy_integ_test/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar ')) + assertThat(getShellCommands('sh', 'report.sh'), hasItems('./report.sh tests/data/opensearch-dashboards-1.3.0-test.yml --artifact-paths opensearch=https://ci.opensearch.org/ci/dbc/distribution-build-opensearch/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar opensearch-dashboards=https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.0/25b38c278cdd45efa583765d8ba76346/linux/x64/tar --test-run-id 1234 --test-type integ-test --base-path DUMMY_PUBLIC_ARTIFACT_URL/dummy_integ_test/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar ')) + } + + def getShellCommands(methodName, searchString) { + def shCommands = helper.callStack.findAll { call -> + call.methodName == methodName + }.collect { call -> + callArgsToString(call) + }.findAll { command -> + command.contains(searchString) + } + return shCommands + } +} diff --git a/tests/jenkins/jobs/CreateUploadTestReportManifest_Jenkinsfile b/tests/jenkins/jobs/CreateUploadTestReportManifest_Jenkinsfile new file mode 100644 index 000000000..a7bc749a1 --- /dev/null +++ b/tests/jenkins/jobs/CreateUploadTestReportManifest_Jenkinsfile @@ -0,0 +1,33 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +pipeline { + agent none + stages { + stage('create-test-run-manifest') { + steps { + script { + createUploadTestReportManifest( + testManifest: "tests/data/opensearch-1.3.0-test.yml", + buildManifest: "tests/data/opensearch-1.3.0-build.yml", + testRunID: "1234", + testType: "integ-test", + ) + createUploadTestReportManifest( + testManifest: "tests/data/opensearch-dashboards-1.3.0-test.yml", + buildManifest: "tests/data/opensearch-1.3.0-build.yml", + dashboardsBuildManifest: "tests/data/opensearch-dashboards-build-1.3.0.yml", + testRunID: "1234", + testType: "integ-test", + ) + } + } + } + } +} diff --git a/tests/jenkins/jobs/CreateUploadTestReportManifest_Jenkinsfile.txt b/tests/jenkins/jobs/CreateUploadTestReportManifest_Jenkinsfile.txt new file mode 100644 index 000000000..599c9d646 --- /dev/null +++ b/tests/jenkins/jobs/CreateUploadTestReportManifest_Jenkinsfile.txt @@ -0,0 +1,56 @@ + CreateUploadTestReportManifest_Jenkinsfile.run() + CreateUploadTestReportManifest_Jenkinsfile.pipeline(groovy.lang.Closure) + CreateUploadTestReportManifest_Jenkinsfile.echo(Executing on agent [label:none]) + CreateUploadTestReportManifest_Jenkinsfile.stage(create-test-run-manifest, groovy.lang.Closure) + CreateUploadTestReportManifest_Jenkinsfile.script(groovy.lang.Closure) + CreateUploadTestReportManifest_Jenkinsfile.createUploadTestReportManifest({testManifest=tests/data/opensearch-1.3.0-test.yml, buildManifest=tests/data/opensearch-1.3.0-build.yml, testRunID=1234, testType=integ-test}) + createUploadTestReportManifest.legacySCM(groovy.lang.Closure) + createUploadTestReportManifest.library({identifier=jenkins@main, retriever=null}) + createUploadTestReportManifest.readYaml({file=tests/data/opensearch-1.3.0-test.yml}) + TestManifest.asBoolean() + createUploadTestReportManifest.readYaml({file=tests/data/opensearch-1.3.0-build.yml}) + BuildManifest.asBoolean() + BuildManifest.getDistribution() + createUploadTestReportManifest.echo(Start Reporting workflow for test type: tar) + BuildManifest.getArtifactRootUrl(distribution-build-opensearch, c3ff7a232d25403fa8cc14c97799c323) + createUploadTestReportManifest.echo(Artifact root URL: https://ci.opensearch.org/ci/dbc/distribution-build-opensearch/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar) + createUploadTestReportManifest.echo(Paths: opensearch=https://ci.opensearch.org/ci/dbc/distribution-build-opensearch/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar) + createUploadTestReportManifest.echo(Base Path DUMMY_PUBLIC_ARTIFACT_URL/dummy_integ_test/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar) + createUploadTestReportManifest.echo(Component: null) + createUploadTestReportManifest.echo(Run command: ./report.sh tests/data/opensearch-1.3.0-test.yml --artifact-paths opensearch=https://ci.opensearch.org/ci/dbc/distribution-build-opensearch/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar --test-run-id 1234 --test-type integ-test --base-path DUMMY_PUBLIC_ARTIFACT_URL/dummy_integ_test/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar ) + createUploadTestReportManifest.sh(./report.sh tests/data/opensearch-1.3.0-test.yml --artifact-paths opensearch=https://ci.opensearch.org/ci/dbc/distribution-build-opensearch/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar --test-run-id 1234 --test-type integ-test --base-path DUMMY_PUBLIC_ARTIFACT_URL/dummy_integ_test/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar ) + createUploadTestReportManifest.echo(Build Id: c3ff7a232d25403fa8cc14c97799c323) + BuildManifest.getArtifactRoot(dummy_integ_test, c3ff7a232d25403fa8cc14c97799c323) + createUploadTestReportManifest.string({credentialsId=jenkins-artifact-bucket-name, variable=ARTIFACT_BUCKET_NAME}) + createUploadTestReportManifest.string({credentialsId=jenkins-aws-account-public, variable=AWS_ACCOUNT_PUBLIC}) + createUploadTestReportManifest.withCredentials([ARTIFACT_BUCKET_NAME, AWS_ACCOUNT_PUBLIC], groovy.lang.Closure) + createUploadTestReportManifest.echo(Uploading to s3://dummy_integ_test/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar/test-results/1234/integ-test/test-report.yml) + createUploadTestReportManifest.withAWS({role=opensearch-test, roleAccount=AWS_ACCOUNT_PUBLIC, duration=900, roleSessionName=jenkins-session}, groovy.lang.Closure) + createUploadTestReportManifest.s3Upload({file=/tmp/workspace/test-report.yml, bucket=ARTIFACT_BUCKET_NAME, path=dummy_integ_test/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar/test-results/1234/integ-test/test-report.yml}) + CreateUploadTestReportManifest_Jenkinsfile.createUploadTestReportManifest({testManifest=tests/data/opensearch-dashboards-1.3.0-test.yml, buildManifest=tests/data/opensearch-1.3.0-build.yml, dashboardsBuildManifest=tests/data/opensearch-dashboards-build-1.3.0.yml, testRunID=1234, testType=integ-test}) + createUploadTestReportManifest.legacySCM(groovy.lang.Closure) + createUploadTestReportManifest.library({identifier=jenkins@main, retriever=null}) + createUploadTestReportManifest.readYaml({file=tests/data/opensearch-dashboards-1.3.0-test.yml}) + TestManifest.asBoolean() + createUploadTestReportManifest.readYaml({file=tests/data/opensearch-1.3.0-build.yml}) + BuildManifest.asBoolean() + createUploadTestReportManifest.readYaml({file=tests/data/opensearch-dashboards-build-1.3.0.yml}) + BuildManifest.asBoolean() + BuildManifest.getDistribution() + createUploadTestReportManifest.echo(Start Reporting workflow for test type: tar) + BuildManifest.getArtifactRootUrl(distribution-build-opensearch, c3ff7a232d25403fa8cc14c97799c323) + BuildManifest.getArtifactRootUrl(distribution-build-opensearch-dashboards, 25b38c278cdd45efa583765d8ba76346) + createUploadTestReportManifest.echo(Artifact root URL: https://ci.opensearch.org/ci/dbc/distribution-build-opensearch/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar) + createUploadTestReportManifest.echo(Paths: opensearch=https://ci.opensearch.org/ci/dbc/distribution-build-opensearch/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar opensearch-dashboards=https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.0/25b38c278cdd45efa583765d8ba76346/linux/x64/tar) + createUploadTestReportManifest.echo(Base Path DUMMY_PUBLIC_ARTIFACT_URL/dummy_integ_test/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar) + createUploadTestReportManifest.echo(Component: null) + createUploadTestReportManifest.echo(Run command: ./report.sh tests/data/opensearch-dashboards-1.3.0-test.yml --artifact-paths opensearch=https://ci.opensearch.org/ci/dbc/distribution-build-opensearch/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar opensearch-dashboards=https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.0/25b38c278cdd45efa583765d8ba76346/linux/x64/tar --test-run-id 1234 --test-type integ-test --base-path DUMMY_PUBLIC_ARTIFACT_URL/dummy_integ_test/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar ) + createUploadTestReportManifest.sh(./report.sh tests/data/opensearch-dashboards-1.3.0-test.yml --artifact-paths opensearch=https://ci.opensearch.org/ci/dbc/distribution-build-opensearch/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar opensearch-dashboards=https://ci.opensearch.org/ci/dbc/distribution-build-opensearch-dashboards/1.3.0/25b38c278cdd45efa583765d8ba76346/linux/x64/tar --test-run-id 1234 --test-type integ-test --base-path DUMMY_PUBLIC_ARTIFACT_URL/dummy_integ_test/1.3.0/c3ff7a232d25403fa8cc14c97799c323/linux/x64/tar ) + createUploadTestReportManifest.echo(Build Id: 25b38c278cdd45efa583765d8ba76346) + BuildManifest.getArtifactRoot(dummy_integ_test, 25b38c278cdd45efa583765d8ba76346) + createUploadTestReportManifest.string({credentialsId=jenkins-artifact-bucket-name, variable=ARTIFACT_BUCKET_NAME}) + createUploadTestReportManifest.string({credentialsId=jenkins-aws-account-public, variable=AWS_ACCOUNT_PUBLIC}) + createUploadTestReportManifest.withCredentials([ARTIFACT_BUCKET_NAME, AWS_ACCOUNT_PUBLIC], groovy.lang.Closure) + createUploadTestReportManifest.echo(Uploading to s3://dummy_integ_test/1.3.0/25b38c278cdd45efa583765d8ba76346/linux/x64/tar/test-results/1234/integ-test/test-report.yml) + createUploadTestReportManifest.withAWS({role=opensearch-test, roleAccount=AWS_ACCOUNT_PUBLIC, duration=900, roleSessionName=jenkins-session}, groovy.lang.Closure) + createUploadTestReportManifest.s3Upload({file=/tmp/workspace/test-report.yml, bucket=ARTIFACT_BUCKET_NAME, path=dummy_integ_test/1.3.0/25b38c278cdd45efa583765d8ba76346/linux/x64/tar/test-results/1234/integ-test/test-report.yml}) diff --git a/tests/jenkins/lib-testers/CreateUploadTestReportManifestLibTest.groovy b/tests/jenkins/lib-testers/CreateUploadTestReportManifestLibTest.groovy new file mode 100644 index 000000000..860cdced8 --- /dev/null +++ b/tests/jenkins/lib-testers/CreateUploadTestReportManifestLibTest.groovy @@ -0,0 +1,62 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +import static org.hamcrest.CoreMatchers.notNullValue +import static org.hamcrest.MatcherAssert.assertThat + + +class CreateUploadTestReportManifestLibTester extends LibFunctionTester { + + private String testType + private String componentName + private String buildManifest + private String testManifest + private String buildManifestDashboards + private String testRunID + + public CreateUploadTestReportManifestLibTester(testManifest, buildManifest, buildManifestDashboards, testRunID, testType, componentName){ + this.testManifest = testManifest + this.buildManifest = buildManifest + this.buildManifestDashboards = buildManifestDashboards + this.testRunID = testRunID + this.testType = testType + this.componentName = componentName + } + + void configure(helper, binding) { + binding.setVariable('env', ['JOB_NAME': 'dummy_integ_test', 'BUILD_NUMBER': '487', 'PUBLIC_ARTIFACT_URL': 'DUMMY_PUBLIC_ARTIFACT_URL' ]) + helper.registerAllowedMethod("withCredentials", [Map, Closure], { args, closure -> + closure.delegate = delegate + return helper.callClosure(closure) + }) + helper.registerAllowedMethod("withAWS", [Map, Closure], { args, closure -> + closure.delegate = delegate + return helper.callClosure(closure) + }) + helper.registerAllowedMethod("s3Upload", [Map]) + } + + void parameterInvariantsAssertions(call) { + assertThat(call.args.testManifest.first(), notNullValue()) + assertThat(call.args.buildManifest.first(), notNullValue()) + assertThat(call.args.testRunID.first(), notNullValue()) + assertThat(call.args.testType.first(), notNullValue()) + } + + boolean expectedParametersMatcher(call) { + return call.args.testManifest.first().toString().equals(this.testManifest) + && call.args.buildManifest.first().toString().equals(this.buildManifest) + && call.args.testRunID.first().toString().equals(this.testRunID) + && call.args.testType.first().toString().equals(this.testType) + } + + String libFunctionName() { + return 'createUploadTestReportManifest' + } +} diff --git a/vars/createUploadTestReportManifest.groovy b/vars/createUploadTestReportManifest.groovy new file mode 100644 index 000000000..113992d59 --- /dev/null +++ b/vars/createUploadTestReportManifest.groovy @@ -0,0 +1,122 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +/** Library to run the report workflow to generate test-report manifest. + @param Map args = [:] args A map of the following parameters + @param args.testManifest - The path of the test manifest used + @param args.buildManifest - The path of the build manifest of OpenSearch artifacts. + @param args.dashboardsBuildManifest - The path of the build manifest of OpenSearch Dashboards + @param args.testRunID - Test run id of the test workflow being reported. + @param args.testType - Type of the test workflow being reported. + @param args.componentName - Components that workflow runs on. + */ + +def call(Map args = [:]) { + lib = library(identifier: 'jenkins@main', retriever: legacySCM(scm)) + + if (!parameterCheck(args.testManifest, args.buildManifest, args.testRunID, args.testType)) return null + + def testRunID = args.testRunID; + def testType = args.testType; + + def testManifest = lib.jenkins.TestManifest.new(readYaml(file: args.testManifest)) + def buildManifest = lib.jenkins.BuildManifest.new(readYaml(file: args.buildManifest)) + def dashboardsBuildManifest = args.dashboardsBuildManifest ? lib.jenkins.BuildManifest.new(readYaml(file: args.dashboardsBuildManifest)) : null; + + echo "Start Reporting workflow for test type: " + buildManifest.getDistribution() + + String paths = generatePaths(testManifest, buildManifest, dashboardsBuildManifest) + echo "Paths: ${paths}" + + String basePath = generateBasePaths(buildManifest) + echo "Base Path ${basePath}" + + String component = args.componentName + echo "Component: ${component}" + + String reportCommand = + [ + './report.sh', + "${args.testManifest}", + "--artifact-paths ${paths}", + "--test-run-id ${testRunID}", + "--test-type ${testType}", + "--base-path ${basePath}", + isNullOrEmpty(component) ? "" : "--component ${component}", + ].join(' ') + + echo "Run command: " + reportCommand + sh(reportCommand) + + String finalUploadPath = generateUploadPath(testManifest, buildManifest, dashboardsBuildManifest, testRunID) + withCredentials([ + string(credentialsId: 'jenkins-artifact-bucket-name', variable: 'ARTIFACT_BUCKET_NAME'), + string(credentialsId: 'jenkins-aws-account-public', variable: 'AWS_ACCOUNT_PUBLIC')]) { + echo "Uploading to s3://${finalUploadPath}" + + withAWS(role: 'opensearch-test', roleAccount: "${AWS_ACCOUNT_PUBLIC}", duration: 900, roleSessionName: 'jenkins-session') { + s3Upload(file: "$WORKSPACE/test-report.yml", bucket: "${ARTIFACT_BUCKET_NAME}", path: finalUploadPath) + } + } +} + +String generatePaths(testManifest, buildManifest, dashboardsBuildManifest) { + String buildId = buildManifest.build.id + String artifactRootUrl = buildManifest.getArtifactRootUrl('distribution-build-opensearch', buildId) + + String artifactRootUrlDashboards + if (dashboardsBuildManifest != null) { + String buildIdDashboards = dashboardsBuildManifest.build.id + artifactRootUrlDashboards = dashboardsBuildManifest.getArtifactRootUrl('distribution-build-opensearch-dashboards', buildIdDashboards) + } + + echo "Artifact root URL: ${artifactRootUrl}" + + return !artifactRootUrlDashboards ? + "opensearch=${artifactRootUrl}" : + "opensearch=${artifactRootUrl} opensearch-dashboards=${artifactRootUrlDashboards}" + +} + +String generateBasePaths(buildManifest) { + return ["${env.PUBLIC_ARTIFACT_URL}", "${env.JOB_NAME}", buildManifest.build.version, buildManifest.build.id, buildManifest.build.platform, buildManifest.build.architecture, buildManifest.build.distribution].join("/") +} + +String generateUploadPath(testManifest, buildManifest, dashboardsBuildManifest, testRunID) { + def product = testManifest.name + def productBuildManifest = (product.equals("OpenSearch")) ? buildManifest : dashboardsBuildManifest + + String buildId = productBuildManifest.build.id + echo "Build Id: ${buildId}" + + def artifactPath = productBuildManifest.getArtifactRoot("${env.JOB_NAME}", buildId) + return [artifactPath, "test-results", testRunID, "integ-test", "test-report.yml"].join("/") +} + +boolean isNullOrEmpty(String str) { return (str == null || str.allWhitespace || str.isEmpty()) } + +boolean parameterCheck(String testManifest, String buildManifest, String testRunID, String testType) { + if (isNullOrEmpty(testManifest)) { + print("Required argument testManifest is null or empty. Skip running report workflow.") + return false + } + if (isNullOrEmpty(buildManifest)) { + print("Required argument buildManifest is null or empty. Skip running report workflow.") + return false + } + if (isNullOrEmpty(testRunID)) { + print("Required argument testRunID is null or empty. Skip running report workflow.") + return false + } + if (isNullOrEmpty(testType)) { + print("Required argument testType is null or empty. Skip running report workflow.") + return false + } + return true +}