Skip to content

Commit 9a32b17

Browse files
committed
CBG-4852 use gotestsum
1 parent bac1e43 commit 9a32b17

File tree

2 files changed

+68
-75
lines changed

2 files changed

+68
-75
lines changed

Jenkinsfile

Lines changed: 57 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,9 @@ pipeline {
5252
}
5353
stage('Go Tools') {
5454
steps {
55-
// unhandled error checker
56-
sh 'go install github.com/kisielk/errcheck@latest'
5755
// goveralls is used to send coverprofiles to coveralls.io
5856
sh 'go install github.com/mattn/goveralls@latest'
59-
// Jenkins test reporting tools
60-
sh 'go install github.com/tebeka/go2xunit@latest'
57+
sh 'go install gotest.tools/gotestsum@latest'
6158
}
6259
}
6360
}
@@ -90,89 +87,86 @@ pipeline {
9087
stage('CE') {
9188
when { branch 'main' }
9289
steps {
93-
// Travis-related variables are required as coveralls.io only officially supports a certain set of CI tools.
94-
withEnv(["PATH+GO=${env.GOTOOLS}/bin", "TRAVIS_BRANCH=${env.BRANCH}", "TRAVIS_PULL_REQUEST=${env.CHANGE_ID}", "TRAVIS_JOB_ID=${env.BUILD_NUMBER}"]) {
95-
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-ce-unit-tests', description: 'CE Unit Tests Running', status: 'PENDING')
96-
97-
// Build CE coverprofiles
98-
sh '2>&1 go test -shuffle=on -timeout=20m -coverpkg=./... -coverprofile=cover_ce.out -race -count=1 -v ./... > verbose_ce.out.raw || true'
99-
100-
// Print total coverage stats
101-
sh 'go tool cover -func=cover_ce.out | awk \'END{print "Total SG CE Coverage: " $3}\''
102-
103-
sh 'mkdir -p reports'
104-
105-
// strip non-printable characters from the raw verbose test output
106-
sh 'LC_CTYPE=C tr -dc [:print:][:space:] < verbose_ce.out.raw > verbose_ce.out'
107-
108-
// Grab test fail/total counts so we can print them later
109-
sh "grep '\\-\\-\\- PASS: ' verbose_ce.out | wc -l | awk '{printf \$1}' > test-ce-pass.count"
110-
sh "grep '\\-\\-\\- FAIL: ' verbose_ce.out | wc -l | awk '{printf \$1}' > test-ce-fail.count"
111-
sh "grep '\\-\\-\\- SKIP: ' verbose_ce.out | wc -l | awk '{printf \$1}' > test-ce-skip.count"
112-
sh "grep '=== RUN' verbose_ce.out | wc -l | awk '{printf \$1}' > test-ce-total.count"
113-
script {
90+
script {
91+
// Travis-related variables are required as coveralls.io only officially supports a certain set of CI tools.
92+
withEnv(["PATH+GO=${env.GOTOOLS}/bin", "TRAVIS_BRANCH=${env.BRANCH}", "TRAVIS_PULL_REQUEST=${env.CHANGE_ID}", "TRAVIS_JOB_ID=${env.BUILD_NUMBER}"]) {
93+
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-ce-unit-tests', description: 'CE Unit Tests Running', status: 'PENDING')
94+
95+
// --junitfile-project-name is used so that Jenkins doesn't collapse CE and EE results together.
96+
def testExitCode = sh(
97+
script: 'gotestsum --junitfile=test-ce.xml --junitfile-project-name CE --junitfile-testcase-classname relative --format standard-verbose -- -shuffle=on -timeout=20m -coverpkg=./... -coverprofile=cover_ce.out -race -count=1 ./... > verbose_ce.out',
98+
returnStatus: true,
99+
)
100+
101+
// convert the junit file to prepend CE- to all test names to differentiate from EE tests
102+
sh '''xmlstarlet ed -u '//testcase/@classname' -x 'concat("CE-", .)' test-ce.xml > reports/test-ce.xml'''
103+
104+
// Print total coverage stats
105+
sh 'go tool cover -func=cover_ce.out | awk \'END{print "Total SG CE Coverage: " $3}\''
106+
107+
sh 'mkdir -p reports'
108+
109+
// Grab test fail/total counts so we can print them later
110+
sh "grep '\\-\\-\\- PASS: ' verbose_ce.out | wc -l | awk '{printf \$1}' > test-ce-pass.count"
111+
sh "grep '\\-\\-\\- FAIL: ' verbose_ce.out | wc -l | awk '{printf \$1}' > test-ce-fail.count"
112+
sh "grep '\\-\\-\\- SKIP: ' verbose_ce.out | wc -l | awk '{printf \$1}' > test-ce-skip.count"
113+
sh "grep '=== RUN' verbose_ce.out | wc -l | awk '{printf \$1}' > test-ce-total.count"
114114
env.TEST_CE_PASS = readFile 'test-ce-pass.count'
115115
env.TEST_CE_FAIL = readFile 'test-ce-fail.count'
116116
env.TEST_CE_SKIP = readFile 'test-ce-skip.count'
117117
env.TEST_CE_TOTAL = readFile 'test-ce-total.count'
118-
}
119118

120-
// Generate junit-formatted test report
121-
script {
122-
try {
123-
sh 'which go2xunit' // check if go2xunit is installed
124-
sh 'go2xunit -fail -suite-name-prefix="CE-" -input verbose_ce.out -output reports/test-ce.xml'
119+
if (testExitCode == 0) {
125120
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-ce-unit-tests', description: env.TEST_CE_PASS + '/' + env.TEST_CE_TOTAL + ' passed (' + env.TEST_CE_SKIP + ' skipped)', status: 'SUCCESS')
126-
} catch (Exception e) {
121+
} else {
127122
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-ce-unit-tests', description: env.TEST_CE_FAIL + '/' + env.TEST_CE_TOTAL + ' failed (' + env.TEST_CE_SKIP + ' skipped)', status: 'FAILURE')
128123
// archive verbose test logs in the event of a test failure
129124
archiveArtifacts artifacts: 'verbose_ce.out', fingerprint: false
130125
unstable('At least one CE unit test failed')
131126
}
132-
}
133127

134-
// Publish CE coverage to coveralls.io
135-
// Replace covermode values with set just for coveralls to reduce the variability in reports.
136-
sh 'awk \'NR==1{print "mode: set";next} $NF>0{$NF=1} {print}\' cover_ce.out > cover_ce_coveralls.out'
137-
sh 'which goveralls' // check if goveralls is installed
138-
sh 'goveralls -coverprofile=cover_ce_coveralls.out -service=uberjenkins -repotoken=$COVERALLS_TOKEN || true'
128+
// Publish CE coverage to coveralls.io
129+
// Replace covermode values with set just for coveralls to reduce the variability in reports.
130+
sh 'awk \'NR==1{print "mode: set";next} $NF>0{$NF=1} {print}\' cover_ce.out > cover_ce_coveralls.out'
131+
sh 'which goveralls' // check if goveralls is installed
132+
sh 'goveralls -coverprofile=cover_ce_coveralls.out -service=uberjenkins -repotoken=$COVERALLS_TOKEN || true'
133+
}
139134
}
140135
}
141136
}
142137

143138
stage('EE') {
144139
steps {
145-
withEnv(["PATH+GO=${env.GOTOOLS}/bin"]) {
146-
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-ee-unit-tests', description: 'EE Unit Tests Running', status: 'PENDING')
147-
148-
// Build EE coverprofiles
149-
sh "2>&1 go test -shuffle=on -timeout=20m -tags ${EE_BUILD_TAG} -coverpkg=./... -coverprofile=cover_ee.out -race -count=1 -v ./... > verbose_ee.out.raw || true"
150-
151-
sh 'go tool cover -func=cover_ee.out | awk \'END{print "Total SG EE Coverage: " $3}\''
152-
153-
sh 'mkdir -p reports'
154-
155-
// strip non-printable characters from the raw verbose test output
156-
sh 'LC_CTYPE=C tr -dc [:print:][:space:] < verbose_ee.out.raw > verbose_ee.out'
157-
158-
// Grab test fail/total counts so we can print them later
159-
sh "grep '\\-\\-\\- PASS: ' verbose_ee.out | wc -l | awk '{printf \$1}' > test-ee-pass.count"
160-
sh "grep '\\-\\-\\- FAIL: ' verbose_ee.out | wc -l | awk '{printf \$1}' > test-ee-fail.count"
161-
sh "grep '\\-\\-\\- SKIP: ' verbose_ee.out | wc -l | awk '{printf \$1}' > test-ee-skip.count"
162-
sh "grep '=== RUN' verbose_ee.out | wc -l | awk '{printf \$1}' > test-ee-total.count"
163-
script {
140+
script {
141+
withEnv(["PATH+GO=${env.GOTOOLS}/bin"]) {
142+
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-ee-unit-tests', description: 'EE Unit Tests Running', status: 'PENDING')
143+
144+
// --junitfile-project-name is used so that Jenkins doesn't collapse CE and EE results together.
145+
def testExitCode = sh(
146+
script: "gotestsum --junitfile=test-ee.xml --junitfile-project-name EE --junitfile-testcase-classname relative --format standard-verbose -- -shuffle=on -timeout=20m -tags ${EE_BUILD_TAG} -coverpkg=./... -coverprofile=cover_ee.out -race -count=1 ./... 2>&1 > verbose_ee.out",
147+
returnStatus: true,
148+
)
149+
sh 'mkdir -p reports'
150+
151+
// convert the junit file to prepend EE- to all test names to differentiate from EE tests
152+
sh '''xmlstarlet ed -u '//testcase/@classname' -x 'concat("EE-", .)' test-ee.xml > reports/test-ee.xml'''
153+
154+
sh 'go tool cover -func=cover_ee.out | awk \'END{print "Total SG EE Coverage: " $3}\''
155+
156+
// Grab test fail/total counts so we can print them later
157+
sh "grep '\\-\\-\\- PASS: ' verbose_ee.out | wc -l | awk '{printf \$1}' > test-ee-pass.count"
158+
sh "grep '\\-\\-\\- FAIL: ' verbose_ee.out | wc -l | awk '{printf \$1}' > test-ee-fail.count"
159+
sh "grep '\\-\\-\\- SKIP: ' verbose_ee.out | wc -l | awk '{printf \$1}' > test-ee-skip.count"
160+
sh "grep '=== RUN' verbose_ee.out | wc -l | awk '{printf \$1}' > test-ee-total.count"
164161
env.TEST_EE_PASS = readFile 'test-ee-pass.count'
165162
env.TEST_EE_FAIL = readFile 'test-ee-fail.count'
166163
env.TEST_EE_SKIP = readFile 'test-ee-skip.count'
167164
env.TEST_EE_TOTAL = readFile 'test-ee-total.count'
168-
}
169165

170-
// Generate junit-formatted test report
171-
script {
172-
try {
173-
sh 'go2xunit -fail -suite-name-prefix="EE-" -input verbose_ee.out -output reports/test-ee.xml'
166+
// Generate junit-formatted test report
167+
if (testExitCode == 0) {
174168
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-ee-unit-tests', description: env.TEST_EE_PASS + '/' + env.TEST_EE_TOTAL + ' passed (' + env.TEST_EE_SKIP + ' skipped)', status: 'SUCCESS')
175-
} catch (Exception e) {
169+
} else {
176170
githubNotify(credentialsId: "${GH_ACCESS_TOKEN_CREDENTIAL}", context: 'sgw-pipeline-ee-unit-tests', description: env.TEST_EE_FAIL + '/' + env.TEST_EE_TOTAL + ' failed (' + env.TEST_EE_SKIP + ' skipped)', status: 'FAILURE')
177171
// archive verbose test logs in the event of a test failure
178172
archiveArtifacts artifacts: 'verbose_ee.out', fingerprint: false

jenkins-integration-build.sh

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,15 @@ if [ "${SG_TEST_PROFILE_FREQUENCY:-}" == "true" ]; then
109109
fi
110110

111111
if [ "${RUN_WALRUS}" == "true" ]; then
112+
set +e
112113
# EE
113-
go test -coverprofile=coverage_walrus_ee.out -coverpkg=github.com/couchbase/sync_gateway/... -tags cb_sg_devmode,cb_sg_enterprise $GO_TEST_FLAGS github.com/couchbase/sync_gateway/${TARGET_PACKAGE} > verbose_unit_ee.out.raw 2>&1 | true
114+
gotestsum --junitfile=rosmar-ee.xml --junitfile-project-name rosmar-EE --junitfile-testcase-classname relative --format standard-verbose -- -coverprofile=coverage_walrus_ee.out -coverpkg=github.com/couchbase/sync_gateway/... -tags cb_sg_devmode,cb_sg_enterprise $GO_TEST_FLAGS github.com/couchbase/sync_gateway/${TARGET_PACKAGE} > verbose_unit_ee.out 2>&1
115+
xmlstarlet ed -u '//testcase/@classname' -x 'concat("rosmar-EE-", .)' rosmar-ee.xml > verbose_unit_ee.xml
114116
# CE
115-
go test -coverprofile=coverage_walrus_ce.out -coverpkg=github.com/couchbase/sync_gateway/... -tags cb_sg_devmode $GO_TEST_FLAGS github.com/couchbase/sync_gateway/${TARGET_PACKAGE} > verbose_unit_ce.out.raw 2>&1 | true
117+
gotestsum --junitfile=rosmar-ce.xml --junitfile-project-name rosmar-CE --junitfile-testcase-classname relative --format standard-verbose -- -coverprofile=coverage_walrus_ce.out -coverpkg=github.com/couchbase/sync_gateway/... -tags cb_sg_devmode $GO_TEST_FLAGS github.com/couchbase/sync_gateway/${TARGET_PACKAGE} > verbose_unit_ce.out 2>&1
118+
xmlstarlet ed -u '//testcase/@classname' -x 'concat("rosmar-CE-", .)' rosmar-ce.xml > verbose_unit_ce.xml
119+
set -e
120+
116121
fi
117122

118123
# Run CBS
@@ -141,26 +146,20 @@ else
141146
GO_TEST_FLAGS="${GO_TEST_FLAGS} -tags cb_sg_devmode"
142147
fi
143148

144-
go test ${GO_TEST_FLAGS} -coverprofile=coverage_int.out -coverpkg=github.com/couchbase/sync_gateway/... github.com/couchbase/sync_gateway/${TARGET_PACKAGE} 2>&1 | stdbuf -oL tee "${INT_LOG_FILE_NAME}.out.raw" | stdbuf -oL grep -a -E '(--- (FAIL|PASS|SKIP):|github.com/couchbase/sync_gateway(/.+)?\t|TEST: |panic: )'
149+
gotestsum --junitfile=integration.xml --junitfile-project-name integration --junitfile-testcase-classname relative --format standard-verbose -- ${GO_TEST_FLAGS} -coverprofile=coverage_int.out -coverpkg=github.com/couchbase/sync_gateway/... github.com/couchbase/sync_gateway/${TARGET_PACKAGE} 2>&1 | stdbuf -oL tee "${INT_LOG_FILE_NAME}.out" | stdbuf -oL grep -a -E '(--- (FAIL|PASS|SKIP):|github.com/couchbase/sync_gateway(/.+)?\t|TEST: |panic: )'
145150
if [ "${PIPESTATUS[0]}" -ne "0" ]; then # If test exit code is not 0 (failed)
146151
echo "Go test failed! Parsing logs to find cause..."
147152
TEST_FAILED=true
148153
fi
149154

150155
# Collect CBS logs if server error occurred
151-
if [ "${SG_CBCOLLECT_ALWAYS:-}" == "true" ] || grep -a -q "server logs for details\|Timed out after 1m0s waiting for a bucket to become available" "${INT_LOG_FILE_NAME}.out.raw"; then
156+
if [ "${SG_CBCOLLECT_ALWAYS:-}" == "true" ] || grep -a -q "server logs for details\|Timed out after 1m0s waiting for a bucket to become available" "${INT_LOG_FILE_NAME}.out"; then
152157
docker exec -t couchbase /opt/couchbase/bin/cbcollect_info /workspace/cbcollect.zip
153158
fi
154159

155-
# Generate xunit test report that can be parsed by the JUnit Plugin
156-
LC_CTYPE=C tr -dc [:print:][:space:] < ${INT_LOG_FILE_NAME}.out.raw > ${INT_LOG_FILE_NAME}.out # Strip non-printable characters
157-
~/go/bin/go2xunit -input "${INT_LOG_FILE_NAME}.out" -output "${INT_LOG_FILE_NAME}.xml"
160+
# If rosmar tests were run, then prepend classname with integration to tell them apart
158161
if [ "${RUN_WALRUS}" == "true" ]; then
159-
# Strip non-printable characters before xml creation
160-
LC_CTYPE=C tr -dc [:print:][:space:] < "verbose_unit_ee.out.raw" > "verbose_unit_ee.out"
161-
LC_CTYPE=C tr -dc [:print:][:space:] < "verbose_unit_ce.out.raw" > "verbose_unit_ce.out"
162-
~/go/bin/go2xunit -input "verbose_unit_ee.out" -output "verbose_unit_ee.xml"
163-
~/go/bin/go2xunit -input "verbose_unit_ce.out" -output "verbose_unit_ce.xml"
162+
xmlstarlet ed -u '//testcase/@classname' -x 'concat("integration-EE-", .)' integration.xml > "${INT_LOG_FILE_NAME}.xml"
164163
fi
165164

166165
# Get coverage

0 commit comments

Comments
 (0)