aboutsummaryrefslogtreecommitdiff
path: root/tests/cases/test_functions.sh
blob: cd607abb38eb81309b3545e15cd7461acb2841fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env bash
# ==============================================================================
# Unit Tests for Internal Functions (is_mounted, derive_paths)
# ==============================================================================
# These source the script with RSYNCSHOT_SOURCE_ONLY=1 so the functions are
# defined without running the main flow, then exercise them directly. Each test
# runs the source + assertions in a subshell so the derived globals and config
# variables don't leak into other suites.

source "$(dirname "${BASH_SOURCE[0]}")/../lib/test_helpers.sh"

# ------------------------------------------------------------------------------
# is_mounted: exact mount point matches
# ------------------------------------------------------------------------------
test_is_mounted_exact_match() {
    setup_test_env
    local mounts="$TEST_DIR/mounts"
    cat > "$mounts" <<EOF
/dev/sda1 /media/backup ext4 rw,relatime 0 0
/dev/sdb1 /home ext4 rw,relatime 0 0
EOF
    (
        INSTALLHOME="$TEST_CONFIG_DIR" RSYNCSHOT_SOURCE_ONLY=1 source "$SCRIPT_PATH"
        is_mounted "/media/backup" "$mounts"
    )
    local rc=$?
    teardown_test_env
    assert_exit_code 0 "$rc" "exact mount point should match" || return 1
}

# ------------------------------------------------------------------------------
# is_mounted: a prefix is NOT a match (the substring-grep bug)
# ------------------------------------------------------------------------------
test_is_mounted_no_substring_match() {
    setup_test_env
    local mounts="$TEST_DIR/mounts"
    cat > "$mounts" <<EOF
/dev/sda1 /media/backup2 ext4 rw,relatime 0 0
EOF
    (
        INSTALLHOME="$TEST_CONFIG_DIR" RSYNCSHOT_SOURCE_ONLY=1 source "$SCRIPT_PATH"
        is_mounted "/media/backup" "$mounts"
    )
    local rc=$?
    teardown_test_env
    assert_exit_code 1 "$rc" "/media/backup must NOT match /media/backup2" || return 1
}

# ------------------------------------------------------------------------------
# is_mounted: mount points with spaces (encoded as \040 in /proc/mounts)
# ------------------------------------------------------------------------------
test_is_mounted_handles_spaces() {
    setup_test_env
    local mounts="$TEST_DIR/mounts"
    printf '/dev/sda1 /media/my\\040backup ext4 rw 0 0\n' > "$mounts"
    (
        INSTALLHOME="$TEST_CONFIG_DIR" RSYNCSHOT_SOURCE_ONLY=1 source "$SCRIPT_PATH"
        is_mounted "/media/my backup" "$mounts"
    )
    local rc=$?
    teardown_test_env
    assert_exit_code 0 "$rc" "mount point with spaces should match" || return 1
}

# ------------------------------------------------------------------------------
# is_mounted: target is treated literally, not as a regex
# ------------------------------------------------------------------------------
test_is_mounted_target_is_literal() {
    setup_test_env
    local mounts="$TEST_DIR/mounts"
    cat > "$mounts" <<EOF
/dev/sda1 /media/backup ext4 rw 0 0
EOF
    (
        INSTALLHOME="$TEST_CONFIG_DIR" RSYNCSHOT_SOURCE_ONLY=1 source "$SCRIPT_PATH"
        is_mounted "/media/b.ckup" "$mounts"
    )
    local rc=$?
    teardown_test_env
    assert_exit_code 1 "$rc" "regex metacharacters in target must be literal" || return 1
}

# ------------------------------------------------------------------------------
# derive_paths: remote mode uses bare cp/mv/rm (resolved by remote PATH)
# ------------------------------------------------------------------------------
test_derive_paths_remote() {
    setup_test_env
    cat > "$TEST_CONFIG_DIR/config" <<EOF
REMOTE_HOST="truenas"
REMOTE_PATH="/mnt/vault/Backups"
EOF
    (
        # The script sources the config and runs derive_paths during load.
        INSTALLHOME="$TEST_CONFIG_DIR" RSYNCSHOT_SOURCE_ONLY=1 source "$SCRIPT_PATH"
        assert_equals "remote" "$MODE" "should be remote mode" &&
        assert_equals "truenas:/mnt/vault/Backups/$HOSTNAME" "$DESTINATION" "remote destination" &&
        assert_equals "cp" "$CP" "remote cp is bare (remote PATH resolves it)" &&
        assert_equals "mv" "$MV" "remote mv is bare" &&
        assert_equals "rm" "$RM" "remote rm is bare"
    )
    local rc=$?
    teardown_test_env
    return $rc
}

# ------------------------------------------------------------------------------
# derive_paths: local mode resolves cp/mv/rm to real absolute binaries
# ------------------------------------------------------------------------------
test_derive_paths_local() {
    setup_test_env
    cat > "$TEST_CONFIG_DIR/config" <<EOF
REMOTE_HOST=""
MOUNTDIR="/media/backup"
EOF
    (
        INSTALLHOME="$TEST_CONFIG_DIR" RSYNCSHOT_SOURCE_ONLY=1 source "$SCRIPT_PATH"
        assert_equals "local" "$MODE" "should be local mode" &&
        assert_equals "/media/backup/$HOSTNAME" "$DESTINATION" "local destination" &&
        assert_contains "$CP" "/" "local cp resolves to an absolute path, not a bare name"
    )
    local rc=$?
    teardown_test_env
    return $rc
}

# ------------------------------------------------------------------------------
# Run tests
# ------------------------------------------------------------------------------
run_functions_tests() {
    echo ""
    echo "Running function unit tests..."
    echo "------------------------------------------------------------"

    run_test "is_mounted exact match" test_is_mounted_exact_match
    run_test "is_mounted rejects prefix (no substring match)" test_is_mounted_no_substring_match
    run_test "is_mounted handles spaces" test_is_mounted_handles_spaces
    run_test "is_mounted treats target literally" test_is_mounted_target_is_literal
    run_test "derive_paths remote mode" test_derive_paths_remote
    run_test "derive_paths local mode" test_derive_paths_local
}

# Run if executed directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    run_functions_tests
    print_summary
fi