noBrokenSymlinks: use lib.optionalAttrs instead of meta.badPlatforms

Having unbuildable tests in the attrset makes it difficult to ask Nix to
build all the working ones at once. See discussion in #380683. So
instead of flagging them, let's just remove them entirely.
This commit is contained in:
Rhys-T 2025-03-05 15:41:16 -05:00
parent 18d92cd065
commit 0354b63bf9

View File

@ -19,9 +19,8 @@ let
# Some platforms implement permissions for symlinks, while others - including Linux - ignore them.
# As a result, testing this hook's handling of unreadable symlinks requires careful attention to
# which kind of platform we're on. See the comments by `meta.badPlatforms` below for details.
platformsWithSymlinkPermissions = with lib.platforms; darwin ++ freebsd ++ netbsd ++ openbsd;
platformsWithoutSymlinkPermissions = lib.subtractLists platformsWithSymlinkPermissions lib.platforms.all;
# which kind of platform we're on. See the comments by `lib.optionalAttrs` below for details.
hasSymlinkPermissions = with stdenv.hostPlatform; isDarwin || isBSD;
mkUnreadableSymlink = absolute: ''
touch "$out/unreadable-symlink-target"
(
@ -44,11 +43,10 @@ let
name,
commands ? [ ],
derivationArgs ? { },
meta ? { },
}:
stdenv.mkDerivation (
{
inherit name meta;
inherit name;
strictDeps = true;
dontUnpack = true;
dontPatch = true;
@ -145,60 +143,6 @@ in
derivationArgs.dontCheckForBrokenSymlinks = true;
};
fail-unreadable-symlink-relative =
runCommand "fail-unreadable-symlink-relative"
{
failed = testBuildFailure (testBuilder {
name = "fail-unreadable-symlink-relative-inner";
commands = [ (mkUnreadableSymlink false) ];
});
# Skip test if symlink permissions are not supported, since the hook won't have anything to report.
meta.badPlatforms = platformsWithoutSymlinkPermissions;
}
''
(( 1 == "$(cat "$failed/testBuildFailure.exit")" ))
grep -F 'found 0 dangling symlinks, 0 reflexive symlinks and 1 unreadable symlinks' "$failed/testBuildFailure.log"
touch $out
'';
pass-unreadable-symlink-relative-allowed = testBuilder {
name = "pass-unreadable-symlink-relative-allowed";
commands = [ (mkUnreadableSymlink false) ];
derivationArgs.dontCheckForBrokenSymlinks = true;
# This test will break on platforms that use symlink permissions, because even though this hook will be okay, later ones will error out.
# It should be safe to run on other platforms, just to make sure the hook isn't completely broken. It won't have anything to report, though.
meta.badPlatforms = platformsWithSymlinkPermissions;
};
fail-unreadable-symlink-absolute =
runCommand "fail-unreadable-symlink-absolute"
{
failed = testBuildFailure (testBuilder {
name = "fail-unreadable-symlink-absolute-inner";
commands = [ (mkUnreadableSymlink true) ];
});
# Skip test if symlink permissions are not supported, since the hook won't have anything to report.
meta.badPlatforms = platformsWithoutSymlinkPermissions;
}
''
(( 1 == "$(cat "$failed/testBuildFailure.exit")" ))
grep -F 'found 0 dangling symlinks, 0 reflexive symlinks and 1 unreadable symlinks' "$failed/testBuildFailure.log"
touch $out
'';
pass-unreadable-symlink-absolute-allowed = testBuilder {
name = "pass-unreadable-symlink-absolute-allowed";
commands = [ (mkUnreadableSymlink true) ];
derivationArgs.dontCheckForBrokenSymlinks = true;
# This test will break on platforms that use symlink permissions, because even though this hook will be okay, later ones will error out.
# It should be safe to run on other platforms, just to make sure the hook isn't completely broken. It won't have anything to report, though.
meta.badPlatforms = platformsWithSymlinkPermissions;
};
# Leave the unreadable symlink out of the combined 'broken' test since it doesn't work on all platforms.
fail-broken-symlinks-relative =
runCommand "fail-broken-symlinks-relative"
@ -254,81 +198,7 @@ in
# The `all-broken` tests include unreadable symlinks along with the other kinds of broken links.
# They should be run/skipped on the same sets platforms as the corresponding `unreadable` tests.
fail-all-broken-symlinks-relative =
runCommand "fail-all-broken-symlinks-relative"
{
failed = testBuildFailure (testBuilder {
name = "fail-all-broken-symlinks-relative-inner";
commands = [
(mkDanglingSymlink false)
(mkReflexiveSymlink false)
(mkUnreadableSymlink false)
];
});
# Skip test if symlink permissions are not supported, since the hook won't have anything to report.
meta.badPlatforms = platformsWithoutSymlinkPermissions;
}
''
(( 1 == "$(cat "$failed/testBuildFailure.exit")" ))
if ! grep -F 'found 1 dangling symlinks, 1 reflexive symlinks and 1 unreadable symlinks' "$failed/testBuildFailure.log"; then
grep -F 'symlink permissions not supported' "$failed/testBuildFailure.log"
grep -F 'found 1 dangling symlinks, 1 reflexive symlinks and 0 unreadable symlinks' "$failed/testBuildFailure.log"
fi
touch $out
'';
pass-all-broken-symlinks-relative-allowed = testBuilder {
name = "pass-all-broken-symlinks-relative-allowed";
commands = [
(mkDanglingSymlink false)
(mkReflexiveSymlink false)
(mkUnreadableSymlink false)
];
derivationArgs.dontCheckForBrokenSymlinks = true;
# This test will break on platforms that use symlink permissions, because even though this hook will be okay, later ones will error out.
# It should be safe to run on other platforms, just to make sure the hook isn't completely broken. It won't have anything to report, though.
meta.badPlatforms = platformsWithSymlinkPermissions;
};
fail-all-broken-symlinks-absolute =
runCommand "fail-all-broken-symlinks-absolute"
{
failed = testBuildFailure (testBuilder {
name = "fail-all-broken-symlinks-absolute-inner";
commands = [
(mkDanglingSymlink true)
(mkReflexiveSymlink true)
(mkUnreadableSymlink true)
];
});
# Skip test if symlink permissions are not supported, since the hook won't have anything to report.
meta.badPlatforms = platformsWithoutSymlinkPermissions;
}
''
(( 1 == "$(cat "$failed/testBuildFailure.exit")" ))
if ! grep -F 'found 1 dangling symlinks, 1 reflexive symlinks and 1 unreadable symlinks' "$failed/testBuildFailure.log"; then
grep -F 'symlink permissions not supported' "$failed/testBuildFailure.log"
grep -F 'found 1 dangling symlinks, 1 reflexive symlinks and 0 unreadable symlinks' "$failed/testBuildFailure.log"
fi
touch $out
'';
pass-all-broken-symlinks-absolute-allowed = testBuilder {
name = "pass-all-broken-symlinks-absolute-allowed";
commands = [
(mkDanglingSymlink true)
(mkReflexiveSymlink true)
(mkUnreadableSymlink true)
];
derivationArgs.dontCheckForBrokenSymlinks = true;
# This test will break on platforms that use symlink permissions, because even though this hook will be okay, later ones will error out.
# It should be safe to run on other platforms, just to make sure the hook isn't completely broken. It won't have anything to report, though.
meta.badPlatforms = platformsWithSymlinkPermissions;
};
# See below.
pass-valid-symlink-relative = testBuilder {
name = "pass-valid-symlink-relative";
@ -350,3 +220,111 @@ in
commands = [ (mkValidSymlinkOutsideNixStore true) ];
};
}
# Skip these tests if symlink permissions are not supported, since the hook won't have anything to report.
// lib.optionalAttrs hasSymlinkPermissions {
fail-unreadable-symlink-relative =
runCommand "fail-unreadable-symlink-relative"
{
failed = testBuildFailure (testBuilder {
name = "fail-unreadable-symlink-relative-inner";
commands = [ (mkUnreadableSymlink false) ];
});
}
''
(( 1 == "$(cat "$failed/testBuildFailure.exit")" ))
grep -F 'found 0 dangling symlinks, 0 reflexive symlinks and 1 unreadable symlinks' "$failed/testBuildFailure.log"
touch $out
'';
fail-unreadable-symlink-absolute =
runCommand "fail-unreadable-symlink-absolute"
{
failed = testBuildFailure (testBuilder {
name = "fail-unreadable-symlink-absolute-inner";
commands = [ (mkUnreadableSymlink true) ];
});
}
''
(( 1 == "$(cat "$failed/testBuildFailure.exit")" ))
grep -F 'found 0 dangling symlinks, 0 reflexive symlinks and 1 unreadable symlinks' "$failed/testBuildFailure.log"
touch $out
'';
fail-all-broken-symlinks-relative =
runCommand "fail-all-broken-symlinks-relative"
{
failed = testBuildFailure (testBuilder {
name = "fail-all-broken-symlinks-relative-inner";
commands = [
(mkDanglingSymlink false)
(mkReflexiveSymlink false)
(mkUnreadableSymlink false)
];
});
}
''
(( 1 == "$(cat "$failed/testBuildFailure.exit")" ))
if ! grep -F 'found 1 dangling symlinks, 1 reflexive symlinks and 1 unreadable symlinks' "$failed/testBuildFailure.log"; then
grep -F 'symlink permissions not supported' "$failed/testBuildFailure.log"
grep -F 'found 1 dangling symlinks, 1 reflexive symlinks and 0 unreadable symlinks' "$failed/testBuildFailure.log"
fi
touch $out
'';
fail-all-broken-symlinks-absolute =
runCommand "fail-all-broken-symlinks-absolute"
{
failed = testBuildFailure (testBuilder {
name = "fail-all-broken-symlinks-absolute-inner";
commands = [
(mkDanglingSymlink true)
(mkReflexiveSymlink true)
(mkUnreadableSymlink true)
];
});
}
''
(( 1 == "$(cat "$failed/testBuildFailure.exit")" ))
if ! grep -F 'found 1 dangling symlinks, 1 reflexive symlinks and 1 unreadable symlinks' "$failed/testBuildFailure.log"; then
grep -F 'symlink permissions not supported' "$failed/testBuildFailure.log"
grep -F 'found 1 dangling symlinks, 1 reflexive symlinks and 0 unreadable symlinks' "$failed/testBuildFailure.log"
fi
touch $out
'';
}
# These tests will break on platforms that do use symlink permissions, because even though this hook will be okay, later ones will error out.
# They should be safe to run on other platforms, just to make sure the hook isn't completely broken. It won't have anything to report, though.
// lib.optionalAttrs (!hasSymlinkPermissions) {
pass-unreadable-symlink-relative-allowed = testBuilder {
name = "pass-unreadable-symlink-relative-allowed";
commands = [ (mkUnreadableSymlink false) ];
derivationArgs.dontCheckForBrokenSymlinks = true;
};
pass-unreadable-symlink-absolute-allowed = testBuilder {
name = "pass-unreadable-symlink-absolute-allowed";
commands = [ (mkUnreadableSymlink true) ];
derivationArgs.dontCheckForBrokenSymlinks = true;
};
pass-all-broken-symlinks-relative-allowed = testBuilder {
name = "pass-all-broken-symlinks-relative-allowed";
commands = [
(mkDanglingSymlink false)
(mkReflexiveSymlink false)
(mkUnreadableSymlink false)
];
derivationArgs.dontCheckForBrokenSymlinks = true;
};
pass-all-broken-symlinks-absolute-allowed = testBuilder {
name = "pass-all-broken-symlinks-absolute-allowed";
commands = [
(mkDanglingSymlink true)
(mkReflexiveSymlink true)
(mkUnreadableSymlink true)
];
derivationArgs.dontCheckForBrokenSymlinks = true;
};
}