Initial version of testing + Nix flake

This commit is contained in:
Andrew Dunham 2021-07-11 15:27:30 -04:00
parent 68af0ac537
commit d7586c4071
6 changed files with 1628 additions and 40 deletions

View file

@ -1,6 +1,19 @@
all:
lint:
@find apply push lib -type f -not -iname '*.*' | xargs shellcheck -s bash
@shellcheck -s dash run
@echo -e "\033[032mOK\033[0m"
@find apply push -type f -not -iname '*.*' | xargs shellcheck -s bash
@find run lib -type f -not -iname '*.*' | xargs shellcheck -s dash
@printf "\033[032mLINT OK\033[0m\n\n"
test: lint test-dash test-bash
test-ash:
@cd test && ash ./lib_test.sh
test-dash:
@cd test && dash ./lib_test.sh
test-bash:
@cd test && bash ./lib_test.sh
.PHONY: lint test test-dash test-bash

42
flake.lock generated Normal file
View file

@ -0,0 +1,42 @@
{
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1623875721,
"narHash": "sha256-A8BU7bjS5GirpAUv4QA+QnJ4CceLHkcXdRp4xITDB0s=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "f7e004a55b120c02ecb6219596820fcd32ca8772",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1625874246,
"narHash": "sha256-7cGgcysIXz/j/lRpJn7cNJjf0+k7sQ5EuGn62252Svw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "45fc7d4a35c5343e58541a7847f6415654ccbb37",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

52
flake.nix Normal file
View file

@ -0,0 +1,52 @@
{
description = "Simple zero-dependency tool to provision *nix machines";
inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachSystem [ "x86_64-linux" ] (system:
let pkgs = nixpkgs.legacyPackages.${system}; in
rec {
devShell = pkgs.mkShell {
buildInputs = with pkgs; [
dash
gnumake
shellcheck
];
};
checks = let
commonDeps = with pkgs; [ gnumake shellcheck ];
in {
bash = pkgs.runCommand "lint" {
src = ./.;
nativeBuildInputs = commonDeps ++ (with pkgs; [ bash ]);
} ''
export SHELL="${pkgs.bash}/bin/bash"
make -C "$src" test-bash
touch "$out"
'';
dash = pkgs.runCommand "lint" {
src = ./.;
nativeBuildInputs = commonDeps ++ (with pkgs; [ dash ]);
} ''
export SHELL="${pkgs.dash}/bin/dash"
make -C "$src" test-dash
touch "$out"
'';
busybox = pkgs.runCommand "lint" {
src = ./.;
nativeBuildInputs = commonDeps ++ (with pkgs; [ busybox ]);
} ''
export SHELL="${pkgs.busybox}/bin/ash"
make -C "$src" test-ash
touch "$out"
'';
};
}
);
}

70
lib
View file

@ -1,46 +1,42 @@
# shellcheck shell=bash
# shellcheck shell=dash
# vim: ft=sh
# Support functions
# substitute replaces all occurances of one string with another in the provided
# file, writing to the specified output file.
substitute() {
local input="$1"
local output="$2"
function ssh_version() {
ssh -V 2>&1 | perl -ne '/^OpenSSH_(\d+\.\d+)/ and print "$1";'
shift 2
# TODO: real parsing
local search="$1"
local replace="$2"
#-v RS="$(printf "\0")" \
awk \
-v srch="$search" \
-v repl="$replace" \
-v RS="" \
-v ORS="" \
'{ gsub(srch, repl, $0); print $0 }' \
< "$input" > "$output"
}
function ssh_back() {
local remote="$1"
local timeout=60
local port=0
# substituteInPlace works like substitute but operates in-place on the provided
# file
substituteInPlace() {
local fpath="$1"
shift
case $(ssh_version) in
5.*)
port=55555
# shellcheck disable=SC2029
ssh -f -R "$port":127.0.0.1:22 "$remote" sleep "$timeout" >/dev/null 2>&1
;;
*)
# shellcheck disable=SC2029
port="$(ssh -f -R 0:127.0.0.1:22 "$remote" sleep "$timeout" 2>&1 >/dev/null | head -1 | perl -ne '/Allocated port (\d+)/ and print "$1"')"
;;
esac
local tmpfile
tmpfile="$(mktemp)"
if ! substitute "$fpath" "$tmpfile" "$@"; then
rm "$tmpfile"
return $?
fi
local args="-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p $port"
# shellcheck disable=SC2029
[[ -n "$port" ]] && ssh -A "$remote" "SSH_BACK_PORT=$port; SSH_BACK_USER=$USER; SSH_BACK_ARGS='$args'; $*" 2> >(grep -v "Permanently added")
# Overwrite now that we've succeeded
mv "$tmpfile" "$fpath"
}
# Fallback functions
if ! which systemctl >/dev/null; then
function systemctl() {
case "$1" in
start|stop|restart|reload)
service "$2" "$1"
;;
*)
false
;;
esac
}
fi

69
test/lib_test.sh Executable file
View file

@ -0,0 +1,69 @@
#!/bin/sh
# shellcheck shell=dash
# Load code to be tested
. ../lib
oneTimeSetUp() {
printf "[INFO] Current shell is: %s\n" "$(cat /proc/$$/cmdline | tr '\0' '\n' | head -n1)"
printf "[INFO] Utility paths:\n"
for util in awk sed grep; do
printf "%8s: %s\n" "$util" "$(which "$util")"
done
}
setUp() {
TEST_TMPDIR="$(mktemp -d)"
touch "$TEST_TMPDIR/.apply_test_dir"
}
tearDown() {
if test -f "$TEST_TMPDIR/.apply_test_dir"; then
rm -rf "$TEST_TMPDIR"
fi
}
testSubstitute_Basic() {
echo "hello world" > "$TEST_TMPDIR/input.txt"
substitute \
"$TEST_TMPDIR/input.txt" \
"$TEST_TMPDIR/output.txt" \
"hello" "goodbye"
assertEquals "goodbye world" "$(cat "$TEST_TMPDIR/output.txt")"
}
testSubstitute_Multi() {
echo "hello hello hello" > "$TEST_TMPDIR/input.txt"
substitute \
"$TEST_TMPDIR/input.txt" \
"$TEST_TMPDIR/output.txt" \
"hello" "hi"
assertEquals "hi hi hi" "$(cat "$TEST_TMPDIR/output.txt")"
}
testSubstitute_Multiline() {
printf "hello\nworld\nhello\nworld\n" > "$TEST_TMPDIR/input.txt"
substitute \
"$TEST_TMPDIR/input.txt" \
"$TEST_TMPDIR/output.txt" \
"hello\nworld" "$(printf "greetings\nall")"
assertEquals \
"$(printf "greetings\nall\ngreetings\nall")" \
"$(cat "$TEST_TMPDIR/output.txt")"
}
testSubstituteInPlace() {
echo "hello hello hello" > "$TEST_TMPDIR/sub.txt"
substituteInPlace \
"$TEST_TMPDIR/sub.txt" \
"hello" "hi"
assertEquals "hi hi hi" "$(cat "$TEST_TMPDIR/sub.txt")"
}
# Load shUnit2
. ./shunit2

1416
test/shunit2 Normal file

File diff suppressed because it is too large Load diff