Commit 75d4ecf2 authored by Waleed Akbar's avatar Waleed Akbar
Browse files

For ECOC2026-Add end-to-end tests for NBI → Pluggables → SBI and pluggable management

- Implemented a comprehensive test suite for NBI to Pluggables to SBI interactions, focusing on NETCONF devices.
- Created `test_nbi_pluggable_sbi.py` to validate the full lifecycle of pluggables including creation, configuration, deletion, and state verification.
- Added tests for ensuring the correct topology is loaded and devices are managed properly.
- Introduced `test_pluggable_ecoc_flow.py` to cover various scenarios for pluggable creation, configuration, and error handling.
- Included logging for better traceability during test execution.
- Ensured cleanup of test environment to maintain isolation between test runs.
parent 4ac3aed2
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
{
    "devices": [
        {
            "device_id": {"device_uuid": {"uuid": "r1"}}, "device_type": "packet-router",
            "device_drivers": ["DEVICEDRIVER_GNMI_OPENCONFIG"],
            "device_config": {"config_rules": [
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "172.20.20.101"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "6030"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": {
                    "username": "admin", "password": "admin", "use_tls": false
                }}}
            ]}
        },
        {
            "device_id": {"device_uuid": {"uuid": "r2"}}, "device_type": "packet-router",
            "device_drivers": ["DEVICEDRIVER_GNMI_OPENCONFIG"],
            "device_config": {"config_rules": [
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "172.20.20.102"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "6030"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": {
                    "username": "admin", "password": "admin", "use_tls": false
                }}}
            ]}
        }
    ],
    "links": [
        {
            "link_id": {"link_uuid": {"uuid": "r1/Ethernet2==r2/Ethernet1"}},
            "link_endpoint_ids": [
                {"device_id": {"device_uuid": {"uuid": "r1"}}, "endpoint_uuid": {"uuid": "Ethernet2"}},
                {"device_id": {"device_uuid": {"uuid": "r2"}}, "endpoint_uuid": {"uuid": "Ethernet1"}}
            ]
        },
        {
            "link_id": {"link_uuid": {"uuid": "r2/Ethernet1==r1/Ethernet2"}},
            "link_endpoint_ids": [
                {"device_id": {"device_uuid": {"uuid": "r2"}}, "endpoint_uuid": {"uuid": "Ethernet1"}},
                {"device_id": {"device_uuid": {"uuid": "r1"}}, "endpoint_uuid": {"uuid": "Ethernet2"}}
            ]
        }
    ]
}
+138 −0
Original line number Diff line number Diff line
# Copyright 2022-2026 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Static HTTP JSON payloads for the NBI→Pluggable→SBI E2E happy-path test.

