Skip to content

Commit ea42a5e

Browse files
committed
refactor(ci): move test logic from Makefile to run_tests.sh
Move all test running logic from the Makefile into a new Bash script `.github/run_tests.sh`.
1 parent e8d1e47 commit ea42a5e

File tree

3 files changed

+216
-85
lines changed

3 files changed

+216
-85
lines changed

.github/regression.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export CARDANO_NODE_SOCKET_PATH_CI="$WORKDIR/state-cluster0/bft1.socket"
9191
# assume we run tests on testnet when `BOOTSTRAP_DIR` is set
9292
if [ -n "${BOOTSTRAP_DIR:-""}" ]; then
9393
export CARDANO_NODE_SOCKET_PATH_CI="$WORKDIR/state-cluster0/relay1.socket"
94-
export MAKE_TARGET="${MAKE_TARGET:-"testnets"}"
94+
export RUN_TARGET="${RUN_TARGET:-"testnets"}"
9595
fi
9696

9797
echo "### Dependencies setup ###"
@@ -227,7 +227,7 @@ nix develop --accept-flake-config .#venv --command bash -c '
227227
export PATH="$PATH_PREPEND":"$PATH"
228228
export CARDANO_NODE_SOCKET_PATH="$CARDANO_NODE_SOCKET_PATH_CI"
229229
retval=0
230-
make "${MAKE_TARGET:-"tests"}" || retval="$?"
230+
. .github/run_tests.sh "${RUN_TARGET:-"tests"}" || retval="$?"
231231
df -h .
232232
echo "::endgroup::" # end group for "Testrun"
233233

