forked from lix-project/lix
Merge pull request #4156 from aszlig/vm-test-python
Convert VM tests to Python
This commit is contained in:
commit
05e6fe69f9
|
@ -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 ]; } ];
|
||||||
};
|
};
|
||||||
|
@ -64,6 +64,7 @@ in
|
||||||
makeTest (
|
makeTest (
|
||||||
|
|
||||||
{
|
{
|
||||||
|
name = "github-flakes";
|
||||||
|
|
||||||
nodes =
|
nodes =
|
||||||
{ # Impersonate github.com and api.github.com.
|
{ # Impersonate github.com and api.github.com.
|
||||||
|
@ -113,36 +114,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,12 +2,13 @@
|
||||||
|
|
||||||
{ 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 ]; } ];
|
||||||
};
|
};
|
||||||
|
|
||||||
makeTest (let pkgA = pkgs.cowsay; pkgB = pkgs.wget; pkgC = pkgs.hello; in {
|
makeTest (let pkgA = pkgs.cowsay; pkgB = pkgs.wget; pkgC = pkgs.hello; in {
|
||||||
|
name = "nix-copy-closure";
|
||||||
|
|
||||||
nodes =
|
nodes =
|
||||||
{ client =
|
{ client =
|
||||||
|
@ -25,41 +26,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 ]; } ];
|
||||||
};
|
};
|
||||||
|
@ -36,6 +36,7 @@ let
|
||||||
in
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
|
name = "remote-builds";
|
||||||
|
|
||||||
nodes =
|
nodes =
|
||||||
{ builder1 = builder;
|
{ builder1 = builder;
|
||||||
|
@ -66,44 +67,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,12 +2,13 @@
|
||||||
|
|
||||||
{ 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 ]; } ];
|
||||||
};
|
};
|
||||||
|
|
||||||
makeTest {
|
makeTest {
|
||||||
|
name = "setuid";
|
||||||
|
|
||||||
machine =
|
machine =
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
@ -17,94 +18,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