Skip to content

Commit bcd2d5d

Browse files
committed
[UDF HLD] Expand section 10 with detailed test scenarios
Replaces the high-level test categories in section 10 with explicit test scenarios drawn from the sonic-mgmt UDF suite, following the Step / Goal / Expected results format used in the Overlay ECMP HLD. 10.2 System Tests now covers: - Baseline programming - End-to-end traffic - UDF/ACL dependency and teardown order - ACL rule priority - Forward reference resolution - Multiple selectors per group - SAI attribute correctness (all 4 match types, 3 bases, auto-mask, match-presence regressions) - Match-type traffic filtering (L2 / L4 / IPv6) - Reference counting (UDF_MATCH dedup, UDF_GROUP refcount layers, ACL_RULE refcount on selectors) - Immutability and idempotency - Validation edge cases 10.3 Negative Tests: - Invalid CONFIG_DB - Selector field validation Each subsection references the corresponding test class(es) in the sonic-mgmt suite (tests/udf/test_udf.py, parallel PR -- Open Item #9). Addresses prsunny review comment. Signed-off-by: Satishkumar Rodd <srodd@nexthop.ai>
1 parent 3b6d857 commit bcd2d5d

1 file changed

Lines changed: 140 additions & 10 deletions

File tree

doc/udf/UDF_HLD.md

Lines changed: 140 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -637,21 +637,151 @@ redis-cli -n 1 HGETALL "ASIC_STATE:SAI_OBJECT_TYPE_UDF_GROUP:<oid>"
637637
## 10. Testing Requirements/Design
638638

639639
### 10.1 Unit Tests
640-
- UdfGroup: Create/remove, validation (length, type)
641-
- UdfMatch: L2/L3/GRE matching, priority validation
642-
- Udf: Dependency handling, offset/base validation
640+
641+
Orchagent unit tests live in `sonic-swss/tests/mock_tests/udforch_ut.cpp`, linked into the existing aclorch unit test binary.
642+
643+
- UdfGroup: create/remove, validation (length, field_type)
644+
- UdfMatch: L2 / L3 / GRE / L4_DST_PORT matching, priority validation
645+
- Udf: dependency handling, offset/base validation
643646
- UdfOrch: CONFIG_DB subscription, group OID resolution, ref-count tracking
644647

645648
### 10.2 System Tests
646-
- **End-to-End**: Complete UDF + ACL configuration, packet matching
647-
- **ACL Integration**: UDF fields in ACL tables/rules, dynamic resolution
648-
- **Error Handling**: SAI failures, invalid configs, missing dependencies
649-
- **Scale**: Max objects, performance (< 1s for 100 objects)
649+
650+
System tests live in `sonic-net/sonic-mgmt` at `tests/udf/test_udf.py` (sonic-mgmt PR — Open Item #9). Topology: one DUT + PTF (`pytest.mark.topology("t0", "t1")`). All CONFIG_DB writes go through `sonic-cfggen -j -w`; SAI object correctness is verified by diffing ASIC_DB OID sets before and after each operation.
651+
652+
Module baseline (programmed by the suite's setup fixture):
653+
654+
```
655+
UDF|G0 length=3 field_type=GENERIC
656+
UDF|G1 length=3 field_type=GENERIC
657+
UDF_SELECTOR|G0|udp_l4 select_base=L4 select_offset=0 match_l3_type=0x11
658+
UDF_SELECTOR|G0|proto18_l3 select_base=L3 select_offset=0 match_l3_type=0x12
659+
UDF_SELECTOR|G1|proto18_l3 select_base=L3 select_offset=0 match_l3_type=0x12
660+
ACL_TABLE_TYPE|T1 MATCHES=IN_PORTS,G0,G1 ACTIONS=PACKET_ACTION,COUNTER
661+
ACL_TABLE|TABLE1 type=T1 ports=<UP intf> stage=ingress
662+
ACL_RULE|TABLE1|RULE_A priority=101 G0=0x33/0xff G1=0x44/0xff PACKET_ACTION=DROP
663+
ACL_RULE|TABLE1|RULE_B priority=101 G0=0x34/0xff G1=0x45/0xff PACKET_ACTION=DROP
664+
```
665+
666+
UDP traffic uses `sport=0x3333 / dport=0x3333`, producing 3 bytes of `0x33` at L4 offset 0 (matches `RULE_A`'s G0 pattern).
667+
668+
#### 10.2.1 Baseline programming
669+
670+
| Step | Goal | Expected results |
671+
|-|-|-|
672+
| Apply baseline config (UDF, selectors, ACL_TABLE_TYPE, ACL_TABLE, RULE_A, RULE_B) | Pipeline programs cleanly | ASIC_DB has expected UDF_GROUP / UDF_MATCH / UDF / ACL_TABLE / ACL_ENTRY OIDs; UDF_GROUP refcount = 4 (TABLE_TYPE + TABLE + RULE_A + RULE_B) |
673+
674+
#### 10.2.2 End-to-end traffic
675+
676+
UDP at L4 offset 0; G0 length=3 extracts 3 bytes; rule matches `0x33/0xff` per byte.
677+
678+
| Step | Goal | Expected results |
679+
|-|-|-|
680+
| Install `RULE_UDP` (G0=0x33/0xff, priority=200); send 500 UDP packets `sport=0x3333 dport=0x3333` | UDF match — drop | `RULE_UDP` counter delta ≥ 50 |
681+
| Send 500 UDP packets `sport=0x4444 dport=0x4444` | UDF non-match — forward | `RULE_UDP` counter delta ≤ 10 |
682+
| Send 500 UDP packets `sport=0x3232 dport=0x3232` | UDF mask check | No match (mask 0xff requires exact 0x33) |
683+
| Delete `RULE_UDP` from CONFIG_DB | ACL rule remove | `ACL_ENTRY` OID for `RULE_UDP` removed; G0 selectors retained |
684+
685+
#### 10.2.3 UDF/ACL dependency and teardown order
686+
687+
| Step | Goal | Expected results |
688+
|-|-|-|
689+
| Delete `UDF\|G0` while selectors and rules still reference it | Wrong-order delete — recoverable | UDF_GROUP retained; orchagent logs error; correct-order delete after still succeeds |
690+
| Top-down teardown: rules → selectors → group | Ordered teardown | All ACL_ENTRY / UDF / UDF_GROUP OIDs removed in dependency order; recreate works |
691+
692+
#### 10.2.4 ACL rule priority
693+
694+
| Step | Goal | Expected results |
695+
|-|-|-|
696+
| Install `R_LOW` (priority=50, G0=0x33) and `RULE_UDP` (priority=200, G0=0x33); send matching UDP | Higher rule priority wins | `RULE_UDP` counter increments; `R_LOW` does not |
697+
698+
#### 10.2.5 Forward reference resolution
699+
700+
| Step | Goal | Expected results |
701+
|-|-|-|
702+
| Write `ACL_TABLE_TYPE\|T_FWD` (references `G_FWD`) before `UDF\|G_FWD` and `UDF_SELECTOR\|G_FWD\|test` exist; then create them | Forward reference resolves | TABLE_TYPE OID appears only after `G_FWD` + selector arrive |
703+
704+
#### 10.2.6 Multiple selectors per group
705+
706+
| Step | Goal | Expected results |
707+
|-|-|-|
708+
| Baseline: G0 with 2 selectors, G1 with 1 selector | Distinct selectors — distinct OIDs | ≥ 2 SAI UDF OIDs for G0, ≥ 1 for G1; distinct match configs produce distinct UDF_MATCH OIDs |
709+
710+
#### 10.2.7 SAI attribute correctness
711+
712+
Covers all four match-type round-trips, all three base round-trips, auto-mask fill, and match-presence regressions.
713+
714+
| Step | Goal | Expected results |
715+
|-|-|-|
716+
| Selector `match_l2_type=0x0800` | L2_TYPE attr round-trip | UDF_MATCH OID has `SAI_UDF_MATCH_ATTR_L2_TYPE = 0x0800` |
717+
| Selector `match_l3_type=0x06` | L3_TYPE attr round-trip | UDF_MATCH OID has `SAI_UDF_MATCH_ATTR_L3_TYPE = 0x06` |
718+
| Selector `match_gre_type=0x6558` | GRE_TYPE attr round-trip | UDF_MATCH OID has `SAI_UDF_MATCH_ATTR_GRE_TYPE = 0x6558` |
719+
| Selector `match_l4_dst_port=0x12B7` | L4_DST_PORT attr round-trip | UDF_MATCH OID has `SAI_UDF_MATCH_ATTR_L4_DST_PORT_TYPE = 0x12B7` |
720+
| Selector `match_l3_type=0x06` with no explicit mask | Auto-mask fill | UDF_MATCH `L3_TYPE` mask = 0xFF |
721+
| Selector `select_base=L2 select_offset=12` | L2 base round-trip | UDF OID has `SAI_UDF_ATTR_BASE = SAI_UDF_BASE_L2` |
722+
| Selector `select_base=L3 select_offset=4` | L3 base round-trip | UDF OID has BASE = `SAI_UDF_BASE_L3` |
723+
| Selector `select_base=L4 select_offset=0` | L4 base round-trip | UDF OID has BASE = `SAI_UDF_BASE_L4` |
724+
| Selector `match_l4_dst_port=0` with explicit `mask=0xFFFF` | Port-0 match — explicit | UDF_MATCH OID has L4_DST_PORT=0, MASK=0xFFFF |
725+
| Selector `match_l4_dst_port=0` with no mask | Port-0 match — auto-fill | UDF_MATCH OID present; port-0 is matchable |
726+
| Selector with only `match_l2_type=0x0800` (no other match fields) | Single-field match | UDF_MATCH OID created with L2_TYPE attr |
727+
728+
#### 10.2.8 Match-type traffic filtering
729+
730+
| Step | Goal | Expected results |
731+
|-|-|-|
732+
| Selector `match_l2_type=0x0800`; send IPv4 UDP | L2 ethertype filter | ACL counter increments |
733+
| Selector `match_l4_dst_port=0x12B7`; send UDP with `dport=4791` | L4 dst-port match | ACL counter increments |
734+
| Selector `match_l4_dst_port=0x12B7`; send UDP with `dport=80` | L4 dst-port non-match | No counter increment |
735+
| Selector `match_l2_type=0x86DD`; send IPv6 UDP | L2 match — IPv6 | ACL counter increments |
736+
737+
#### 10.2.9 Reference counting
738+
739+
Covers UDF_MATCH dedup across groups, UDF_GROUP refcount across ACL layers, and ACL_RULE refcount on selectors.
740+
741+
| Step | Goal | Expected results |
742+
|-|-|-|
743+
| Two selectors in different groups with identical match config | UDF_MATCH dedup | One shared UDF_MATCH OID; removing one selector retains it; removing both frees it |
744+
| `ACL_TABLE_TYPE\|T1` references G0 (no TABLE or rules) | TABLE_TYPE refcount holds | Deleting G0 rejected |
745+
| Add `ACL_TABLE\|TABLE1` referencing T1 | TABLE refcount independent | Deleting TABLE_TYPE alone rejected while TABLE references G0 |
746+
| Two TABLEs both reference T1 | Refcount stacks | Deleting one TABLE leaves G0 still held |
747+
| With RULE_A + RULE_B referencing G0 (G0 has 2 selectors), delete one selector | Intermediate selector deletable | First selector removed; G0 still programmed |
748+
| After full ACL teardown, delete the last G0 selector | Last selector deletable | Last selector removed cleanly when refcount = 0 |
749+
750+
#### 10.2.10 Immutability and idempotency
751+
752+
| Step | Goal | Expected results |
753+
|-|-|-|
754+
| Re-write `UDF_SELECTOR\|G0\|udp_l4` with identical values | Identical SET — no-op | No ASIC_DB churn; OIDs unchanged |
755+
| Delete `UDF\|G0` while selectors reference it | Delete-while-referenced — recoverable | UDF_GROUP retained; correct delete sequence after succeeds |
756+
| Replay identical SET twice on a committed selector | Idempotent SET — no refcount leak | Single delete frees UDF_MATCH cleanly |
757+
758+
#### 10.2.11 Validation edge cases
759+
760+
| Step | Goal | Expected results |
761+
|-|-|-|
762+
| ACL_RULE references `G_T` which is in udforch but NOT in TABLE's MATCHES | UDF outside MATCHES — accepted | ACL_ENTRY OID created |
763+
| Delete non-existent `UDF_SELECTOR\|NONEXISTENT\|phantom` | Double-delete — no-op | No ASIC_DB change |
764+
| Delete non-existent `UDF\|NONEXISTENT_GROUP` | Double-delete (group) — no-op | No ASIC_DB change |
765+
| Delete `ACL_TABLE_TYPE\|T1` while `ACL_TABLE\|TABLE1` references it | TABLE_TYPE delete blocked by TABLE | TABLE_TYPE retained; error logged |
650766

651767
### 10.3 Negative Tests
652-
- Invalid type/priority/base/offset/length
653-
- Missing mandatory fields
654-
- Dependency violations
768+
769+
#### 10.3.1 Invalid CONFIG_DB
770+
771+
| Step | Goal | Expected results |
772+
|-|-|-|
773+
| Push `UDF\|G_ZERO` with `length=0` | YANG length constraint | Write rejected; no UDF_GROUP OID |
774+
| Push `ACL_RULE` with match value `not_a_hex/0xff` | Malformed hex | No ACL_ENTRY OID; orchagent logs error |
775+
| Push `ACL_RULE` referencing non-existent group `G9` | Unresolvable UDF reference | No ACL_ENTRY OID |
776+
| Push `UDF_SELECTOR` with `select_offset=200` | Large in-range offset — no crash | Existing UDF_GROUP / UDF_MATCH / UDF OIDs retained |
777+
778+
#### 10.3.2 Selector field validation
779+
780+
| Step | Goal | Expected results |
781+
|-|-|-|
782+
| Push `UDF_SELECTOR` missing `select_base` | Mandatory field check | Rejected; no UDF_MATCH OID |
783+
| Push `UDF_SELECTOR` with unknown `select_base` value | Enum constraint | Rejected |
784+
| Push `UDF_SELECTOR` with only `match_priority` and no L2 / L3 / GRE / L4_DST_PORT | At-least-one-match check | Rejected |
655785

656786
## 11. Open/Action Items
657787

0 commit comments

Comments
 (0)