mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 20:07:04 +01:00
phone_focus_mode: split test_adb_common.sh 287 -> 134 + 105
Mirrors the source split in the previous commit: the six tests exercising adb_verify_trusted_identity and adb_forget_trusted_device move to test_adb_trusted.sh, beside the adb_trusted.sh they cover. Shared fixtures go to adb_test_harness.sh (76) -- counters, run_test, the adb() mock, the injection payloads, and the XDG_STATE_HOME redirect into a mktemp dir. That redirect had to travel with the mock: a test file sourcing the library without it writes to live phone state. 10 + 6 = 16, the pre-split count. That sum is the check that matters -- a dropped test or a file that failed to source its fixtures would lower the total while both files still printed success. Also verified both exit 0 explicitly (the summary line prints either way), and that a copy with one assertion replaced by `return 1` still exits 1, so neither file is vacuously green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
This commit is contained in:
parent
466b074dd7
commit
6a019633e5
@ -0,0 +1,51 @@
|
||||
{
|
||||
"intent": "Bring phone_focus_mode/lib/tests/test_adb_common.sh (287 lines) under the repo-wide 250-line cap without losing a single test, completing the adb_common split started in the previous commit.",
|
||||
"scope": [
|
||||
"phone_focus_mode/lib/tests/test_adb_common.sh — reduced to the ten logging, cooldown, lock, sanitiser, root and device-selection tests",
|
||||
"phone_focus_mode/lib/tests/test_adb_trusted.sh — new: the six enrolled-device tests, mirroring the adb_trusted.sh split",
|
||||
"phone_focus_mode/lib/tests/adb_test_harness.sh — new: the shared counters, run_test, TEST_TMPDIR, XDG_STATE_HOME redirect and adb() mock",
|
||||
"Non-goal: adding, deleting or weakening any assertion; all sixteen are carried across verbatim"
|
||||
],
|
||||
"changes": [
|
||||
"Split the sixteen tests along the same seam as the source split in the previous commit: the six that exercise adb_verify_trusted_identity and adb_forget_trusted_device moved to test_adb_trusted.sh, matching adb_trusted.sh, and the other ten stayed.",
|
||||
"Moved the shared fixtures into adb_test_harness.sh, sourced by both files from their own directory. It keeps the XDG_STATE_HOME redirect into a mktemp dir, so neither test file can touch the real ~/.local/state/phone_focus_mode — that redirect had to move as a unit with the mock, since a test file sourcing the library without it would write to live state.",
|
||||
"Both test files keep the original exit convention ([[ FAIL -eq 0 ]] as the last statement), so each fails the shell with a non-zero status rather than merely printing a count.",
|
||||
"The harness keeps the single-quoted injection payloads verbatim, including the comment explaining that expanding $evil or `cmd` there would execute them in the harness and test nothing."
|
||||
],
|
||||
"verification": [
|
||||
{
|
||||
"command": "bash lib/tests/test_adb_common.sh && bash lib/tests/test_adb_trusted.sh",
|
||||
"result": "pass",
|
||||
"evidence": "10 passed / 0 failed and 6 passed / 0 failed. 10 + 6 = 16, exactly the pre-split count, which is the discriminating check for a test split: had a test been dropped or a file failed to source its fixtures, the total would have fallen while both files still reported success."
|
||||
},
|
||||
{
|
||||
"command": "Exit-status check on both files",
|
||||
"result": "pass",
|
||||
"evidence": "Both exit 0. Checked explicitly rather than read off the printed summary, because the summary line prints regardless of outcome."
|
||||
},
|
||||
{
|
||||
"command": "Mutation check: a copy of test_adb_common.sh with one assertion body replaced by `return 1`",
|
||||
"result": "pass",
|
||||
"evidence": "The mutated copy exits 1. This proves the split files are not vacuously green — that the run_test dispatch still reaches the test bodies and a genuine failure still fails the script."
|
||||
},
|
||||
{
|
||||
"command": "pre-commit run --files on all three files",
|
||||
"result": "pass",
|
||||
"evidence": "Every hook passes, including shellcheck with no --severity filter, and the shebang/executable check that rejected the previous commit's first attempt. Zero suppressions added."
|
||||
},
|
||||
{
|
||||
"command": "bash ~/utils/scripts/check_file_length.sh --all",
|
||||
"result": "pass",
|
||||
"evidence": "test_adb_common.sh 134, test_adb_trusted.sh 105, adb_test_harness.sh 76 — no adb file of any kind appears in the over-cap listing now, source or test."
|
||||
}
|
||||
],
|
||||
"risks": [
|
||||
"adb_test_harness.sh carries a shebang and the executable bit to match every sibling in lib/tests/, but it is not a test file — running it directly defines fixtures and exits 0 without asserting anything. Its header comment says so. A future test-runner that globs lib/tests/*.sh would count it as a passing suite.",
|
||||
"The two test files now each source the library independently, so a fixture change has to satisfy both. That is the same tradeoff as the source split and is the reason the harness exists rather than the fixtures being duplicated.",
|
||||
"This package has no CI workflow, so these tests only run when invoked by hand or by the pre-push ci-mirror; nothing runs them on every commit."
|
||||
],
|
||||
"rollback": [
|
||||
"git revert the commit — one edited file and two added files, with no data, config or schema migration.",
|
||||
"After rollback, re-run bash phone_focus_mode/lib/tests/test_adb_common.sh; expect 16 passed, 0 failed from the single file."
|
||||
]
|
||||
}
|
||||
76
phone_focus_mode/lib/tests/adb_test_harness.sh
Executable file
76
phone_focus_mode/lib/tests/adb_test_harness.sh
Executable file
@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env bash
|
||||
# lib/tests/adb_test_harness.sh — shared fixtures for the adb_common test files.
|
||||
# Sourced by test_adb_common.sh and test_adb_trusted.sh; not a test file itself.
|
||||
#
|
||||
# Provides: the PASS/FAIL counters, run_test, a TEST_TMPDIR with an EXIT trap,
|
||||
# an XDG_STATE_HOME redirect so no test touches the real state dir, the adb()
|
||||
# mock, and the two injection payloads the sanitiser is tested against.
|
||||
# Unit tests for adb_common.sh helper functions (no real device needed).
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PASS=0
|
||||
FAIL=0
|
||||
|
||||
_t_pass() {
|
||||
PASS=$((PASS + 1))
|
||||
printf ' OK: %s\n' "$1"
|
||||
}
|
||||
|
||||
_t_fail() {
|
||||
FAIL=$((FAIL + 1))
|
||||
printf ' FAIL: %s\n' "$1"
|
||||
}
|
||||
|
||||
TEST_TMPDIR="$(mktemp -d)"
|
||||
trap 'rm -rf "${TEST_TMPDIR}"' EXIT
|
||||
|
||||
export XDG_STATE_HOME="${TEST_TMPDIR}/state"
|
||||
mkdir -p "${XDG_STATE_HOME}"
|
||||
|
||||
source "${SCRIPT_DIR}/../adb_common.sh"
|
||||
|
||||
ADB_MOCK_MODEL=$'Pixel "7";$(rm -rf /)`danger`\nline2'
|
||||
# Single quotes are the whole point: this is an injection payload that must
|
||||
# reach the code under test LITERALLY. Expanding $evil / `cmd` here would
|
||||
# execute them in the test harness and test nothing.
|
||||
# shellcheck disable=SC2016
|
||||
ADB_MOCK_FINGERPRINT='google/pixel:14/UP1A.231005.007/$evil;`cmd`'
|
||||
|
||||
adb() {
|
||||
if [[ "$#" -eq 1 && "$1" == "devices" ]]; then
|
||||
printf 'List of devices attached\nSERIAL123\tdevice\n'
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$1" == "-s" && "$3" == "shell" && "$4" == "getprop" && "$5" == "ro.product.model" ]]; then
|
||||
printf '%s\r\n' "${ADB_MOCK_MODEL}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$1" == "-s" && "$3" == "shell" && "$4" == "getprop" && "$5" == "ro.build.fingerprint" ]]; then
|
||||
printf '%s\r\n' "${ADB_MOCK_FINGERPRINT}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$1" == "-s" && "$3" == "shell" && "$4" == "su" && "$5" == "--mount-master" && "$6" == "-c" && "$7" == "echo ok" ]]; then
|
||||
printf 'ok\n'
|
||||
return 0
|
||||
fi
|
||||
|
||||
printf 'Unexpected adb invocation:' >&2
|
||||
printf ' %q' "$@" >&2
|
||||
printf '\n' >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
run_test() {
|
||||
local name="$1"
|
||||
shift
|
||||
|
||||
if "$@"; then
|
||||
_t_pass "${name}"
|
||||
else
|
||||
_t_fail "${name}"
|
||||
fi
|
||||
}
|
||||
@ -1,73 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
# Unit tests for adb_common.sh helper functions (no real device needed).
|
||||
# Unit tests for adb_common.sh and adb_locking.sh (no real device needed).
|
||||
# The enrolled-device tests live in test_adb_trusted.sh; both share the
|
||||
# fixtures in adb_test_harness.sh.
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PASS=0
|
||||
FAIL=0
|
||||
|
||||
_t_pass() {
|
||||
PASS=$((PASS + 1))
|
||||
printf ' OK: %s\n' "$1"
|
||||
}
|
||||
|
||||
_t_fail() {
|
||||
FAIL=$((FAIL + 1))
|
||||
printf ' FAIL: %s\n' "$1"
|
||||
}
|
||||
|
||||
TEST_TMPDIR="$(mktemp -d)"
|
||||
trap 'rm -rf "${TEST_TMPDIR}"' EXIT
|
||||
|
||||
export XDG_STATE_HOME="${TEST_TMPDIR}/state"
|
||||
mkdir -p "${XDG_STATE_HOME}"
|
||||
|
||||
source "${SCRIPT_DIR}/../adb_common.sh"
|
||||
|
||||
ADB_MOCK_MODEL=$'Pixel "7";$(rm -rf /)`danger`\nline2'
|
||||
# Single quotes are the whole point: this is an injection payload that must
|
||||
# reach the code under test LITERALLY. Expanding $evil / `cmd` here would
|
||||
# execute them in the test harness and test nothing.
|
||||
# shellcheck disable=SC2016
|
||||
ADB_MOCK_FINGERPRINT='google/pixel:14/UP1A.231005.007/$evil;`cmd`'
|
||||
|
||||
adb() {
|
||||
if [[ "$#" -eq 1 && "$1" == "devices" ]]; then
|
||||
printf 'List of devices attached\nSERIAL123\tdevice\n'
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$1" == "-s" && "$3" == "shell" && "$4" == "getprop" && "$5" == "ro.product.model" ]]; then
|
||||
printf '%s\r\n' "${ADB_MOCK_MODEL}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$1" == "-s" && "$3" == "shell" && "$4" == "getprop" && "$5" == "ro.build.fingerprint" ]]; then
|
||||
printf '%s\r\n' "${ADB_MOCK_FINGERPRINT}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$1" == "-s" && "$3" == "shell" && "$4" == "su" && "$5" == "--mount-master" && "$6" == "-c" && "$7" == "echo ok" ]]; then
|
||||
printf 'ok\n'
|
||||
return 0
|
||||
fi
|
||||
|
||||
printf 'Unexpected adb invocation:' >&2
|
||||
printf ' %q' "$@" >&2
|
||||
printf '\n' >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
run_test() {
|
||||
local name="$1"
|
||||
shift
|
||||
|
||||
if "$@"; then
|
||||
_t_pass "${name}"
|
||||
else
|
||||
_t_fail "${name}"
|
||||
fi
|
||||
}
|
||||
_HARNESS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=adb_test_harness.sh
|
||||
source "${_HARNESS_DIR}/adb_test_harness.sh"
|
||||
|
||||
test_box_does_not_crash() {
|
||||
_box "Test title" "line 1" "line 2" >/dev/null 2>&1
|
||||
@ -180,92 +119,6 @@ EOF
|
||||
return 0
|
||||
}
|
||||
|
||||
test_verify_trusted_identity_accepts_exact_match() {
|
||||
export ADB_SERIAL='SERIAL123'
|
||||
adb_save_trusted_device
|
||||
adb_verify_trusted_identity >/dev/null 2>&1
|
||||
}
|
||||
|
||||
test_verify_trusted_identity_rejects_model_mismatch() {
|
||||
export ADB_SERIAL='SERIAL123'
|
||||
adb_save_trusted_device
|
||||
|
||||
cat >"${ADB_ENROLLED_DEVICE_FILE}" <<'EOF'
|
||||
TRUSTED_SERIAL='SERIAL123'
|
||||
TRUSTED_MODEL='Different Model'
|
||||
TRUSTED_FINGERPRINT='google/pixel:14/UP1A.231005.007/evilcmd'
|
||||
EOF
|
||||
|
||||
if (adb_verify_trusted_identity >/dev/null 2>&1); then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
test_verify_trusted_identity_rejects_fingerprint_mismatch() {
|
||||
export ADB_SERIAL='SERIAL123'
|
||||
adb_save_trusted_device
|
||||
|
||||
cat >"${ADB_ENROLLED_DEVICE_FILE}" <<'EOF'
|
||||
TRUSTED_SERIAL='SERIAL123'
|
||||
TRUSTED_MODEL='Pixel 7rm -rf /dangerline2'
|
||||
TRUSTED_FINGERPRINT='different/fingerprint'
|
||||
EOF
|
||||
|
||||
if (adb_verify_trusted_identity >/dev/null 2>&1); then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
test_verify_trusted_identity_accepts_any_enrolled_device() {
|
||||
# Two phones enrolled from one PC: the second must not evict the first,
|
||||
# which is the whole reason the store is a directory.
|
||||
export ADB_SERIAL='SERIAL_ONE'
|
||||
adb_save_trusted_device
|
||||
export ADB_SERIAL='SERIAL_TWO'
|
||||
adb_save_trusted_device
|
||||
|
||||
adb_verify_trusted_identity >/dev/null 2>&1 || return 1
|
||||
|
||||
export ADB_SERIAL='SERIAL_ONE'
|
||||
adb_verify_trusted_identity >/dev/null 2>&1 || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
test_verify_trusted_identity_rejects_unenrolled_device() {
|
||||
export ADB_SERIAL='SERIAL_ONE'
|
||||
adb_save_trusted_device
|
||||
|
||||
# An unknown serial must still abort, or multi-device support would have
|
||||
# quietly turned the guard off.
|
||||
export ADB_SERIAL='SERIAL_STRANGER'
|
||||
if (adb_verify_trusted_identity >/dev/null 2>&1); then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
test_forget_trusted_device_removes_only_that_record() {
|
||||
export ADB_SERIAL='SERIAL_ONE'
|
||||
adb_save_trusted_device
|
||||
export ADB_SERIAL='SERIAL_TWO'
|
||||
adb_save_trusted_device
|
||||
|
||||
adb_forget_trusted_device 'SERIAL_ONE' >/dev/null 2>&1
|
||||
|
||||
adb_list_trusted_serials | grep -qx 'SERIAL_TWO' || return 1
|
||||
if adb_list_trusted_serials | grep -qx 'SERIAL_ONE'; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
run_test "_box output without crash" test_box_does_not_crash
|
||||
run_test "adb_check_cooldown 0 returns 0 (proceed)" test_check_cooldown_zero_allows
|
||||
run_test "adb_check_cooldown blocks when marker is fresh" test_check_cooldown_blocks_when_marker_fresh
|
||||
@ -276,12 +129,6 @@ run_test "_sanitize_device_string strips dangerous characters" test_sanitize_dev
|
||||
run_test "adb_save_trusted_device sanitizes and safely quotes values" test_save_trusted_device_sanitizes_and_quotes
|
||||
run_test "adb_verify_root succeeds when root shell returns ok" test_verify_root_uses_root_shell
|
||||
run_test "adb_select_device rejects multiple devices even with trusted record" test_select_device_rejects_multiple_devices_even_with_trusted_record
|
||||
run_test "adb_verify_trusted_identity accepts exact saved identity" test_verify_trusted_identity_accepts_exact_match
|
||||
run_test "adb_verify_trusted_identity rejects model mismatch" test_verify_trusted_identity_rejects_model_mismatch
|
||||
run_test "adb_verify_trusted_identity rejects fingerprint mismatch" test_verify_trusted_identity_rejects_fingerprint_mismatch
|
||||
run_test "adb_verify_trusted_identity accepts any enrolled device" test_verify_trusted_identity_accepts_any_enrolled_device
|
||||
run_test "adb_verify_trusted_identity rejects unenrolled device" test_verify_trusted_identity_rejects_unenrolled_device
|
||||
run_test "adb_forget_trusted_device removes only that record" test_forget_trusted_device_removes_only_that_record
|
||||
|
||||
printf '\nResults: %d passed, %d failed\n' "${PASS}" "${FAIL}"
|
||||
[[ "${FAIL}" -eq 0 ]]
|
||||
|
||||
105
phone_focus_mode/lib/tests/test_adb_trusted.sh
Executable file
105
phone_focus_mode/lib/tests/test_adb_trusted.sh
Executable file
@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env bash
|
||||
# Unit tests for adb_trusted.sh: verifying a connected phone against the
|
||||
# enrolled-device records, and forgetting one. Shares the fixtures in
|
||||
# adb_test_harness.sh with test_adb_common.sh.
|
||||
set -euo pipefail
|
||||
|
||||
_HARNESS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=adb_test_harness.sh
|
||||
source "${_HARNESS_DIR}/adb_test_harness.sh"
|
||||
|
||||
test_verify_trusted_identity_accepts_exact_match() {
|
||||
export ADB_SERIAL='SERIAL123'
|
||||
adb_save_trusted_device
|
||||
adb_verify_trusted_identity >/dev/null 2>&1
|
||||
}
|
||||
|
||||
test_verify_trusted_identity_rejects_model_mismatch() {
|
||||
export ADB_SERIAL='SERIAL123'
|
||||
adb_save_trusted_device
|
||||
|
||||
cat >"${ADB_ENROLLED_DEVICE_FILE}" <<'EOF'
|
||||
TRUSTED_SERIAL='SERIAL123'
|
||||
TRUSTED_MODEL='Different Model'
|
||||
TRUSTED_FINGERPRINT='google/pixel:14/UP1A.231005.007/evilcmd'
|
||||
EOF
|
||||
|
||||
if (adb_verify_trusted_identity >/dev/null 2>&1); then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
test_verify_trusted_identity_rejects_fingerprint_mismatch() {
|
||||
export ADB_SERIAL='SERIAL123'
|
||||
adb_save_trusted_device
|
||||
|
||||
cat >"${ADB_ENROLLED_DEVICE_FILE}" <<'EOF'
|
||||
TRUSTED_SERIAL='SERIAL123'
|
||||
TRUSTED_MODEL='Pixel 7rm -rf /dangerline2'
|
||||
TRUSTED_FINGERPRINT='different/fingerprint'
|
||||
EOF
|
||||
|
||||
if (adb_verify_trusted_identity >/dev/null 2>&1); then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
test_verify_trusted_identity_accepts_any_enrolled_device() {
|
||||
# Two phones enrolled from one PC: the second must not evict the first,
|
||||
# which is the whole reason the store is a directory.
|
||||
export ADB_SERIAL='SERIAL_ONE'
|
||||
adb_save_trusted_device
|
||||
export ADB_SERIAL='SERIAL_TWO'
|
||||
adb_save_trusted_device
|
||||
|
||||
adb_verify_trusted_identity >/dev/null 2>&1 || return 1
|
||||
|
||||
export ADB_SERIAL='SERIAL_ONE'
|
||||
adb_verify_trusted_identity >/dev/null 2>&1 || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
test_verify_trusted_identity_rejects_unenrolled_device() {
|
||||
export ADB_SERIAL='SERIAL_ONE'
|
||||
adb_save_trusted_device
|
||||
|
||||
# An unknown serial must still abort, or multi-device support would have
|
||||
# quietly turned the guard off.
|
||||
export ADB_SERIAL='SERIAL_STRANGER'
|
||||
if (adb_verify_trusted_identity >/dev/null 2>&1); then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
test_forget_trusted_device_removes_only_that_record() {
|
||||
export ADB_SERIAL='SERIAL_ONE'
|
||||
adb_save_trusted_device
|
||||
export ADB_SERIAL='SERIAL_TWO'
|
||||
adb_save_trusted_device
|
||||
|
||||
adb_forget_trusted_device 'SERIAL_ONE' >/dev/null 2>&1
|
||||
|
||||
adb_list_trusted_serials | grep -qx 'SERIAL_TWO' || return 1
|
||||
if adb_list_trusted_serials | grep -qx 'SERIAL_ONE'; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
run_test "adb_verify_trusted_identity accepts exact saved identity" test_verify_trusted_identity_accepts_exact_match
|
||||
run_test "adb_verify_trusted_identity rejects model mismatch" test_verify_trusted_identity_rejects_model_mismatch
|
||||
run_test "adb_verify_trusted_identity rejects fingerprint mismatch" test_verify_trusted_identity_rejects_fingerprint_mismatch
|
||||
run_test "adb_verify_trusted_identity accepts any enrolled device" test_verify_trusted_identity_accepts_any_enrolled_device
|
||||
run_test "adb_verify_trusted_identity rejects unenrolled device" test_verify_trusted_identity_rejects_unenrolled_device
|
||||
run_test "adb_forget_trusted_device removes only that record" test_forget_trusted_device_removes_only_that_record
|
||||
|
||||
printf '\nResults: %d passed, %d failed\n' "${PASS}" "${FAIL}"
|
||||
[[ "${FAIL}" -eq 0 ]]
|
||||
Loading…
Reference in New Issue
Block a user