Files
daily-notification-plugin/test-apps/android-test-app/test-phase1.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

642 lines
26 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
#!/bin/bash
# Phase 1 Testing Script - Interactive Test Runner
# Guides through all Phase 1 tests with clear prompts for UI interaction
set -e # Exit on error
# Source shared library
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${SCRIPT_DIR}/alarm-test-lib.sh"
# Phase 1 specific configuration
VERIFY_FIRE=${VERIFY_FIRE:-false} # Set VERIFY_FIRE=true to enable alarm fire verification
APP_DIR="${SCRIPT_DIR}"
PROJECT_ROOT="$(cd "${APP_DIR}/../.." && pwd)"
# Allow selecting specific tests on the command line (e.g. ./test-phase1.sh 1 2)
SELECTED_TESTS=()
check_plugin_configured() {
print_info "Checking if plugin is already configured..."
# Wait a moment for app to fully load
sleep 3
# Check if database exists (indicates plugin has been used)
DB_EXISTS=$($ADB_BIN shell run-as "${APP_ID}" ls databases/ 2>/dev/null | grep -c "daily_notification" || echo "0")
# Check if SharedPreferences has configuration (more reliable)
# The plugin stores config in SharedPreferences
PREFS_EXISTS=$($ADB_BIN shell run-as "${APP_ID}" ls shared_prefs/ 2>/dev/null | grep -c "DailyNotification" || echo "0")
# Check recent logs for configuration activity
RECENT_CONFIG=$($ADB_BIN logcat -d -t 50 | grep -E "Plugin configured|configurePlugin|Configuration" | tail -3)
if [ "${DB_EXISTS}" -gt "0" ] || [ "${PREFS_EXISTS}" -gt "0" ]; then
print_success "Plugin appears to be configured (database or preferences exist)"
# Show user what to check in UI
print_info "Please verify in the app UI that you see:"
echo " ⚙️ Plugin Settings: ✅ Configured"
echo " 🔌 Native Fetcher: ✅ Configured"
echo ""
echo "If both show ✅, the plugin is configured and you can skip configuration."
echo "If either shows ❌ or 'Not configured', you'll need to click 'Configure Plugin'."
echo ""
return 0
else
print_info "Plugin not configured (no database or preferences found)"
print_info "You will need to click 'Configure Plugin' in the app UI"
return 1
fi
}
check_permissions() {
print_info "Checking notification permissions..."
# Check if POST_NOTIFICATIONS permission is granted (Android 13+)
PERM_CHECK=$($ADB_BIN shell dumpsys package "${APP_ID}" | grep -A 5 "granted=true" | grep -c "android.permission.POST_NOTIFICATIONS" || echo "0")
# Also check via app's permission status if available
PERM_GRANTED=false
if [ "${PERM_CHECK}" -gt "0" ]; then
PERM_GRANTED=true
else
# Check if we're on Android 12 or below (permission not required)
SDK_VERSION=$($ADB_BIN shell getprop ro.build.version.sdk)
if [ "${SDK_VERSION}" -lt "33" ]; then
PERM_GRANTED=true # Pre-Android 13 doesn't need runtime permission
fi
fi
if [ "${PERM_GRANTED}" = true ]; then
print_success "Notification permissions granted"
return 0
else
print_warn "Notification permissions may not be granted"
return 1
fi
}
ensure_permissions() {
if check_permissions; then
print_success "Permissions already granted"
return 0
else
print_info "Notification permissions needed"
wait_for_ui_action "In the app UI, click the 'Request Permissions' button.
This will show a system permission dialog.
Steps:
1. Click 'Request Permissions' button
2. In the system dialog, tap 'Allow' to grant notification permission
3. Return to the app and verify the status shows:
- 🔔 Notifications: ✅ Granted (or similar)
Once permission is granted, press Enter to continue."
# Re-check permissions
sleep 2
if check_permissions; then
print_success "Permissions granted"
return 0
else
print_warn "Permissions may still not be granted - continuing anyway"
print_info "If notifications fail, you may need to grant permissions manually"
return 1
fi
fi
}
ensure_plugin_configured() {
if check_plugin_configured; then
# Plugin might be configured, but let user verify
wait_for_ui_action "Please check the Plugin Status section at the top of the app.
If you see:
- ⚙️ Plugin Settings: ✅ Configured
- 🔌 Native Fetcher: ✅ Configured
- 🔔 Notifications: ✅ Granted (or similar)
Then the plugin is already configured - just press Enter to continue.
If any show ❌ or 'Not configured':
- Click 'Request Permissions' if notifications are not granted
- Click 'Configure Plugin' if settings/fetcher are not configured
- Wait for all to show ✅, then press Enter."
# Give a moment for any configuration that just happened
sleep 2
print_success "Continuing with tests (plugin configuration verified or skipped)"
return 0
else
# Plugin definitely needs configuration
print_info "Plugin needs configuration"
# First ensure permissions
ensure_permissions
wait_for_ui_action "Click the 'Configure Plugin' button in the app UI.
Wait for the status to update:
- ⚙️ Plugin Settings: Should change to ✅ Configured
- 🔌 Native Fetcher: Should change to ✅ Configured
Once both show ✅, press Enter to continue."
# Verify configuration completed
sleep 2
print_success "Plugin configuration completed (or verified)"
fi
}
# kill_app is now provided by the library, but Phase 1 uses it with PACKAGE variable
# The library version uses APP_ID, which is set to PACKAGE, so it should work
# But we keep this as a compatibility wrapper if needed
# Phase 1 specific helper: get_current_time (used for fire verification)
get_current_time() {
$ADB_BIN shell date +%s
}
# Main test execution
main() {
# Allow selecting specific tests: e.g. `./test-phase1.sh 1 2`
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"
return 0
fi
SELECTED_TESTS=("$@")
print_header "Phase 1 Testing Script"
echo "This script will guide you through Phase 1 tests."
echo "You'll be prompted when UI interaction is needed."
echo ""
wait_for_user
# Pre-flight checks
print_header "Pre-Flight Checks"
check_adb_connection
check_emulator_ready
# Build and install
build_app
install_app
# Clear logs
clear_logs
# ============================================
# TEST 1: Force-Stop Recovery - Database Restoration
# ============================================
if should_run_test "1" SELECTED_TESTS; then
print_header "TEST 1: Force-Stop Recovery - Database Restoration"
echo "Purpose: Verify that after force-stop (which clears alarms), recovery"
echo " uses the database to rebuild alarms on app relaunch."
echo ""
echo "Note: App supports one alarm per day."
echo ""
echo "Test sequence:"
echo " 1. Clean start - verify no lingering alarms"
echo " 2. Schedule one alarm → Verify it exists in AlarmManager"
echo " 3. Force-stop app → Verify alarm is cleared (count = 0)"
echo " 4. Relaunch app → Verify recovery rebuilds alarm from database"
echo " 5. Verify alarm actually fires at scheduled time (optional)"
echo ""
wait_for_user
# ============================================
# Step 1: Clean start - verify no lingering alarms
# ============================================
print_step "1" "Clean start - checking for lingering alarms..."
LINGERING_COUNT=$(count_alarms)
if [ "${LINGERING_COUNT}" -gt "0" ] 2>/dev/null; then
print_warn "Found ${LINGERING_COUNT} lingering alarm(s) - these may interfere with test"
print_info "Consider uninstalling/reinstalling app for clean state"
wait_for_user
else
print_success "No lingering alarms found (clean state)"
fi
# ============================================
# Step 2: Schedule a known future alarm
# ============================================
print_step "2" "Launch app and schedule alarm..."
launch_app
ensure_plugin_configured
wait_for_ui_action "In the app UI, click the 'Test Notification' button.
This will schedule ONE notification for 4 minutes in the future.
(App supports one alarm per day)
The alarm will be stored in the database AND scheduled in AlarmManager."
print_step "3" "Verifying alarm exists in AlarmManager (BEFORE force-stop)..."
sleep 2
ALARM_COUNT_BEFORE=$(count_alarms)
print_info "Alarm count in AlarmManager: ${ALARM_COUNT_BEFORE}"
if [ "${ALARM_COUNT_BEFORE}" -eq "0" ] 2>/dev/null; then
print_error "No alarms found in AlarmManager - cannot test force-stop recovery"
print_info "Make sure you clicked 'Test Notification' and wait a moment"
wait_for_user
# Re-check
ALARM_COUNT_BEFORE=$(count_alarms)
if [ "${ALARM_COUNT_BEFORE}" -eq "0" ] 2>/dev/null; then
print_error "Still no alarms found - aborting test"
exit 1
fi
fi
print_success "✅ Alarms confirmed in AlarmManager (count: ${ALARM_COUNT_BEFORE})"
# Capture alarm details for later verification
ALARM_DETAILS_BEFORE=$($ADB_BIN shell dumpsys alarm | grep -A 3 "$APP_ID" | head -10)
print_info "Alarm details:"
echo "${ALARM_DETAILS_BEFORE}" | head -5
echo ""
# Extract trigger time for later verification
ALARM_TRIGGER_MS=$(echo "${ALARM_DETAILS_BEFORE}" | grep -oE "origWhen [0-9]+" | head -1 | awk '{print $2}')
if [ -n "${ALARM_TRIGGER_MS}" ]; then
ALARM_TRIGGER_SEC=$((ALARM_TRIGGER_MS / 1000))
ALARM_READABLE=$(date -d "@${ALARM_TRIGGER_SEC}" 2>/dev/null || echo "${ALARM_TRIGGER_SEC}")
print_info "Alarm scheduled for: ${ALARM_READABLE} (${ALARM_TRIGGER_MS} ms)"
fi
print_info "Checking logs for scheduling confirmation..."
$ADB_BIN logcat -d | grep -E "DN|SCHEDULE|Stored notification content" | tail -5
echo ""
wait_for_user
# ============================================
# Step 3: Force-stop the app (clears alarms)
# ============================================
print_step "4" "Force-stopping app (clears all alarms)..."
print_warn "Force-stop will clear ALL alarms from AlarmManager"
print_info "Executing: $ADB_BIN shell am force-stop ${APP_ID}"
force_stop_app
sleep 2
# Verify app is stopped (force_stop_app already handles this)
# ============================================
# Step 4: Verify alarms are MISSING (cleared by OS)
# ============================================
print_step "5" "Verifying alarms are MISSING from AlarmManager (AFTER force-stop)..."
sleep 1
ALARM_COUNT_AFTER=$(count_alarms)
print_info "Alarm count in AlarmManager after force-stop: ${ALARM_COUNT_AFTER}"
if [ "${ALARM_COUNT_AFTER}" -eq "0" ] 2>/dev/null; then
print_success "✅ Alarms cleared by force-stop (count: ${ALARM_COUNT_AFTER})"
print_info "This confirms: Force-stop cleared alarms from AlarmManager"
else
print_warn "⚠️ Alarms still present after force-stop (count: ${ALARM_COUNT_AFTER})"
print_info "Some devices/OS versions may not clear alarms on force-stop"
print_info "Continuing test anyway - recovery should still work"
fi
wait_for_user
# ============================================
# Step 5: Relaunch app (triggers recovery from database)
# ============================================
print_step "6" "Relaunching app (triggers recovery from database)..."
clear_logs
launch_app
sleep 4 # Give recovery time to run
# ============================================
# Step 6: Verify recovery rebuilt alarms from database
# ============================================
print_step "7" "Verifying recovery rebuilt alarms from database..."
sleep 2
ALARM_COUNT_RECOVERED=$(count_alarms)
print_info "Alarm count in AlarmManager after recovery: ${ALARM_COUNT_RECOVERED}"
print_info "Checking recovery logs..."
check_recovery_logs
print_info "Expected log output:"
echo " DNP-REACTIVATION: Starting app launch recovery"
echo " DNP-REACTIVATION: Rescheduled alarm: <id> for <time>"
echo " DNP-REACTIVATION: Cold start recovery complete: ... rescheduled>=1, ..."
echo ""
# Check recovery logs for rescheduling and recovery source
RECOVERY_RESULT=$($ADB_BIN logcat -d | grep "Cold start recovery complete\|Boot recovery complete" | tail -1)
RESCHEDULED_COUNT=$(echo "${RECOVERY_RESULT}" | grep -oE "rescheduled=[0-9]+" | grep -oE "[0-9]+" || echo "0")
VERIFIED_COUNT=$(echo "${RECOVERY_RESULT}" | grep -oE "verified=[0-9]+" | grep -oE "[0-9]+" || echo "0")
# Check for explicit recovery source indication (if logged)
RECOVERY_SOURCE=$($ADB_BIN logcat -d | grep -E "recovery source|from database|DATABASE" | tail -1 || echo "")
# Pass/fail criteria
TEST1_PASSED=false
if [ "${ALARM_COUNT_RECOVERED}" -gt "0" ] 2>/dev/null; then
print_success "✅ Alarms restored in AlarmManager (count: ${ALARM_COUNT_RECOVERED})"
if [ "${RESCHEDULED_COUNT}" -gt "0" ] 2>/dev/null; then
print_success "✅ Recovery logs confirm rescheduling (rescheduled=${RESCHEDULED_COUNT})"
TEST1_PASSED=true
else
print_warn "⚠️ Alarms restored but logs show rescheduled=0"
print_info "This might be okay if alarms were verified instead of rescheduled"
# Still pass if alarms are restored, even if rescheduled=0
TEST1_PASSED=true
fi
else
print_error "❌ No alarms restored (count: ${ALARM_COUNT_RECOVERED})"
print_info "Recovery may have failed or alarms were not in database"
fi
if [ "${TEST1_PASSED}" = true ]; then
print_success "TEST 1 PASSED: Recovery successfully rebuilt alarms from database!"
print_info "Summary:"
echo " - Before force-stop: ${ALARM_COUNT_BEFORE} alarm(s)"
echo " - After force-stop: ${ALARM_COUNT_AFTER} alarm(s) (cleared)"
echo " - After recovery: ${ALARM_COUNT_RECOVERED} alarm(s) (rebuilt)"
echo " - Rescheduled: ${RESCHEDULED_COUNT} alarm(s)"
echo " - Verified: ${VERIFIED_COUNT} alarm(s)"
if [ -n "${RECOVERY_SOURCE}" ]; then
echo " - Recovery source: ${RECOVERY_SOURCE}"
fi
else
print_error "TEST 1 FAILED: Recovery did not rebuild alarms correctly"
print_info "Check logs above for recovery errors"
fi
# ============================================
# Step 7: Verify alarms actually fire (optional, controlled by VERIFY_FIRE flag)
# ============================================
if [ "${VERIFY_FIRE}" = "true" ] && [ -n "${ALARM_TRIGGER_MS}" ]; then
print_step "8" "Verifying alarm fires at scheduled time..."
# Get current time in milliseconds
CURRENT_TIME_SEC=$(get_current_time)
CURRENT_TIME_MS=$((CURRENT_TIME_SEC * 1000))
WAIT_MS=$((ALARM_TRIGGER_MS - CURRENT_TIME_MS))
if [ "${WAIT_MS}" -lt 0 ]; then
print_warn "Alarm time already passed (${WAIT_MS} ms ago); skipping fire verification"
else
WAIT_SEC=$((WAIT_MS / 1000))
# Clamp upper bound to prevent accidentally waiting 30+ minutes
if [ "${WAIT_SEC}" -gt 600 ]; then
print_warn "Alarm is >10 minutes away (${WAIT_SEC}s); skipping fire verification"
print_info "To test fire verification, schedule alarm closer to current time"
print_info "Or set a shorter test alarm interval in the app"
else
print_info "Alarm scheduled for: ${ALARM_READABLE}"
print_info "Current time: $(date -d "@${CURRENT_TIME_SEC}" 2>/dev/null || echo "${CURRENT_TIME_SEC}")"
print_info "Waiting ~${WAIT_SEC} seconds for alarm to fire..."
# Clear logs before waiting
clear_logs
# Wait for alarm time (with a small buffer)
sleep ${WAIT_SEC}
# Give alarm a moment to fire and log
sleep 2
print_info "Checking logs for fired alarm..."
ALARM_FIRED=$($ADB_BIN logcat -d | grep -E "DNP-RECEIVE|DNP-NOTIFY|DNP-WORK|Alarm fired|Notification displayed" | tail -10)
if [ -n "${ALARM_FIRED}" ]; then
print_success "✅ Alarm fired! Logs:"
echo "${ALARM_FIRED}"
else
print_warn "⚠️ No alarm fire logs found"
print_info "This might mean:"
echo " - Alarm fired but logs were cleared"
echo " - Alarm receiver didn't log"
echo " - Check notification tray manually"
print_info "Recent logs:"
$ADB_BIN logcat -d | grep -E "DNP|DailyNotification" | tail -10
fi
fi
fi
elif [ "${VERIFY_FIRE}" = "true" ]; then
print_info "Skipping fire verification (alarm trigger time not captured)"
else
print_info "Skipping fire verification (VERIFY_FIRE=false, set VERIFY_FIRE=true to enable)"
fi
wait_for_user
fi
# ============================================
# TEST 2: Future Alarm Verification
# ============================================
if should_run_test "2" SELECTED_TESTS; then
print_header "TEST 2: Future Alarm Verification"
echo "Purpose: Verify future alarms are verified/rescheduled if missing."
echo ""
echo "Note: This test verifies that recovery correctly handles multiple alarms."
echo " We'll schedule a second alarm to test recovery with multiple schedules."
echo ""
wait_for_user
print_step "1" "Launch app"
launch_app
ensure_plugin_configured
wait_for_ui_action "In the app UI, click 'Test Notification' to schedule a SECOND notification.
This creates an additional scheduled notification (you should now have 2 total).
This tests recovery behavior when multiple alarms exist in the database."
print_step "2" "Verifying alarms are scheduled..."
sleep 2
check_alarm_status
ALARM_COUNT=$(count_alarms)
print_info "Found ${ALARM_COUNT} scheduled alarm(s) (expected: 1)"
if [ "${ALARM_COUNT}" -eq "1" ] 2>/dev/null; then
print_success "✅ Single alarm confirmed in AlarmManager"
elif [ "${ALARM_COUNT}" -gt "1" ] 2>/dev/null; then
print_success "Alarms are scheduled in AlarmManager"
else
print_error "No alarms found in AlarmManager"
wait_for_user
fi
print_step "3" "Killing app and relaunching (triggers recovery)..."
kill_app
clear_logs
launch_app
print_step "4" "Checking recovery logs for verification..."
sleep 3
check_recovery_logs
print_info "Expected log output (either):"
echo " DNP-REACTIVATION: Verified scheduled alarm: <id> at <time>"
echo " OR"
echo " DNP-REACTIVATION: Rescheduled missing alarm: <id> at <time>"
echo " DNP-REACTIVATION: Cold start recovery complete: ..., verified=1 or rescheduled=1, ..."
echo ""
RECOVERY_RESULT=$($ADB_BIN logcat -d | grep "Cold start recovery complete" | tail -1)
# Extract counts from recovery result
RESCHEDULED_COUNT=$(echo "${RECOVERY_RESULT}" | grep -oE "rescheduled=[0-9]+" | grep -oE "[0-9]+" || echo "0")
VERIFIED_COUNT=$(echo "${RECOVERY_RESULT}" | grep -oE "verified=[0-9]+" | grep -oE "[0-9]+" || echo "0")
# Verify alarm count after recovery
ALARM_COUNT_AFTER_RECOVERY=$(count_alarms)
print_info "Alarm count after recovery: ${ALARM_COUNT_AFTER_RECOVERY} (expected: 1)"
if [ "${RESCHEDULED_COUNT}" -gt "0" ] 2>/dev/null; then
print_success "✅ TEST 2 PASSED: Missing future alarm was detected and rescheduled (rescheduled=${RESCHEDULED_COUNT})!"
if [ "${ALARM_COUNT_AFTER_RECOVERY}" -eq "1" ] 2>/dev/null; then
print_success "✅ Single alarm confirmed in AlarmManager after recovery"
fi
elif [ "${VERIFIED_COUNT}" -gt "0" ] 2>/dev/null; then
print_success "✅ TEST 2 PASSED: Future alarm verified in AlarmManager (verified=${VERIFIED_COUNT})!"
if [ "${ALARM_COUNT_AFTER_RECOVERY}" -eq "1" ] 2>/dev/null; then
print_success "✅ Single alarm confirmed in AlarmManager after recovery"
fi
elif [ "${RESCHEDULED_COUNT}" -eq "0" ] 2>/dev/null && [ "${VERIFIED_COUNT}" -eq "0" ] 2>/dev/null; then
print_warn "⚠️ TEST 2: No verification/rescheduling needed (both verified=0 and rescheduled=0)"
print_info "This might mean:"
echo " - Alarm was already properly scheduled and didn't need recovery"
echo " - Recovery didn't detect any issues"
if [ "${ALARM_COUNT_AFTER_RECOVERY}" -eq "1" ] 2>/dev/null; then
print_success "✅ Single alarm still present - recovery may have verified it silently"
fi
else
print_error "TEST 2 INCONCLUSIVE: Could not find recovery result"
print_info "Recovery result: ${RECOVERY_RESULT}"
fi
print_step "5" "Verifying alarms are still scheduled in AlarmManager..."
check_alarm_status
wait_for_user
fi
# ============================================
# TEST 3: Recovery Timeout
# ============================================
if should_run_test "3" SELECTED_TESTS; then
print_header "TEST 3: Recovery Timeout"
echo "Purpose: Verify recovery times out gracefully."
echo ""
echo "Note: This test requires creating many schedules (100+)."
echo "For now, we'll verify the timeout mechanism exists."
echo ""
wait_for_user
print_step "1" "Checking recovery timeout implementation..."
if grep -q "RECOVERY_TIMEOUT_SECONDS.*2L" "${PROJECT_ROOT}/android/src/main/java/com/timesafari/dailynotification/ReactivationManager.kt"; then
print_success "Timeout is set to 2 seconds"
else
print_error "Timeout not found in code"
fi
if grep -q "withTimeout" "${PROJECT_ROOT}/android/src/main/java/com/timesafari/dailynotification/ReactivationManager.kt"; then
print_success "Timeout protection is implemented"
else
print_error "Timeout protection not found"
fi
print_info "TEST 3: Timeout mechanism verified in code"
print_info "Full test (100+ schedules) can be done manually if needed"
wait_for_user
fi
# ============================================
# TEST 4: Invalid Data Handling
# ============================================
if should_run_test "4" SELECTED_TESTS; then
print_header "TEST 4: Invalid Data Handling"
echo "Purpose: Verify invalid data doesn't crash recovery."
echo ""
echo "Note: This requires database access. We'll check if the app is debuggable."
echo ""
wait_for_user
print_step "1" "Checking if app is debuggable..."
if $ADB_BIN shell dumpsys package "${APP_ID}" | grep -q "debuggable=true"; then
print_success "App is debuggable - can access database"
print_info "Invalid data handling is tested automatically during recovery."
print_info "The ReactivationManager code includes checks for:"
echo " - Empty notification IDs (skipped with warning)"
echo " - Invalid schedule IDs (skipped with warning)"
echo " - Database errors (logged, non-fatal)"
echo ""
print_info "To manually test invalid data:"
echo " 1. Use: $ADB_BIN shell run-as ${APP_ID} sqlite3 databases/daily_notification_plugin.db"
echo " 2. Insert invalid notification: INSERT INTO notification_content (id, ...) VALUES ('', ...);"
echo " 3. Launch app and check logs for 'Skipping invalid notification'"
else
print_info "App is not debuggable - cannot access database directly"
print_info "TEST 4: Code review confirms invalid data handling exists"
print_info " - ReactivationManager.kt checks for empty IDs"
print_info " - Errors are logged but don't crash recovery"
fi
wait_for_user
fi
# ============================================
# Summary
# ============================================
print_header "Testing Complete"
echo "Test Results Summary:"
echo ""
echo "TEST 1: Cold Start Missed Detection"
echo " - ✅ PASSED if logs show 'missed=1'"
echo " - ❌ FAILED if logs show 'missed=0' or no recovery logs"
echo ""
echo "TEST 2: Future Alarm Verification/Rescheduling"
echo " - ✅ PASSED if logs show 'rescheduled=1' OR 'verified=1'"
echo " - INFO if both are 0 (no future alarms to check)"
echo ""
echo "TEST 3: Recovery Timeout"
echo " - Timeout mechanism verified in code"
echo ""
echo "TEST 4: Invalid Data Handling"
echo " - Requires database access (debuggable app or root)"
echo ""
print_info "All recovery logs:"
echo ""
$ADB_BIN logcat -d | grep "$REACTIVATION_TAG" | tail -20
echo ""
print_success "Phase 1 testing script complete!"
echo ""
echo "Next steps:"
echo " - Review logs above"
echo " - Verify all tests passed"
echo " - Check database if needed (debuggable app)"
echo " - Update Doc B with test results"
}
# Run main function
main "$@"