diff options
author | Gabriel Arazas <foodogsquared@foodogsquared.one> | 2023-10-29 14:44:03 +0800 |
---|---|---|
committer | Weijia Wang <9713184+wegank@users.noreply.github.com> | 2023-12-01 09:10:37 +0100 |
commit | ad277ea47e17e3073ba61af07284d1dff8d1601e (patch) | |
tree | 96a00528434dac4c21c855f227ca8a137e1b7df5 /nixos/tests/guix | |
parent | 092aaf841806e8a5fcdfea566bbaae2e25cea069 (diff) |
nixos/guix: init
Diffstat (limited to 'nixos/tests/guix')
-rw-r--r-- | nixos/tests/guix/basic.nix | 38 | ||||
-rw-r--r-- | nixos/tests/guix/default.nix | 8 | ||||
-rw-r--r-- | nixos/tests/guix/publish.nix | 95 | ||||
-rw-r--r-- | nixos/tests/guix/scripts/add-existing-files-to-store.scm | 52 | ||||
-rw-r--r-- | nixos/tests/guix/scripts/create-file-to-store.scm | 8 |
5 files changed, 201 insertions, 0 deletions
diff --git a/nixos/tests/guix/basic.nix b/nixos/tests/guix/basic.nix new file mode 100644 index 0000000000000..7f90bdeeb1e0f --- /dev/null +++ b/nixos/tests/guix/basic.nix @@ -0,0 +1,38 @@ +# Take note the Guix store directory is empty. Also, we're trying to prevent +# Guix from trying to downloading substitutes because of the restricted +# access (assuming it's in a sandboxed environment). +# +# So this test is what it is: a basic test while trying to use Guix as much as +# we possibly can (including the API) without triggering its download alarm. + +import ../make-test-python.nix ({ lib, pkgs, ... }: { + name = "guix-basic"; + meta.maintainers = with lib.maintainers; [ foo-dogsquared ]; + + nodes.machine = { config, ... }: { + environment.etc."guix/scripts".source = ./scripts; + services.guix.enable = true; + }; + + testScript = '' + import pathlib + + machine.wait_for_unit("multi-user.target") + machine.wait_for_unit("guix-daemon.service") + + # Can't do much here since the environment has restricted network access. + with subtest("Guix basic package management"): + machine.succeed("guix build --dry-run --verbosity=0 hello") + machine.succeed("guix show hello") + + # This is to see if the Guix API is usable and mostly working. + with subtest("Guix API scripting"): + scripts_dir = pathlib.Path("/etc/guix/scripts") + + text_msg = "Hello there, NixOS!" + text_store_file = machine.succeed(f"guix repl -- {scripts_dir}/create-file-to-store.scm '{text_msg}'") + assert machine.succeed(f"cat {text_store_file}") == text_msg + + machine.succeed(f"guix repl -- {scripts_dir}/add-existing-files-to-store.scm {scripts_dir}") + ''; +}) diff --git a/nixos/tests/guix/default.nix b/nixos/tests/guix/default.nix new file mode 100644 index 0000000000000..a017668c05a75 --- /dev/null +++ b/nixos/tests/guix/default.nix @@ -0,0 +1,8 @@ +{ system ? builtins.currentSystem +, pkgs ? import ../../.. { inherit system; } +}: + +{ + basic = import ./basic.nix { inherit system pkgs; }; + publish = import ./publish.nix { inherit system pkgs; }; +} diff --git a/nixos/tests/guix/publish.nix b/nixos/tests/guix/publish.nix new file mode 100644 index 0000000000000..6dbe8f99ebd68 --- /dev/null +++ b/nixos/tests/guix/publish.nix @@ -0,0 +1,95 @@ +# Testing out the substitute server with two machines in a local network. As a +# bonus, we'll also test a feature of the substitute server being able to +# advertise its service to the local network with Avahi. + +import ../make-test-python.nix ({ pkgs, lib, ... }: let + publishPort = 8181; + inherit (builtins) toString; +in { + name = "guix-publish"; + + meta.maintainers = with lib.maintainers; [ foo-dogsquared ]; + + nodes = let + commonConfig = { config, ... }: { + # We'll be using '--advertise' flag with the + # substitute server which requires Avahi. + services.avahi = { + enable = true; + nssmdns = true; + publish = { + enable = true; + userServices = true; + }; + }; + }; + in { + server = { config, lib, pkgs, ... }: { + imports = [ commonConfig ]; + + services.guix = { + enable = true; + publish = { + enable = true; + port = publishPort; + + generateKeyPair = true; + extraArgs = [ "--advertise" ]; + }; + }; + + networking.firewall.allowedTCPPorts = [ publishPort ]; + }; + + client = { config, lib, pkgs, ... }: { + imports = [ commonConfig ]; + + services.guix = { + enable = true; + + extraArgs = [ + # Force to only get all substitutes from the local server. We don't + # have anything in the Guix store directory and we cannot get + # anything from the official substitute servers anyways. + "--substitute-urls='http://server.local:${toString publishPort}'" + + # Enable autodiscovery of the substitute servers in the local + # network. This machine shouldn't need to import the signing key from + # the substitute server since it is automatically done anyways. + "--discover=yes" + ]; + }; + }; + }; + + testScript = '' + import pathlib + + start_all() + + scripts_dir = pathlib.Path("/etc/guix/scripts") + + for machine in machines: + machine.wait_for_unit("multi-user.target") + machine.wait_for_unit("guix-daemon.service") + machine.wait_for_unit("avahi-daemon.service") + + server.wait_for_unit("guix-publish.service") + server.wait_for_open_port(${toString publishPort}) + server.succeed("curl http://localhost:${toString publishPort}/") + + # Now it's the client turn to make use of it. + substitute_server = "http://server.local:${toString publishPort}" + client.wait_for_unit("network-online.target") + response = client.succeed(f"curl {substitute_server}") + assert "Guix Substitute Server" in response + + # Authorizing the server to be used as a substitute server. + client.succeed(f"curl -O {substitute_server}/signing-key.pub") + client.succeed("guix archive --authorize < ./signing-key.pub") + + # Since we're using the substitute server with the `--advertise` flag, we + # might as well check it. + client.succeed("avahi-browse --resolve --terminate _guix_publish._tcp | grep '_guix_publish._tcp'") + ''; +}) diff --git a/nixos/tests/guix/scripts/add-existing-files-to-store.scm b/nixos/tests/guix/scripts/add-existing-files-to-store.scm new file mode 100644 index 0000000000000..fa47320b6a511 --- /dev/null +++ b/nixos/tests/guix/scripts/add-existing-files-to-store.scm @@ -0,0 +1,52 @@ +;; A simple script that adds each file given from the command-line into the +;; store and checks them if it's the same. +(use-modules (guix) + (srfi srfi-1) + (ice-9 ftw) + (rnrs io ports)) + +;; This is based from tests/derivations.scm from Guix source code. +(define* (directory-contents dir #:optional (slurp get-bytevector-all)) + "Return an alist representing the contents of DIR" + (define prefix-len (string-length dir)) + (sort (file-system-fold (const #t) + (lambda (path stat result) + (alist-cons (string-drop path prefix-len) + (call-with-input-file path slurp) + result)) + (lambda (path stat result) result) + (lambda (path stat result) result) + (lambda (path stat result) result) + (lambda (path stat errno result) result) + '() + dir) + (lambda (e1 e2) + (string<? (car e1) (car e2))))) + +(define* (check-if-same store drv path) + "Check if the given path and its store item are the same" + (let* ((filetype (stat:type (stat drv)))) + (case filetype + ((regular) + (and (valid-path? store drv) + (equal? (call-with-input-file path get-bytevector-all) + (call-with-input-file drv get-bytevector-all)))) + ((directory) + (and (valid-path? store drv) + (equal? (directory-contents path) + (directory-contents drv)))) + (else #f)))) + +(define* (add-and-check-item-to-store store path) + "Add PATH to STORE and check if the contents are the same" + (let* ((store-item (add-to-store store + (basename path) + #t "sha256" path)) + (is-same (check-if-same store store-item path))) + (if (not is-same) + (exit 1)))) + +(with-store store + (map (lambda (path) + (add-and-check-item-to-store store (readlink* path))) + (cdr (command-line)))) diff --git a/nixos/tests/guix/scripts/create-file-to-store.scm b/nixos/tests/guix/scripts/create-file-to-store.scm new file mode 100644 index 0000000000000..467e4c4fd53f2 --- /dev/null +++ b/nixos/tests/guix/scripts/create-file-to-store.scm @@ -0,0 +1,8 @@ +;; A script that creates a store item with the given text and prints the +;; resulting store item path. +(use-modules (guix)) + +(with-store store + (display (add-text-to-store store "guix-basic-test-text" + (string-join + (cdr (command-line)))))) |