mirror of
https://github.com/NixOS/nix
synced 2025-06-25 06:31:14 +02:00
Add test case for catching caching of transient flake evaluation error
Co-authored-by: Robert Hensing <robert@roberthensing.nl>
This commit is contained in:
parent
2172c17b5e
commit
cee75fbf64
2 changed files with 54 additions and 0 deletions
|
@ -4653,6 +4653,16 @@ static RegisterPrimOp primop_splitVersion({
|
||||||
.fun = prim_splitVersion,
|
.fun = prim_splitVersion,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
static void prim_testThrowErrorMaybe(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
|
{
|
||||||
|
if (getEnv("_NIX_TEST_DO_THROW_ERROR") == "1") {
|
||||||
|
state.error<EvalError>("this is a dummy error").atPos(pos).debugThrow();
|
||||||
|
} else {
|
||||||
|
state.forceValue(*args[0], pos);
|
||||||
|
v = *args[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* Primop registration
|
* Primop registration
|
||||||
|
@ -4880,6 +4890,16 @@ void EvalState::createBaseEnv()
|
||||||
.fun = settings.traceVerbose ? prim_trace : prim_second,
|
.fun = settings.traceVerbose ? prim_trace : prim_second,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (getEnv("_NIX_TEST_PRIMOPS") == "1") {
|
||||||
|
addPrimOp({
|
||||||
|
.name = "__testThrowErrorMaybe",
|
||||||
|
.args = { "e" },
|
||||||
|
.arity = 1,
|
||||||
|
.doc = "throw dummy error if _NIX_TEST_DO_THROW_ERROR == 1, return arg otherwise",
|
||||||
|
.fun = prim_testThrowErrorMaybe
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* Add a value containing the current Nix expression search path. */
|
/* Add a value containing the current Nix expression search path. */
|
||||||
auto list = buildList(lookupPath.elements.size());
|
auto list = buildList(lookupPath.elements.size());
|
||||||
for (const auto & [n, i] : enumerate(lookupPath.elements)) {
|
for (const auto & [n, i] : enumerate(lookupPath.elements)) {
|
||||||
|
|
|
@ -28,6 +28,8 @@ cat >"$flake1Dir/flake.nix" <<EOF
|
||||||
in
|
in
|
||||||
assert (f 100); self.drv;
|
assert (f 100); self.drv;
|
||||||
ifd = assert (import self.drv); self.drv;
|
ifd = assert (import self.drv); self.drv;
|
||||||
|
artificialTwoDifferentThrows = builtins.testThrowErrorMaybe (throw "real throw");
|
||||||
|
artificialThrowOrDrv = builtins.testThrowErrorMaybe self.drv;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
@ -48,3 +50,35 @@ nix build --no-link "$flake1Dir#stack-depth"
|
||||||
expect 1 nix build "$flake1Dir#ifd" --option allow-import-from-derivation false 2>&1 \
|
expect 1 nix build "$flake1Dir#ifd" --option allow-import-from-derivation false 2>&1 \
|
||||||
| grepQuiet 'error: cannot build .* during evaluation because the option '\''allow-import-from-derivation'\'' is disabled'
|
| grepQuiet 'error: cannot build .* during evaluation because the option '\''allow-import-from-derivation'\'' is disabled'
|
||||||
nix build --no-link "$flake1Dir#ifd"
|
nix build --no-link "$flake1Dir#ifd"
|
||||||
|
|
||||||
|
# make sure this builtin does not reach production
|
||||||
|
nix eval --expr 'assert ! (builtins ? testThrowErrorMaybe); null'
|
||||||
|
|
||||||
|
# and that it does reach the testing environment
|
||||||
|
export _NIX_TEST_PRIMOPS=1
|
||||||
|
nix eval --expr 'assert (builtins.testThrowErrorMaybe true); null'
|
||||||
|
|
||||||
|
# and that it works
|
||||||
|
_NIX_TEST_DO_THROW_ERROR=1 expect 1 nix eval --expr 'builtins.testThrowErrorMaybe true' 2>&1 \
|
||||||
|
| grepQuiet 'this is a dummy error'
|
||||||
|
|
||||||
|
|
||||||
|
# make sure error details do not get cached
|
||||||
|
_NIX_TEST_DO_THROW_ERROR=1 expect 1 nix eval "$flake1Dir#artificialTwoDifferentThrows" 2>&1 \
|
||||||
|
| grepQuiet "this is a dummy error"
|
||||||
|
expect 1 nix eval "$flake1Dir#artificialTwoDifferentThrows" 2>&1 \
|
||||||
|
| grepQuiet "real throw"
|
||||||
|
|
||||||
|
# If a cached error cannot be reproduced, do not continue as usual.
|
||||||
|
# Instead, throw an error.
|
||||||
|
#
|
||||||
|
# To be clear, the following test case should never occur in production.
|
||||||
|
# But it might, due to an implementation error in Nix or plugins.
|
||||||
|
|
||||||
|
# create an artificial exception cache entry
|
||||||
|
_NIX_TEST_DO_THROW_ERROR=1 expect 1 nix build "$flake1Dir#artificialThrowOrDrv" 2>&1 \
|
||||||
|
| grepQuiet "this is a dummy error"
|
||||||
|
|
||||||
|
# Invoke again but without the artificial throwing of an exception
|
||||||
|
expect 1 nix build "$flake1Dir#artificialThrowOrDrv" 2>&1 \
|
||||||
|
| grepQuiet "unexpected evaluation success despite the existence of a cached error. This should not happen. It is a bug in the implementation of Nix or a plugin. A transient exception should not have been cached."
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue