test-gitpages-mirror-git.sh (4165B)
1 #!/bin/sh 2 # 3 # Copyright (c) 2026 Fred Großkopf 4 # 5 # Permission to use, copy, modify, and/or distribute this software for any 6 # purpose with or without fee is hereby granted, provided that the above 7 # copyright notice and this permission notice appear in all copies. 8 # 9 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 17 set -eu 18 19 SCRIPT_NAME="./gitpages-mirror-git.sh" 20 21 check_script() { 22 if [ ! -x "$SCRIPT_NAME" ]; then 23 printf 'ERROR: %s not found or not executable\n' "$SCRIPT_NAME" >&2 24 printf 'Please run:\n chmod +x git-sync.sh\n ./test-git-sync.sh\n' >&2 25 exit 1 26 fi 27 } 28 29 TEST_BASE="" 30 cleanup() { 31 [ -n "$TEST_BASE" ] && rm -rf "$TEST_BASE" 32 } 33 trap cleanup EXIT INT TERM 34 35 error() { 36 printf 'FAIL: %s\n' "$1" >&2 37 exit 1 38 } 39 40 success() { 41 printf 'PASS: %s\n' "$1" 42 } 43 44 setup() { 45 TEST_BASE=$(mktemp -d) || error "Failed to create temp dir" 46 SRC_DIR="$TEST_BASE/src" 47 DST_DIR="$TEST_BASE/dst" 48 mkdir -p "$SRC_DIR" "$DST_DIR" 49 } 50 51 assert_fails() { 52 test_num="$1" 53 test_desc="$2" 54 shift 2 55 printf '=== Test %s: %s ===\n' "$test_num" "$test_desc" 56 "$@" && error "Should fail" || success "Rejects $test_desc" 57 } 58 59 assert_repo_copied() { 60 repo="$1" 61 test_name="$2" 62 [ -d "$repo" ] && success "$test_name" || error "$test_name" 63 } 64 65 assert_repo_skipped() { 66 repo="$1" 67 test_name="$2" 68 [ ! -d "$repo" ] && success "$test_name" || error "$test_name" 69 } 70 71 assert_bare_repo() { 72 repo="$1" 73 test_name="$2" 74 git --git-dir="$repo" rev-parse --is-bare-repository >/dev/null 2>&1 || error "$test_name" 75 } 76 77 assert_server_info() { 78 repo="$1" 79 test_name="$2" 80 [ -f "$repo/info/refs" ] && success "$test_name" || error "$test_name" 81 } 82 83 test_args() { 84 assert_fails 1 "Wrong number of arguments" "$SCRIPT_NAME" "$SRC_DIR" "$DST_DIR" extra_arg 85 } 86 87 test_bad_src_file() { 88 bad_src="$TEST_BASE/bad_src" 89 touch "$bad_src" 90 assert_fails 2 "Source is file" "$SCRIPT_NAME" "$bad_src" "$DST_DIR" 91 } 92 93 test_bad_dst() { 94 bad_dst="$TEST_BASE/bad_dst" 95 touch "$bad_dst" && chmod 444 "$bad_dst" 96 assert_fails 3 "Destination not writable" "$SCRIPT_NAME" "$SRC_DIR" "$bad_dst" 97 } 98 99 test_empty_src() { 100 rm -rf "$SRC_DIR"/* 101 assert_fails 4 "Empty source directory" "$SCRIPT_NAME" "$SRC_DIR" "$DST_DIR" 102 } 103 104 test_full_sync() { 105 printf '=== Test 5: Full sync ===\n' 106 mkdir -p "$SRC_DIR/myrepo.git" "$SRC_DIR/otherrepo" 107 (cd "$SRC_DIR/myrepo.git" && git init --bare . >/dev/null 2>&1) 108 (cd "$SRC_DIR/otherrepo" && git init >/dev/null 2>&1) 109 110 "$SCRIPT_NAME" "$SRC_DIR" "$DST_DIR" 111 112 assert_repo_copied "$DST_DIR/myrepo.git" "Bare repo copied" 113 assert_repo_skipped "$DST_DIR/otherrepo" "Skipped non-bare" 114 assert_bare_repo "$DST_DIR/myrepo.git" "Destination is bare" 115 assert_server_info "$DST_DIR/myrepo.git" "update-server-info ran" 116 } 117 118 test_single_repo() { 119 printf '=== Test 6: Single repo ===\n' 120 mkdir -p "$SRC_DIR/myrepo.git" 121 (cd "$SRC_DIR/myrepo.git" && git init --bare . >/dev/null 2>&1) 122 123 "$SCRIPT_NAME" "$SRC_DIR/myrepo.git" "$DST_DIR" 124 125 assert_repo_copied "$DST_DIR/myrepo.git" "Single repo copied" 126 assert_bare_repo "$DST_DIR/myrepo.git" "Single mode: bare repo" 127 assert_server_info "$DST_DIR/myrepo.git" "Single mode: update-server-info ran" 128 } 129 130 test_root_protection() { 131 assert_fails 7 "Root protection" "$SCRIPT_NAME" "$SRC_DIR" "/" 132 } 133 134 test_non_repo_dir() { 135 assert_fails 8 "Non-repo directory" "$SCRIPT_NAME" "$TEST_BASE" "$DST_DIR" 136 } 137 138 main() { 139 printf 'Testing %s\n' "$SCRIPT_NAME" 140 check_script 141 setup 142 143 test_args 144 test_bad_src_file 145 test_bad_dst 146 test_empty_src 147 test_full_sync 148 test_single_repo 149 test_root_protection 150 test_non_repo_dir 151 152 printf '\nALL TESTS PASSED!\n' 153 printf 'Test environment cleaned up.\n' 154 } 155 156 [ "${0##*/}" = "test-gitpages-mirror-git.sh" ] && main "$@"