1
0
Fork 0
mirror of https://github.com/NixOS/nix.dev.git synced 2024-10-18 14:32:43 -04:00

wording and links

This commit is contained in:
Valentin Gagarin 2023-09-11 15:13:00 +02:00 committed by GitHub
parent bfb1858a51
commit 7a681b98ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 31 deletions

View file

@ -6,26 +6,26 @@ This tutorial aims to be compatible with NixOS release 22.11.
## What will you learn?
This guide introduces the functionality of Nixpkgs to write automated tests to debug NixOS configurations independent of a working NixOS installation.
This tutorial introduces the functionality of Nixpkgs to write automated tests to debug NixOS configurations independent of a working NixOS installation.
## What do you need?
- A working installation of [Nix Package Manager](https://nixos.org/manual/nix/stable/installation/installation.html) or [NixOS](https://nixos.org/manual/nixos/stable/index.html#sec-installation).
- Basic knowledge of the [Nix language](https://nixos.org/manual/nix/stable/language/index.html).
- Basic knowledge of the [Nix language](<nix-language>).
- Basic knowledge of [NixOS configuration](<nixos-vms>).
## Introduction
Nixpkgs provides a [test environment](https://nixos.org/manual/nixos/stable/index.html#sec-nixos-tests) to automate integration testing.
You can define tests that make use of a set of declarative NixOS configurations and use a Python shell to interact with them through [QEMU](https://www.qemu.org/) as the backend.
It allows defining tests based on a set of declarative NixOS configurations and using a Python shell to interact with them through [QEMU](https://www.qemu.org/) as the backend.
Those tests are widely used to ensure that NixOS works as intended, so in general they are called [NixOS Tests](https://nixos.org/manual/nixos/stable/index.html#sec-nixos-tests).
They can be written and launched outside of NixOS, on any Linux machine (with [MacOS support coming soon](https://github.com/NixOS/nixpkgs/issues/108984)).
Integration tests are reproducible due to the design properties of Nix, making them a valuable part of a Continuous Integration (CI) pipeline.
## The `nixosTest` function
To setup a test you make use of the `nixosTest` function.
The scaffolding of a test nix file looks like the following:
NixOS VM tests are defined using the `nixosTest` function.
The pattern for NixOS VM tests looks like this:
```nix
let
@ -49,7 +49,7 @@ in
```
The function `nixosTest` takes an attribute set that follows the module convention to [specify the test](https://nixos.org/manual/nixos/stable/index.html#sec-test-options-reference).
Because the attribute set only defines options, one can use the abbreviated form of the module convention.
Because the attribute set only defines options, one can use the abbreviated form of the [module convention](https://nixos.org/manual/nixos/stable/#sec-writing-modules).
The attribute set needs to define the following options:
- [`name`](https://nixos.org/manual/nixos/stable/index.html#test-opt-name) defines the name of the test.
@ -68,6 +68,8 @@ The test framework automatically starts the virtual machines and runs the Python
## Minimal example
As a minimal test on the default configuration, we will check if the user `root` and `alice` can run Firefox.
We will build the example up from scratch.
As [recommended](<ref-pinning-nixpkgs>) you use an explicitly pinned version of Nixpkgs:
```nix
@ -84,7 +86,7 @@ in
#### Name
You define the name of the test using a descriptive name like "minimal-test":
Label the test with a descriptive name such as "minimal-test":
```nix
name = "minimal-test";
@ -92,8 +94,9 @@ name = "minimal-test";
#### Nodes
Because this example only uses one virtual machine the node you specify is simply called `machine`.
As configuration you use the relevant parts of the default configuration, [that we used before](<nixos-vms>):
Because this example only uses one virtual machine, the node we specify is simply called `machine`.
This name is arbitrary and can be chosen freely.
As configuration you use the relevant parts of the default configuration, [that we used in a previous tutorial](<nixos-vms>):
```nix
nodes.machine = { config, pkgs, ... }: {
@ -122,11 +125,11 @@ machine.fail("su -- root -c 'which firefox'")
This Python script is referring to `machine` which is the name chosen for the virtual machine configuration used in the `nodes` attribute set.
The script waits until start up is reaching systemd `default.target`.
It utilizes the `su` command to switch between users and the `which` command to see if the user has access to `firefox`.
The script waits until systemd reaches `default.target`.
It uses the `su` command to switch between users and the `which` command to check if the user has access to `firefox`.
It expects that the command `which firefox` to succeed for user `alice` and to fail for `root`.
This script needs to be located in a function inside the `testScript` attribute.
This script will be the value of the `testScript` attribute.
### Test file
@ -162,7 +165,7 @@ in
## Running tests
To set up all machines and execute the test script:
To set up all machines and run the test script:
```shell-session
$ nix-build minimal-test.nix
@ -176,24 +179,24 @@ $ nix-build minimal-test.nix
/nix/store/bx7z3imvxxpwkkza10vb23czhw7873w2-vm-test-run-minimal-test
## Interactive Python shell to interact with virtual machine
## Interactive Python shell in the virtual machine
When developing tests or when something breaks, its useful to interactively tinker with the test or access a terminal for a machine.
To interactively start a Python session with the testing framework:
To start an interactive Python session with the testing framework:
```shell-session
$ $(nix-build -A driverInteractive minimal-test.nix)/bin/nixos-test-driver
```
You can run any of the testing operations.
The `testScript` attribute from `minimal-test.nix` definition can be executed with `test_script()` function.
Here you can run any of the testing operations.
Execute the `testScript` attribute from `minimal-test.nix` with the `test_script()` function.
Within this Python shell you can enter a interactive shell and run Python commands like those in the test script.
If a virtual machine is not yet started, the test environment takes care of it on the first call of a method of a `machine` object.
If a virtual machine is not yet started, the test environment takes care of it on the first call of a method on a `machine` object.
But you can also manually trigger the start of the virtual machine by using
But you can also manually trigger the start of the virtual machine with:
```shell-session
>>> machine.start()
@ -205,7 +208,7 @@ or
```shell-session
>>> start_all()
```
for all specified nodes.
for all nodes.
You can enter a interactive shell on the virtual machine using:
@ -213,7 +216,7 @@ You can enter a interactive shell on the virtual machine using:
>>> machine.shell_interact()
```
and run commandline commands like:
and run shell commands like:
```shell-session
uname -a
@ -222,7 +225,9 @@ uname -a
Linux server 5.10.37 #1-NixOS SMP Fri May 14 07:50:46 UTC 2021 x86_64 GNU/Linux
<details><summary> Re-run successful tests </summary>
<details><summary>Re-running successful tests</summary>
<!-- FIXME: this should be a separate recipe that can be linked to, as it's a bit of knowledge one will need now and again. -->
Because test results are kept in the Nix store, a successful test is cached.
This means that Nix will not run the test a second time as long as the test setup (node configuration and test script) stays semantically the same.
@ -254,7 +259,7 @@ result=$(readlink -f ./result) rm ./result && nix-store --delete $result
## Tests that need multiple virtual machines
Tests can utilize multiple virtual machines.
Tests can involve multiple virtual machines.
This example uses the use-case of a [REST](https://en.m.wikipedia.org/wiki/REST) interface to a [PostgreSQL](https://www.postgresql.org/) database.
The following example Nix expression is adapted from [How to use NixOS for lightweight integration tests](https://www.haskellforall.com/2020/11/how-to-use-nixos-for-lightweight.html).
@ -273,7 +278,7 @@ The complete `postgrest.nix` file looks like the following:
```{code-block}
let
# Pin nixpkgs, see pinning tutorial for more details
# Pin Nixpkgs, as some packages are broken in the 22.11 release
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/0f8f64b54ed07966b83db2f20c888d5e035012ef.tar.gz";
pkgs = import nixpkgs { config = {}; overlays = []; };
@ -288,13 +293,13 @@ let
# NixOS module shared between server and client
sharedModule = {
# Since it's common for CI not to have $DISPLAY available, you have to explicitly tell the tests "please don't expect any screen available"
# Since it's common for CI not to have $DISPLAY available, explicitly disable graphics support
virtualisation.graphics = false;
};
in
pkgs.nixosTest {
# NixOS tests are run inside a virtual machine, and here you specify system of the machine.
# NixOS tests are run inside a virtual machine, and here you specify its system type
system = "x86_64-linux";
name = "postgres-test";
nodes = {
@ -390,7 +395,7 @@ in
Unlike the previous example, the virtual machines need an expressive name to distinguish them.
For this example we choose `client` and `server`.
To set up all machines and execute the test script:
Set up all machines and run the test script:
```shell-session
nix-build postgrest.nix
@ -408,9 +413,11 @@ nix-build postgrest.nix
```
## Additional information regarding NixOS tests:
- NixOS Tests section in [NixOS manual](https://nixos.org/manual/nixos/stable/index.html#sec-nixos-tests)
- Running integration tests on CI requires hardware acceleration, which many CIs do not support.
To run integration tests on [GitHub Actions](<github-actions>) see [how to disable hardware acceleration](https://github.com/cachix/install-nix-action#how-do-i-run-nixos-tests).
- NixOS comes with a large set of tests that serve also as educational examples.
A good inspiration is [Matrix bridging with an IRC](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/matrix/appservice-irc.nix).
- [NixOS.wiki on NixOS Testing library](https://nixos.wiki/wiki/NixOS_Testing_library) seems to be mostly outdated (last edit 05.11.2021)
<!-- TODO: move examples from https://nixos.wiki/wiki/NixOS_Testing_library to the NixOS manual and troubleshooting tips to nix.dev -->

View file

@ -193,8 +193,9 @@ rm nixos.qcow2
## References
- [Nix manual: `nix-build` man page](https://nixos.org/manual/nix/stable/command-ref/nix-build.html).
- [Nix manual: common cli options](https://nixos.org/manual/nix/stable/command-ref/opt-common.html).
- NixOS Tests section in [NixOS manual](https://nixos.org/manual/nixos/stable/index.html#sec-nixos-tests)
- [Nix manual: `nix-build`](https://nixos.org/manual/nix/stable/command-ref/nix-build.html).
- [Nix manual: common command-line options](https://nixos.org/manual/nix/stable/command-ref/opt-common.html).
- [Nix manual: `NIX_PATH` environment variable](https://nixos.org/manual/nix/stable/command-ref/env-common.html#env-NIX_PATH).
- [NixOS Manual: NixOS Configuration](https://nixos.org/manual/nixos/stable/index.html#ch-configuration).
- [NixOS Manual: Modules](https://nixos.org/manual/nixos/stable/index.html#sec-writing-modules).