diff --git a/docs/testplan/transceiver/diagrams/README.md b/docs/testplan/transceiver/diagrams/README.md new file mode 100644 index 00000000000..10701a9327a --- /dev/null +++ b/docs/testplan/transceiver/diagrams/README.md @@ -0,0 +1,30 @@ +# Transceiver Test Plan - Visual Diagrams + +This directory contains visual diagrams to help understand the complex concepts in the transceiver test plan. + +## Available Diagrams + +### 1. [File Organization](file_organization.md) + +- Shows the overall file structure and relationships +- Illustrates how `dut_info.json` and category attribute files work together +- Displays the final `port_attributes_dict` structure + +### 2. [Data Flow Architecture](data_flow.md) + +- Comprehensive view of the entire system architecture +- Sequence diagram showing processing steps +- Examples of data transformation at each stage + +### 3. [Validation Flow](validation_flow.md) + +- Attribute completeness validation process +- Template-based validation workflow +- Pytest integration and execution control + +## How to Use These Diagrams + +1. **Start with File Organization** to understand the overall structure +2. **Reference Data Flow** for end-to-end system understanding + +These diagrams complement the detailed text in the main test plan document and provide visual clarity for implementation and troubleshooting. diff --git a/docs/testplan/transceiver/diagrams/data_flow.md b/docs/testplan/transceiver/diagrams/data_flow.md new file mode 100644 index 00000000000..afd39dc57b9 --- /dev/null +++ b/docs/testplan/transceiver/diagrams/data_flow.md @@ -0,0 +1,199 @@ +# Data Flow Architecture Diagram + +## Overall System Architecture + +```mermaid +graph TB + subgraph "Input Files" + A[dut_info.json] + B[eeprom.json] + C[system.json] + D[Other category files...] + X[(prerequisites.json)] + end + + subgraph "Framework Processing" + E[AttributeManager] + F[Port Expansion Processor] + G[Configuration Parser] + H[Priority Resolver] + I[Validator] + end + + subgraph "Output Structure" + J[port_attributes_dict] + K[BASE_ATTRIBUTES] + L[EEPROM_ATTRIBUTES] + M[SYSTEM_ATTRIBUTES] + N[Other Category Attributes] + end + + subgraph "Validation (Optional)" + Q[Deployment Templates] + R[AttributeCompletenessValidator] + end + + subgraph "Test Consumption" + O[Test Cases] + P[DUT Host Object] + end + + A --> E + B --> E + C --> E + D --> E + X --> T[Prerequisite Test Runner] + T --> O + + E --> F + F --> G + G --> H + H --> I + + I --> K + I --> L + I --> M + I --> N + + K --> J + L --> J + M --> J + N --> J + + J --> R + Q --> R + R --> P + P --> O + J --> O + + style A fill:#e1f5fe + style E fill:#f3e5f5 + style J fill:#e8f5e8 + style O fill:#fff3e0 +``` + +## Detailed Processing Flow + +```mermaid +sequenceDiagram + participant DI as dut_info.json + participant AM as AttributeManager + participant PP as Port Processor + participant CP as Config Parser + participant CF as Category Files + participant PR as Priority Resolver + participant PD as port_attributes_dict + participant V as Validator + participant TC as Test Cases + participant PRQ as Prerequisites File + + TC->>AM: Initialize framework & load base data + AM->>DI: Load dut_info.json + DI-->>AM: Port specs & metadata + AM->>PP: Expand port specifications + PP-->>AM: Expanded port list + AM->>CP: Parse transceiver configuration strings + CP-->>AM: Parsed components + AM->>PD: Seed BASE_ATTRIBUTES per port + + loop For each category + TC->>CF: Load category JSON file + CF-->>TC: Raw category attributes + TC->>PR: Resolve via 8-level priority hierarchy + PR-->>TC: Merged CATEGORY_ATTRIBUTES + TC->>PD: Store CATEGORY_ATTRIBUTES + opt Attribute Completeness Validation + PD->>V: Validate against deployment templates + V-->>PD: Results + end + TC->>PRQ: Load category prerequisite list (if present) + PRQ->>PRQ: Execute prerequisite tests (gating checks) + PRQ-->>TC: Continue if all pass + PD-->>TC: Run main category test cases + end +``` + +## Data Transformation Examples + +### Step 1: Port Expansion + +```text +Input (dut_info.json): +{ + "dut_name_1": { + "Ethernet4:7": { + "vendor_name": "ACME Corp.", + "transceiver_configuration": "AOC-100-QSFPDD-2x100G_100G_SIDE-0xFF-0xFF" + } + } +} + +After Port Expansion: +- Ethernet4: same attributes +- Ethernet5: same attributes +- Ethernet6: same attributes +``` + +### Step 2: Configuration Parsing + +```text +Input: "AOC-100-QSFPDD-2x100G_100G_SIDE-0xFF-0xFF" + +Parsed Components: +- cable_type: "AOC" +- speed_gbps: 100 +- form_factor: "QSFPDD" +- deployment: "2x100G_100G_SIDE" +- media_lane_mask: "0xFF" +- host_lane_mask: "0xFF" +- media_lane_count: 8 +- host_lane_count: 8 +``` + +### Step 3: Attribute Merging + +```text +For Ethernet4 EEPROM_ATTRIBUTES: + +Priority Resolution: +1. defaults.dual_bank_supported = false +2. deployment_configurations.2x100G_100G_SIDE.dual_bank_supported = true ← WINS +3. vendor.ACME_CORP.defaults.dual_bank_supported = false +4. No higher priority overrides found + +Result: dual_bank_supported = true +``` + +### Step 4: Final Structure + +```python +port_attributes_dict = { + "Ethernet4": { + "BASE_ATTRIBUTES": { + "vendor_name": "ACME Corp.", + "cable_type": "AOC", + "speed_gbps": 100, + "deployment": "2x100G_100G_SIDE", + # ... other parsed fields + }, + "EEPROM_ATTRIBUTES": { + "dual_bank_supported": true, + "vdm_supported": false, + # ... other resolved attributes + }, + "SYSTEM_ATTRIBUTES": { + # ... resolved system attributes + } + } + # ... other ports +} +``` + +## Key Benefits + +1. **Separation of Concerns**: Base hardware data vs. test-specific attributes +2. **Modular Design**: Each category file is independent +3. **Flexible Overrides**: 8-level priority system handles all scenarios +4. **Efficient Grouping**: Port ranges reduce configuration overhead +5. **Deployment Patterns**: Shared attributes for similar deployments +6. **Extensible**: Easy to add new categories and attributes \ No newline at end of file diff --git a/docs/testplan/transceiver/diagrams/file_organization.md b/docs/testplan/transceiver/diagrams/file_organization.md new file mode 100644 index 00000000000..e687f960ee1 --- /dev/null +++ b/docs/testplan/transceiver/diagrams/file_organization.md @@ -0,0 +1,213 @@ +# File Organization Diagram + +## Data and Configuration File Structure + +```text +ansible/files/transceiver/inventory/ +├── normalization_mappings.json # Shared vendor/PN normalization rules +│ +├── dut_info/ # Per-DUT transceiver metadata +│ ├── sonic-device-01.json # DUT 1 port configurations +│ ├── sonic-device-02.json # DUT 2 port configurations +│ └── ... # Additional DUT files +│ +├── attributes/ # Test category attribute files +│ ├── eeprom.json # EEPROM test attributes +│ ├── system.json # System test attributes +│ ├── physical_oir.json # Physical OIR attributes +│ ├── remote_reseat.json # Remote reseat attributes +│ ├── cdb_fw_upgrade.json # CDB FW upgrade attributes +│ ├── dom.json # DOM test attributes +│ ├── vdm.json # VDM test attributes +│ └── pm.json # PM test attributes +│ +├── prerequisites.json # OPTIONAL grouped prerequisite tests (pre-category gating) +│ +└── templates/ # Validation templates (optional) + └── deployment_templates.json # Attribute completeness validation +``` + +## File Relationships + +```mermaid +graph TD + NM[normalization_mappings.json] --> B[Framework Parser] + A[dut_info/.json] --> B + C[eeprom.json] --> B + D[system.json] --> B + E[physical_oir.json] --> B + F[other category files...] --> B + P[(prerequisites.json?)] --> Z[Prerequisite Test Runner] + Z --> L[Test Cases] + + B --> H[BASE_ATTRIBUTES] + B --> I[EEPROM_ATTRIBUTES] + B --> J[SYSTEM_ATTRIBUTES] + B --> K[Other Category Attributes] + + H --> G[port_attributes_dict] + I --> G + J --> G + K --> G + + G --> M{Validation Templates?} + M -->|Yes| N[Validator] + M -->|No| L[Test Cases] + N --> L + O[deployment_templates.json] --> N + + style A fill:#e1f5fe + style G fill:#f3e5f5 + style L fill:#e8f5e8 + style O fill:#fff3e0 +``` + +## Key Concepts + +- **normalization_mappings.json**: Shared normalization rules for vendor names and part numbers across all DUTs +- **dut_info/.json**: Per-DUT port-specific transceiver configurations; improves scalability and independent management +- **Category files**: Modular test-specific attribute definitions for each type of transceiver +- **Templates**: Optional validation templates for attribute completeness checking +- **port_attributes_dict**: Final merged data structure used by test cases +- **prerequisites.json (optional)**: Grouped list of tests executed before each category's tests +- **BASE_ATTRIBUTES**: Core transceiver info parsed from per-DUT files +- **Category-specific attributes**: Merged from respective JSON files using priority hierarchy +- **Validation**: Optional post-processing step to ensure attribute completeness + +## Python Test Code Structure + +```text +tests/transceiver/ +├── __init__.py +├── conftest.py # Shared pytest fixtures, uses infra and helper modules +│ +├── infra/ # Infrastructure modules for attribute and DUT management and parsing +│ ├── __init__.py +│ ├── attribute_manager.py # Attribute loading and resolution +│ ├── config_parser.py # Configuration file parsing +│ ├── dut_info_loader.py # DUT information loading +│ ├── exceptions.py # Custom exceptions +│ ├── paths.py # Path constants +│ ├── port_spec.py # Port specification handling +│ ├── template_validator.py # Template validation +│ ├── transceiver_attribute_infra_test.py # Infra unit tests +│ └── utils.py # General utilities +│ +├── helpers/ # Test-specific helper modules +│ ├── __init__.py +│ ├── verification.py # Standard Port Recovery and Verification Procedure +│ ├── state_management.py # State Preservation and Restoration helpers +│ ├── db_helpers.py # CONFIG_DB, STATE_DB, APPL_DB query wrappers +│ └── cli_helpers.py # CLI command wrappers (sfputil, config interface) +│ +├── eeprom/ +│ ├── __init__.py +│ ├── conftest.py # EEPROM-specific fixtures +│ ├── test_presence.py # TC 1-2: Transceiver presence verification +│ ├── test_eeprom_content.py # TC 3-4: Basic EEPROM content verification +│ ├── test_firmware.py # TC 5: Firmware version validation +│ ├── test_hexdump.py # TC 6-7: Hexdump and read-eeprom verification +│ ├── test_error_handling.py # TC 8: Error handling - Missing transceiver +│ ├── test_breakout_serial.py # TC 9: Serial number pattern validation +│ ├── test_port_config.py # TC 10-11: Port speed and FEC validation +│ └── cmis/ +│ ├── __init__.py +│ └── test_cdb_background_mode.py # CMIS TC 1-2: CDB background mode tests +│ +├── dom/ +│ ├── __init__.py +│ ├── conftest.py # DOM-specific fixtures +│ ├── test_dom_availability.py # Basic TC 1: DOM data availability +│ ├── test_dom_operational_range.py # Basic TC 2: DOM sensor operational range +│ ├── test_dom_threshold.py # Basic TC 3: DOM threshold validation +│ ├── test_dom_consistency.py # Basic TC 4: DOM data consistency +│ └── advanced/ +│ ├── __init__.py +│ ├── test_dom_interface_state.py # Advanced TC 1: DOM during interface state changes +│ └── test_dom_polling.py # Advanced TC 2: DOM polling and data freshness +│ +├── system/ +│ ├── __init__.py +│ ├── conftest.py # System-specific fixtures +│ │ +│ ├── link_behavior/ +│ │ ├── __init__.py +│ │ ├── test_port_link_toggle.py # TC 1-2: Port link toggle tests +│ │ +│ ├── process_restart/ +│ │ ├── __init__.py +│ │ ├── test_xcvrd_restart.py # TC 1-3: xcvrd restart tests +│ │ ├── test_pmon_restart.py # TC 4: pmon docker restart +│ │ ├── test_swss_restart.py # TC 5: swss docker restart +│ │ └── test_syncd_restart.py # TC 6: syncd process restart +│ │ +│ ├── recovery/ +│ │ ├── __init__.py +│ │ ├── test_config_reload.py # TC 1: Config reload impact +│ │ ├── test_cold_reboot.py # TC 2: Cold reboot link recovery +│ │ ├── test_warm_reboot.py # TC 3: Warm reboot link recovery +│ │ ├── test_fast_reboot.py # TC 4: Fast reboot link recovery +│ │ └── test_power_cycle.py # TC 5: Power cycle link recovery +│ │ +│ ├── event_handling/ +│ │ ├── __init__.py +│ │ ├── test_transceiver_reset.py # TC 1: Transceiver reset validation +│ │ ├── test_low_power_mode.py # TC 2-3: Low power mode tests +│ │ ├── test_tx_disable.py # TC 4: Tx disable DataPath validation +│ │ ├── test_si_settings.py # TC 5-6: Optics and Media SI settings +│ │ └── test_ccmis_tuning.py # TC 7-8: C-CMIS frequency/tx power +│ │ +│ ├── diagnostics/ +│ │ ├── __init__.py +│ │ └── test_loopback.py # TC 1: Transceiver loopback validation +│ │ +│ └── stress/ +│ ├── __init__.py +│ ├── test_port_toggle_stress.py # TC 1-2: Port toggle stress tests +│ ├── test_reboot_stress.py # TC 3-5: Reboot stress tests +│ ├── test_link_stability.py # TC 6: Link stability monitoring +│ └── test_power_cycle_stress.py # TC 7: Power cycle stress test +├── cdb_fw_upgrade/ +│ ├── __init__.py +│ ├── conftest.py # CDB FW upgrade-specific fixtures +│ └── test_fw_upgrade.py # CDB FW upgrade specific test cases +├── vdm/ +│ ├── __init__.py +│ ├── conftest.py # VDM-specific fixtures +│ └── test_vdm.py # VDM specific test cases +└── pm/ + ├── __init__.py + ├── conftest.py # PM-specific fixtures + └── test_pm.py # PM specific test cases +``` + +## Module Relationship + +```text +┌────────────────────────────────────────────────────────────────────────┐ +│ Test Files │ +│ (eeprom/, dom/, system/, cdb_fw_upgrade/, vdm/, pm/ etc.) │ +└──────────────────────────────┬─────────────────────────────────────────┘ + │ uses + ▼ +┌────────────────────────────────────────────────────────────────────────┐ +│ helpers/ │ +│ verification.py, state_management.py, db_helpers.py, cli_helpers.py │ +└──────────────────────────────┬─────────────────────────────────────────┘ + │ uses + ▼ +┌────────────────────────────────────────────────────────────────────────┐ +│ infra/ │ +│ attribute_manager.py, config_parser.py, dut_info_loader.py, │ +│ port_spec.py, utils.py, exceptions.py, paths.py │ +└──────────────────────────────┬─────────────────────────────────────────┘ + │ reads + ▼ +┌────────────────────────────────────────────────────────────────────────┐ +│ Data Configuration Files │ +│ ansible/files/transceiver/inventory/ │ +│ ├── normalization_mappings.json │ +│ ├── dut_info/.json │ +│ └── attributes/{eeprom,dom,system, etc}.json │ +└────────────────────────────────────────────────────────────────────────┘ +``` diff --git a/docs/testplan/transceiver/diagrams/validation_flow.md b/docs/testplan/transceiver/diagrams/validation_flow.md new file mode 100644 index 00000000000..aed1f663ccb --- /dev/null +++ b/docs/testplan/transceiver/diagrams/validation_flow.md @@ -0,0 +1,37 @@ +# Attribute Completeness Validation Flow + +Visual overview of the validation process for ensuring comprehensive attribute coverage during transceiver qualification. + +## Process Flow + +```mermaid +flowchart TD + A[Attribute Processing Complete] --> B{Templates Found?} + B -->|No| C[Skip Validation] + B -->|Yes| D[Select Template by Deployment Type] + D --> E[Compare Attributes vs Template] + E --> F{Missing Required?} + F -->|Yes| G[pytest.fail - Stop Tests] + F -->|No| H{Missing Optional?} + H -->|Yes| I[pytest.warns - Continue with Warnings] + H -->|No| J[Continue Normal Execution] + I --> J +``` + +## Template Structure + +```mermaid +graph LR + A[deployment_templates.json] --> B[Deployment Types] + B --> C[required_attributes] + B --> D[optional_attributes] + C --> E[BASE_ATTRIBUTES] + C --> F[EEPROM_ATTRIBUTES] + C --> G[DOM_ATTRIBUTES] +``` + +## Integration Points + +- **Template Selection**: Uses `deployment` field from `BASE_ATTRIBUTES` +- **Validation**: Compares actual vs template requirements per category +- **Pytest Control**: Reports with INFO/WARNING/ERROR levels and execution control \ No newline at end of file diff --git a/docs/testplan/transceiver/examples/inventory/attributes/eeprom.json b/docs/testplan/transceiver/examples/inventory/attributes/eeprom.json new file mode 100644 index 00000000000..e2cbe4881c3 --- /dev/null +++ b/docs/testplan/transceiver/examples/inventory/attributes/eeprom.json @@ -0,0 +1,42 @@ +{ + "mandatory": ["sff8024_identifier", "dual_bank_supported"], + "defaults": { + "vdm_supported": false, + "is_non_dac_and_cmis": false, + "eeprom_dump_timeout_sec": 5 + }, + "transceivers": { + "deployment_configurations": { + "8x100G_DR8": { + "vdm_supported": true, + "dual_bank_supported": true + } + } + }, + "vendors": { + "ACME_CORP": { + "part_numbers": { + "QSFP-2X100G-AOC-GENERIC_2_ENDM": { + "dual_bank_supported": true, + "platform_hwsku_overrides": { + "x86_64-mlnx_msn4700-r0+ACS-MSN4700": { + "eeprom_dump_timeout_sec": 5 + } + } + } + } + }, + "XYZ_CORP": { + "part_numbers": { + "QSFP-2X100G-AOC-GENERIC_2_ENDM": { + "dual_bank_supported": true, + "platform_hwsku_overrides": { + "x86_64-mlnx_msn4700-r0+ACS-MSN4700": { + "eeprom_dump_timeout_sec": 4 + } + } + } + } + } + } +} diff --git a/docs/testplan/transceiver/examples/inventory/dut_info/lab-dut-01.json b/docs/testplan/transceiver/examples/inventory/dut_info/lab-dut-01.json new file mode 100644 index 00000000000..c823af5e177 --- /dev/null +++ b/docs/testplan/transceiver/examples/inventory/dut_info/lab-dut-01.json @@ -0,0 +1,48 @@ +{ + "Ethernet0:7": { + "vendor_name": "ACME Corp.", + "vendor_pn": "QSFP-2X100G-AOC-15M", + "vendor_sn": "ACM2024001234", + "vendor_date": "20240115", + "vendor_oui": "00-A0-C9", + "vendor_rev": "A1", + "hardware_rev": "1.0" + }, + "Ethernet0": { + "transceiver_configuration": "AOC-200-QSFPDD-2x100G_200G_SIDE-0x1-0x1" + }, + "Ethernet1": { + "transceiver_configuration": "AOC-200-QSFPDD-2x100G_200G_SIDE-0x2-0x2" + }, + "Ethernet2": { + "transceiver_configuration": "AOC-200-QSFPDD-2x100G_200G_SIDE-0x4-0x4" + }, + "Ethernet3": { + "transceiver_configuration": "AOC-200-QSFPDD-2x100G_200G_SIDE-0x8-0x8" + }, + "Ethernet4": { + "transceiver_configuration": "AOC-100-QSFPDD-2x100G_100G_SIDE-0x10-0x10" + }, + "Ethernet5": { + "transceiver_configuration": "AOC-100-QSFPDD-2x100G_100G_SIDE-0x20-0x20" + }, + "Ethernet6": { + "transceiver_configuration": "AOC-100-QSFPDD-2x100G_100G_SIDE-0x40-0x40" + }, + "Ethernet16,Ethernet20,Ethernet24": { + "vendor_name": "Example & Co", + "vendor_pn": "SFP-1000BASE-LX", + "transceiver_configuration": "LR-1-SFP-1G_STRAIGHT-0x01-0x01" + }, + "Ethernet28:33,Ethernet36,Ethernet40:45": { + "vendor_name": "Vendor/Inc", + "vendor_pn": "QSFP-100G-AOC-10M", + "transceiver_configuration": "AOC-100-QSFP-100G_STRAIGHT-0x0F-0x0F" + }, + "Ethernet48": { + "vendor_name": "Tech-Solutions Ltd.", + "vendor_pn": "DAC-400G-5M", + "vendor_sn": "TSL2024005678", + "transceiver_configuration": "DAC-400-OSFP-400G_STRAIGHT-0x0F-0x0F" + } +} diff --git a/docs/testplan/transceiver/examples/inventory/normalization_mappings.json b/docs/testplan/transceiver/examples/inventory/normalization_mappings.json new file mode 100644 index 00000000000..33e326d8c48 --- /dev/null +++ b/docs/testplan/transceiver/examples/inventory/normalization_mappings.json @@ -0,0 +1,18 @@ +{ + "vendor_names": { + "ACME Corp.": "ACME_CORP", + "Example & Co": "EXAMPLE_CO", + "Vendor/Inc": "VENDOR_INC", + "Tech-Solutions Ltd.": "TECH_SOLUTIONS_LTD" + }, + "part_numbers": { + "QSFP-100G-AOC-15M": "QSFP-100G-AOC-GENERIC_2_ENDM", + "QSFP-100G-AOC-10M": "QSFP-100G-AOC-GENERIC_2_ENDM", + "QSFP-100G-AOC-3M": "QSFP-100G-AOC-GENERIC_1_ENDM", + "QSFP-100G-AOC-25M": "QSFP-100G-AOC-GENERIC_2_ENDM", + "QSFP-2X100G-AOC-15M": "QSFP-2X100G-AOC-GENERIC_2_ENDM", + "QSFP-2X100G-AOC-10M": "QSFP-2X100G-AOC-GENERIC_2_ENDM", + "SFP-1000BASE-LX": "SFP-1000BASE-LX", + "DAC-400G-5M": "DAC-400G-GENERIC_1_ENDM" + } +} diff --git a/docs/testplan/transceiver/examples/inventory/prerequisites.json b/docs/testplan/transceiver/examples/inventory/prerequisites.json new file mode 100644 index 00000000000..20762b7e05e --- /dev/null +++ b/docs/testplan/transceiver/examples/inventory/prerequisites.json @@ -0,0 +1,21 @@ +{ + "eeprom": [ + { + "name": "transceiver_presence", + "module": "tests/transceiver/eeprom/test_eeprom_basic.py", + "function": "test_transceiver_presence" + }, + { + "name": "gold_firmware_check", + "module": "tests/transceiver/firmware/test_eeprom_basic.py", + "function": "test_gold_firmware" + } + ], + "dom": [ + { + "name": "transceiver_presence", + "module": "tests/transceiver/eeprom/test_eeprom_basic.py", + "function": "test_transceiver_presence" + } + ] +} diff --git a/docs/testplan/transceiver/examples/inventory/templates/README.md b/docs/testplan/transceiver/examples/inventory/templates/README.md new file mode 100644 index 00000000000..32d30e6a62b --- /dev/null +++ b/docs/testplan/transceiver/examples/inventory/templates/README.md @@ -0,0 +1,48 @@ +# Transceiver Template Files + +This directory contains template files for validating attribute completeness during transceiver testing. + +## deployment_templates.json + +This file defines required and optional attributes for each deployment type. The validation process compares the actual attributes in `port_attributes_dict` against these templates to ensure comprehensive coverage. + +### Structure + +```json +{ + "deployment_templates": { + "": { + "required_attributes": { + "": ["attr1", "attr2"] + }, + "optional_attributes": { + "": ["attr1", "attr2"] + } + } + } +} +``` + +### Usage + +The framework automatically: + +1. Extracts the `deployment` field from `BASE_ATTRIBUTES` +2. Loads the corresponding deployment template +3. Compares actual attributes against required/optional lists +4. Reports missing attributes with appropriate severity: + - **ERROR**: Missing required attributes (test fails) + - **WARNING**: Missing optional attributes (test continues) + - **INFO**: Fully compliant (all attributes present) + +### Example Template + +See the test plan documentation for a complete example of `deployment_templates.json`. + +### Configuration + +- **File location**: `ansible/files/transceiver/inventory/templates/deployment_templates.json` +- **Validation control**: Use `--skip_transceiver_template_validation` pytest parameter to bypass validation +- **Default behavior**: Validation runs automatically if the template file exists + +For more details, see the [Attribute Completeness Validation](../../test_plan.md#3-attribute-completeness-validation) section in the test plan. diff --git a/docs/testplan/transceiver/examples/inventory/templates/deployment_templates.json b/docs/testplan/transceiver/examples/inventory/templates/deployment_templates.json new file mode 100644 index 00000000000..c686fd729f6 --- /dev/null +++ b/docs/testplan/transceiver/examples/inventory/templates/deployment_templates.json @@ -0,0 +1,17 @@ +{ + "deployment_templates": { + "8x100G_DR8": { + "required_attributes": { + "EEPROM_ATTRIBUTES": [ + "sff8024_identifier", + "dual_bank_supported" + ] + }, + "optional_attributes": { + "EEPROM_ATTRIBUTES": [ + "vdm_supported" + ] + } + } + } +} diff --git a/docs/testplan/transceiver/test_plan.md b/docs/testplan/transceiver/test_plan.md index db519600dcd..fc6329b96ab 100644 --- a/docs/testplan/transceiver/test_plan.md +++ b/docs/testplan/transceiver/test_plan.md @@ -96,126 +96,823 @@ These tests do not require traffic and are standalone, designed to run on a Devi - All sides of the breakout cable should be connected to the DUT, and each port should be tested individually starting from subport 1 to subport N. The test should be run in reverse order as well i.e. starting from subport N to subport 1. - For link toggling tests on a subport, it's crucial to ensure that the link status of remaining subports of the breakout port group remains unaffected. -**Pre-requisites for the Below Tests:** +### Test Prerequisites and Configuration Files -1. A file `transceiver_dut_info.csv` (located in `ansible/files/transceiver_inventory` directory) should be present to describe the metadata of the transceiver connected to every port of each DUT. Following should be the format of the file +The following configuration files must be present to enable comprehensive transceiver testing. - ```csv - dut_name,physical_port,vendor_pn,normalized_vendor_pn,vendor_sn,vendor_date,vendor_oui,vendor_rev - dut_name_1,port_1,vendor_part_number,normalized_vendor_part_number,serial_number,vendor_date_code,vendor_oui,revision_number - dut_name_1,port_2,vendor_part_number,normalized_vendor_part_number,serial_number,vendor_date_code,vendor_oui,revision_number - # Add more DUTs as needed - ``` +> 📁 **Example Files**: Examples of all configuration files described below are available in the [`examples/inventory/`](examples/inventory/) directory. Use these as templates when creating your own configuration files. + +### Test Category Prerequisite Tests - - `dut_name`: The name of the DUT. - - `physical_port`: The physical port number on the DUT where the transceiver is connected (e.g., 1, 2, etc.). - - `vendor_pn`: The vendor part number as specified in the transceiver's EEPROM. - - `normalized_vendor_pn`: The normalized vendor part number, created by applying the normalization rules described in the [CMIS CDB Firmware Binary Management](#141-cmis-cdb-firmware-binary-management) section. - - `vendor_sn`: The vendor serial number. - - `vendor_date`: The vendor date code. - - `vendor_oui`: The vendor OUI. - - `vendor_rev`: The vendor revision number. +Prerequisite tests provide early readiness validation before a category's main test cases execute. They run after attribute resolution and optional validation, serving as gating checks to verify basic functionality before proceeding with the full test suite for a test category. - Functionality to parse the above files and store the data in a dictionary should be implemented in the test framework. This dictionary should act as a source of truth for the test cases. - The `normalized_vendor_pn` from `transceiver_dut_info.csv` file should be used to fetch the common attributes of the transceiver from `transceiver_common_attributes.csv` file for a given port. - > Note: If any non-string value is planned to be added to the dictionary, the `convert_row_types` function should be modified to convert the relevant value to the appropriate datatype. +**File location:** `ansible/files/transceiver/inventory/prerequisites.json` - Example of an dictionary created by parsing the above files +**Structure:** Grouped by test category, with each entry specifying a test module and function: - ```python +```json +{ + "eeprom": [ { - "dut_name_1": { - "port_1": { + "name": "eeprom_readability", + "module": "tests/transceiver/eeprom/test_eeprom_basic.py", + "function": "test_eeprom_pages" + } + ], + "dom": [ + { + "name": "dom_basic", + "module": "tests/transceiver/dom/test_dom_basic.py", + "function": "test_dom_read" + } + ] +} +``` + +**Execution behavior:** + +1. Run immediately before each category's main tests (after attribute resolution and optional validation) +2. Only the current category's list is loaded and executed; other categories' lists are deferred +3. Execution order within each category array is preserved +4. Duplicate tests (same module+function) are executed only once per category +5. If the file or category key is absent, no prerequisites run for that category + +**Common prerequisite test examples:** + +- Verify transceiver presence on the port +- Verify port speed in CONFIG_DB matches expected speed per dut_info.json +- Ensure RS FEC is configured if applicable +- Validate active firmware version matches the expected gold firmware +- Confirm I2C communication functionality via `sfputil` +- Verify link operational status (link-up state) +- Ensure critical system processes (`xcvrd`, `pmon`, `syncd`, `orchagent`) are running + +#### 1. DUT Info Files + +> 📊 **Visual Guide**: See the [File Organization Diagram](diagrams/file_organization.md) for a visual overview of the file structure and relationships. + +Transceiver metadata is organized into per-DUT files located in the `ansible/files/transceiver/inventory/dut_info/` directory. Each file is named after its corresponding DUT hostname (e.g., `sonic-device-01.json`) and contains port-specific transceiver configurations for that device. + +Additionally, a shared `normalization_mappings.json` file in the `ansible/files/transceiver/inventory/` directory provides vendor name and part number normalization rules used across all DUTs. + +Each per-DUT file supports multiple port specification formats for flexibility and efficiency: + +Example of `dut_info/sonic-device-01.json`: + +```json +{ + "Ethernet0:7": { + "vendor_name": "ACME Corp.", + "vendor_pn": "QSFP-2X100G-AOC-15M", + "vendor_sn": "serial_number_001", + "vendor_date": "vendor_date_code", + "vendor_oui": "vendor_oui", + "vendor_rev": "revision_number", + "hardware_rev": "hardware_revision_number" + }, + "Ethernet0": {"transceiver_configuration": "AOC-200-QSFPDD-2x100G_200G_SIDE-0x1-0x1"}, + "Ethernet1": {"transceiver_configuration": "AOC-200-QSFPDD-2x100G_200G_SIDE-0x2-0x2"}, + "Ethernet2": {"transceiver_configuration": "AOC-200-QSFPDD-2x100G_200G_SIDE-0x4-0x4"}, + "Ethernet3": {"transceiver_configuration": "AOC-200-QSFPDD-2x100G_200G_SIDE-0x8-0x8"}, + "Ethernet4": {"transceiver_configuration": "AOC-100-QSFPDD-2x100G_100G_SIDE-0x10-0x10"}, + "Ethernet5": {"transceiver_configuration": "AOC-100-QSFPDD-2x100G_100G_SIDE-0x20-0x20"}, + "Ethernet6": {"transceiver_configuration": "AOC-100-QSFPDD-2x100G_100G_SIDE-0x40-0x40"}, + "Ethernet16,Ethernet20,Ethernet24": { + "vendor_name": "Example & Co", + "vendor_pn": "SFP-1000BASE-LX", + "transceiver_configuration": "LR-1-SFP-1G_STRAIGHT-0x01-0x01" + }, + "Ethernet28:33,Ethernet36,Ethernet40:45": { + "vendor_name": "Vendor/Inc", + "vendor_pn": "QSFP-100G-AOC-10M", + "transceiver_configuration": "AOC-100-QSFP-100G_STRAIGHT-0x0F-0x0F" + } +} +``` + +##### Normalization Mappings File + +**File location:** `ansible/files/transceiver/inventory/normalization_mappings.json` + +**Purpose:** Provides a centralized, shared mapping for normalizing vendor names and part numbers across all DUTs. + +**Structure:** + +- `vendor_names`: Dictionary mapping raw vendor names to their normalized forms using the normalization rules described in the [CMIS CDB Firmware Binary Management](#141-cmis-cdb-firmware-binary-management) section. +- `part_numbers`: Dictionary mapping raw part numbers to their normalized forms using the normalization rules described in the [CMIS CDB Firmware Binary Management](#141-cmis-cdb-firmware-binary-management) section. + +Example of `normalization_mappings.json`: + +```json +{ + "vendor_names": { + "ACME Corp.": "ACME_CORP", + "Example & Co": "EXAMPLE_CO", + "Vendor/Inc": "VENDOR_INC", + "Tech-Solutions Ltd.": "TECH_SOLUTIONS_LTD" + }, + "part_numbers": { + "QSFP-100G-AOC-15M": "QSFP-100G-AOC-GENERIC_2_ENDM", + "QSFP-100G-AOC-10M": "QSFP-100G-AOC-GENERIC_2_ENDM", + "QSFP-100G-AOC-3M": "QSFP-100G-AOC-GENERIC_1_ENDM", + "QSFP-100G-AOC-25M": "QSFP-100G-AOC-GENERIC_2_ENDM", + "QSFP-2X100G-AOC-15M": "QSFP-2X100G-AOC-GENERIC_2_ENDM", + "QSFP-2X100G-AOC-10M": "QSFP-2X100G-AOC-GENERIC_2_ENDM", + "SFP-1000BASE-LX": "SFP-1000BASE-LX", + "DAC-400G-5M": "DAC-400G-GENERIC_1_ENDM" + } +} +``` + +##### Per-DUT File Structure + +**File location:** `ansible/files/transceiver/inventory/dut_info/.json` + +**Naming convention:** Each file must be named exactly as the DUT's hostname (e.g., `sonic-device-01.json`, `lab-switch-05.json`). + +**Discovery:** The framework automatically discovers and loads the appropriate DUT file based on the current testbed's DUT hostname. + +##### Per-Port Fields + +**Mandatory Fields:** + +- `vendor_name`: The name of the vendor as specified in the transceiver's EEPROM. +- `vendor_pn`: The vendor part number as specified in the transceiver's EEPROM. +- `transceiver_configuration`: The transceiver configuration name following the format defined in the **Transceiver Configuration Format** section below. The DEPLOYMENT component of this field is used to reference deployment configurations in the per-category attribute files. + +**Optional Fields:** + +- `vendor_sn`: The vendor serial number. +- `vendor_date`: The vendor date code. +- `vendor_oui`: The vendor OUI. +- `vendor_rev`: The vendor revision number. +- `hardware_rev`: The hardware revision number. + +##### Field Handling Rules + +- **Normalized values are derived automatically**: The framework will look up `vendor_name` and `vendor_pn` in the `normalization_mappings.json` file to get the corresponding normalized values. +- **Default normalization**: If no mapping is found in `normalization_mappings.json`, the normalized value defaults to the original value. +- **Cable length normalization**: For modules such as **AOC cables** (or any module whose part number includes a cable length), it is **mandatory** to provide a mapping in `normalization_mappings.json` `part_numbers` section following the cable length normalization rules. +- **Port expansion processing**: Range and list specifications are expanded to individual ports before attribute processing. +- **Overlapping port specifications**: Multiple port specifications can target the same port. Later specifications override attributes from earlier ones, enabling efficient configuration patterns like defining shared attributes in ranges and port-specific attributes individually. +- **Deferred mandatory field validation**: Mandatory fields are validated after all applicable port specifications have been merged for each port, allowing flexible configuration where some fields come from ranges and others from individual port entries. +- **Transceiver configuration format**: The `transceiver_configuration` field uses a mandatory 6-component naming format to fully describe a transceiver's deployment characteristics: + + **Format (Mandatory)**: `{TYPE}-{SPEED}-{FORM_FACTOR}-{DEPLOYMENT}-{MEDIA_LANE_MASK}-{HOST_LANE_MASK}` + + **Note**: The hyphen (`-`) character acts as a delimiter between each component, enabling straightforward parsing by splitting the configuration string on this delimiter. + + **Component Definitions:** + +**Physical Port Based Components** (determined by the physical transceiver module): + +- **TYPE**: Cable/optics type - AOC, AEC, LPO, LRO, TRO, CPO, DAC, DR, FR, LR, ZR, Backplane +- **SPEED**: Total aggregate speed in Gbps (e.g., 1, 10, 25, 100, 200, 400, 800, 1600) +- **FORM_FACTOR**: Physical form factor - CPO, OSFP, QSFPDD, QSFP, SFP +- **DEPLOYMENT**: Traffic deployment pattern describing how the speed is distributed (this list is expected to grow in future). This component serves as a means to combine similar attributes for a particular deployment pattern together in test attribute JSON files, grouping required attributes irrespective of the transceiver or platform vendor: + - `2x100G_200G_SIDE` - 200G side of a 2x100G breakout cable + - `2x100G_100G_SIDE` - 100G side of a 2x100G breakout cable + - `4x100G_400G_SIDE` - 400G side of a 4x100G breakout cable + - `4x100G_100G_SIDE` - 100G side of a 4x100G breakout cable + - `2x200G_400G_SIDE` - 400G side of a 2x200G breakout cable + - `2x200G_200G_SIDE` - 200G side of a 2x200G breakout cable + - `4x200G_800G_SIDE` - 800G side of a 4x200G breakout cable + - `4x200G_200G_SIDE` - 200G side of a 4x200G breakout cable + - `8x100G_800G_SIDE` - 800G side of an 8x100G breakout cable + - `8x100G_100G_SIDE` - 100G side of an 8x100G breakout cable + - `400G_STRAIGHT` - 400G total as single port (no breakout) + - `800G_STRAIGHT` - 800G total as single port (no breakout) + - `1G_STRAIGHT` - 1G total as single port + +**Logical Port Based Components** (specific to individual logical interfaces): + +- **MEDIA_LANE_MASK**: Hexadecimal bitmask indicating which media/optical lanes are used (e.g., 0x01, 0x0F, 0xFF) +- **HOST_LANE_MASK**: Hexadecimal bitmask indicating which host/electrical lanes are used (e.g., 0x01, 0x0F, 0xFF) + +**Configuration Examples:** + +- `AOC-200-QSFPDD-2x100G_200G_SIDE-0xF-0xF` - Active Optical Cable, 200G speed, QSFP-DD form factor, 200G side of 2x100G deployment, 4 media lanes (0-3), 4 host lanes (0-3) +- `AOC-100-QSFPDD-2x100G_100G_SIDE-0xF-0xF` - Active Optical Cable, 100G speed, QSFP-DD form factor, 100G side of 2x100G deployment, 4 media lanes (0-3), 4 host lanes (0-3) +- `LR-1-SFP-1G_STRAIGHT-0x01-0x01` - LR specification, 1G total, SFP form factor, straight deployment, 1 media lane, 1 host lane +- `DAC-400-OSFP-400G_STRAIGHT-0x0F-0x0F` - Direct Attach Cable, 400G total, OSFP form factor, straight deployment, 4 media lanes (0-3), 4 host lanes (0-3) +- `DR-800-OSFP-4x200G_800G_SIDE-0xFF-0xFF` - DR specification, 800G speed, OSFP form factor, 800G side of 4x200G deployment, 8 media lanes (all), 8 host lanes (all) +- `DR-200-OSFP-4x200G_200G_SIDE-0xFF-0xFF` - DR specification, 200G speed, OSFP form factor, 200G side of 4x200G deployment, 8 media lanes (all), 8 host lanes (all) + +**Purpose**: This standardized format enables: + +- Automatic parsing of transceiver characteristics for test frameworks +- Deployment pattern grouping for shared attribute configurations +- Clear identification of lane usage and deployment topology + +##### Port Specification Formats + +The framework supports multiple flexible port specification formats to reduce configuration overhead: + +1. **Individual Port**: `"Ethernet0"` - Single port specification +2. **Range**: `"Ethernet4:13"` - Continuous range from Ethernet4 to Ethernet12 (exclusive of 13, following Python slice convention) +3. **Range with Step**: `"Ethernet0:97:4"` - Range with step size (Ethernet0, Ethernet4, Ethernet8, ..., Ethernet96) +4. **List**: `"Ethernet16,Ethernet20,Ethernet24"` - Comma-separated list of specific ports without spaces +5. **Mixed**: `"Ethernet28:33,Ethernet36,Ethernet40:45"` - Combination of ranges and individual ports + +**Requirements:** + +- Port numbering must follow SONiC logical port naming convention (e.g., Ethernet0, Ethernet4, Ethernet8...) +- Range format follows Python slice convention (start:stop where stop is exclusive) +- Step size must be > 0 for range with step format + +##### Framework Implementation Requirements + +The test framework must implement the following core components to process per-DUT files and create a comprehensive `port_attributes_dict` dictionary. All parsed data is stored in `port_attributes_dict["EthernetXX"]["BASE_ATTRIBUTES"]` as the foundation for test operations. +More details on the `port_attributes_dict` structure and usage are provided in the Test Category Attribute Files section. + +**File Discovery and Loading:** + +1. **Load Normalization Mappings**: Parse `normalization_mappings.json` once at framework initialization. +2. **Discover DUT File**: Determine current DUT hostname from testbed configuration. +3. **Load DUT Data**: Open and parse `dut_info/.json`. +4. **Error Handling**: Provide clear error messages if: + - `normalization_mappings.json` is missing or invalid + - DUT file for current hostname is not found + - JSON parsing fails + +###### 1. Port Expansion Processing + +**Purpose**: Handle various port specification formats and expand them into individual port names. + +**Processing Algorithm**: + +1. **Parse Port Specifications**: Identify range, list, and individual port formats +2. **Expand to Individual Ports**: Convert all specifications to individual port names +3. **Merge Overlapping Attributes**: Collect all attributes for each port, with later port specifications overriding earlier ones +4. **Deferred Validation**: Validate mandatory fields after all applicable port specifications have been merged +5. **Generate Final Dictionary**: Create the standard per-port attribute dictionary + +###### 2. Transceiver Configuration String Parsing + +**Purpose**: Extract all components from the `transceiver_configuration` string during base attributes initialization phase. + +**Requirements**: + +- Parse the mandatory 6-component format: `{TYPE}-{SPEED}-{FORM_FACTOR}-{DEPLOYMENT}-{MEDIA_LANE_MASK}-{HOST_LANE_MASK}` +- Store all parsed components in `BASE_ATTRIBUTES` for easy access by all test categories +- Handle error cases (invalid format, missing components) + +**Implementation Example**: + +```python + def parse_transceiver_configuration(config_string): + """ + Parse transceiver configuration string into individual components. + Format: {TYPE}-{SPEED}-{FORM_FACTOR}-{DEPLOYMENT}-{MEDIA_LANE_MASK}-{HOST_LANE_MASK} + Example: "AOC-200-QSFPDD-2x100G_200G_SIDE-0xFF-0xFF" + Returns: dictionary with all parsed components + """ + if not config_string: + return {} + + parts = config_string.split('-') + if len(parts) != 6: + raise ValueError("Invalid transceiver configuration format: {}".format(config_string)) + + type_name, speed, form_factor, deployment, media_mask, host_mask = parts + + # Parse lane counts from hexadecimal masks + media_lane_count = bin(int(media_mask, 16)).count('1') + host_lane_count = bin(int(host_mask, 16)).count('1') + + return { + 'cable_type': type_name, + 'speed_gbps': int(speed), + 'form_factor': form_factor, + 'deployment': deployment, + 'media_lane_mask': media_mask, + 'host_lane_mask': host_mask, + 'media_lane_count': media_lane_count, + 'host_lane_count': host_lane_count + } +``` + +###### 3. Dictionary Management + +**Purpose**: Create and maintain the comprehensive port attributes dictionary that serves as the source of truth for test cases. + +**Requirements**: + +- Load `normalization_mappings.json` for vendor/PN normalization lookup +- Parse per-DUT file (`dut_info/.json`) and store data in `port_attributes_dict["EthernetXX"]["BASE_ATTRIBUTES"]` for the current DUT +- Support overlapping port specifications by merging attributes per port (later specs override earlier ones) +- Validate mandatory fields only after all applicable port specifications have been processed and merged +- Include all mandatory and optional fields, along with normalized values and parsed configuration components +- Implement proper error handling and validation + +Example of a dictionary created by parsing the above file: + +```python + { + "Ethernet0": { + "BASE_ATTRIBUTES": { + "vendor_name": "ACME Corp.", + "normalized_vendor_name": "ACME_CORP", # looked up from normalization_mappings.json + "vendor_pn": "QSFP-2X100G-AOC-15M", + "normalized_vendor_pn": "QSFP-2X100G-AOC-GENERIC_2_ENDM", # looked up from normalization_mappings.json + "transceiver_configuration": "AOC-200-QSFPDD-2x100G_200G_SIDE-0xFF-0xFF", # single string configuration + # Parsed components from transceiver_configuration + "cable_type": "AOC", # extracted from TYPE + "speed_gbps": 200, # extracted from SPEED + "form_factor": "QSFPDD", # extracted from FORM_FACTOR + "deployment": "2x100G_200G_SIDE", # extracted from DEPLOYMENT + "media_lane_mask": "0xFF", # extracted from MEDIA_LANE_MASK + "host_lane_mask": "0xFF", # extracted from HOST_LANE_MASK + "media_lane_count": 8, # derived from media_lane_mask + "host_lane_count": 8, # derived from host_lane_mask + "vendor_sn": "serial_number_001", + "vendor_date": "vendor_date_code", + "vendor_oui": "vendor_oui", + "vendor_rev": "revision_number", + "hardware_rev": "hardware_revision_number" + } + }, + "Ethernet4": { + "BASE_ATTRIBUTES": { + "vendor_name": "ACME Corp.", + "normalized_vendor_name": "ACME_CORP", + "vendor_pn": "QSFP-2X100G-AOC-15M", + "normalized_vendor_pn": "QSFP-2X100G-AOC-GENERIC_2_ENDM", + "transceiver_configuration": "AOC-100-QSFPDD-2x100G_100G_SIDE-0xFF-0xFF", # single string configuration + # Parsed components from transceiver_configuration + "cable_type": "AOC", # extracted from TYPE + "speed_gbps": 100, # extracted from SPEED + "form_factor": "QSFPDD", # extracted from FORM_FACTOR + "deployment": "2x100G_100G_SIDE", # extracted from DEPLOYMENT + "media_lane_mask": "0xFF", # extracted from MEDIA_LANE_MASK + "host_lane_mask": "0xFF", # extracted from HOST_LANE_MASK + "media_lane_count": 8, # derived from media_lane_mask + "host_lane_count": 8, # derived from host_lane_mask + "vendor_sn": "serial_number_range", # same value for all ports in range + "vendor_date": "vendor_date_code", + "vendor_oui": "vendor_oui", + "vendor_rev": "revision_number", + "hardware_rev": "hardware_revision_number" + } + }, + "Ethernet5": { + "BASE_ATTRIBUTES": { + "vendor_name": "ACME Corp.", + "normalized_vendor_name": "ACME_CORP", + "vendor_pn": "QSFP-2X100G-AOC-15M", + "normalized_vendor_pn": "QSFP-2X100G-AOC-GENERIC_2_ENDM", + "transceiver_configuration": "AOC-100-QSFPDD-2x100G_100G_SIDE-0xFF-0xFF", # single string configuration + # Parsed components from transceiver_configuration + "cable_type": "AOC", # extracted from TYPE + "speed_gbps": 100, # extracted from SPEED + "form_factor": "QSFPDD", # extracted from FORM_FACTOR + "deployment": "2x100G_100G_SIDE", # extracted from DEPLOYMENT + "media_lane_mask": "0xFF", # extracted from MEDIA_LANE_MASK + "host_lane_mask": "0xFF", # extracted from HOST_LANE_MASK + "media_lane_count": 8, # derived from media_lane_mask + "host_lane_count": 8, # derived from host_lane_mask + "vendor_sn": "serial_number_range", # same value for all ports in range "vendor_date": "vendor_date_code", "vendor_oui": "vendor_oui", "vendor_rev": "revision_number", - "vendor_sn": "serial_number", - "vendor_pn": "vendor_part_number", - "normalized_vendor_pn": "normalized_vendor_part_number", - "active_firmware": "active_firmware_version", - "inactive_firmware": "inactive_firmware_version", - "cmis_rev": "cmis_revision", - "vendor_name": "vendor_name", - "normalized_vendor_name": "normalized_vendor_name", - 'vdm_supported': True, - 'cdb_backgroundmode_supported': True, - 'dual_bank_supported': True - }, - "port_2": { + "hardware_rev": "hardware_revision_number" + } + }, + "Ethernet6": { + "BASE_ATTRIBUTES": { + "vendor_name": "ACME Corp.", + "normalized_vendor_name": "ACME_CORP", + "vendor_pn": "QSFP-2X100G-AOC-15M", + "normalized_vendor_pn": "QSFP-2X100G-AOC-GENERIC_2_ENDM", + "transceiver_configuration": "AOC-200-QSFPDD-2x100G_200G_SIDE-0xFF-0xFF", # single string configuration + # Parsed components from transceiver_configuration + "cable_type": "AOC", # extracted from TYPE + "speed_gbps": 200, # extracted from SPEED + "form_factor": "QSFPDD", # extracted from FORM_FACTOR + "deployment": "2x100G_200G_SIDE", # extracted from DEPLOYMENT + "media_lane_mask": "0xFF", # extracted from MEDIA_LANE_MASK + "host_lane_mask": "0xFF", # extracted from HOST_LANE_MASK + "media_lane_count": 8, # derived from media_lane_mask + "host_lane_count": 8, # derived from host_lane_mask + "vendor_sn": "serial_number_range", # same value for all ports in range "vendor_date": "vendor_date_code", "vendor_oui": "vendor_oui", "vendor_rev": "revision_number", - "vendor_sn": "serial_number", - "vendor_pn": "vendor_part_number", - "normalized_vendor_pn": "normalized_vendor_part_number", - "active_firmware": "active_firmware_version", - "inactive_firmware": "inactive_firmware_version", - "cmis_rev": "cmis_revision", - "vendor_name": "vendor_name", - "normalized_vendor_name": "normalized_vendor_name", - 'vdm_supported': True, - 'cdb_backgroundmode_supported': True, - 'dual_bank_supported': True + "hardware_rev": "hardware_revision_number" + } + }, + "Ethernet16": { + "BASE_ATTRIBUTES": { + "vendor_name": "Example & Co", + "normalized_vendor_name": "EXAMPLE_CO", # looked up from normalization_mappings.json + "vendor_pn": "SFP-1000BASE-LX", + "normalized_vendor_pn": "SFP-1000BASE-LX", # looked up from normalization_mappings.json (same value) + "transceiver_configuration": "LR-1-SFP-1G_STRAIGHT-0x01-0x01", # single string configuration + # Parsed components from transceiver_configuration + "cable_type": "LR", # extracted from TYPE + "speed_gbps": 1, # extracted from SPEED + "form_factor": "SFP", # extracted from FORM_FACTOR + "deployment": "1G_STRAIGHT", # extracted from DEPLOYMENT + "media_lane_mask": "0x01", # extracted from MEDIA_LANE_MASK + "host_lane_mask": "0x01", # extracted from HOST_LANE_MASK + "media_lane_count": 1, # derived from media_lane_mask + "host_lane_count": 1 # derived from host_lane_mask + } + }, + "Ethernet20": { + "BASE_ATTRIBUTES": { + "vendor_name": "Example & Co", + "normalized_vendor_name": "EXAMPLE_CO", # looked up from normalization_mappings.json + "vendor_pn": "SFP-1000BASE-LX", + "normalized_vendor_pn": "SFP-1000BASE-LX", # looked up from normalization_mappings.json + "transceiver_configuration": "LR-1-SFP-1G_STRAIGHT-0x01-0x01", # single string configuration + # Parsed components from transceiver_configuration + "cable_type": "LR", # extracted from TYPE + "speed_gbps": 1, # extracted from SPEED + "form_factor": "SFP", # extracted from FORM_FACTOR + "deployment": "1G_STRAIGHT", # extracted from DEPLOYMENT + "media_lane_mask": "0x01", # extracted from MEDIA_LANE_MASK + "host_lane_mask": "0x01", # extracted from HOST_LANE_MASK + "media_lane_count": 1, # derived from media_lane_mask + "host_lane_count": 1 # derived from host_lane_mask } } + # Additional ports expanded from ranges and lists... } - ``` +``` -2. A file named `transceiver_common_attributes.csv` (located in the `ansible/files/transceiver_inventory` directory) must be present to define the common attributes for each transceiver, keyed by normalized vendor part number. The file should use the following format: +#### 2. Test Category Attribute Files - ```csv - normalized_vendor_name,normalized_vendor_pn,active_firmware,inactive_firmware,cmis_rev,vdm_supported,cdb_backgroundmode_supported,dual_bank_supported - ,,,,,,, - ,,,,,,, - # Add more entries as needed - ``` +> 🔄 **Process Flow**: See the [Data Flow Architecture Diagram](diagrams/data_flow.md) for a comprehensive view of how these files are processed and merged. - - `normalized_vendor_name`: The normalized vendor name, created by applying the normalization rules described in the [CMIS CDB Firmware Binary Management](#141-cmis-cdb-firmware-binary-management) section. -
The normalization rules ensure that the vendor name is consistent and compatible with directory structures used in firmware management and upgrade tests. - - `normalized_vendor_pn`: The normalized vendor part number, created by applying the normalization rules described in the [CMIS CDB Firmware Binary Management](#141-cmis-cdb-firmware-binary-management) section. -
This ensures the inventory does not need to list every possible cable length and standardizes the format for compatibility with directory structures used in firmware management and upgrade tests. See the detailed normalization rules in the referenced section for full details. - - `active_firmware` and `inactive_firmware`: Firmware version strings in the format `X.Y.Z` (e.g., `1.2.3`). The `active_firmware` version represents the gold firmware version. - - `cmis_rev`: CMIS revision string in the format `X.Y`. - - `vdm_supported`, `cdb_backgroundmode_supported`, `dual_bank_supported`: Boolean values indicating support for VDM, CDB background mode, and dual bank firmware, respectively. - -3. A `transceiver_firmware_info.csv` file (located in `ansible/files/transceiver_inventory` directory) should exist if a transceiver being tested supports CMIS CDB firmware upgrade. This file will capture the firmware binary metadata for the transceiver. Each transceiver should have at least 2 firmware binaries (in addition to the gold firmware binary) so that firmware upgrade can be tested. Following should be the format of the file - - ```csv - normalized_vendor_name,normalized_vendor_pn,fw_version,fw_binary_name,md5sum - ,,,, - ,,,, - ,,,, - # Add more vendor part numbers as needed - ``` +Multiple JSON files based on test category define the metadata and test-specific attributes required for each type of transceiver. +**Note:** If a test category attribute file is absent, the corresponding test case will be skipped. This allows for selective test execution and gradual framework adoption. - For each firmware binary, the following metadata should be included: +##### File Organization - - `normalized_vendor_name`: The normalized vendor name, created by applying the normalization rules described in the [CMIS CDB Firmware Binary Management](#141-cmis-cdb-firmware-binary-management) section. - - `normalized_vendor_pn`: The normalized vendor part number, created by applying the normalization rules described in the [CMIS CDB Firmware Binary Management](#141-cmis-cdb-firmware-binary-management) section. - - `fw_version`: The version of the firmware. - - `fw_binary_name`: The filename of the firmware binary. - - `md5sum`: The MD5 checksum of the firmware binary. +**Recommended JSON files:** -4. A `cmis_cdb_firmware_base_url.csv` file (located in `ansible/files/transceiver_inventory` directory) should be present to define the base URL for downloading CMIS CDB firmware binaries. The file should follow this format: +- `eeprom.json` (EEPROM tests) +- `system.json` (System tests) +- `physical_oir.json` (Physical OIR) +- `remote_reseat.json` (remote reseat) +- `cdb_fw_upgrade.json` (CDB FW Upgrade tests) +- `dom.json` (DOM) +- `vdm.json` (VDM) +- `pm.json` (PM) - ```csv - inv_name,fw_base_url - , - ``` +**Location:** `ansible/files/transceiver/inventory/attributes/` directory - - `inv_name`: The name of the inventory file that contains the definition of the target DUTs. For further details, please refer to the [Inventory File](https://github.com/sonic-net/sonic-mgmt/blob/master/docs/testbed/README.new.testbed.Configuration.md#inventory-file). The `inv_name` allows DUTs to be grouped based on their inventory file, enabling the test framework to fetch the correct base URL for firmware downloads. - - `fw_base_url`: The base URL from which the CMIS CDB firmware binaries can be downloaded. This URL should point to the directory where the firmware binaries are stored. e.g., `http://1.2.3.4/cmis_cdb_firmware/`. +##### JSON Schema Structure - Example of the file: +All files follow a consistent schema with these main sections: - ```csv - inv_name,fw_base_url - lab,http://1.2.3.4/cmis_cdb_firmware/ - ``` +```json +{ + "mandatory": ["field_1", "field_2", "field_3"], + "defaults": { + "field_4": "value_4", + "field_5": "value_5" + }, + "platform": { + "PLATFORM_NAME": { + "field_4": "platform_override_value" + } + }, + "hwsku": { + "HWSKU_NAME": { + "field_5": "hwsku_override_value" + } + }, + "dut": { + "DUT_NAME": { + "field_1": "dut_specific_value_1" + } + }, + "transceivers": { + "deployment_configurations": { + "DEPLOYMENT_NAME": { + "field_2": "deployment_specific_value_2" + } + }, + "vendors": { + "NORMALIZED_VENDOR_NAME": { + "defaults": { + "field_6": "vendor_default_value" + }, + "part_numbers": { + "NORMALIZED_VENDOR_PN": { + "field_1": "specific_value_1", + "platform_hwsku_overrides": { + "PLATFORM_NAME+HWSKU_NAME": { + "field_1": "highest_priority_value" + } + } + } + } + } + } + } +} +``` + +##### Schema Components + +**Main Sections:** + +- `mandatory`: List of mandatory fields that must be present in the attributes at some level of the hierarchy (cannot be in `defaults`) +- `defaults`: Default values for the transceiver or test attributes +- `platform`: Platform-specific overrides (optional) +- `hwsku`: HWSKU-specific overrides (optional) +- `dut`: DUT-specific overrides (optional) wherein the `DUT_NAME` is the inventory based hostname of the DUT +- `transceivers`: Contains vendor and deployment-specific configurations organized in a hierarchical structure (mandatory) + - `deployment_configurations`: Deployment-based attribute definitions using the mandatory naming format (e.g., AOC-200-QSFPDD-2x100G_200G_SIDE-0xFF-0xFF, AOC-100-QSFPDD-2x100G_100G_SIDE-0xFF-0xFF, DAC-400-OSFP-400G_STRAIGHT-0x0F-0x0F) (optional) + - `vendors`: Vendor-specific configurations organized by normalized vendor name (optional) + - ``: Individual vendor section containing defaults and part number configurations + - `defaults`: Vendor-level default values (optional) + - `part_numbers`: Part number-specific configurations organized by normalized part number (optional) + - ``: Individual part number section with specific attributes and overrides + - `platform_hwsku_overrides`: Overrides for specific platform+HWSKU combinations (optional) + +> Note: Each sub-section can contain its own `defaults` fields. + +**Key Design Rules:** + +- **No Overlap**: A field should **never** appear in both `mandatory` and `defaults` sections. This creates logical inconsistency because a field cannot simultaneously require explicit specification (mandatory) and have a fallback value (default). The framework would be unable to determine whether to enforce validation or apply defaults when the field is missing. +- **Validation First**: The framework should first validate that all mandatory fields can be resolved through the priority hierarchy, then apply defaults for any missing optional fields. +- **Category Isolation**: Each file contains only relevant test domain attributes +- **Deployment Grouping**: Similar deployment patterns share common attributes via `deployment_configurations` +- **Category Isolation**: Each category file should only contain attributes relevant to its specific test domain to maintain clear separation of concerns. +- **Backward Compatibility**: Missing optional sections (platform, hwsku, etc.) are silently ignored to support gradual adoption and legacy configurations. + +##### Deployment Configurations + +The `deployment_configurations` feature eliminates attribute duplication by defining common attributes once per deployment type instead of repeating across vendors. The framework automatically extracts the DEPLOYMENT component from the `BASE_ATTRIBUTES` field in `port_attributes_dict` to determine which deployment configuration to apply. + +##### Priority-Based Attribute Resolution + +Attributes are resolved using this hierarchy (highest to lowest priority): + +1. **DUT-specific**: `dut.` +2. **Normalized Vendor Name + PN + Platform + HWSKU**: `transceivers.vendors..part_numbers..platform_hwsku_overrides.+` +3. **Normalized Vendor Name + PN**: `transceivers.vendors..part_numbers.` +4. **Normalized Vendor Name (defaults)**: `transceivers.vendors..defaults` +5. **Deployment Configuration**: `transceivers.deployment_configurations.` (resolved by extracting DEPLOYMENT from the `transceiver_configuration` field in `dut_info/.json`) +6. **HWSKU-specific**: `hwsku.` (if present in the file) +7. **Platform-specific**: `platform.` (if present in the file) +8. **Global defaults**: `defaults` + +> **Note:** For platform+HWSKU combinations in `platform_hwsku_overrides`, the key format is `"+"` where the platform name and HWSKU name are concatenated with a literal `+` symbol. + +##### Example Category File + +Example `eeprom.json` file: + +```json +{ + "mandatory": ["vendor_name", "normalized_vendor_name", "dual_bank_supported"], + "defaults": { + "vdm_supported": false, + "cdb_backgroundmode_supported": false, + "sfputil_eeprom_dump_sec": 2 + }, + "transceivers": { + "deployment_configurations": { + "2x100G_200G_SIDE": { + "vdm_supported": true, + "dual_bank_supported": true + } + }, + "vendors": { + "NORMALIZED_VENDOR_A": { + "defaults": {"vdm_supported": false}, + "part_numbers": { + "NORMALIZED_VENDOR_PN_ABC": { + "vendor_name": "Vendor A", + "dual_bank_supported": true, + "platform_hwsku_overrides": { + "PLATFORM_ABC+VENDOR_HWSKU_ABC": { + "sfputil_eeprom_dump_time": 5 + } + } + } + } + } + } + } +} +``` + +##### Framework Implementation + +The test framework loads and merges attributes from all relevant category files for each transceiver, using hierarchical override rules. This enables category-specific test logic to access only needed attributes while supporting platform, HWSKU, and vendor overrides. + +**Core Components:** + +1. **AttributeManager**: Central class for loading, merging, and accessing transceiver attributes +2. **Category File Loader**: Loads JSON files for each test category +3. **Priority Resolver**: Implements the 8-level priority hierarchy +4. **Validator**: Ensures mandatory fields are present + +**Data Structure:** +The framework builds a `port_attributes_dict` keyed by logical port name, containing only ports from `dut_info/.json`: + +```python +{ + "PORT_NAME": { + # Base transceiver information from dut_info/.json + "BASE_ATTRIBUTES": { + "vendor_name": "vendor_name", + "normalized_vendor_name": "NORMALIZED_VENDOR_NAME", + "vendor_pn": "vendor_part_number", + "normalized_vendor_pn": "NORMALIZED_VENDOR_PN", + "vendor_sn": "serial_number", + "vendor_date": "vendor_date_code", + "vendor_oui": "vendor_oui", + "vendor_rev": "revision_number", + "transceiver_configuration": "AOC-200-QSFPDD-2x100G_200G_SIDE-0xFF-0xFF", # original configuration string + # Parsed components from transceiver_configuration + "cable_type": "AOC", # extracted from TYPE + "speed_gbps": 200, # extracted from SPEED + "form_factor": "QSFPDD", # extracted from FORM_FACTOR + "deployment": "2x100G_200G_SIDE", # extracted from DEPLOYMENT + "media_lane_mask": "0xFF", # extracted from MEDIA_LANE_MASK + "host_lane_mask": "0xFF", # extracted from HOST_LANE_MASK + "media_lane_count": 8, # derived from media_lane_mask + "host_lane_count": 8 # derived from host_lane_mask + }, + # Category-specific attributes with merged overrides applied + "EEPROM_ATTRIBUTES": { + "attribute_1": "value_1", + "attribute_2": "value_2", + ... + } + "SYSTEM_ATTRIBUTES": { + "attribute_1": "value_1", + "attribute_2": "value_2", + ... + } + ... + } +} +``` + +##### Attribute Merging Process + +The framework builds `port_attributes_dict` using this systematic process: + +1. **Initialize** port dictionary from `dut_info/.json` base attributes +2. **For each category file**, perform priority-based merging using the 8-level hierarchy +3. **Validate** mandatory fields for the current category +4. **Store** merged attributes under category key (e.g., `EEPROM_ATTRIBUTES`, `SYSTEM_ATTRIBUTES`) +5. **Expose** the complete dictionary via the session-scoped fixture `port_attributes_dict` (an autouse session fixture logs its contents for traceability). + +**Merging Behavior:** + +- Higher priority fields completely override earlier values +- Missing sections are silently skipped +- Graceful error handling for missing files and invalid JSON +- The entire `port_attributes_dict` is captured in the log for debugging + +##### Usage + +Tests access attributes using: `port_attributes_dict[port_name][category_key][attribute_name]` +The `port_attributes_dict` is provided directly as a session-scoped fixture and is also initialized early for logging. + +**Example (inside a test):** + +```python +def test_example(port_attributes_dict): + # Access EEPROM attributes + eeprom_attrs = port_attributes_dict["Ethernet0"].get("EEPROM_ATTRIBUTES", {}) + dual_bank_supported = eeprom_attrs.get("dual_bank_supported") + + # Access base transceiver configuration (parsed from transceiver_configuration) + base_attrs = port_attributes_dict["Ethernet0"]["BASE_ATTRIBUTES"] + cable_type = base_attrs["cable_type"] + deployment = base_attrs["deployment"] + + assert cable_type in ("AOC", "DAC", "LR", "DR") +``` + +**Benefits:** Modular design, independent updates per category, conflict prevention, flexible overrides, and performance optimization. + +#### 3. Attribute Completeness Validation + +> **Process Flow**: See the [Validation Flow Diagram](diagrams/validation_flow.md) for a visual overview of the validation process and pytest integration. + +Optional post-processing validation ensures comprehensive attribute coverage for transceiver qualification by comparing the populated `port_attributes_dict` against deployment-specific templates. + +##### Template Structure + +**Location:** `ansible/files/transceiver/inventory/templates/deployment_templates.json` + +**Schema:** Templates define required and optional attributes by deployment type: -5. A file (`sonic_{inv_name}_links.csv`) containing the connections of the ports should be present. This file is used to create the topology of the testbed which is required for minigraph generation. +```json +{ + "deployment_templates": { + "2x100G_200G_SIDE": { + "required_attributes": { + "BASE_ATTRIBUTES": ["vendor_name", "vendor_pn", "cable_type", "speed_gbps", "deployment"], + "EEPROM_ATTRIBUTES": ["dual_bank_supported", "vdm_supported"], + "DOM_ATTRIBUTES": ["temperature", "voltage", "tx_power", "alarm_flags"] + }, + "optional_attributes": { + "BASE_ATTRIBUTES": ["hardware_rev", "vendor_rev"], + "CDB_FW_ATTRIBUTES": ["firmware_upgrade_support"] + } + } + } +} +``` + +##### Template Components + +- `deployment_templates`: Root object containing all deployment templates + - ``: Individual deployment template (e.g., `2x100G_200G_SIDE`) + - `required_attributes`: Lists of attributes that must be present for each category + - `optional_attributes`: Lists of attributes that should be present if available + - **Note:** Each category (e.g., `BASE_ATTRIBUTES`, `EEPROM_ATTRIBUTES`, `DOM_ATTRIBUTES`) can have its own set of required and optional attributes. + +##### Validation Process + +1. **Template Selection**: Uses `deployment` field from `BASE_ATTRIBUTES` to select appropriate template +2. **Attribute Comparison**: Compares actual vs required attributes per category +3. **Gap Analysis**: Identifies missing required/optional attributes +4. **Pytest Integration**: Reports results with standard log levels (INFO/WARNING/ERROR/DEBUG) + +##### Configuration Control + +The validation feature can also be controlled via passing a test parameters: + +- **`--skip_transceiver_template_validation`**: When specified, completely bypasses the attribute completeness validation + - Use case: Quick test runs during development or when template definitions are incomplete + - Default: `False` (validation is performed if the deployment_templates.json files exists) + - Example: `pytest test_transceiver.py --skip_transceiver_template_validation` + +**Note:** Even when validation is skipped, all attributes from category files are still loaded and available for test execution. This parameter only affects the post-processing template validation step. + +##### Console Output + +```python +INFO PASS: Ethernet0 (2x100G_200G_SIDE) - FULLY_COMPLIANT (19/20 attributes) +WARNING PARTIAL: Ethernet4 - Missing optional: VDM_ATTRIBUTES.historical_data +ERROR FAIL: Ethernet8 - Missing required: DOM_ATTRIBUTES.alarm_flags +INFO Overall Compliance: 87.5% (21/24 ports fully compliant) +``` + +##### Execution Control + +The validation results determine test execution flow: + +- **Critical failures**: `pytest.fail()` - stops test execution when required attributes are missing +- **Warnings only**: `pytest.warns()` - continues with warnings for missing optional attributes +- **Fully compliant**: Normal test execution proceeds without validation messages + +**Skipping Validation:** + +- Use `--skip_transceiver_template_validation` pytest parameter to completely bypass this validation step +- See the "Configuration Control" section above for detailed usage information - - `inv_name` - inventory file name that contains the definition of the target DUTs. For further details, please refer to the [Inventory File](https://github.com/sonic-net/sonic-mgmt/blob/master/docs/testbed/README.new.testbed.Configuration.md#inventory-file) +#### 4. Transceiver Firmware Info File + +A `transceiver_firmware_info.csv` file (located in `ansible/files/transceiver/inventory` directory) should exist if a transceiver being tested supports CMIS CDB firmware upgrade. This file will capture the firmware binary metadata for the transceiver. Each transceiver should have at least 2 firmware binaries (in addition to the gold firmware binary) so that firmware upgrade can be tested. Following should be the format of the file + +```csv +normalized_vendor_name,normalized_vendor_pn,fw_version,fw_binary_name,md5sum +,,,, +,,,, +,,,, +# Add more vendor part numbers as needed +``` + +For each firmware binary, the following metadata should be included: + +- `normalized_vendor_name`: The normalized vendor name, created by applying the normalization rules described in the [CMIS CDB Firmware Binary Management](#141-cmis-cdb-firmware-binary-management) section. +- `normalized_vendor_pn`: The normalized vendor part number, created by applying the normalization rules described in the [CMIS CDB Firmware Binary Management](#141-cmis-cdb-firmware-binary-management) section. +- `fw_version`: The version of the firmware. +- `fw_binary_name`: The filename of the firmware binary. +- `md5sum`: The MD5 checksum of the firmware binary. + +#### 5. CMIS CDB Firmware Base URL File + +A `cmis_cdb_firmware_base_url.csv` file (located in `ansible/files/transceiver/inventory` directory) should be present to define the base URL for downloading CMIS CDB firmware binaries. The file should follow this format: + +```csv +inv_name,fw_base_url +, +``` + +- `inv_name`: The name of the inventory file that contains the definition of the target DUTs. For further details, please refer to the [Inventory File](https://github.com/sonic-net/sonic-mgmt/blob/master/docs/testbed/README.new.testbed.Configuration.md#inventory-file). The `inv_name` allows DUTs to be grouped based on their inventory file, enabling the test framework to fetch the correct base URL for firmware downloads. +- `fw_base_url`: The base URL from which the CMIS CDB firmware binaries can be downloaded. This URL should point to the directory where the firmware binaries are stored. e.g., `http://1.2.3.4/cmis_cdb_firmware/`. + +Example of the file: + +```csv +inv_name,fw_base_url +lab,http://1.2.3.4/cmis_cdb_firmware/ +``` #### 1.1 Link related tests @@ -225,7 +922,8 @@ The following tests aim to validate the link status and stability of transceiver |------|------|------------------| | Issue CLI command to shutdown a port | Validate link status using CLI configuration | Ensure that the link goes down | | Issue CLI command to startup a port | Validate link status using CLI configuration | Ensure that the link is up and the port appears in the LLDP table. | -| In a loop, issue startup/shutdown command 100 times | Stress test for link status validation | Ensure link status toggles to up/down appropriately with each startup/shutdown command. Verify ports appear in the LLDP table when the link is up | +| In a loop, issue startup/shutdown command for a port 100 times | Stress test for link status validation | Ensure link status toggles to up/down appropriately with each startup/shutdown command. Verify ports appear in the LLDP table when the link is up | +| In a loop, issue startup/shutdown command for all ports 100 times | Stress test for link status validation | Ensure link status toggles to up/down appropriately for all relevant ports with each startup/shutdown command. Verify ports appear in the LLDP table when the link is up | | Restart `xcvrd` | Test link and xcvrd stability | Confirm `xcvrd` restarts successfully without causing link flaps for the corresponding ports, and verify their presence in the LLDP table. Also ensure that xcvrd is up for at least 2 mins | | Induce I2C errors and restart `xcvrd` | Test link stability in case of `xcvrd` restart + I2C errors | Confirm `xcvrd` restarts successfully without causing link flaps for the corresponding ports, and verify their presence in the LLDP table | | Modify xcvrd.py to raise an Exception and induce a crash | Test link and xcvrd stability | Confirm `xcvrd` restarts successfully without causing link flaps for the corresponding ports, and verify their presence in the LLDP table. Also ensure that xcvrd is up for at least 2 mins | @@ -409,8 +1107,6 @@ lab,http://firmware-server.example.com/cmis_cdb_firmware production,https://secure-firmware.example.com/cmis_cdb_firmware ``` -> Note: The `fw_base_url` should not end with a trailing slash (`/`). The test framework will append the necessary path components based on the normalized vendor name and part number. - **Download URL Format:** Firmware binaries are accessed using the following URL pattern: ``` @@ -431,13 +1127,13 @@ This section describes the automated process for copying firmware binaries to th To ensure only the necessary firmware binaries are present for each transceiver: 1. **Parse `transceiver_firmware_info.csv`** to obtain the list of available firmware binaries, their versions, and associated vendor and part numbers. -2. **Parse `transceiver_dut_info.csv`** to identify the transceivers present on each DUT. -3. **Parse `transceiver_common_attributes.csv`** to get the gold firmware version for each transceiver type. +2. **Parse `dut_info/.json`** to identify the transceivers present on each DUT. +3. **Parse the appropriate per-category attributes file** to get the gold firmware version for each transceiver type. 4. **For each unique combination of normalized vendor name and normalized part number on the DUT**, perform version sorting and selection: - Parse firmware versions using semantic versioning (X.Y.Z format) - Sort available firmware versions in descending order (most recent first) - **Selection criteria:** - - Always include the gold firmware version (from `transceiver_common_attributes.csv`) + - Always include the gold firmware version (from the per-category attributes file) - Include the two most recent firmware versions in addition to the gold version - This ensures at least 2 firmware versions are available for upgrade testing, with the gold version guaranteed to be present as the third firmware binary. If there are fewer than 3 firmware versions available for a transceiver, the entire test will fail. 5. **Copy only the selected firmware binaries** to the target directory structure on the DUT. @@ -456,7 +1152,7 @@ To ensure only the necessary firmware binaries are present for each transceiver: 2. **Platform-specific processes:** On some platforms, `thermalctld` or similar user processes that perform I2C transactions with the module may need to be stopped during firmware operations. 3. **Firmware requirements:** - At least two firmware versions must be available for each transceiver type to enable upgrade testing - - The gold firmware version (specified in `transceiver_common_attributes.csv`) must be available + - The gold firmware version (specified in the per-category attributes file) must be available - All firmware versions must support the CDB protocol for proper testing 4. **Module capabilities:** The module must support dual banks for firmware upgrade operations. 5. **Network connectivity:** The DUT must have network access to the firmware server specified in `cmis_cdb_firmware_base_url.csv` for downloading firmware binaries.