diff --git a/nix-on-droid/nix-on-droid.sh b/nix-on-droid/nix-on-droid.sh index 54ff4b7..51c74f9 100644 --- a/nix-on-droid/nix-on-droid.sh +++ b/nix-on-droid/nix-on-droid.sh @@ -1,6 +1,6 @@ #!@bash@/bin/bash -# Copyright (c) 2019-2020, see AUTHORS. Licensed under MIT License, see LICENSE. +# Copyright (c) 2019-2021, see AUTHORS. Licensed under MIT License, see LICENSE. PATH=@coreutils@/bin:@nix@/bin:${PATH:+:}$PATH @@ -73,6 +73,13 @@ function doHelp() { echo " Switch generation and activate configuration" } +function doOnDeviceTest() { + # This is for maintainer convenience only, see tests/on-device/.run.sh + nix-channel --update nix-on-droid + exec "$(nix-instantiate --eval --expr \ + "")" +} + function doSwitch() { echo "Building activation package..." nix build \ @@ -114,7 +121,7 @@ while [[ $# -gt 0 ]]; do opt="$1" shift case $opt in - build|generations|help|rollback|switch|switch-generation) + build|generations|help|rollback|switch|switch-generation|on-device-test) COMMAND="$opt" ;; -f|--file) @@ -178,6 +185,9 @@ case $COMMAND in help) doHelp ;; + on-device-test) + doOnDeviceTest + ;; rollback) if [[ $(readlink $PROFILE_DIRECTORY) =~ ^nix-on-droid-([0-9]+)-link$ ]]; then doSwitchGeneration $((${BASH_REMATCH[1]} - 1)) diff --git a/tests/on-device/.run.sh b/tests/on-device/.run.sh new file mode 100755 index 0000000..246ca0c --- /dev/null +++ b/tests/on-device/.run.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env nix-shell +#! nix-shell -i bash -p bats + +# Copyright (c) 2019-2021, see AUTHORS. Licensed under MIT License, see LICENSE. + +set -ueo pipefail + +SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" +SELF_TEST_DIR="$HOME/.cache/nix-on-droid-self-test" +CONFIRMATION_FILE="$SELF_TEST_DIR/confirmation-granted" +mkdir -p "$SELF_TEST_DIR" + +if [[ ! -e "$CONFIRMATION_FILE" ]]; then + echo 'These semi-automated tests are destructive!' + echo 'They are meant to be executed by maintainers on a clean install.' + echo 'Proceeding will wreck your installation.' + echo 'Do you still wish to proceed?' + echo -n '(type "I do" to proceed, anything else to abort) > ' + read -r CONFIRMATION + if [[ "$CONFIRMATION" != 'I do' ]]; then echo 'Cool, aborting.'; exit 7; fi + touch "$CONFIRMATION_FILE" +fi + +if [[ ! -d ~/.config.bak ]]; then + mv ~/.config ~/.config.bak + cp -r ~/.config.bak ~/.config +fi + +bats "${SCRIPT_DIR}" --verbose-run --timing + +rm -rf ~/.config +mv ~/.config.bak ~/.config diff --git a/tests/on-device/config-default.bats b/tests/on-device/config-default.bats new file mode 100644 index 0000000..5565078 --- /dev/null +++ b/tests/on-device/config-default.bats @@ -0,0 +1,7 @@ +# Copyright (c) 2019-2021, see AUTHORS. Licensed under MIT License, see LICENSE. + +load lib + +@test 'default config can be switched into' { + switch_to_default_config +} diff --git a/tests/on-device/config-flake-h-m.bats b/tests/on-device/config-flake-h-m.bats new file mode 100644 index 0000000..1085488 --- /dev/null +++ b/tests/on-device/config-flake-h-m.bats @@ -0,0 +1,39 @@ +# Copyright (c) 2019-2021, see AUTHORS. Licensed under MIT License, see LICENSE. + +load lib + +@test 'flake + h-m + #134 overlays case work' { + # start from a known baseline + switch_to_default_config + assert_command vi + assert_no_command dash zsh + + # set up / build / activate the configuration + cat "$ON_DEVICE_TESTS_DIR/config-flake-h-m.cfg.nix" \ + > ~/.config/nixpkgs/nix-on-droid.nix + nix-shell -p gnused --run \ + "sed 's|<>|$FLAKE_URL|g' \ + < '$ON_DEVICE_TESTS_DIR/config-flake-h-m.flake.nix' \ + > ~/.config/nixpkgs/flake.nix" + pushd ~/.config/nixpkgs + nix-shell -p nixFlakes --run \ + 'nix build \ + --extra-experimental-features nix-command \ + --extra-experimental-features flakes \ + --impure .#nix-on-droid' + result/activate + popd + + # test presence of several crucial commands + assert_command nix-on-droid nix-shell bash + + # test that both zsh (system) and dash (user) have appeared in $PATH + assert_command dash zsh + assert_no_command vi + + # check that reverting works too + rm -f ~/.config/nix/nix.conf ~/.config/nixpkgs/flake.nix + switch_to_default_config + assert_command vi + assert_no_command dash zsh +} diff --git a/tests/on-device/config-flake-h-m.cfg.nix b/tests/on-device/config-flake-h-m.cfg.nix new file mode 100644 index 0000000..2785fb0 --- /dev/null +++ b/tests/on-device/config-flake-h-m.cfg.nix @@ -0,0 +1,18 @@ +{ pkgs, config, ... }: + +{ + system.stateVersion = "21.11"; + + # no nixpkgs.overlays defined + environment.packages = with pkgs; [ zsh ]; + + home-manager.config = + { pkgs, ... }: + { + home.stateVersion = "21.11"; + + nixpkgs.overlays = config.nixpkgs.overlays; + home.packages = with pkgs; [ dash ]; + }; + nixpkgs.overlays = []; +} diff --git a/tests/on-device/config-flake-h-m.flake.nix b/tests/on-device/config-flake-h-m.flake.nix new file mode 100644 index 0000000..a1fc04c --- /dev/null +++ b/tests/on-device/config-flake-h-m.flake.nix @@ -0,0 +1,19 @@ +{ + description = "nix-on-droid configuration"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/release-21.11"; + home-manager.url = "github:nix-community/home-manager/release-21.11"; + nix-on-droid.url = "<>"; + + home-manager.inputs.nixpkgs.follows = "nixpkgs"; + nix-on-droid.inputs.nixpkgs.follows = "nixpkgs"; + nix-on-droid.inputs.home-manager.follows = "home-manager"; + }; + + outputs = { nix-on-droid, ... }: { + nix-on-droid = (nix-on-droid.lib.aarch64-linux.nix-on-droid { + config = /data/data/com.termux.nix/files/home/.config/nixpkgs/nix-on-droid.nix; + }).activationPackage; + }; +} diff --git a/tests/on-device/config-flake.bats b/tests/on-device/config-flake.bats new file mode 100644 index 0000000..bdb6b4c --- /dev/null +++ b/tests/on-device/config-flake.bats @@ -0,0 +1,43 @@ +# Copyright (c) 2019-2021, see AUTHORS. Licensed under MIT License, see LICENSE. + +load lib + +@test 'flake example works' { + # start from a known baseline + switch_to_default_config + assert_command vi + assert_no_command dash unzip + + nix-shell -p gnused --run \ + "sed \ + -e s/vim/nano/ \ + -e s/#unzip/unzip/ \ + < '$CHANNEL_DIR/modules/environment/login/nix-on-droid.nix.default' \ + > ~/.config/nixpkgs/nix-on-droid.nix" + + nix-shell -p gnused --run \ + "sed 's|<>|$FLAKE_URL|g' \ + < '$ON_DEVICE_TESTS_DIR/config-flake.nix' \ + > ~/.config/nixpkgs/flake.nix" + + # this is more cumbersome than options, + # but this is what we recommend to users, so taking the hard way + echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf + pushd ~/.config/nixpkgs + nix-shell -p nixFlakes --run 'nix build .#nix-on-droid --impure' + result/activate + popd + + # test presence of several crucial commands + assert_command nix-on-droid nix-shell bash + + # test that nano has replaced vi and unzip has appeared in $PATH + assert_command nano unzip + assert_no_command vi + + # check that reverting works too + rm -f ~/.config/nix/nix.conf ~/.config/nixpkgs/flake.nix + switch_to_default_config + assert_command vi + assert_no_command dash unzip +} diff --git a/tests/on-device/config-flake.nix b/tests/on-device/config-flake.nix new file mode 100644 index 0000000..357b720 --- /dev/null +++ b/tests/on-device/config-flake.nix @@ -0,0 +1,15 @@ +{ + description = "nix-on-droid configuration"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/release-21.11"; + nix-on-droid.url = "<>"; + nix-on-droid.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = { nix-on-droid, ... }: { + nix-on-droid = (nix-on-droid.lib.aarch64-linux.nix-on-droid { + config = /data/data/com.termux.nix/files/home/.config/nixpkgs/nix-on-droid.nix; + }).activationPackage; + }; +} diff --git a/tests/on-device/config-h-m.bats b/tests/on-device/config-h-m.bats new file mode 100644 index 0000000..d76e393 --- /dev/null +++ b/tests/on-device/config-h-m.bats @@ -0,0 +1,34 @@ +# Copyright (c) 2019-2021, see AUTHORS. Licensed under MIT License, see LICENSE. + +load lib + +@test 'using home-manager works' { + # start from a known baseline + switch_to_default_config + assert_command vi + assert_no_command dash + ! [[ -e ~/.config/example ]] + + nix-channel --add https://github.com/rycee/home-manager/archive/release-21.11.tar.gz home-manager + nix-channel --update + cp "$ON_DEVICE_TESTS_DIR/config-h-m.nix" ~/.config/nixpkgs/nix-on-droid.nix + nix-on-droid switch + + # test config file + [[ -e ~/.config/example ]] + [[ "$(cat ~/.config/example)" == 'example config' ]] + + # test common commands presence + assert_command nix-on-droid nix-shell bash + + # test that vi has disappeared + assert_no_command vi + + # test dash has appeared and works + assert_command dash + run dash -c 'echo success; exit 42' + [[ "$output" == success ]] + [[ "$status" == 42 ]] + + switch_to_default_config +} diff --git a/tests/on-device/config-h-m.nix b/tests/on-device/config-h-m.nix new file mode 100644 index 0000000..3da5cf1 --- /dev/null +++ b/tests/on-device/config-h-m.nix @@ -0,0 +1,18 @@ +{ pkgs, config, ... }: + +{ + system.stateVersion = "21.11"; + + home-manager.config = + { pkgs, lib, ... }: + { + home.stateVersion = "21.11"; + nixpkgs = { inherit (config.nixpkgs) overlays; }; + + # example config + xdg.configFile.example.text = "example config"; + + # example package + home.packages = [ pkgs.dash ]; + }; +} diff --git a/tests/on-device/gnumake.bats b/tests/on-device/gnumake.bats new file mode 100644 index 0000000..97dd946 --- /dev/null +++ b/tests/on-device/gnumake.bats @@ -0,0 +1,14 @@ +# Copyright (c) 2019-2021, see AUTHORS. Licensed under MIT License, see LICENSE. + +@test 'GNU Make is functional' { + TEMPDIR=/tmp/.tmp-gnumake.$$ + mkdir -p "$TEMPDIR" + echo -e 'x:\n\techo desired output > x' > "$TEMPDIR/Makefile" + nix-shell -p gnumake --run "make -C $TEMPDIR x" + [[ -e "$TEMPDIR/x" ]] + [[ "$(cat "$TEMPDIR/x")" == 'desired output' ]] +} + +teardown() { + rm -r "$TEMPDIR" +} diff --git a/tests/on-device/hello.bats b/tests/on-device/hello.bats new file mode 100644 index 0000000..033aefc --- /dev/null +++ b/tests/on-device/hello.bats @@ -0,0 +1,7 @@ +# Copyright (c) 2019-2021, see AUTHORS. Licensed under MIT License, see LICENSE. + +@test 'GNU Hello is functional' { + out=$(nix-shell -p hello --run hello) + [[ "$out" == 'Hello, world!' ]] + [[ "$status" -eq 0 ]] +} diff --git a/tests/on-device/lib.bash b/tests/on-device/lib.bash new file mode 100644 index 0000000..64dd54a --- /dev/null +++ b/tests/on-device/lib.bash @@ -0,0 +1,47 @@ +# Copyright (c) 2019-2021, see AUTHORS. Licensed under MIT License, see LICENSE. + +setup() { + if [[ -z "$ON_DEVICE_TESTS_SETUP" ]]; then + CHANNEL_DIR="$(nix-instantiate --eval --expr '')" + ON_DEVICE_TESTS_DIR="$CHANNEL_DIR/tests/on-device" + + while read -r channel_line; do + if [[ "$channel_line" =~ nix-on-droid[[:space:]]+(.*) ]]; then + CHANNEL_URL=${BASH_REMATCH[1]} + fi + done < <(nix-channel --list) + echo "parsing detected channel url: $CHANNEL_URL" + [[ "$CHANNEL_URL" =~ https://github.com/(.+)/(.+)/archive/(.+)\.tar\.gz ]] + REPO_USER=${BASH_REMATCH[1]} + REPO_NAME=${BASH_REMATCH[2]} + REPO_BRANCH=${BASH_REMATCH[3]} + FLAKE_URL=github:$REPO_USER/$REPO_NAME/$REPO_BRANCH + echo "autodetected flake url: $FLAKE_URL" + + ON_DEVICE_TESTS_SETUP=1 + fi +} + +assert_command() { + for cmd_name; do + command -v "$cmd_name" + done +} + +assert_no_command() { + for cmd_name; do + run command -v "$cmd_name" + [[ "$status" == 1 ]] + done +} + +switch_to_default_config() { + rm -rf ~/.config/nix ~/.config/nixpkgs + mkdir -p ~/.config/nix ~/.config/nixpkgs + cat "$CHANNEL_DIR/modules/environment/login/nix-on-droid.nix.default" \ + > ~/.config/nixpkgs/nix-on-droid.nix + nix-on-droid switch + + assert_command nix-on-droid nix-shell bash vi find + assert_no_command dash xonsh zsh +}