diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml index 8c14f3c4d..9db653166 100644 --- a/.github/workflows/continuous-integration-workflow.yml +++ b/.github/workflows/continuous-integration-workflow.yml @@ -165,10 +165,10 @@ jobs: name: Checkout repository uses: actions/checkout@v4.1.7 - - name: Setup Go 1.18 + name: Setup Go 1.23 uses: actions/setup-go@v5 with: - go-version: 1.18 + go-version: 1.23 - name: Verify all Go files are formatted with gofmt working-directory: tests @@ -186,7 +186,7 @@ jobs: name: Verify all Go tests pass linting uses: golangci/golangci-lint-action@v6 with: - version: v1.49.0 + version: v1.60.1 working-directory: tests args: --timeout=10m - diff --git a/CHANGELOG.md b/CHANGELOG.md index bd841c73a..3d1e2ce5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Webhook Proxy maintenance ([#1298](https://github.com/opendevstack/ods-core/pull/1298)) - Update SonarQube to 10.x non LTS ([#1300](https://github.com/opendevstack/ods-core/issues/1300)) - Jenkins maintenance ([#1299](https://github.com/opendevstack/ods-core/pull/1299)) and update java version in Jenkins ([#1295](https://github.com/opendevstack/ods-core/issues/1295)) +- Update and fix golden tests ([#1233](https://github.com/opendevstack/ods-core/issues/1233)) ### Fixed diff --git a/tests/Jenkinsfile b/tests/Jenkinsfile new file mode 100644 index 000000000..743f0eefa --- /dev/null +++ b/tests/Jenkinsfile @@ -0,0 +1,181 @@ +properties([ + parameters([ + string( + name: 'Quickstarter', + description: 'Enter the quickstarter name which is to be tested. Use "all" to test all the quickstarters together' + ), + string( + name: 'QuickstarterRepository', + defaultValue: 'ods-quickstarters', + description: 'Enter the repository name for the quickstarter which is to be tested' + ), + string( + name: 'quickstarterRef', + defaultValue: '4.x', + description: 'Enter the reference for the quickstarter (e.g., branch, tag, or commit)' + ), + string( + name: 'configurationRef', + defaultValue: 'master', + description: 'Enter the reference for the configuration (e.g., branch, tag, or commit)' + ), + string( + name: 'Project', + description: 'Enter the project name (in lower case) where the quickstarter will be provisioned' + ), + string( + name: 'ODS_NAMESPACE', + defaultValue: 'ods', + description: 'Enter the ods namespae to fetch the jenkins agent. Include "-cd" if the ODS Namespace is not ods as default' + ), + string( + name: 'ODS_URL', + defaultValue: 'https://github.com/opendevstack', + description: 'Enter the whole URL of the ODS files (https included)' + ), + string( + name: 'JENKINS_AGENT_TAG', + defaultValue: '4.x', + description: 'Enter the tag for the jenkins golang agent' + ), + string( + name: 'SONAR_QUALITY_PROFILE', + description: 'Enter the tag for the jenkins golang agent' + ), + text( + name: 'excludedQuickstarters', + defaultValue: '''inf-terraform-aws +inf-terraform-azure +ods-document-gen-svc +ods-provisioning-app +release-manager +ds-jupyter-lab +ds-rshiny''', + description: 'Enter the list of excluded quickstarters, one per line' + ) + ]), + disableConcurrentBuilds(), + buildDiscarder(logRotator(numToKeepStr: '10')), +]) + +// The project that we will use to test the quickstarters +def project = params.Project +// The Quickstarter to test +def quickstarter = params.Quickstarter +// Namespace fo the cd project +def odsNamespace = params.ODS_NAMESPACE +// odsReference +def odsRef = params.quickstarterRef?:"master" +// configurationReference +def confRef = params.configurationRef?:"master" +// QS repo +def QUICKSTARTER_REPO = params.QuickstarterRepository + +// URIS of the repositories used +def QUICK_STARTERS_URL = "${ODS_URL}/${QUICKSTARTER_REPO}.git" +def QUICK_STARTERS_BRANCH = "${quickstarterRef}" + +def ODS_CONFIGURATION_URL = "${ODS_URL}/ods-configuration.git" +def ODS_CONFIGURATION_BRANCH = "${confRef}" + +def ODS_CORE_URL = "${ODS_URL}/ods-core.git" +def ODS_CORE_BRANCH = "${quickstarterRef}" + +def JENKINS_AGENT_TAG = "${JENKINS_AGENT_TAG}" +def SONAR_QUALITY_PROFILE = "${SONAR_QUALITY_PROFILE}" + +// List of QS that we want to exclude from the execution of the job. +def excludedQS = params.excludedQuickstarters?:'' + + +echo "QUICKSTARTER_REPO : ${QUICKSTARTER_REPO}" + +// Jenkins DeploymentConfig environment variables +def dockerRegistry +node { + dockerRegistry = env.DOCKER_REGISTRY +} + +// We need a golang version >= 17, so if we don't have one we need to build it. +// trigger pipeline + +def conts = containerTemplate( + name: 'jnlp', + image: "${dockerRegistry}/${odsNamespace}/jenkins-agent-golang:${JENKINS_AGENT_TAG}", + workingDir: '/tmp', + alwaysPullImage: true, + args: '' +) +def podLabel = "qs-tests" + +podTemplate( + label: podLabel, + cloud: 'openshift', + containers: [conts], + volumes: [], + serviceAccount: 'jenkins' +) { + node(podLabel) { + + stage('Init') { + currentBuild.description = "Testing QS" + + dir("${QUICKSTARTER_REPO}"){ + git branch: "${QUICK_STARTERS_BRANCH}", + credentialsId: "${project}-cd-cd-user-with-password", + url: "${QUICK_STARTERS_URL}" + } + dir('ods-configuration'){ + git branch: "${ODS_CONFIGURATION_BRANCH}", + credentialsId: "${project}-cd-cd-user-with-password", + url: "${ODS_CONFIGURATION_URL}" + } + + dir('ods-core'){ + git branch: "${ODS_CORE_BRANCH}", + credentialsId: "${project}-cd-cd-user-with-password", + url: "${ODS_CORE_URL}" + + // Write the file used to exclude Quickstarters in the tests + echo "Writing file quickStartersExclusionList.txt" + writeFile file: './tests/quickStartersExclusionList.txt', text: excludedQS + } + } + + stage('Test') { + echo "${WORKSPACE}" + + // If we select 'all' no one parameter will be provided, so it will try to test all the Quickstarters + // that have a test defined in the testdata folder. + def quickstarter_to_test = "" + quickstarter_to_test = "-q ${quickstarter}" + + echo "QUICKSTARTER TO TEST : ${quickstarter_to_test}" + echo "QUICKSTARTER REPO : ${QUICKSTARTER_REPO}" + echo "Project : ${project}" + + // In different environments SONAR_QUALITY_PROFILE can be different, with this env variable we provide + // the needed value + withEnv([ + "CGO_ENABLED=0", + "GOMODCACHE=${WORKSPACE}/.cache", + "SONAR_QUALITY_PROFILE=${SONAR_QUALITY_PROFILE}", + "ODS_GIT_REF=${odsRef}"]) { + sh """ + cd ods-core/tests + ls -lrta + ./quickstarter-test.sh -p ${project} -qf "${QUICKSTARTER_REPO}/..." ${quickstarter_to_test} || true + """ + } + + } + + stage('Get test results') { + archiveArtifacts artifacts: 'ods-core/tests/*.txt', followSymlinks: false + archiveArtifacts artifacts: 'ods-core/tests/test-quickstarter-report.xml', followSymlinks: false + junit(testResults:"ods-core/tests/test-quickstarter-report.xml", allowEmptyResults:true) + + } + } +} + diff --git a/tests/Makefile b/tests/Makefile index 56fa45058..1188a83f5 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -7,8 +7,16 @@ MAKEFLAGS += --no-builtin-rules ### By default we test all quickstarters located in ods-quickstarters QS := ods-quickstarters/... +# Load environment variables from .env file +include ../../ods-configuration/ods-core.env +export $(shell sed 's/=.*//' ../../ods-configuration/ods-core.env) + ### By default we do not parallelize tests PARALLEL := 1 +PROJECT := unitt +SONAR_PROFILE := "Sonar way" +QUICKSTARTER_REPOSITORY := ods-quickstarters +configurationRef := master ## Full test of existing ODS core installation. Caution: Creates UNITT project and ODSVERIFY project. test: smoketest verify test-create-projects @@ -33,21 +41,28 @@ test-create-projects: @(./create-projects-test.sh) .PHONY: test-create-projects -## Run quickstarter tests within existing ODS installation. Depends on UNITT project. +## Create Jenkins pipeline using REST API +jenkins-pipeline: + @(envsubst < jenkinsPipelineCreation.sh) + @(./jenkinsPipelineCreation.sh -p $(PROJECT) -q $(QUICKSTARTER_REPOSITORY) -s $(SONAR_PROFILE) -c $(configurationRef)) +.PHONY: jenkins-pipeline + +## Run quickstarter tests within existing ODS installation. Depends on UNITT project (default). test-quickstarter: - @(./quickstarter-test.sh $(QS) $(PARALLEL)) + @(./quickstarter-test.sh -p $(PROJECT) -q $(QS) -pa $(PARALLEL)) .PHONY: test-quickstarter ## Install tools required for tests. prep-tools: which go-junit-report || go get github.com/jstemmer/go-junit-report + which golangci-lint || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.60.1 .PHONY: prep-tools ## Lint lint: echo "Checking code ..." golangci-lint --version - golangci-lint run --go=1.18 + golangci-lint run --go=1.23 .PHONY: lint ### HELP diff --git a/tests/go.mod b/tests/go.mod index 2a00fafd6..cd179ed50 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -1,33 +1,44 @@ module github.com/opendevstack/ods-core/tests -go 1.13 +go 1.23 require ( github.com/ghodss/yaml v1.0.0 - github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/go-cmp v0.5.1 + github.com/jstemmer/go-junit-report v0.9.1 + github.com/openshift/api v0.0.0-20180801171038-322a19404e37 + github.com/openshift/client-go v3.9.0+incompatible + k8s.io/api v0.0.0-20190222213804-5cb15d344471 + k8s.io/apimachinery v0.0.0-20190221213512-86fb29eff628 + k8s.io/client-go v0.0.0-20190228174230-b40b2a5939e4 +) + +require ( + github.com/gogo/protobuf v1.3.1 // indirect github.com/golang/protobuf v1.4.2 // indirect github.com/google/btree v1.0.0 // indirect - github.com/google/go-cmp v0.5.1 + github.com/google/gofuzz v1.0.0 // indirect github.com/googleapis/gnostic v0.4.0 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/imdario/mergo v0.3.8 // indirect github.com/json-iterator/go v1.1.8 // indirect - github.com/jstemmer/go-junit-report v0.9.1 github.com/kr/pretty v0.2.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.1 // indirect - github.com/openshift/api v0.0.0-20180801171038-322a19404e37 - github.com/openshift/client-go v3.9.0+incompatible github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/crypto v0.17.0 // indirect + golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/term v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect + google.golang.org/appengine v1.4.0 // indirect + google.golang.org/protobuf v1.23.0 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.2.7 // indirect - k8s.io/api v0.0.0-20190222213804-5cb15d344471 - k8s.io/apimachinery v0.0.0-20190221213512-86fb29eff628 - k8s.io/client-go v0.0.0-20190228174230-b40b2a5939e4 k8s.io/klog v1.0.0 // indirect sigs.k8s.io/yaml v1.1.0 // indirect ) diff --git a/tests/go.sum b/tests/go.sum index 0e4ed6ee5..2ca0ca9ed 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -6,8 +6,8 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3 github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -36,7 +36,7 @@ github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46O github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -61,75 +61,27 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6 h1:pE8b58s1HRDMi8RDc79m0HISf9D4TzseP40cEA6IGfs= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/tests/golden-test-pipeline.yml b/tests/golden-test-pipeline.yml new file mode 100644 index 000000000..e5ecd571f --- /dev/null +++ b/tests/golden-test-pipeline.yml @@ -0,0 +1,76 @@ +apiVersion: template.openshift.io/v1 +kind: Template +parameters: + - name: PROJECT + displayName: Application + description: The name of the application project. + required: true + - name: ODS_GIT_REF + displayName: Git branch + description: The git branch to use for the pipeline. + required: true + - name: ODS_IMAGE_TAG + displayName: Agent tag + description: The tag for the jenkins golang agent. + required: true + - name: ODS_NAMESPACE + displayName: ODS namespace + description: The ods namespae to fetch the jenkins agent. Include "-cd" if the ODS Namespace is not ods as default + required: true + - name: BITBUCKET_URL + displayName: Bitbucket server URL + description: The Bitbucket server URL. + required: true + - name: ODS_BITBUCKET_PROJECT + displayName: ODS Bitbucket project + description: The ODS Bitbucket project. + required: true + - name: SONAR_QUALITY_PROFILE + displayName: SonarQube Quality Profile + description: SonarQube Quality Profile. + required: true + - name: QuickstarterRepository + displayName: Quickstarter repository + description: Quickstarter repository. + required: true +objects: + - apiVersion: build.openshift.io/v1 + kind: BuildConfig + metadata: + labels: + template: golden-test-pipeline + name: '${PROJECT}-golden-test' + spec: + failedBuildsHistoryLimit: 5 + runPolicy: Serial + source: + git: + ref: ${ODS_GIT_REF} + uri: '${BITBUCKET_URL}/scm/${ODS_BITBUCKET_PROJECT}/ods-core.git' + sourceSecret: + name: cd-user-with-password + type: Git + strategy: + jenkinsPipelineStrategy: + env: + - name: Quickstarter + value: '' + - name: QuickstarterRepository + value: '${QuickstarterRepository}' + - name: quickstarterRef + value: '${ODS_GIT_REF}' + - name: Project + value: '${PROJECT}' + - name: ODS_NAMESPACE + value: '${ODS_NAMESPACE}' + - name: ODS_URL + value: '${BITBUCKET_URL}/scm/${ODS_BITBUCKET_PROJECT}' + - name: JENKINS_AGENT_TAG + value: '${ODS_IMAGE_TAG}' + - name: SONAR_QUALITY_PROFILE + value: '${SONAR_QUALITY_PROFILE}' + - name: excludedQuickstarters + value: '' + jenkinsfilePath: tests/Jenkinsfile + type: JenkinsPipeline + successfulBuildsHistoryLimit: 5 \ No newline at end of file diff --git a/tests/jenkinsPipelineCreation.sh b/tests/jenkinsPipelineCreation.sh new file mode 100644 index 000000000..9938d1d40 --- /dev/null +++ b/tests/jenkinsPipelineCreation.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +set -eux + +PROJECT="" +QuickstarterRepository="" +configurationRef="" +SONAR_QUALITY_PROFILE="" +ODS_GIT_REF="$ODS_GIT_REF" +BITBUCKET_URL="$BITBUCKET_URL" +ODS_NAMESPACE="$ODS_NAMESPACE" +ODS_IMAGE_TAG="$ODS_IMAGE_TAG" +ODS_BITBUCKET_PROJECT="$ODS_BITBUCKET_PROJECT" + +# Override ods configuration (optional) +while [[ "$#" > 0 ]]; do case $1 in + -g=*|--ods-git-ref=*) ODS_GIT_REF="${1#*=}";; + -g|--ods-git-ref) ODS_GIT_REF="$2"; shift;; + + -c=*|--configurationRef=*) configurationRef="${1#*=}";; + -c|--configurationRef) configurationRef="$2"; shift;; + + -b=*|--bitbucket=*) BITBUCKET_URL="${1#*=}";; + -b|--bitbucket) BITBUCKET_URL="$2"; shift;; + + -n=*|--ods-namespace=*) ODS_NAMESPACE="${1#*=}";; + -n|--ods-namespace) ODS_NAMESPACE="$2"; shift;; + + -i=*|--ods-image-tag=*) ODS_IMAGE_TAG="${1#*=}";; + -i|--ods-image-tag) ODS_IMAGE_TAG="$2"; shift;; + + -m=*|--bitbucket-ods-project=*) ODS_BITBUCKET_PROJECT="${1#*=}";; + -m|--bitbucket-ods-project) ODS_BITBUCKET_PROJECT="$2"; shift;; + + -p=*|--project=*) PROJECT="${1#*=}";; + -p|--project) PROJECT="$2"; shift;; + + -q=*|--quickstarter-repository=*) QuickstarterRepository="${1#*=}";; + -q|--quickstarter-repository) QuickstarterRepository="$2"; shift;; + + -s=*|--sonar-quality-profile=*) SONAR_QUALITY_PROFILE="${1#*=}";; + -s|--sonar-quality-profile) SONAR_QUALITY_PROFILE="$2"; shift;; + + *) echo "Unknown parameter passed: $1"; exit 1;; +esac; shift; done + +# echo "create trigger secret" +# SECRET=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '') + +tailor --namespace=${PROJECT}-cd --non-interactive \ + apply \ + --param=ODS_GIT_REF=${ODS_GIT_REF} \ + --param=configurationRef=${configurationRef} \ + --param=PROJECT=${PROJECT} \ + --param=BITBUCKET_URL=${BITBUCKET_URL} \ + --param=ODS_NAMESPACE=${ODS_NAMESPACE} \ + --param=ODS_IMAGE_TAG=${ODS_IMAGE_TAG} \ + --param=ODS_BITBUCKET_PROJECT=${ODS_BITBUCKET_PROJECT} \ + --param=SONAR_QUALITY_PROFILE="${SONAR_QUALITY_PROFILE}" \ + --param=QuickstarterRepository=${QuickstarterRepository} \ + --selector template=golden-test-pipeline diff --git a/tests/quickstarter-test.sh b/tests/quickstarter-test.sh index ff78c1db4..caf20a217 100755 --- a/tests/quickstarter-test.sh +++ b/tests/quickstarter-test.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -set -eu +set -u set -o pipefail export CGO_ENABLED=0 @@ -7,58 +7,103 @@ THIS_SCRIPT="$(basename $0)" # By default we run all quickstarter tests, otherwise just the quickstarter # passed as the first argument to this script. -QUICKSTARTER=${1-"ods-quickstarters/..."} -PARALLEL=${2-"1"} +BITBUCKET_TEST_PROJECT="unitt" +QUICKSTARTER_FOLDER="ods-quickstarters/..." +QUICKSTARTER="" +PARALLEL="1" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ODS_CORE_DIR=${SCRIPT_DIR%/*} -if ! oc whoami &> /dev/null; then - echo "${THIS_SCRIPT}: You need to login to OpenShift to run the tests" - echo "${THIS_SCRIPT}: Returning with exit code 1" - exit 1 -fi +function check_already_logged_in_openshift(){ + if ! oc whoami &> /dev/null; then + echo "${THIS_SCRIPT}: You need to login to OpenShift to run the tests" + echo "${THIS_SCRIPT}: Returning with exit code 1" + exit 1 + fi +} -if [ -f test-quickstarter-results.txt ]; then - rm test-quickstarter-results.txt -fi +function cleanup_workspace(){ + if [ -f test-quickstarter-results.txt ]; then + rm test-quickstarter-results.txt + fi +} -BITBUCKET_TEST_PROJECT="unitt" -echo "Setup Bitbucket test project ${BITBUCKET_TEST_PROJECT} ..." -BITBUCKET_URL=$(${ODS_CORE_DIR}/scripts/get-config-param.sh BITBUCKET_URL) -CD_USER_ID=$(${ODS_CORE_DIR}/scripts/get-config-param.sh CD_USER_ID) -CD_USER_PWD_B64=$(${ODS_CORE_DIR}/scripts/get-config-param.sh CD_USER_PWD_B64) -./scripts/setup-bitbucket-test-project.sh \ - --bitbucket=${BITBUCKET_URL} \ - --user=${CD_USER_ID} \ - --password=$(base64 -d - <<< ${CD_USER_PWD_B64}) \ - --project=${BITBUCKET_TEST_PROJECT} - -echo " " -echo "${THIS_SCRIPT}: Cleaning a little bit the host machine to not suffer from limitated resources... " -echo " " -if [ -f ./scripts/free-unused-resources.sh ]; then - chmod +x ./scripts/free-unused-resources.sh - ./scripts/free-unused-resources.sh || true -else - echo "Not found script ./scripts/free-unused-resources.sh " -fi +function generate_results(){ + echo "Process results" + cd $ODS_CORE_DIR/tests + if [ -f test-quickstarter-results.txt ]; then + go-junit-report < test-quickstarter-results.txt > test-quickstarter-report.xml + cat -v test-quickstarter-results.txt > test-output + go-junit-report < test-output > test-quickstarter-report.xml + csplit -z test-quickstarter-results.txt '/=== CONT/' {*} + rm xx00 + for file in xx*; do + newName=$(grep -oP -m 1 'TestQuickstarter/\K\w+.*' $file) + mv $file $newName.txt + done + fi +} + +function run_test(){ + echo " " + echo "${THIS_SCRIPT}: Running tests (${QUICKSTARTER}). Output will take a while to arrive ..." + echo " " + + + # Should fix error " panic: test timed out after " + echo "${THIS_SCRIPT}: go test -v -count=1 -timeout 30h -parallel ${PARALLEL} github.com/opendevstack/ods-core/tests/quickstarter -args ${BITBUCKET_TEST_PROJECT} ${QUICKSTARTER_FOLDER} ${QUICKSTARTER}" + go test -v -count=1 -timeout 30h -parallel ${PARALLEL} github.com/opendevstack/ods-core/tests/quickstarter -args ${BITBUCKET_TEST_PROJECT} ${QUICKSTARTER_FOLDER} ${QUICKSTARTER} | tee test-quickstarter-results.txt 2>&1 + + exitcode="${PIPESTATUS[0]}" + + echo " " + echo " " + echo "${THIS_SCRIPT}: Returning with exit code ${exitcode}" + echo " " + echo " " + + generate_results -echo " " -echo "${THIS_SCRIPT}: Running tests (${QUICKSTARTER}). Output will take a while to arrive ..." -echo " " + exit $exitcode +} -# Should fix error " panic: test timed out after " -echo "${THIS_SCRIPT}: go test -v -count=1 -timeout 30h -parallel ${PARALLEL} github.com/opendevstack/ods-core/tests/quickstarter -args ${QUICKSTARTER}" -go test -v -count=1 -timeout 30h -parallel ${PARALLEL} github.com/opendevstack/ods-core/tests/quickstarter -args ${QUICKSTARTER} | tee test-quickstarter-results.txt 2>&1 -exitcode="${PIPESTATUS[0]}" -if [ -f test-quickstarter-results.txt ]; then - go-junit-report < test-quickstarter-results.txt > test-quickstarter-report.xml + +function usage { + printf "Run quickstarters tests.\n\n" + printf "\t-h |--help\t\tPrint usage\n" + printf "\t-p |--project\t\tBitbucket project (* mandatory)\n" + printf "\t-pa|--parallel\t\tNumber of test executed in parallel\n" + printf "\t-qf |--quickstarterfolder\tQuickstarter folder (default:ods-quickstarters/...)\n" + printf "\t-q |--quickstarter\tQuickStarter to test\n" +} + +while [[ "$#" -gt 0 ]]; do + case $1 in + + -h|--help) usage; exit 0;; + + -pa|--parallel) PARALLEL="$2"; shift;; + -pa=*|--parallel=*) PARALLEL="${1#*=}";; + + -q|--quickstarter) QUICKSTARTER="$2"; shift;; + -q=*|--quickstarter=*) QUICKSTARTER="${1#*=}";; + + -qf|--quickstarterfolder) QUICKSTARTER_FOLDER="$2"; shift;; + -qf=*|--quickstarterfolder=*) QUICKSTARTER_FOLDER="${1#*=}";; + + -p|--project) BITBUCKET_TEST_PROJECT="$2"; shift;; + -p=*|--project=*) BITBUCKET_TEST_PROJECT="${1#*=}";; + + *) echo_error "Unknown parameter passed: $1"; exit 1;; +esac; shift; done + +if [ -z "${BITBUCKET_TEST_PROJECT}" ]; then + echo "--project is mandatory" + usage + exit 1 fi -echo " " -echo " " -echo "${THIS_SCRIPT}: Returning with exit code ${exitcode}" -echo " " -echo " " -exit $exitcode +check_already_logged_in_openshift +cleanup_workspace +run_test diff --git a/tests/quickstarter/bitbucket.go b/tests/quickstarter/bitbucket.go index c962ba236..642478689 100644 --- a/tests/quickstarter/bitbucket.go +++ b/tests/quickstarter/bitbucket.go @@ -20,6 +20,7 @@ func recreateBitbucketRepo(config map[string]string, project string, repo string fmt.Sprintf("--password=%s", password), fmt.Sprintf("--project=%s", project), fmt.Sprintf("--repository=%s", repo), + "--insecure", }, []string{}) if err != nil { diff --git a/tests/quickstarter/golden-files.go b/tests/quickstarter/golden-files.go new file mode 100644 index 000000000..7e0e14f07 --- /dev/null +++ b/tests/quickstarter/golden-files.go @@ -0,0 +1,28 @@ +package quickstarter + +import ( + "bytes" + "fmt" + "html/template" + + "github.com/google/go-cmp/cmp" +) + +func verifyGoldenFile(componentID string, wantFile string, gotFile string, tmplData TemplateData) error { + + var want bytes.Buffer + tmpl, err := template.ParseFiles(wantFile) + if err != nil { + return fmt.Errorf("Failed to load golden file to verify State: %w", err) + } + err = tmpl.Execute(&want, tmplData) + if err != nil { + return fmt.Errorf("Failed to render file to verify State: %w", err) + } + + if diff := cmp.Diff(want.String(), gotFile); diff != "" { + return fmt.Errorf("State mismatch for %s (-want +got):\n%s", componentID, diff) + } + + return nil +} diff --git a/tests/quickstarter/quickstarter_test.go b/tests/quickstarter/quickstarter_test.go index 2e7e72872..70ecccca3 100644 --- a/tests/quickstarter/quickstarter_test.go +++ b/tests/quickstarter/quickstarter_test.go @@ -24,11 +24,20 @@ import ( // folder - otherwise a folder next to "ods-core" is assumed, by default // "ods-quickstarters". If the argument ends with "...", all directories with a // "testdata" directory are tested, otherwise only the given folder is run. + +// Adding new parameter quickstarter to parameterize the hardcoded value "ods-quickstarters" func TestQuickstarter(t *testing.T) { var quickstarterPaths []string odsCoreRootPath := "../.." - target := os.Args[len(os.Args)-1] + quickstarter := os.Args[len(os.Args)-1] + fmt.Printf("QS: %s\n", quickstarter) + target := os.Args[len(os.Args)-2] + fmt.Printf("Target: %s\n", target) + project := os.Args[len(os.Args)-3] + fmt.Printf("Project: %s\n", project) + utils.Set_project_name(project) + if strings.HasPrefix(target, ".") || strings.HasPrefix(target, "/") { if strings.HasSuffix(target, "...") { quickstarterPaths = collectTestableQuickstarters( @@ -38,29 +47,28 @@ func TestQuickstarter(t *testing.T) { quickstarterPaths = append(quickstarterPaths, target) } } else { - // No slash = quickstarter in ods-quickstarters - // Ending with ... = all quickstarters in given folder - // otherwise = exactly one quickstarter - if !strings.Contains(target, "/") { - quickstarterPaths = []string{fmt.Sprintf("%s/../%s/%s", odsCoreRootPath, "ods-quickstarters", target)} - } else if strings.HasSuffix(target, "...") { + if quickstarter != "all" { + // quickstarter variable value not all = test only one quickstarter + quickstarterPaths = []string{fmt.Sprintf("%s/../%s/%s", odsCoreRootPath, strings.TrimSuffix(target, "/..."), quickstarter)} + } else { + // quickstarter variable value all = test all quickstarters quickstarterPaths = collectTestableQuickstarters( t, fmt.Sprintf("%s/../%s", odsCoreRootPath, strings.TrimSuffix(target, "/...")), ) - } else { - quickstarterPaths = []string{fmt.Sprintf("%s/../%s", odsCoreRootPath, target)} } } - config, err := utils.ReadConfiguration() + dir, err := os.Getwd() if err != nil { - t.Fatal(err) + fmt.Println("Error:", err) + return } - cdUserPassword, err := b64.StdEncoding.DecodeString(config["CD_USER_PWD_B64"]) + quickstarterPaths = utils.RemoveExcludedQuickstarters(t, dir, quickstarterPaths) + + config, err := utils.ReadConfiguration() if err != nil { - t.Fatalf("Error decoding cd_user password: %s", err) + t.Fatal(err) } - fmt.Printf("\n\nRunning test steps found in the following directories:\n") for _, quickstarterPath := range quickstarterPaths { fmt.Printf("- %s\n", quickstarterPath) @@ -68,6 +76,7 @@ func TestQuickstarter(t *testing.T) { fmt.Printf("\n\n") for _, quickstarterPath := range quickstarterPaths { + testdataPath := fmt.Sprintf("%s/testdata", quickstarterPath) quickstarterRepo := filepath.Base(filepath.Dir(quickstarterPath)) quickstarterName := filepath.Base(quickstarterPath) @@ -76,9 +85,6 @@ func TestQuickstarter(t *testing.T) { fmt.Printf("Running tests for quickstarter %s\n", quickstarterName) fmt.Printf("\n\n") - freeUnusedResources(t) - restartAtlassianSuiteIfLicenseExpiresInLessThan(t) - // Run each quickstarter test in a subtest to avoid exiting early // when t.Fatal is used. t.Run(quickstarterName, func(t *testing.T) { @@ -103,166 +109,226 @@ func TestQuickstarter(t *testing.T) { ) repoName := fmt.Sprintf("%s-%s", strings.ToLower(utils.PROJECT_NAME), step.ComponentID) + tmplData := templateData(config, step.ComponentID, "") if step.Type == "upload" { - if len(step.UploadParams.Filename) == 0 { - step.UploadParams.Filename = filepath.Base(step.UploadParams.File) - } - stdout, stderr, err := utils.RunScriptFromBaseDir("tests/scripts/upload-file-to-bitbucket.sh", []string{ - fmt.Sprintf("--bitbucket=%s", config["BITBUCKET_URL"]), - fmt.Sprintf("--user=%s", config["CD_USER_ID"]), - fmt.Sprintf("--password=%s", cdUserPassword), - fmt.Sprintf("--project=%s", utils.PROJECT_NAME), - fmt.Sprintf("--repository=%s", repoName), - fmt.Sprintf("--file=%s/%s", testdataPath, step.UploadParams.File), - fmt.Sprintf("--filename=%s", step.UploadParams.Filename), - }, []string{}) - - if err != nil { - t.Fatalf( - "Execution of `upload-file-to-bitbucket.sh` failed: \nStdOut: %s\nStdErr: %s\nErr: %s\n", - stdout, - stderr, - err) - } else { - fmt.Printf("Uploaded file %s to %s\n", step.UploadParams.File, config["BITBUCKET_URL"]) - } + executeStepUpload(t, step, testdataPath, tmplData, repoName, config) + continue + } + + if step.Type == "run" { + executeStepRun(t, step, testdataPath) continue } - var request utils.RequestBuild - var pipelineName string - var jenkinsfile string - var verify *TestStepVerify - tmplData := templateData(config, step.ComponentID, "") if step.Type == "provision" { - // cleanup and create bb resources for this test - err = recreateBitbucketRepo(config, utils.PROJECT_NAME, repoName) - if err != nil { - t.Fatal(err) - } - err = deleteOpenShiftResources(utils.PROJECT_NAME, step.ComponentID, utils.PROJECT_NAME_DEV) - if err != nil { - t.Fatal(err) - } - branch := config["ODS_GIT_REF"] - if len(step.ProvisionParams.Branch) > 0 { - branch = renderTemplate(t, step.ProvisionParams.Branch, tmplData) - } - agentImageTag := config["ODS_IMAGE_TAG"] - if len(step.ProvisionParams.AgentImageTag) > 0 { - agentImageTag = renderTemplate(t, step.ProvisionParams.AgentImageTag, tmplData) - } - sharedLibraryRef := agentImageTag - if len(step.ProvisionParams.SharedLibraryRef) > 0 { - sharedLibraryRef = renderTemplate(t, step.ProvisionParams.SharedLibraryRef, tmplData) - } - env := []utils.EnvPair{ - { - Name: "ODS_NAMESPACE", - Value: config["ODS_NAMESPACE"], - }, - { - Name: "ODS_GIT_REF", - Value: config["ODS_GIT_REF"], - }, - { - Name: "ODS_IMAGE_TAG", - Value: config["ODS_IMAGE_TAG"], - }, - { - Name: "ODS_BITBUCKET_PROJECT", - Value: config["ODS_BITBUCKET_PROJECT"], - }, - { - Name: "AGENT_IMAGE_TAG", - Value: agentImageTag, - }, - { - Name: "SHARED_LIBRARY_REF", - Value: sharedLibraryRef, - }, - { - Name: "PROJECT_ID", - Value: utils.PROJECT_NAME, - }, - { - Name: "COMPONENT_ID", - Value: step.ComponentID, - }, - { - Name: "GIT_URL_HTTP", - Value: fmt.Sprintf("%s/%s/%s.git", config["REPO_BASE"], utils.PROJECT_NAME, repoName), - }, - } - request = utils.RequestBuild{ - Repository: quickstarterRepo, - Branch: branch, - Project: config["ODS_BITBUCKET_PROJECT"], - Env: append(env, step.ProvisionParams.Env...), - } - // If quickstarter is overwritten, use that value. Otherwise - // we use the quickstarter under test. - if len(step.ProvisionParams.Quickstarter) > 0 { - jenkinsfile = fmt.Sprintf("%s/Jenkinsfile", step.ProvisionParams.Quickstarter) - } else { - jenkinsfile = fmt.Sprintf("%s/Jenkinsfile", quickstarterName) - } - pipelineName = step.ProvisionParams.Pipeline - verify = step.ProvisionParams.Verify - } else if step.Type == "build" { - branch := "master" - if len(step.BuildParams.Branch) > 0 { - branch = renderTemplate(t, step.BuildParams.Branch, tmplData) - } - request = utils.RequestBuild{ - Repository: repoName, - Branch: branch, - Project: utils.PROJECT_NAME, - Env: step.BuildParams.Env, - } - jenkinsfile = "Jenkinsfile" - pipelineName = step.BuildParams.Pipeline - verify = step.BuildParams.Verify + executeProvision(t, step, testdataPath, tmplData, repoName, quickstarterRepo, quickstarterName, config) + continue } - buildName, err := utils.RunJenkinsPipeline(jenkinsfile, request, pipelineName) - if err != nil { - t.Fatal(err) + + if step.Type == "build" { + executeBuild(t, step, testdataPath, tmplData, repoName, config) + continue } - verifyPipelineRun(t, step, verify, testdataPath, repoName, buildName, config) + t.Fatal("Unknown step") + } + + fmt.Printf("\n\n\n\n") + fmt.Printf("========== End test for Quickstarter %s\n", quickstarterName) + fmt.Printf("\n\n") }) + } + } -func freeUnusedResources(t *testing.T) { +func executeProvision(t *testing.T, step TestStep, testdataPath string, tmplData TemplateData, repoName string, quickstarterRepo string, quickstarterName string, config map[string]string) { + // cleanup and create bb resources for this test + err := recreateBitbucketRepo(config, utils.PROJECT_NAME, repoName) + if err != nil { + t.Fatal(err) + } + err = deleteOpenShiftResources(utils.PROJECT_NAME, step.ComponentID, utils.PROJECT_NAME_DEV) + if err != nil { + t.Fatal(err) + } + branch := config["ODS_GIT_REF"] + if len(step.ProvisionParams.Branch) > 0 { + branch = renderTemplate(t, step.ProvisionParams.Branch, tmplData) + } + agentImageTag := config["ODS_IMAGE_TAG"] + if len(step.ProvisionParams.AgentImageTag) > 0 { + agentImageTag = renderTemplate(t, step.ProvisionParams.AgentImageTag, tmplData) + } + sharedLibraryRef := agentImageTag + if len(step.ProvisionParams.SharedLibraryRef) > 0 { + sharedLibraryRef = renderTemplate(t, step.ProvisionParams.SharedLibraryRef, tmplData) + } + env := []utils.EnvPair{ + { + Name: "ODS_NAMESPACE", + Value: config["ODS_NAMESPACE"], + }, + { + Name: "ODS_GIT_REF", + Value: config["ODS_GIT_REF"], + }, + { + Name: "ODS_IMAGE_TAG", + Value: config["ODS_IMAGE_TAG"], + }, + { + Name: "ODS_BITBUCKET_PROJECT", + Value: config["ODS_BITBUCKET_PROJECT"], + }, + { + Name: "AGENT_IMAGE_TAG", + Value: agentImageTag, + }, + { + Name: "SHARED_LIBRARY_REF", + Value: sharedLibraryRef, + }, + { + Name: "PROJECT_ID", + Value: utils.PROJECT_NAME, + }, + { + Name: "COMPONENT_ID", + Value: step.ComponentID, + }, + { + Name: "GIT_URL_HTTP", + Value: fmt.Sprintf("%s/%s/%s.git", config["REPO_BASE"], utils.PROJECT_NAME, repoName), + }, + } + request := utils.RequestBuild{ + Repository: quickstarterRepo, + Branch: branch, + Project: config["ODS_BITBUCKET_PROJECT"], + Env: append(env, step.ProvisionParams.Env...), + } - // Run cleanup operations to ensure we always have enough resources. - stdout, stderr, err := utils.RunScriptFromBaseDir( - "tests/scripts/free-unused-resources.sh", - []string{}, []string{}, - ) + t.Cleanup(func() { + err = deleteOpenShiftResources(utils.PROJECT_NAME, step.ComponentID, utils.PROJECT_NAME_DEV) + }) + // If quickstarter is overwritten, use that value. Otherwise + // we use the quickstarter under test. + var jenkinsfile string + if len(step.ProvisionParams.Quickstarter) > 0 { + jenkinsfile = fmt.Sprintf("%s/Jenkinsfile", step.ProvisionParams.Quickstarter) + } else { + jenkinsfile = fmt.Sprintf("%s/Jenkinsfile", quickstarterName) + } + pipelineName := step.ProvisionParams.Pipeline + verify := step.ProvisionParams.Verify + + buildName, err := utils.RunJenkinsPipeline(jenkinsfile, request, pipelineName) + if err != nil { + t.Fatal(err) + } + verifyPipelineRun(t, step, verify, testdataPath, repoName, buildName, config) +} + +func executeBuild(t *testing.T, step TestStep, testdataPath string, tmplData TemplateData, repoName string, config map[string]string) { + branch := "master" + if len(step.BuildParams.Branch) > 0 { + branch = renderTemplate(t, step.BuildParams.Branch, tmplData) + } + request := utils.RequestBuild{ + Repository: repoName, + Branch: branch, + Project: utils.PROJECT_NAME, + Env: step.BuildParams.Env, + } + jenkinsfile := "Jenkinsfile" + pipelineName := step.BuildParams.Pipeline + verify := step.BuildParams.Verify + + buildName, err := utils.RunJenkinsPipeline(jenkinsfile, request, pipelineName) + if err != nil { + t.Fatal(err) + } + verifyPipelineRun(t, step, verify, testdataPath, repoName, buildName, config) +} + +func executeStepUpload(t *testing.T, step TestStep, testdataPath string, tmplData TemplateData, repoName string, config map[string]string) { + if step.UploadParams == nil || len(step.UploadParams.File) == 0 { + t.Fatalf("Missing upload parameters.") + } + if len(step.UploadParams.Filename) == 0 { + step.UploadParams.Filename = filepath.Base(step.UploadParams.File) + } + cdUserPassword, err := b64.StdEncoding.DecodeString(config["CD_USER_PWD_B64"]) + if err != nil { + t.Fatalf("Execution of `upload-file-to-bitbucket.sh` failed: \nErr: %s\n", err) + } + + fileToUpload := fmt.Sprintf("%s/%s", testdataPath, step.UploadParams.File) + + if step.UploadParams.Render { + fmt.Printf("Rendering template to upload") + tmpl, err := template.ParseFiles(fileToUpload) + if err != nil { + t.Fatalf("Failed to load file to upload: \nErr: %s\n", err) + + } + outputFile, err := os.Create(fileToUpload) + if err != nil { + t.Fatalf("Error creating output file: \nErr: %s\n", err) + + } + defer outputFile.Close() + fmt.Printf("Execute render") + err = tmpl.Execute(outputFile, tmplData) + if err != nil { + t.Fatalf("Failed to render file: \nErr: %s\n", err) + } + } + + stdout, stderr, err := utils.RunScriptFromBaseDir("tests/scripts/upload-file-to-bitbucket.sh", []string{ + fmt.Sprintf("--bitbucket=%s", config["BITBUCKET_URL"]), + fmt.Sprintf("--user=%s", config["CD_USER_ID"]), + fmt.Sprintf("--password=%s", cdUserPassword), + fmt.Sprintf("--project=%s", utils.PROJECT_NAME), + fmt.Sprintf("--repository=%s", repoName), + fmt.Sprintf("--file=%s", fileToUpload), + fmt.Sprintf("--filename=%s", step.UploadParams.Filename), + }, []string{}) + fmt.Printf("%s", stdout) if err != nil { - t.Fatalf("Error cleaning up : \nStdOut: %s\nStdErr: %s\nErr: %s\n", stdout, stderr, err) + t.Fatalf( + "Execution of `upload-file-to-bitbucket.sh` failed: \nStdOut: %s\nStdErr: %s\nErr: %s\n", + stdout, + stderr, + err) } else { - fmt.Printf("Cleaned cluster state.\n") + fmt.Printf("Uploaded file %s to %s\n", step.UploadParams.File, config["BITBUCKET_URL"]) } } -func restartAtlassianSuiteIfLicenseExpiresInLessThan(t *testing.T) { +func executeStepRun(t *testing.T, step TestStep, testdataPath string) { + if step.RunParams == nil || len(step.RunParams.File) == 0 { + t.Fatalf("Missing run parameters, not defined script file.") + } - // Run cleanup operations to ensure we always have enough resources. - stdout, stderr, err := utils.RunScriptFromBaseDir( - "ods-devenv/scripts/restart-atlassian-suite-if-license-expires-in-less-than.sh", - []string{"--hours-left", "2"}, []string{}, - ) + fmt.Printf("Executing script: %s\n", step.RunParams.File) + step.RunParams.File = fmt.Sprintf("%s/%s", testdataPath, step.RunParams.File) + stdout, stderr, err := utils.RunCommand(step.RunParams.File, []string{}, []string{}) + fmt.Printf("%s", stdout) if err != nil { - t.Fatalf("Error cleaning up : \nStdOut: %s\nStdErr: %s\nErr: %s\n", stdout, stderr, err) + t.Fatalf( + "Execution of script:%s failed: \nStdOut: %s\nStdErr: %s\nErr: %s\n", + step.RunParams.File, + stdout, + stderr, + err) } else { - fmt.Printf("Checked if needed to restart atlassian suite.\n") + fmt.Printf("Executed script: %s\n", step.RunParams.File) } } @@ -295,6 +361,7 @@ func templateData(config map[string]string, componentID string, buildName string buildParts := strings.Split(buildName, "-") buildNumber = buildParts[len(buildParts)-1] } + aquaEnabled, _ := strconv.ParseBool(config["AQUA_ENABLED"]) return TemplateData{ ProjectID: utils.PROJECT_NAME, ComponentID: componentID, @@ -304,6 +371,8 @@ func templateData(config map[string]string, componentID string, buildName string OdsBitbucketProject: config["ODS_BITBUCKET_PROJECT"], SanitizedOdsGitRef: sanitizedOdsGitRef, BuildNumber: buildNumber, + SonarQualityProfile: utils.GetEnv("SONAR_QUALITY_PROFILE", "Sonar way"), + AquaEnabled: aquaEnabled, } } @@ -324,9 +393,11 @@ func verifyPipelineRun(t *testing.T, step TestStep, verify *TestStepVerify, test t.Fatal(err) } fmt.Printf("%s pipeline run for %s returned:\n%s", step.Type, step.ComponentID, stages) - err = utils.VerifyJenkinsStages( + err = verifyGoldenFile( + step.ComponentID, fmt.Sprintf("%s/%s", testdataPath, verify.JenkinsStages), stages, + tmplData, ) if err != nil { t.Fatal(err) @@ -339,7 +410,7 @@ func verifyPipelineRun(t *testing.T, step TestStep, verify *TestStepVerify, test if err != nil { t.Fatal(err) } - err = verifySonarScan( + err = verifyGoldenFile( step.ComponentID, fmt.Sprintf("%s/%s", testdataPath, verify.SonarScan), sonarscan, diff --git a/tests/quickstarter/sonarqube.go b/tests/quickstarter/sonarqube.go index 52a8d4e89..fc184b07a 100644 --- a/tests/quickstarter/sonarqube.go +++ b/tests/quickstarter/sonarqube.go @@ -1,12 +1,9 @@ package quickstarter import ( - "bytes" b64 "encoding/base64" "fmt" - "html/template" - "github.com/google/go-cmp/cmp" "github.com/opendevstack/ods-core/tests/utils" ) @@ -34,21 +31,3 @@ func retrieveSonarScan(projectKey string, config map[string]string) (string, err return stdout, nil } - -func verifySonarScan(componentID string, wantScanFile string, gotScan string, tmplData TemplateData) error { - var wantScan bytes.Buffer - tmpl, err := template.ParseFiles(wantScanFile) - if err != nil { - return fmt.Errorf("Failed to load golden file to verify Sonar scan: %w", err) - } - err = tmpl.Execute(&wantScan, tmplData) - if err != nil { - return fmt.Errorf("Failed to render file to verify Sonar scan: %w", err) - } - - if diff := cmp.Diff(wantScan.String(), gotScan); diff != "" { - return fmt.Errorf("Sonar scan mismatch for %s (-want +got):\n%s", componentID, diff) - } - - return nil -} diff --git a/tests/quickstarter/steps.go b/tests/quickstarter/steps.go index 55e118f92..8b809105b 100644 --- a/tests/quickstarter/steps.go +++ b/tests/quickstarter/steps.go @@ -34,6 +34,14 @@ type TestStep struct { BuildParams *TestStepBuildParams `json:"buildParams"` // Parameters for "upload" step type UploadParams *TestStepUploadParams `json:"uploadParams"` + // Parameters for "run" step type + RunParams *TestStepRunParams `json:"runParams"` +} + +// TestStepUploadParams defines the parameters for the "provision" step type. +type TestStepRunParams struct { + // File to execute relative to "testdata" directory + File string `json:"file"` } // TestStepUploadParams defines the parameters for the "provision" step type. @@ -42,6 +50,8 @@ type TestStepUploadParams struct { File string `json:"file"` // Name of the uploaded file in the repository. Defaults to just the filename of +File+. Filename string `json:"filename"` + // In case this is a template file that we want to render. + Render bool `json:"render"` } // TestStepProvisionParams defines the parameters for the "provision" step type. @@ -126,6 +136,10 @@ type TemplateData struct { SanitizedOdsGitRef string // Jenkins Build number BuildNumber string + // Name of the Sonar Quality Profile + SonarQualityProfile string + // Is enable Aqua + AquaEnabled bool } // readSteps reads "steps.yml" in given folder. @@ -149,7 +163,7 @@ func readSteps(folder string) (*TestSteps, error) { } // A poor man's workaround for missing enums in Go. There are better ways // to do it, but nothing as simple as this. - allowedTypes := map[string]bool{"provision": true, "build": true, "upload": true} + allowedTypes := map[string]bool{"provision": true, "build": true, "upload": true, "run": true} for i, step := range s.Steps { if _, ok := allowedTypes[step.Type]; !ok { allowed := []string{} diff --git a/tests/scripts/free-unused-resources.sh b/tests/scripts/free-unused-resources.sh index 83890c00c..4fdd24ac9 100755 --- a/tests/scripts/free-unused-resources.sh +++ b/tests/scripts/free-unused-resources.sh @@ -2,8 +2,6 @@ echo " " -ME=$(basename $0) - function clean_containers { echo "Removing docker containers no more used... " if docker ps -a | grep -q 'Exited .* ago' ; then @@ -29,7 +27,6 @@ function clean_tests { } function clean_odsverify { - echo "Cleaning projects ODS__VERIFY... " if [ "true" == "$CLEAN_ODS_VERIFY" ]; then echo "Removing ODS VERIFY projects..." oc projects | grep '^\s*odsverify.*' | while read -r line; do @@ -44,14 +41,14 @@ function clean_odsverify { } function clean_images { - echo "Cleaning OC images" echo "oc adm prune images --keep-tag-revisions=1 --keep-younger-than=30m --confirm" oc adm prune images --keep-tag-revisions=1 --keep-younger-than=30m --confirm || true } function usage { + ME=$(basename $0) echo " " - echo "usage: ${ME} [--odsVerify] [--omitTests] [--omitTestsProject tes22]" + echo "usage: ${ME} [--odsVerify] [--omitTestsProject tes22]" echo " " } @@ -62,7 +59,6 @@ function echo_error() { OMIT_TESTS_PROJECT=none CLEAN_ODS_VERIFY="false" -CLEAN_TESTS="false" while [[ "$#" -gt 0 ]]; do case $1 in @@ -75,19 +71,11 @@ while [[ "$#" -gt 0 ]]; do --omitTestsProject) OMIT_TESTS_PROJECT="$2"; echo "Tests to omit: $OMIT_TESTS_PROJECT"; shift;; - --cleanTests) CLEAN_TESTS="true";; - *) echo_error "Unknown parameter passed: $1"; exit 1;; esac; shift; done clean_containers -if [ "true" == "${CLEAN_TESTS}" ]; then - clean_tests -else - echo " " - echo "${ME}: INFO: Not cleaning tests" - echo " " -fi +clean_tests clean_odsverify clean_images diff --git a/tests/scripts/get-artifact-from-jenkins-run.sh b/tests/scripts/get-artifact-from-jenkins-run.sh index a06539211..9444aceaf 100755 --- a/tests/scripts/get-artifact-from-jenkins-run.sh +++ b/tests/scripts/get-artifact-from-jenkins-run.sh @@ -8,7 +8,7 @@ BUILD_URL=$(oc get -n ${PROJECT} build ${BUILD_NAME} -o jsonpath='{.metadata.ann echo $BUILD_URL ARTIFACT_URL=$BUILD_URL/artifact/artifacts/$3 echo "grabbing artifact from $ARTIFACT_URL - and storing in /tmp" -TOKEN=$(oc -n ${PROJECT} get sa/jenkins --template='{{range .secrets}}{{ .name }} {{end}}' | xargs -n 1 oc -n ${PROJECT} get secret --template='{{ if .data.token }}{{ .data.token }}{{end}}' | head -n 1 | base64 -d -) +TOKEN=$(oc whoami --show-token) httpCode=$(curl --insecure -sS ${ARTIFACT_URL} --header "Authorization: Bearer ${TOKEN}" -o /tmp/$3 -w "%{http_code}") echo "response: $httpCode" if [ ! "${httpCode}" == "200" ]; then diff --git a/tests/scripts/print-jenkins-log.sh b/tests/scripts/print-jenkins-log.sh index 3da6d75bc..17f5e2ff8 100755 --- a/tests/scripts/print-jenkins-log.sh +++ b/tests/scripts/print-jenkins-log.sh @@ -26,7 +26,7 @@ if [ "OC_ERROR" == "${LOG_URL}" ]; then OC_ERROR="true" TOKEN="OC_ERROR" else - TOKEN=$(oc -n ${PROJECT} get sa/jenkins --template='{{range .secrets}}{{ .name }} {{end}}' | xargs -n 1 oc -n ${PROJECT} get secret --template='{{ if .data.token }}{{ .data.token }}{{end}}' | head -n 1 | base64 -d -) + TOKEN=$(oc whoami --show-token) fi if [ -f ${JENKINS_LOG_FILE} ]; then diff --git a/tests/scripts/print-jenkins-unittest-results.sh b/tests/scripts/print-jenkins-unittest-results.sh index fdb2370a2..f4a1d890c 100755 --- a/tests/scripts/print-jenkins-unittest-results.sh +++ b/tests/scripts/print-jenkins-unittest-results.sh @@ -7,6 +7,6 @@ BUILD_NAME=$2 BUILD_URL=$(oc get -n "${PROJECT}" build "${BUILD_NAME}" -o jsonpath='{.metadata.annotations.openshift\.io/jenkins-build-uri}') echo "Using $BUILD_URL/testReport calculated from ${BUILD_NAME}" -TOKEN=$(oc -n "${PROJECT}" get sa/jenkins --template='{{range .secrets}}{{ .name }} {{end}}' | xargs -n 1 oc -n "${PROJECT}" get secret --template='{{ if .data.token }}{{ .data.token }}{{end}}' | head -n 1 | base64 -d -) +TOKEN=$(oc whoami --show-token) curl --insecure -sS "${BUILD_URL}/testReport" --location --header "Authorization: Bearer ${TOKEN}" diff --git a/tests/scripts/print-sonar-scan-run.sh b/tests/scripts/print-sonar-scan-run.sh index da64b53ca..a76b46373 100755 --- a/tests/scripts/print-sonar-scan-run.sh +++ b/tests/scripts/print-sonar-scan-run.sh @@ -2,4 +2,12 @@ set -eu set -o pipefail -curl -sS --insecure -u $1: $2/api/navigation/component?componentKey=$3 | jq 'del(.analysisDate)' | jq 'del(.version)' | jq 'del(.id)' | jq 'del(.qualityProfiles[].key)' | jq 'del(.qualityGate.key)' | jq 'del (.extensions[] | select(.))' +curl -sS --insecure -u $1: $2/api/navigation/component?component=$3 | \ +jq 'del(.analysisDate)' | \ +jq 'del(.version)' | \ +jq 'del(.id)' | \ +jq 'del(.qualityProfiles[].key)' | \ +jq 'del(.qualityGate.key)' | \ +jq 'del(.extensions[] | select(.))' | \ +jq 'del(.qualityProfiles[] | select(.language == "xml"))' | \ +jq 'del(.organization)' diff --git a/tests/scripts/upload-file-to-bitbucket.sh b/tests/scripts/upload-file-to-bitbucket.sh index c5166685c..80d344a99 100755 --- a/tests/scripts/upload-file-to-bitbucket.sh +++ b/tests/scripts/upload-file-to-bitbucket.sh @@ -76,24 +76,56 @@ while [[ "$#" -gt 0 ]]; do *) echo_error "Unknown parameter passed: $1"; exit 1;; esac; shift; done -lastCommit=$(curl --insecure -sS \ - -u "${BITBUCKET_USER}:${BITBUCKET_PWD}" \ - "${BITBUCKET_URL}/rest/api/latest/projects/${BITBUCKET_PROJECT}/repos/${REPOSITORY}/commits" | jq .values[0].id | sed 's|\"||g') - -echo "last commit: ${lastCommit}" - httpCode=$(curl --insecure -sS \ -u "${BITBUCKET_USER}:${BITBUCKET_PWD}" \ - -X PUT \ - -F branch=$BRANCH \ - -F sourceCommitId=$lastCommit \ - -F "comment=ods test" \ - -F "content=@${FILE}" \ - -F filename=blob \ + -X GET \ "${BITBUCKET_URL}/rest/api/latest/projects/${BITBUCKET_PROJECT}/repos/${REPOSITORY}/browse/${REPO_FILE}" \ + -o /dev/null \ -w "%{http_code}") if [ $httpCode != "200" ]; then - echo "An error occured during update of ${BITBUCKET_URL}/rest/api/latest/projects/${BITBUCKET_PROJECT}/repos/${REPOSITORY}/browse/${REPO_FILE} - error:$httpCode" - exit 1 + echo "New file added to Bitbucket" + httpCode=$(curl --insecure -sS \ + -u "${BITBUCKET_USER}:${BITBUCKET_PWD}" \ + -X PUT \ + -F branch=$BRANCH \ + -F "comment=ods test" \ + -F "content=@${FILE}" \ + -F filename=blob \ + "${BITBUCKET_URL}/rest/api/latest/projects/${BITBUCKET_PROJECT}/repos/${REPOSITORY}/browse/${REPO_FILE}" \ + -o /dev/null \ + -w "%{http_code}") + + if [ $httpCode != "200" ]; then + echo "An error occured during creation of ${BITBUCKET_URL}/rest/api/latest/projects/${BITBUCKET_PROJECT}/repos/${REPOSITORY}/browse/${REPO_FILE} - error:$httpCode" + exit 1 + fi + +else + echo "File update" + + lastCommit=$(curl --insecure -sS \ + -u "${BITBUCKET_USER}:${BITBUCKET_PWD}" \ + "${BITBUCKET_URL}/rest/api/latest/projects/${BITBUCKET_PROJECT}/repos/${REPOSITORY}/commits" | jq .values[0].id | sed 's|\"||g') + + echo "last commit: ${lastCommit}" + + httpCode=$(curl --insecure -sS \ + -u "${BITBUCKET_USER}:${BITBUCKET_PWD}" \ + -X PUT \ + -F branch=$BRANCH \ + -F sourceCommitId=$lastCommit \ + -F "comment=ods test" \ + -F "content=@${FILE}" \ + -F filename=blob \ + "${BITBUCKET_URL}/rest/api/latest/projects/${BITBUCKET_PROJECT}/repos/${REPOSITORY}/browse/${REPO_FILE}" \ + -o /dev/null \ + -w "%{http_code}") + + if [ $httpCode != "200" ] && [ $httpCode != "409"]; then + echo "An error occured during update of ${BITBUCKET_URL}/rest/api/latest/projects/${BITBUCKET_PROJECT}/repos/${REPOSITORY}/browse/${REPO_FILE} - error:$httpCode" + exit 1 + fi fi + + diff --git a/tests/utils/constants.go b/tests/utils/constants.go deleted file mode 100644 index 53b4be03d..000000000 --- a/tests/utils/constants.go +++ /dev/null @@ -1,7 +0,0 @@ -package utils - -const PROJECT_NAME = "unitt" -const PROJECT_ENV_VAR = "PROJECT_ID=" + PROJECT_NAME -const PROJECT_NAME_CD = "unitt-cd" -const PROJECT_NAME_DEV = "unitt-dev" -const PROJECT_NAME_TEST = "unitt-test" diff --git a/tests/utils/environment.go b/tests/utils/environment.go new file mode 100644 index 000000000..282a61311 --- /dev/null +++ b/tests/utils/environment.go @@ -0,0 +1,10 @@ +package utils + +import "os" + +func GetEnv(key, fallback string) string { + if value, ok := os.LookupEnv(key); ok { + return value + } + return fallback +} diff --git a/tests/utils/filter-quickstarters.go b/tests/utils/filter-quickstarters.go new file mode 100644 index 000000000..5eee50e47 --- /dev/null +++ b/tests/utils/filter-quickstarters.go @@ -0,0 +1,55 @@ +package utils + +import ( + "bufio" + "fmt" + "os" + "strings" + "testing" +) + +func RemoveExcludedQuickstarters(t *testing.T, dir string, quickstarterPaths []string) []string { + var quickstarterPathsFiltered []string + var exclusionList []string + + var filePath string = fmt.Sprintf("%s/../%s", dir, "quickStartersExclusionList.txt") + fmt.Printf("\n\nLooking for file quickStartersExclusionList.txt ... %s\n", filePath) + + _, err := os.Stat(filePath) + + if os.IsNotExist(err) { + fmt.Printf("File %s does not exist, The list of Quickstarters is not filtered.\n", filePath) + return quickstarterPaths + } + + file, err := os.Open(filePath) + if err != nil { + fmt.Println(err) + t.Fatal(err) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + exclusionList = append(exclusionList, scanner.Text()) + } + + fmt.Printf("\n\nQuickStarters that will be excluded...\n%s", exclusionList) + + for _, quickstarterPath := range quickstarterPaths { + if sliceContainsString(exclusionList, quickstarterPath) == -1 { + quickstarterPathsFiltered = append(quickstarterPathsFiltered, quickstarterPath) + } + } + + return quickstarterPathsFiltered +} + +func sliceContainsString(slice []string, str string) int { + for pos, s := range slice { + if strings.Contains(str, s) { + return pos + } + } + return -1 +} diff --git a/tests/utils/ods-env.go b/tests/utils/ods-env.go index ca7405c16..d5ca9a0b2 100644 --- a/tests/utils/ods-env.go +++ b/tests/utils/ods-env.go @@ -29,5 +29,10 @@ func ReadConfiguration() (map[string]string, error) { } } + for _, e := range os.Environ() { + parts := strings.SplitN(e, "=", 2) + values[parts[0]] = parts[1] + } + return values, nil } diff --git a/tests/utils/openshift-client.go b/tests/utils/openshift-client.go index dbe02e49e..ca7dcae4e 100644 --- a/tests/utils/openshift-client.go +++ b/tests/utils/openshift-client.go @@ -3,19 +3,18 @@ package utils import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" - "os" - "path/filepath" ) func GetOCClient() (*rest.Config, error) { - home, err := os.UserHomeDir() - if err != nil { - return nil, err - } - config, err := clientcmd.BuildConfigFromFlags("", filepath.Join(home, ".kube", "config")) + + kubeCfg := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + clientcmd.NewDefaultClientConfigLoadingRules(), + &clientcmd.ConfigOverrides{}, + ) + restCfg, err := kubeCfg.ClientConfig() if err != nil { return nil, err } - return config, nil + return restCfg, nil } diff --git a/tests/utils/project_names.go b/tests/utils/project_names.go new file mode 100644 index 000000000..38d2574f6 --- /dev/null +++ b/tests/utils/project_names.go @@ -0,0 +1,15 @@ +package utils + +var PROJECT_NAME = "unitt" +var PROJECT_ENV_VAR = "PROJECT_ID=" + PROJECT_NAME +var PROJECT_NAME_CD = PROJECT_NAME + "-cd" +var PROJECT_NAME_DEV = PROJECT_NAME + "-dev" +var PROJECT_NAME_TEST = PROJECT_NAME + "-test" + +func Set_project_name(project string) { + PROJECT_NAME = project + PROJECT_ENV_VAR = "PROJECT_ID=" + PROJECT_NAME + PROJECT_NAME_CD = PROJECT_NAME + "-cd" + PROJECT_NAME_DEV = PROJECT_NAME + "-dev" + PROJECT_NAME_TEST = PROJECT_NAME + "-test" +}