Skip to content

Commit e21fa6b

Browse files
test(e2e): read the cache root from mcpp, not from a bash re-derivation (#318)
* test(e2e): read the cache root from mcpp, not from a bash re-derivation 170 asserted the staging source lived under ${MCPP_HOME:-$HOME/.mcpp}/build-cache/v1. That re-derivation is wrong for a SELF-CONTAINED install, where the unpacked tree itself is the home — the shape of every release tarball and every `xlings install mcpp`. Running the suite against the released 2026.7.30.2 binary therefore failed the test while the binary was correct: FAIL: std BMI cache is '<tarball>/build-cache/v1/std/...', expected under '/home/speak/.mcpp/build-cache/v1/std' CI never saw it because the binary under test lives at target/<triple>/<fp>/bin/mcpp, which mcpp.home::root() deliberately disqualifies from self-contained detection. The root now comes from `mcpp cache dir`, which exists precisely so "where is the cache" has one answer. Verified passing against both shapes: the released tarball binary and a dev build. * test(e2e): accept either build verb where a dependency may come from the cache Fallout from making the global cache work, and one of the two is a negative assertion my change silently weakened. 163 asserted `Compiling acme.widget`. What it tests is that the descriptor was found BY IDENTITY and the package joined the build; whether its objects were compiled here or served from the cache belongs to a different subsystem. Now that hits actually skip work, a sibling app dir under the same MCPP_HOME — 163 builds several — can legitimately supply them, which is how it failed on Windows CI: Cached acme.widget v1.38.1 (2 units) FAIL: 163_identity_first_resolution.sh 82 is the more important one. Its NEGATIVE check ("widget must not be pulled when the feature is inactive") grepped only `Compiling widget`, so a wrongly-pulled dependency whose objects happened to be cached would announce `Cached widget` and pass. Both directions now match either verb through one `pulled()` helper, so the positive cannot be too narrow and the negative cannot be too weak. 25 and 48 grep the ROOT package's Compiling line, which is never cached; left alone. --------- Co-authored-by: sunrisepeak <speakshen@163.com>
1 parent 3fec883 commit e21fa6b

3 files changed

Lines changed: 37 additions & 11 deletions

File tree

tests/e2e/163_identity_first_resolution.sh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,16 @@ EOF
7878
mkidx idx1 a/acme.widget.lua acme widget
7979
mkapp app1 acme ../idx1 acme widget
8080
(cd app1 && "$MCPP" build > out.txt 2>&1) || { cat app1/out.txt; exit 1; }
81-
grep -q "Compiling acme.widget" app1/out.txt || { cat app1/out.txt; exit 1; }
81+
# Either verb: what this test is about is that the descriptor was found BY
82+
# IDENTITY and the package became part of the build. Whether its objects were
83+
# compiled here or served from the global build cache is a different subsystem's
84+
# business — and now that the cache actually works, a sibling app dir under the
85+
# same MCPP_HOME (or a restored CI sandbox) can legitimately supply them.
86+
grep -qE "(Compiling|Cached) acme\.widget" app1/out.txt || {
87+
cat app1/out.txt
88+
echo "FAIL: acme.widget was neither compiled nor served from cache"
89+
exit 1
90+
}
8291
# xlings names the dir {namespace}-x-{literal name} — short name → acme-x-widget
8392
test -d "app1/.mcpp/.xlings/data/xpkgs/acme-x-widget" \
8493
|| { echo "FAIL: expected store dir acme-x-widget"; ls -R app1/.mcpp/.xlings/data/xpkgs 2>/dev/null; exit 1; }

tests/e2e/170_bmi_staging_no_cascade.sh

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# carried no `restat`, so every importer of `import std` rebuilt whenever
1010
# the cache-side BMI got a newer mtime (which happens on any cwd change
1111
# before the cache-root fix below).
12-
# 2. The staging SOURCE must live under $MCPP_HOME/build-cache/v1/std. That cache
12+
# 2. The staging SOURCE must live under the cache root mcpp itself reports. That cache
1313
# used to resolve its root through a private copy of the home logic that
1414
# knew neither %USERPROFILE% nor self-contained installs, so on Windows it
1515
# parked the cache in the current working directory as `.mcpp-bmi/`.
@@ -56,12 +56,22 @@ DST=$(unescape_ninja "$(echo "$EDGE" | awk '{print $2}')")
5656
SRC=$(unescape_ninja "$(echo "$EDGE" | awk '{print $NF}')")
5757
echo "staging: $SRC -> $DST"
5858

59-
# ── invariant 2: the cache root is $MCPP_HOME/build-cache/v1/std, never a cwd-local
60-
# dir (and never the pre-v1 $MCPP_HOME/bmi tree, which nothing reads now) ──
61-
HOME_ROOT=$(norm_path "${MCPP_HOME:-$HOME/.mcpp}")
59+
# ── invariant 2: the staging SOURCE lives under the tool's OWN cache root, and
60+
# never in a cwd-local directory (nor in the pre-v1 bmi/ tree, which nothing
61+
# reads now) ──
62+
#
63+
# The root is read from `mcpp cache dir` rather than re-derived here as
64+
# ${MCPP_HOME:-$HOME/.mcpp}/build-cache/v1. That re-derivation is wrong for a
65+
# SELF-CONTAINED install, where the unpacked tree itself is the home — which is
66+
# the shape of every release tarball and every `xlings install mcpp`. Re-deriving
67+
# it made this test fail against a released binary while the binary was right,
68+
# and "where is the cache" having two answers in two places is the exact defect
69+
# #311 spent a module (mcpp.home) removing.
70+
CACHE_ROOT=$(norm_path "$("$MCPP" cache dir | head -1)")
71+
[[ -n "$CACHE_ROOT" ]] || { echo "FAIL: mcpp cache dir printed nothing"; exit 1; }
6272
case "$(norm_path "$SRC")" in
63-
"$HOME_ROOT"/build-cache/v1/std/*) ;;
64-
*) echo "FAIL: std BMI cache is '$SRC', expected under '$HOME_ROOT/build-cache/v1/std'"
73+
"$CACHE_ROOT"/std/*) ;;
74+
*) echo "FAIL: std BMI cache is '$SRC', expected under '$CACHE_ROOT/std'"
6575
exit 1 ;;
6676
esac
6777
for leftover in "$TMP/.mcpp-bmi" "$TMP/app/.mcpp-bmi"; do

tests/e2e/82_feature_optional_deps.sh

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,22 @@ EOF
4646

4747
cd app
4848

49-
# 1. Feature inactive → widget is NOT pulled (never resolved/compiled).
49+
# Both directions match EITHER verb. A dependency that is in the graph announces
50+
# itself as `Compiling` or, when the global build cache supplies its objects, as
51+
# `Cached` — so "Compiling" alone is too narrow for the positive AND too weak for
52+
# the negative: a wrongly-pulled dependency whose objects happened to be cached
53+
# would print `Cached widget` and slip past a `Compiling`-only check.
54+
pulled() { grep -qE '(Compiling|Cached) widget' "$1"; }
55+
56+
# 1. Feature inactive → widget is NOT pulled (never resolved, never built).
5057
"$MCPP" build > b1.log 2>&1 || { cat b1.log; echo "FAIL: baseline build failed"; exit 1; }
51-
if grep -q 'Compiling widget' b1.log; then
58+
if pulled b1.log; then
5259
cat b1.log; echo "FAIL: widget must NOT be pulled when feature inactive"; exit 1
5360
fi
5461

55-
# 2. Feature active → widget IS pulled and compiled like a normal dependency.
62+
# 2. Feature active → widget IS pulled and built like a normal dependency.
5663
rm -rf target
5764
"$MCPP" build --features extra > b2.log 2>&1 || { cat b2.log; echo "FAIL: feature build failed (widget not pulled?)"; exit 1; }
58-
grep -q 'Compiling widget' b2.log || { cat b2.log; echo "FAIL: widget was not pulled/compiled when feature active"; exit 1; }
65+
pulled b2.log || { cat b2.log; echo "FAIL: widget was not pulled when feature active"; exit 1; }
5966

6067
echo "OK"

0 commit comments

Comments
 (0)