Files
daily-notification-plugin/test-apps/android-test-app/test-phase3.sh
Matthew Raymer 07ace32982 refactor(test): extract shared helpers into alarm-test-lib.sh
Extract common helper functions from test-phase1.sh, test-phase2.sh,
and test-phase3.sh into a shared library (alarm-test-lib.sh) to reduce
code duplication and improve maintainability.

Changes:
- Create alarm-test-lib.sh with shared configuration, UI helpers, ADB
  helpers, log parsing, and test selection logic
- Refactor all three phase test scripts to source the shared library
- Remove ~200 lines of duplicated code across the three scripts
- Preserve all existing behavior, CLI arguments, and test semantics
- Maintain Phase 1 compatibility (print_* functions, VERIFY_FIRE flag)
- Update all adb references to use $ADB_BIN variable
- Standardize alarm counting to use shared count_alarms() function

Benefits:
- Single source of truth for shared helpers
- Easier maintenance (fix once, benefits all scripts)
- Consistent behavior across all test phases
- No functional changes to test execution or results
2025-11-28 08:53:42 +00:00

419 lines
14 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -euo pipefail
# ========================================
# Phase 3 Testing Script Boot Recovery
# ========================================
# Source shared library
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/alarm-test-lib.sh"
# Phase 3 specific configuration
# Log tags / patterns (matched to actual ReactivationManager logs)
BOOT_SCENARIO_VALUE="BOOT"
NONE_SCENARIO_VALUE="NONE"
# Allow selecting specific tests on the command line (e.g. ./test-phase3.sh 1 3)
SELECTED_TESTS=()
# Phase 3 specific: override extract_scenario_from_logs to handle boot recovery
extract_scenario_from_logs() {
local logs="$1"
local scen
# Looks for "Detected scenario: BOOT" or "Starting boot recovery" format
if echo "$logs" | grep -qi "Starting boot recovery\|boot recovery"; then
echo "$BOOT_SCENARIO_VALUE"
else
# Use shared library function as fallback
scen="$(grep -oE "${SCENARIO_KEY}[A-Z_]+" <<<"$logs" | tail -n1 | sed "s/${SCENARIO_KEY}//" || true)"
echo "$scen"
fi
}
# ------------------------------------------------------------------------------
# TEST 1 Boot with Future Alarms
# ------------------------------------------------------------------------------
test1_boot_future_alarms() {
section "TEST 1: Boot with Future Alarms"
echo "Purpose: Verify alarms are recreated on boot when schedules have future run times."
pause
substep "Step 1: Launch app & check plugin status"
launch_app
ui_prompt "In the app UI, verify plugin status:\n\n ⚙️ Plugin Settings: ✅ Configured\n 🔌 Native Fetcher: ✅ Configured\n\nIf either shows ❌ or 'Not configured', click 'Configure Plugin', wait until both are ✅, then press Enter."
ui_prompt "Now schedule at least one future notification (e.g., click 'Test Notification' to schedule for a few minutes in the future)."
substep "Step 2: Verify alarms are scheduled"
show_alarms
local before_count
before_count="$(count_alarms)"
info "Alarm count before reboot: $before_count"
if [[ "$before_count" -eq 0 ]]; then
warn "No alarms found before reboot; TEST 1 may not be meaningful."
fi
pause
substep "Step 3: Reboot emulator"
warn "The emulator will reboot now. This will take 30-60 seconds."
pause
reboot_emulator
substep "Step 4: Collect boot recovery logs"
info "Collecting recovery logs from boot..."
sleep 2 # Give recovery a moment to complete
local logs
logs="$(get_recovery_logs)"
echo "$logs"
local missed rescheduled verified errors scenario
missed="$(extract_field_from_logs "$logs" "missed")"
rescheduled="$(extract_field_from_logs "$logs" "rescheduled")"
verified="$(extract_field_from_logs "$logs" "verified")"
errors="$(extract_field_from_logs "$logs" "errors")"
scenario="$(extract_scenario_from_logs "$logs")"
echo
info "Parsed recovery summary:"
echo " scenario = ${scenario:-<none>}"
echo " missed = ${missed}"
echo " rescheduled= ${rescheduled}"
echo " verified = ${verified}"
echo " errors = ${errors}"
echo
if [[ "$errors" -gt 0 ]]; then
error "Recovery reported errors>0 (errors=$errors)"
fi
substep "Step 5: Verify alarms were recreated"
show_alarms
local after_count
after_count="$(count_alarms)"
info "Alarm count after boot: $after_count"
if [[ "$scenario" == "$BOOT_SCENARIO_VALUE" && "$rescheduled" -gt 0 ]]; then
ok "TEST 1 PASSED: Boot recovery detected and alarms rescheduled (scenario=$scenario, rescheduled=$rescheduled)."
elif echo "$logs" | grep -qi "Starting boot recovery\|boot recovery"; then
if [[ "$rescheduled" -gt 0 ]]; then
ok "TEST 1 PASSED: Boot recovery ran and alarms rescheduled (rescheduled=$rescheduled)."
else
warn "TEST 1: Boot recovery ran but rescheduled=0. Check implementation or logs."
fi
else
warn "TEST 1: Boot recovery not clearly detected. Review logs and boot receiver implementation."
info "Scenario detected: ${scenario:-<none>}, rescheduled=$rescheduled"
fi
}
# ------------------------------------------------------------------------------
# TEST 2 Boot with Past Alarms
# ------------------------------------------------------------------------------
test2_boot_past_alarms() {
section "TEST 2: Boot with Past Alarms"
echo "Purpose: Verify missed alarms are detected and next occurrence is scheduled on boot."
pause
substep "Step 1: Launch app & ensure plugin configured"
launch_app
ui_prompt "In the app UI, verify plugin status:\n\n ⚙️ Plugin Settings: ✅ Configured\n 🔌 Native Fetcher: ✅ Configured\n\nIf needed, click 'Configure Plugin', then press Enter."
ui_prompt "Click 'Test Notification' to schedule a notification for 2 minutes in the future.\n\nAfter scheduling, we'll wait for the alarm time to pass, then reboot."
substep "Step 2: Wait for alarm time to pass"
info "Waiting 3 minutes for scheduled alarm time to pass..."
warn "You can manually advance system time if needed (requires root/emulator)"
sleep 180 # Wait 3 minutes
substep "Step 3: Verify alarm time has passed"
info "Alarm time should now be in the past"
show_alarms
pause
substep "Step 4: Reboot emulator"
warn "The emulator will reboot now. This will take 30-60 seconds."
pause
reboot_emulator
substep "Step 5: Collect boot recovery logs"
info "Collecting recovery logs from boot..."
sleep 2
local logs
logs="$(get_recovery_logs)"
echo "$logs"
local missed rescheduled verified errors scenario
missed="$(extract_field_from_logs "$logs" "missed")"
rescheduled="$(extract_field_from_logs "$logs" "rescheduled")"
verified="$(extract_field_from_logs "$logs" "verified")"
errors="$(extract_field_from_logs "$logs" "errors")"
scenario="$(extract_scenario_from_logs "$logs")"
echo
info "Parsed recovery summary:"
echo " scenario = ${scenario:-<none>}"
echo " missed = ${missed}"
echo " rescheduled= ${rescheduled}"
echo " verified = ${verified}"
echo " errors = ${errors}"
echo
if [[ "$errors" -gt 0 ]]; then
error "Recovery reported errors>0 (errors=$errors)"
fi
if [[ "$missed" -ge 1 && "$rescheduled" -ge 1 ]]; then
ok "TEST 2 PASSED: Past alarms detected and next occurrence scheduled (missed=$missed, rescheduled=$rescheduled)."
elif [[ "$missed" -ge 1 ]]; then
warn "TEST 2: Past alarms detected (missed=$missed) but rescheduled=$rescheduled. Check reschedule logic."
else
warn "TEST 2: No missed alarms detected. Verify alarm time actually passed before reboot."
fi
}
# ------------------------------------------------------------------------------
# TEST 3 Boot with No Schedules
# ------------------------------------------------------------------------------
test3_boot_no_schedules() {
section "TEST 3: Boot with No Schedules"
echo "Purpose: Verify boot recovery handles empty database gracefully."
pause
substep "Step 1: Uninstall app to clear DB/state"
set +e
$ADB_BIN uninstall "$APP_ID" >/dev/null 2>&1
set -e
ok "App uninstalled (state cleared)"
substep "Step 2: Reinstall app"
if $ADB_BIN install -r "$APK_PATH"; then
ok "App installed"
else
error "Reinstall failed"
exit 1
fi
info "Clearing logcat..."
$ADB_BIN logcat -c
ok "Logs cleared"
pause
substep "Step 3: Reboot emulator WITHOUT scheduling anything"
warn "Do NOT schedule any notifications. The app should have no schedules in the database."
warn "The emulator will reboot now. This will take 30-60 seconds."
pause
reboot_emulator
substep "Step 4: Collect boot recovery logs"
info "Collecting recovery logs from boot..."
sleep 2
local logs
logs="$(get_recovery_logs)"
echo "$logs"
local scenario rescheduled missed
scenario="$(extract_scenario_from_logs "$logs")"
rescheduled="$(extract_field_from_logs "$logs" "rescheduled")"
missed="$(extract_field_from_logs "$logs" "missed")"
echo
info "Parsed recovery summary:"
echo " scenario = ${scenario:-<none>}"
echo " rescheduled= ${rescheduled}"
echo " missed = ${missed}"
echo
if [[ -z "$logs" ]]; then
ok "TEST 3 PASSED: No recovery logs when there are no schedules (safe behavior)."
return
fi
if echo "$logs" | grep -qiE "No schedules found|No schedules present"; then
ok "TEST 3 PASSED: Explicit 'No schedules found' message logged with no rescheduling."
elif [[ "$scenario" == "$NONE_SCENARIO_VALUE" && "$rescheduled" -eq 0 ]]; then
ok "TEST 3 PASSED: NONE scenario detected with no rescheduling."
elif [[ "$rescheduled" -gt 0 ]]; then
warn "TEST 3: rescheduled>0 on first launch / empty DB. Check that boot recovery isn't misfiring."
else
info "TEST 3: Logs present but no rescheduling; review scenario handling to ensure it's explicit about NONE / NO_SCHEDULES."
fi
}
# ------------------------------------------------------------------------------
# TEST 4 Silent Boot Recovery (App Never Opened)
# ------------------------------------------------------------------------------
test4_silent_boot_recovery() {
section "TEST 4: Silent Boot Recovery (App Never Opened)"
echo "Purpose: Verify boot recovery occurs even when the app is never opened after reboot."
pause
substep "Step 1: Launch app & ensure plugin configured"
launch_app
ui_prompt "In the app UI, verify plugin status:\n\n ⚙️ Plugin Settings: ✅ Configured\n 🔌 Native Fetcher: ✅ Configured\n\nIf needed, click 'Configure Plugin', then press Enter."
ui_prompt "Click 'Test Notification' to schedule a notification for a few minutes in the future."
substep "Step 2: Verify alarms are scheduled"
show_alarms
local before_count
before_count="$(count_alarms)"
info "Alarm count before reboot: $before_count"
if [[ "$before_count" -eq 0 ]]; then
warn "No alarms found; TEST 4 may not be meaningful."
fi
pause
substep "Step 3: Reboot emulator (DO NOT open app after reboot)"
warn "IMPORTANT: After reboot, DO NOT open the app. Boot recovery should run silently."
warn "The emulator will reboot now. This will take 30-60 seconds."
pause
reboot_emulator
substep "Step 4: Collect boot recovery logs (without opening app)"
info "Collecting recovery logs from boot (app was NOT opened)..."
sleep 2
local logs
logs="$(get_recovery_logs)"
echo "$logs"
local missed rescheduled verified errors scenario
missed="$(extract_field_from_logs "$logs" "missed")"
rescheduled="$(extract_field_from_logs "$logs" "rescheduled")"
verified="$(extract_field_from_logs "$logs" "verified")"
errors="$(extract_field_from_logs "$logs" "errors")"
scenario="$(extract_scenario_from_logs "$logs")"
echo
info "Parsed recovery summary:"
echo " scenario = ${scenario:-<none>}"
echo " missed = ${missed}"
echo " rescheduled= ${rescheduled}"
echo " verified = ${verified}"
echo " errors = ${errors}"
echo
substep "Step 5: Verify alarms were recreated (without opening app)"
show_alarms
local after_count
after_count="$(count_alarms)"
info "Alarm count after boot (app never opened): $after_count"
if [[ "$after_count" -gt 0 && "$rescheduled" -gt 0 ]]; then
ok "TEST 4 PASSED: Boot recovery occurred silently and alarms were recreated (rescheduled=$rescheduled) without app launch."
elif [[ "$rescheduled" -gt 0 ]]; then
ok "TEST 4 PASSED: Boot recovery occurred silently (rescheduled=$rescheduled), but alarm count check unclear."
elif echo "$logs" | grep -qi "Starting boot recovery\|boot recovery"; then
warn "TEST 4: Boot recovery ran but alarms may not have been recreated. Check logs and implementation."
else
warn "TEST 4: Boot recovery not detected. Verify boot receiver is registered and has BOOT_COMPLETED permission."
fi
}
# ------------------------------------------------------------------------------
# Main
# ------------------------------------------------------------------------------
main() {
# Allow selecting specific tests: e.g. `./test-phase3.sh 1 3`
if [[ "$#" -gt 0 && ( "$1" == "-h" || "$1" == "--help" ) ]]; then
echo "Usage: $0 [TEST_IDS...]"
echo
echo "If no TEST_IDS are given, all tests (1, 2, 3, 4) will run."
echo "Examples:"
echo " $0 # run all tests"
echo " $0 1 # run only TEST 1"
echo " $0 2 3 # run only TEST 2 and TEST 3"
echo " $0 4 # run only TEST 4 (silent boot recovery)"
return 0
fi
SELECTED_TESTS=("$@")
echo
echo "========================================"
echo "Phase 3 Testing Script Boot Recovery"
echo "========================================"
echo
echo "This script will guide you through Phase 3 tests."
echo "You'll be prompted when UI interaction is needed."
echo
echo "⚠️ WARNING: This script will reboot the emulator multiple times."
echo " Each reboot takes 30-60 seconds."
echo
pause
require_adb_device
build_app
install_app
if should_run_test "1" SELECTED_TESTS; then
test1_boot_future_alarms
pause
fi
if should_run_test "2" SELECTED_TESTS; then
test2_boot_past_alarms
pause
fi
if should_run_test "3" SELECTED_TESTS; then
test3_boot_no_schedules
pause
fi
if should_run_test "4" SELECTED_TESTS; then
test4_silent_boot_recovery
fi
section "Testing Complete"
echo "Test Results Summary (see logs above for details):"
echo
echo "TEST 1: Boot with Future Alarms"
echo " - Check logs for scenario=$BOOT_SCENARIO_VALUE and rescheduled>0"
echo
echo "TEST 2: Boot with Past Alarms"
echo " - Check that missed>=1 and rescheduled>=1"
echo
echo "TEST 3: Boot with No Schedules"
echo " - Check that no recovery runs, or NONE scenario is logged with rescheduled=0"
echo
echo "TEST 4: Silent Boot Recovery"
echo " - Check that boot recovery occurred and alarms were recreated without app launch"
echo
ok "Phase 3 testing script complete!"
echo
echo "Next steps:"
echo " - Review logs above"
echo " - Capture snippets into PHASE3-EMULATOR-TESTING.md"
echo " - Update PHASE3-VERIFICATION.md and unified directive status matrix"
echo
}
main "$@"