mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-10 00:08:07 +02:00
tests: Add hydraJobs.tests.functional_*
This commit is contained in:
parent
dc720f89f2
commit
439022c5ac
13 changed files with 273 additions and 28 deletions
|
@ -23,7 +23,7 @@ EOF
|
||||||
chmod +x "$TEST_ROOT/post-build-hook.sh"
|
chmod +x "$TEST_ROOT/post-build-hook.sh"
|
||||||
rm -f "$TEST_ROOT/post-hook-counter"
|
rm -f "$TEST_ROOT/post-hook-counter"
|
||||||
|
|
||||||
echo "post-build-hook = $TEST_ROOT/post-build-hook.sh" >> "$NIX_CONF_DIR/nix.conf"
|
echo "post-build-hook = $TEST_ROOT/post-build-hook.sh" >> "$test_nix_conf"
|
||||||
}
|
}
|
||||||
|
|
||||||
registerBuildHook
|
registerBuildHook
|
||||||
|
|
|
@ -1,5 +1,30 @@
|
||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
# for shellcheck
|
||||||
|
: "${test_nix_conf_dir?}" "${test_nix_conf?}"
|
||||||
|
|
||||||
|
if isTestOnNixOS; then
|
||||||
|
|
||||||
|
mkdir -p "$test_nix_conf_dir" "$TEST_HOME"
|
||||||
|
|
||||||
|
export NIX_USER_CONF_FILES="$test_nix_conf_dir/nix.conf"
|
||||||
|
mkdir -p "$test_nix_conf_dir" "$TEST_HOME"
|
||||||
|
! test -e "$test_nix_conf"
|
||||||
|
cat > "$test_nix_conf_dir/nix.conf" <<EOF
|
||||||
|
experimental-features = nix-command flakes
|
||||||
|
flake-registry = $TEST_ROOT/registry.json
|
||||||
|
show-trace = true
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# When we're doing everything in the same store, we need to bring
|
||||||
|
# dependencies into context.
|
||||||
|
sed -i "$(dirname "${BASH_SOURCE[0]}")"/../config.nix \
|
||||||
|
-e 's^\(shell\) = "/nix/store/\([^/]*\)/\(.*\)";^\1 = builtins.appendContext "/nix/store/\2" { "/nix/store/\2".path = true; } + "/\3";^' \
|
||||||
|
-e 's^\(path\) = "/nix/store/\([^/]*\)/\(.*\)";^\1 = builtins.appendContext "/nix/store/\2" { "/nix/store/\2".path = true; } + "/\3";^' \
|
||||||
|
;
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
test -n "$TEST_ROOT"
|
test -n "$TEST_ROOT"
|
||||||
# We would delete any daemon socket, so let's stop the daemon first.
|
# We would delete any daemon socket, so let's stop the daemon first.
|
||||||
killDaemon
|
killDaemon
|
||||||
|
@ -41,3 +66,5 @@ EOF
|
||||||
nix-store --init
|
nix-store --init
|
||||||
# Sanity check
|
# Sanity check
|
||||||
test -e "$NIX_STATE_DIR"/db/db.sqlite
|
test -e "$NIX_STATE_DIR"/db/db.sqlite
|
||||||
|
|
||||||
|
fi # !isTestOnNixOS
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
# NOTE: instances of @variable@ are substituted as defined in /mk/templates.mk
|
# NOTE: instances of @variable@ are substituted as defined in /mk/templates.mk
|
||||||
|
|
||||||
|
if ! isTestOnNixOS; then
|
||||||
|
export SHELL="@bash@"
|
||||||
export PATH=@bindir@:$PATH
|
export PATH=@bindir@:$PATH
|
||||||
|
fi
|
||||||
|
|
||||||
export coreutils=@coreutils@
|
export coreutils=@coreutils@
|
||||||
#lsof=@lsof@
|
#lsof=@lsof@
|
||||||
|
|
||||||
export dot=@dot@
|
export dot=@dot@
|
||||||
export SHELL="@bash@"
|
|
||||||
export PAGER=cat
|
export PAGER=cat
|
||||||
export busybox="@sandbox_shell@"
|
export busybox="@sandbox_shell@"
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,15 @@ if [[ -z "${COMMON_VARS_AND_FUNCTIONS_SH_SOURCED-}" ]]; then
|
||||||
|
|
||||||
COMMON_VARS_AND_FUNCTIONS_SH_SOURCED=1
|
COMMON_VARS_AND_FUNCTIONS_SH_SOURCED=1
|
||||||
|
|
||||||
|
isTestOnNixOS() {
|
||||||
|
[[ "${isTestOnNixOS:-}" == 1 ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
die() {
|
||||||
|
echo "fatal error: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
set +x
|
set +x
|
||||||
|
|
||||||
commonDir="$(readlink -f "$(dirname "${BASH_SOURCE[0]-$0}")")"
|
commonDir="$(readlink -f "$(dirname "${BASH_SOURCE[0]-$0}")")"
|
||||||
|
@ -15,6 +24,12 @@ source "$commonDir/subst-vars.sh"
|
||||||
: "${PATH?} ${coreutils?} ${dot?} ${SHELL?} ${PAGER?} ${busybox?} ${version?} ${system?} ${BUILD_SHARED_LIBS?}"
|
: "${PATH?} ${coreutils?} ${dot?} ${SHELL?} ${PAGER?} ${busybox?} ${version?} ${system?} ${BUILD_SHARED_LIBS?}"
|
||||||
|
|
||||||
export TEST_ROOT=$(realpath ${TMPDIR:-/tmp}/nix-test)/${TEST_NAME:-default/tests\/functional//}
|
export TEST_ROOT=$(realpath ${TMPDIR:-/tmp}/nix-test)/${TEST_NAME:-default/tests\/functional//}
|
||||||
|
test_nix_conf_dir=$TEST_ROOT/etc
|
||||||
|
test_nix_conf=$test_nix_conf_dir/nix.conf
|
||||||
|
|
||||||
|
export TEST_HOME=$TEST_ROOT/test-home
|
||||||
|
|
||||||
|
if ! isTestOnNixOS; then
|
||||||
export NIX_STORE_DIR
|
export NIX_STORE_DIR
|
||||||
if ! NIX_STORE_DIR=$(readlink -f $TEST_ROOT/store 2> /dev/null); then
|
if ! NIX_STORE_DIR=$(readlink -f $TEST_ROOT/store 2> /dev/null); then
|
||||||
# Maybe the build directory is symlinked.
|
# Maybe the build directory is symlinked.
|
||||||
|
@ -24,7 +39,7 @@ fi
|
||||||
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
|
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
|
||||||
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
|
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
|
||||||
export NIX_STATE_DIR=$TEST_ROOT/var/nix
|
export NIX_STATE_DIR=$TEST_ROOT/var/nix
|
||||||
export NIX_CONF_DIR=$TEST_ROOT/etc
|
export NIX_CONF_DIR=$test_nix_conf_dir
|
||||||
export NIX_DAEMON_SOCKET_PATH=$TEST_ROOT/dSocket
|
export NIX_DAEMON_SOCKET_PATH=$TEST_ROOT/dSocket
|
||||||
unset NIX_USER_CONF_FILES
|
unset NIX_USER_CONF_FILES
|
||||||
export _NIX_TEST_SHARED=$TEST_ROOT/shared
|
export _NIX_TEST_SHARED=$TEST_ROOT/shared
|
||||||
|
@ -34,8 +49,10 @@ fi
|
||||||
export _NIX_IN_TEST=$TEST_ROOT/shared
|
export _NIX_IN_TEST=$TEST_ROOT/shared
|
||||||
export _NIX_TEST_NO_LSOF=1
|
export _NIX_TEST_NO_LSOF=1
|
||||||
export NIX_REMOTE=${NIX_REMOTE_-}
|
export NIX_REMOTE=${NIX_REMOTE_-}
|
||||||
|
|
||||||
|
fi # ! isTestOnNixOS
|
||||||
|
|
||||||
unset NIX_PATH
|
unset NIX_PATH
|
||||||
export TEST_HOME=$TEST_ROOT/test-home
|
|
||||||
export HOME=$TEST_HOME
|
export HOME=$TEST_HOME
|
||||||
unset XDG_STATE_HOME
|
unset XDG_STATE_HOME
|
||||||
unset XDG_DATA_HOME
|
unset XDG_DATA_HOME
|
||||||
|
@ -66,6 +83,10 @@ clearProfiles() {
|
||||||
}
|
}
|
||||||
|
|
||||||
clearStore() {
|
clearStore() {
|
||||||
|
if isTestOnNixOS; then
|
||||||
|
die "clearStore: not supported when testing on NixOS. Is it really needed? If so add conditionals; e.g. if ! isTestOnNixOS; then ..."
|
||||||
|
fi
|
||||||
|
|
||||||
echo "clearing store..."
|
echo "clearing store..."
|
||||||
chmod -R +w "$NIX_STORE_DIR"
|
chmod -R +w "$NIX_STORE_DIR"
|
||||||
rm -rf "$NIX_STORE_DIR"
|
rm -rf "$NIX_STORE_DIR"
|
||||||
|
@ -84,6 +105,10 @@ clearCacheCache() {
|
||||||
}
|
}
|
||||||
|
|
||||||
startDaemon() {
|
startDaemon() {
|
||||||
|
if isTestOnNixOS; then
|
||||||
|
die "startDaemon: not supported when testing on NixOS. Is it really needed? If so add conditionals; e.g. if ! isTestOnNixOS; then ..."
|
||||||
|
fi
|
||||||
|
|
||||||
# Don’t start the daemon twice, as this would just make it loop indefinitely
|
# Don’t start the daemon twice, as this would just make it loop indefinitely
|
||||||
if [[ "${_NIX_TEST_DAEMON_PID-}" != '' ]]; then
|
if [[ "${_NIX_TEST_DAEMON_PID-}" != '' ]]; then
|
||||||
return
|
return
|
||||||
|
@ -110,6 +135,10 @@ startDaemon() {
|
||||||
}
|
}
|
||||||
|
|
||||||
killDaemon() {
|
killDaemon() {
|
||||||
|
if isTestOnNixOS; then
|
||||||
|
die "killDaemon: not supported when testing on NixOS. Is it really needed? If so add conditionals; e.g. if ! isTestOnNixOS; then ..."
|
||||||
|
fi
|
||||||
|
|
||||||
# Don’t fail trying to stop a non-existant daemon twice
|
# Don’t fail trying to stop a non-existant daemon twice
|
||||||
if [[ "${_NIX_TEST_DAEMON_PID-}" == '' ]]; then
|
if [[ "${_NIX_TEST_DAEMON_PID-}" == '' ]]; then
|
||||||
return
|
return
|
||||||
|
@ -130,6 +159,10 @@ killDaemon() {
|
||||||
}
|
}
|
||||||
|
|
||||||
restartDaemon() {
|
restartDaemon() {
|
||||||
|
if isTestOnNixOS; then
|
||||||
|
die "restartDaemon: not supported when testing on NixOS. Is it really needed? If so add conditionals; e.g. if ! isTestOnNixOS; then ..."
|
||||||
|
fi
|
||||||
|
|
||||||
[[ -z "${_NIX_TEST_DAEMON_PID:-}" ]] && return 0
|
[[ -z "${_NIX_TEST_DAEMON_PID:-}" ]] && return 0
|
||||||
|
|
||||||
killDaemon
|
killDaemon
|
||||||
|
@ -152,6 +185,12 @@ skipTest () {
|
||||||
exit 99
|
exit 99
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TODO_NixOS() {
|
||||||
|
if isTestOnNixOS; then
|
||||||
|
skipTest "This test has not been adapted for NixOS yet"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
requireDaemonNewerThan () {
|
requireDaemonNewerThan () {
|
||||||
isDaemonNewer "$1" || skipTest "Daemon is too old"
|
isDaemonNewer "$1" || skipTest "Daemon is too old"
|
||||||
}
|
}
|
||||||
|
@ -234,7 +273,7 @@ buggyNeedLocalStore() {
|
||||||
|
|
||||||
enableFeatures() {
|
enableFeatures() {
|
||||||
local features="$1"
|
local features="$1"
|
||||||
sed -i 's/experimental-features .*/& '"$features"'/' "$NIX_CONF_DIR"/nix.conf
|
sed -i 's/experimental-features .*/& '"$features"'/' "$test_nix_conf_dir"/nix.conf
|
||||||
}
|
}
|
||||||
|
|
||||||
set -x
|
set -x
|
||||||
|
|
|
@ -20,13 +20,13 @@ startDaemon
|
||||||
|
|
||||||
varTest env_name value --impure-env env_name=value
|
varTest env_name value --impure-env env_name=value
|
||||||
|
|
||||||
echo 'impure-env = set_in_config=config_value' >> "$NIX_CONF_DIR/nix.conf"
|
echo 'impure-env = set_in_config=config_value' >> "$test_nix_conf"
|
||||||
set_in_config=daemon_value restartDaemon
|
set_in_config=daemon_value restartDaemon
|
||||||
|
|
||||||
varTest set_in_config config_value
|
varTest set_in_config config_value
|
||||||
varTest set_in_config client_value --impure-env set_in_config=client_value
|
varTest set_in_config client_value --impure-env set_in_config=client_value
|
||||||
|
|
||||||
sed -i -e '/^trusted-users =/d' "$NIX_CONF_DIR/nix.conf"
|
sed -i -e '/^trusted-users =/d' "$test_nix_conf"
|
||||||
|
|
||||||
env_name=daemon_value restartDaemon
|
env_name=daemon_value restartDaemon
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ requireEnvironment () {
|
||||||
}
|
}
|
||||||
|
|
||||||
addConfig () {
|
addConfig () {
|
||||||
echo "$1" >> "$NIX_CONF_DIR/nix.conf"
|
echo "$1" >> "$test_nix_conf"
|
||||||
}
|
}
|
||||||
|
|
||||||
setupConfig () {
|
setupConfig () {
|
||||||
|
|
|
@ -7,7 +7,7 @@ clearStore
|
||||||
rm -f $TEST_ROOT/result
|
rm -f $TEST_ROOT/result
|
||||||
|
|
||||||
export REMOTE_STORE=file:$TEST_ROOT/remote_store
|
export REMOTE_STORE=file:$TEST_ROOT/remote_store
|
||||||
echo 'require-sigs = false' >> $NIX_CONF_DIR/nix.conf
|
echo 'require-sigs = false' >> $test_nix_conf
|
||||||
|
|
||||||
restartDaemon
|
restartDaemon
|
||||||
|
|
||||||
|
|
|
@ -132,4 +132,11 @@ in
|
||||||
ca-fd-leak = runNixOSTestFor "x86_64-linux" ./ca-fd-leak;
|
ca-fd-leak = runNixOSTestFor "x86_64-linux" ./ca-fd-leak;
|
||||||
|
|
||||||
gzip-content-encoding = runNixOSTestFor "x86_64-linux" ./gzip-content-encoding.nix;
|
gzip-content-encoding = runNixOSTestFor "x86_64-linux" ./gzip-content-encoding.nix;
|
||||||
|
|
||||||
|
functional_user = runNixOSTestFor "x86_64-linux" ./functional/as-user.nix;
|
||||||
|
|
||||||
|
functional_trusted = runNixOSTestFor "x86_64-linux" ./functional/as-trusted-user.nix;
|
||||||
|
|
||||||
|
functional_root = runNixOSTestFor "x86_64-linux" ./functional/as-root.nix;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
12
tests/nixos/functional/as-root.nix
Normal file
12
tests/nixos/functional/as-root.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
name = "functional-tests-on-nixos_root";
|
||||||
|
|
||||||
|
imports = [ ./common.nix ];
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
machine.wait_for_unit("multi-user.target")
|
||||||
|
machine.succeed("""
|
||||||
|
run-test-suite >&2
|
||||||
|
""")
|
||||||
|
'';
|
||||||
|
}
|
18
tests/nixos/functional/as-trusted-user.nix
Normal file
18
tests/nixos/functional/as-trusted-user.nix
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
name = "functional-tests-on-nixos_trusted-user";
|
||||||
|
|
||||||
|
imports = [ ./common.nix ];
|
||||||
|
|
||||||
|
nodes.machine = {
|
||||||
|
users.users.alice = { isNormalUser = true; };
|
||||||
|
nix.settings.trusted-users = [ "alice" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
machine.wait_for_unit("multi-user.target")
|
||||||
|
machine.succeed("""
|
||||||
|
export TEST_TRUSTED_USER=1
|
||||||
|
su --login --command "run-test-suite" alice >&2
|
||||||
|
""")
|
||||||
|
'';
|
||||||
|
}
|
16
tests/nixos/functional/as-user.nix
Normal file
16
tests/nixos/functional/as-user.nix
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
name = "functional-tests-on-nixos_user";
|
||||||
|
|
||||||
|
imports = [ ./common.nix ];
|
||||||
|
|
||||||
|
nodes.machine = {
|
||||||
|
users.users.alice = { isNormalUser = true; };
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
machine.wait_for_unit("multi-user.target")
|
||||||
|
machine.succeed("""
|
||||||
|
su --login --command "run-test-suite" alice >&2
|
||||||
|
""")
|
||||||
|
'';
|
||||||
|
}
|
76
tests/nixos/functional/common.nix
Normal file
76
tests/nixos/functional/common.nix
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
# FIXME (roberth) reference issue
|
||||||
|
inputDerivation = pkg: (pkg.overrideAttrs (o: {
|
||||||
|
disallowedReferences = [ ];
|
||||||
|
})).inputDerivation;
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
# Add the quickBuild attribute to the check package
|
||||||
|
./quick-build.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# We rarely change the script in a way that benefits from type checking, so
|
||||||
|
# we skip it to save time.
|
||||||
|
skipTypeCheck = true;
|
||||||
|
|
||||||
|
nodes.machine = { config, pkgs, ... }: {
|
||||||
|
|
||||||
|
virtualisation.writableStore = true;
|
||||||
|
system.extraDependencies = [
|
||||||
|
(inputDerivation config.nix.package)
|
||||||
|
];
|
||||||
|
|
||||||
|
nix.settings.substituters = lib.mkForce [];
|
||||||
|
|
||||||
|
environment.systemPackages = let
|
||||||
|
run-test-suite = pkgs.writeShellApplication {
|
||||||
|
name = "run-test-suite";
|
||||||
|
runtimeInputs = [ pkgs.gnumake pkgs.jq pkgs.git ];
|
||||||
|
text = ''
|
||||||
|
set -x
|
||||||
|
cat /proc/sys/fs/file-max
|
||||||
|
ulimit -Hn
|
||||||
|
ulimit -Sn
|
||||||
|
cd ~
|
||||||
|
cp -r ${pkgs.nix.overrideAttrs (o: {
|
||||||
|
name = "nix-configured-source";
|
||||||
|
outputs = [ "out" ];
|
||||||
|
separateDebugInfo = false;
|
||||||
|
disallowedReferences = [ ];
|
||||||
|
buildPhase = ":";
|
||||||
|
checkPhase = ":";
|
||||||
|
installPhase = ''
|
||||||
|
cp -r . $out
|
||||||
|
'';
|
||||||
|
installCheckPhase = ":";
|
||||||
|
fixupPhase = ":";
|
||||||
|
doInstallCheck = true;
|
||||||
|
})} nix
|
||||||
|
chmod -R +w nix
|
||||||
|
cd nix
|
||||||
|
|
||||||
|
# Tests we don't need
|
||||||
|
echo >tests/functional/plugins/local.mk
|
||||||
|
sed -i tests/functional/local.mk \
|
||||||
|
-e 's!nix_tests += plugins\.sh!!' \
|
||||||
|
-e 's!nix_tests += test-libstoreconsumer\.sh!!' \
|
||||||
|
;
|
||||||
|
|
||||||
|
export isTestOnNixOS=1
|
||||||
|
export version=${config.nix.package.version}
|
||||||
|
export NIX_REMOTE_=daemon
|
||||||
|
export NIX_REMOTE=daemon
|
||||||
|
export NIX_STORE=${builtins.storeDir}
|
||||||
|
make -j1 installcheck --keep-going
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in [
|
||||||
|
run-test-suite
|
||||||
|
pkgs.git
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
47
tests/nixos/functional/quick-build.nix
Normal file
47
tests/nixos/functional/quick-build.nix
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
test@{ lib, extendModules, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
quickBuild = mkOption {
|
||||||
|
description = ''
|
||||||
|
Whether to perform a "quick" build of the Nix package to test.
|
||||||
|
|
||||||
|
When iterating on the functional tests, it's recommended to "set" this
|
||||||
|
to `true`, so that changes to the functional tests don't require any
|
||||||
|
recompilation of the package.
|
||||||
|
You can do so by buildin the `.quickBuild` attribute on the check package,
|
||||||
|
e.g:
|
||||||
|
```console
|
||||||
|
nix build .#hydraJobs.functional_user.quickBuild
|
||||||
|
```
|
||||||
|
|
||||||
|
We don't enable this by default to avoid the mostly unnecessary work of
|
||||||
|
performing an additional build of the package in cases where we build
|
||||||
|
the package normally anyway, such as in our pre-merge CI.
|
||||||
|
'';
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
passthru.quickBuild =
|
||||||
|
let withQuickBuild = extendModules { modules = [{ quickBuild = true; }]; };
|
||||||
|
in withQuickBuild.config.test;
|
||||||
|
|
||||||
|
defaults = { pkgs, ... }: {
|
||||||
|
config = lib.mkIf test.config.quickBuild {
|
||||||
|
nix.package = pkgs.nix_noTests;
|
||||||
|
|
||||||
|
system.forbiddenDependenciesRegexes = [
|
||||||
|
# This would indicate that the quickBuild feature is broken.
|
||||||
|
# It could happen if NixOS has a dependency on pkgs.nix instead of
|
||||||
|
# config.nix.package somewhere.
|
||||||
|
(builtins.unsafeDiscardStringContext pkgs.nix.outPath)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue