mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-12-01 18:16:14 +02:00
Convert VM tests to Python
Perl-based tests are deprecated since NixOS 20.03 and subsequently got removed in NixOS 20.09, which effectively means that tests are going to fail as soon as we build it with NixOS 20.09 or anything newer. I've put "# fmt: off" at the start of every testScript, because formatting with Black really messes up indentation and I don't think it really adds anything in value or readability for inlined Python scripts. Signed-off-by: aszlig <aszlig@nix.build>
This commit is contained in:
parent
2a37c35650
commit
5cfdf16dd6
4 changed files with 178 additions and 155 deletions
|
@ -1,6 +1,6 @@
|
||||||
{ nixpkgs, system, overlay }:
|
{ nixpkgs, system, overlay }:
|
||||||
|
|
||||||
with import (nixpkgs + "/nixos/lib/testing.nix") {
|
with import (nixpkgs + "/nixos/lib/testing-python.nix") {
|
||||||
inherit system;
|
inherit system;
|
||||||
extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
|
extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
|
||||||
};
|
};
|
||||||
|
@ -113,36 +113,37 @@ makeTest (
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = { nodes }:
|
testScript = { nodes }: ''
|
||||||
''
|
# fmt: off
|
||||||
use POSIX qw(strftime);
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
startAll;
|
start_all()
|
||||||
|
|
||||||
$github->waitForUnit("httpd.service");
|
github.wait_for_unit("httpd.service")
|
||||||
|
|
||||||
$client->succeed("curl -v https://github.com/ >&2");
|
client.succeed("curl -v https://github.com/ >&2")
|
||||||
|
client.succeed("nix registry list | grep nixpkgs")
|
||||||
|
|
||||||
$client->succeed("nix registry list | grep nixpkgs");
|
rev = client.succeed("nix flake info nixpkgs --json | jq -r .revision")
|
||||||
|
assert rev.strip() == "${nixpkgs.rev}", "revision mismatch"
|
||||||
|
|
||||||
$client->succeed("nix flake info nixpkgs --json | jq -r .revision") eq "${nixpkgs.rev}\n"
|
client.succeed("nix registry pin nixpkgs")
|
||||||
or die "revision mismatch";
|
|
||||||
|
|
||||||
$client->succeed("nix registry pin nixpkgs");
|
client.succeed("nix flake info nixpkgs --tarball-ttl 0 >&2")
|
||||||
|
|
||||||
$client->succeed("nix flake info nixpkgs --tarball-ttl 0 >&2");
|
|
||||||
|
|
||||||
# Shut down the web server. The flake should be cached on the client.
|
# Shut down the web server. The flake should be cached on the client.
|
||||||
$github->succeed("systemctl stop httpd.service");
|
github.succeed("systemctl stop httpd.service")
|
||||||
|
|
||||||
my $date = $client->succeed("nix flake info nixpkgs --json | jq -M .lastModified");
|
info = json.loads(client.succeed("nix flake info nixpkgs --json"))
|
||||||
strftime("%Y%m%d%H%M%S", gmtime($date)) eq "${nixpkgs.lastModifiedDate}" or die "time mismatch";
|
date = time.strftime("%Y%m%d%H%M%S", time.gmtime(info['lastModified']))
|
||||||
|
assert date == "${nixpkgs.lastModifiedDate}", "time mismatch"
|
||||||
|
|
||||||
$client->succeed("nix build nixpkgs#hello");
|
client.succeed("nix build nixpkgs#hello")
|
||||||
|
|
||||||
# The build shouldn't fail even with --tarball-ttl 0 (the server
|
# The build shouldn't fail even with --tarball-ttl 0 (the server
|
||||||
# being down should not be a fatal error).
|
# being down should not be a fatal error).
|
||||||
$client->succeed("nix build nixpkgs#fuse --tarball-ttl 0");
|
client.succeed("nix build nixpkgs#fuse --tarball-ttl 0")
|
||||||
'';
|
'';
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
{ nixpkgs, system, overlay }:
|
{ nixpkgs, system, overlay }:
|
||||||
|
|
||||||
with import (nixpkgs + "/nixos/lib/testing.nix") {
|
with import (nixpkgs + "/nixos/lib/testing-python.nix") {
|
||||||
inherit system;
|
inherit system;
|
||||||
extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
|
extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
|
||||||
};
|
};
|
||||||
|
@ -25,41 +25,46 @@ makeTest (let pkgA = pkgs.cowsay; pkgB = pkgs.wget; pkgC = pkgs.hello; in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = { nodes }:
|
testScript = { nodes }: ''
|
||||||
''
|
# fmt: off
|
||||||
startAll;
|
import subprocess
|
||||||
|
|
||||||
|
start_all()
|
||||||
|
|
||||||
# Create an SSH key on the client.
|
# Create an SSH key on the client.
|
||||||
my $key = `${pkgs.openssh}/bin/ssh-keygen -t ed25519 -f key -N ""`;
|
subprocess.run([
|
||||||
$client->succeed("mkdir -m 700 /root/.ssh");
|
"${pkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", ""
|
||||||
$client->copyFileFromHost("key", "/root/.ssh/id_ed25519");
|
], capture_output=True, check=True)
|
||||||
$client->succeed("chmod 600 /root/.ssh/id_ed25519");
|
|
||||||
|
client.succeed("mkdir -m 700 /root/.ssh")
|
||||||
|
client.copy_from_host("key", "/root/.ssh/id_ed25519")
|
||||||
|
client.succeed("chmod 600 /root/.ssh/id_ed25519")
|
||||||
|
|
||||||
# Install the SSH key on the server.
|
# Install the SSH key on the server.
|
||||||
$server->succeed("mkdir -m 700 /root/.ssh");
|
server.succeed("mkdir -m 700 /root/.ssh")
|
||||||
$server->copyFileFromHost("key.pub", "/root/.ssh/authorized_keys");
|
server.copy_from_host("key.pub", "/root/.ssh/authorized_keys")
|
||||||
$server->waitForUnit("sshd");
|
server.wait_for_unit("sshd")
|
||||||
$client->waitForUnit("network.target");
|
client.wait_for_unit("network.target")
|
||||||
$client->succeed("ssh -o StrictHostKeyChecking=no " . $server->name() . " 'echo hello world'");
|
client.succeed(f"ssh -o StrictHostKeyChecking=no {server.name} 'echo hello world'")
|
||||||
|
|
||||||
# Copy the closure of package A from the client to the server.
|
# Copy the closure of package A from the client to the server.
|
||||||
$server->fail("nix-store --check-validity ${pkgA}");
|
server.fail("nix-store --check-validity ${pkgA}")
|
||||||
$client->succeed("nix-copy-closure --to server --gzip ${pkgA} >&2");
|
client.succeed("nix-copy-closure --to server --gzip ${pkgA} >&2")
|
||||||
$server->succeed("nix-store --check-validity ${pkgA}");
|
server.succeed("nix-store --check-validity ${pkgA}")
|
||||||
|
|
||||||
# Copy the closure of package B from the server to the client.
|
# Copy the closure of package B from the server to the client.
|
||||||
$client->fail("nix-store --check-validity ${pkgB}");
|
client.fail("nix-store --check-validity ${pkgB}")
|
||||||
$client->succeed("nix-copy-closure --from server --gzip ${pkgB} >&2");
|
client.succeed("nix-copy-closure --from server --gzip ${pkgB} >&2")
|
||||||
$client->succeed("nix-store --check-validity ${pkgB}");
|
client.succeed("nix-store --check-validity ${pkgB}")
|
||||||
|
|
||||||
# Copy the closure of package C via the SSH substituter.
|
# Copy the closure of package C via the SSH substituter.
|
||||||
$client->fail("nix-store -r ${pkgC}");
|
client.fail("nix-store -r ${pkgC}")
|
||||||
# FIXME
|
# FIXME
|
||||||
#$client->succeed(
|
# client.succeed(
|
||||||
# "nix-store --option use-ssh-substituter true"
|
# "nix-store --option use-ssh-substituter true"
|
||||||
# . " --option ssh-substituter-hosts root\@server"
|
# " --option ssh-substituter-hosts root\@server"
|
||||||
# . " -r ${pkgC} >&2");
|
# " -r ${pkgC} >&2"
|
||||||
#$client->succeed("nix-store --check-validity ${pkgC}");
|
# )
|
||||||
|
# client.succeed("nix-store --check-validity ${pkgC}")
|
||||||
'';
|
'';
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
{ nixpkgs, system, overlay }:
|
{ nixpkgs, system, overlay }:
|
||||||
|
|
||||||
with import (nixpkgs + "/nixos/lib/testing.nix") {
|
with import (nixpkgs + "/nixos/lib/testing-python.nix") {
|
||||||
inherit system;
|
inherit system;
|
||||||
extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
|
extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
|
||||||
};
|
};
|
||||||
|
@ -66,44 +66,46 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = { nodes }:
|
testScript = { nodes }: ''
|
||||||
''
|
# fmt: off
|
||||||
startAll;
|
import subprocess
|
||||||
|
|
||||||
|
start_all()
|
||||||
|
|
||||||
# Create an SSH key on the client.
|
# Create an SSH key on the client.
|
||||||
my $key = `${pkgs.openssh}/bin/ssh-keygen -t ed25519 -f key -N ""`;
|
subprocess.run([
|
||||||
$client->succeed("mkdir -p -m 700 /root/.ssh");
|
"${pkgs.openssh}/bin/ssh-keygen", "-t", "ed25519", "-f", "key", "-N", ""
|
||||||
$client->copyFileFromHost("key", "/root/.ssh/id_ed25519");
|
], capture_output=True, check=True)
|
||||||
$client->succeed("chmod 600 /root/.ssh/id_ed25519");
|
client.succeed("mkdir -p -m 700 /root/.ssh")
|
||||||
|
client.copy_from_host("key", "/root/.ssh/id_ed25519")
|
||||||
|
client.succeed("chmod 600 /root/.ssh/id_ed25519")
|
||||||
|
|
||||||
# Install the SSH key on the builders.
|
# Install the SSH key on the builders.
|
||||||
$client->waitForUnit("network.target");
|
client.wait_for_unit("network.target")
|
||||||
foreach my $builder ($builder1, $builder2) {
|
for builder in [builder1, builder2]:
|
||||||
$builder->succeed("mkdir -p -m 700 /root/.ssh");
|
builder.succeed("mkdir -p -m 700 /root/.ssh")
|
||||||
$builder->copyFileFromHost("key.pub", "/root/.ssh/authorized_keys");
|
builder.copy_from_host("key.pub", "/root/.ssh/authorized_keys")
|
||||||
$builder->waitForUnit("sshd");
|
builder.wait_for_unit("sshd")
|
||||||
$client->succeed("ssh -o StrictHostKeyChecking=no " . $builder->name() . " 'echo hello world'");
|
client.succeed(f"ssh -o StrictHostKeyChecking=no {builder.name} 'echo hello world'")
|
||||||
}
|
|
||||||
|
|
||||||
# Perform a build and check that it was performed on the builder.
|
# Perform a build and check that it was performed on the builder.
|
||||||
my $out = $client->succeed(
|
out = client.succeed(
|
||||||
"nix-build ${expr nodes.client.config 1} 2> build-output",
|
"nix-build ${expr nodes.client.config 1} 2> build-output",
|
||||||
"grep -q Hello build-output"
|
"grep -q Hello build-output"
|
||||||
);
|
)
|
||||||
$builder1->succeed("test -e $out");
|
builder1.succeed(f"test -e {out}")
|
||||||
|
|
||||||
# And a parallel build.
|
# And a parallel build.
|
||||||
my ($out1, $out2) = split /\s/,
|
paths = client.succeed(r'nix-store -r $(nix-instantiate ${expr nodes.client.config 2})\!out $(nix-instantiate ${expr nodes.client.config 3})\!out')
|
||||||
$client->succeed('nix-store -r $(nix-instantiate ${expr nodes.client.config 2})\!out $(nix-instantiate ${expr nodes.client.config 3})\!out');
|
out1, out2 = paths.split()
|
||||||
$builder1->succeed("test -e $out1 -o -e $out2");
|
builder1.succeed(f"test -e {out1} -o -e {out2}")
|
||||||
$builder2->succeed("test -e $out1 -o -e $out2");
|
builder2.succeed(f"test -e {out1} -o -e {out2}")
|
||||||
|
|
||||||
# And a failing build.
|
# And a failing build.
|
||||||
$client->fail("nix-build ${expr nodes.client.config 5}");
|
client.fail("nix-build ${expr nodes.client.config 5}")
|
||||||
|
|
||||||
# Test whether the build hook automatically skips unavailable builders.
|
# Test whether the build hook automatically skips unavailable builders.
|
||||||
$builder1->block;
|
builder1.block()
|
||||||
$client->succeed("nix-build ${expr nodes.client.config 4}");
|
client.succeed("nix-build ${expr nodes.client.config 4}")
|
||||||
'';
|
'';
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
{ nixpkgs, system, overlay }:
|
{ nixpkgs, system, overlay }:
|
||||||
|
|
||||||
with import (nixpkgs + "/nixos/lib/testing.nix") {
|
with import (nixpkgs + "/nixos/lib/testing-python.nix") {
|
||||||
inherit system;
|
inherit system;
|
||||||
extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
|
extraConfigurations = [ { nixpkgs.overlays = [ overlay ]; } ];
|
||||||
};
|
};
|
||||||
|
@ -17,94 +17,109 @@ makeTest {
|
||||||
virtualisation.pathsInNixDB = [ pkgs.stdenv pkgs.pkgsi686Linux.stdenv ];
|
virtualisation.pathsInNixDB = [ pkgs.stdenv pkgs.pkgsi686Linux.stdenv ];
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = { nodes }:
|
testScript = { nodes }: ''
|
||||||
''
|
# fmt: off
|
||||||
startAll;
|
start_all()
|
||||||
|
|
||||||
# Copying to /tmp should succeed.
|
# Copying to /tmp should succeed.
|
||||||
$machine->succeed('nix-build --no-sandbox -E \'(with import <nixpkgs> {}; runCommand "foo" {} "
|
machine.succeed(r"""
|
||||||
|
nix-build --no-sandbox -E '(with import <nixpkgs> {}; runCommand "foo" {} "
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp ${pkgs.coreutils}/bin/id /tmp/id
|
cp ${pkgs.coreutils}/bin/id /tmp/id
|
||||||
")\' ');
|
")'
|
||||||
|
""".strip())
|
||||||
|
|
||||||
$machine->succeed('[[ $(stat -c %a /tmp/id) = 555 ]]');
|
machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]')
|
||||||
|
|
||||||
$machine->succeed("rm /tmp/id");
|
machine.succeed("rm /tmp/id")
|
||||||
|
|
||||||
# Creating a setuid binary should fail.
|
# Creating a setuid binary should fail.
|
||||||
$machine->fail('nix-build --no-sandbox -E \'(with import <nixpkgs> {}; runCommand "foo" {} "
|
machine.fail(r"""
|
||||||
|
nix-build --no-sandbox -E '(with import <nixpkgs> {}; runCommand "foo" {} "
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp ${pkgs.coreutils}/bin/id /tmp/id
|
cp ${pkgs.coreutils}/bin/id /tmp/id
|
||||||
chmod 4755 /tmp/id
|
chmod 4755 /tmp/id
|
||||||
")\' ');
|
")'
|
||||||
|
""".strip())
|
||||||
|
|
||||||
$machine->succeed('[[ $(stat -c %a /tmp/id) = 555 ]]');
|
machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]')
|
||||||
|
|
||||||
$machine->succeed("rm /tmp/id");
|
machine.succeed("rm /tmp/id")
|
||||||
|
|
||||||
# Creating a setgid binary should fail.
|
# Creating a setgid binary should fail.
|
||||||
$machine->fail('nix-build --no-sandbox -E \'(with import <nixpkgs> {}; runCommand "foo" {} "
|
machine.fail(r"""
|
||||||
|
nix-build --no-sandbox -E '(with import <nixpkgs> {}; runCommand "foo" {} "
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp ${pkgs.coreutils}/bin/id /tmp/id
|
cp ${pkgs.coreutils}/bin/id /tmp/id
|
||||||
chmod 2755 /tmp/id
|
chmod 2755 /tmp/id
|
||||||
")\' ');
|
")'
|
||||||
|
""".strip())
|
||||||
|
|
||||||
$machine->succeed('[[ $(stat -c %a /tmp/id) = 555 ]]');
|
machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]')
|
||||||
|
|
||||||
$machine->succeed("rm /tmp/id");
|
machine.succeed("rm /tmp/id")
|
||||||
|
|
||||||
# The checks should also work on 32-bit binaries.
|
# The checks should also work on 32-bit binaries.
|
||||||
$machine->fail('nix-build --no-sandbox -E \'(with import <nixpkgs> { system = "i686-linux"; }; runCommand "foo" {} "
|
machine.fail(r"""
|
||||||
|
nix-build --no-sandbox -E '(with import <nixpkgs> { system = "i686-linux"; }; runCommand "foo" {} "
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp ${pkgs.coreutils}/bin/id /tmp/id
|
cp ${pkgs.coreutils}/bin/id /tmp/id
|
||||||
chmod 2755 /tmp/id
|
chmod 2755 /tmp/id
|
||||||
")\' ');
|
")'
|
||||||
|
""".strip())
|
||||||
|
|
||||||
$machine->succeed('[[ $(stat -c %a /tmp/id) = 555 ]]');
|
machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]')
|
||||||
|
|
||||||
$machine->succeed("rm /tmp/id");
|
machine.succeed("rm /tmp/id")
|
||||||
|
|
||||||
# The tests above use fchmodat(). Test chmod() as well.
|
# The tests above use fchmodat(). Test chmod() as well.
|
||||||
$machine->succeed('nix-build --no-sandbox -E \'(with import <nixpkgs> {}; runCommand "foo" { buildInputs = [ perl ]; } "
|
machine.succeed(r"""
|
||||||
|
nix-build --no-sandbox -E '(with import <nixpkgs> {}; runCommand "foo" { buildInputs = [ perl ]; } "
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp ${pkgs.coreutils}/bin/id /tmp/id
|
cp ${pkgs.coreutils}/bin/id /tmp/id
|
||||||
perl -e \"chmod 0666, qw(/tmp/id) or die\"
|
perl -e \"chmod 0666, qw(/tmp/id) or die\"
|
||||||
")\' ');
|
")'
|
||||||
|
""".strip())
|
||||||
|
|
||||||
$machine->succeed('[[ $(stat -c %a /tmp/id) = 666 ]]');
|
machine.succeed('[[ $(stat -c %a /tmp/id) = 666 ]]')
|
||||||
|
|
||||||
$machine->succeed("rm /tmp/id");
|
machine.succeed("rm /tmp/id")
|
||||||
|
|
||||||
$machine->fail('nix-build --no-sandbox -E \'(with import <nixpkgs> {}; runCommand "foo" { buildInputs = [ perl ]; } "
|
machine.fail(r"""
|
||||||
|
nix-build --no-sandbox -E '(with import <nixpkgs> {}; runCommand "foo" { buildInputs = [ perl ]; } "
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp ${pkgs.coreutils}/bin/id /tmp/id
|
cp ${pkgs.coreutils}/bin/id /tmp/id
|
||||||
perl -e \"chmod 04755, qw(/tmp/id) or die\"
|
perl -e \"chmod 04755, qw(/tmp/id) or die\"
|
||||||
")\' ');
|
")'
|
||||||
|
""".strip())
|
||||||
|
|
||||||
$machine->succeed('[[ $(stat -c %a /tmp/id) = 555 ]]');
|
machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]')
|
||||||
|
|
||||||
$machine->succeed("rm /tmp/id");
|
machine.succeed("rm /tmp/id")
|
||||||
|
|
||||||
# And test fchmod().
|
# And test fchmod().
|
||||||
$machine->succeed('nix-build --no-sandbox -E \'(with import <nixpkgs> {}; runCommand "foo" { buildInputs = [ perl ]; } "
|
machine.succeed(r"""
|
||||||
|
nix-build --no-sandbox -E '(with import <nixpkgs> {}; runCommand "foo" { buildInputs = [ perl ]; } "
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp ${pkgs.coreutils}/bin/id /tmp/id
|
cp ${pkgs.coreutils}/bin/id /tmp/id
|
||||||
perl -e \"my \\\$x; open \\\$x, qw(/tmp/id); chmod 01750, \\\$x or die\"
|
perl -e \"my \\\$x; open \\\$x, qw(/tmp/id); chmod 01750, \\\$x or die\"
|
||||||
")\' ');
|
")'
|
||||||
|
""".strip())
|
||||||
|
|
||||||
$machine->succeed('[[ $(stat -c %a /tmp/id) = 1750 ]]');
|
machine.succeed('[[ $(stat -c %a /tmp/id) = 1750 ]]')
|
||||||
|
|
||||||
$machine->succeed("rm /tmp/id");
|
machine.succeed("rm /tmp/id")
|
||||||
|
|
||||||
$machine->fail('nix-build --no-sandbox -E \'(with import <nixpkgs> {}; runCommand "foo" { buildInputs = [ perl ]; } "
|
machine.fail(r"""
|
||||||
|
nix-build --no-sandbox -E '(with import <nixpkgs> {}; runCommand "foo" { buildInputs = [ perl ]; } "
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp ${pkgs.coreutils}/bin/id /tmp/id
|
cp ${pkgs.coreutils}/bin/id /tmp/id
|
||||||
perl -e \"my \\\$x; open \\\$x, qw(/tmp/id); chmod 04777, \\\$x or die\"
|
perl -e \"my \\\$x; open \\\$x, qw(/tmp/id); chmod 04777, \\\$x or die\"
|
||||||
")\' ');
|
")'
|
||||||
|
""".strip())
|
||||||
|
|
||||||
$machine->succeed('[[ $(stat -c %a /tmp/id) = 555 ]]');
|
machine.succeed('[[ $(stat -c %a /tmp/id) = 555 ]]')
|
||||||
|
|
||||||
$machine->succeed("rm /tmp/id");
|
machine.succeed("rm /tmp/id")
|
||||||
'';
|
'';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue