From 86a9d80b45a1b9aed0c1b0f94fdbec614703ff4a Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Fri, 6 Dec 2019 07:05:06 +0100 Subject: [PATCH 1/4] nixosTests.dhparams: Port to Python --- nixos/tests/dhparams.nix | 98 ++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 50 deletions(-) diff --git a/nixos/tests/dhparams.nix b/nixos/tests/dhparams.nix index d11dfeec5d0c..a0de2911777c 100644 --- a/nixos/tests/dhparams.nix +++ b/nixos/tests/dhparams.nix @@ -4,7 +4,7 @@ let environment.systemPackages = [ pkgs.openssl ]; }; -in import ./make-test.nix { +in import ./make-test-python.nix { name = "dhparams"; nodes.generation1 = { pkgs, config, ... }: { @@ -66,79 +66,77 @@ in import ./make-test.nix { node = "generation${toString gen}"; in nodes.${node}.config.security.dhparams.params.${name}.path; - assertParamBits = gen: name: bits: let - path = getParamPath gen name; - in '' - $machine->nest('check bit size of ${path}', sub { - my $out = $machine->succeed('openssl dhparam -in ${path} -text'); - $out =~ /^\s*DH Parameters:\s+\((\d+)\s+bit\)\s*$/m; - die "bit size should be ${toString bits} but it is $1 instead." - if $1 != ${toString bits}; - }); - ''; - switchToGeneration = gen: let node = "generation${toString gen}"; inherit (nodes.${node}.config.system.build) toplevel; switchCmd = "${toplevel}/bin/switch-to-configuration test"; in '' - $machine->nest('switch to generation ${toString gen}', sub { - $machine->succeed('${switchCmd}'); - $main::machine = ''$${node}; - }); + with machine.nested("switch to generation ${toString gen}"): + machine.succeed( + "${switchCmd}" + ) + machine = ${node} ''; in '' - my $machine = $generation1; + import re - $machine->waitForUnit('multi-user.target'); - subtest "verify startup order", sub { - $machine->succeed('systemctl is-active foo.service'); - }; + def assert_param_bits(path, bits): + with machine.nested(f"check bit size of {path}"): + output = machine.succeed(f"openssl dhparam -in {path} -text") + pattern = re.compile(r"^\s*DH Parameters:\s+\((\d+)\s+bit\)\s*$", re.M) + match = pattern.match(output) + if match is None: + raise Exception("bla") + if match[1] != str(bits): + raise Exception(f"bit size should be {bits} but it is {match[1]} instead.") - subtest "check bit sizes of dhparam files", sub { - ${assertParamBits 1 "foo" 16} - ${assertParamBits 1 "bar" 17} - }; + + machine = generation1 + + machine.wait_for_unit("multi-user.target") + + with subtest("verify startup order"): + machine.succeed("systemctl is-active foo.service") + + with subtest("check bit sizes of dhparam files"): + assert_param_bits("${getParamPath 1 "foo"}", 16) + assert_param_bits("${getParamPath 1 "bar"}", 17) ${switchToGeneration 2} - subtest "check whether bit size has changed", sub { - ${assertParamBits 2 "foo" 18} - }; + with subtest("check whether bit size has changed"): + assert_param_bits("${getParamPath 2 "foo"}", 18) - subtest "ensure that dhparams file for 'bar' was deleted", sub { - $machine->fail('test -e ${getParamPath 1 "bar"}'); - }; + with subtest("ensure that dhparams file for 'bar' was deleted"): + machine.fail("test -e ${getParamPath 1 "bar"}") ${switchToGeneration 3} - subtest "ensure that 'security.dhparams.path' has been deleted", sub { - $machine->fail( - 'test -e ${nodes.generation3.config.security.dhparams.path}' - ); - }; + with subtest("ensure that 'security.dhparams.path' has been deleted"): + machine.fail("test -e ${nodes.generation3.config.security.dhparams.path}") ${switchToGeneration 4} - subtest "check bit sizes dhparam files", sub { - ${assertParamBits 4 "foo2" 18} - ${assertParamBits 4 "bar2" 19} - }; + with subtest("check bit sizes dhparam files"): + assert_param_bits( + "${getParamPath 4 "foo2"}", 18 + ) + assert_param_bits( + "${getParamPath 4 "bar2"}", 19 + ) - subtest "check whether dhparam files are in the Nix store", sub { - $machine->succeed( - 'expr match ${getParamPath 4 "foo2"} ${builtins.storeDir}', - 'expr match ${getParamPath 4 "bar2"} ${builtins.storeDir}', - ); - }; + with subtest("check whether dhparam files are in the Nix store"): + machine.succeed( + "expr match ${getParamPath 4 "foo2"} ${builtins.storeDir}", + "expr match ${getParamPath 4 "bar2"} ${builtins.storeDir}", + ) ${switchToGeneration 5} - subtest "check whether defaultBitSize works as intended", sub { - ${assertParamBits 5 "foo3" 30} - ${assertParamBits 5 "bar3" 30} - }; + with subtest("check whether defaultBitSize works as intended"): + assert_param_bits("${getParamPath 5 "foo3"}", 30) + assert_param_bits("${getParamPath 5 "bar3"}", 30) ''; } From 4a7ba2cdfe69e18bee4753e2582bb924116c6029 Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Fri, 6 Dec 2019 07:45:49 +0100 Subject: [PATCH 2/4] nixosTests.docker-tools-overlay: Port to Python --- nixos/tests/docker-tools-overlay.nix | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/nixos/tests/docker-tools-overlay.nix b/nixos/tests/docker-tools-overlay.nix index 637957bd3e8b..1a0e0ea67750 100644 --- a/nixos/tests/docker-tools-overlay.nix +++ b/nixos/tests/docker-tools-overlay.nix @@ -1,6 +1,6 @@ # this test creates a simple GNU image with docker tools and sees if it executes -import ./make-test.nix ({ pkgs, ... }: +import ./make-test-python.nix ({ pkgs, ... }: { name = "docker-tools-overlay"; meta = with pkgs.stdenv.lib.maintainers; { @@ -16,17 +16,18 @@ import ./make-test.nix ({ pkgs, ... }: }; }; - testScript = - '' - $docker->waitForUnit("sockets.target"); + testScript = '' + docker.wait_for_unit("sockets.target") - $docker->succeed("docker load --input='${pkgs.dockerTools.examples.bash}'"); - $docker->succeed("docker run --rm ${pkgs.dockerTools.examples.bash.imageName} bash --version"); + docker.succeed( + "docker load --input='${pkgs.dockerTools.examples.bash}'", + "docker run --rm ${pkgs.dockerTools.examples.bash.imageName} bash --version", + ) # Check if the nix store has correct user permissions depending on what # storage driver is used, incorrectly built images can show up as readonly. # drw------- 3 0 0 3 Apr 14 11:36 /nix # drw------- 99 0 0 100 Apr 14 11:36 /nix/store - $docker->succeed("docker run --rm -u 1000:1000 ${pkgs.dockerTools.examples.bash.imageName} bash --version"); + docker.succeed("docker run --rm -u 1000:1000 ${pkgs.dockerTools.examples.bash.imageName} bash --version") ''; }) From 46fab2e289ba396db4d29be327b879c15b4951fb Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Fri, 6 Dec 2019 07:53:04 +0100 Subject: [PATCH 3/4] nixosTests.ecryptfs: Port to Python --- nixos/tests/ecryptfs.nix | 111 ++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 55 deletions(-) diff --git a/nixos/tests/ecryptfs.nix b/nixos/tests/ecryptfs.nix index 3f02cecb8662..ef7bd13eb92c 100644 --- a/nixos/tests/ecryptfs.nix +++ b/nixos/tests/ecryptfs.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ ... }: +import ./make-test-python.nix ({ ... }: { name = "ecryptfs"; @@ -10,75 +10,76 @@ import ./make-test.nix ({ ... }: }; testScript = '' - $machine->waitForUnit("default.target"); + def login_as_alice(): + machine.wait_until_tty_matches(1, "login: ") + machine.send_chars("alice\n") + machine.wait_until_tty_matches(1, "Password: ") + machine.send_chars("foobar\n") + machine.wait_until_tty_matches(1, "alice\@machine") - # Set alice up with a password and a home - $machine->succeed("(echo foobar; echo foobar) | passwd alice"); - $machine->succeed("chown -R alice.users ~alice"); - # Migrate alice's home - my $out = $machine->succeed("echo foobar | ecryptfs-migrate-home -u alice"); - $machine->log("ecryptfs-migrate-home said: $out"); + def logout(): + machine.send_chars("logout\n") + machine.wait_until_tty_matches(1, "login: ") - # Log alice in (ecryptfs passwhrase is wrapped during first login) - $machine->waitUntilTTYMatches(1, "login: "); - $machine->sendChars("alice\n"); - $machine->waitUntilTTYMatches(1, "Password: "); - $machine->sendChars("foobar\n"); - $machine->waitUntilTTYMatches(1, "alice\@machine"); - $machine->sendChars("logout\n"); - $machine->waitUntilTTYMatches(1, "login: "); + + machine.wait_for_unit("default.target") + + with subtest("Set alice up with a password and a home"): + machine.succeed("(echo foobar; echo foobar) | passwd alice") + machine.succeed("chown -R alice.users ~alice") + + with subtest("Migrate alice's home"): + out = machine.succeed("echo foobar | ecryptfs-migrate-home -u alice") + machine.log(f"ecryptfs-migrate-home said: {out}") + + with subtest("Log alice in (ecryptfs passwhrase is wrapped during first login)"): + login_as_alice() + machine.send_chars("logout\n") + machine.wait_until_tty_matches(1, "login: ") # Why do I need to do this?? - $machine->succeed("su alice -c ecryptfs-umount-private || true"); - $machine->sleep(1); - $machine->fail("mount | grep ecryptfs"); # check that encrypted home is not mounted + machine.succeed("su alice -c ecryptfs-umount-private || true") + machine.sleep(1) - # Show contents of the user keyring - my $out = $machine->succeed("su - alice -c 'keyctl list \@u'"); - $machine->log("keyctl unlink said: " . $out); + with subtest("check that encrypted home is not mounted"): + machine.fail("mount | grep ecryptfs") - # Log alice again - $machine->waitUntilTTYMatches(1, "login: "); - $machine->sendChars("alice\n"); - $machine->waitUntilTTYMatches(1, "Password: "); - $machine->sendChars("foobar\n"); - $machine->waitUntilTTYMatches(1, "alice\@machine"); + with subtest("Show contents of the user keyring"): + out = machine.succeed("su - alice -c 'keyctl list \@u'") + machine.log(f"keyctl unlink said: {out}") - # Create some files in encrypted home - $machine->succeed("su alice -c 'touch ~alice/a'"); - $machine->succeed("su alice -c 'echo c > ~alice/b'"); + with subtest("Log alice again"): + login_as_alice() - # Logout - $machine->sendChars("logout\n"); - $machine->waitUntilTTYMatches(1, "login: "); + with subtest("Create some files in encrypted home"): + machine.succeed("su alice -c 'touch ~alice/a'") + machine.succeed("su alice -c 'echo c > ~alice/b'") + + with subtest("Logout"): + logout() # Why do I need to do this?? - $machine->succeed("su alice -c ecryptfs-umount-private || true"); - $machine->sleep(1); + machine.succeed("su alice -c ecryptfs-umount-private || true") + machine.sleep(1) - # Check that the filesystem is not accessible - $machine->fail("mount | grep ecryptfs"); - $machine->succeed("su alice -c 'test \! -f ~alice/a'"); - $machine->succeed("su alice -c 'test \! -f ~alice/b'"); + with subtest("Check that the filesystem is not accessible"): + machine.fail("mount | grep ecryptfs") + machine.succeed("su alice -c 'test \! -f ~alice/a'") + machine.succeed("su alice -c 'test \! -f ~alice/b'") - # Log alice once more - $machine->waitUntilTTYMatches(1, "login: "); - $machine->sendChars("alice\n"); - $machine->waitUntilTTYMatches(1, "Password: "); - $machine->sendChars("foobar\n"); - $machine->waitUntilTTYMatches(1, "alice\@machine"); + with subtest("Log alice once more"): + login_as_alice() - # Check that the files are there - $machine->sleep(1); - $machine->succeed("su alice -c 'test -f ~alice/a'"); - $machine->succeed("su alice -c 'test -f ~alice/b'"); - $machine->succeed(qq%test "\$(cat ~alice/b)" = "c"%); + with subtest("Check that the files are there"): + machine.sleep(1) + machine.succeed("su alice -c 'test -f ~alice/a'") + machine.succeed("su alice -c 'test -f ~alice/b'") + machine.succeed('test "$(cat ~alice/b)" = "c"') - # Catch https://github.com/NixOS/nixpkgs/issues/16766 - $machine->succeed("su alice -c 'ls -lh ~alice/'"); + with subtest("Catch https://github.com/NixOS/nixpkgs/issues/16766"): + machine.succeed("su alice -c 'ls -lh ~alice/'") - $machine->sendChars("logout\n"); - $machine->waitUntilTTYMatches(1, "login: "); + logout() ''; }) From 7e25be92b716ecc39320521c26351d6e66268d77 Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Fri, 6 Dec 2019 08:18:47 +0100 Subject: [PATCH 4/4] nixosTests.env: Port to Python --- nixos/tests/env.nix | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/nixos/tests/env.nix b/nixos/tests/env.nix index 6c681905b19f..e603338e489b 100644 --- a/nixos/tests/env.nix +++ b/nixos/tests/env.nix @@ -1,4 +1,4 @@ -import ./make-test.nix ({ pkgs, ...} : { +import ./make-test-python.nix ({ pkgs, ...} : { name = "environment"; meta = with pkgs.stdenv.lib.maintainers; { maintainers = [ nequissimus ]; @@ -20,16 +20,17 @@ import ./make-test.nix ({ pkgs, ...} : { }; }; - testScript = - '' - $machine->succeed('[ -L "/etc/plainFile" ]'); - $machine->succeed('cat "/etc/plainFile" | grep "Hello World"'); - $machine->succeed('[ -d "/etc/folder" ]'); - $machine->succeed('[ -d "/etc/folder/with" ]'); - $machine->succeed('[ -L "/etc/folder/with/file" ]'); - $machine->succeed('cat "/etc/plainFile" | grep "Hello World"'); + testScript = '' + machine.succeed('[ -L "/etc/plainFile" ]') + assert "Hello World" in machine.succeed('cat "/etc/plainFile"') + machine.succeed('[ -d "/etc/folder" ]') + machine.succeed('[ -d "/etc/folder/with" ]') + machine.succeed('[ -L "/etc/folder/with/file" ]') + assert "Hello World" in machine.succeed('cat "/etc/plainFile"') - $machine->succeed('echo ''${TERMINFO_DIRS} | grep "/run/current-system/sw/share/terminfo"'); - $machine->succeed('echo ''${NIXCON} | grep "awesome"'); - ''; + assert "/run/current-system/sw/share/terminfo" in machine.succeed( + "echo ''${TERMINFO_DIRS}" + ) + assert "awesome" in machine.succeed("echo ''${NIXCON}") + ''; })