about summary refs log tree commit diff
path: root/tests/sandbox.nix
blob: 20ae88d6dacb2e529e635ab7e09eae3ada1b9596 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
{
  name = "sandbox";

  machine = { pkgs, lib, ... }: {
    system.activationScripts.inject-link = ''
      ln -svf ${pkgs.hello} /run/foo-test-sandbox
      ln -svf ${pkgs.gnused} /run/bar-test-sandbox
      ln -svf ${pkgs.gnugrep} /run/baz-test-sandbox
    '';
    environment.sessionVariables.COLLECT_ME = [
      "/run/foo-test-sandbox"
      "/run/bar-test-sandbox"
      "/run/baz-test-sandbox"
    ];

    # Only needed so we get the right XDG paths in the system path.
    services.xserver.enable = true;
    systemd.services.display-manager.enable = false;

    environment.systemPackages = let
      testPackage = pkgs.runCommand "test-sandbox" {
        program = ''
          #!${pkgs.stdenv.shell} -ex

          if [ "$1" != canary ]; then
            echo 'Canary check failed, so the test program probably' \
                 'was not executed via the XDG desktop entry.' >&2
            exit 1
          fi

          # Should fail because we can't access the host's PATH
          ! echo foo | grep -qF foo

          export PATH=/run/baz-test-sandbox/bin
          echo foo > /home/foo/existing/bar
          test ! -d /home/foo/nonexisting
          /run/foo-test-sandbox/bin/hello
          echo aaa | /run/bar-test-sandbox/bin/sed -e 's/a/b/g'

          echo XDG1 > /home/foo/.local/share/xdg/1
          echo XDG2 > /home/foo/.config/xdg/2
          echo XDG3 > /home/foo/.cache/xdg/3
          echo > /home/foo/.cache/xdg/done
        '';
      } ''
        mkdir -p "$out/bin" "$out/share/applications" "$out/share/test-sandbox"

        echo -n "$program" > "$out/bin/test-sandbox"
        chmod +x "$out/bin/test-sandbox"

        echo '<svg xmlns="http://www.w3.org/2000/svg"/>' \
          > "$out/share/test-sandbox/icon.svg"

        cat > "$out/share/applications/test.desktop" <<EOF
        [Desktop Entry]
        Name=$fullName
        Type=Application
        Version=1.1
        Exec=$out/bin/test-sandbox canary
        Icon=$out/share/test-sandbox/icon.svg
        Categories=Utility
        EOF
      '';

    in [
      # Unfortunately, "xdg-open test-sandbox.desktop" doesn't work, so let's
      # use gtk-launch instead. We also need xvfb_run so that we can avoid to
      # start a full-blown X server.
      #
      # See also:
      #
      #   https://askubuntu.com/questions/5172
      #   https://bugs.launchpad.net/ubuntu/+source/gvfs/+bug/378783
      #
      (lib.getBin pkgs.gtk3) pkgs.xvfb_run

      (pkgs.vuizvui.buildSandbox testPackage {
        paths.required = [
          "/home/foo/existing"
          "$XDG_DATA_HOME/xdg"
          "$XDG_CONFIG_HOME/xdg"
          "$XDG_CACHE_HOME/xdg"
        ];
        paths.wanted = [ "/home/foo/nonexisting" ];
        paths.runtimeVars = [ "COLLECT_ME" ];
      })
    ];
    users.users.foo.isNormalUser = true;
  };

  testScript = ''
    $machine->waitForUnit('multi-user.target');
    $machine->succeed('su - -c "xvfb-run gtk-launch test" foo >&2');
    $machine->waitForFile('/home/foo/.cache/xdg/done');

    $machine->succeed('test -d /home/foo/existing');
    $machine->succeed('grep -qF foo /home/foo/existing/bar');
    $machine->fail('test -d /home/foo/nonexisting');

    $machine->succeed('grep -qF XDG1 /home/foo/.local/share/xdg/1');
    $machine->succeed('grep -qF XDG2 /home/foo/.config/xdg/2');
    $machine->succeed('grep -qF XDG3 /home/foo/.cache/xdg/3');
  '';
}