Commit 5f33e787 authored by Cesar Cajas's avatar Cesar Cajas
Browse files

feature/add-e2e-tests-gsma-edgecloud: add tests e2e edgecloud gsma methods

parent 51835308
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -64,7 +64,7 @@ class OSType(BaseModel):
class Flavour(BaseModel):
    flavourId: str
    cpuArchType: Literal["ISA_X86", "ISA_X86_64", "ISA_ARM_64"]
    supportedOSTypes: List[OSType] = Field(..., min_items=1)
    supportedOSTypes: List[OSType] = Field(..., min_length=1)
    numCPU: int
    memorySize: int
    storageSize: int
@@ -105,9 +105,9 @@ class ZoneServiceLevelObjsInfo(BaseModel):

class ZoneRegisteredData(BaseModel):
    zoneId: str
    reservedComputeResources: List[ComputeResourceInfo] = Field(..., min_items=1)
    computeResourceQuotaLimits: List[ComputeResourceInfo] = Field(..., min_items=1)
    flavoursSupported: List[Flavour] = Field(..., min_items=1)
    reservedComputeResources: List[ComputeResourceInfo] = Field(..., min_length=1)
    computeResourceQuotaLimits: List[ComputeResourceInfo] = Field(..., min_length=1)
    flavoursSupported: List[Flavour] = Field(..., min_length=1)
    networkResources: Optional[NetworkResources] = None
    zoneServiceLevelObjsInfo: Optional[ZoneServiceLevelObjsInfo] = None

+116 −48
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ CONFIG = {
                    "componentName": "my-component",
                    "networkInterfaces": [
                        {
                            "interfaceId": "c3e1e6d4-1a5c-4a3b-9e4a-5f3d7b6c8e01",
                            "interfaceId": "eth0",
                            "protocol": "TCP",
                            "port": 8080,
                            "visibilityType": "VISIBILITY_EXTERNAL",
@@ -65,14 +65,91 @@ CONFIG = {
                }
            ],
        },
        # GSMA
        "APP_ONBOARD_MANIFEST_GSMA": {
            "appId": "demo-app-id",
            "appProviderId": "Y89TSlxMPDKlXZz7rN6vU2y",
            "appDeploymentZones": [
                "Dmgoc-y2zv97lar0UKqQd53aS6MCTTdoGMY193yvRBYgI07zOAIktN2b9QB2THbl5Gqvbj5Zp92vmNeg7v4M"
            ],
            "appMetaData": {
                "appName": "pj1iEkprop",
                "version": "string",
                "appDescription": "stringstringstri",
                "mobilitySupport": False,
                "accessToken": "MfxADOjxDgBhMrqmBeG8XdQFLp2XviG3cZ_LM7uQKc9b",
                "category": "IOT",
            },
            "appQoSProfile": {
                "latencyConstraints": "NONE",
                "bandwidthRequired": 1,
                "multiUserClients": "APP_TYPE_SINGLE_USER",
                "noOfUsersPerAppInst": 1,
                "appProvisioning": True,
            },
            "appComponentSpecs": [
                {
                    "serviceNameNB": "k8yyElSyJN4ctbNVqwodEQNUoGb2EzOEt4vQBjGnPii_5",
                    "serviceNameEW": "iDm08OZN",
                    "componentName": "HIEWqstajCmZJQmSFUj0kNHZ0xYvKWq720BKt8wjA41p",
                    "artefactId": "9c9143f0-f44f-49df-939e-1e8b891ba8f5",
                }
            ],
            "appStatusCallbackLink": "string",
            "edgeAppFQDN": "string",
        },
        "APP_DEPLOY_PAYLOAD_GSMA": {
            "appId": "demo-app-id",
            "appVersion": "string",
            "appProviderId": "Y89TSlxMPDKlXZz7rN6vU2y",
            "zoneInfo": {
                "zoneId": "f0662bfe-1d90-5f59-a759-c755b3b69b93",
                "flavourId": "67f3a0b0e3184a85952e174d",
                "resourceConsumption": "RESERVED_RES_AVOID",
                "resPool": "ySIT0LuZ6ApHs0wlyGZve",
            },
            "appInstCallbackLink": "string",
        },
        "PATCH_ONBOARDED_APP_GSMA": {
            "appUpdQoSProfile": {
                "latencyConstraints": "NONE",
                "bandwidthRequired": 1,
                "mobilitySupport": False,
                "multiUserClients": "APP_TYPE_SINGLE_USER",
                "noOfUsersPerAppInst": 1,
                "appProvisioning": True,
            },
            "appComponentSpecs": [
                {
                    "serviceNameNB": "7CI_9d4lAK90vU4ASUkKxYdQjsv3y3IuwucISSQ6lG5_EMqeyVUHPIhwa5",
                    "serviceNameEW": "tPihoUFj30938Bu9blpsHkvsec1iA7gqZZRMpsx6o7aSSj5",
                    "componentName": "YCAhqPadfld8y68wJfTc6QNGguI41z",
                    "artefactId": "9c9143f0-f44f-49df-939e-1e8b891ba8f5",
                },
                {
                    "serviceNameNB": "JCjR0Lc3J0sm2PcItECdbHXtpCLQCfq3B",
                    "serviceNameEW": "N8KBAdqT8L_sWOxeFZs3XYn6oykTTFHLiPKOS7kdYbw",
                    "componentName": "9aCfCEDe2Dv0Peg",
                    "artefactId": "9c9143f0-f44f-49df-939e-1e8b891ba8f5",
                },
                {
                    "serviceNameNB": "RIfXlfU9cDeLnrOBYzz9LJGdAjwPRp_3Mjp0Wq_RDlQiAPyXm",
                    "serviceNameEW": "31y8sCwvvyNCXfwtLhwJw6hoblG7ZcFzEjyFdAnzq7M8cxiOtDik0",
                    "componentName": "3kTa4zKEX",
                    "artefactId": "9c9143f0-f44f-49df-939e-1e8b891ba8f5",
                },
            ],
        },
    },
    "aeros": {
        # Basic identifiers
        "ZONE_ID": "<UUID>",
        "APP_ID": "<UUID>",
        # CAMARA onboard_app payload
        "ZONE_ID": "urn:ngsi-ld:Domain:NCSRD",
        "ARTEFACT_ID": "aeros-app-2",
        "ARTEFACT_NAME": "aeroschart",
        "REPO_NAME": "github-aeros",
        "REPO_TYPE": "PUBLICREPO",
        "REPO_URL": "https://aeros.github.io/helm/",
        "APP_ONBOARD_MANIFEST": {
            "appId": "<UUID>",
            "appId": "aeros-app-2",
            "name": "aeros-SDK-app",
            "version": "1.0.0",
            "appProvider": "aeros",
@@ -102,7 +179,7 @@ CONFIG = {
                    "componentName": "aeros-component",
                    "networkInterfaces": [
                        {
                            "interfaceId": "<UUID>",
                            "interfaceId": "eth0",
                            "protocol": "TCP",
                            "port": 9090,
                            "visibilityType": "VISIBILITY_INTERNAL",
@@ -111,13 +188,14 @@ CONFIG = {
                }
            ],
        },
        "APP_ID": "aeros-app-2",
        # CAMARA deploy_app payload
        "APP_DEPLOY_PAYLOAD": {
            "appId": "<UUID>",
            "appId": "aeros-app-2",
            "appZones": [
                {
                    "EdgeCloudZone": {
                        "edgeCloudZoneId": "<UUID>",
                        "edgeCloudZoneId": "urn:ngsi-ld:Domain:NCSRD",
                        "edgeCloudZoneName": "aeros-zone-1",
                        "edgeCloudZoneStatus": "active",
                        "edgeCloudProvider": "NCSRD",
@@ -128,34 +206,39 @@ CONFIG = {
        },
    },
    "kubernetes": {
        # Basic identifiers
        "ZONE_ID": "999b7746-d2e2-4bb4-96e6-f1e895adef0c",
        "K8S_ONBOARDED_APP_NAME": "nginx",
        "K8S_APP_ID": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "APP_ID": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "ZONE_ID": "999b7746-d2e2-4bb4-96e6-f1e895adef0c",
        # CAMARA onboard_app payload
        "ZONE_ID": "b2a1b33d-f382-47de-b555-2d32155eb74c",
        # CAMARA deploy_app payload
        "APP_DEPLOY_PAYLOAD": {
            "appId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            "appZones": [
                {
                    "EdgeCloudZone": {
                        "edgeCloudZoneId": "b2a1b33d-f382-47de-b555-2d32155eb74c",
                        "edgeCloudZoneName": "k8s-zone-1",
                        "edgeCloudZoneStatus": "active",
                        "edgeCloudProvider": "kubernetes",
                        "edgeCloudRegion": "Local",
                    }
                }
            ],
        },
        # Legacy K8S_DEPLOY_PAYLOAD for backward compatibility (if needed)
        "K8S_DEPLOY_PAYLOAD": {
            "appId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            "name": "nginx-test",
            "edgeCloudZoneId": "zorro-solutions",
            "kubernetesClusterRef": "",
        },
        "APP_ONBOARD_MANIFEST": {
            "appId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            "name": "nginx_test",
            "name": "nginx",
            "version": "1",
            "packageType": "QCOW2",
            "appProvider": "jJsxUU403g5PUhoRtYfOBaaIRZGVzXDZgMBqzMYq5xLcdZoWGYIYqmVy0",
            "appProvider": "Nginx Inc.",
            "appRepo": {"imagePath": "nginx", "type": "PRIVATEREPO"},
            "requiredResources": {
                "infraKind": "kubernetes",
                "applicationResources": {
                    "cpuPool": {
                        "numCPU": 2,
                        "memory": 2048,
                        "topology": {
                            "minNumberOfNodes": 2,
                            "minNodeCpu": 1,
                            "minNodeMemory": 1024,
                        },
                    }
                },
                "isStandalone": False,
                "version": "1.29",
            },
            "componentSpec": [
                {
                    "componentName": "nginx",
@@ -163,33 +246,18 @@ CONFIG = {
                        {
                            "protocol": "TCP",
                            "port": 80,
                            "interfaceId": "8f4b02a9-73ba-4fde-9d93-3b1a6e7c5d9f",
                            "interfaceId": "Uj6qThvzkegxa3L4b88",
                            "visibilityType": "VISIBILITY_EXTERNAL",
                        },
                        {
                            "protocol": "TCP",
                            "port": 443,
                            "interfaceId": "e5c9a2b1-3d7f-4b8e-a6c4-1f9d8b7a6c0e",
                            "interfaceId": "Uj6qThvzkegxa3L4b88",
                            "visibilityType": "VISIBILITY_EXTERNAL",
                        },
                    ],
                }
            ],
        },
        # CAMARA deploy_app payload
        "APP_DEPLOY_PAYLOAD": {
            "appId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            "appZones": [
                {
                    "EdgeCloudZone": {
                        "edgeCloudZoneId": "999b7746-d2e2-4bb4-96e6-f1e895adef0c",
                        "edgeCloudZoneName": "zorro-solutions",
                        "edgeCloudZoneStatus": "active",
                        "edgeCloudProvider": "ICOM",
                        "edgeCloudRegion": "Europe-Southeast",
                    }
                }
            ],
        },
    },
}
+298 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
# Contributors:
#   - Adrián Pino Martínez (adrian.pino@i2cat.net)
#   - Sergio Giménez (sergio.gimenez@i2cat.net)
#   - César Cajas (cesar.cajas@i2cat.net)
##
"""
EdgeCloud adapters Integration Tests
@@ -31,6 +32,7 @@ from sunrise6g_opensdk.edgecloud.adapters.errors import EdgeCloudPlatformError
from sunrise6g_opensdk.edgecloud.adapters.i2edge.client import (
    EdgeApplicationManager as I2EdgeClient,
)
from sunrise6g_opensdk.edgecloud.core import gsma_schemas
from sunrise6g_opensdk.edgecloud.core import schemas as camara_schemas
from tests.edgecloud.test_cases import test_cases
from tests.edgecloud.test_config import CONFIG
@@ -338,3 +340,299 @@ def test_delete_artefact(edgecloud_client):
            edgecloud_client.delete_artefact(artefact_id=config["ARTEFACT_ID"])
        except EdgeCloudPlatformError as e:
            pytest.fail(f"Artefact deletion failed: {e}")


# ====================================================================
# GSMA EDGE COMPUTING API (EWBI OPG) - FEDERATION
# ====================================================================


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_get_edge_cloud_zones_list_gsma(edgecloud_client):
    config = CONFIG[edgecloud_client.client_name]
    try:
        response = edgecloud_client.get_edge_cloud_zones_list_gsma()
        assert isinstance(response, Response)
        assert response.status_code == 200
        zones = response.json()
        assert isinstance(zones, list)

        # GSMA schema validation for each zone
        validated_zones = []
        for zone in zones:
            validated_zone = gsma_schemas.ZoneDetails(**zone)
            validated_zones.append(validated_zone)

        # Logical validation: verify our expected zone is in the list
        expected_zone_id = config["ZONE_ID"]
        found_expected_zone = any(str(zone.zoneId) == expected_zone_id for zone in validated_zones)
        assert found_expected_zone, f"Expected zone {expected_zone_id} not found in returned zones"

    except EdgeCloudPlatformError as e:
        pytest.fail(f"Failed to retrieve zones: {e}")
    except Exception as e:
        pytest.fail(f"Unexpected error during zone validation: {e}")


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_get_edge_cloud_zones_gsma(edgecloud_client):
    config = CONFIG[edgecloud_client.client_name]
    try:
        response = edgecloud_client.get_edge_cloud_zones_gsma()
        assert isinstance(response, Response)
        assert response.status_code == 200
        zones = response.json()
        assert isinstance(zones, list)

        # GSMA schema validation for each zone
        validated_zones = []
        for zone in zones:
            validated_zone = gsma_schemas.ZoneRegisteredData(**zone)
            validated_zones.append(validated_zone)

        # Logical validation: verify our expected zone is in the list
        expected_zone_id = config["ZONE_ID"]
        found_expected_zone = any(str(zone.zoneId) == expected_zone_id for zone in validated_zones)
        assert found_expected_zone, f"Expected zone {expected_zone_id} not found in returned zones"

    except EdgeCloudPlatformError as e:
        pytest.fail(f"Failed to retrieve zones details: {e}")
    except Exception as e:
        pytest.fail(f"Unexpected error during zone validation: {e}")


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_get_edge_cloud_zone_details_gsma(edgecloud_client):
    config = CONFIG[edgecloud_client.client_name]
    expected_zone_id = config["ZONE_ID"]
    try:
        response = edgecloud_client.get_edge_cloud_zone_details_gsma(expected_zone_id)
        assert isinstance(response, Response)
        assert response.status_code == 200
        zone = response.json()
        assert isinstance(zone, dict)

        # GSMA schema validation for zone
        validated_zone = gsma_schemas.ZoneRegisteredData(**zone)

        # Logical validation: verify our expected zone is in the dict
        assert (
            str(validated_zone.zoneId) == expected_zone_id
        ), f"Expected zoneId {expected_zone_id}, got {validated_zone.zoneId}"

    except EdgeCloudPlatformError as e:
        pytest.fail(f"Failed to retrieve zones details: {e}")
    except Exception as e:
        pytest.fail(f"Unexpected error during zone validation: {e}")


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_artefact_methods_gsma(edgecloud_client):
    config = CONFIG[edgecloud_client.client_name]
    if isinstance(edgecloud_client, I2EdgeClient):
        try:
            response = edgecloud_client.create_artefact(
                artefact_id=config["ARTEFACT_ID"],
                artefact_name=config["ARTEFACT_NAME"],
                repo_name=config["REPO_NAME"],
                repo_type=config["REPO_TYPE"],
                repo_url=config["REPO_URL"],
                password=None,
                token=None,
                user_name=None,
            )
            assert response.status_code == 201
        except EdgeCloudPlatformError as e:
            pytest.fail(f"Artefact creation failed: {e}")


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_get_artefact_gsma(edgecloud_client):
    config = CONFIG[edgecloud_client.client_name]
    expected_artefact_id = config["ARTEFACT_ID"]
    try:
        response = edgecloud_client.get_artefact_gsma(expected_artefact_id)
        assert isinstance(response, Response)
        assert response.status_code == 200
        artefact = response.json()
        assert isinstance(artefact, dict)

        # GSMA schema validation for artefact
        validated_artefact = gsma_schemas.Artefact(**artefact)

        # Logical validation: verify our expected artefact_id is in the dict
        assert (
            str(validated_artefact.artefactId) == expected_artefact_id
        ), f"Expected artefactId {expected_artefact_id}, got {validated_artefact.artefactId}"

    except EdgeCloudPlatformError as e:
        pytest.fail(f"Failed to retrieve artefact: {e}")
    except Exception as e:
        pytest.fail(f"Unexpected error during artefact validation: {e}")


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_onboard_app_gsma(edgecloud_client):
    config = CONFIG[edgecloud_client.client_name]
    try:
        response = edgecloud_client.onboard_app_gsma(config["APP_ONBOARD_MANIFEST_GSMA"])
        assert isinstance(response, Response)
        assert response.status_code == 200

    except EdgeCloudPlatformError as e:
        pytest.fail(f"App onboarding failed: {e}")
    except Exception as e:
        pytest.fail(f"Unexpected error during app onboarding: {e}")


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_get_onboarded_app_gsma(edgecloud_client):
    config = CONFIG[edgecloud_client.client_name]
    app_id = config["APP_ONBOARD_MANIFEST_GSMA"]["appId"]
    try:
        response = edgecloud_client.get_onboarded_app_gsma(app_id)
        assert isinstance(response, Response)
        assert response.status_code == 200

        onboarded_app = response.json()
        assert isinstance(onboarded_app, dict)

        # GSMA schema validation for onboarded_app
        validated_schema = gsma_schemas.ApplicationModel(**onboarded_app)

        # Logical validation: verify our expected app_id is in the dict
        assert (
            str(validated_schema.appId) == app_id
        ), f"Expected appId {app_id}, got {validated_schema.appId}"
    except EdgeCloudPlatformError as e:
        pytest.fail(f"Failed to retrieve app: {e}")
    except Exception as e:
        pytest.fail(f"Unexpected error validating app: {e}")


@pytest.fixture(scope="module")
def app_instance_id_gsma(edgecloud_client):
    config = CONFIG[edgecloud_client.client_name]
    try:
        # Use standardized GSMA structure for all adapters
        deploy_payload = config["APP_DEPLOY_PAYLOAD_GSMA"]

        response = edgecloud_client.deploy_app_gsma(deploy_payload)

        assert isinstance(response, Response)
        assert (
            response.status_code == 202
        ), f"Expected 202, got {response.status_code}: {response.text}"

        response_data = response.json()
        instance_info = gsma_schemas.AppInstance(**response_data)

        # Extract appInstIdentifier from the validated object
        app_instance_id_gsma = instance_info.appInstIdentifier

        assert app_instance_id_gsma is not None
        yield app_instance_id_gsma
    finally:
        pass


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_deploy_app_gsma(app_instance_id_gsma):
    assert app_instance_id_gsma is not None


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_timer_wait_10_seconds(edgecloud_client):
    time.sleep(10)


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_get_all_deployed_apps_gsma(edgecloud_client):
    """Test retrieving all deployed application instances"""
    try:
        response = edgecloud_client.get_all_deployed_apps_gsma()
        assert isinstance(response, Response)
        assert response.status_code == 200

        instances_data = response.json()
        assert isinstance(instances_data, list)

        validated_instances = []
        for instance_data in instances_data:
            validated_instance = gsma_schemas.ZoneIdentifier(**instance_data)
            validated_instances.append(validated_instance)

    except EdgeCloudPlatformError as e:
        pytest.fail(f"Failed to get all deployed apps: {e}")


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_get_deployed_app_gsma(edgecloud_client, app_instance_id_gsma):
    """Test retrieving a specific deployed application instance"""
    config = CONFIG[edgecloud_client.client_name]
    app_id = config["APP_DEPLOY_PAYLOAD_GSMA"]["appId"]
    zone_id = config["APP_DEPLOY_PAYLOAD_GSMA"]["zoneInfo"]["zoneId"]
    try:
        response = edgecloud_client.get_deployed_app_gsma(app_id, app_instance_id_gsma, zone_id)
        assert isinstance(response, Response)
        assert response.status_code == 200

        instance_data = response.json()
        assert isinstance(instance_data, dict)
        assert "appInstanceState" in instance_data

        gsma_schemas.AppInstanceStatus(**instance_data)

    except EdgeCloudPlatformError as e:
        pytest.fail(f"Failed to get deployed app: {e}")


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_undeploy_app_gsma(edgecloud_client, app_instance_id_gsma):
    config = CONFIG[edgecloud_client.client_name]
    app_id = config["APP_DEPLOY_PAYLOAD_GSMA"]["appId"]
    zone_id = config["APP_DEPLOY_PAYLOAD_GSMA"]["zoneInfo"]["zoneId"]
    try:
        response = edgecloud_client.undeploy_app_gsma(app_id, app_instance_id_gsma, zone_id)
        assert isinstance(response, Response)
        assert response.status_code == 200
    except EdgeCloudPlatformError as e:
        pytest.fail(f"App undeployment failed: {e}")


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_patch_onboarded_app_gsma(edgecloud_client):
    config = CONFIG[edgecloud_client.client_name]
    app_id = config["APP_ONBOARD_MANIFEST_GSMA"]["appId"]
    try:
        payload = config["PATCH_ONBOARDED_APP_GSMA"]
        response = edgecloud_client.patch_onboarded_app_gsma(app_id, payload)
        assert isinstance(response, Response)
        assert response.status_code == 200
    except EdgeCloudPlatformError as e:
        pytest.fail(f"Failed to patch onboarded app: {e}")


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_delete_onboarded_app_gsma(edgecloud_client):
    config = CONFIG[edgecloud_client.client_name]
    try:
        app_id = config["APP_ONBOARD_MANIFEST_GSMA"]["appId"]
        response = edgecloud_client.delete_onboarded_app_gsma(app_id)
        assert isinstance(response, Response)
        assert response.status_code == 200
    except EdgeCloudPlatformError as e:
        pytest.fail(f"App onboarding deletion failed: {e}")


@pytest.mark.parametrize("edgecloud_client", test_cases, ids=id_func, indirect=True)
def test_delete_artefact_gsma(edgecloud_client):
    config = CONFIG[edgecloud_client.client_name]

    if isinstance(edgecloud_client, I2EdgeClient):
        try:
            response = edgecloud_client.delete_artefact_gsma(config["ARTEFACT_ID"])
            assert isinstance(response, Response)
            assert response.status_code == 200
        except EdgeCloudPlatformError as e:
            pytest.fail(f"Artefact deletion failed: {e}")