Skip to content

[transceiver][test-plan][attribute_parser]: restructure per-category attribute JSONs into scope-rooted shards - #1

Closed
mihirpat1 wants to merge 1 commit into
masterfrom
json_file_restructuring
Closed

[transceiver][test-plan][attribute_parser]: restructure per-category attribute JSONs into scope-rooted shards#1
mihirpat1 wants to merge 1 commit into
masterfrom
json_file_restructuring

Conversation

@mihirpat1

Copy link
Copy Markdown
Owner

Description of PR

Summary:
Restructure the per-category transceiver attribute JSONs under ansible/files/transceiver/inventory/attributes/ from a single flat <category>.json file into a sharded, scope-rooted layout. Every non-category shard (platform / HWSKU / vendor / per-PN) carries only its scope's body; the scope is encoded entirely in the directory path. The loader grafts each body into the correct slot of the merged in-memory tree before priority resolution.

attributes/<category>/
  <category>.json                                              # mandatory / defaults / dut / deployment_configurations
  platforms/<PLATFORM>/<category>.json                         # platform body
  platforms/<PLATFORM>/hwskus/<HWSKU>.json                     # HWSKU body
  transceivers/vendors/<V>/<category>.json                     # vendor `defaults` body
  transceivers/vendors/<V>/part_numbers/<PN>/<category>.json   # per-PN body (attrs + optional firmware_overrides / platform_hwsku_overrides)

Because each shard owns a disjoint subtree of the merged tree, two shards can never write the same key path - the directory IS the schema. Path/payload mismatch and duplicate-leaf checks are no longer needed; the layout makes them structurally impossible.

Fixes # (issue) — ADO PBI link will be added in a comment.

Type of change

  • Bug fix
  • Testbed and Framework(new/improvement)
  • New Test case
    • Skipped for non-supported platforms
  • Test case improvement

Back port request

  • 202205
  • 202305
  • 202311
  • 202405
  • 202411
  • 202505
  • 202511

Approach

What is the motivation for this PR?

The previous single-file-per-category layout did not scale to vendor onboarding and per-PN tuning. Every vendor or PN-specific tweak had to be edited into the same shared JSON, creating merge friction and making it easy to mis-place attributes. A path-mismatch or duplicate-leaf required custom loader checks to catch.

The sharded layout isolates each ownership level into its own file and uses the directory structure itself as the schema - vendor onboarding adds a vendor directory, PN-specific tuning adds a PN directory, and no two shards can collide.

How did you do it?

Loader (tests/transceiver/attribute_parser/attribute_manager.py)

  • Discovers shards from the directory tree and grafts each body into the right slot.
  • Validation reduced from 5 checks to 4:
    1. Category top-key whitelist — only mandatory, defaults, dut, and transceivers.deployment_configurations allowed at category-level.
    2. Body-shape sanity — every shard body must be an object; per-PN firmware_overrides / platform_hwsku_overrides must be dict-of-dict.
    3. Normalization check — vendor/PN directory names must appear in normalization_mappings.json when the vendor/PN owns a shard.
    4. Mandatory-field resolution — after merge + priority resolution, every port resolves each mandatory field somewhere in the hierarchy.

Tests (tests/transceiver/attribute_parser/transceiver_attribute_infra_test.py)

  • _shard_category helper rewritten to emit scope-rooted bodies.
  • Removed: path/payload mismatch (both vendor + per-PN), vendor-shard extra slot, duplicate-leaf detection — all structurally impossible now.
  • Rewritten: slot-whitelist and normalization-check tests use raw bodies.
  • Added: test_loader_pn_reserved_subslot_shape covers the dict-of-dict check.

HLD updates in docs/testplan/transceiver/:

  • test_plan.md — File Organization (tree + shard contracts table), Loader Validation (5 → 4 checks), JSON Schema Structure (scope-rooted examples).
  • diagrams/file_organization.md and diagrams/data_flow.md — trees + Mermaid graphs updated; priority hierarchy 8 → 9 levels (firmware_overrides reserved slot).
  • eeprom_test_plan.md, system_test_plan.md, dom_test_plan.md — pre-req / attributes sections link to the shard layout and validation rules.
  • Example inventory under docs/testplan/transceiver/examples/inventory/attributes/eeprom/ — flat eeprom.json replaced by a full scope-rooted shard tree exercising platform / HWSKU / two vendors / two per-PN files.

How did you verify/test it?

python3 tests/transceiver/attribute_parser/transceiver_attribute_infra_test.py
…
Test Summary: 25 passed, 0 failed out of 25 tests
All tests passed!

Any platform specific information?

None — this is framework / HLD work; no DUT runtime behavior is affected. Loader changes are exercised by the standalone unit-test runner.

Supported testbed topology if it's a new test case?

