Skip to content

Commit 9d22934

Browse files
author
Benjamin Reed
committed
NMS-14759: enable (optimized) sonar in Foundation 2022
* (slightly) smarter cache handling for sonar * add support for the jacoco agent to horizon, minion, and sentinel startup scripts (`JACOCO_AGENT_ENABLED=1` env var) * enable jacoco coverage reports for smoke test runs of horizon (minion and sentinel don't allow vm: access for JMX) * push report-generation to the coverage (sonar.sh) run to synthesize integration and smoke test runs into a single report * update the coverage packing and unpacking scripts to handle multiple types of runs without stepping on filenames * backport some of my previous sonar improvements from develop
1 parent aa2d2d3 commit 9d22934

File tree

24 files changed

+489
-187
lines changed

24 files changed

+489
-187
lines changed

.circleci/config.yml

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,15 @@ commands:
289289
steps:
290290
- restore_cache:
291291
keys:
292-
- sonar-cache-v2-{{ checksum "pom-version-cache.key" }}
292+
- sonar-cache-v3-{{ .Branch }}-{{ checksum "pom-version-cache.key" }}-{{ .Revision }}
293+
- sonar-cache-v3-{{ .Branch }}-{{ checksum "pom-version-cache.key" }}-
294+
- sonar-cache-v3-{{ .Branch }}-
295+
- sonar-cache-v3-
293296
save-sonar-cache:
294297
description: "Sonar: Save sonar cache"
295298
steps:
296299
- save_cache:
297-
key: sonar-cache-v2-{{ checksum "pom-version-cache.key" }}
300+
key: sonar-cache-v3-{{ .Branch }}- {{ checksum "pom-version-cache.key" }}
298301
paths:
299302
- ~/.sonar
300303
dockerhub-login:
@@ -500,21 +503,22 @@ commands:
500503
when: always
501504
command: |
502505
mkdir -p ~/generated-tests
503-
cp ./surefire_classname* ~/generated-tests/ || :
504-
cp ./failsafe_classname* ~/generated-tests/ || :
505-
cp /tmp/this_node* ~/generated-tests/ || :
506+
cp target/find-tests/* ~/generated-tests/ || :
507+
cp /tmp/this_node* ~/generated-tests/ || :
506508
- when:
507509
condition: << parameters.run-code-coverage >>
508510
steps:
509511
- run:
510-
name: Compress Target Directories (Code Coverage)
512+
name: Save Code Coverage Data
511513
when: always
512514
command: |
513-
.circleci/scripts/codecoverage-save.sh
515+
.circleci/scripts/codecoverage-save.sh integration-test
514516
- persist_to_workspace:
515517
root: ~/
516518
paths:
517519
- code-coverage
520+
- project/target/find-tests
521+
- project/target/structure-graph.json
518522
- run:
519523
name: Gather system logs
520524
when: always
@@ -1583,11 +1587,19 @@ jobs:
15831587
changes-only: false
15841588
code-coverage:
15851589
executor: centos-build-executor
1586-
resource_class: large
1590+
resource_class: xlarge
15871591
steps:
15881592
- attach_workspace:
15891593
at: ~/
1594+
- checkout
1595+
- cached-download:
1596+
url: https://repo1.maven.org/maven2/org/jacoco/org.jacoco.cli/0.8.8/org.jacoco.cli-0.8.8-nodeps.jar
1597+
file: /tmp/jacoco-cli.jar
1598+
- cached-download:
1599+
url: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747.zip
1600+
file: /tmp/sonar-scanner-cli.zip
15901601
- extract-pom-version
1602+
- restore-maven-cache
15911603
- restore-sonar-cache
15921604
- run:
15931605
name: Restore Target Directories (Code Coverage)
@@ -1598,7 +1610,7 @@ jobs:
15981610
name: Run SonarQube Code Analysis
15991611
when: always
16001612
command: |
1601-
export MAVEN_OPTS="-Xms3G -Xmx3G"
1613+
export MAVEN_OPTS="-Xms1g -Xmx12g"
16021614
.circleci/scripts/sonar.sh
16031615
- save-sonar-cache
16041616
smoke-test-core:
@@ -1665,7 +1677,7 @@ jobs:
16651677
suite: minion
16661678
smoke-test-sentinel:
16671679
executor: smoke-test-executor
1668-
parallelism: 5
1680+
parallelism: 4
16691681
# No resource class support for machine executors, we're constrained to use the default
16701682
# medium class which has 2 vCPUs and 8 GB RAM
16711683
#resource_class: large

.circleci/scripts/codecoverage-restore.sh

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
#!/bin/sh -e
2-
cd ~/project
3-
for file in ~/code-coverage/target-*.zip; do
1+
#!/bin/bash
2+
3+
set -e
4+
set -o pipefail
5+
6+
for file in ~/code-coverage/*.zip; do
47
FILENAME="$(basename "$file")"
58
NUMBER="$(echo "$FILENAME" | cut -d. -f1 | cut -d- -f2-)"
69
echo "* unpacking coverage reports $NUMBER:"
710
unzip -qo "$file"
8-
find . -type d -name failsafe-reports -o -name surefire-reports | while read DIR; do
11+
find . -type d '!' -path './.git/*' \( -name failsafe-reports -o -name surefire-reports -o -name jacoco -o -name coverage \) | while read -r DIR; do
912
mkdir -p "${DIR}-${NUMBER}"
1013
mv "${DIR}"/* "${DIR}-${NUMBER}/"
1114
rm -rf "${DIR}"
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
#!/bin/sh -e
2-
cd ~/project
1+
#!/bin/bash
2+
3+
TYPE="$1"; shift
4+
[ -z "$TYPE" ] && TYPE="coverage"
5+
6+
set -e
7+
set -o pipefail
8+
39
mkdir -p ~/code-coverage
4-
find . -type d | grep -E ".*/target$" | zip ~/code-coverage/target-"$CIRCLE_NODE_INDEX.zip" -9r@ -x \*.gz -x \*.zip -x \*.war -x \*target/dist\* -x \*/node/\* -x \*target/unpacked/\*
10+
11+
find . -type f '!' -path './.git/*' '!' -path '*/node_modules/*' '!' -name '*.jar' '!' -name '*.sh' | grep -E '(surefire-reports|failsafe-reports|jacoco|coverage)' > /tmp/coverage-files.txt
12+
if [ -s /tmp/coverage-files.txt ]; then
13+
zip '-9@' ~/code-coverage/${TYPE}-"${CIRCLE_NODE_INDEX}.zip" < /tmp/coverage-files.txt
14+
fi

.circleci/scripts/itest.sh

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
#!/bin/sh
1+
#!/bin/bash
22

33
set -e
44

5+
FIND_TESTS_DIR="target/find-tests"
6+
57
# attempt to work around repository flakiness
68
retry()
79
{
@@ -10,34 +12,38 @@ retry()
1012

1113
find_tests()
1214
{
15+
mkdir -p "${FIND_TESTS_DIR}"
16+
17+
echo "#### Generate project structure .json"
18+
./compile.pl -s .circleci/scripts/structure-settings.xml --batch-mode --fail-at-end -Prun-expensive-tasks -Pbuild-bamboo org.opennms.maven.plugins:structure-maven-plugin:1.0:structure
19+
1320
# Generate surefire & failsafe test list based on current
1421
# branch and the list of files changed
1522
# (The format of the output files contains the canonical class names i.e. org.opennms.core.soa.filter.FilterTest)
16-
pyenv local 3.8.5
1723
python3 .circleci/scripts/find-tests/find-tests.py generate-test-lists \
1824
--changes-only="${CCI_CHANGES_ONLY:-true}" \
19-
--output-unit-test-classes=surefire_classnames \
20-
--output-integration-test-classes=failsafe_classnames \
25+
--output-unit-test-classes="${FIND_TESTS_DIR}/surefire_classnames" \
26+
--output-integration-test-classes="${FIND_TESTS_DIR}/failsafe_classnames" \
2127
.
2228

2329
# Now determine the tests for this particular container based on the parallelism level and the test timings
24-
< surefire_classnames circleci tests split --split-by=timings --timings-type=classname > /tmp/this_node_tests
25-
< failsafe_classnames circleci tests split --split-by=timings --timings-type=classname > /tmp/this_node_it_tests
30+
< "${FIND_TESTS_DIR}/surefire_classnames" circleci tests split --split-by=timings --timings-type=classname > /tmp/this_node_tests
31+
< "${FIND_TESTS_DIR}/failsafe_classnames" circleci tests split --split-by=timings --timings-type=classname > /tmp/this_node_it_tests
2632

2733
# Now determine the Maven modules related to the tests we need to run
2834
cat /tmp/this_node* | python3 .circleci/scripts/find-tests/find-tests.py generate-test-modules \
2935
--output=/tmp/this_node_projects \
3036
.
3137
}
3238

33-
echo "#### Making sure git is up-to-date"
34-
git fetch --all
39+
. ./.circleci/scripts/lib.sh
40+
41+
REFERENCE_BRANCH="$(get_reference_branch || echo "develop")"
3542

36-
echo "#### Generate project structure .json"
37-
./compile.pl -s .circleci/scripts/structure-settings.xml --batch-mode --fail-at-end -Prun-expensive-tasks -Pbuild-bamboo org.opennms.maven.plugins:structure-maven-plugin:1.0:structure
43+
echo "#### Making sure git is up-to-date"
44+
git fetch origin "${REFERENCE_BRANCH}"
3845

3946
echo "#### Determining tests to run"
40-
cd ~/project
4147
find_tests
4248
if [ ! -s /tmp/this_node_projects ]; then
4349
echo "No tests to run."
@@ -51,7 +57,6 @@ echo "#### Allowing non-root ICMP"
5157
sudo sysctl net.ipv4.ping_group_range='0 429496729'
5258

5359
echo "#### Setting up Postgres"
54-
cd ~/project
5560
./.circleci/scripts/postgres.sh
5661

5762
echo "#### Installing other dependencies"
@@ -96,46 +101,57 @@ export MAVEN_OPTS="$MAVEN_OPTS -Xmx8g -XX:ReservedCodeCacheSize=1g"
96101
# shellcheck disable=SC3045
97102
ulimit -n 65536
98103

99-
MAVEN_ARGS="install"
104+
MAVEN_ARGS=()
100105

101106
case "${CIRCLE_BRANCH}" in
102107
"master"*|"release-"*|develop)
103-
MAVEN_ARGS="-Dbuild.type=production $MAVEN_ARGS"
108+
MAVEN_ARGS=("-Dbuild.type=production" "${MAVEN_ARGS[@]}")
104109
;;
105110
esac
106111

112+
# if node tests does not exist or is empty, skip surefire
113+
if [ ! -s /tmp/this_node_tests ]; then
114+
MAVEN_ARGS+=("-DskipSurefire=true")
115+
fi
116+
117+
# if node ITs does not exist or is empty, skip surefire
118+
if [ ! -s /tmp/this_node_it_tests ]; then
119+
MAVEN_ARGS+=("-DskipFailsafe=true")
120+
fi
121+
122+
MAVEN_COMMANDS=("install")
123+
107124
echo "#### Building Assembly Dependencies"
108-
./compile.pl $MAVEN_ARGS \
125+
./compile.pl "${MAVEN_ARGS[@]}" \
109126
-P'!checkstyle' \
110127
-P'!production' \
111128
-Pbuild-bamboo \
112129
-Dbuild.skip.tarball=true \
113130
-Dmaven.test.skip.exec=true \
114131
-DskipTests=true \
115132
-DskipITs=true \
116-
-Dci.instance="${CIRCLE_NODE_INDEX:-0}" \
117133
--batch-mode \
118134
"${CCI_FAILURE_OPTION:--fae}" \
119135
--also-make \
120-
--projects "$(< /tmp/this_node_projects paste -s -d, -)"
136+
--projects "$(< /tmp/this_node_projects paste -s -d, -)" \
137+
install
121138

122139
echo "#### Executing tests"
123-
./compile.pl $MAVEN_ARGS \
140+
./compile.pl "${MAVEN_ARGS[@]}" \
124141
-P'!checkstyle' \
125142
-P'!production' \
126143
-Pbuild-bamboo \
144+
-Pcoverage \
127145
-Dbuild.skip.tarball=true \
128146
-DfailIfNoTests=false \
129147
-DskipITs=false \
130-
-Dci.instance="${CIRCLE_NODE_INDEX:-0}" \
131148
-Dci.rerunFailingTestsCount="${CCI_RERUN_FAILTEST:-0}" \
132-
-Dcode.coverage="${CCI_CODE_COVERAGE:-false}" \
133149
--batch-mode \
134150
"${CCI_FAILURE_OPTION:--fae}" \
135151
-Dorg.opennms.core.test-api.dbCreateThreads=1 \
136152
-Dorg.opennms.core.test-api.snmp.useMockSnmpStrategy=false \
137153
-Djava.security.egd=file:/dev/./urandom \
138154
-Dtest="$(< /tmp/this_node_tests paste -s -d, -)" \
139155
-Dit.test="$(< /tmp/this_node_it_tests paste -s -d, -)" \
140-
--projects "$(< /tmp/this_node_projects paste -s -d, -)"
141-
156+
--projects "$(< /tmp/this_node_projects paste -s -d, -)" \
157+
install

.circleci/scripts/lib.sh

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,37 @@
11
#!/bin/bash
22

3-
# this will return "1" for versions without -SNAPSHOT, and "0" for versions with
4-
ONMS_MAJOR_REVISION="$(grep '<version>' pom.xml | head -n 1 | grep -c -v -- -SNAPSHOT)"
3+
OPENNMS_POM_VERSION="$(~/project/.circleci/scripts/pom2version.sh ~/project/pom.xml || echo "0.0.0")"
4+
OPENNMS_VERSION="$(echo "${OPENNMS_POM_VERSION}" | sed -e 's,^\([0-9\.][0-9\.]*\).*$,\1,g')"
5+
OPENNMS_SHORT_VERSION="$(echo "${OPENNMS_VERSION}" | cut -d. -f 1-2)"
6+
OPENNMS_MAJOR_VERSION="$(echo "${OPENNMS_VERSION}" | cut -d. -f1)"
7+
8+
# if $CIRCLE_BRANCH is not set, tag it as a "local" build
9+
DOCKER_TAGS=("local" "latest")
10+
11+
if [ -n "${CIRCLE_BRANCH}" ]; then
12+
# If $CIRCLE_BRANCH _is_ set, dump the local and latest tags,
13+
# and instead set tags based on the branch.
14+
15+
# Always include $CIRCLE_BRANCH with "/" turned into "-".
16+
DOCKER_BRANCH_TAG="${CIRCLE_BRANCH//\//-}"
17+
DOCKER_TAGS=("${DOCKER_BRANCH_TAG}")
518

19+
# In addition, set a few extra tag aliases for convenience.
20+
case "${CIRCLE_BRANCH}" in
21+
"master-"*)
22+
DOCKER_TAGS=("${DOCKER_TAGS[@]}" "${OPENNMS_VERSION}" "${OPENNMS_SHORT_VERSION}-latest" "${OPENNMS_MAJOR_VERSION}-latest" "latest")
23+
;;
24+
"release-"*)
25+
DOCKER_TAGS=("${DOCKER_TAGS[@]}" "${OPENNMS_POM_VERSION}" "${OPENNMS_VERSION}-rc" "${OPENNMS_SHORT_VERSION}-rc" "${OPENNMS_MAJOR_VERSION}-rc" "release-candidate")
26+
;;
27+
"develop")
28+
DOCKER_TAGS=("${DOCKER_TAGS[@]}" "${OPENNMS_POM_VERSION}" "${OPENNMS_MAJOR_VERSION}-dev" "bleeding")
29+
;;
30+
esac
31+
fi
32+
33+
# this will return "1" for versions without -SNAPSHOT, and "0" for versions with
34+
ONMS_MAJOR_REVISION="$(echo "${OPENNMS_POM_VERSION}" | (grep -c -v -- -SNAPSHOT || :))"
635
ONMS_MINOR_REVISION="$(date '+%Y%m%d')"
736
ONMS_MICRO_REVISION=1
837

