Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CI Tests #161

Merged
merged 35 commits into from
Nov 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
136cc14
use systemd-run instead of machinectl
nzbr Oct 8, 2022
8cfef03
fix systemd user sessions by launching through runuser
nzbr Oct 17, 2022
aff4bf6
skip mounting binfmt_misc if the kernel lacks support for it
nzbr Nov 9, 2022
14c3025
link syschdemd/installer to static location
nzbr Nov 9, 2022
6ab9a9e
make check happy
nzbr Nov 9, 2022
abe56b5
Merge branch 'main' into tests
nzbr Nov 9, 2022
c376de7
test tests
nzbr Nov 9, 2022
1ff0201
add a simple installer test
nzbr Nov 9, 2022
fc1fb4f
add second test for exit codes
nzbr Nov 9, 2022
40493e5
Merge branch 'main' into exit-code
nzbr Nov 10, 2022
3bda6c1
Merge branch 'exit-code' into tests
nzbr Nov 10, 2022
b0aed50
make tests responsible for checking exit code
nzbr Nov 10, 2022
1bc49d8
fix: add which to path
nzbr Nov 10, 2022
54a2f75
Merge branch 'exit-code' into tests
nzbr Nov 10, 2022
91d0353
overhaul actions workflow
nzbr Nov 10, 2022
3bcd5ba
move checks out of flake.nix
nzbr Nov 10, 2022
2c8f69b
use GUID for image name
nzbr Nov 10, 2022
c7ec43a
Split flake checks into matrix job
nzbr Nov 10, 2022
101423b
Check for side-effects
nzbr Nov 10, 2022
d75cc32
reformat powershell scripts
nzbr Nov 10, 2022
1a5804b
extend basic test
nzbr Nov 10, 2022
da98e33
use pester for tests
nzbr Nov 10, 2022
a20184d
"fix" (purposefully) failing test
nzbr Nov 11, 2022
dc51fdd
Merge remote-tracking branch 'nix-community/main' into tests
nzbr Nov 17, 2022
df1bde2
rename lib -> init
nzbr Nov 17, 2022
da0b3e5
Add test for systemd --user
nzbr Nov 17, 2022
55f218d
Add test for docker-native
nzbr Nov 17, 2022
c6cd480
move release to separate workflow
nzbr Nov 17, 2022
3bb60fd
change downstream workflow path
nzbr Nov 17, 2022
1f5db11
switch to a class
nzbr Nov 22, 2022
f9025b2
Test running with different user shells
nzbr Nov 24, 2022
31d07f2
Add lib implementation for Windows
nzbr Nov 25, 2022
4b244b1
Add documentation for the tests
nzbr Nov 25, 2022
d36ef47
readme: docker permissions
nzbr Nov 25, 2022
13a9adb
remove empty files
nzbr Nov 25, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
root = true

[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
117 changes: 71 additions & 46 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,78 +1,103 @@
name: 'Build NixOS WSL tarball'
name: 'CI'

on: [push, pull_request, release]
on:
push: {}
pull_request: {}
workflow_call: {}

jobs:
build:
find-tests:
name: Find Tests 🔍
runs-on: ubuntu-latest
outputs:
tests: ${{ steps.tests.outputs.tests }}
checks: ${{ steps.checks.outputs.checks }}
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
# Nix Flakes doesn't work on shallow clones
fetch-depth: 0

- name: Install nix
uses: cachix/install-nix-action@v12
with:
install_url: https://github.com/numtide/nix-flakes-installer/releases/download/nix-2.4pre20201221_9fab14a/install
# Configure Nix to enable flakes
extra_nix_config: |
experimental-features = nix-command flakes
- name: Install nix ❄️
uses: cachix/install-nix-action@v18

- name: Run checks
- name: Find tests 🔍
id: tests
run: |
nix flake check
find tests -name '*.Tests.ps1' -print0 | perl -pe 's|(.*?)\x0|"\1",|g;s|,$||;s|(.*)|tests=[\1]|' >> $GITHUB_OUTPUT

- name: Build tarball
- name: Find checks 🔍
id: checks
run: |
nix build '.#nixosConfigurations.mysystem.config.system.build.tarball'
nix-instantiate --json --eval --strict -E 'with builtins; attrNames (getFlake (toString ./.)).checks.${currentSystem}' | perl -pe 's|(.*)|checks=\1|' >>$GITHUB_OUTPUT

- name: Upload tarball
uses: actions/upload-artifact@v2
build:
name: Build 🛠️
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
name: rootfs
path: result/tarball/nixos-wsl-x86_64-linux.tar.gz
fetch-depth: 0

- name: Build installer
- name: Install nix ❄️
uses: cachix/install-nix-action@v18

- name: Build installer 🛠️
run: |
nix build '.#nixosConfigurations.mysystem.config.system.build.installer'

- name: Upload installer
uses: actions/upload-artifact@v2
- name: Upload installer 📤
uses: actions/upload-artifact@v3
with:
name: installer
path: result/tarball/nixos-wsl-installer.tar.gz

release:
if: startsWith(github.ref, 'refs/tags/')
needs: build
checks:
name: Flake Check 📋
needs:
- find-tests
strategy:
fail-fast: false
matrix:
check: ${{ fromJSON(needs.find-tests.outputs.checks) }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- uses: actions/download-artifact@v2
uses: actions/checkout@v3
with:
name: rootfs
fetch-depth: 0

- uses: actions/download-artifact@v2
with:
name: installer
- name: Install nix ❄️
uses: cachix/install-nix-action@v18

- name: Generate checksums
- name: Run check 📋
run: |
for x in *.tar.gz; do
sha256sum $x > ${x}.sha256
done
nix build -L --impure --expr "with builtins; (getFlake (toString ./.)).checks.\${currentSystem}.${{ matrix.check }}"

- name: Attach to release
uses: softprops/action-gh-release@v1
tests:
name: Test 🧪
needs:
- find-tests
- build
strategy:
fail-fast: false
matrix:
test: ${{ fromJSON(needs.find-tests.outputs.tests) }}
os:
- ubuntu-latest
# - windows-latest # doesn't work due to lack of nested virtualization on the runners, hopefully this will work one day
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Download installer 📥
uses: actions/download-artifact@v3
with:
files: |
nixos-wsl-x86_64-linux.tar.gz
nixos-wsl-x86_64-linux.tar.gz.sha256
nixos-wsl-installer.tar.gz
nixos-wsl-installer.tar.gz.sha256
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
name: installer

- name: Execute test 🧪
shell: pwsh
run: |
Invoke-Pester -Output Detailed ${{ matrix.test }}
35 changes: 35 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: 'Release'

on:
push:
tags: []

jobs:
build:
name: Build 🛠️
uses: nix-community/nixos-wsl/.github/workflows/main.yml@main
release:
needs:
- build
name: Create Release 📢
runs-on: ubuntu-latest
steps:
- name: Download installer 📥
uses: actions/download-artifact@v3
with:
name: installer

- name: Generate checksums 🔑
run: |
for x in *.tar.gz; do
sha256sum $x > ${x}.sha256
done

- name: Attach to release 📦
uses: softprops/action-gh-release@v1
with:
files: |
nixos-wsl-installer.tar.gz
nixos-wsl-installer.tar.gz.sha256
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
11 changes: 11 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "PowerShell: Invoke Pester",
"type": "PowerShell",
"request": "launch",
"script": "Invoke-Pester -Output Detailed",
}
]
}
8 changes: 8 additions & 0 deletions checks/nixpkgs-fmt.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{ runCommand
, nixpkgs-fmt
, ...
}:
runCommand "check-nixpkgs-fmt" { nativeBuildInputs = [ nixpkgs-fmt ]; } ''
nixpkgs-fmt --check ${./..}
touch $out
''
8 changes: 8 additions & 0 deletions checks/shfmt.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{ runCommand
, shfmt
, ...
}:
runCommand "check-shfmt" { nativeBuildInputs = [ shfmt ]; } ''
shfmt -i 2 -d ${./../scripts}/*.sh
touch $out
''
35 changes: 35 additions & 0 deletions checks/side-effects.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Test that including the WSL module in a config does not change anything without enabling it

{ inputs
, system
, emptyFile
, ...
}:
let
configModule = { config, options, ... }: {
fileSystems."/" = {
device = "/dev/sda1";
fsType = "ext4";
};
boot.loader.grub.device = "nodev";
system.stateVersion = options.system.stateVersion.default;
};

cleanConfig = inputs.nixpkgs.lib.nixosSystem {
inherit system;
modules = [
configModule
];
};
wslModuleConfig = inputs.nixpkgs.lib.nixosSystem {
inherit system;
modules = [
configModule
inputs.self.nixosModules.wsl
];
};
in
# Check that both configs evaluate to the same derivation
if cleanConfig.config.system.build.toplevel.outPath == wslModuleConfig.config.system.build.toplevel.outPath
then emptyFile
else throw "The WSL module introduces a side-effect even when not enabled!"
18 changes: 10 additions & 8 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
};
};

outputs = { self, nixpkgs, flake-utils, ... }:
outputs = inputs@{ self, nixpkgs, flake-utils, ... }:
{

nixosModules.wsl = {
Expand Down Expand Up @@ -41,13 +41,15 @@
pkgs = import nixpkgs { inherit system; };
in
{
checks = {
check-format = pkgs.runCommand "check-format" { nativeBuildInputs = with pkgs; [ nixpkgs-fmt shfmt ]; } ''
nixpkgs-fmt --check ${./.}
shfmt -i 2 -d ${./scripts}/*.sh
mkdir $out # success
'';
};
checks =
let
args = { inherit inputs; };
in
{
nixpkgs-fmt = pkgs.callPackage ./checks/nixpkgs-fmt.nix args;
shfmt = pkgs.callPackage ./checks/shfmt.nix args;
side-effects = pkgs.callPackage ./checks/side-effects.nix args;
};

devShell = pkgs.mkShell {
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
Expand Down
6 changes: 4 additions & 2 deletions modules/build-tarball.nix
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ in
# These options make no sense without the wsl-distro module anyway

system.build.tarball = pkgs.callPackage "${nixpkgs}/nixos/lib/make-system-tarball.nix" {
# No contents, structure will be added by prepare script
contents = [ ];

contents = [
{ source = config.users.users.root.shell; target = "/nix/nixos-wsl/entrypoint"; }
];

fileName = "nixos-wsl-${pkgs.hostPlatform.system}";

Expand Down
1 change: 1 addition & 0 deletions modules/installer.nix
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ with builtins; with lib; {
{ source = passwd; target = "/etc/passwd"; }
{ source = "${pkgs.busybox}/bin/busybox"; target = "/bin/sh"; }
{ source = "${pkgs.busybox}/bin/busybox"; target = "/bin/mount"; }
{ source = "${installer}"; target = "/nix/nixos-wsl/entrypoint"; }
];

extraCommands = pkgs.writeShellScript "prepare" ''
Expand Down
1 change: 1 addition & 0 deletions scripts/syschdemd.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ let
src = ./wrapper.sh;
path = lib.makeSearchPath "" [
"/run/wrappers/bin" # mount
"${gnugrep}/bin" # grep
"${systemd}/lib/systemd" # systemd
Comment on lines +34 to 35
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use lib.makeBinPath here

];
};
Expand Down
2 changes: 1 addition & 1 deletion scripts/syschdemd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ main() {
start_systemd
fi

if [ $# -gt 0 ]; then
if [ $# -gt 1 ]; then # Ignore just -c without a command
# wsl seems to prefix with "-c"
shift
command="$*"
Expand Down
4 changes: 3 additions & 1 deletion scripts/wrapper.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/usr/bin/env bash
set -euxo pipefail

mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
if grep -q binfmt_misc /proc/filesystems; then
mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
fi

exec systemd
49 changes: 49 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Tests

This directory contains tests that are executed against a built installer tarball.
The test are written using the [Pester](https://pester.dev/) testing framework

## Execute Tests

The tests can be executed on both Windows or Linux.

### Windows

Make sure that you are able to run a distro in WSL2 before trying to run the tests.
Please note that the tests are not compatible with Windows PowerShell, but require the new [PowerShell Core](https://apps.microsoft.com/store/detail/powershell/9MZ1SNWT0N5D?hl=en-us&gl=us).

### Linux

Running the tests requires Docker and PowerShell to be installed on your system. Make sure that the user you are running the tests as has permissions to run docker containers and that it is possible to access the internet from inside docker containers.

### Running the Tests

If you haven't already, [install Pester](https://pester.dev/docs/introduction/installation/).
The tests require a `nixos-wsl-installer.tar.gz` to be present in the current working directory or in `./result/tarball`. Refer to the top-level readme on how to build it.
Once everything is in place, run the test by running the following in PowerShell at the root of this repo:

```powershell
Invoke-Pester -Output Detailed ./tests
```


## Writing Test

Please refer to [the Pester documentation](https://pester.dev/docs/quick-start) on how to write new tests.

Put this snippet at the start of your test file to gain access to the following libray functions:
(This assumes that your test is at the root of the `tests` directory)

```powershell
BeforeAll {
. $PSScriptRoot/lib/lib.ps1
}
```

- `Install-Distro`: Creates a new NixOS-WSL instance, automatically selecting the appropriate runtime (WSL or Docker) for the host OS. Returns a new `Distro` object
- A Distro object has the following methods:
- `Launch($command)`: Runs the specified command inside the container. Returns the command output
- `GetPath($path)`: Returns the path inside the container, that points to the specified file on the host.
- `InstallConfig($path)`: Installs a nix-file as the systems `configuration.nix`. The default configuration is moved to `base.nix`, so that it can be imported by the new config
- `Shutdown()`: End all processes running in the container
- `Uninstall()`: Stop and then delete the container from the system. This should be called in an AfterEach or AfterAll block, so that the test does not leave it on the system.
Loading