nixos-rebuild-ng: add repl test and fix issues

This commit is contained in:
Thiago Kenji Okada
2024-12-10 18:38:09 +00:00
parent 14ab7a484d
commit c27b1c401a
5 changed files with 185 additions and 17 deletions
+16 -12
View File
@@ -1,5 +1,6 @@
{
lib,
callPackage,
installShellFiles,
mkShell,
nix,
@@ -92,20 +93,23 @@ python3Packages.buildPythonApplication rec {
'';
};
# NOTE: this is a passthru test rather than a build-time test because we
# want to keep the build closures small
tests.ci = runCommand "${pname}-ci" { nativeBuildInputs = [ python-with-pkgs ]; } ''
export RUFF_CACHE_DIR="$(mktemp -d)"
tests = {
repl = callPackage ./tests/repl.nix { };
# NOTE: this is a passthru test rather than a build-time test because we
# want to keep the build closures small
linters = runCommand "${pname}-linters" { nativeBuildInputs = [ python-with-pkgs ]; } ''
export RUFF_CACHE_DIR="$(mktemp -d)"
echo -e "\x1b[32m## run mypy\x1b[0m"
mypy ${src}
echo -e "\x1b[32m## run ruff\x1b[0m"
ruff check ${src}
echo -e "\x1b[32m## run ruff format\x1b[0m"
ruff format --check ${src}
echo -e "\x1b[32m## run mypy\x1b[0m"
mypy ${src}
echo -e "\x1b[32m## run ruff\x1b[0m"
ruff check ${src}
echo -e "\x1b[32m## run ruff format\x1b[0m"
ruff format --check ${src}
touch $out
'';
touch $out
'';
};
};
meta = {
@@ -366,7 +366,8 @@ def repl_flake(attr: str, flake: Flake, **flake_flags: Args) -> None:
expr = Template(
files(__package__).joinpath(FLAKE_REPL_TEMPLATE).read_text()
).substitute(
flake_path=flake.path,
flake=flake,
flake_path=flake.path.resolve() if isinstance(flake.path, Path) else flake.path,
flake_attr=flake.attr,
bold="\033[1m",
blue="\033[34;1m",
@@ -16,7 +16,7 @@ let
- ${blue}lib${reset} Nixpkgs library functions
- other module arguments
- ${blue}flake${reset} Flake outputs, inputs and source info of ${flake_path}
- ${blue}flake${reset} Flake outputs, inputs and source info of ${flake}
Use tab completion to browse around ${blue}config${reset}.
@@ -399,9 +399,9 @@ def test_repl(mock_run: Any) -> None:
@patch(get_qualified_name(n.run_wrapper, n), autospec=True)
def test_repl_flake(mock_run: Any) -> None:
n.repl_flake("attr", m.Flake(Path("flake.nix"), "myAttr"), nix_flag=True)
# This method would be really annoying to test, and it is not that important
# So just check that we are at least calling it
assert mock_run.called
# See nixos-rebuild-ng.tests.repl for a better test,
# this is mostly for sanity check
assert mock_run.call_count == 1
@patch(get_qualified_name(n.run_wrapper, n), autospec=True)
@@ -0,0 +1,163 @@
{
lib,
expect,
nix,
nixos-rebuild-ng,
path,
runCommand,
stdenv,
writeText,
}:
let
# Arguably not true, but it holds up for now.
escapeExpect = lib.strings.escapeNixString;
expectSetup = ''
set timeout 180
proc expect_simple { pattern } {
puts "Expecting: $pattern"
expect {
timeout {
puts "\nTimeout waiting for: $pattern\n"
exit 1
}
$pattern
}
}
'';
# In case we want/need to evaluate packages or the assertions or whatever,
# we want to have a linux system.
# TODO: make the non-flake test use thise.
linuxSystem = lib.replaceStrings [ "darwin" ] [ "linux" ] stdenv.hostPlatform.system;
in
runCommand "test-nixos-rebuild-repl"
{
nativeBuildInputs = [
expect
nix
(nixos-rebuild-ng.override { withNgSuffix = false; })
];
nixpkgs = if builtins.pathExists (path + "/.git") then lib.cleanSource path else path;
}
''
export HOME=$(mktemp -d)
export TEST_ROOT=$PWD/test-tmp
# Prepare for running Nix in sandbox
export NIX_BUILD_HOOK=
export NIX_CONF_DIR=$TEST_ROOT/etc
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
export NIX_STATE_DIR=$TEST_ROOT/var/nix
export NIX_STORE_DIR=$TEST_ROOT/store
export PAGER=cat
mkdir -p $TEST_ROOT $NIX_CONF_DIR
echo General setup
##################
export NIX_PATH=nixpkgs=$nixpkgs:nixos-config=$HOME/configuration.nix
cat >> ~/configuration.nix <<EOF
{
boot.loader.grub.enable = false;
fileSystems."/".device = "x";
imports = [ ./hardware-configuration.nix ];
}
EOF
echo '{ }' > ~/hardware-configuration.nix
echo Test traditional NixOS configuration
#########################################
expect ${writeText "test-nixos-rebuild-repl-expect" ''
${expectSetup}
spawn nixos-rebuild repl --fast
expect "nix-repl> "
send "config.networking.hostName\n"
expect "\"nixos\""
''}
echo Test flake based NixOS configuration
#########################################
# Switch to flake flavored environment
unset NIX_PATH
cat > $NIX_CONF_DIR/nix.conf <<EOF
experimental-features = nix-command flakes
EOF
# Make the config pure
echo '{ nixpkgs.hostPlatform = "${linuxSystem}"; }' > ~/hardware-configuration.nix
cat >~/flake.nix <<EOF
{
inputs.nixpkgs.url = "path:$nixpkgs";
outputs = { nixpkgs, ... }: {
nixosConfigurations.testconf = nixpkgs.lib.nixosSystem {
modules = [
./configuration.nix
# Let's change it up a bit
{ networking.hostName = "itsme"; }
];
};
};
}
EOF
# cat -n ~/flake.nix
expect ${writeText "test-nixos-rebuild-repl-absolute-path-expect" ''
${expectSetup}
spawn sh -c "nixos-rebuild repl --fast --flake path:\$HOME#testconf"
expect_simple "nix-repl>"
send "config.networking.hostName\n"
expect_simple "itsme"
expect_simple "nix-repl>"
send "lib.version\n"
expect_simple ${
escapeExpect (
# The version string is a bit different in the flake lib, so we expect a prefix and ignore the rest
# Furthermore, including the revision (suffix) would cause unnecessary rebuilds.
# Note that a length of 4 only matches e.g. "24.
lib.strings.substring 0 4 (lib.strings.escapeNixString lib.version)
)
}
# Make sure it's the right lib - should be the flake lib, not Nixpkgs lib.
expect_simple "nix-repl>"
send "lib?nixosSystem\n"
expect_simple "true"
expect_simple "nix-repl>"
send "lib?nixos\n"
expect_simple "true"
''}
pushd "$HOME"
expect ${writeText "test-nixos-rebuild-repl-relative-path-expect" ''
${expectSetup}
spawn sh -c "nixos-rebuild repl --fast --flake .#testconf"
expect_simple "nix-repl>"
send "config.networking.hostName\n"
expect_simple "itsme"
''}
popd
echo
#########
echo Done
touch $out
''