1{
2 config,
3 lib,
4 testName,
5 enableAutologin,
6 enableXWayland,
7 ...
8}:
9
10{
11 name = testName;
12
13 meta = {
14 platforms = lib.platforms.linux;
15 maintainers = lib.teams.cosmic.members;
16 };
17
18 nodes.machine = {
19 imports = [ ./common/user-account.nix ];
20
21 services = {
22 # For `cosmic-store` to be added to `environment.systemPackages`
23 # and for it to work correctly because Flatpak is a runtime
24 # dependency of `cosmic-store`.
25 flatpak.enable = true;
26
27 displayManager.cosmic-greeter.enable = true;
28 desktopManager.cosmic = {
29 enable = true;
30 xwayland.enable = enableXWayland;
31 };
32 };
33
34 services.displayManager.autoLogin = lib.mkIf enableAutologin {
35 enable = true;
36 user = "alice";
37 };
38
39 environment.systemPackages = with config.node.pkgs; [
40 # These two packages are used to check if a window was opened
41 # under the COSMIC session or not. Kinda important.
42 # TODO: Move the check from the test module to
43 # `nixos/lib/test-driver/src/test_driver/machine.py` so more
44 # Wayland-only testing can be done using the existing testing
45 # infrastructure.
46 jq
47 lswt
48 ];
49
50 # So far, all COSMIC tests launch a few GUI applications. In doing
51 # so, the default allocated memory to the guest of 1024M quickly
52 # poses a very high risk of an OOM-shutdown which is worse than an
53 # OOM-kill. Because now, the test failed, but not for a genuine
54 # reason, but an OOM-shutdown. That's an inconclusive failure
55 # which might possibly mask an actual failure. Not enabling
56 # systemd-oomd because we need said applications running for a
57 # few seconds. So instead, bump the allocated memory to the guest
58 # from 1024M to 4x; 4096M.
59 virtualisation.memorySize = 4096;
60 };
61
62 testScript =
63 { nodes, ... }:
64 let
65 cfg = nodes.machine;
66 user = cfg.users.users.alice;
67 DISPLAY = lib.strings.optionalString enableXWayland (
68 if enableAutologin then "DISPLAY=:0" else "DISPLAY=:1"
69 );
70 in
71 ''
72 #testName: ${testName}
73 ''
74 + (
75 if (enableAutologin) then
76 ''
77 with subtest("cosmic-greeter initialisation"):
78 machine.wait_for_unit("graphical.target", timeout=120)
79 ''
80 else
81 ''
82 from time import sleep
83
84 machine.wait_for_unit("graphical.target", timeout=120)
85 machine.wait_until_succeeds("pgrep --uid ${toString cfg.users.users.cosmic-greeter.name} --full cosmic-greeter", timeout=30)
86 # Sleep for 10 seconds for ensuring that `greetd` loads the
87 # password prompt for the login screen properly.
88 sleep(10)
89
90 with subtest("cosmic-session login"):
91 machine.send_chars("${user.password}\n", delay=0.2)
92 ''
93 )
94 + ''
95 # _One_ of the final processes to start as part of the
96 # `cosmic-session` target is the Workspaces applet. So, wait
97 # for it to start. The process existing means that COSMIC
98 # now handles any opened windows from now on.
99 machine.wait_until_succeeds("pgrep --uid ${toString user.uid} --full 'cosmic-panel-button com.system76.CosmicWorkspaces'", timeout=30)
100
101 # The best way to test for Wayland and XWayland is to launch
102 # the GUI applications and see the results yourself.
103 with subtest("Launch applications"):
104 # key: binary_name
105 # value: "app-id" as reported by `lswt`
106 gui_apps_to_launch = {}
107
108 # We want to ensure that the first-party applications
109 # start/launch properly.
110 gui_apps_to_launch['cosmic-edit'] = 'com.system76.CosmicEdit'
111 gui_apps_to_launch['cosmic-files'] = 'com.system76.CosmicFiles'
112 gui_apps_to_launch['cosmic-player'] = 'com.system76.CosmicPlayer'
113 gui_apps_to_launch['cosmic-settings'] = 'com.system76.CosmicSettings'
114 gui_apps_to_launch['cosmic-store'] = 'com.system76.CosmicStore'
115 gui_apps_to_launch['cosmic-term'] = 'com.system76.CosmicTerm'
116
117 for gui_app, app_id in gui_apps_to_launch.items():
118 machine.succeed(f"su - ${user.name} -c 'WAYLAND_DISPLAY=wayland-1 XDG_RUNTIME_DIR=/run/user/${toString user.uid} ${DISPLAY} {gui_app} >&2 &'", timeout=5)
119 # Nix builds the following non-commented expression to the following:
120 # `su - alice -c 'WAYLAND_DISPLAY=wayland-1 XDG_RUNTIME_DIR=/run/user/1000 lswt --json | jq ".toplevels" | grep "^ \\"app-id\\": \\"{app_id}\\"$"' `
121 machine.wait_until_succeeds(f''''su - ${user.name} -c 'WAYLAND_DISPLAY=wayland-1 XDG_RUNTIME_DIR=/run/user/${toString user.uid} lswt --json | jq ".toplevels" | grep "^ \\"app-id\\": \\"{app_id}\\"$"' '''', timeout=30)
122 machine.succeed(f"pkill {gui_app}", timeout=5)
123
124 machine.succeed("echo 'test completed succeessfully' > /${testName}", timeout=5)
125 machine.copy_from_vm('/${testName}')
126
127 machine.shutdown()
128 '';
129}