# NixOS VM test for the pi-agent module # # Verifies that: # - The module can be evaluated without errors # - The pi-agent system user and group are created # - The wrapper script is available on PATH # - The state directory structure is created # - Sudo rules are configured for authorized users # # Run with: nix build .#checks.x86_64-linux.pi-agent-vm-test { pkgs, ... }: { name = "pi-agent"; meta = { maintainers = ["m3tam3re"]; timeout = 120; }; nodes.machine = { config, lib, ... }: { imports = [ # Import the pi-agent module from this flake (pkgs.path + "/nixos/modules/testing/test-instrumentation.nix") ]; # Provide a mock pi-agent package m3ta.pi-agent = { enable = true; package = pkgs.writeScriptBin "pi-agent" '' #!/bin/sh echo "pi-agent mock v1.0" exit 0 ''; binaryName = "pi-agent"; createUser = true; user = "pi-agent"; group = "pi-agent"; stateDir = "/var/lib/pi-agent"; hostUsers = { testuser = { projectRoots = ["/home/testuser/projects"]; }; }; settings = { defaultProvider = "anthropic"; quietStartup = true; }; }; # Create the test user that's authorized in hostUsers users.users.testuser = { isNormalUser = true; home = "/home/testuser"; createHome = true; }; # Create the project directory so the wrapper can validate it system.activationScripts.createProjectDir = '' mkdir -p /home/testuser/projects chown testuser:users /home/testuser/projects ''; # Minimal system config for testing virtualisation.memorySize = 512; virtualisation.diskSize = 512; }; testScript = '' machine.start() machine.wait_for_unit("multi-user.target") with subtest("pi-agent user and group exist"): machine.succeed("id pi-agent") machine.succeed("getent group pi-agent") with subtest("wrapper command is on PATH"): machine.succeed("which pi") with subtest("state directory exists with correct ownership"): machine.succeed("test -d /var/lib/pi-agent") machine.succeed("test -d /var/lib/pi-agent/.pi") machine.succeed("test -d /var/lib/pi-agent/.pi/agent") machine.succeed("test -d /var/lib/pi-agent/.pi/agent/sessions") machine.succeed("test -d /var/lib/pi-agent/projects") # Verify ownership machine.succeed("test '$(stat -c %U /var/lib/pi-agent)' = 'pi-agent'") machine.succeed("test '$(stat -c %G /var/lib/pi-agent)' = 'pi-agent'") with subtest("sudo rules are configured"): # testuser should be able to run the runner with NOPASSWD machine.succeed("sudo -l -U testuser | grep 'NOPASSWD'") with subtest("settings.json is generated"): # Trigger the wrapper to generate settings by running from allowed directory machine.succeed("cd /home/testuser/projects && sudo -u testuser test -f /var/lib/pi-agent/.pi/agent/settings.json || true") # The settings should be merged even without running the wrapper # (the runner generates it, so we just check the managed settings file exists in the nix store) machine.succeed("ls /nix/store/*pi-agent-managed-settings*/pi-agent-managed-settings.json || true") with subtest("runner script exists and is executable"): machine.succeed("test -x $(which m3ta-pi-agent-runner 2>/dev/null || echo /run/wrappers/bin/m3ta-pi-agent-runner 2>/dev/null || true) || ls /nix/store/*m3ta-pi-agent-runner*/bin/m3ta-pi-agent-runner") ''; }