.github/run_tests.sh

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
#!/usr/bin/env bash
2+
3+
# Run test suites.
4+
#
5+
# Targets: tests | testpr | testnets
6+
# Usage:
7+
# ./run_tests.sh tests
8+
# ./run_tests.sh testpr
9+
# ./run_tests.sh testnets
10+
#
11+
# Env vars:
12+
# TESTS_DIR: directory with tests to run (default: cardano_node_tests/)
13+
# ARTIFACTS_DIR: directory to save artifacts into (default: .artifacts)
14+
# COVERAGE_DIR: directory to save CLI coverage data into (default: .cli_coverage)
15+
# REPORTS_DIR: directory to save Allure test reports into (default: .reports)
16+
# MARKEXPR: pytest mark expression to filter tests, without the `-m` flag
17+
# NO_ARTIFACTS: if set, do not save artifacts
18+
# PYTEST_ARGS: additional args to pass to pytest
19+
# CI_ARGS: additional args to pass to pytest (for CI runs)
20+
# TEST_THREADS: number of pytest workers (defaults vary per target)
21+
# DESELECT_FROM_FILE: path to file with tests to deselect
22+
# CLUSTERS_COUNT: number of local testnet clusters to launch
23+
# FORBID_RESTART: if set to 1, do not restart clusters between tests
24+
#
25+
# Notes:
26+
# - If PYTEST_ARGS is provided, we disable cleanup and the initial "skip all" pass.
27+
# - If DESELECT_FROM_FILE is provided, we disable the initial "skip all" pass.
28+
# - If NO_ARTIFACTS is unset, we save artifacts under ARTIFACTS_DIR.
29+
# - HTML/JUnit reports are generated only when PYTEST_ARGS is unset.
30+
31+
set -Eeuo pipefail
32+
33+
# Defaults
34+
TESTS_DIR="${TESTS_DIR:-cardano_node_tests/}"
35+
ARTIFACTS_DIR="${ARTIFACTS_DIR:-.artifacts}"
36+
COVERAGE_DIR="${COVERAGE_DIR:-.cli_coverage}"
37+
REPORTS_DIR="${REPORTS_DIR:-.reports}"
38+
39+
# Helpers
40+
usage() {
41+
cat <<EOF
42+
Usage: "$0" [tests|testpr|testnets]
43+
44+
Targets:
45+
tests Run all tests (default TEST_THREADS=20), DbSyncAbortOnPanic=1
46+
testpr Run PR-level tests (default CLUSTERS_COUNT=5, TEST_THREADS=20, MARKEXPR="smoke")
47+
testnets Run tests that can run on public testnets (CLUSTERS_COUNT=1, FORBID_RESTART=1,
48+
default TEST_THREADS=15, MARKEXPR="testnets")
49+
50+
All targets respect the same env vars as the original Makefile.
51+
EOF
52+
}
53+
54+
pytest_w_echo() {
55+
echo "Running: PYTEST_ADDOPTS='${PYTEST_ADDOPTS:-}' pytest $*"
56+
pytest "$@"
57+
}
58+
59+
ensure_dirs() {
60+
mkdir -p "$ARTIFACTS_DIR" "$COVERAGE_DIR" "$REPORTS_DIR"
61+
}
62+
63+
# Set common env vars that affect test runs.
64+
set_common_env() {
65+
# Cleanup / skip logic
66+
CLEANUP="yes"
67+
RUN_SKIPS="yes"
68+
69+
if [[ -n "${PYTEST_ARGS:-}" ]]; then
70+
CLEANUP="no"
71+
RUN_SKIPS="no"
72+
export PYTEST_ADDOPTS="${PYTEST_ADDOPTS:+$PYTEST_ADDOPTS }${PYTEST_ARGS}"
73+
fi
74+
75+
if [[ -n "${DESELECT_FROM_FILE:-}" ]]; then
76+
RUN_SKIPS="no"
77+
fi
78+
79+
if [[ -n "${CI_ARGS:-}" ]]; then
80+
export PYTEST_ADDOPTS="${PYTEST_ADDOPTS:+$PYTEST_ADDOPTS }${CI_ARGS}"
81+
fi
82+
}
83+
84+
# Compute args that depend on current environment.
85+
compute_common_args() {
86+
# MARKEXPR handling
87+
if [[ -n "${MARKEXPR:-}" ]]; then
88+
MARKEXPR_ARR=( -m "$MARKEXPR" )
89+
else
90+
MARKEXPR_ARR=()
91+
fi
92+
93+
# It may not be always necessary to save artifacts, e.g. when running tests on local cluster
94+
# on local machine.
95+
if [[ -n "${NO_ARTIFACTS+x}" ]]; then
96+
ARTIFACTS_ARR=()
97+
else
98+
ARTIFACTS_ARR=( "--artifacts-base-dir=$ARTIFACTS_DIR" )
99+
fi
100+
101+
# Test run report args only when PYTEST_ARGS is unset.
102+
if [[ -z "${PYTEST_ARGS:-}" ]]; then
103+
TESTRUN_REPORT_ARR=(
104+
"--html=$REPORTS_DIR/testrun-report.html"
105+
"--self-contained-html"
106+
"--junitxml=$REPORTS_DIR/testrun-report.xml"
107+
)
108+
else
109+
TESTRUN_REPORT_ARR=()
110+
fi
111+
112+
# Deselect-from-file
113+
if [[ -n "${DESELECT_FROM_FILE:-}" ]]; then
114+
DESELECT_FROM_FILE_ARR=( "--deselect-from-file=$DESELECT_FROM_FILE" )
115+
else
116+
DESELECT_FROM_FILE_ARR=()
117+
fi
118+
}
119+
120+
cleanup_previous_run() {
121+
if [[ "$CLEANUP" == "yes" ]]; then
122+
# Remove previous reports and coverage artifacts.
123+
rm -f "$REPORTS_DIR"/{*-attachment.txt,*-result.json,*-container.json,testrun-report.*} || true
124+
rm -f "$COVERAGE_DIR"/cli_coverage_* || true
125+
fi
126+
}
127+
128+
initial_skip_pass() {
129+
if [[ "$RUN_SKIPS" == "yes" ]]; then
130+
echo "Initial pass: skipping all tests to register them with Allure"
131+
pytest -s "$TESTS_DIR" "${MARKEXPR_ARR[@]}" --skipall --alluredir="$REPORTS_DIR" >/dev/null
132+
fi
133+
}
134+
135+
run_real_tests() {
136+
pytest_w_echo \
137+
"$TESTS_DIR" \
138+
"${MARKEXPR_ARR[@]}" \
139+
"${DESELECT_FROM_FILE_ARR[@]}" \
140+
-n "${TEST_THREADS}" \
141+
"${ARTIFACTS_ARR[@]}" \
142+
--cli-coverage-dir="$COVERAGE_DIR" \
143+
--alluredir="$REPORTS_DIR" \
144+
"${TESTRUN_REPORT_ARR[@]}" \
145+
"$@"
146+
}
147+
148+
# Provide default MARKEXPR if none was given from env/CLI.
149+
ensure_markexpr_default() {
150+
local default_expr="$1"
151+
if [[ -z "${MARKEXPR:-}" ]]; then
152+
MARKEXPR="$default_expr"
153+
fi
154+
}
155+
156+
# Targets
157+
target_tests() {
158+
export DbSyncAbortOnPanic="${DbSyncAbortOnPanic:-1}"
159+
TEST_THREADS="${TEST_THREADS:-20}"
160+
161+
ensure_dirs
162+
set_common_env
163+
compute_common_args
164+
cleanup_previous_run
165+
initial_skip_pass
166+
run_real_tests "$@"
167+
}
168+
169+
target_testpr() {
170+
export TESTPR=1
171+
export CLUSTERS_COUNT="${CLUSTERS_COUNT:-5}"
172+
TEST_THREADS="${TEST_THREADS:-20}"
173+
ensure_markexpr_default "smoke"
174+
175+
ensure_dirs
176+
set_common_env
177+
compute_common_args
178+
cleanup_previous_run
179+
initial_skip_pass
180+
run_real_tests "$@"
181+
}
182+
183+
target_testnets() {
184+
export CLUSTERS_COUNT=1
185+
export FORBID_RESTART=1
186+
TEST_THREADS="${TEST_THREADS:-15}"
187+
ensure_markexpr_default "testnets"
188+
189+
ensure_dirs
190+
set_common_env
191+
compute_common_args
192+
cleanup_previous_run
193+
initial_skip_pass
194+
run_real_tests "$@"
195+
}
196+
197+
# Dispatch
198+
main() {
199+
command -v pytest >/dev/null 2>&1 || {
200+
echo "Error: pytest not found in PATH." >&2
201+
exit 127
202+
}
203+
204+
local cmd="${1:-tests}"
205+
case "$cmd" in
206+
tests) shift; target_tests "$@";;
207+
testpr) shift; target_testpr "$@";;
208+
testnets) shift; target_testnets "$@";;
209+
-h|--help) usage;;
210+
*) echo "Unknown target: $cmd" >&2; usage; exit 2;;
211+
esac
212+
}
213+
214+
main "$@"

