diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..beffa308 --- /dev/null +++ b/.editorconfig @@ -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 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3db8e0d6..2a66281e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -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 }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..72ba873b --- /dev/null +++ b/.github/workflows/release.yml @@ -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 }} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..fd01366e --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "PowerShell: Invoke Pester", + "type": "PowerShell", + "request": "launch", + "script": "Invoke-Pester -Output Detailed", + } + ] +} diff --git a/checks/nixpkgs-fmt.nix b/checks/nixpkgs-fmt.nix new file mode 100644 index 00000000..0958dd7c --- /dev/null +++ b/checks/nixpkgs-fmt.nix @@ -0,0 +1,8 @@ +{ runCommand +, nixpkgs-fmt +, ... +}: +runCommand "check-nixpkgs-fmt" { nativeBuildInputs = [ nixpkgs-fmt ]; } '' + nixpkgs-fmt --check ${./..} + touch $out +'' diff --git a/checks/shfmt.nix b/checks/shfmt.nix new file mode 100644 index 00000000..3a655147 --- /dev/null +++ b/checks/shfmt.nix @@ -0,0 +1,8 @@ +{ runCommand +, shfmt +, ... +}: +runCommand "check-shfmt" { nativeBuildInputs = [ shfmt ]; } '' + shfmt -i 2 -d ${./../scripts}/*.sh + touch $out +'' diff --git a/checks/side-effects.nix b/checks/side-effects.nix new file mode 100644 index 00000000..84b88667 --- /dev/null +++ b/checks/side-effects.nix @@ -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!" diff --git a/flake.nix b/flake.nix index 3fa1881f..8643da31 100644 --- a/flake.nix +++ b/flake.nix @@ -11,7 +11,7 @@ }; }; - outputs = { self, nixpkgs, flake-utils, ... }: + outputs = inputs@{ self, nixpkgs, flake-utils, ... }: { nixosModules.wsl = { @@ -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}"; diff --git a/modules/build-tarball.nix b/modules/build-tarball.nix index feba78d4..5eba52d9 100644 --- a/modules/build-tarball.nix +++ b/modules/build-tarball.nix @@ -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}"; diff --git a/modules/installer.nix b/modules/installer.nix index 3fd404f2..63bdc9e3 100644 --- a/modules/installer.nix +++ b/modules/installer.nix @@ -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" '' diff --git a/scripts/syschdemd.nix b/scripts/syschdemd.nix index b7b42fd4..ab3d9fe5 100644 --- a/scripts/syschdemd.nix +++ b/scripts/syschdemd.nix @@ -31,6 +31,7 @@ let src = ./wrapper.sh; path = lib.makeSearchPath "" [ "/run/wrappers/bin" # mount + "${gnugrep}/bin" # grep "${systemd}/lib/systemd" # systemd ]; }; diff --git a/scripts/syschdemd.sh b/scripts/syschdemd.sh index 73adb402..a28ffccf 100644 --- a/scripts/syschdemd.sh +++ b/scripts/syschdemd.sh @@ -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="$*" diff --git a/scripts/wrapper.sh b/scripts/wrapper.sh index 6f4dd5ad..15b24be3 100644 --- a/scripts/wrapper.sh +++ b/scripts/wrapper.sh @@ -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 diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 00000000..d2858098 --- /dev/null +++ b/tests/README.md @@ -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. diff --git a/tests/basic-functionality.Tests.ps1 b/tests/basic-functionality.Tests.ps1 new file mode 100644 index 00000000..d62823b6 --- /dev/null +++ b/tests/basic-functionality.Tests.ps1 @@ -0,0 +1,44 @@ +BeforeAll { + . $PSScriptRoot/lib/lib.ps1 +} + +Describe "Basic Functionality" { + BeforeAll { + $distro = Install-Distro + } + + It "is possible to run a command through the installer" { + $distro.Launch("nixos-version") + $LASTEXITCODE | Should -Be 0 + } + + It "is possible to run a second command" { + $distro.Launch("true") + $LASTEXITCODE | Should -Be 0 + } + + It "is possible to run a command after restarting the container" { + $distro.Shutdown() + $distro.Launch("true") + $LASTEXITCODE | Should -Be 0 + } + + It "is possible to use nixos-rebuild" { + $distro.Launch("sudo nixos-rebuild switch") + $LASTEXITCODE | Should -Be 0 + } + + It "is possible to run a command through nix-shell" { + $distro.Launch("nix-shell -p neofetch --command neofetch") + $LASTEXITCODE | Should -Be 0 + } + + It "is possible to run a command through nix run" { + $distro.Launch("nix run nixpkgs#neofetch") + $LASTEXITCODE | Should -Be 0 + } + + AfterAll { + $distro.Uninstall() + } +} diff --git a/tests/docker/docker-native.nix b/tests/docker/docker-native.nix new file mode 100644 index 00000000..47ccb7f9 --- /dev/null +++ b/tests/docker/docker-native.nix @@ -0,0 +1,12 @@ +{ pkgs, lib, ... }: +{ + imports = [ ./base.nix ]; + + wsl.docker-native.enable = true; + wsl.docker-native.addToDockerGroup = true; + + # Github Actions runners try to use aufs and fail if this is not set explicitly + virtualisation.docker.daemon.settings = { + "storage-driver" = "vfs"; + }; +} diff --git a/tests/docker/docker.Tests.ps1 b/tests/docker/docker.Tests.ps1 new file mode 100644 index 00000000..666d0992 --- /dev/null +++ b/tests/docker/docker.Tests.ps1 @@ -0,0 +1,42 @@ +BeforeAll { + . $PSScriptRoot/../lib/lib.ps1 +} + +Describe "Docker (native)" { + BeforeAll { + $distro = Install-Distro + $distro.InstallConfig("$PSScriptRoot/docker-native.nix") + } + + It "should be possible to run a docker container" { + $distro.Launch("docker run --rm -it hello-world") + $LASTEXITCODE | Should -Be 0 + } + + It "should still be possible to run a docker container after a restart" { + $distro.Shutdown() + $distro.Launch("docker run --rm -it hello-world") + $LASTEXITCODE | Should -Be 0 + } + + It "should be possible to connect to the internet from a container" { + $distro.Launch("docker run --rm -it alpine wget -qO- http://www.msftconnecttest.com/connecttest.txt") | Select-Object -Last 1 | Should -BeExactly "Microsoft Connect Test" + # docker exec -it $distro.id /nix/nixos-wsl/entrypoint -c "docker run --rm -it alpine wget -qO- http://www.msftconnecttest.com/connecttest.txt" | Select-Object -Last 1 | Should -BeExactly "Microsoft Connect Test" + $LASTEXITCODE | Should -Be 0 + } + + It "should be possible to mount a volume from the host" { + $teststring = [guid]::NewGuid().ToString() + + $testdir = $distro.Launch("mktemp -d") | Select-Object -Last 1 + $testfilename = "testfile" + $testfile = "${testdir}/${testfilename}" + $distro.Launch("echo $teststring > $testfile") + $distro.Launch("docker run --rm -it -v ${testdir}:/mnt alpine cat /mnt/${testfilename}") | Select-Object -Last 1 | Should -BeExactly $teststring + $LASTEXITCODE | Should -Be 0 + } + + AfterAll { + $distro.Uninstall() + } +} diff --git a/tests/exit-codes.Tests.ps1 b/tests/exit-codes.Tests.ps1 new file mode 100644 index 00000000..8f8bae94 --- /dev/null +++ b/tests/exit-codes.Tests.ps1 @@ -0,0 +1,23 @@ +BeforeAll { + . $PSScriptRoot/lib/lib.ps1 +} + +Describe "Exit Codes" { + BeforeAll { + $distro = Install-Distro + } + + It "should return 0 when running true" { + $distro.Launch("true") + $LASTEXITCODE | Should -Be 0 + } + + It "should return 1 when running false" { + $distro.Launch("false") + $LASTEXITCODE | Should -Be 1 + } + + AfterAll { + $distro.Uninstall() + } +} diff --git a/tests/lib/Dockerfile b/tests/lib/Dockerfile new file mode 100644 index 00000000..1fcea668 --- /dev/null +++ b/tests/lib/Dockerfile @@ -0,0 +1,2 @@ +FROM scratch +ADD nixos-wsl-installer.tar.gz / diff --git a/tests/lib/lib.ps1 b/tests/lib/lib.ps1 new file mode 100644 index 00000000..beef272a --- /dev/null +++ b/tests/lib/lib.ps1 @@ -0,0 +1,163 @@ +if ($PSVersionTable.PSEdition -ne 'Core') { + throw "The tests are not compatible with Windows PowerShell, please use PowerShell Core instead" +} + +# Implementation-independent base class +class Distro { + [string]$id + + [string]Launch() { + throw "Not implemented" + } + + [string]GetPath([string]$path) { + throw "Not implemented" + } + + [string]FindTarball() { + # Check if a fresh tarball exists in result, otherwise try one in the current directory + $tarball = "./result/tarball/nixos-wsl-installer.tar.gz" + if (!(Test-Path $tarball)) { + $tarball = "./nixos-wsl-installer.tar.gz" + if (!(Test-Path $tarball)) { + throw "Could not find the installer tarball! Run nix build first, or place one in the current directory." + } + } + Write-Host "Using tarball: $tarball" + return $tarball + } + + [void]InstallConfig([string]$path) { + Write-Host "Installing config: $path" + + # Move config out of the way + $this.Launch("/bin/sh -c 'test -f /etc/nixos/base.nix || sudo mv /etc/nixos/configuration.nix /etc/nixos/base.nix'") + $LASTEXITCODE | Should -Be 0 + + # Copy the new config + $this.Launch("sudo cp $($this.GetPath($path)) /etc/nixos/configuration.nix") + $LASTEXITCODE | Should -Be 0 + + # Rebuild + $this.Launch("sudo nixos-rebuild switch") + $LASTEXITCODE | Should -Be 0 + + Write-Host "Config installed successfully" + } + + [void]Shutdown() { + throw "Not implemented" + } + + [void]Uninstall() { + throw "Not implemented" + } +} + +# Emulates a WSL distro using a Docker container (for Linux hosts) +class DockerDistro : Distro { + static [string]$hostMount = "/mnt/c" + static [string]$imageName = "local:nixos-wsl" + + static [bool]$imageCreated = $false + + DockerDistro() { + $tarball = $this.FindTarball() + + if (!([DockerDistro]::imageCreated)) { + # Build docker image from the installer tarball + $tmpdir = $(mktemp -d) + Copy-Item $PSScriptRoot/Dockerfile $tmpdir + Copy-Item $tarball $tmpdir + docker build -t $([DockerDistro]::imageName) $tmpdir | Write-Host + Remove-Item $tmpdir -Recurse -Force + + [DockerDistro]::imageCreated = $true + } + + $this.id = [guid]::NewGuid().ToString() + + docker run -di --privileged --volume "/:$([DockerDistro]::hostMount)" --name $this.id $([DockerDistro]::imageName) "/bin/sh" | Out-Null + if ($LASTEXITCODE -ne 0) { + throw "Failed to launch container" + } + } + + [Array]Launch([string]$command) { + $result = @() + docker exec -t $this.id /nix/nixos-wsl/entrypoint -c $command | Tee-Object -Variable result | Write-Host + return $result + } + + [string]GetPath([string]$path) { + return [DockerDistro]::hostMount + $(readlink -f $path) + } + + [void]Shutdown() { + docker restart $this.id # Restart instead of stop so that exec can still be used + if ($LASTEXITCODE -ne 0) { + throw "Failed to stop container" + } + } + + [void]Uninstall() { + docker rm -f $this.id + if ($LASTEXITCODE -ne 0) { + throw "Failed to remove container" + } + } +} + +# A real WSL distro (for Windows hosts) +class WslDistro : Distro { + [string]$tempdir + + WslDistro() { + $tarball = $this.FindTarball() + + $this.id = [guid]::NewGuid().ToString() + $this.tempdir = Join-Path $([System.IO.Path]::GetTempPath()) $this.id + New-Item -ItemType Directory $this.tempdir + + & wsl.exe --import $this.id $this.tempdir $tarball --version 2 | Write-Host + if ($LASTEXITCODE -ne 0) { + throw "Failed to import distro" + } + & wsl.exe --list | Should -Contain $this.id + } + + [Array]Launch([string]$command) { + $result = @() + & wsl.exe (@("-d", "$($this.id)") + $command.Split()) | Tee-Object -Variable result | Write-Host + return $result + } + + [string]GetPath([string]$path) { + return $this.Launch("wslpath $($path -replace "\\", "/")") | Select-Object -Last 1 + } + + [void]Shutdown() { + & wsl.exe -t $this.id + if ($LASTEXITCODE -ne 0) { + throw "Failed to stop distro" + } + } + + [void]Uninstall() { + & wsl.exe --unregister $this.id | Write-Host + if ($LASTEXITCODE -ne 0) { + throw "Failed to unregister distro" + } + Remove-Item $this.tempdir -Recurse -Force + } +} + +# Auto-select the implementation to use +function Install-Distro() { + if ($IsWindows) { + return [WslDistro]::new() + } + else { + return [DockerDistro]::new() + } +} diff --git a/tests/shells.Tests.ps1 b/tests/shells.Tests.ps1 new file mode 100644 index 00000000..fda3295a --- /dev/null +++ b/tests/shells.Tests.ps1 @@ -0,0 +1,49 @@ +BeforeAll { + . $PSScriptRoot/lib/lib.ps1 +} + +Describe "Shells" { + BeforeAll { + $distro = Install-Distro + + function Add-ShellTest([string]$package, [string]$executable) { + $temp = New-TemporaryFile + @" +{ pkgs, config, ... }: +{ +imports = [ ./base.nix ]; + +users.users.`${config.wsl.defaultUser}.shell = pkgs.$package; +} +"@ > $temp + $distro.InstallConfig($temp) + Remove-Item $temp + $distro.Launch("echo `$SHELL") | Select-Object -Last 1 | Should -BeExactly "/run/current-system/sw/bin/$executable" + $LASTEXITCODE | Should -Be 0 + } + } + + It "should be possible to use zsh" { + Add-ShellTest "zsh" "zsh" + } + It "should be possible to use fish" { + Add-ShellTest "fish" "fish" + } + It "should be possible to use PowerShell" { + Add-ShellTest "powershell" "pwsh" + } + It "should be possible to use nushell" { + Add-ShellTest "nushell" "nu" + } + It "should be possible to use xonsh" { + Add-ShellTest "xonsh" "xonsh" + } + # Do bash last so every shell was used to run InstallConfig + It "should be possible to use bash" { + Add-ShellTest "bashInteractive" "bash" + } + + AfterAll { + $distro.Uninstall() + } +} diff --git a/tests/systemd-user.Tests.ps1 b/tests/systemd-user.Tests.ps1 new file mode 100644 index 00000000..63eabd96 --- /dev/null +++ b/tests/systemd-user.Tests.ps1 @@ -0,0 +1,18 @@ +BeforeAll { + . $PSScriptRoot/lib/lib.ps1 +} + +Describe "Systemd User Daemon" { + BeforeAll { + $distro = Install-Distro + } + + It "should be possible to connect to the user daemon" { + $distro.Launch("systemctl --user status --no-pager") + $LASTEXITCODE | Should -Be 0 + } + + AfterAll { + $distro.Uninstall() + } +}