P2.1: iOS Schema Versioning Strategy
- Added SCHEMA_VERSION constant and checkSchemaVersion() method in PersistenceController
- Version stored in NSPersistentStore metadata (observability contract, not migration gate)
- CoreData auto-migration remains authoritative; version mismatches logged, not blocked
- Documentation added to ios/Plugin/README.md with migration contract
P2.2: Combined Edge Case Tests
- Added 3 resilience test scenarios to DailyNotificationRecoveryTests.swift:
- test_combined_dst_boundary_duplicate_delivery_cold_start()
- test_combined_rollover_duplicate_delivery_cold_start()
- test_combined_schema_version_cold_start_recovery()
- All tests labeled with @resilience @combined-scenarios comments
- Tests verify idempotency and correctness under combined stressors
P2.3: Android Combined Tests Design
- Created P2.3-DESIGN.md with scope, invariants, and acceptance criteria
- Created P2.3-IMPLEMENTATION-CHECKLIST.md with step-by-step execution plan
- Design ready for implementation to achieve parity with iOS P2.2
Documentation Updates
- Fixed parity matrix: iOS invalid data handling now correctly shows "✅ Recovery tested" with test references
- Updated progress docs (00-STATUS.md, 01-CHANGELOG-WORK.md, 03-TEST-RUNS.md, 04-PARITY-MATRIX.md)
- Updated P2-DESIGN.md to reflect P2.3 scope (Android combined tests)
- Updated SYSTEM_INVARIANTS.md baseline tag references
Baseline Tag
- Created and pushed v1.0.11-p2-complete tag
- Tag represents P2.x completion (schema versioning + combined resilience tests)
All invariants preserved. CI passes. Tests runnable via xcodebuild on macOS.
389 lines
12 KiB
Markdown
389 lines
12 KiB
Markdown
# P2.3 Design: Android Combined Edge Case Tests
|
|
|
|
**Purpose:** Defines scope, boundaries, and acceptance criteria for Android combined resilience tests to achieve parity with iOS P2.2.
|
|
**Owner:** Development Team
|
|
**Last Updated:** 2025-12-22
|
|
**Status:** design-only (no implementation)
|
|
**Baseline:** `v1.0.11-p2-complete`
|
|
|
|
---
|
|
|
|
## Purpose
|
|
|
|
This document defines the **scope, boundaries, and acceptance criteria** for P2.3 work **before any implementation begins**. It ensures P2.3:
|
|
|
|
- Achieves parity with iOS combined edge case tests (P2.2)
|
|
- Uses CI-compatible testing approach (JUnit + Robolectric or pure unit tests)
|
|
- Maintains all established invariants
|
|
- Can be executed incrementally
|
|
|
|
---
|
|
|
|
## P2.3 Scope Definition
|
|
|
|
### What P2.3 Includes
|
|
|
|
**Android Combined Edge Case Tests**
|
|
- Add automated resilience tests mirroring iOS P2.2 scenarios
|
|
- Enable Android test infrastructure (currently disabled in `build.gradle`)
|
|
- Use CI-compatible testing framework (JUnit + Robolectric or pure unit tests)
|
|
- Validate idempotency and correctness under combined stressors
|
|
|
|
**Test Scenarios (Must-Have):**
|
|
|
|
1. **DST boundary + duplicate delivery + cold start**
|
|
- Validate recovery idempotency under DST transitions
|
|
- Verify only one logical delivery recorded after dedupe
|
|
- Validate next scheduled time is DST-consistent
|
|
- Test cold start recovery after duplicate delivery
|
|
|
|
2. **Rollover + duplicate delivery + cold start**
|
|
- Test rollover idempotency under re-entry
|
|
- Verify duplicate delivery doesn't double-apply state transitions
|
|
- Validate cold start reconciliation produces correct state
|
|
|
|
**Test Scenarios (Optional):**
|
|
|
|
3. **Schema version + cold start recovery** (if Android has explicit version tracking)
|
|
- Confirm Room database version is observable
|
|
- Verify version doesn't interfere with recovery
|
|
|
|
### What P2.3 Excludes
|
|
|
|
- **No emulator/instrumentation tests in CI** — Use JVM-compatible tests (Robolectric or pure unit tests)
|
|
- **No new features** — Tests only, no production code changes
|
|
- **No architectural changes** — Core structure remains unchanged
|
|
- **No breaking changes** — Backward compatibility required
|
|
- **No new dependencies** — Use existing AndroidX test libraries
|
|
|
|
---
|
|
|
|
## Current State Analysis
|
|
|
|
### Android Test Infrastructure
|
|
|
|
**Current Status:**
|
|
- Tests are **disabled** in `android/build.gradle` (lines 48-63)
|
|
- Comment: "tests reference deprecated/removed code"
|
|
- TODO: "Rewrite tests to use modern AndroidX testing framework"
|
|
- Test source directory exists but is empty/placeholder
|
|
|
|
**Existing Test Infrastructure:**
|
|
- Manual emulator scripts: `test-phase1.sh`, `test-phase2.sh`, `test-phase3.sh`
|
|
- These validate recovery scenarios but are not automated/CI-compatible
|
|
- No automated unit/integration tests in `android/src/test/`
|
|
|
|
### iOS Comparison (P2.2)
|
|
|
|
**iOS State:**
|
|
- ✅ Automated combined edge case tests in `ios/Tests/DailyNotificationRecoveryTests.swift`
|
|
- ✅ 3 combined scenarios with direct references in parity matrix
|
|
- ✅ Tests runnable via `xcodebuild` (skipped on Linux CI, documented)
|
|
|
|
**Parity Gap:**
|
|
- Android has manual scripts but no automated combined scenarios
|
|
- Need to close this gap with CI-compatible automated tests
|
|
|
|
---
|
|
|
|
## Invariants That Must Not Be Violated
|
|
|
|
### 1. Packaging Invariants (P0)
|
|
|
|
**Enforced by:** `verify.sh` → `check_package()`
|
|
|
|
- `npm pack --dry-run` must not contain forbidden files
|
|
- `package.json.files` whitelist must remain authoritative
|
|
|
|
**P2.3 Constraint:** Test files must not be included in published package (already excluded via `package.json.files`).
|
|
|
|
---
|
|
|
|
### 2. Core Module Purity (P1.4)
|
|
|
|
**Enforced by:** `verify.sh` → `check_core_source()` + `check_core_artifacts()`
|
|
|
|
- `src/core/` must not import platform-specific modules
|
|
|
|
**P2.3 Constraint:** Tests are Android-only, no impact on core module.
|
|
|
|
---
|
|
|
|
### 3. CI Authority (P0)
|
|
|
|
**Enforced by:** `ci/README.md` (policy-as-code contract)
|
|
|
|
- `./ci/run.sh` is the **only** supported CI entrypoint
|
|
- All gates must call `./ci/run.sh`
|
|
|
|
**P2.3 Constraint:** Tests must be runnable via `./ci/run.sh` (or clearly documented as manual if platform-specific).
|
|
|
|
---
|
|
|
|
### 4. Export Correctness (P0)
|
|
|
|
**Enforced by:** `verify.sh` → `check_build()`
|
|
|
|
- All exported paths must match actual build artifacts
|
|
|
|
**P2.3 Constraint:** Test files don't affect exports.
|
|
|
|
---
|
|
|
|
### 5. Documentation Structure (P1.5)
|
|
|
|
**Enforced by:** `docs/00-INDEX.md` (index-first rule)
|
|
|
|
- New docs must be linked from index or placed in `_archive/`/`_reference/`
|
|
|
|
**P2.3 Constraint:** Test documentation must follow existing patterns.
|
|
|
|
---
|
|
|
|
### 6. Baseline Tag Integrity
|
|
|
|
**Baseline:** `v1.0.11-p2-complete`
|
|
|
|
- This tag represents a known-good state
|
|
- P2.3 work must not invalidate the baseline
|
|
|
|
**P2.3 Constraint:** Tests must not break existing functionality.
|
|
|
|
---
|
|
|
|
## P2.3 Work Items (Detailed)
|
|
|
|
### P2.3.1: Enable Android Test Infrastructure
|
|
|
|
**Goal:** Re-enable Android tests with modern AndroidX testing framework.
|
|
|
|
**Scope:**
|
|
- Update `android/build.gradle` to enable unit tests
|
|
- Add AndroidX test dependencies (JUnit, Robolectric if needed)
|
|
- Create test directory structure
|
|
- Verify tests can compile and run (even if initially empty)
|
|
|
|
**Constraints:**
|
|
- Must use modern AndroidX testing framework (not deprecated APIs)
|
|
- Must be runnable on Linux CI (JVM-compatible, no emulator required)
|
|
- Must not break existing build
|
|
|
|
**Acceptance Criteria:**
|
|
- [ ] `android/build.gradle` test configuration updated
|
|
- [ ] Test dependencies added (JUnit, Robolectric if needed)
|
|
- [ ] `./gradlew test` runs successfully (even if no tests yet)
|
|
- [ ] CI can run tests (`./ci/run.sh` includes Android test step or documents manual requirement)
|
|
|
|
---
|
|
|
|
### P2.3.2: Create Test Infrastructure Helpers
|
|
|
|
**Goal:** Create test helpers similar to iOS `TestDBFactory.swift`.
|
|
|
|
**Scope:**
|
|
- Create test database factory (in-memory Room database)
|
|
- Create test data injection helpers (invalid data, duplicate scenarios)
|
|
- Create mock context/component helpers if needed
|
|
|
|
**Constraints:**
|
|
- Must use in-memory databases for isolation
|
|
- Must not require real Android device/emulator
|
|
- Must follow existing test patterns where possible
|
|
|
|
**Acceptance Criteria:**
|
|
- [ ] Test database factory created (in-memory Room)
|
|
- [ ] Test data injection helpers created
|
|
- [ ] Helpers support invalid data scenarios
|
|
- [ ] Helpers support duplicate delivery scenarios
|
|
|
|
---
|
|
|
|
### P2.3.3: Implement Combined Test Scenarios
|
|
|
|
**Goal:** Add 2-3 combined edge case tests mirroring iOS P2.2.
|
|
|
|
**Scope:**
|
|
|
|
**Scenario A: DST boundary + duplicate delivery + cold start**
|
|
- Create notification scheduled at DST boundary
|
|
- Simulate duplicate delivery events (rapid succession)
|
|
- Trigger cold start recovery
|
|
- Verify: idempotency, deduplication, DST-consistent next time
|
|
|
|
**Scenario B: Rollover + duplicate delivery + cold start**
|
|
- Create notification that was just delivered (past time)
|
|
- Trigger rollover (first delivery)
|
|
- Simulate duplicate delivery immediately
|
|
- Trigger cold start recovery
|
|
- Verify: rollover idempotency, no double-apply, correct state
|
|
|
|
**Scenario C: Schema version + cold start recovery (optional)**
|
|
- Verify Room database version is observable
|
|
- Test recovery with version metadata present
|
|
- Verify version doesn't interfere with recovery
|
|
|
|
**Constraints:**
|
|
- Must use Robolectric or pure unit tests (no emulator)
|
|
- Must test core logic, not platform-specific AlarmManager (mock if needed)
|
|
- Must be deterministic and CI-runnable
|
|
|
|
**Acceptance Criteria:**
|
|
- [ ] At least 2 combined test scenarios implemented
|
|
- [ ] Tests verify idempotency in combined scenarios
|
|
- [ ] Tests labeled explicitly as resilience/combined-scenarios
|
|
- [ ] Tests pass in CI (or clearly documented as manual if platform-specific)
|
|
- [ ] Test results logged in `docs/progress/03-TEST-RUNS.md`
|
|
- [ ] Parity matrix updated with direct test references
|
|
|
|
---
|
|
|
|
## P2.3 Execution Strategy
|
|
|
|
### Phase Ordering
|
|
|
|
**Recommended sequence:**
|
|
|
|
1. **P2.3.1 First** — Enable test infrastructure
|
|
- Establishes foundation for tests
|
|
- Verifies CI compatibility
|
|
- Low risk, enables subsequent work
|
|
|
|
2. **P2.3.2 Second** — Create test helpers
|
|
- Provides utilities for test scenarios
|
|
- Enables isolated, repeatable tests
|
|
- Medium complexity
|
|
|
|
3. **P2.3.3 Third** — Implement combined scenarios
|
|
- Builds on infrastructure and helpers
|
|
- Validates resilience under combined stressors
|
|
- Higher complexity, benefits from previous phases
|
|
|
|
### Incremental Approach
|
|
|
|
- Each P2.3 item can be completed independently
|
|
- Can pause/resume at any item boundary
|
|
- Each item has its own acceptance criteria
|
|
|
|
### Testing Strategy
|
|
|
|
- **P2.3.1:** Verify test infrastructure works (`./gradlew test`)
|
|
- **P2.3.2:** Verify helpers work in isolation
|
|
- **P2.3.3:** New tests required, existing functionality must pass
|
|
|
|
---
|
|
|
|
## P2.3 "Done" Criteria
|
|
|
|
### Overall P2.3 Completion
|
|
|
|
P2.3 is complete when:
|
|
|
|
1. **All P2.3 items completed** (P2.3.1, P2.3.2, P2.3.3)
|
|
2. **All invariants preserved** (verified by CI)
|
|
3. **All acceptance criteria met** (per item)
|
|
4. **Documentation updated** (progress docs, parity matrix, changelog)
|
|
5. **Parity achieved** (Android has automated combined tests matching iOS)
|
|
|
|
### Individual Item Completion
|
|
|
|
Each P2.3 item is complete when:
|
|
|
|
- [ ] Acceptance criteria met
|
|
- [ ] CI passes (`./ci/run.sh`)
|
|
- [ ] No invariant violations
|
|
- [ ] Documentation updated (if applicable)
|
|
- [ ] Progress docs updated
|
|
|
|
---
|
|
|
|
## Risk Mitigation
|
|
|
|
### Risk: Android Tests Currently Disabled
|
|
|
|
**Mitigation:**
|
|
- Start with minimal test infrastructure (one simple test)
|
|
- Verify CI compatibility before adding complex scenarios
|
|
- Use Robolectric for Android framework mocking (no emulator needed)
|
|
|
|
### Risk: CI Incompatibility
|
|
|
|
**Mitigation:**
|
|
- Use JVM-compatible tests (Robolectric or pure unit tests)
|
|
- Document manual test requirements clearly if any
|
|
- Ensure `./ci/run.sh` can run tests or skip gracefully
|
|
|
|
### Risk: Breaking Existing Functionality
|
|
|
|
**Mitigation:**
|
|
- Tests only, no production code changes
|
|
- Incremental approach (one scenario at a time)
|
|
- CI gates prevent regressions
|
|
|
|
### Risk: Scope Creep
|
|
|
|
**Mitigation:**
|
|
- Clear "what P2.3 excludes" section
|
|
- Acceptance criteria defined upfront
|
|
- Can pause/resume at item boundaries
|
|
|
|
---
|
|
|
|
## Success Metrics
|
|
|
|
### Quantitative
|
|
|
|
- **P2.3.1:** Test infrastructure enabled and CI-compatible
|
|
- **P2.3.2:** Test helpers created (database factory, data injection)
|
|
- **P2.3.3:** At least 2 combined test scenarios (3 if time permits)
|
|
|
|
### Qualitative
|
|
|
|
- **Parity:** Android has automated combined tests matching iOS intent
|
|
- **CI Compatibility:** Tests runnable in CI or clearly documented as manual
|
|
- **Maintainability:** Tests follow existing patterns and are well-documented
|
|
|
|
---
|
|
|
|
## Dependencies
|
|
|
|
### External Dependencies
|
|
|
|
- **Robolectric** (if used) — Must be compatible with existing AndroidX versions
|
|
- **JUnit** — Standard Android testing framework
|
|
|
|
### Internal Dependencies
|
|
|
|
- **P2.3.1 → P2.3.2 → P2.3.3:** Sequential dependency (infrastructure → helpers → scenarios)
|
|
|
|
### Blocking Dependencies
|
|
|
|
- None — P2.3 can start immediately after P2.x completion
|
|
|
|
---
|
|
|
|
## Timeline Estimate
|
|
|
|
**P2.3.1:** 2-4 hours (test infrastructure setup)
|
|
**P2.3.2:** 4-6 hours (test helpers creation)
|
|
**P2.3.3:** 6-10 hours (combined scenarios implementation)
|
|
|
|
**Total:** 12-20 hours (can be spread over multiple sessions)
|
|
|
|
**Note:** These are estimates. Actual time depends on Android test framework complexity and Robolectric setup.
|
|
|
|
---
|
|
|
|
## Next Steps (After Design Approval)
|
|
|
|
1. **Review this design** — Ensure scope and constraints are correct
|
|
2. **Approve test framework choice** — Robolectric vs pure unit tests
|
|
3. **Begin P2.3.1** — Enable test infrastructure first
|
|
4. **Execute incrementally** — One item at a time, pause/resume as needed
|
|
|
|
---
|
|
|
|
**Last Updated:** 2025-12-22
|
|
**Status:** Design-Only (No Implementation)
|
|
**Next Action:** Review and approve design before proceeding
|
|
|