N/A — no new test cases. Framework + documentation only.

Documentation

The HLD documents in docs/testplan/transceiver/ are part of this PR. The example inventory tree under docs/testplan/transceiver/examples/inventory/ is updated to match the new layout.

…attribute JSONs into scope-rooted shards

Replace the single flat `<category>.json` file under
`ansible/files/transceiver/inventory/attributes/` with a sharded layout
where each non-category shard is rooted on disk by its scope:

  attributes/<category>/
    <category>.json                                          # mandatory / defaults / dut / deployment_configurations
    platforms/<PLATFORM>/<category>.json                     # platform body
    platforms/<PLATFORM>/hwskus/<HWSKU>.json                 # HWSKU body
    transceivers/vendors/<V>/<category>.json                 # vendor `defaults` body
    transceivers/vendors/<V>/part_numbers/<PN>/<category>.json  # per-PN body (attrs + optional firmware_overrides / platform_hwsku_overrides)

Each non-category shard's JSON contains only its scope's body; the scope
is encoded in the directory path. Because each shard owns a disjoint
subtree of the merged tree (`platforms.<P>`, `hwskus.<H>`,
`transceivers.vendors.<V>.defaults`, `transceivers.vendors.<V>.part_numbers.<PN>`),
two shards can never write the same key path - the directory IS the schema.

Loader (tests/transceiver/attribute_parser/attribute_manager.py):
- Discovers shards from the directory tree and grafts each body into the
  correct slot of the merged in-memory tree.
- Validation reduced to four fail-fast checks at framework init:
    1. Category top-key whitelist (mandatory / defaults / dut /
       transceivers.deployment_configurations only)
    2. Body-shape sanity (per-PN reserved sub-slots must be dict-of-dict)
    3. Vendor / PN normalization (directory names must appear in
       normalization_mappings.json when the vendor/PN owns a shard)
    4. Mandatory-field resolution after merge + priority resolution
  Path/payload mismatch and duplicate-leaf checks are no longer needed -
  the scope-rooted layout makes them structurally impossible.

Tests (tests/transceiver/attribute_parser/transceiver_attribute_infra_test.py):
- `_shard_category` helper rewritten to emit scope-rooted bodies.
- Obsolete tests removed: path/payload mismatch (both vendor + per-PN),
  vendor-shard extra slot, duplicate-leaf detection.
- Existing slot-whitelist / normalization tests rewritten for the new
  body shape.
- New test: `test_loader_pn_reserved_subslot_shape` covers the dict-of-dict
  check for `firmware_overrides` / `platform_hwsku_overrides`.
- Final result: 25 / 25 passing.

HLD updates (docs/testplan/transceiver/):
- `test_plan.md`: File Organization tree + shard contracts table now show
  per-scope body shapes; Loader Validation reduced from 5 to 4 checks;
  JSON Schema Structure section replaces wrapped templates with scope-rooted
  bodies and a comment indicating where each is grafted.
- `diagrams/file_organization.md` and `diagrams/data_flow.md`: trees and
  Mermaid graphs updated to reflect sharded layout; priority hierarchy
  bumped from 8 to 9 levels (firmware_overrides reserved slot).
- `eeprom_test_plan.md`, `system_test_plan.md`, `dom_test_plan.md`:
  pre-req / attributes sections link to the shard layout and validation
  rules.
- Example inventory under `docs/testplan/transceiver/examples/inventory/`:
  the flat `eeprom.json` replaced by a full scope-rooted shard tree
  exercising platform / HWSKU / two vendors / two per-PN files.

Signed-off-by: Mihir Patel <patelmi@microsoft.com>
@mssonicbld

Copy link
Copy Markdown

/azp run

@mihirpat1 mihirpat1 closed this May 29, 2026
mihirpat1 pushed a commit that referenced this pull request Jun 11, 2026
…net#24994)

### Description of PR

Summary:
The `snappi_api` fixture previously had the IxNetwork API
username/password hardcoded behind a commented-out TODO, so any site
whose IxNetwork uses non-default credentials had to edit the fixture
locally. This change reads those credentials from the DUT's ansible
inventory variable `snappi_api_server.user` /
`snappi_api_server.password` — the same inventory source already used to
read `rest_port` (`snappi_api_serv_port`). Credentials now live in the
testbed inventory instead of in test code.

When those keys are absent, the values stay `None` and the snappi
library defaults apply, so behavior is unchanged for testbeds that don't
define them.

### Type of change

- [ ] Bug fix
- [x] Testbed and Framework(new/improvement)
- [ ] New Test case
    - [ ] Skipped for non-supported platforms
- [ ] Test case improvement

### Back port request
- [ ] 202311
- [ ] 202405
- [ ] 202411
- [ ] 202505
- [ ] 202511
- [ ] 202512
- [ ] 202605