Mirrors the pattern from `src/nbi/tests/messages/dscm_messages.py`:
all fields are constant; only the top-level format (HUB vs LEAF) differs.
"""

from typing import Any, Dict, Iterable, Set


_HUB_GROUP_SUBCARRIERS = {
    1: (1, 2, 3, 4),
    2: (5, 6, 7, 8),
    3: (9, 10, 11, 12),
    4: (13, 14, 15, 16),
}

_LEAF_CHANNELS = {
    5: {
        "name": "channel-5",
        "frequency": "194006250",
        "target_output_power": "-99.0",
    },
    7: {
        "name": "channel-7",
        "frequency": "194018750",
        "target_output_power": "-99.0",
    },
}


def _subcarriers(subcarrier_ids: Iterable[int], active: bool) -> list:
    return [
        {"subcarrier-id": subcarrier_id, "active": active}
        for subcarrier_id in subcarrier_ids
    ]


def _hub_payload(active_group_ids: Set[int]) -> Dict[str, Any]:
    invalid_group_ids = active_group_ids - set(_HUB_GROUP_SUBCARRIERS)
    if invalid_group_ids:
        raise ValueError(f"Unsupported HUB DSC group ids: {sorted(invalid_group_ids)}")

    return {
        "name": "channel-5",
        "frequency": "194000000",
        "target_output_power": "0.0",
        "operation": "merge",
        "digital_subcarriers_groups": [
            {
                "group_id": group_id,
                "digital-subcarrier-id": _subcarriers(
                    subcarrier_ids, group_id in active_group_ids
                ),
            }
            for group_id, subcarrier_ids in _HUB_GROUP_SUBCARRIERS.items()
        ],
    }


def _leaf_payload(active_channels: Set[int]) -> Dict[str, Any]:
    invalid_channels = active_channels - set(_LEAF_CHANNELS)
    if invalid_channels:
        raise ValueError(f"Unsupported LEAF channels: {sorted(invalid_channels)}")

    return {
        "operation": "merge",
        "channels": [
            {
                **channel_data,
                "digital_subcarriers_groups": [
                    {
                        "group_id": 1,
                        "digital-subcarrier-id": _subcarriers(
                            (1, 2, 3, 4), channel_id in active_channels
                        ),
                    }
                ],
            }
            for channel_id, channel_data in _LEAF_CHANNELS.items()
        ],
    }


def get_hub_payload() -> Dict[str, Any]:
    """Static HUB-format payload for NBI POST.

    4 digital-subcarrier groups with 4 subcarriers each (16 total).
    Groups 1 and 2 are active; groups 3 and 4 are inactive.
    The NBI POST handler routes this to CreatePluggable gRPC, which triggers
    _push_config_to_device → NETCONF push to the hub device.
    """
    return _hub_payload({1, 2})


def get_hub_payload_for_active_group(active_group_id: int) -> Dict[str, Any]:
    """HUB-format payload with one active DSC group and all other groups false."""
    return _hub_payload({active_group_id})


def get_hub_payload_all_false() -> Dict[str, Any]:
    """HUB-format payload with all DSC groups and subcarriers inactive."""
    return _hub_payload(set())


def get_leaf_payload() -> Dict[str, Any]:
    """Static LEAF-format payload for NBI POST.

    2 channels (channel-5, channel-7), each with 1 DSC group of 4 subcarriers.
    All subcarriers active.
    The NBI POST handler routes this to CreatePluggable gRPC, which triggers
    _push_config_to_device → NETCONF push to the leaf device.
    """
    return _leaf_payload({5, 7})


def get_leaf_payload_for_active_channel(active_channel: int) -> Dict[str, Any]:
    """LEAF-format payload with one active channel and all other channels false."""
    return _leaf_payload({active_channel})


def get_leaf_payload_all_false() -> Dict[str, Any]:
    """LEAF-format payload with all channels, DSC groups, and subcarriers inactive."""
    return _leaf_payload(set())
+30 −0
Original line number Diff line number Diff line
{
    "devices": [
        {
            "device_id": {"device_uuid": {"uuid": "r1"}}, "device_type": "packet-router",
            "device_drivers": ["DEVICEDRIVER_OPENCONFIG"],
            "device_config": {"config_rules": [
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "10.30.7.8"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "830"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": {
                    "username": "admin", "password": "admin", "use_tls": false,
                    "hostkey_verify": false, "look_for_keys": false, "allow_agent": false
                }}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/populate_resource_keys", "resource_value": "__inventory__, __interfaces__, __network_instances__"}}
            ]}
        },
        {
            "device_id": {"device_uuid": {"uuid": "r2"}}, "device_type": "packet-router",
            "device_drivers": ["DEVICEDRIVER_OPENCONFIG"],
            "device_config": {"config_rules": [
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "10.30.7.7"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "830"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": {
                    "username": "admin", "password": "admin", "use_tls": false,
                    "hostkey_verify": false, "look_for_keys": false, "allow_agent": false
                }}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/populate_resource_keys", "resource_value": "__inventory__, __interfaces__, __network_instances__"}}
            ]}
        }
    ]
}
+46 −0
Original line number Diff line number Diff line
{
    "devices": [
        {
            "device_id": {"device_uuid": {"uuid": "r1"}}, "device_type": "packet-router",
            "device_drivers": ["DEVICEDRIVER_OPENCONFIG"],
            "device_config": {"config_rules": [
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "10.30.7.8"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "830"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": {
                    "username": "admin", "password": "admin", "use_tls": false,
                    "hostkey_verify": false, "look_for_keys": false, "allow_agent": false
                }}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/populate_resource_keys", "resource_value": "__inventory__, __interfaces__, __network_instances__"}}
            ]}
        },
        {
            "device_id": {"device_uuid": {"uuid": "r2"}}, "device_type": "packet-router",
            "device_drivers": ["DEVICEDRIVER_OPENCONFIG"],
            "device_config": {"config_rules": [
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "10.30.7.7"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "830"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": {
                    "username": "admin", "password": "admin", "use_tls": false,
                    "hostkey_verify": false, "look_for_keys": false, "allow_agent": false
                }}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/populate_resource_keys", "resource_value": "__inventory__, __interfaces__, __network_instances__"}}
            ]}
        }
    ],
    "links": [
        {
            "link_id": {"link_uuid": {"uuid": "r1/Ethernet5==r2/Ethernet7"}},
            "link_endpoint_ids": [
                {"device_id": {"device_uuid": {"uuid": "r1"}}, "endpoint_uuid": {"uuid": "Ethernet5"}},
                {"device_id": {"device_uuid": {"uuid": "r2"}}, "endpoint_uuid": {"uuid": "Ethernet7"}}
            ]
        },
        {
            "link_id": {"link_uuid": {"uuid": "r2/Ethernet7==r1/Ethernet5"}},
            "link_endpoint_ids": [
                {"device_id": {"device_uuid": {"uuid": "r2"}}, "endpoint_uuid": {"uuid": "Ethernet7"}},
                {"device_id": {"device_uuid": {"uuid": "r1"}}, "endpoint_uuid": {"uuid": "Ethernet5"}}
            ]
        }
    ]
}
+38 −0
Original line number Diff line number Diff line
{
    "contexts": [
        {"context_id": {"context_uuid": {"uuid": "admin"}}}
    ],
    "topologies": [
        {"topology_id": {"context_id": {"context_uuid": {"uuid": "admin"}}, "topology_uuid": {"uuid": "admin"}}}
    ],
    "devices": [
        {
            "device_id": {"device_uuid": {"uuid": "r1"}}, "device_type": "packet-router",
            "device_drivers": ["DEVICEDRIVER_OPENCONFIG"],
            "device_config": {"config_rules": [
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "10.30.7.8"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "830"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": {
                    "username": "admin", "password": "admin", "use_tls": false,
                    "hostkey_verify": false, "look_for_keys": false, "allow_agent": false,
                    "force_running": true
                }}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/populate_resource_keys", "resource_value": "__inventory__, __interfaces__, __network_instances__,__endpoints__"}}
            ]}
        },
        {
            "device_id": {"device_uuid": {"uuid": "r2"}}, "device_type": "packet-router",
            "device_drivers": ["DEVICEDRIVER_OPENCONFIG"],
            "device_config": {"config_rules": [
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/address", "resource_value": "10.30.7.7"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/port", "resource_value": "830"}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/settings", "resource_value": {
                    "username": "admin", "password": "admin", "use_tls": false,
                    "hostkey_verify": false, "look_for_keys": false, "allow_agent": false,
                    "force_running": true
                }}},
                {"action": "CONFIGACTION_SET", "custom": {"resource_key": "_connect/populate_resource_keys", "resource_value": "__inventory__, __interfaces__, __network_instances__,__endpoints__"}}
            ]}
        }
    ]
}
Loading