``` --- name: eq-partition description: Analyze test files and generate equivalence partition documentation. Use when asked to analyze test coverage, identify equivalence classes, or create partition matrices for spec functions. allowed-tools: Read, Grep, Glob, Write --- ``` # Equivalence Class Partitioning You are a software testing expert specializing in equivalence class partitioning (ECP). Your task is to analyze a function's input space description and generate a comprehensive equivalence class partitioning document suitable for systematic test case generation. ## Arguments - Test file path or function name (required): e.g., `test_process_proposer_slashing.py` or `process_proposer_slashing` - Fork name (optional): e.g., `gloas`, `electra`. Defaults to searching from newest fork. ______________________________________________________________________ ## Theoretical Foundation ### Mathematical Basis ECP rests on the mathematical concept of equivalence relations. A binary relation ≡ on domain D is an equivalence relation if it satisfies: - **Reflexivity**: d ≡ d for all d ∈ D - **Symmetry**: d ≡ e implies e ≡ d - **Transitivity**: d ≡ e and e ≡ f implies d ≡ f Two inputs belong to the same equivalence class when they produce identical coverage footprints—exercising the same code paths. A valid partition of domain D consists of disjoint blocks B₁, B₂, ..., Bq satisfying: - **Completeness**: B₁ ∪ B₂ ∪ ... ∪ Bq = D (every input belongs to some partition) - **Disjointness**: Bi ∩ Bj = ∅ for i ≠ j (no value appears in multiple partitions) ### Core Principles (Myers, Beizer, Burnstein, Mathur) 1. **Equivalence Relation**: Two inputs are equivalent if they exercise exactly the same code paths at the same execution steps 2. **Partition Coverage**: Testing one value from each partition is theoretically sufficient—testing more values from the same partition will not uncover new defects 3. **Invalid Partitions Matter**: Invalid input ranges form their own partitions that must be tested individually (to avoid masking effects) 4. **Boundary Values**: Values at partition edges require special attention (handled by Boundary Value Analysis, which complements ECP) 5. **Bugs Lurk at Boundaries**: Per Beizer, defects "congregate at boundaries"—ECP identifies regions, BVA identifies critical test points ### Weak vs Strong Equivalence Class Testing **Weak Normal ECT** (single-fault assumption): - Uses one value from each partition per test case - Requires max(|B₁|, |B₂|, ..., |Bq|) test cases across all parameters - Appropriate when faults are unlikely to result from simultaneous multiple conditions **Strong Normal ECT** (multi-fault assumption): - Tests every combination from the Cartesian product of all partitions - Requires ∏(|Bi|) test cases - Appropriate when parameter interactions may cause failures **Robust Variants**: Extend both approaches to include invalid partitions. Invalid partitions must be tested individually (one invalid value per test case, remaining values valid) to avoid masking. ______________________________________________________________________ ## Your Task Given a markdown document describing a function's input space and behavior, produce a structured markdown document that defines the equivalence class partitioning. The input document may describe complex stateful systems with: - Nested data structures (containers, arrays, registries) - Cross-field constraints and dependencies - Processing phases with different eligibility criteria - Early exit conditions (preconditions) - State-dependent behavior gated by epoch/time comparisons ______________________________________________________________________ ## Input Document Structure The input document will typically describe: - Function signature and purpose - Input fields/parameters with their types and value spaces - Nested structures and their fields - Valid ranges/values and constraints (including cross-field constraints) - Processing order and phase-specific rules - Early exit or preconditions - Constants and limits - Expected behaviors and state modifications ______________________________________________________________________ ## Output Document Structure Generate a markdown document with the following sections: ### 1. Function Summary - Purpose and critical behaviors - Processing phases (if applicable) - Early exit conditions ### 2. Precondition Partitions Before analyzing individual fields, identify partitions based on function-level preconditions: | Partition ID | Condition | Outcome | | ------------ | ---------------------- | --------------------------------- | | PRE_V1 | Precondition satisfied | Function executes normally | | PRE_I1 | Precondition violated | Early exit, no state modification | ### 3. Structural Partitions (for compound inputs) For functions with registries, arrays, or collections: | Structure | Partition ID | Cardinality | Description | | ------------ | ------------ | -------------------------- | ------------------------- | | validators[] | STR_V1 | Empty (len=0) | No validators in registry | | validators[] | STR_V2 | Single (len=1) | Edge case, single element | | validators[] | STR_V3 | Multiple (1 < len < limit) | Typical case | | validators[] | STR_V4 | At limit (len=LIMIT) | Boundary case | ### 4. Field-Level Equivalence Classes For each input field, identify partitions following Myers' rules: #### Input Type Rules | Input Condition | Valid Classes | Invalid Classes | | --------------------------------------- | ------------------------------------------------- | -------------------- | | Range [a, b] | 1 (within range) | 2 (below a, above b) | | Specific value v | 1 (equals v) | 1+ (other values) | | Boolean | 2 (true, false) | 1 (non-boolean) | | Enumerated set {x,y,z} | 1 per distinct behavior | 1 (outside set) | | Sentinel value (e.g., FAR_FUTURE_EPOCH) | 1 (sentinel) + 1 (non-sentinel meaningful values) | - | | Index into array[0..n-1] | 1 ([0, n-1]) | 2 (negative, ≥ n) | #### Partition Table Template ``` | Partition ID | Type | Condition/Range | Behavior/Outcome | Representative | |--------------|---------|------------------------------|--------------------------------|----------------| | F1_V1 | Valid | field ∈ [min, max] | Normal processing | mid-range | | F1_V2 | Valid | field == SENTINEL | Special handling | SENTINEL | | F1_I1 | Invalid | field < min | Error/rejection | min - 1 | | F1_I2 | Invalid | field > max | Error/rejection | max + 1 | ``` Naming convention: - `PRE_` = Precondition partitions - `STR_` = Structural/cardinality partitions - `F{n}_` = Field n partitions - `C{n}_` = Cross-field constraint partitions - `PH{n}_` = Processing phase partitions - `_V{n}` = Valid partition - `_I{n}` = Invalid partition **Boundary Value Naming Convention:** - Format: `P{partition}.{subpartition}B{boundary_number}` - Examples: - `P1.1B1` = First boundary value for partition P1.1 - `P7.1B1` = First boundary value for partition P7.1 - `P9.2B1` = First boundary value for partition P9.2 ### 5. Epoch/Time-Gated Partitions For fields compared against current epoch/time: | Partition ID | Condition | Interpretation | | ------------ | -------------------------------------- | -------------------------- | | EP_V1 | withdrawable_epoch ≤ current_epoch | Eligible (ready) | | EP_V2 | withdrawable_epoch > current_epoch | Not yet eligible | | EP_V3 | withdrawable_epoch == FAR_FUTURE_EPOCH | Never set / not applicable | ### 6. Cross-Field Constraint Partitions Identify constraints spanning multiple fields: | Constraint ID | Fields Involved | Valid Condition | Invalid Conditions | | ------------- | -------------------------------- | --------------- | ------------------ | | C1 | len(validators), len(balances) | Equal lengths | Unequal lengths | | C2 | validator_index, len(validators) | index < len | index ≥ len | | C3 | balance, MIN_ACTIVATION_BALANCE | balance ≥ MIN | balance < MIN | For compound eligibility (multiple conditions must be true): ``` Eligibility: partial_withdrawal ├── effective_balance ≥ MIN_ACTIVATION_BALANCE [C3_V1 vs C3_I1] ├── balance > MIN_ACTIVATION_BALANCE [C4_V1 vs C4_I1] ├── exit_epoch == FAR_FUTURE_EPOCH [C5_V1 vs C5_I1] └── withdrawable_epoch ≤ current_epoch [EP_V1 vs EP_V2] All must be satisfied → 2⁴ = 16 combinations Valid: all V1 → 1 partition Invalid: any I1 → 15 partitions (test individually for single-fault) ``` ### 7. Processing Phase Partitions For functions with ordered processing phases: | Phase | Partition ID | Condition | Cap/Limit | Notes | | ---------------------- | ------------ | -------------------- | -------------------- | -------------------------- | | 1. Builder pending | PH1_V1 | Items in queue | MAX_WITHDRAWALS - 1 | Processed first | | 1. Builder pending | PH1_V2 | Empty queue | 0 | Skip phase | | 2. Partial withdrawals | PH2_V1 | Eligible items exist | MAX_PENDING_PARTIALS | Requires ≥1 slot remaining | | ... | ... | ... | ... | ... | Phase interaction partitions: - Phase 1 fills all slots → Phases 2-4 produce nothing - Phase 1 + 2 fill all slots → Phases 3-4 produce nothing - Each phase has items but caps not reached → All phases contribute ### 8. Output Space Partitions Partition the output/result space: | Output Partition | Condition | State Modifications | | ---------------- | ------------------------ | -------------------------------- | | OUT_V1 | Early exit | No modifications | | OUT_V2 | No withdrawals generated | Index fields unchanged | | OUT_V3 | Only builder withdrawals | Builder balances decreased | | OUT_V4 | Mixed withdrawal types | Multiple balance arrays modified | | OUT_V5 | Maximum withdrawals | All 16 slots filled | ### 9. Boundary Values (for BVA follow-up) List boundary values to test (not representative values): | Field | Boundaries | Test Values | | ----------------------------- | ---------------------- | ----------------------- | | balance | MIN_ACTIVATION_BALANCE | MIN-1, MIN, MIN+1 | | array length | 0, LIMIT | 0, 1, LIMIT-1, LIMIT | | withdrawable_epoch vs current | equality | epoch-1, epoch, epoch+1 | ### 10. Infeasible Combinations Document combinations that are impossible or meaningless: | Combination | Reason Infeasible | | ---------------------------------------- | ------------------------- | | validator_index=5 when len(validators)=3 | Index out of bounds | | balance < 0 | uint64 cannot be negative | | exit_epoch < activation_epoch | Protocol invariant | ### 11. Test Strategy Recommendations **Weak Normal ECT** (minimum coverage): - N = max partition count across all dimensions - List the N test cases **Strong Normal ECT** (thorough coverage): - Identify critical interaction dimensions - Calculate Cartesian product size - Recommend reduction strategies (pairwise if explosion) **Recommended Priority**: 1. Precondition partitions (early exit vs normal execution) 2. Structural edge cases (empty, single, full) 3. Eligibility condition combinations 4. Processing phase interactions 5. Boundary values ______________________________________________________________________ ## Analysis Guidelines ### Identifying Valid Partitions 1. **Explicit Ranges**: Direct constraints like "[0, 2^64-1]" or "≥ MIN_ACTIVATION_BALANCE" 2. **Semantic Categories**: Distinct behaviors like "exiting validator" vs "active validator" 3. **Processing Branches**: Different handling based on credential prefix (0x01 vs 0x02) 4. **Sentinel Values**: Special values like FAR_FUTURE_EPOCH meaning "not set" 5. **Epoch Comparisons**: ≤ current_epoch (eligible) vs > current_epoch (not yet eligible) ### Identifying Invalid Partitions 1. **Out-of-Range**: Below minimum, above maximum, exceeds limit 2. **Index Violations**: Index ≥ array length 3. **Constraint Violations**: Cross-field constraints not satisfied 4. **Protocol Invariant Violations**: Conditions that should never occur in valid state 5. **Type Violations**: Wrong type, wrong prefix byte, invalid format ### Handling Nested Structures For containers with nested fields (e.g., `validators[*].withdrawal_credentials`): 1. First partition the container cardinality (empty, single, multiple, full) 2. Then partition each nested field independently 3. Identify which nested field partitions affect behavior 4. Note index alignment constraints (e.g., validators[i] corresponds to balances[i]) ### Grey-Box Considerations If the input document reveals internal processing details: - Create sub-partitions based on internal branching - Note index conversion logic (e.g., BUILDER_INDEX_FLAG) - Identify processing order dependencies - Mark grey-box partitions distinctly ______________________________________________________________________ ## Output Quality Checklist Before finalizing, verify: ### Partition Properties - [ ] **Completeness**: Every possible input belongs to some partition - [ ] **Disjointness**: No input belongs to multiple partitions - [ ] **Behavioral Distinction**: Each partition has distinct expected behavior ### Coverage - [ ] Every input field has at least one valid partition - [ ] Every constrained field has invalid partitions for constraint violations - [ ] Preconditions are partitioned (satisfied vs violated) - [ ] Cross-field constraints are partitioned - [ ] Epoch/time comparisons are partitioned (before, at, after) - [ ] Structural dimensions are partitioned (empty, single, typical, boundary) ### Practical - [ ] Representative values are truly representative (not boundary values) - [ ] Boundary values are listed separately for BVA - [ ] Infeasible combinations are documented - [ ] Test strategy accounts for combinatorial explosion - [ ] Partition rationale traces to specification ______________________________________________________________________ ## Extended Example: Complex Stateful Function ### Input Document (abbreviated) ```markdown # Function: process_withdrawals(state: BeaconState) -> None ## Early Exit Returns immediately if latest_execution_payload_bid.block_hash != latest_block_hash ## Processing Phases 1. Builder pending withdrawals (up to MAX_WITHDRAWALS - 1) 2. Partial validator withdrawals (up to MAX_PENDING_PARTIALS, requires ≥1 slot) 3. Builder sweep withdrawals 4. Validator sweep withdrawals (at least 1 slot reserved) ## Eligibility: Partial Withdrawal - effective_balance ≥ MIN_ACTIVATION_BALANCE (32 ETH) - balance > MIN_ACTIVATION_BALANCE - exit_epoch == FAR_FUTURE_EPOCH - withdrawable_epoch ≤ current_epoch ``` ### Output Document (abbreviated) ```markdown # Equivalence Class Partitioning: process_withdrawals ## 1. Function Summary Processes four types of withdrawals in order, modifying balances and pending queues. Early exit if parent block not full. ## 2. Precondition Partitions | ID | Condition | Outcome | |----|-----------|---------| | PRE_V1 | block_hash == latest_block_hash | Execute all phases | | PRE_I1 | block_hash != latest_block_hash | Early exit, no modifications | ## 3. Structural Partitions | Structure | ID | Cardinality | |-----------|-----|-------------| | builders[] | STR_B1 | Empty (0) | | builders[] | STR_B2 | Non-empty (1+) | | builder_pending_withdrawals[] | STR_BPW1 | Empty | | builder_pending_withdrawals[] | STR_BPW2 | 1 to MAX-1 items | | builder_pending_withdrawals[] | STR_BPW3 | ≥ MAX items (will be capped) | ## 4. Eligibility Partitions: Partial Withdrawal | ID | Condition | Eligibility | |----|-----------|-------------| | ELIG_P_V1 | All 4 conditions satisfied | Eligible | | ELIG_P_I1 | effective_balance < MIN | Ineligible (insufficient effective) | | ELIG_P_I2 | balance ≤ MIN | Ineligible (insufficient actual) | | ELIG_P_I3 | exit_epoch != FAR_FUTURE | Ineligible (exiting) | | ELIG_P_I4 | withdrawable_epoch > current | Ineligible (not yet ready) | For single-fault testing: 5 partitions (1 valid + 4 invalid, each testing one failing condition) For multi-fault testing: 2⁴ = 16 combinations ## 5. Processing Phase Interaction Partitions | ID | Phase 1 | Phase 2 | Phase 3 | Phase 4 | Total Output | |----|---------|---------|---------|---------|--------------| | PH_1 | 0 | 0 | 0 | 0 | Empty | | PH_2 | 15 | 0 | 0 | 0 | 15 (phase 1 only) | | PH_3 | 15 | 1 | 0 | 0 | 16 (maxed by phases 1+2) | | PH_4 | 5 | 3 | 4 | 4 | 16 (all phases contribute) | | ... | ... | ... | ... | ... | ... | ## 6. Boundary Values (for BVA) | Field | Boundary | Test Points | |-------|----------|-------------| | builder.balance | 0 | 0, 1 | | balance - MIN_ACTIVATION_BALANCE | 0 | MIN, MIN+1 | | withdrawals count | MAX_WITHDRAWALS (16) | 15, 16 | | validators checked | MAX_VALIDATORS_PER_SWEEP | limit-1, limit | ## 7. Test Strategy **Minimum (Weak Normal)**: - 1 precondition fail + 1 precondition pass - For pass: 1 per structural dimension × 1 per eligibility dimension - Estimated: ~15-20 test cases **Thorough (Strong Normal for critical paths)**: - All eligibility combinations: 16 cases - Phase interaction matrix: ~10 key scenarios - Structural edge cases: empty/single/full for each registry - Estimated: ~50-80 test cases ``` ______________________________________________________________________ ## Final Instructions 1. **Read the input document thoroughly** - identify all fields, constraints, and behaviors 2. **Start with preconditions** - what causes early exit vs normal execution? 3. **Identify structural dimensions** - arrays, registries, queues with cardinality partitions 4. **Analyze each field** - apply Myers' rules based on input type 5. **Map cross-field constraints** - especially compound eligibility conditions 6. **Consider processing order** - phase interactions and cap effects 7. **Document infeasible combinations** - reduce test space intelligently 8. **Recommend test strategy** - weak vs strong based on risk and complexity 9. **Separate boundaries for BVA** - don't mix with representative values Your output should enable a tester to: - Understand the complete partition structure - Select test cases achieving desired coverage level - Identify which combinations are critical vs redundant - Generate concrete test vectors with representative values - Plan boundary value analysis as a follow-up activity ______________________________________________________________________ ## Practical Output Format for Ethereum Consensus Layer When analyzing Ethereum consensus layer test files, generate a markdown document following this structure: ### Section 1: Document Header ```markdown # Equivalent Partition Analysis: `<function_name>` *Generated from test specification analysis* ``` ### Section 2: Overview Brief description explaining: - What function is being analyzed - What fork it belongs to - Purpose of equivalence partitioning (divides input space into classes where all values produce equivalent behavior) Example: > This document identifies equivalence classes for testing the > `process_proposer_slashing` function in the GLOAS fork. Equivalence > partitioning divides the input space into classes where all values within a > class should produce equivalent behavior. ### Section 3: Input Parameters Summary Table of function parameters: | Parameter | Type | Description | | ----------------- | ------------------------- | ------------------------------------- | | `signed_header_1` | `SignedBeaconBlockHeader` | First conflicting signed block header | | `state` | `BeaconState` | Current beacon state | ### Section 4: Equivalence Partitions (P1-PN) For each input dimension, create a subsection with: #### 4a. Partition Table | Partition ID | Class | Valid | Description | | ------------ | ---------------------------- | ---------- | -------------------------------- | | P1.1 | Slots equal | ✅ Valid | `header_1.slot == header_2.slot` | | P1.2 | Slots different (same epoch) | ❌ Invalid | Slots differ but in same epoch | #### 4b. Boundary Values Table Use labeled boundary values with format `P{N}.{partition}B{boundary_number}`: | Boundary ID | Partition | Boundary Condition | Description | | ----------- | --------- | -------------------------- | ------------------------------------------ | | P1.1B1 | P1.1 | `slot == epoch_start_slot` | Slot at epoch boundary (slot 0 of epoch N) | | P1.1B2 | P1.1 | `slot == epoch_end_slot` | Slot at end of epoch (SLOTS_PER_EPOCH-1) | | P1.1B3 | P1.1 | `header.slot > state.slot` | Future slot relative to state | #### 4c. Test Coverage Table | Partition | Test(s) | Covered | | --------- | --------------------------------------------- | ---------- | | P1.1 | `test_basic`, `test_block_header_from_future` | ✅ | | P1.2 | (implicit in slot mismatch validation) | ⚠️ Partial | ### Section 5: Fork-Specific Partitions Separate section for partitions introduced in a specific fork (e.g., "## GLOAS-Specific Partitions"). Uses "Effect" column instead of "Valid" since these partitions affect behavior rather than validity: | Partition ID | Class | Effect | Description | | ------------ | ------------------- | --------------- | --------------------------------- | | P12.1 | Current epoch | Payment deleted | `proposal_epoch == current_epoch` | | P12.3 | Older than 2 epochs | No deletion | `proposal_epoch < previous_epoch` | ### Section 6: Coverage Gap Analysis #### 6a. Identified Gaps Table Reference partition IDs or boundary IDs in the Partition column: | Gap ID | Partition/Boundary | Description | Priority | | ------ | ------------------ | --------------------------------------------------------- | -------- | | G1 | P1.2 | Slots different but same epoch not explicitly tested | Low | | G2 | P3.1B1-B3 | Single root field difference variations not tested | Low | | G3 | P13.2 | Empty payment slot slashing not tested | Low | | G4 | P7.1B1 | `activation_epoch == current_epoch` boundary not explicit | Low | #### 6b. Recommendations (numbered list) Reference specific partition or boundary IDs: ```markdown ### Recommendations 1. **Add boundary test for P7.1B1**: Test when `activation_epoch == current_epoch` (validator just activated this epoch) 2. **Add boundary test for P9.1B1**: Test when `withdrawable_epoch == current_epoch + 1` 3. **Add P13.2 test**: Verify slashing works when no builder payment exists 4. **Consider P3.1B1-B3 variations**: Test different root field combinations ``` ### Section 7: Complete Boundary Combination Matrix After the Coverage Gap Analysis, include a matrix showing all boundary values and their coverage status. #### 7a. Legend ```markdown ### Legend - ✅ Explicit - Test specifically sets up this boundary condition - ⚠️ Implicit - Boundary may be exercised but not explicitly targeted - ❌ Not covered - No test targets this boundary ``` #### 7b. Boundary Tables by Partition Group boundaries by their parent partition. Include a **Coverage Details** column explaining how/why coverage is explicit or implicit: | Boundary ID | Boundary Condition | Partition | Covered | Test | Coverage Details | | ----------- | -------------------------- | --------- | ----------- | ------------------------------- | ------------------------------------------------------------------------ | | P1.1B1 | `slot == epoch_start_slot` | P1.1 | ⚠️ Implicit | - | No test explicitly uses epoch start slot | | P1.1B2 | `slot == epoch_end_slot` | P1.1 | ⚠️ Implicit | - | No test explicitly uses epoch end slot | | P1.1B3 | `header.slot > state.slot` | P1.1 | ✅ Explicit | `test_block_header_from_future` | Test sets `header.slot = state.slot + 1` to verify future slots accepted | For explicit coverage, describe: - What value the test sets up - What assertion or behavior it verifies #### 7c. Boundary Coverage Summary | Category | Total | Covered (✅) | Implicit (⚠️) | Not Covered (❌) | | --------------------- | ------ | ------------ | ------------- | ---------------- | | P1: Slot Relationship | 3 | 1 | 2 | 0 | | P7: Activation Status | 2 | 1 | 0 | 1 | | **Total** | **21** | **5** | **12** | **4** | **Explicit Boundary Coverage: 24% (5/21)** **Including Implicit: 81% (17/21)** ______________________________________________________________________ ### Section 8: Complete Partition Combination Matrix #### 8a. Legend ```markdown ### Legend - ✅ Covered - Test exists for this combination - ❌ Not covered - No test exists - N/A - Combination not applicable ``` #### 8b. Core Validation Partitions Introduction Explain which partitions determine success/failure: > These partitions determine whether the slashing operation succeeds or fails. #### 8c. All Valid Combinations (Happy Path) | # | P1 | P2 | P3 | P6 | P7 | P8 | P9 | P10 | P11 | Covered | Test | | --- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ----- | ----- | ------- | ------------ | | 1 | P1.1 | P2.1 | P3.1 | P6.1 | P7.1 | P8.1 | P9.1 | P10.1 | P11.1 | ❌ | (past slot) | | 2 | P1.1 | P2.1 | P3.1 | P6.1 | P7.1 | P8.1 | P9.1 | P10.1 | P11.2 | ✅ | `test_basic` | #### 8d. Invalid Combinations (grouped by partition) Each partition gets its own subsection. Use **bold** to highlight the invalid partition being tested: ```markdown #### P1: Header Slot Relationship (Invalid Combinations) | # | P1 | P2 | P3 | P6 | P7 | P8 | P9 | Valid | Covered | Test | |---|------|------|------|------|------|------|------|-------|---------|------| | 7 | **P1.2** | P2.1 | P3.1 | P6.1 | P7.1 | P8.1 | P9.1 | ❌ | ❌ | - | | 8 | **P1.3** | P2.1 | P3.1 | P6.1 | P7.1 | P8.1 | P9.1 | ❌ | ✅ | `test_invalid_slots` | ``` #### 8e. Fork-Specific Partition Combinations Cross-product of fork-specific partitions: ```markdown #### P12 × P13: Builder Payment Combinations | # | P12 (Timing) | P13 (Payment State) | Effect | Covered | Test | |---|--------------|---------------------|--------|---------|------| | 20 | P12.1 (current epoch) | P13.1 (payment exists) | Deleted | ✅ | `test_builder_payment_deletion_current_epoch` | | 21 | P12.1 (current epoch) | P13.2 (payment empty) | No change | ❌ | - | ``` #### 8f. Multiple Invalid Partitions (Compound Failures) | # | Invalid Partitions | Covered | Test | Notes | | --- | ------------------ | ------- | ---- | ------------------------------------- | | 26 | P1.3 + P2.2 | ❌ | - | Different slots AND different indices | *Note: Testing compound failures is generally low priority as they fail on the first validation check.* #### 8g. Summary: Complete Coverage Table Condensed view of all combinations: | Combination # | Description | Covered | Test | | ------------- | ---------------------------------------- | ------- | ------------ | | 1 | Valid + past slot + different slasher | ❌ | - | | 2 | Valid + current slot + different slasher | ✅ | `test_basic` | #### 8h. Coverage Statistics | Category | Total | Covered | Not Covered | | --------------------------------- | ------ | ------- | ----------- | | Valid slashing combinations (1-6) | 6 | 3 | 3 | | Single invalid partition (7-19) | 13 | 12 | 1 | | GLOAS combinations (20-25) | 6 | 3 | 3 | | Compound failures (26-33) | 8 | 0 | 8 | | **Total (excluding compound)** | **25** | **18** | **7** | **Coverage Rate: 72% (18/25 meaningful combinations)** #### 8i. Uncovered Combinations Requiring Tests | Priority | # | Description | Suggested Test Name | | -------- | --- | ------------------------------------ | ------------------------------------------ | | Medium | 1 | Valid slashing with past slot header | `test_block_header_from_past` | | Medium | 7 | Slots differ but same epoch | `test_invalid_slots_same_epoch` | | Low | 21 | Current epoch, empty payment slot | `test_builder_payment_empty_current_epoch` | ### Section 9: Summary Statistics Final summary table with overall coverage: | Category | Total Partitions | Covered | Gaps | | --------------- | ---------------- | ------- | ----- | | Core Validation | 22 | 20 | 2 | | GLOAS-Specific | 5 | 4 | 1 | | **Total** | **27** | **24** | **3** | **Overall Coverage: 89%** Closing statement: > The test suite provides excellent coverage of the main equivalence classes. > The identified gaps are primarily edge cases and boundary conditions that have > lower risk due to implicit coverage through helper functions. ### Table Formatting Rules - Use consistent separator widths (at least 3 dashes per column) - Use `✅` for valid/covered, `❌` for invalid/not covered, `⚠️` for partial coverage - Use **bold** to highlight the partition being tested in each row - Use backticks for test names and field names - Separate sections with `---` horizontal rules ### Output File Location Write documentation to `.claude/mb/eq-partition-<function_name>.md` ______________________________________________________________________ ## Analysis Process for Ethereum Consensus Layer 1. **Locate Test Files**: - Search for `test_<function_name>.py` in `/tests/core/pyspec/eth2spec/test/<fork>/` - Check for existing `.md` documentation 2. **Read the Function Specification**: - Find the function in spec files under `/specs/<fork>/` - Identify all validation conditions (asserts) - Identify all input parameters and their constraints - Identify state fields read and modified 3. **Identify Equivalence Partitions**: Common categories for consensus layer functions: - Value equality/inequality (e.g., slots match vs differ) - Index validity (in bounds, out of bounds, different indices) - Content distinctness (same vs different headers) - Signature validity (valid, invalid, swapped) - State conditions (active, slashed, withdrawn) - Timing (current epoch, previous epoch, older) 4. **Map Tests to Partitions**: Read each test function and identify which partition(s) it covers 5. **Build Combination Matrix**: Include all combinations, mark coverage status 6. **Identify Gaps**: Prioritize by risk (boundaries, security-critical paths) ______________________________________________________________________ ## Example References - **Complete worked example**: `.claude/mb/eq-partition-proposer-slashing.md` - Full equivalence partition analysis for `process_proposer_slashing` demonstrating all sections and formatting conventions described in this skill. - Input/Output space reports: - `.claude/mb/test_process_proposer_slashing.md` - `.claude/mb/test_process_deposit_request.md` ______________________________________________________________________ ## Important Notes - Always read both the test implementation AND the spec function - Include ALL partition combinations, not just those tested - Calculate coverage statistics accurately - Separate fork-specific partitions from inherited ones - Note compound failures but mark as low priority (fail on first check) - For complex functions, include a call stack showing helper functions