From 7b6cec41000dcc9980f4bc35448a3f3ccc7ec1d9 Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Sat, 1 Nov 2025 12:25:50 +0100 Subject: [PATCH] services: update hello-world readme and tests --- clanServices/hello-world/README.md | 84 ++++++++++++++++++- clanServices/hello-world/default.nix | 2 +- clanServices/hello-world/flake-module.nix | 2 +- clanServices/hello-world/tests/eval-tests.nix | 20 +++-- 4 files changed, 100 insertions(+), 8 deletions(-) diff --git a/clanServices/hello-world/README.md b/clanServices/hello-world/README.md index 04c30234b..5a6451870 100644 --- a/clanServices/hello-world/README.md +++ b/clanServices/hello-world/README.md @@ -1 +1,83 @@ -This a test README just to appease the eval warnings if we don't have one \ No newline at end of file +!!! Danger "Experimental" + This service is for demonstration purpose only and may change in the future. + +The Hello-World Clan Service is a minimal example showing how to build and register your own service. + +It serves as a reference implementation and is used in clan-core CI tests to ensure compatibility. + +## What it demonstrates + +- How to define a basic Clan-compatible service. +- How to structure your service for discovery and configuration. +- How Clan services interact with nixos. + +## Testing + +This service demonstrates two levels of testing to ensure quality and stability across releases: + +1. **Unit & Integration Testing** — via [`nix-unit`](https://github.com/nix-community/nix-unit) +2. **End-to-End Testing** — via **NixOS VM tests**, which we extended to support **container virtualization** for better performance. + +We highly advocate following the [Practical Testing Pyramid](https://martinfowler.com/articles/practical-test-pyramid.html): + +* Write **unit tests** for core logic and invariants. +* Add **one or two end-to-end (E2E)** tests to confirm your service starts and behaves correctly in a real NixOS environment. + +NixOS is **untyped** and frequently changes; tests are the safest way to ensure long-term stability of services. + +``` + / \ + / \ + / E2E \ + /-------\ + / \ + /Integration\ + /-------------\ + / \ + / Unit Tests \ + ------------------- +``` + +### nix-unit + +We highly advocate the usage of + +[nix-unit](https://github.com/nix-community/nix-unit) + +Example in: tests/eval-tests.nix + +If you use flake-parts you can use the [native integration](https://flake.parts/options/nix-unit.html) + +If nix-unit succeeds you'r nixos evaluation should be mostly correct. + +!!! Tip + - Ensure most used 'settings' and variants are tested. + - Think about some important edge-cases your system should handle. + +### NixOS VM / Container Test + +!!! Warning "Early Vars & clanTest" + The testing system around vars is experimental + + `clanTest` is still experimental and enables container virtualization by default. + This is still early and might have some limitations. + +Some minimal boilerplate is needed to use `clanTest` + +```nix +nixosLib = import (inputs.nixpkgs + "/nixos/lib") { } +nixosLib.runTest ( + { ... }: + { + imports = [ + self.modules.nixosTest.clanTest + # Example in tests/vm/default.nix + testModule + ]; + hostPkgs = pkgs; + + # Uncomment if you don't want or cannot use containers + # test.useContainers = false; + } +) +``` diff --git a/clanServices/hello-world/default.nix b/clanServices/hello-world/default.nix index 5c682cb13..d86d5cfe8 100644 --- a/clanServices/hello-world/default.nix +++ b/clanServices/hello-world/default.nix @@ -8,7 +8,7 @@ { _class = "clan.service"; manifest.name = "clan-core/hello-word"; - manifest.description = "This is a test"; + manifest.description = "Minimal example clan service that greets the world"; manifest.readme = builtins.readFile ./README.md; # This service provides two roles: "morning" and "evening". Roles can be diff --git a/clanServices/hello-world/flake-module.nix b/clanServices/hello-world/flake-module.nix index e41c5c196..f62f0811f 100644 --- a/clanServices/hello-world/flake-module.nix +++ b/clanServices/hello-world/flake-module.nix @@ -26,7 +26,7 @@ in # The hello-world service being tested ../../clanServices/hello-world # Required modules - ../../nixosModules/clanCore + ../../nixosModules ]; testName = "hello-world"; tests = ./tests/eval-tests.nix; diff --git a/clanServices/hello-world/tests/eval-tests.nix b/clanServices/hello-world/tests/eval-tests.nix index 1cca5c54b..dfa735af2 100644 --- a/clanServices/hello-world/tests/eval-tests.nix +++ b/clanServices/hello-world/tests/eval-tests.nix @@ -4,7 +4,7 @@ ... }: let - testFlake = clanLib.clan { + testClan = clanLib.clan { self = { }; # Point to the folder of the module # TODO: make this optional @@ -33,10 +33,20 @@ let }; in { - test_simple = { - config = testFlake.config; + /** + We highly advocate the usage of: + https://github.com/nix-community/nix-unit - expr = { }; - expected = { }; + If you use flake-parts you can use the native integration: https://flake.parts/options/nix-unit.html + */ + test_simple = { + # Allows inspection via the nix-repl + # Ignored by nix-unit; it only looks at 'expr' and 'expected' + inherit testClan; + + # Assert that jon has the + # configured greeting in 'environment.etc.hello.text' + expr = testClan.config.nixosConfigurations.jon.config.environment.etc."hello".text; + expected = "Good evening World!"; }; }