-
-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathci.bash
More file actions
106 lines (96 loc) · 3.46 KB
/
ci.bash
File metadata and controls
106 lines (96 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env bash
#
# Uses nix-eval-jobs with $(nproc) workers
# NOTE: Ignores tests with expectedError
#
# Redirect stdout to null IF you only want to see failures
set -aeuo pipefail
system="x86_64-linux"
if test -n "${1:-}"; then
system="${1}"
shift
fi
suite=""
testFilter=""
preSuite=""
postSuite=""
if test -n "${1:-}"; then
input="$1"
# Split suite.test-name into suite + test filter
suite="${input%%.*}"
if [[ "$input" == *.* ]]; then
testFilter="${input#*.}"
fi
preSuite=".${suite}"
postSuite="${suite}."
shift
fi
args=($@)
# When a specific test is requested, delegate to nix-unit for traces
if test -n "$testFilter"; then
nix_unit_output=$(nix-unit --override-input den . --flake "./templates/ci#.tests.${suite}" "${args[@]}" 2>&1) || true
# Show only the matching test's output (with surrounding trace context)
echo "$nix_unit_output" | grep -v '^[✅❌🎉😢]' | grep -v 'successful$' >&2 || true
if echo "$nix_unit_output" | grep -q "^✅ ${testFilter}$"; then
echo "✅ ${postSuite}${testFilter}"
echo "🎉 1/1 successful" >&2
else
echo "❌ ${postSuite}${testFilter}"
echo "😢 0/1 successful" >&2
exit 1
fi
exit 0
fi
results=$(mktemp -t den-test-XXXXX.json)
# Cap workers and per-worker memory to prevent OOM from infinite recursion.
# nproc can be very high (32+); limit workers so worst-case memory is bounded.
max_workers=8
mem_per_worker=2048 # MiB
workers=$(( $(nproc) < max_workers ? $(nproc) : max_workers ))
nix-eval-jobs \
--flake ./templates/ci#tests${preSuite} \
--override-input den . \
--workers "$workers" \
--max-memory-size "$mem_per_worker" \
--force-recurse \
--select 'tests: let
system="'"${system}"'";
go = prefix: v:
if v ? expr then
let
hasExpected = v ? expected && !(v.expected ? undefined);
hasExpectedError = v ? expectedError && !(v.expectedError ? undefined);
pass = if hasExpected then v.expr == v.expected
else if hasExpectedError then true # ignored
else true;
name = builtins.replaceStrings ["." "'\''"] ["-" "_"] prefix;
in derivation {
name = if pass then "PASS-${name}" else "FAIL-${name}";
system = "${system}"; builder = "/bin/sh";
args = ["-c" "echo > $out"];
}
else if builtins.isAttrs v then
builtins.mapAttrs (k: go (if prefix == "" then k else "${prefix}.${k}")) v
else derivation { name = "SKIP"; system = "${system}"; builder = "/bin/sh"; args = ["-c" "echo > $out"]; };
in builtins.mapAttrs (k: go k) tests' \
"${args[@]}" 2>/dev/null \
| tee "$results" \
| jq -r 'if (.name != null and (.name | startswith("PASS-"))) then "✅ '"${postSuite}"'" + .attr else empty end'
pass=$(jq -r 'select(.name != null and (.name | startswith("PASS-"))) | "."' "$results" | wc -l)
fail=$(jq -r 'select(.error != null or (.name != null and (.name | startswith("FAIL-")))) | "."' "$results" | wc -l)
total=$(expr "$pass" + "$fail")
if [ "$fail" -eq "0" ]; then
echo "🎉 ${pass}/${total} successful" >&2
rm "$results" || true
else
echo >&2
echo "💥 FAILURES (${fail}):" >&2
echo "For details run with \`just ci-deep <suite>\`" >&2
echo "where <suite> does not include \`.test-xyz\`" >&2
echo >&2
jq -r 'select(.error != null or (.name != null and (.name | startswith("FAIL-")))) | "❌ '"${postSuite}"'" + .attr' "$results" >&2
echo >&2
echo "😢 ${pass}/${total} successful" >&2
rm "$results" || true
exit 1
fi