@@ -12,7 +41,72 @@ if [ -n "$CIRCLE_BUILD_NUM" ] && [ -n "$CIRCLE_BRANCH" ]; then
1241
ONMS_MICRO_REVISION="${CIRCLE_BUILD_NUM}"
1342
fi
1443

44+
# get the PR number from CircleCI environment; caches on success
45+
__cache_pr_num=""
46+
get_pr_num() {
47+
if [ -z "${__cache_pr_num}" ]; then
48+
local _pr_num=0
49+
if [ -n "${CIRCLE_PULL_REQUEST}" ]; then
50+
_pr_num="$(echo "${CIRCLE_PULL_REQUEST}" | sed -e 's,.*/,,')"
51+
if [ -n "${_pr_num}" ] && [ "${_pr_num}" -gt 0 ]; then
52+
__cache_pr_num="${_pr_num}"
53+
fi
54+
fi
55+
__cache_pr_num=0
56+
fi
57+
if [ ! "${__cache_pr_num}" -gt 0 ]; then
58+
return 1
59+
fi
60+
echo "${__cache_pr_num}"
61+
}
62+
63+
# get the "reference" (merge/pr-parent) branch for this branch; caches on success
64+
__cache_reference_branch=""
65+
get_reference_branch() {
66+
if [ -z "${__cache_reference_branch}" ]; then
67+
local _parent_branch=""
68+
69+
local _pr_num="$(get_pr_num || echo 0)"
70+
71+
if [ "${_pr_num}" -gt 0 ] && [ -n "${GITHUB_API_TOKEN}" ]; then
72+
local _github_base="$(curl -s -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${GITHUB_API_TOKEN}" "https://api.github.com/repos/OpenNMS/opennms/pulls/${_pr_num}" | jq -r '.base.ref')"
73+
if [ -n "${_github_base}" ]; then
74+
__cache_reference_branch="${_github_base}"
75+
fi
76+
fi
77+
78+
if [ -z "${__cache_reference_branch}" ] && [ -e .nightly ]; then
79+
_parent_branch="$(cat .nightly | grep -E '^parent_branch:' | sed -e 's,parent_branch: *,,')"
80+
if [ -n "${_parent_branch}" ]; then
81+
__cache_reference_branch="${_parent_branch}"
82+
fi
83+
fi
84+
fi
85+
86+
if [ -n "${__cache_reference_branch}" ]; then
87+
echo "${__cache_reference_branch}"
88+
return 0
89+
fi
90+
91+
return 1
92+
}
93+
94+
# retry a command 3 times
95+
do_with_retries() {
96+
for try in 1 2 3; do
97+
if "$@"; then return 0; fi
98+
done
99+
return 1
100+
}
101+
15102
export \
103+
OPENNMS_POM_VERSION \
104+
OPENNMS_VERSION \
105+
OPENNMS_SHORT_VERSION \
106+
OPENNMS_MAJOR_VERSION \
107+
\
16108
ONMS_MAJOR_REVISION \
17109
ONMS_MINOR_REVISION \
18-
ONMS_MICRO_REVISION
110+
ONMS_MICRO_REVISION \
111+
\
112+
DOCKER_TAGS

0 commit comments

Comments
 (0)