summary refs log tree commit diff
path: root/nixos/tests
diff options
context:
space:
mode:
authorFrederik Rietdijk <fridh@fridh.nl>2020-08-24 11:50:58 +0200
committerFrederik Rietdijk <fridh@fridh.nl>2020-08-24 11:50:58 +0200
commit0a874ff2a6dad9d2693f08a733d58f8077f36916 (patch)
tree80360888241c761769d9a1074fd96b22d7664598 /nixos/tests
parent91104b5417275b780f6947b46a5c1bcc0d99f10b (diff)
parentbc00ecedfa709f4fa91d445dd76ecd792cb2c728 (diff)
downloadnixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.tar
nixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.tar.gz
nixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.tar.bz2
nixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.tar.lz
nixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.tar.xz
nixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.tar.zst
nixpkgs-0a874ff2a6dad9d2693f08a733d58f8077f36916.zip
Merge master into staging-next
Diffstat (limited to 'nixos/tests')
-rw-r--r--nixos/tests/all-tests.nix6
-rw-r--r--nixos/tests/common/ec2.nix58
-rw-r--r--nixos/tests/containers-reloadable.nix4
-rw-r--r--nixos/tests/cri-o.nix19
-rw-r--r--nixos/tests/docker-preloader.nix27
-rw-r--r--nixos/tests/ec2.nix140
-rw-r--r--nixos/tests/gnome3.nix10
-rw-r--r--nixos/tests/hardened.nix114
-rw-r--r--nixos/tests/hocker-fetchdocker/default.nix9
-rw-r--r--nixos/tests/installer.nix2
-rw-r--r--nixos/tests/openstack-image.nix70
11 files changed, 241 insertions, 218 deletions
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 0ce5f89b27c..7b8e1b2b56d 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -66,11 +66,13 @@ in
   containers-macvlans = handleTest ./containers-macvlans.nix {};
   containers-physical_interfaces = handleTest ./containers-physical_interfaces.nix {};
   containers-portforward = handleTest ./containers-portforward.nix {};
+  containers-reloadable = handleTest ./containers-reloadable.nix {};
   containers-restart_networking = handleTest ./containers-restart_networking.nix {};
   containers-tmpfs = handleTest ./containers-tmpfs.nix {};
   convos = handleTest ./convos.nix {};
   corerad = handleTest ./corerad.nix {};
   couchdb = handleTest ./couchdb.nix {};
+  cri-o = handleTestOn ["x86_64-linux"] ./cri-o.nix {};
   deluge = handleTest ./deluge.nix {};
   dhparams = handleTest ./dhparams.nix {};
   dnscrypt-proxy2 = handleTestOn ["x86_64-linux"] ./dnscrypt-proxy2.nix {};
@@ -79,15 +81,13 @@ in
   docker = handleTestOn ["x86_64-linux"] ./docker.nix {};
   oci-containers = handleTestOn ["x86_64-linux"] ./oci-containers.nix {};
   docker-edge = handleTestOn ["x86_64-linux"] ./docker-edge.nix {};
-  docker-preloader = handleTestOn ["x86_64-linux"] ./docker-preloader.nix {};
   docker-registry = handleTest ./docker-registry.nix {};
   docker-tools = handleTestOn ["x86_64-linux"] ./docker-tools.nix {};
   docker-tools-overlay = handleTestOn ["x86_64-linux"] ./docker-tools-overlay.nix {};
   documize = handleTest ./documize.nix {};
   dokuwiki = handleTest ./dokuwiki.nix {};
   dovecot = handleTest ./dovecot.nix {};
-  # ec2-config doesn't work in a sandbox as the simulated ec2 instance needs network access
-  #ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {};
+  ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {};
   ec2-nixops = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-nixops or {};
   ecryptfs = handleTest ./ecryptfs.nix {};
   ejabberd = handleTest ./xmpp/ejabberd.nix {};
diff --git a/nixos/tests/common/ec2.nix b/nixos/tests/common/ec2.nix
index ba087bb6009..502fe96231f 100644
--- a/nixos/tests/common/ec2.nix
+++ b/nixos/tests/common/ec2.nix
@@ -20,30 +20,44 @@ with pkgs.lib;
     in makeTest {
       name = "ec2-" + name;
       nodes = {};
-      testScript =
-        ''
-          my $imageDir = ($ENV{'TMPDIR'} // "/tmp") . "/vm-state-machine";
-          mkdir $imageDir, 0700;
-          my $diskImage = "$imageDir/machine.qcow2";
-          system("qemu-img create -f qcow2 -o backing_file=${image} $diskImage") == 0 or die;
-          system("qemu-img resize $diskImage 10G") == 0 or die;
+      testScript = ''
+        import os
+        import subprocess
 
-          # Note: we use net=169.0.0.0/8 rather than
-          # net=169.254.0.0/16 to prevent dhcpcd from getting horribly
-          # confused. (It would get a DHCP lease in the 169.254.*
-          # range, which it would then configure and prompty delete
-          # again when it deletes link-local addresses.) Ideally we'd
-          # turn off the DHCP server, but qemu does not have an option
-          # to do that.
-          my $startCommand = "qemu-kvm -m 1024";
-          $startCommand .= " -device virtio-net-pci,netdev=vlan0";
-          $startCommand .= " -netdev 'user,id=vlan0,net=169.0.0.0/8,guestfwd=tcp:169.254.169.254:80-cmd:${pkgs.micro-httpd}/bin/micro_httpd ${metaData}'";
-          $startCommand .= " -drive file=$diskImage,if=virtio,werror=report";
-          $startCommand .= " \$QEMU_OPTS";
+        image_dir = os.path.join(
+            os.environ.get("TMPDIR", tempfile.gettempdir()), "tmp", "vm-state-machine"
+        )
+        os.makedirs(image_dir, mode=0o700, exist_ok=True)
+        disk_image = os.path.join(image_dir, "machine.qcow2")
+        subprocess.check_call(
+            [
+                "qemu-img",
+                "create",
+                "-f",
+                "qcow2",
+                "-o",
+                "backing_file=${image}",
+                disk_image,
+            ]
+        )
+        subprocess.check_call(["qemu-img", "resize", disk_image, "10G"])
 
-          my $machine = createMachine({ startCommand => $startCommand });
+        # Note: we use net=169.0.0.0/8 rather than
+        # net=169.254.0.0/16 to prevent dhcpcd from getting horribly
+        # confused. (It would get a DHCP lease in the 169.254.*
+        # range, which it would then configure and prompty delete
+        # again when it deletes link-local addresses.) Ideally we'd
+        # turn off the DHCP server, but qemu does not have an option
+        # to do that.
+        start_command = (
+            "qemu-kvm -m 1024"
+            + " -device virtio-net-pci,netdev=vlan0"
+            + " -netdev 'user,id=vlan0,net=169.0.0.0/8,guestfwd=tcp:169.254.169.254:80-cmd:${pkgs.micro-httpd}/bin/micro_httpd ${metaData}'"
+            + f" -drive file={disk_image},if=virtio,werror=report"
+            + " $QEMU_OPTS"
+        )
 
-          ${script}
-        '';
+        machine = create_machine({"startCommand": start_command})
+      '' + script;
     };
 }
diff --git a/nixos/tests/containers-reloadable.nix b/nixos/tests/containers-reloadable.nix
index 35aff91e85b..2d81f163938 100644
--- a/nixos/tests/containers-reloadable.nix
+++ b/nixos/tests/containers-reloadable.nix
@@ -9,13 +9,13 @@ let
       };
     };
 
-    # prevent make-test.nix to change IP
+    # prevent make-test-python.nix to change IP
     networking.interfaces = {
       eth1.ipv4.addresses = lib.mkOverride 0 [ ];
     };
   };
 in {
-  name = "cotnainers-reloadable";
+  name = "containers-reloadable";
   meta = with pkgs.stdenv.lib.maintainers; {
     maintainers = [ danbst ];
   };
diff --git a/nixos/tests/cri-o.nix b/nixos/tests/cri-o.nix
new file mode 100644
index 00000000000..f13f1bdacb6
--- /dev/null
+++ b/nixos/tests/cri-o.nix
@@ -0,0 +1,19 @@
+# This test runs CRI-O and verifies via critest
+import ./make-test-python.nix ({ pkgs, ... }: {
+  name = "cri-o";
+  maintainers = with pkgs.stdenv.lib.maintainers; teams.podman.members;
+
+  nodes = {
+    crio = {
+      virtualisation.cri-o.enable = true;
+    };
+  };
+
+  testScript = ''
+    start_all()
+    crio.wait_for_unit("crio.service")
+    crio.succeed(
+        "critest --ginkgo.focus='Runtime info' --runtime-endpoint unix:///var/run/crio/crio.sock"
+    )
+  '';
+})
diff --git a/nixos/tests/docker-preloader.nix b/nixos/tests/docker-preloader.nix
deleted file mode 100644
index c3e8aced351..00000000000
--- a/nixos/tests/docker-preloader.nix
+++ /dev/null
@@ -1,27 +0,0 @@
-import ./make-test.nix ({ pkgs, ...} : {
-  name = "docker-preloader";
-  meta = with pkgs.stdenv.lib.maintainers; {
-    maintainers = [ lewo ];
-  };
-
-  nodes = {
-    docker =
-      { pkgs, ... }:
-        {
-          virtualisation.docker.enable = true;
-          virtualisation.dockerPreloader.images = [ pkgs.dockerTools.examples.nix pkgs.dockerTools.examples.bash ];
-
-          services.openssh.enable = true;
-          services.openssh.permitRootLogin = "yes";
-          services.openssh.extraConfig = "PermitEmptyPasswords yes";
-          users.extraUsers.root.password = "";
-        };
-  };
-  testScript = ''
-    startAll;
-
-    $docker->waitForUnit("sockets.target");
-    $docker->succeed("docker run nix nix-store --version");
-    $docker->succeed("docker run bash bash --version");
-  '';
-})
diff --git a/nixos/tests/ec2.nix b/nixos/tests/ec2.nix
index 5a59d65e602..df067248016 100644
--- a/nixos/tests/ec2.nix
+++ b/nixos/tests/ec2.nix
@@ -3,58 +3,58 @@
   pkgs ? import ../.. { inherit system config; }
 }:
 
-with import ../lib/testing.nix { inherit system pkgs; };
+with import ../lib/testing-python.nix { inherit system pkgs; };
 with pkgs.lib;
 
 with import common/ec2.nix { inherit makeTest pkgs; };
 
 let
-  imageCfg =
-    (import ../lib/eval-config.nix {
-      inherit system;
-      modules = [
-        ../maintainers/scripts/ec2/amazon-image.nix
-        ../modules/testing/test-instrumentation.nix
-        ../modules/profiles/qemu-guest.nix
-        { ec2.hvm = true;
-
-          # Hack to make the partition resizing work in QEMU.
-          boot.initrd.postDeviceCommands = mkBefore
-            ''
-              ln -s vda /dev/xvda
-              ln -s vda1 /dev/xvda1
-            '';
-
-          # Needed by nixos-rebuild due to the lack of network
-          # access. Determined by trial and error.
-          system.extraDependencies =
-            with pkgs; (
-              [
-                # Needed for a nixos-rebuild.
-                busybox
-                stdenv
-                stdenvNoCC
-                mkinitcpio-nfs-utils
-                unionfs-fuse
-                cloud-utils
-                desktop-file-utils
-                texinfo
-                libxslt.bin
-                xorg.lndir
-
-                # These are used in the configure-from-userdata tests
-                # for EC2. Httpd and valgrind are requested by the
-                # configuration.
-                apacheHttpd apacheHttpd.doc apacheHttpd.man valgrind.doc
-              ]
-            );
-        }
-      ];
-    }).config;
+  imageCfg = (import ../lib/eval-config.nix {
+    inherit system;
+    modules = [
+      ../maintainers/scripts/ec2/amazon-image.nix
+      ../modules/testing/test-instrumentation.nix
+      ../modules/profiles/qemu-guest.nix
+      {
+        ec2.hvm = true;
+
+        # Hack to make the partition resizing work in QEMU.
+        boot.initrd.postDeviceCommands = mkBefore ''
+          ln -s vda /dev/xvda
+          ln -s vda1 /dev/xvda1
+        '';
+
+        # Needed by nixos-rebuild due to the lack of network
+        # access. Determined by trial and error.
+        system.extraDependencies = with pkgs; ( [
+          # Needed for a nixos-rebuild.
+          busybox
+          cloud-utils
+          desktop-file-utils
+          libxslt.bin
+          mkinitcpio-nfs-utils
+          stdenv
+          stdenvNoCC
+          texinfo
+          unionfs-fuse
+          xorg.lndir
+
+          # These are used in the configure-from-userdata tests
+          # for EC2. Httpd and valgrind are requested by the
+          # configuration.
+          apacheHttpd
+          apacheHttpd.doc
+          apacheHttpd.man
+          valgrind.doc
+        ]);
+      }
+    ];
+  }).config;
   image = "${imageCfg.system.build.amazonImage}/${imageCfg.amazonImage.name}.vhd";
 
   sshKeys = import ./ssh-keys.nix pkgs;
   snakeOilPrivateKey = sshKeys.snakeOilPrivateKey.text;
+  snakeOilPrivateKeyFile = pkgs.writeText "private-key" snakeOilPrivateKey;
   snakeOilPublicKey = sshKeys.snakeOilPublicKey;
 
 in {
@@ -68,43 +68,47 @@ in {
       SSH_HOST_ED25519_KEY:${replaceStrings ["\n"] ["|"] snakeOilPrivateKey}
     '';
     script = ''
-      $machine->start;
-      $machine->waitForFile("/etc/ec2-metadata/user-data");
-      $machine->waitForUnit("sshd.service");
+      machine.start()
+      machine.wait_for_file("/etc/ec2-metadata/user-data")
+      machine.wait_for_unit("sshd.service")
 
-      $machine->succeed("grep unknown /etc/ec2-metadata/ami-manifest-path");
+      machine.succeed("grep unknown /etc/ec2-metadata/ami-manifest-path")
 
       # We have no keys configured on the client side yet, so this should fail
-      $machine->fail("ssh -o BatchMode=yes localhost exit");
+      machine.fail("ssh -o BatchMode=yes localhost exit")
 
       # Let's install our client private key
-      $machine->succeed("mkdir -p ~/.ssh");
+      machine.succeed("mkdir -p ~/.ssh")
 
-      $machine->succeed("echo '${snakeOilPrivateKey}' > ~/.ssh/id_ed25519");
-      $machine->succeed("chmod 600 ~/.ssh/id_ed25519");
+      machine.copy_from_host_via_shell(
+          "${snakeOilPrivateKeyFile}", "~/.ssh/id_ed25519"
+      )
+      machine.succeed("chmod 600 ~/.ssh/id_ed25519")
 
       # We haven't configured the host key yet, so this should still fail
-      $machine->fail("ssh -o BatchMode=yes localhost exit");
+      machine.fail("ssh -o BatchMode=yes localhost exit")
 
       # Add the host key; ssh should finally succeed
-      $machine->succeed("echo localhost,127.0.0.1 ${snakeOilPublicKey} > ~/.ssh/known_hosts");
-      $machine->succeed("ssh -o BatchMode=yes localhost exit");
+      machine.succeed(
+          "echo localhost,127.0.0.1 ${snakeOilPublicKey} > ~/.ssh/known_hosts"
+      )
+      machine.succeed("ssh -o BatchMode=yes localhost exit")
 
       # Test whether the root disk was resized.
-      my $blocks = $machine->succeed("stat -c %b -f /");
-      my $bsize = $machine->succeed("stat -c %S -f /");
-      my $size = $blocks * $bsize;
-      die "wrong free space $size" if $size < 9.7 * 1024 * 1024 * 1024 || $size > 10 * 1024 * 1024 * 1024;
+      blocks, block_size = map(int, machine.succeed("stat -c %b:%S -f /").split(":"))
+      GB = 1024 ** 3
+      assert 9.7 * GB <= blocks * block_size <= 10 * GB
 
       # Just to make sure resizing is idempotent.
-      $machine->shutdown;
-      $machine->start;
-      $machine->waitForFile("/etc/ec2-metadata/user-data");
+      machine.shutdown()
+      machine.start()
+      machine.wait_for_file("/etc/ec2-metadata/user-data")
     '';
   };
 
   boot-ec2-config = makeEc2Test {
     name         = "config-userdata";
+    meta.broken = true; # amazon-init wants to download from the internet while building the system
     inherit image;
     sshPublicKey = snakeOilPublicKey;
 
@@ -133,17 +137,17 @@ in {
       }
     '';
     script = ''
-      $machine->start;
+      machine.start()
 
       # amazon-init must succeed. if it fails, make the test fail
-      # immediately instead of timing out in waitForFile.
-      $machine->waitForUnit('amazon-init.service');
+      # immediately instead of timing out in wait_for_file.
+      machine.wait_for_unit("amazon-init.service")
 
-      $machine->waitForFile("/etc/testFile");
-      $machine->succeed("cat /etc/testFile | grep -q 'whoa'");
+      machine.wait_for_file("/etc/testFile")
+      assert "whoa" in machine.succeed("cat /etc/testFile")
 
-      $machine->waitForUnit("httpd.service");
-      $machine->succeed("curl http://localhost | grep Valgrind");
+      machine.wait_for_unit("httpd.service")
+      assert "Valgrind" in machine.succeed("curl http://localhost")
     '';
   };
 }
diff --git a/nixos/tests/gnome3.nix b/nixos/tests/gnome3.nix
index b3d7aff8bd7..7e301be49d1 100644
--- a/nixos/tests/gnome3.nix
+++ b/nixos/tests/gnome3.nix
@@ -23,6 +23,13 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : {
       services.xserver.desktopManager.gnome3.enable = true;
       services.xserver.desktopManager.gnome3.debug = true;
 
+      environment.systemPackages = [
+        (pkgs.makeAutostartItem {
+          name = "org.gnome.Terminal";
+          package = pkgs.gnome3.gnome-terminal;
+        })
+      ];
+
       virtualisation.memorySize = 1024;
     };
 
@@ -65,9 +72,6 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : {
           )
 
       with subtest("Open Gnome Terminal"):
-          machine.succeed(
-              "${gnomeTerminalCommand}"
-          )
           # correct output should be (true, '"gnome-terminal-server"')
           machine.wait_until_succeeds(
               "${wmClass} | grep -q 'gnome-terminal-server'"
diff --git a/nixos/tests/hardened.nix b/nixos/tests/hardened.nix
index 5ed0dfcf9ab..8d845de70e2 100644
--- a/nixos/tests/hardened.nix
+++ b/nixos/tests/hardened.nix
@@ -1,4 +1,4 @@
-import ./make-test.nix ({ pkgs, latestKernel ? false, ... } : {
+import ./make-test-python.nix ({ pkgs, latestKernel ? false, ... } : {
   name = "hardened";
   meta = with pkgs.stdenv.lib.maintainers; {
     maintainers = [ joachifm ];
@@ -47,84 +47,88 @@ import ./make-test.nix ({ pkgs, latestKernel ? false, ... } : {
       };
     in
     ''
-      $machine->waitForUnit("multi-user.target");
+      machine.wait_for_unit("multi-user.target")
+
+
+      with subtest("AppArmor profiles are loaded"):
+          machine.succeed("systemctl status apparmor.service")
 
-      subtest "apparmor-loaded", sub {
-          $machine->succeed("systemctl status apparmor.service");
-      };
 
       # AppArmor securityfs
-      subtest "apparmor-securityfs", sub {
-          $machine->succeed("mountpoint -q /sys/kernel/security");
-          $machine->succeed("cat /sys/kernel/security/apparmor/profiles");
-      };
+      with subtest("AppArmor securityfs is mounted"):
+          machine.succeed("mountpoint -q /sys/kernel/security")
+          machine.succeed("cat /sys/kernel/security/apparmor/profiles")
+
 
       # Test loading out-of-tree modules
-      subtest "extra-module-packages", sub {
-          $machine->succeed("grep -Fq wireguard /proc/modules");
-      };
+      with subtest("Out-of-tree modules can be loaded"):
+          machine.succeed("grep -Fq wireguard /proc/modules")
+
 
       # Test hidepid
-      subtest "hidepid", sub {
-          $machine->succeed("grep -Fq hidepid=2 /proc/mounts");
+      with subtest("hidepid=2 option is applied and works"):
+          machine.succeed("grep -Fq hidepid=2 /proc/mounts")
           # cannot use pgrep -u here, it segfaults when access to process info is denied
-          $machine->succeed("[ `su - sybil -c 'ps --no-headers --user root | wc -l'` = 0 ]");
-          $machine->succeed("[ `su - alice -c 'ps --no-headers --user root | wc -l'` != 0 ]");
-      };
+          machine.succeed("[ `su - sybil -c 'ps --no-headers --user root | wc -l'` = 0 ]")
+          machine.succeed("[ `su - alice -c 'ps --no-headers --user root | wc -l'` != 0 ]")
+
 
       # Test kernel module hardening
-      subtest "lock-modules", sub {
+      with subtest("No more kernel modules can be loaded"):
           # note: this better a be module we normally wouldn't load ...
-          $machine->fail("modprobe dccp");
-      };
+          machine.fail("modprobe dccp")
+
 
       # Test userns
-      subtest "userns", sub {
-          $machine->succeed("unshare --user true");
-          $machine->fail("su -l alice -c 'unshare --user true'");
-      };
+      with subtest("User namespaces are restricted"):
+          machine.succeed("unshare --user true")
+          machine.fail("su -l alice -c 'unshare --user true'")
+
 
       # Test dmesg restriction
-      subtest "dmesg", sub {
-          $machine->fail("su -l alice -c dmesg");
-      };
+      with subtest("Regular users cannot access dmesg"):
+          machine.fail("su -l alice -c dmesg")
+
 
       # Test access to kcore
-      subtest "kcore", sub {
-          $machine->fail("cat /proc/kcore");
-      };
+      with subtest("Kcore is inaccessible as root"):
+          machine.fail("cat /proc/kcore")
+
 
       # Test deferred mount
-      subtest "mount", sub {
-        $machine->fail("mountpoint -q /efi"); # was deferred
-        $machine->execute("mkdir -p /efi");
-        $machine->succeed("mount /dev/disk/by-label/EFISYS /efi");
-        $machine->succeed("mountpoint -q /efi"); # now mounted
-      };
+      with subtest("Deferred mounts work"):
+          machine.fail("mountpoint -q /efi")  # was deferred
+          machine.execute("mkdir -p /efi")
+          machine.succeed("mount /dev/disk/by-label/EFISYS /efi")
+          machine.succeed("mountpoint -q /efi")  # now mounted
+
 
       # Test Nix dæmon usage
-      subtest "nix-daemon", sub {
-        $machine->fail("su -l nobody -s /bin/sh -c 'nix ping-store'");
-        $machine->succeed("su -l alice -c 'nix ping-store'") =~ "OK";
-      };
+      with subtest("nix-daemon cannot be used by all users"):
+          machine.fail("su -l nobody -s /bin/sh -c 'nix ping-store'")
+          machine.succeed("su -l alice -c 'nix ping-store'")
+
 
       # Test kernel image protection
-      subtest "kernelimage", sub {
-        $machine->fail("systemctl hibernate");
-        $machine->fail("systemctl kexec");
-      };
+      with subtest("The kernel image is protected"):
+          machine.fail("systemctl hibernate")
+          machine.fail("systemctl kexec")
 
-      # Test hardened memory allocator
-      sub runMallocTestProg {
-          my ($progName, $errorText) = @_;
-          my $text = "fatal allocator error: " . $errorText;
-          $machine->fail("${hardened-malloc-tests}/bin/" . $progName) =~ $text;
-      };
 
-      subtest "hardenedmalloc", sub {
-        runMallocTestProg("double_free_large", "invalid free");
-        runMallocTestProg("unaligned_free_small", "invalid unaligned free");
-        runMallocTestProg("write_after_free_small", "detected write after free");
-      };
+      # Test hardened memory allocator
+      def runMallocTestProg(prog_name, error_text):
+          text = "fatal allocator error: " + error_text
+          if not text in machine.fail(
+              "${hardened-malloc-tests}/bin/"
+              + prog_name
+              + " 2>&1"
+          ):
+              raise Exception("Hardened malloc does not work for {}".format(error_text))
+
+
+      with subtest("The hardened memory allocator works"):
+          runMallocTestProg("double_free_large", "invalid free")
+          runMallocTestProg("unaligned_free_small", "invalid unaligned free")
+          runMallocTestProg("write_after_free_small", "detected write after free")
     '';
 })
diff --git a/nixos/tests/hocker-fetchdocker/default.nix b/nixos/tests/hocker-fetchdocker/default.nix
index 4f30f01e403..978dbf310b1 100644
--- a/nixos/tests/hocker-fetchdocker/default.nix
+++ b/nixos/tests/hocker-fetchdocker/default.nix
@@ -1,15 +1,16 @@
-import ../make-test.nix ({ pkgs, ...} : {
+import ../make-test-python.nix ({ pkgs, ...} : {
   name = "test-hocker-fetchdocker";
   meta = with pkgs.stdenv.lib.maintainers; {
     maintainers = [ ixmatus ];
+    broken = true; # tries to download from registry-1.docker.io - how did this ever work?
   };
 
   machine = import ./machine.nix;
 
   testScript = ''
-    startAll;
+    start_all()
 
-    $machine->waitForUnit("sockets.target");
-    $machine->waitUntilSucceeds("docker run registry-1.docker.io/v2/library/hello-world:latest");
+    machine.wait_for_unit("sockets.target")
+    machine.wait_until_succeeds("docker run registry-1.docker.io/v2/library/hello-world:latest")
   '';
 })
diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix
index 02b839fee3f..50c6af485da 100644
--- a/nixos/tests/installer.nix
+++ b/nixos/tests/installer.nix
@@ -799,7 +799,7 @@ in {
           "btrfs subvol create /mnt/badpath/boot",
           "btrfs subvol create /mnt/nixos",
           "btrfs subvol set-default "
-          + "$(btrfs subvol list /mnt | grep 'nixos' | awk '{print \$2}') /mnt",
+          + "$(btrfs subvol list /mnt | grep 'nixos' | awk '{print $2}') /mnt",
           "umount /mnt",
           "mount -o defaults LABEL=root /mnt",
           "mkdir -p /mnt/badpath/boot",  # Help ensure the detection mechanism
diff --git a/nixos/tests/openstack-image.nix b/nixos/tests/openstack-image.nix
index 97c9137fe1d..0b57dfb8e7e 100644
--- a/nixos/tests/openstack-image.nix
+++ b/nixos/tests/openstack-image.nix
@@ -3,30 +3,30 @@
   pkgs ? import ../.. { inherit system config; }
 }:
 
-with import ../lib/testing.nix { inherit system pkgs; };
+with import ../lib/testing-python.nix { inherit system pkgs; };
 with pkgs.lib;
 
 with import common/ec2.nix { inherit makeTest pkgs; };
 
 let
-  image =
-    (import ../lib/eval-config.nix {
-      inherit system;
-      modules = [
-        ../maintainers/scripts/openstack/openstack-image.nix
-        ../modules/testing/test-instrumentation.nix
-        ../modules/profiles/qemu-guest.nix
-        {
-          # Needed by nixos-rebuild due to lack of network access.
-          system.extraDependencies = with pkgs; [
-            stdenv
-          ];
-        }
-      ];
-    }).config.system.build.openstackImage + "/nixos.qcow2";
+  image = (import ../lib/eval-config.nix {
+    inherit system;
+    modules = [
+      ../maintainers/scripts/openstack/openstack-image.nix
+      ../modules/testing/test-instrumentation.nix
+      ../modules/profiles/qemu-guest.nix
+      {
+        # Needed by nixos-rebuild due to lack of network access.
+        system.extraDependencies = with pkgs; [
+          stdenv
+        ];
+      }
+    ];
+  }).config.system.build.openstackImage + "/nixos.qcow2";
 
   sshKeys = import ./ssh-keys.nix pkgs;
   snakeOilPrivateKey = sshKeys.snakeOilPrivateKey.text;
+  snakeOilPrivateKeyFile = pkgs.writeText "private-key" snakeOilPrivateKey;
   snakeOilPublicKey = sshKeys.snakeOilPublicKey;
 
 in {
@@ -39,32 +39,36 @@ in {
       SSH_HOST_ED25519_KEY:${replaceStrings ["\n"] ["|"] snakeOilPrivateKey}
     '';
     script = ''
-      $machine->start;
-      $machine->waitForFile("/etc/ec2-metadata/user-data");
-      $machine->waitForUnit("sshd.service");
+      machine.start()
+      machine.wait_for_file("/etc/ec2-metadata/user-data")
+      machine.wait_for_unit("sshd.service")
 
-      $machine->succeed("grep unknown /etc/ec2-metadata/ami-manifest-path");
+      machine.succeed("grep unknown /etc/ec2-metadata/ami-manifest-path")
 
       # We have no keys configured on the client side yet, so this should fail
-      $machine->fail("ssh -o BatchMode=yes localhost exit");
+      machine.fail("ssh -o BatchMode=yes localhost exit")
 
       # Let's install our client private key
-      $machine->succeed("mkdir -p ~/.ssh");
+      machine.succeed("mkdir -p ~/.ssh")
 
-      $machine->succeed("echo '${snakeOilPrivateKey}' > ~/.ssh/id_ed25519");
-      $machine->succeed("chmod 600 ~/.ssh/id_ed25519");
+      machine.copy_from_host_via_shell(
+          "${snakeOilPrivateKeyFile}", "~/.ssh/id_ed25519"
+      )
+      machine.succeed("chmod 600 ~/.ssh/id_ed25519")
 
       # We haven't configured the host key yet, so this should still fail
-      $machine->fail("ssh -o BatchMode=yes localhost exit");
+      machine.fail("ssh -o BatchMode=yes localhost exit")
 
       # Add the host key; ssh should finally succeed
-      $machine->succeed("echo localhost,127.0.0.1 ${snakeOilPublicKey} > ~/.ssh/known_hosts");
-      $machine->succeed("ssh -o BatchMode=yes localhost exit");
+      machine.succeed(
+          "echo localhost,127.0.0.1 ${snakeOilPublicKey} > ~/.ssh/known_hosts"
+      )
+      machine.succeed("ssh -o BatchMode=yes localhost exit")
 
       # Just to make sure resizing is idempotent.
-      $machine->shutdown;
-      $machine->start;
-      $machine->waitForFile("/etc/ec2-metadata/user-data");
+      machine.shutdown()
+      machine.start()
+      machine.wait_for_file("/etc/ec2-metadata/user-data")
     '';
   };
 
@@ -86,9 +90,9 @@ in {
       }
     '';
     script = ''
-      $machine->start;
-      $machine->waitForFile("/etc/testFile");
-      $machine->succeed("cat /etc/testFile | grep -q 'whoa'");
+      machine.start()
+      machine.wait_for_file("/etc/testFile")
+      assert "whoa" in machine.succeed("cat /etc/testFile")
     '';
   };
 }