diablo2-web/TEST_INFRA.md

125 lines
7.5 KiB
Markdown
Raw Permalink 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.

# E2E Test Infrastructure: Diablo II 1.13c Item Drop Engine Parity (Issues #412–#428)
## 1. Test Architecture & Hierarchy
The Diablo II Web Port Item Drop Engine test suite is built on a 4-tier opaque-box test architecture designed to enforce strict Blizzard v1.13c ground truth parity across all 17 inventoried features (Issues #412–#428).
```
▲
/ \
/ \
/ \
/ Tier 4\ Real-World Workload Scenarios (12 tests)
/─────────\ Full gameplay loops, boss runs, inventory caps
/ Tier 3 \ Cross-Feature Interactions (16 tests)
/─────────────\ Pairwise subsystems, MF + NoDrop + Boss TCs
/ Tier 2 \ Boundary & Corner Cases (85 tests, >=5/feature)
/─────────────────\ Zero/extreme inputs, clamping, edge coords
/ Tier 1 \ Feature Coverage (85 tests, >=5/feature)
/─────────────────────\ Primary behavior across all 17 features
```
### Tier Descriptions & Scope
| Tier | Suite File | Target Scope | Min Tests Required | Actual Tests |
| :--- | :--- | :--- | :---: | :---: |
| **Tier 1** | `tests/e2e-drop-parity/tier1-feature-coverage.test.ts` | Complete feature coverage for all 17 features (#412–#428) | >= 85 (>=5/feat) | 85 |
| **Tier 2** | `tests/e2e-drop-parity/tier2-boundary-corner.test.ts` | Boundary, negative, edge and out-of-bounds cases | >= 85 (>=5/feat) | 85 |
| **Tier 3** | `tests/e2e-drop-parity/tier3-cross-feature-combinations.test.ts` | Multi-subsystem pairwise interaction matrices | >= 15 | 16 |
| **Tier 4** | `tests/e2e-drop-parity/tier4-real-world-scenarios.test.ts` | End-to-end multi-tick combat, drop dispersion, and farm runs | >= 10 | 12 |
| **Total** | | **Comprehensive Drop Parity Test Suite** | **>= 195** | **198** |
---
## 2. Authoritative Ground Truth Oracles
Every test in this suite derives its expected values directly from authoritative Blizzard v1.13c artifacts:
1. **MPQ Data Tables (`/usr/local/google/home/taodao/d2-data`)**:
- `Patch_D2.mpq:data\global\excel\difficultylevels.txt`: Exact base upgrade divisors (`UberCodeOddsNormal`, `UberCodeOddsNightmare`, `UberCodeOddsHell`).
- `Patch_D2.mpq:data\global\excel\monstats.txt`: 734 monster kinds, `boss = 1` flag, and multi-difficulty `TreasureClass1..4`.
- `Patch_D2.mpq:data\global\excel\superuniques.txt`: 66 unique bosses and difficulty-specific TCs.
- `Patch_D2.mpq:data\global\excel\TreasureClassEx.txt`: Complete TC hierarchy, `picks`, negative picks (`picks < 0`), Countess item/rune tables, quest first-kill boss TCs.
- `Patch_D2.mpq:data\global\excel\ItemRatio.txt`: Quality ratios, divisors, and base chances for Magic, Rare, Set, Unique.
- `Patch_D2.mpq:data\global\excel\weapons.txt`, `armor.txt`, `misc.txt`: Base item `dropsound` and `dropsfxframe` definitions.
- `Patch_D2.mpq:data\global\excel\Levels.txt`: 138 level zones, area levels, and monster density configurations.
2. **D2MOO Decompiled C++ Assembly (`D2Game.dll`, `D2Common.dll`)**:
- `D2Game/src/ITEMS/Items.cpp:2142-2166`: Exact `/players N` NoDrop exponential dampening formula:
$$\text{eff} = p + \left\lfloor\frac{g - p}{2}\right\rfloor, \quad \text{ratio} = \left(\frac{\text{NoDrop}}{\text{NoDrop} + \text{TotalProb}}\right)^\text{eff}, \quad \text{NewNoDrop} = \left\lfloor \frac{\text{TotalProb} \times \text{ratio}}{1 - \text{ratio}} \right\rfloor$$
- `D2Game/src/ITEMS/Items.cpp:2346-2433`: Magic Find diminishing returns equations:
$$\text{Unique} = \left\lfloor\frac{250 \times \text{MF}}{\text{MF} + 250}\right\rfloor, \quad \text{Set} = \left\lfloor\frac{500 \times \text{MF}}{\text{MF} + 500}\right\rfloor, \quad \text{Rare} = \left\lfloor\frac{600 \times \text{MF}}{\text{MF} + 600}\right\rfloor, \quad \text{Magic} = \text{MF}$$
- `D2Common/src/Units/Units.cpp:3103`: Inventory gold limit:
$$\text{GoldLimit} = 10,000 \times \text{Level}$$
- `D2Game/src/MONSTER/MonsterUnique.cpp:269, 294`: Elite monster level modifiers:
$$\text{Champion} = \text{Level} + 2, \quad \text{Unique} / \text{Minion} = \text{Level} + 3$$
- `D2Game/src/ITEMS/ItemMode.cpp:6084`: Countess 6-item drop ceiling and quadrant spiral discrete collision scan.
---
## 3. Test Runner & Execution Commands
The test runner is Vitest v2.1.9 running on Node.js v22.
### Running Individual Tiers
```bash
# Tier 1: Feature Coverage (85 tests)
npx vitest run tests/e2e-drop-parity/tier1-feature-coverage.test.ts
# Tier 2: Boundary & Corner Cases (85 tests)
npx vitest run tests/e2e-drop-parity/tier2-boundary-corner.test.ts
# Tier 3: Cross-Feature Interactions (16 tests)
npx vitest run tests/e2e-drop-parity/tier3-cross-feature-combinations.test.ts
# Tier 4: Real-World Workload Scenarios (12 tests)
npx vitest run tests/e2e-drop-parity/tier4-real-world-scenarios.test.ts
```
### Running Entire E2E Drop Parity Suite
```bash
npx vitest run tests/e2e-drop-parity/
```
### Full Workspace Verification
```bash
# Typecheck
npm run typecheck
# Comprehensive verification
npx vitest run tests/e2e-drop-parity/ tests/monster-treasure-class.test.ts tests/ground-items-scatter-bounce.test.ts
```
---
## 4. Feature Coverage Matrix (Issues #412–#428)
| # | Feature | Issue | Tier 1 (Coverage) | Tier 2 (Boundary) | Tier 3 (Pairwise) | Tier 4 (Workload) |
|---|---|:---:|:---:|:---:|:---:|:---:|
| 1 | DifficultyLevels.txt & Upgrade Divisors | #412 | 5 tests | 5 tests | P2, P9, P13 | S11 |
| 2 | Remove Silent Fallbacks | #413 | 5 tests | 5 tests | P3, P8, P16 | S1 |
| 3 | Delete rollDrop Dead Code | #414 | 5 tests | 5 tests | P16 | S12 |
| 4 | Act Boss MonsterRank & monsterType = 4 | #415 | 5 tests | 5 tests | P1, P8 | S2, S4, S5, S11 |
| 5 | Elite mlvl Calculation (+2, +3, Demote) | #416 | 5 tests | 5 tests | P2, P9, P13 | S1 |
| 6 | Magic Find Wiring & Diminishing Returns | #417 | 5 tests | 5 tests | P1, P8 | S4 |
| 7 | /players N NoDrop Scaling | #418 | 5 tests | 5 tests | P1, P12 | S3 |
| 8 | Physical Gold Piles (3 Tiers, Cap) | #419 | 5 tests | 5 tests | P3, P11, P14 | S7 |
| 9 | Death Animation Drop Gating (DT->DD) | #420 | 5 tests | 5 tests | P4, P11 | S1, S5 |
| 10 | Drop SFX (dropsound, dropsfxframe) | #421 | 5 tests | 5 tests | P4, P10 | S2 |
| 11 | Quadrant Spiral Drop Coords | #422 | 5 tests | 5 tests | P4, P10, P11 | S4, S10 |
| 12 | DC6 Flippy Coverage & No Color Box | #423 | 5 tests | 5 tests | P5 | S12 |
| 13 | Ground Label Gray Override (Eth/Sock) | #424 | 5 tests | 5 tests | P5 | S2 |
| 14 | Pickup Radius & 2-Pass Auto-Belt | #425 | 5 tests | 5 tests | P6, P15 | S1, S8 |
| 15 | Multiplayer Lockstep Drop Sync | #427 | 5 tests | 5 tests | P7, P14 | S9 |
| 16 | Quest Drops (Countess, Boss, Hellforge)| #426 | 5 tests | 5 tests | P7, P8, P10, P12| S2, S3, S6 |
| 17 | Full-Spectrum Drop Verification | #428 | 5 tests | 5 tests | P9, P15, P16 | S10, S12 |
---
## 5. Coverage Thresholds & Quality Gates
1. **Pass Rate Gate**: 100% pass rate across all 198 tests. Zero tests skipped, zero flaky tests.
2. **Determinism Gate**: All drop rolling simulations MUST be seeded with deterministic `D2Rng` seeds to ensure repeatable runs.
3. **Anti-Silent Failure Invariant**: Missing data tables, invalid monster kinds, or unmapped TCs must raise explicit errors; fallbacks to synthetic constants or default TCs are strictly prohibited.
4. **Performance Gate**: The entire 4-tier suite (198 tests) must execute in under 15 seconds.