diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 4d46a66..7cabe43 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -9,20 +9,42 @@ on: jobs: validate: runs-on: ubuntu-latest + outputs: + drvpath: ${{ steps.test-derivation.outputs.drvpath }} + steps: - uses: actions/checkout@v3 - uses: cachix/install-nix-action@v22 + with: + extra_nix_config: "system-features = nixos-test benchmark big-parallel kvm" + nix_path: nixpkgs=channel:nixos-23.05 - name: build run: NIXPKGS_ALLOW_UNFREE=1 nix build --impure - - name: check flake - run: NIXPKGS_ALLOW_UNFREE=1 nix flake check --impure + - name: check flake (runs tests) + run: NIXPKGS_ALLOW_UNFREE=1 nix flake check --impure --log-format internal-json + timeout-minutes: 15 + + - name: get test derivation path + id: test-derivation + if: always() + run: | + drvpath=$(ls -d /nix/store/*-vm-test-run-kolide-launcher) + echo "drvpath=${drvpath}" >> "$GITHUB_OUTPUT" + + - name: upload test screenshot + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-screenshot + path: ${{ steps.test-derivation.outputs.drvpath }}/test.png + retention-days: 1 - name: show flake output attributes - run: nix flake show + run: nix flake show --impure - name: show flake metadata run: nix flake metadata diff --git a/README.md b/README.md index 1f83869..89e1d51 100644 --- a/README.md +++ b/README.md @@ -75,3 +75,9 @@ echo -n 'your-enroll-secret-goes-here' | sudo tee /etc/kolide-k2/secret ``` Then start the `kolide-launcher.service` service. + +### Running tests + +[NixOS tests](https://nixos.org/manual/nixos/stable/index.html#sec-nixos-tests) +live in the [./tests](./tests) directory and are included via flake checks. +They are able to be run via the `nix flake check` command. diff --git a/flake.nix b/flake.nix index 8e8c6e9..fa79bce 100644 --- a/flake.nix +++ b/flake.nix @@ -47,5 +47,7 @@ packages.x86_64-linux.default = self.packages.x86_64-linux.kolide-launcher; nixosModules.kolide-launcher = import ./modules/kolide-launcher self; + + checks.x86_64-linux.kolide-launcher = import ./tests/kolide-launcher.nix { flake = self; }; }; } diff --git a/tests/kolide-launcher.nix b/tests/kolide-launcher.nix new file mode 100644 index 0000000..c60685a --- /dev/null +++ b/tests/kolide-launcher.nix @@ -0,0 +1,80 @@ +{ flake }: + +let + nixpkgs = builtins.fetchTarball { + url = "https://github.com/nixOS/nixpkgs/archive/23.05.tar.gz"; + sha256 = "sha256:10wn0l08j9lgqcw8177nh2ljrnxdrpri7bp0g7nvrsn9rkawvlbf"; + }; + pkgs = import nixpkgs { config = {}; overlays = []; }; +in + +pkgs.nixosTest { + name = "kolide-launcher"; + + nodes.machine = { config, pkgs, ... }: { + imports = [ + flake.nixosModules.kolide-launcher + ]; + + users.users.alice = { + isNormalUser = true; + description = "Alice Test"; + password = "alicetest"; + uid = 1000; + }; + + services.xserver.enable = true; + services.xserver.displayManager = { + lightdm.enable = true; + autoLogin = { + enable = true; + user = "alice"; + }; + }; + services.xserver.desktopManager.mate.enable = true; + + # This just quiets some log spam we don't care about + hardware.pulseaudio.enable = true; + + services.kolide-launcher.enable = true; + system.stateVersion = "23.05"; + }; + + testScript = { nodes, ... }: + let + user = nodes.machine.users.users.alice; + in + '' + machine.start() + + # TODO: currently launcher will shut itself down if its secret file doesn't exist, + # so we don't get all the way through setup and launcher doesn't stay running. + # In the future, we'll want to validate setup and that the service is running. + + with subtest("kolide-launcher service starts"): + machine.wait_for_unit("kolide-launcher.service") + machine.sleep(10) + machine.systemctl("stop kolide-launcher.service") + + with subtest("launcher set up correctly"): + machine.wait_for_file("/var/lib/kolide-k2/k2device.kolide.com/debug.json") + + with subtest("get a screenshot"): + machine.wait_for_unit("display-manager.service") + + machine.wait_for_file("${user.home}/.Xauthority") + machine.succeed("xauth merge ${user.home}/.Xauthority") + + machine.wait_until_succeeds("pgrep marco") + machine.wait_for_window("marco") + machine.wait_until_succeeds("pgrep mate-panel") + machine.wait_for_window("Top Panel") + machine.wait_for_window("Bottom Panel") + machine.wait_until_succeeds("pgrep caja") + machine.wait_for_window("Caja") + machine.sleep(20) + machine.screenshot("test.png") + + machine.shutdown() + ''; +}