Merge pull request #237512 from hercules-ci/lib-system-equals
This commit is contained in:
commit
5ff6f51c1c
3 changed files with 90 additions and 7 deletions
|
@ -9,6 +9,39 @@ rec {
|
|||
examples = import ./examples.nix { inherit lib; };
|
||||
architectures = import ./architectures.nix { inherit lib; };
|
||||
|
||||
/*
|
||||
Elaborated systems contain functions, which means that they don't satisfy
|
||||
`==` for a lack of reflexivity.
|
||||
|
||||
They might *appear* to satisfy `==` reflexivity when the same exact value is
|
||||
compared to itself, because object identity is used as an "optimization";
|
||||
compare the value with a reconstruction of itself, e.g. with `f == a: f a`,
|
||||
or perhaps calling `elaborate` twice, and one will see reflexivity fail as described.
|
||||
|
||||
Hence a custom equality test.
|
||||
|
||||
Note that this does not canonicalize the systems, so you'll want to make sure
|
||||
both arguments have been `elaborate`-d.
|
||||
*/
|
||||
equals =
|
||||
let removeFunctions = a: lib.filterAttrs (_: v: !builtins.isFunction v) a;
|
||||
in a: b: removeFunctions a == removeFunctions b;
|
||||
|
||||
/*
|
||||
Try to convert an elaborated system back to a simple string. If not possible,
|
||||
return null. So we have the property:
|
||||
|
||||
sys: _valid_ sys ->
|
||||
sys == elaborate (toLosslessStringMaybe sys)
|
||||
|
||||
NOTE: This property is not guaranteed when `sys` was elaborated by a different
|
||||
version of Nixpkgs.
|
||||
*/
|
||||
toLosslessStringMaybe = sys:
|
||||
if lib.isString sys then sys
|
||||
else if equals sys (elaborate sys.system) then sys.system
|
||||
else null;
|
||||
|
||||
/* List of all Nix system doubles the nixpkgs flake will expose the package set
|
||||
for. All systems listed here must be supported by nixpkgs as `localSystem`.
|
||||
|
||||
|
|
|
@ -53,6 +53,9 @@ let
|
|||
echo "Running lib/tests/sources.sh"
|
||||
TEST_LIB=$PWD/lib bash lib/tests/sources.sh
|
||||
|
||||
echo "Running lib/tests/systems.nix"
|
||||
[[ $(nix-instantiate --eval --strict lib/tests/systems.nix | tee /dev/stderr) == '[ ]' ]];
|
||||
|
||||
mkdir $out
|
||||
echo success > $out/${nix.version}
|
||||
'';
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
# We assert that the new algorithmic way of generating these lists matches the
|
||||
# way they were hard-coded before.
|
||||
# Run:
|
||||
# [nixpkgs]$ nix-instantiate --eval --strict lib/tests/systems.nix
|
||||
# Expected output: [], or the failed cases
|
||||
#
|
||||
# One might think "if we exhaustively test, what's the point of procedurally
|
||||
# calculating the lists anyway?". The answer is one can mindlessly update these
|
||||
# tests as new platforms become supported, and then just give the diff a quick
|
||||
# sanity check before committing :).
|
||||
# OfBorg runs (approximately) nix-build lib/tests/release.nix
|
||||
let
|
||||
lib = import ../default.nix;
|
||||
mseteq = x: y: {
|
||||
|
@ -12,7 +10,16 @@ let
|
|||
expected = lib.sort lib.lessThan y;
|
||||
};
|
||||
in
|
||||
with lib.systems.doubles; lib.runTests {
|
||||
lib.runTests (
|
||||
# We assert that the new algorithmic way of generating these lists matches the
|
||||
# way they were hard-coded before.
|
||||
#
|
||||
# One might think "if we exhaustively test, what's the point of procedurally
|
||||
# calculating the lists anyway?". The answer is one can mindlessly update these
|
||||
# tests as new platforms become supported, and then just give the diff a quick
|
||||
# sanity check before committing :).
|
||||
|
||||
(with lib.systems.doubles; {
|
||||
testall = mseteq all (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ wasi ++ windows ++ embedded ++ mmix ++ js ++ genode ++ redox);
|
||||
|
||||
testarm = mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv6l-netbsd" "armv6l-none" "armv7a-linux" "armv7a-netbsd" "armv7l-linux" "armv7l-netbsd" "arm-none" "armv7a-darwin" ];
|
||||
|
@ -39,4 +46,44 @@ with lib.systems.doubles; lib.runTests {
|
|||
testopenbsd = mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ];
|
||||
testwindows = mseteq windows [ "i686-cygwin" "x86_64-cygwin" "i686-windows" "x86_64-windows" ];
|
||||
testunix = mseteq unix (linux ++ darwin ++ freebsd ++ openbsd ++ netbsd ++ illumos ++ cygwin ++ redox);
|
||||
})
|
||||
|
||||
// {
|
||||
test_equals_example_x86_64-linux = {
|
||||
expr = lib.systems.equals (lib.systems.elaborate "x86_64-linux") (lib.systems.elaborate "x86_64-linux");
|
||||
expected = true;
|
||||
};
|
||||
|
||||
test_toLosslessStringMaybe_example_x86_64-linux = {
|
||||
expr = lib.systems.toLosslessStringMaybe (lib.systems.elaborate "x86_64-linux");
|
||||
expected = "x86_64-linux";
|
||||
};
|
||||
test_toLosslessStringMaybe_fail = {
|
||||
expr = lib.systems.toLosslessStringMaybe (lib.systems.elaborate "x86_64-linux" // { something = "extra"; });
|
||||
expected = null;
|
||||
};
|
||||
}
|
||||
|
||||
# Generate test cases to assert that a change in any non-function attribute makes a platform unequal
|
||||
// lib.concatMapAttrs (platformAttrName: origValue: {
|
||||
|
||||
${"test_equals_unequal_${platformAttrName}"} =
|
||||
let modified =
|
||||
assert origValue != arbitraryValue;
|
||||
lib.systems.elaborate "x86_64-linux" // { ${platformAttrName} = arbitraryValue; };
|
||||
arbitraryValue = x: "<<modified>>";
|
||||
in {
|
||||
expr = lib.systems.equals (lib.systems.elaborate "x86_64-linux") modified;
|
||||
expected = {
|
||||
# Changes in these attrs are not detectable because they're function.
|
||||
# The functions should be derived from the data, so this is not a problem.
|
||||
canExecute = null;
|
||||
emulator = null;
|
||||
emulatorAvailable = null;
|
||||
isCompatible = null;
|
||||
}?${platformAttrName};
|
||||
};
|
||||
|
||||
}) (lib.systems.elaborate "x86_64-linux" /* arbitrary choice, just to get all the elaborated attrNames */)
|
||||
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue