about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2021-11-20 12:01:21 +0000
committerGitHub <noreply@github.com>2021-11-20 12:01:21 +0000
commit2d03d542c7c0ffbf359b9cb199bdcb9bc038f099 (patch)
tree7e1ca8a76a52b55ca3fd6b886e2ad05ad7a08598 /nixos
parent0373476c4a69cf435677709fbb94328bd7885e57 (diff)
parentc247bf87da0e2262339fe6d5c79b15cd77d76b7a (diff)
Merge master into staging-next
Diffstat (limited to 'nixos')
-rwxr-xr-xnixos/lib/test-driver/test-driver.py72
-rw-r--r--nixos/lib/testing-python.nix4
-rw-r--r--nixos/tests/all-tests.nix2
-rw-r--r--nixos/tests/common/wayland-cage.nix14
-rw-r--r--nixos/tests/vscodium.nix92
5 files changed, 112 insertions, 72 deletions
diff --git a/nixos/lib/test-driver/test-driver.py b/nixos/lib/test-driver/test-driver.py
index a7c0484060f2f..643446f313e3a 100755
--- a/nixos/lib/test-driver/test-driver.py
+++ b/nixos/lib/test-driver/test-driver.py
@@ -4,6 +4,7 @@ from queue import Queue, Empty
 from typing import Tuple, Any, Callable, Dict, Iterator, Optional, List, Iterable
 from xml.sax.saxutils import XMLGenerator
 from colorama import Style
+from pathlib import Path
 import queue
 import io
 import threading
@@ -11,7 +12,6 @@ import argparse
 import base64
 import codecs
 import os
-import pathlib
 import ptpython.repl
 import pty
 import re
@@ -239,8 +239,8 @@ class StartCommand:
 
     def cmd(
         self,
-        monitor_socket_path: pathlib.Path,
-        shell_socket_path: pathlib.Path,
+        monitor_socket_path: Path,
+        shell_socket_path: Path,
         allow_reboot: bool = False,  # TODO: unused, legacy?
     ) -> str:
         display_opts = ""
@@ -272,8 +272,8 @@ class StartCommand:
 
     @staticmethod
     def build_environment(
-        state_dir: pathlib.Path,
-        shared_dir: pathlib.Path,
+        state_dir: Path,
+        shared_dir: Path,
     ) -> dict:
         # We make a copy to not update the current environment
         env = dict(os.environ)
@@ -288,10 +288,10 @@ class StartCommand:
 
     def run(
         self,
-        state_dir: pathlib.Path,
-        shared_dir: pathlib.Path,
-        monitor_socket_path: pathlib.Path,
-        shell_socket_path: pathlib.Path,
+        state_dir: Path,
+        shared_dir: Path,
+        monitor_socket_path: Path,
+        shell_socket_path: Path,
     ) -> subprocess.Popen:
         return subprocess.Popen(
             self.cmd(monitor_socket_path, shell_socket_path),
@@ -334,7 +334,7 @@ class LegacyStartCommand(StartCommand):
         self,
         netBackendArgs: Optional[str] = None,
         netFrontendArgs: Optional[str] = None,
-        hda: Optional[Tuple[pathlib.Path, str]] = None,
+        hda: Optional[Tuple[Path, str]] = None,
         cdrom: Optional[str] = None,
         usb: Optional[str] = None,
         bios: Optional[str] = None,
@@ -394,11 +394,11 @@ class Machine:
     the machine lifecycle with the help of a start script / command."""
 
     name: str
-    tmp_dir: pathlib.Path
-    shared_dir: pathlib.Path
-    state_dir: pathlib.Path
-    monitor_path: pathlib.Path
-    shell_path: pathlib.Path
+    tmp_dir: Path
+    shared_dir: Path
+    state_dir: Path
+    monitor_path: Path
+    shell_path: Path
 
     start_command: StartCommand
     keep_vm_state: bool
@@ -421,7 +421,7 @@ class Machine:
 
     def __init__(
         self,
-        tmp_dir: pathlib.Path,
+        tmp_dir: Path,
         start_command: StartCommand,
         name: str = "machine",
         keep_vm_state: bool = False,
@@ -463,7 +463,7 @@ class Machine:
         hda = None
         if args.get("hda"):
             hda_arg: str = args.get("hda", "")
-            hda_arg_path: pathlib.Path = pathlib.Path(hda_arg)
+            hda_arg_path: Path = Path(hda_arg)
             hda = (hda_arg_path, args.get("hdaInterface", ""))
         return LegacyStartCommand(
             netBackendArgs=args.get("netBackendArgs"),
@@ -814,12 +814,12 @@ class Machine:
         """Copy a file from the host into the guest via the `shared_dir` shared
         among all the VMs (using a temporary directory).
         """
-        host_src = pathlib.Path(source)
-        vm_target = pathlib.Path(target)
+        host_src = Path(source)
+        vm_target = Path(target)
         with tempfile.TemporaryDirectory(dir=self.shared_dir) as shared_td:
-            shared_temp = pathlib.Path(shared_td)
+            shared_temp = Path(shared_td)
             host_intermediate = shared_temp / host_src.name
-            vm_shared_temp = pathlib.Path("/tmp/shared") / shared_temp.name
+            vm_shared_temp = Path("/tmp/shared") / shared_temp.name
             vm_intermediate = vm_shared_temp / host_src.name
 
             self.succeed(make_command(["mkdir", "-p", vm_shared_temp]))
@@ -836,11 +836,11 @@ class Machine:
         all the VMs (using a temporary directory).
         """
         # Compute the source, target, and intermediate shared file names
-        out_dir = pathlib.Path(os.environ.get("out", os.getcwd()))
-        vm_src = pathlib.Path(source)
+        out_dir = Path(os.environ.get("out", os.getcwd()))
+        vm_src = Path(source)
         with tempfile.TemporaryDirectory(dir=self.shared_dir) as shared_td:
-            shared_temp = pathlib.Path(shared_td)
-            vm_shared_temp = pathlib.Path("/tmp/shared") / shared_temp.name
+            shared_temp = Path(shared_td)
+            vm_shared_temp = Path("/tmp/shared") / shared_temp.name
             vm_intermediate = vm_shared_temp / vm_src.name
             intermediate = shared_temp / vm_src.name
             # Copy the file to the shared directory inside VM
@@ -911,12 +911,12 @@ class Machine:
 
         self.log("starting vm")
 
-        def clear(path: pathlib.Path) -> pathlib.Path:
+        def clear(path: Path) -> Path:
             if path.exists():
                 path.unlink()
             return path
 
-        def create_socket(path: pathlib.Path) -> socket.socket:
+        def create_socket(path: Path) -> socket.socket:
             s = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM)
             s.bind(str(path))
             s.listen(1)
@@ -1061,7 +1061,7 @@ class VLan:
     """
 
     nr: int
-    socket_dir: pathlib.Path
+    socket_dir: Path
 
     process: subprocess.Popen
     pid: int
@@ -1070,7 +1070,7 @@ class VLan:
     def __repr__(self) -> str:
         return f"<Vlan Nr. {self.nr}>"
 
-    def __init__(self, nr: int, tmp_dir: pathlib.Path):
+    def __init__(self, nr: int, tmp_dir: Path):
         self.nr = nr
         self.socket_dir = tmp_dir / f"vde{self.nr}.ctl"
 
@@ -1123,7 +1123,7 @@ class Driver:
     ):
         self.tests = tests
 
-        tmp_dir = pathlib.Path(os.environ.get("TMPDIR", tempfile.gettempdir()))
+        tmp_dir = Path(os.environ.get("TMPDIR", tempfile.gettempdir()))
         tmp_dir.mkdir(mode=0o700, exist_ok=True)
 
         with rootlog.nested("start all VLans"):
@@ -1183,9 +1183,11 @@ class Driver:
             serial_stdout_on=self.serial_stdout_on,
             Machine=Machine,  # for typing
         )
-        machine_symbols = {
-            m.name: self.machines[idx] for idx, m in enumerate(self.machines)
-        }
+        machine_symbols = {m.name: m for m in self.machines}
+        # If there's exactly one machine, make it available under the name
+        # "machine", even if it's not called that.
+        if len(self.machines) == 1:
+            (machine_symbols["machine"],) = self.machines
         vlan_symbols = {
             f"vlan{v.nr}": self.vlans[idx] for idx, v in enumerate(self.vlans)
         }
@@ -1230,7 +1232,7 @@ class Driver:
             "Using legacy create_machine(), please instantiate the"
             "Machine class directly, instead"
         )
-        tmp_dir = pathlib.Path(os.environ.get("TMPDIR", tempfile.gettempdir()))
+        tmp_dir = Path(os.environ.get("TMPDIR", tempfile.gettempdir()))
         tmp_dir.mkdir(mode=0o700, exist_ok=True)
 
         if args.get("startCommand"):
@@ -1316,7 +1318,7 @@ if __name__ == "__main__":
         action=EnvDefault,
         envvar="testScript",
         help="the test script to run",
-        type=pathlib.Path,
+        type=Path,
     )
 
     args = arg_parser.parse_args()
diff --git a/nixos/lib/testing-python.nix b/nixos/lib/testing-python.nix
index cce017a6441db..4306d102b2d64 100644
--- a/nixos/lib/testing-python.nix
+++ b/nixos/lib/testing-python.nix
@@ -134,7 +134,9 @@ rec {
       vlans = map (m: m.config.virtualisation.vlans) (lib.attrValues nodes);
       vms = map (m: m.config.system.build.vm) (lib.attrValues nodes);
 
-      nodeHostNames = map (c: c.config.system.name) (lib.attrValues nodes);
+      nodeHostNames = let
+        nodesList = map (c: c.config.system.name) (lib.attrValues nodes);
+      in nodesList ++ lib.optional (lib.length nodesList == 1) "machine";
 
       # TODO: This is an implementation error and needs fixing
       # the testing famework cannot legitimately restrict hostnames further
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index cd13183ed0a32..b8219416dc42a 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -489,7 +489,7 @@ in
   victoriametrics = handleTest ./victoriametrics.nix {};
   vikunja = handleTest ./vikunja.nix {};
   virtualbox = handleTestOn ["x86_64-linux"] ./virtualbox.nix {};
-  vscodium = handleTest ./vscodium.nix {};
+  vscodium = discoverTests (import ./vscodium.nix);
   wasabibackend = handleTest ./wasabibackend.nix {};
   wiki-js = handleTest ./wiki-js.nix {};
   wireguard = handleTest ./wireguard {};
diff --git a/nixos/tests/common/wayland-cage.nix b/nixos/tests/common/wayland-cage.nix
new file mode 100644
index 0000000000000..55aeb858d7a42
--- /dev/null
+++ b/nixos/tests/common/wayland-cage.nix
@@ -0,0 +1,14 @@
+{ ... }:
+
+{
+  imports = [ ./user-account.nix ];
+  services.cage = {
+    enable = true;
+    user = "alice";
+  };
+
+  virtualisation = {
+    memorySize = 1024;
+    qemu.options = [ "-vga virtio" ];
+  };
+}
diff --git a/nixos/tests/vscodium.nix b/nixos/tests/vscodium.nix
index 033090aa0e3d1..43a0d61c856f5 100644
--- a/nixos/tests/vscodium.nix
+++ b/nixos/tests/vscodium.nix
@@ -1,47 +1,69 @@
-import ./make-test-python.nix ({ pkgs, ...} :
+let
+  tests = {
+    wayland = { pkgs, ... }: {
+      imports = [ ./common/wayland-cage.nix ];
 
-{
-  name = "vscodium";
-  meta = with pkgs.lib.maintainers; {
-    maintainers = [ turion ];
+      services.cage.program = ''
+        ${pkgs.vscodium}/bin/codium \
+          --enable-features=UseOzonePlatform \
+          --ozone-platform=wayland
+      '';
+
+      fonts.fonts = with pkgs; [ dejavu_fonts ];
+    };
+    xorg = { pkgs, ... }: {
+      imports = [ ./common/user-account.nix ./common/x11.nix ];
+
+      virtualisation.memorySize = 2047;
+      services.xserver.enable = true;
+      services.xserver.displayManager.sessionCommands = ''
+        ${pkgs.vscodium}/bin/codium
+      '';
+      test-support.displayManager.auto.user = "alice";
+    };
   };
 
-  machine = { ... }:
+  mkTest = name: machine:
+    import ./make-test-python.nix ({ pkgs, ... }: {
+      inherit name;
 
-  {
-    imports = [
-      ./common/user-account.nix
-      ./common/x11.nix
-    ];
+      nodes = { "${name}" = machine; };
 
-    virtualisation.memorySize = 2047;
-    services.xserver.enable = true;
-    test-support.displayManager.auto.user = "alice";
-    environment.systemPackages = with pkgs; [
-      vscodium
-    ];
-  };
+      meta = with pkgs.lib.maintainers; {
+        maintainers = [ synthetica turion ];
+      };
+      enableOCR = true;
+      testScript = ''
+        start_all()
+
+        machine.wait_for_unit('graphical.target')
+        machine.wait_until_succeeds('pgrep -x codium')
 
-  enableOCR = true;
+        # Wait until vscodium is visible. "File" is in the menu bar.
+        machine.wait_for_text('File')
+        machine.screenshot('start_screen')
 
-  testScript = { nodes, ... }: ''
-    # Start up X
-    start_all()
-    machine.wait_for_x()
+        test_string = 'testfile'
 
-    # Start VSCodium with a file that doesn't exist yet
-    machine.fail("ls /home/alice/foo.txt")
-    machine.succeed("su - alice -c 'codium foo.txt' >&2 &")
+        # Create a new file
+        machine.send_key('ctrl-n')
+        machine.wait_for_text('Untitled')
+        machine.screenshot('empty_editor')
 
-    # Wait for the window to appear
-    machine.wait_for_text("VSCodium")
+        # Type a string
+        machine.send_chars(test_string)
+        machine.wait_for_text(test_string)
+        machine.screenshot('editor')
 
-    # Save file
-    machine.send_key("ctrl-s")
+        # Save the file
+        machine.send_key('ctrl-s')
+        machine.wait_for_text('Save')
+        machine.screenshot('save_window')
+        machine.send_key('ret')
 
-    # Wait until the file has been saved
-    machine.wait_for_file("/home/alice/foo.txt")
+        # (the default filename is the first line of the file)
+        machine.wait_for_file(f'/home/alice/{test_string}')
+      '';
+    });
 
-    machine.screenshot("VSCodium")
-  '';
-})
+in builtins.mapAttrs (k: v: mkTest k v { }) tests