From 2517e4b4acb84c27df2106f55ddb1c21ad08288f Mon Sep 17 00:00:00 2001 From: Tim Byrne Date: Sun, 17 Sep 2017 19:06:02 -0500 Subject: [PATCH] Add test-case for exclusions in `.yadm/encrypt` (#86) --- test/007_unit_parse_encrypt.bats | 318 +++++++++++++++++++++++++++++++ test/108_accept_alt.bats | 11 ++ test/109_accept_encryption.bats | 66 +++++-- test/110_accept_perms.bats | 16 +- test/113_accept_jinja_alt.bats | 28 +++ 5 files changed, 415 insertions(+), 24 deletions(-) create mode 100644 test/007_unit_parse_encrypt.bats diff --git a/test/007_unit_parse_encrypt.bats b/test/007_unit_parse_encrypt.bats new file mode 100644 index 0000000..54ee3a9 --- /dev/null +++ b/test/007_unit_parse_encrypt.bats @@ -0,0 +1,318 @@ +load common +load_fixtures + +setup() { + # SC2153 is intentional + # shellcheck disable=SC2153 + make_parents "$T_YADM_ENCRYPT" + make_parents "$T_DIR_WORK" + make_parents "$T_DIR_REPO" + mkdir "$T_DIR_WORK" + git init --shared=0600 --bare "$T_DIR_REPO" >/dev/null 2>&1 + GIT_DIR="$T_DIR_REPO" git config core.bare 'false' + GIT_DIR="$T_DIR_REPO" git config core.worktree "$T_DIR_WORK" + GIT_DIR="$T_DIR_REPO" git config yadm.managed 'true' +} + +teardown() { + destroy_tmp +} + +function run_parse() { + # shellcheck source=/dev/null + YADM_TEST=1 source "$T_YADM" + YADM_ENCRYPT="$T_YADM_ENCRYPT" + export YADM_ENCRYPT + GIT_DIR="$T_DIR_REPO" + export GIT_DIR + + # shellcheck disable=SC2034 + + status=0 + { output=$( parse_encrypt) && parse_encrypt; } || { + status=$? + true + } + + if [ "$1" == "twice" ]; then + GIT_DIR="$T_DIR_REPO" parse_encrypt + fi + + echo -e "OUTPUT:$output\n" + echo "ENCRYPT_INCLUDE_FILES:" + echo " Size: ${#ENCRYPT_INCLUDE_FILES[@]}" + echo " Items: ${ENCRYPT_INCLUDE_FILES[*]}" + echo "EXPECT_INCLUDE:" + echo " Size: ${#EXPECT_INCLUDE[@]}" + echo " Items: ${EXPECT_INCLUDE[*]}" +} + +@test "parse_encrypt (not called)" { + echo " + parse_encrypt() is not called + Array should be 'unparsed' + " + + # shellcheck source=/dev/null + YADM_TEST=1 source "$T_YADM" + + echo "ENCRYPT_INCLUDE_FILES=$ENCRYPT_INCLUDE_FILES" + + [ "$ENCRYPT_INCLUDE_FILES" == "unparsed" ] + +} + +@test "parse_encrypt (short-circuit)" { + echo " + Parsing should not happen more than once + " + + run_parse "twice" + echo "PARSE_ENCRYPT_SHORT: $PARSE_ENCRYPT_SHORT" + + [ "$status" == 0 ] + [ "$output" == "" ] + [[ "$PARSE_ENCRYPT_SHORT" =~ not\ reprocessed ]] +} + +@test "parse_encrypt (file missing)" { + echo " + .yadm/encrypt is empty + Array should be empty + " + + EXPECT_INCLUDE=() + + run_parse + + [ "$status" == 0 ] + [ "$output" == "" ] + [ "${#ENCRYPT_INCLUDE_FILES[@]}" -eq "${#EXPECT_INCLUDE[@]}" ] + [ "${ENCRYPT_INCLUDE_FILES[*]}" == "${EXPECT_INCLUDE[*]}" ] +} + +@test "parse_encrypt (empty file)" { + echo " + .yadm/encrypt is empty + Array should be empty + " + + touch "$T_YADM_ENCRYPT" + + EXPECT_INCLUDE=() + + run_parse + + [ "$status" == 0 ] + [ "$output" == "" ] + [ "${#ENCRYPT_INCLUDE_FILES[@]}" -eq "${#EXPECT_INCLUDE[@]}" ] + [ "${ENCRYPT_INCLUDE_FILES[*]}" == "${EXPECT_INCLUDE[*]}" ] +} + +@test "parse_encrypt (files)" { + echo " + .yadm/encrypt is references present and missing files + Array should be as expected + " + + echo "file1" > "$T_DIR_WORK/file1" + echo "file3" > "$T_DIR_WORK/file3" + echo "file5" > "$T_DIR_WORK/file5" + + { echo "file1" + echo "file2" + echo "file3" + echo "file4" + echo "file5" + } > "$T_YADM_ENCRYPT" + + EXPECT_INCLUDE=("file1" "file3" "file5") + + run_parse + + [ "$status" == 0 ] + [ "$output" == "" ] + [ "${#ENCRYPT_INCLUDE_FILES[@]}" -eq "${#EXPECT_INCLUDE[@]}" ] + [ "${ENCRYPT_INCLUDE_FILES[*]}" == "${EXPECT_INCLUDE[*]}" ] +} + +@test "parse_encrypt (files and dirs)" { + echo " + .yadm/encrypt is references present and missing files + .yadm/encrypt is references present and missing dirs + Array should be as expected + " + + mkdir -p "$T_DIR_WORK/dir1" + mkdir -p "$T_DIR_WORK/dir2" + echo "file1" > "$T_DIR_WORK/file1" + echo "file2" > "$T_DIR_WORK/file2" + echo "a" > "$T_DIR_WORK/dir1/a" + echo "b" > "$T_DIR_WORK/dir1/b" + + { echo "file1" + echo "file2" + echo "file3" + echo "dir1" + echo "dir2" + echo "dir3" + } > "$T_YADM_ENCRYPT" + + EXPECT_INCLUDE=("file1" "file2" "dir1" "dir2") + + run_parse + + [ "$status" == 0 ] + [ "$output" == "" ] + [ "${#ENCRYPT_INCLUDE_FILES[@]}" -eq "${#EXPECT_INCLUDE[@]}" ] + [ "${ENCRYPT_INCLUDE_FILES[*]}" == "${EXPECT_INCLUDE[*]}" ] +} + +@test "parse_encrypt (comments/empty lines)" { + echo " + .yadm/encrypt is references present and missing files + .yadm/encrypt is references present and missing dirs + .yadm/encrypt contains comments / blank lines + Array should be as expected + " + + mkdir -p "$T_DIR_WORK/dir1" + mkdir -p "$T_DIR_WORK/dir2" + echo "file1" > "$T_DIR_WORK/file1" + echo "file2" > "$T_DIR_WORK/file2" + echo "file3" > "$T_DIR_WORK/file3" + echo "a" > "$T_DIR_WORK/dir1/a" + echo "b" > "$T_DIR_WORK/dir1/b" + + { echo "file1" + echo "file2" + echo "#file3" + echo " #file3" + echo "" + echo "dir1" + echo "dir2" + echo "dir3" + } > "$T_YADM_ENCRYPT" + + EXPECT_INCLUDE=("file1" "file2" "dir1" "dir2") + + run_parse + + [ "$status" == 0 ] + [ "$output" == "" ] + [ "${#ENCRYPT_INCLUDE_FILES[@]}" -eq "${#EXPECT_INCLUDE[@]}" ] + [ "${ENCRYPT_INCLUDE_FILES[*]}" == "${EXPECT_INCLUDE[*]}" ] +} + +@test "parse_encrypt (w/spaces)" { + echo " + .yadm/encrypt is references present and missing files + .yadm/encrypt is references present and missing dirs + .yadm/encrypt references contain spaces + Array should be as expected + " + + mkdir -p "$T_DIR_WORK/di r1" + mkdir -p "$T_DIR_WORK/dir2" + echo "file1" > "$T_DIR_WORK/file1" + echo "fi le2" > "$T_DIR_WORK/fi le2" + echo "file3" > "$T_DIR_WORK/file3" + echo "a" > "$T_DIR_WORK/di r1/a" + echo "b" > "$T_DIR_WORK/di r1/b" + + { echo "file1" + echo "fi le2" + echo "#file3" + echo " #file3" + echo "" + echo "di r1" + echo "dir2" + echo "dir3" + } > "$T_YADM_ENCRYPT" + + EXPECT_INCLUDE=("file1" "fi le2" "di r1" "dir2") + + run_parse + + [ "$status" == 0 ] + [ "$output" == "" ] + [ "${#ENCRYPT_INCLUDE_FILES[@]}" -eq "${#EXPECT_INCLUDE[@]}" ] + [ "${ENCRYPT_INCLUDE_FILES[*]}" == "${EXPECT_INCLUDE[*]}" ] +} + +@test "parse_encrypt (wildcards)" { + echo " + .yadm/encrypt contains wildcards + Array should be as expected + " + + mkdir -p "$T_DIR_WORK/di r1" + mkdir -p "$T_DIR_WORK/dir2" + echo "file1" > "$T_DIR_WORK/file1" + echo "fi le2" > "$T_DIR_WORK/fi le2" + echo "file2" > "$T_DIR_WORK/file2" + echo "file3" > "$T_DIR_WORK/file3" + echo "a" > "$T_DIR_WORK/di r1/a" + echo "b" > "$T_DIR_WORK/di r1/b" + + { echo "fi*" + echo "#file3" + echo " #file3" + echo "" + echo "#dir2" + echo "di r1" + echo "dir2" + echo "dir3" + } > "$T_YADM_ENCRYPT" + + EXPECT_INCLUDE=("fi le2" "file1" "file2" "file3" "di r1" "dir2") + + run_parse + + [ "$status" == 0 ] + [ "$output" == "" ] + [ "${#ENCRYPT_INCLUDE_FILES[@]}" -eq "${#EXPECT_INCLUDE[@]}" ] + [ "${ENCRYPT_INCLUDE_FILES[*]}" == "${EXPECT_INCLUDE[*]}" ] +} + +@test "parse_encrypt (excludes)" { + echo " + .yadm/encrypt contains exclusions + Array should be as expected + " + + mkdir -p "$T_DIR_WORK/di r1" + mkdir -p "$T_DIR_WORK/dir2" + mkdir -p "$T_DIR_WORK/dir3" + echo "file1" > "$T_DIR_WORK/file1" + echo "file1.ex" > "$T_DIR_WORK/file1.ex" + echo "fi le2" > "$T_DIR_WORK/fi le2" + echo "file3" > "$T_DIR_WORK/file3" + echo "test" > "$T_DIR_WORK/test" + echo "a.txt" > "$T_DIR_WORK/di r1/a.txt" + echo "b.txt" > "$T_DIR_WORK/di r1/b.txt" + echo "c.inc" > "$T_DIR_WORK/di r1/c.inc" + + { echo "fi*" + echo "#file3" + echo " #file3" + echo "" + echo " #test" + echo "#dir2" + echo "di r1/*" + echo "dir2" + echo "dir3" + echo "dir4" + echo "!*.ex" + echo "!di r1/*.txt" + } > "$T_YADM_ENCRYPT" + + EXPECT_INCLUDE=("fi le2" "file1" "file3" "di r1/c.inc" "dir2" "dir3") + + run_parse + + [ "$status" == 0 ] + [ "$output" == "" ] + [ "${#ENCRYPT_INCLUDE_FILES[@]}" -eq "${#EXPECT_INCLUDE[@]}" ] + [ "${ENCRYPT_INCLUDE_FILES[*]}" == "${EXPECT_INCLUDE[*]}" ] +} diff --git a/test/108_accept_alt.bats b/test/108_accept_alt.bats index c6cecea..5ebf9c8 100644 --- a/test/108_accept_alt.bats +++ b/test/108_accept_alt.bats @@ -4,6 +4,7 @@ status=;output=; #; populated by bats run() IN_REPO=(alt* "dir one") export TEST_TREE_WITH_ALT=1 +EXCLUDED_NAME="excluded-base" function create_encrypt() { for efile in "encrypted-base##" "encrypted-system##$T_SYS" "encrypted-host##$T_SYS.$T_HOST" "encrypted-user##$T_SYS.$T_HOST.$T_USER"; do @@ -13,6 +14,10 @@ function create_encrypt() { echo "dir one/$efile/file1" >> "$T_YADM_ENCRYPT" echo "dir one/$efile/file1" >> "$T_DIR_WORK/dir one/$efile/file1" done + + echo "$EXCLUDED_NAME##" >> "$T_YADM_ENCRYPT" + echo "!$EXCLUDED_NAME##" >> "$T_YADM_ENCRYPT" + echo "$EXCLUDED_NAME##" >> "$T_DIR_WORK/$EXCLUDED_NAME##" } setup() { @@ -130,6 +135,12 @@ function test_alt() { fi fi + if [ -L "$T_DIR_WORK/$EXCLUDED_NAME" ] ; then + echo "ERROR: Found link: $T_DIR_WORK/$EXCLUDED_NAME" + echo "ERROR: Excluded files should not be linked" + return 1 + fi + #; validate link content if [[ "$alt_type" =~ none ]] || [ "$auto_alt" = "false" ]; then #; no link should be present diff --git a/test/109_accept_encryption.bats b/test/109_accept_encryption.bats index 449487b..439f44c 100644 --- a/test/109_accept_encryption.bats +++ b/test/109_accept_encryption.bats @@ -88,6 +88,8 @@ EOF "$T_GPG_PROGRAM" -q -d "$T_YADM_ARCHIVE" | tar t | sort > "$T_TMP/archive_list" fi + excluded="$2" + #; inventory what is expected in the archive ( if cd "$T_DIR_WORK"; then @@ -95,19 +97,23 @@ EOF # (globbing is desired) while IFS='' read -r glob || [ -n "$glob" ]; do if [[ ! $glob =~ ^# && ! $glob =~ ^[[:space:]]*$ ]] ; then - local IFS=$'\n' - for matching_file in $glob; do - if [ -e "$matching_file" ]; then - if [ -d "$matching_file" ]; then - echo "$matching_file/" - for subfile in "$matching_file"/*; do - echo "$subfile" - done - else - echo "$matching_file" + if [[ ! $glob =~ ^!(.+) ]] ; then + local IFS=$'\n' + for matching_file in $glob; do + if [ -e "$matching_file" ]; then + if [ "$matching_file" != "$excluded" ]; then + if [ -d "$matching_file" ]; then + echo "$matching_file/" + for subfile in "$matching_file"/*; do + echo "$subfile" + done + else + echo "$matching_file" + fi + fi fi - fi - done + done + fi fi done < "$T_YADM_ENCRYPT" | sort > "$T_TMP/expected_list" fi @@ -320,6 +326,42 @@ EOF validate_archive symmetric } +@test "Command 'encrypt' (exclusions in YADM_ENCRYPT)" { + echo " + When 'encrypt' command is provided, + and YADM_ENCRYPT is present + Create YADM_ARCHIVE + Report the archive created + Archive should be valid + Exit with 0 + " + + #; add paths with spaces to YADM_ARCHIVE + local original_encrypt + original_encrypt=$(cat "$T_YADM_ENCRYPT") + echo -e ".ssh/*" >> "$T_YADM_ENCRYPT" + echo -e "!.ssh/sec*.pub" >> "$T_YADM_ENCRYPT" + + #; run encrypt + run expect < "$T_YADM_ENCRYPT" + echo -e "#.vimrc\n.tmux.conf\n.hammerspoon/*\n!.tmux.conf" > "$T_YADM_ENCRYPT" #; run perms run "${T_YADM_Y[@]}" perms @@ -89,11 +84,8 @@ function validate_perms() { [ "$status" -eq 0 ] [ "$output" = "" ] - #; this version has no comments in it - echo -e ".hammerspoon/*" > "$T_YADM_ENCRYPT" - #; validate permissions - validate_perms ssh gpg encrypt + validate_perms ssh gpg ".hammerspoon/*" } @test "Command 'perms' (ssh-perms=false)" { diff --git a/test/113_accept_jinja_alt.bats b/test/113_accept_jinja_alt.bats index 8cfe343..0f73af9 100644 --- a/test/113_accept_jinja_alt.bats +++ b/test/113_accept_jinja_alt.bats @@ -9,6 +9,11 @@ export TEST_TREE_WITH_ALT=1 setup() { destroy_tmp build_repo "${IN_REPO[@]}" + echo "excluded-encrypt##yadm.j2" > "$T_YADM_ENCRYPT" + echo "included-encrypt##yadm.j2" >> "$T_YADM_ENCRYPT" + echo "!excluded-encrypt*" >> "$T_YADM_ENCRYPT" + echo "included-encrypt" > "$T_DIR_WORK/included-encrypt##yadm.j2" + echo "excluded-encrypt" > "$T_DIR_WORK/excluded-encrypt##yadm.j2" } @@ -27,6 +32,11 @@ function test_alt() { real_name="alt-jinja" file_content_match="custom_class-custom_system-custom_host-custom_user-${T_DISTRO}" ;; + encrypt) + real_name="included-encrypt" + file_content_match="included-encrypt" + missing_name="excluded-encrypt" + ;; esac if [ "$test_overwrite" = "true" ] ; then @@ -63,6 +73,11 @@ function test_alt() { fi fi + if [ -n "$missing_name" ] && [ -f "$T_DIR_WORK/$missing_name" ]; then + echo "ERROR: File should not have been created '$missing_name'" + return 1 + fi + #; validate link content if [[ "$alt_type" =~ none ]] || [ "$auto_alt" = "false" ]; then #; no real file should be present @@ -173,3 +188,16 @@ function test_alt() { GIT_DIR="$T_DIR_REPO" git config local.class custom_class test_alt 'override_all' 'false' '' } + +@test "Command 'alt' (select jinja within .yadm/encrypt)" { + echo " + When the command 'alt' is provided + and file matches ##yadm.j2 within .yadm/encrypt + and file excluded within .yadm/encrypt + Report jinja template processing + Verify that the correct content is written + Exit with 0 + " + + test_alt 'encrypt' 'false' '' +}