### Approach
#### What is the motivation for this PR?
IxNetwork API credentials were hardcoded (commented out) in the
`snappi_api` fixture. Sites whose IxNetwork uses non-default credentials
had to patch the fixture in place. Reading them from the ansible
inventory keeps credentials out of the test code and is consistent with
how `snappi_api_serv_port` already reads `rest_port` from the same
`snappi_api_server` inventory variable.

#### How did you do it?
In the `snappi_api` fixture, added the `duthosts` and
`rand_one_dut_hostname` fixtures, looked up the `snappi_api_server` host
var for the selected DUT, and set `api._username` / `api._password` from
its `user` / `password` keys when present. Absent keys leave the snappi
library defaults in place, preserving existing behavior.

#### How did you verify/test it?
```
INFO     tests.snappi_tests.ecn.test_red_accuracy_with_snappi:test_red_accuracy_with_snappi.py:113 Running ECN red accuracy test with ECN params: {'kmin': 500000, 'kmax': 900000, 'pmax': 5}
INFO     tests.snappi_tests.ecn.test_red_accuracy_with_snappi:test_red_accuracy_with_snappi.py:114 Running ECN red accuracy test for 1 iterations
INFO     tests.snappi_tests.ecn.files.helper:helper.py:346 Stopping PFC watchdog
INFO     tests.snappi_tests.ecn.files.helper:helper.py:349 Disabling packet aging if necessary
INFO     tests.snappi_tests.ecn.files.helper:helper.py:352 Enabling WRED queue counters
INFO     tests.snappi_tests.ecn.files.helper:helper.py:357 Configuring WRED and ECN thresholds
INFO     tests.snappi_tests.ecn.files.helper:helper.py:372 Enabling ECN markings
INFO     tests.snappi_tests.ecn.files.helper:helper.py:401 Generating base flow config
INFO     tests.snappi_tests.ecn.files.helper:helper.py:406 Setting test flow config params
INFO     tests.snappi_tests.ecn.files.helper:helper.py:414 Setting pause flow config params
INFO     tests.snappi_tests.ecn.files.helper:helper.py:428 Generating test flows
INFO     tests.snappi_tests.ecn.files.helper:helper.py:435 Generating pause flows
INFO     tests.snappi_tests.ecn.files.helper:helper.py:446 Setting packet capture port to Port 0
INFO     tests.snappi_tests.ecn.files.helper:helper.py:450 Running 1 iteration(s)
INFO     tests.snappi_tests.ecn.files.helper:helper.py:452 Running iteration 0
INFO     tests.snappi_tests.ecn.files.helper:helper.py:454 Packet capture file: ECN_cap-0.pcapng
INFO     tests.snappi_tests.ecn.files.helper:helper.py:462 Clearing DUT counters before iter 0 traffic
INFO     tests.snappi_tests.ecn.files.helper:helper.py:466 Running traffic
INFO     tests.common.snappi_tests.traffic_generation:traffic_generation.py:616 Wait for Arp to Resolve ...
INFO     tests.common.snappi_tests.traffic_generation:traffic_generation.py:627 Starting packet capture ...
INFO     tests.common.snappi_tests.traffic_generation:traffic_generation.py:639 Starting transmit on all flows ...
INFO     tests.common.snappi_tests.traffic_generation:traffic_generation.py:685 Polling TGEN for in-flight traffic statistics...
INFO     tests.common.snappi_tests.traffic_generation:traffic_generation.py:693 Checking if all flows have stopped. Attempt #1
INFO     tests.common.snappi_tests.traffic_generation:traffic_generation.py:693 Checking if all flows have stopped. Attempt #2
INFO     tests.common.snappi_tests.traffic_generation:traffic_generation.py:700 All test and background traffic flows stopped
INFO     tests.common.snappi_tests.traffic_generation:traffic_generation.py:711 Stopping packet capture ...
INFO     tests.common.snappi_tests.traffic_generation:traffic_generation.py:717 Retrieving and saving packet capture to ECN_cap-0.pcapng
WARNING  root:snappi_api.py:1518 Capture was not stopped for this port Port 0
INFO     tests.common.snappi_tests.traffic_generation:traffic_generation.py:723 Dumping per-flow statistics
INFO     tests.common.snappi_tests.traffic_generation:traffic_generation.py:725 Stopping transmit on all remaining flows
INFO     tests.snappi_tests.ecn.files.helper:helper.py:500 Queue counters after iter 0 (prio 3):
```
#### Any platform specific information?
None — this affects only the snappi/IxNetwork API session setup.

#### Supported testbed topology if it's a new test case?
N/A — not a new test case; applies to snappi tgen testbeds.

### Documentation
N/A — no documentation/wiki changes required.

Signed-off-by: atul-nexthop <atul@nexthop.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants