Skip to content

Manual Test Runbook — L5: RTO/RPO Doc Generator

Owner: Sagar  |  Time: ~5 min (offline only — L5 is a pure doc generator, no live phase)

Overview

L5 merges three already-shipped DR-series sources into one client-facing RTO/RPO objectives document:

  • L1 (modules/azure/backup-policy) retention_summary — bounds RPO for backup-restored workloads from the configured cadence.
  • L2 (modules/azure/cross-region-replication) replication_summary — bounds RPO for replicated workloads (states the mechanism, not a fabricated minute figure, for continuously-replicating SQL failover groups).
  • L4 (apps/restore-drill) versioned RestoreDrillReports — the measured evidence: each drill is one tested workload, carrying its RTO target and the real recovery duration the latest run measured.

Pure adapt → render + jest, mirroring E0/S1/S2/L4 — there is no live Azure phase to test (the tool only reads JSON and writes markdown).

Part A — Build, typecheck, unit tests (~3 min)

cd apps/rto-rpo-doc-generator
npm ci
npm run typecheck
npm run build
npm test

Expect: 2 suites, 15 tests pass — RPO derivation (shortest-cadence backup bound, replication-mechanism statement with no fabricated minute figure, "unknown bound" cases), status classification (met/at-risk/failing), latest-report-per-drill dedup, sort order, and the renderer (posture, workload table, gap analysis, empty-state honesty, determinism).

Part B — Offline CLI demo (~2 min)

B1. Generate the doc from the bundled fixtures

node dist/index.js \
  --l1 examples/l1-outputs.json --l2 examples/l2-outputs.json \
  --drill-reports examples/drill-reports --output /tmp/l5out
cat /tmp/l5out/rto-rpo.md

Expect: stdout wrote /tmp/l5out/rto-rpo.md (3 workload(s) documented). The doc contains:

  • A Recovery posture section with the L1 cadence table (Daily | 30 etc.) and the L2 replication summary (object replication + SQL failover group).
  • A per-workload table with three rows, sorted by name: payments-prod-sql-monthly (⚠️ At risk — RTO target missed), payments-prod-vm-monthly (✅ Met), reporting-prod-fileshare-monthly (🔴 Failing — last drill outcome failed).
  • The payments-prod-sql-monthly row's Defined RPO cell is (not a fabricated number) — its derivation note explicitly says continuous asynchronous replication is "NOT a fixed backup-style schedule".
  • A Gap analysis section naming the at-risk and failing workloads with a concrete next step each.
grep -c "^|" /tmp/l5out/rto-rpo.md          # table rows present
grep "Defined RPO" -A1 /tmp/l5out/rto-rpo.md | head -1
cat /tmp/l5out/model.json | head -5         # versioned model.json (schema v1.0) also written

B2. Honest empty state (no evidence supplied)

node dist/index.js --output /tmp/l5empty
cat /tmp/l5empty/rto-rpo.md | grep -A1 "not supplied"

Expect: the doc plainly states "L1 backup retention: not supplied" / "L2 cross-region replication: not supplied" / "No restore-drill evidence supplied" — L5 never invents posture or workloads it wasn't given.

B3. CLI help

node dist/index.js --help

Expect: usage text listing --l1, --l2, --drill-reports, --output.

Pass criteria

  • Part A — builds, typechecks; 15 tests pass
  • Part B1 — fixture run renders all three workloads with correct status badges; replication-bound row shows for Defined RPO (no fabricated figure); model.json (schema v1.0) also written
  • Part B2 — missing-evidence states are rendered honestly, not omitted
  • Part B3 — --help prints usage

Sign-off

  • Tester: _  |  Date: _  |  Result: PASS / FAIL / N/A
  • Notes: