nix: add graphical-gnome-test
This VM integration test spawns Gnome, monado-service, stardust-xr-server, flatland and weston-cliptest and tests that the functionality works correctly. The result is a screenshot. If any program in the test produces an exit code above 0 it will fail the test, graphical rendering bugs should be visible in the resulting screenshot
This commit is contained in:
committed by
Matthew Croughan
parent
1740d55f9c
commit
13da4c8d60
23
README.md
23
README.md
@@ -20,3 +20,26 @@ cargo build
|
|||||||
```bash
|
```bash
|
||||||
cargo install
|
cargo install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Test
|
||||||
|
|
||||||
|
##### Gnome Graphical Integration Test
|
||||||
|
|
||||||
|
- `nix build .#gnome-graphical-test`
|
||||||
|
|
||||||
|
This test uses Nix to reproducibly execute a QEMU virtual machine which
|
||||||
|
spawns a full Gnome desktop. It runs `monado-service`, `stardust-xr-server`
|
||||||
|
`flatland` underneath of Gnome and then attaches `weston-cliptest` to the
|
||||||
|
`flatland` process running underneath of `stardust-xr-server`, the result is
|
||||||
|
a screenshot in PNG format that should look like expected. If any process in
|
||||||
|
this test produces an exit code above 0, the test will fail, graphical bugs
|
||||||
|
should be visible in the screenshot. An example of the result is below.
|
||||||
|
|
||||||
|
###### Result
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
##### Everything
|
||||||
|
|
||||||
|
`nix flake check` will build every test underneath of the `checks` attribute in the `flake.nix`
|
||||||
|
|
||||||
|
|||||||
12
flake.nix
12
flake.nix
@@ -2,10 +2,14 @@
|
|||||||
# 22.11 does not include PR #218472, hence we use the unstable version
|
# 22.11 does not include PR #218472, hence we use the unstable version
|
||||||
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable;
|
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable;
|
||||||
|
|
||||||
|
# Since we do not have a monorepo, we have to fetch Flatland in order to use
|
||||||
|
# it to create VM Tests
|
||||||
|
inputs.flatland.url = "github:StardustXR/flatland";
|
||||||
|
|
||||||
inputs.fenix.url = github:nix-community/fenix;
|
inputs.fenix.url = github:nix-community/fenix;
|
||||||
inputs.fenix.inputs.nixpkgs.follows = "nixpkgs";
|
inputs.fenix.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|
||||||
outputs = { self, nixpkgs, fenix }:
|
outputs = { self, nixpkgs, fenix, ... }:
|
||||||
let
|
let
|
||||||
name = "server";
|
name = "server";
|
||||||
pkgs = system: import nixpkgs {
|
pkgs = system: import nixpkgs {
|
||||||
@@ -82,6 +86,12 @@
|
|||||||
packages."x86_64-linux".default = package (pkgs "x86_64-linux");
|
packages."x86_64-linux".default = package (pkgs "x86_64-linux");
|
||||||
packages."aarch64-linux".default = package (pkgs "aarch64-linux");
|
packages."aarch64-linux".default = package (pkgs "aarch64-linux");
|
||||||
|
|
||||||
|
packages."x86_64-linux".gnome-graphical-test = self.checks.x86_64-linux.gnome-graphical-test;
|
||||||
|
packages."aarch64-linux".gnome-graphical-test = self.checks.aarch64-linux.gnome-graphical-test;
|
||||||
|
|
||||||
|
checks."x86_64-linux".gnome-graphical-test = (pkgs "x86_64-linux").nixosTest (import ./nix/gnome-graphical-test.nix { pkgs = (pkgs "x86_64-linux"); inherit self; });
|
||||||
|
checks."aarch64-linux".gnome-graphical-test = (pkgs "aarch64-linux").nixosTest (import ./nix/gnome-graphical-test.nix { pkgs = (pkgs "aarch64-linux"); inherit self; });
|
||||||
|
|
||||||
devShells."x86_64-linux".default = shell (pkgs "x86_64-linux");
|
devShells."x86_64-linux".default = shell (pkgs "x86_64-linux");
|
||||||
devShells."aarch64-linux".default = shell (pkgs "aarch64-linux");
|
devShells."aarch64-linux".default = shell (pkgs "aarch64-linux");
|
||||||
};
|
};
|
||||||
|
|||||||
155
nix/gnome-graphical-test.nix
Normal file
155
nix/gnome-graphical-test.nix
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
{ pkgs, lib ? pkgs.lib, self, ... }:
|
||||||
|
# Some code is copy-pasted from https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/gnome.nix
|
||||||
|
# TODO: make this less boiler-platey and make a function like mkGnomeTest that does all this and upstream it to nixpkgs
|
||||||
|
{
|
||||||
|
name = "stardust-xr-server-gnome-vmtest";
|
||||||
|
meta = with lib; {
|
||||||
|
maintainers = [ maintainers.matthewcroughan ];
|
||||||
|
};
|
||||||
|
nodes.machine = { ... }: {
|
||||||
|
imports = [ "${pkgs.path}/nixos/tests/common/user-account.nix" ];
|
||||||
|
virtualisation.qemu.options = [
|
||||||
|
"-device virtio-gpu-pci"
|
||||||
|
];
|
||||||
|
environment.systemPackages = [ pkgs.monado ];
|
||||||
|
services.xserver = {
|
||||||
|
enable = true;
|
||||||
|
desktopManager.gnome = {
|
||||||
|
enable = true;
|
||||||
|
debug = true;
|
||||||
|
# Set a nice desktop background that is pleasing to the eyes :3
|
||||||
|
extraGSettingsOverrides = ''
|
||||||
|
[org.gnome.desktop.background]
|
||||||
|
picture-uri='file://${pkgs.gnome.gnome-backgrounds}/share/backgrounds/gnome/blobs-l.svg'
|
||||||
|
picture-uri-dark='file://${pkgs.gnome.gnome-backgrounds}/share/backgrounds/gnome/blobs-l.svg'
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
displayManager = {
|
||||||
|
gdm = {
|
||||||
|
enable = true;
|
||||||
|
debug = true;
|
||||||
|
};
|
||||||
|
autoLogin = {
|
||||||
|
enable = true;
|
||||||
|
user = "alice";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.user.services = {
|
||||||
|
"monado" = {
|
||||||
|
after = [ "graphical-session.target" "default.target" "org.gnome.Shell@wayland.service" ];
|
||||||
|
environment = {
|
||||||
|
XRT_COMPOSITOR_FORCE_WAYLAND = "1";
|
||||||
|
WAYLAND_DISPLAY = "wayland-0";
|
||||||
|
};
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStartPre = [
|
||||||
|
"${pkgs.writeShellScript "sleep" ''
|
||||||
|
sleep 3
|
||||||
|
''}"
|
||||||
|
];
|
||||||
|
ExecStart = let
|
||||||
|
# stdin disappears in NixOS test driver ( machine.succeed() ), requiring us to specify < /dev/ttyS0 to fake stdin
|
||||||
|
exec-monado-service = pkgs.writeShellScript "exec-monado-service" "${pkgs.monado}/bin/monado-service < /dev/ttyS0";
|
||||||
|
in [
|
||||||
|
"${exec-monado-service}"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"stardust-xr-server" = {
|
||||||
|
after = [ "monado.service" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "notify";
|
||||||
|
NotifyAccess = "all";
|
||||||
|
ExecStartPre = [
|
||||||
|
"${pkgs.writeShellScript "sleep" ''
|
||||||
|
sleep 3
|
||||||
|
''}"
|
||||||
|
];
|
||||||
|
ExecStart = let
|
||||||
|
notifyReady = pkgs.writeShellScript "notifyReady" "systemd-notify --ready";
|
||||||
|
exec-stardust-xr-server = pkgs.writeShellScript "exec-stardust-xr-server" "${self.packages.${pkgs.hostPlatform.system}.default}/bin/stardust-xr-server -e ${notifyReady}";
|
||||||
|
in [
|
||||||
|
"${exec-stardust-xr-server}"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"weston-cliptest" = {
|
||||||
|
after = [ "flatland.service" ];
|
||||||
|
environment.WAYLAND_DISPLAY = "wayland-1";
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = [
|
||||||
|
"${pkgs.weston}/bin/weston-cliptest"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"flatland" = {
|
||||||
|
after = [ "stardust-xr-server.service" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = [
|
||||||
|
"${self.inputs.flatland.packages.${pkgs.hostPlatform.system}.default}/bin/flatland"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"org.gnome.Shell@wayland" = {
|
||||||
|
wants = [ "monado.service" "stardust-xr-server.service" "flatland.service" "weston-cliptest.service" ];
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = [
|
||||||
|
# Clear the list before overriding it.
|
||||||
|
""
|
||||||
|
# Eval API is now internal so Shell needs to run in unsafe mode.
|
||||||
|
# TODO: improve test driver so that it supports openqa-like manipulation
|
||||||
|
# that would allow us to drop this mess.
|
||||||
|
"${pkgs.gnome.gnome-shell}/bin/gnome-shell --unsafe-mode"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = { nodes, ... }: let
|
||||||
|
# Keep line widths somewhat managable
|
||||||
|
user = nodes.machine.config.users.users.alice;
|
||||||
|
uid = toString user.uid;
|
||||||
|
bus = "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/${uid}/bus";
|
||||||
|
gdbus = "${bus} gdbus";
|
||||||
|
su = command: "su ${user.name} -c '${command}'";
|
||||||
|
|
||||||
|
# Call javascript in gnome shell, returns a tuple (success, output), where
|
||||||
|
# `success` is true if the dbus call was successful and output is what the
|
||||||
|
# javascript evaluates to.
|
||||||
|
eval = "call --session -d org.gnome.Shell -o /org/gnome/Shell -m org.gnome.Shell.Eval";
|
||||||
|
|
||||||
|
# False when startup is done
|
||||||
|
startingUp = su "${gdbus} ${eval} Main.layoutManager._startingUp";
|
||||||
|
in ''
|
||||||
|
with subtest("Login to GNOME with GDM"):
|
||||||
|
# wait for gdm to start
|
||||||
|
machine.wait_for_unit("display-manager.service")
|
||||||
|
# wait for the wayland server
|
||||||
|
machine.wait_for_file("/run/user/${uid}/wayland-0")
|
||||||
|
# wait for alice to be logged in
|
||||||
|
machine.wait_for_unit("default.target", "${user.name}")
|
||||||
|
# check that logging in has given the user ownership of devices
|
||||||
|
assert "alice" in machine.succeed("getfacl -p /dev/snd/timer")
|
||||||
|
|
||||||
|
with subtest("Wait for GNOME Shell"):
|
||||||
|
# correct output should be (true, 'false')
|
||||||
|
machine.wait_until_succeeds(
|
||||||
|
"${startingUp} | grep -q 'true,..false'"
|
||||||
|
)
|
||||||
|
|
||||||
|
# To allow monado-service to use < /dev/ttyS0
|
||||||
|
machine.succeed("chown alice /dev/ttyS0")
|
||||||
|
|
||||||
|
with subtest("Open Monado and StardustXR"):
|
||||||
|
# Close the Activities view so that Shell can correctly track the focused window.
|
||||||
|
machine.send_key("esc")
|
||||||
|
machine.wait_for_unit("monado.service", "${user.name}")
|
||||||
|
machine.wait_for_unit("stardust-xr-server.service", "${user.name}")
|
||||||
|
machine.wait_for_unit("flatland.service", "${user.name}")
|
||||||
|
machine.wait_for_unit("weston-cliptest.service", "${user.name}")
|
||||||
|
machine.sleep(3)
|
||||||
|
machine.screenshot("screen")
|
||||||
|
'';
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user