Makefile

Lines changed: 0 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -44,86 +44,3 @@ reinstall-editable:
4444
exit 1; \
4545
fi
4646
@./scripts/clusterlib_reinstall_editable.sh "$(repo)"
47-
48-
49-
# run tests
50-
51-
TESTS_DIR ?= cardano_node_tests/
52-
ARTIFACTS_DIR ?= .artifacts
53-
COVERAGE_DIR ?= .cli_coverage
54-
REPORTS_DIR ?= .reports
55-
56-
ifneq ($(MARKEXPR),)
57-
MARKEXPR := -m "$(MARKEXPR)"
58-
endif
59-
60-
# it may not be always necessary to save artifacts, e.g. when running tests on local cluster
61-
# on local machine
62-
ifndef NO_ARTIFACTS
63-
ARTIFACTS_ARGS := --artifacts-base-dir=$(ARTIFACTS_DIR)
64-
endif
65-
66-
ifndef PYTEST_ARGS
67-
TESTRUN_REPORT_ARGS := --html=$(REPORTS_DIR)/testrun-report.html --self-contained-html --junitxml=$(REPORTS_DIR)/testrun-report.xml
68-
endif
69-
70-
ifdef DESELECT_FROM_FILE
71-
DESELECT_FROM_FILE_ARGS := --deselect-from-file=$(DESELECT_FROM_FILE)
72-
endif
73-
74-
CLEANUP := yes
75-
RUN_SKIPS := yes
76-
77-
ifdef PYTEST_ARGS
78-
CLEANUP := no
79-
RUN_SKIPS := no
80-
endif
81-
82-
ifdef DESELECT_FROM_FILE
83-
RUN_SKIPS := no
84-
endif
85-
86-
.PHONY: .dirs
87-
.dirs:
88-
mkdir -p $(ARTIFACTS_DIR) $(COVERAGE_DIR) $(REPORTS_DIR)
89-
90-
.PHONY: .run_tests
91-
.run_tests:
92-
# delete artifacts from previous runs
93-
ifeq ($(CLEANUP),yes)
94-
rm -f $(REPORTS_DIR)/{*-attachment.txt,*-result.json,*-container.json,testrun-report.*}
95-
rm -f $(COVERAGE_DIR)/cli_coverage_*
96-
endif
97-
98-
# first just skip all tests so Allure has a list of all tests that were supposed to run
99-
ifeq ($(RUN_SKIPS),yes)
100-
pytest -s $(TESTS_DIR) $(MARKEXPR) --skipall --alluredir=$(REPORTS_DIR) >/dev/null
101-
endif
102-
103-
# run tests for real and produce Allure results
104-
pytest $(TESTS_DIR) $(PYTEST_ARGS) $(CI_ARGS) $(MARKEXPR) $(DESELECT_FROM_FILE_ARGS) -n $(TEST_THREADS) $(ARTIFACTS_ARGS) --cli-coverage-dir=$(COVERAGE_DIR) --alluredir=$(REPORTS_DIR) $(TESTRUN_REPORT_ARGS)
105-
106-
107-
# run all tests
108-
.PHONY: tests
109-
tests: export DbSyncAbortOnPanic=1
110-
tests: TEST_THREADS := $(or $(TEST_THREADS),20)
111-
tests: .dirs .run_tests
112-
113-
114-
# run tests that are supposed to run on PR level
115-
.PHONY: testpr
116-
testpr: export TESTPR=1
117-
testpr: export CLUSTERS_COUNT := $(or $(CLUSTERS_COUNT),5)
118-
testpr: TEST_THREADS := $(or $(TEST_THREADS),20)
119-
testpr: MARKEXPR := $(or $(MARKEXPR),-m "smoke")
120-
testpr: .dirs .run_tests
121-
122-
123-
# run all tests that can run on testnets
124-
.PHONY: testnets
125-
testnets: export CLUSTERS_COUNT=1
126-
testnets: export FORBID_RESTART=1
127-
testnets: TEST_THREADS := $(or $(TEST_THREADS),15)
128-
testnets: MARKEXPR := $(or $(MARKEXPR),-m "testnets")
129-
testnets: .dirs .run_tests

0 commit comments

Comments
 (0)