From 3378c7f2d91b7c3bbdff3414cce1aea4a7ba166e Mon Sep 17 00:00:00 2001 From: Maciej Wilk Date: Wed, 22 Jul 2026 09:52:33 +0200 Subject: [PATCH 01/10] Fix test_interface_settings_update removing outdated cli arguments --- tests/integration/linodes/test_linode_interfaces.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/integration/linodes/test_linode_interfaces.py b/tests/integration/linodes/test_linode_interfaces.py index f36ed1a50..ca861750a 100644 --- a/tests/integration/linodes/test_linode_interfaces.py +++ b/tests/integration/linodes/test_linode_interfaces.py @@ -146,10 +146,6 @@ def test_interface_settings_update( interface_id, "--default_route.ipv6_interface_id", interface_id, - "--default_route.ipv4_eligible_interface_ids", - interface_id, - "--default_route.ipv6_eligible_interface_ids", - interface_id, "--json", ] ) @@ -161,8 +157,6 @@ def test_interface_settings_update( default_route = settings["default_route"] assert default_route["ipv4_interface_id"] == int(interface_id) assert default_route["ipv6_interface_id"] == int(interface_id) - assert default_route["ipv4_eligible_interface_ids"] == [int(interface_id)] - assert default_route["ipv6_eligible_interface_ids"] == [int(interface_id)] def test_interface_update(linode_interface_public, monkeypatch: MonkeyPatch): From fe809a4b0c5b72188243eeb06677539dfaf2c283 Mon Sep 17 00:00:00 2001 From: Maciej Wilk Date: Wed, 22 Jul 2026 10:11:48 +0200 Subject: [PATCH 02/10] Fix test_channels_list aligning headers to TechDoc --- tests/integration/monitor/test_alerts.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/integration/monitor/test_alerts.py b/tests/integration/monitor/test_alerts.py index 15ff6449f..6d3328d3c 100644 --- a/tests/integration/monitor/test_alerts.py +++ b/tests/integration/monitor/test_alerts.py @@ -38,12 +38,18 @@ def test_channels_list(): ) lines = res.splitlines() headers = [ + "alerts.alert_count", + "alerts.type", + "alerts.url", "channel_type", - "content.email.email_addresses", + "created", + "created_by", + "details", "id", "label", "type", "updated", + "updated_by", ] assert_headers_in_lines(headers, lines) From a69c4ed7f93d344c720c20227918597b96571d11 Mon Sep 17 00:00:00 2001 From: Maciej Wilk Date: Wed, 22 Jul 2026 12:58:06 +0200 Subject: [PATCH 03/10] Add skip for invalid_label tests due to ARB-8019 defect --- tests/integration/vpc/test_vpc.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/integration/vpc/test_vpc.py b/tests/integration/vpc/test_vpc.py index 6616aa9f6..6da63355c 100644 --- a/tests/integration/vpc/test_vpc.py +++ b/tests/integration/vpc/test_vpc.py @@ -137,6 +137,7 @@ def test_update_subnet(test_vpc_w_subnet): assert new_label == updated_label +@pytest.mark.skip(reason="Defect: ARB-8019") def test_fails_to_create_vpc_invalid_label(): invalid_label = "invalid_label" region = get_random_region_with_caps(required_capabilities=["VPCs"]) @@ -165,6 +166,7 @@ def test_fails_to_create_vpc_duplicate_label(test_vpc_wo_subnet): assert "Label must be unique among your VPCs" in res +@pytest.mark.skip(reason="Defect: ARB-8019") def test_fails_to_update_vpc_invalid_label(test_vpc_wo_subnet): vpc_id = test_vpc_wo_subnet invalid_label = "invalid_label" @@ -178,6 +180,7 @@ def test_fails_to_update_vpc_invalid_label(test_vpc_wo_subnet): assert "Must only use ASCII letters, numbers, and dashes" in res +@pytest.mark.skip(reason="Defect: ARB-8019") def test_fails_to_create_vpc_subnet_w_invalid_label(test_vpc_wo_subnet): vpc_id = test_vpc_wo_subnet invalid_label = "invalid_label" @@ -199,6 +202,7 @@ def test_fails_to_create_vpc_subnet_w_invalid_label(test_vpc_wo_subnet): assert "Must only use ASCII letters, numbers, and dashes" in res +@pytest.mark.skip(reason="Defect: ARB-8019") def test_fails_to_update_vpc_subnet_w_invalid_label(test_vpc_w_subnet): vpc_id = test_vpc_w_subnet From 5411ed6b1cea888d87e7b7456aeb56eee6121974 Mon Sep 17 00:00:00 2001 From: Maciej Wilk Date: Wed, 22 Jul 2026 13:19:35 +0200 Subject: [PATCH 04/10] Move create_reserved_ip & DEFAULT_REGIONS to general conftest & helpers --- tests/integration/conftest.py | 23 ++++++++++++ tests/integration/helpers.py | 7 ++++ tests/integration/linodes/helpers.py | 7 +--- tests/integration/networking/fixtures.py | 37 +------------------ .../integration/networking/test_networking.py | 2 - 5 files changed, 32 insertions(+), 44 deletions(-) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 2f1e5ed76..30afa9fd7 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -18,6 +18,7 @@ from linodecli import ENV_TOKEN_NAME from tests.integration.helpers import ( + DEFAULT_REGION, check_attribute_value, delete_target_id, exec_test_command, @@ -248,3 +249,25 @@ def pytest_configure(config): config.addinivalue_line( "markers", "smoke: mark test as part of smoke test suite" ) + + +@pytest.fixture +def create_reserved_ip(request): + tags = getattr(request, "param", None) + command = [ + "linode-cli", + "networking", + "reserved-ip-add", + "--region", + DEFAULT_REGION, + "--json", + ] + + if tags: + command += ["--tags", tags] + + result = json.loads(exec_test_command(command))[0] + + yield result + + delete_target_id("networking", result["address"], "reserved-ip-delete") diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 03a0fc30b..a1ba7d6ef 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -1,4 +1,5 @@ import json +import os import random import re import subprocess @@ -14,6 +15,12 @@ FAILED_STATUS_CODE = 256 COMMAND_JSON_OUTPUT = ["--suppress-warnings", "--no-defaults", "--json"] +DEFAULT_REGION = ( + "pl-labkrk-2" + if "devcloud" in os.getenv("LINODE_CLI_API_HOST", "") + else "us-ord" +) + # TypeVars for generic type hints below T = TypeVar("T") diff --git a/tests/integration/linodes/helpers.py b/tests/integration/linodes/helpers.py index 39ff206ad..2714a6219 100644 --- a/tests/integration/linodes/helpers.py +++ b/tests/integration/linodes/helpers.py @@ -1,18 +1,13 @@ import json -import os import time from tests.integration.helpers import ( BASE_CMDS, + DEFAULT_REGION, exec_test_command, ) DEFAULT_RANDOM_PASS = exec_test_command(["openssl", "rand", "-base64", "32"]) -DEFAULT_REGION = ( - "pl-labkrk-2" - if "devcloud" in os.getenv("LINODE_CLI_API_HOST", "") - else "us-ord" -) DEFAULT_TEST_IMAGE = exec_test_command( [ diff --git a/tests/integration/networking/fixtures.py b/tests/integration/networking/fixtures.py index d6948417e..723694adb 100644 --- a/tests/integration/networking/fixtures.py +++ b/tests/integration/networking/fixtures.py @@ -1,39 +1,12 @@ -import json - import pytest -from tests.integration.helpers import ( - BASE_CMDS, - delete_target_id, - exec_test_command, -) +from tests.integration.helpers import delete_target_id from tests.integration.linodes.helpers import ( - DEFAULT_REGION, create_linode, create_linode_and_wait, ) -@pytest.fixture -def create_reserved_ip(request): - tags = getattr(request, "param", None) - command = BASE_CMDS["networking"] + [ - "reserved-ip-add", - "--region", - DEFAULT_REGION, - "--json", - ] - - if tags: - command += ["--tags", tags] - - result = json.loads(exec_test_command(command))[0] - - yield result - - delete_target_id("networking", result["address"], "reserved-ip-delete") - - @pytest.fixture(scope="package") def get_linode_id(linode_cloud_firewall): linode_id = create_linode_and_wait(firewall_id=linode_cloud_firewall) @@ -60,11 +33,3 @@ def get_linode_ids_shared_ipv4(linode_cloud_firewall): for id_num in linode_ids: delete_target_id(target="linodes", id=id_num) - - -def get_command_heads_and_vals(command): - result = exec_test_command(command).splitlines() - headers = [item for item in result[0].split(",")] - values = [item for item in result[1].split(",")] - - return headers, values diff --git a/tests/integration/networking/test_networking.py b/tests/integration/networking/test_networking.py index 23904b956..fff0fa152 100644 --- a/tests/integration/networking/test_networking.py +++ b/tests/integration/networking/test_networking.py @@ -12,8 +12,6 @@ ) from tests.integration.linodes.helpers import DEFAULT_REGION from tests.integration.networking.fixtures import ( # noqa: F401 - create_reserved_ip, - get_command_heads_and_vals, get_linode_id, get_linode_ids_shared_ipv4, ) From 0118458393b23bbc49f71f1ccc345df798ad4e2b Mon Sep 17 00:00:00 2001 From: Maciej Wilk Date: Wed, 22 Jul 2026 13:24:42 +0200 Subject: [PATCH 05/10] Add test for nodebalancer with ipv4 --- tests/integration/linodes/fixtures.py | 2 +- .../integration/networking/test_networking.py | 2 +- tests/integration/nodebalancers/fixtures.py | 26 +++++++++++++++++++ .../nodebalancers/test_node_balancers.py | 19 ++++++++++++++ 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/tests/integration/linodes/fixtures.py b/tests/integration/linodes/fixtures.py index 85ec179ed..683e80b0f 100644 --- a/tests/integration/linodes/fixtures.py +++ b/tests/integration/linodes/fixtures.py @@ -5,6 +5,7 @@ from tests.integration.helpers import ( BASE_CMDS, + DEFAULT_REGION, delete_target_id, exec_test_command, get_random_region_with_caps, @@ -16,7 +17,6 @@ DEFAULT_LABEL, DEFAULT_LINODE_TYPE, DEFAULT_RANDOM_PASS, - DEFAULT_REGION, DEFAULT_TEST_IMAGE, create_linode, create_linode_and_wait, diff --git a/tests/integration/networking/test_networking.py b/tests/integration/networking/test_networking.py index fff0fa152..445d389fa 100644 --- a/tests/integration/networking/test_networking.py +++ b/tests/integration/networking/test_networking.py @@ -7,10 +7,10 @@ from tests.integration.helpers import ( BASE_CMDS, + DEFAULT_REGION, assert_headers_in_lines, exec_test_command, ) -from tests.integration.linodes.helpers import DEFAULT_REGION from tests.integration.networking.fixtures import ( # noqa: F401 get_linode_id, get_linode_ids_shared_ipv4, diff --git a/tests/integration/nodebalancers/fixtures.py b/tests/integration/nodebalancers/fixtures.py index a1a973e66..958b802de 100644 --- a/tests/integration/nodebalancers/fixtures.py +++ b/tests/integration/nodebalancers/fixtures.py @@ -336,3 +336,29 @@ def simple_nodebalancer_with_config(linode_cloud_firewall): yield nodebalancer_id, config_id delete_target_id(target="nodebalancers", id=nodebalancer_id) + + +@pytest.fixture +def nodebalancer_with_reserved_ipv4(create_reserved_ip): + res_ip = create_reserved_ip["address"] + region = create_reserved_ip["region"] + nodebalancer_id = exec_test_command( + BASE_CMDS["nodebalancers"] + + [ + "create", + "--region", + region, + "--ipv4", + res_ip, + "--text", + "--delimiter", + ",", + "--no-headers", + "--format", + "id", + ] + ) + + yield res_ip, nodebalancer_id + + delete_target_id(target="nodebalancers", id=nodebalancer_id) diff --git a/tests/integration/nodebalancers/test_node_balancers.py b/tests/integration/nodebalancers/test_node_balancers.py index 1a0bac919..43f6d064a 100644 --- a/tests/integration/nodebalancers/test_node_balancers.py +++ b/tests/integration/nodebalancers/test_node_balancers.py @@ -5,6 +5,7 @@ from linodecli.exit_codes import ExitCodes from tests.integration.helpers import ( BASE_CMDS, + DEFAULT_REGION, exec_failing_test_command, exec_test_command, ) @@ -12,6 +13,7 @@ linode_to_add, nodebalancer_w_config_and_node, nodebalancer_with_default_conf, + nodebalancer_with_reserved_ipv4, nodebalancer_with_udp_config_and_node, simple_nodebalancer_with_config, ) @@ -68,6 +70,23 @@ def test_display_public_ipv4_for_nodebalancer(nodebalancer_w_config_and_node): assert re.search(r"^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}", result) +def test_display_nodebalancer_with_res_ipv4(nodebalancer_with_reserved_ipv4): + res_ip, nb_id = nodebalancer_with_reserved_ipv4 + result = exec_test_command( + BASE_CMDS["nodebalancers"] + + [ + "view", + nb_id, + "--format", + "ipv4", + "--text", + "--no-headers", + ] + ) + + assert res_ip in result + + def test_fail_to_view_nodebalancer_with_invalid_id(): result = exec_failing_test_command( BASE_CMDS["nodebalancers"] + ["view", "535", "--text", "--no-headers"], From 2302eb1463628b0a09cd7e1b1d5d42e51f1ae427 Mon Sep 17 00:00:00 2001 From: Maciej Wilk Date: Wed, 22 Jul 2026 14:37:37 +0200 Subject: [PATCH 06/10] Add test for linode with ipv4 --- tests/integration/linodes/fixtures.py | 32 +++++++++++++++-- tests/integration/linodes/test_linodes.py | 44 +++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/tests/integration/linodes/fixtures.py b/tests/integration/linodes/fixtures.py index 683e80b0f..265fd5510 100644 --- a/tests/integration/linodes/fixtures.py +++ b/tests/integration/linodes/fixtures.py @@ -487,8 +487,6 @@ def test_linode_instance(linode_cloud_firewall): "--delimiter", ",", "--no-headers", - "--format", - "id", "--no-defaults", "--format", "id", @@ -700,3 +698,33 @@ def linode_with_authorization_key(linode_cloud_firewall): yield result delete_target_id(target="linodes", id=result[0]) + + +@pytest.fixture +def linode_with_reserved_ip(linode_cloud_firewall, create_reserved_ip): + res_ip = create_reserved_ip["address"] + + linode_id = exec_test_command( + BASE_CMDS["linodes"] + + [ + "create", + "--type", + "g6-nanode-1", + "--region", + DEFAULT_REGION, + "--firewall_id", + linode_cloud_firewall, + "--ipv4", + res_ip, + "--text", + "--no-headers", + "--format", + "id", + ] + ) + + wait_until(linode_id=linode_id, timeout=180, status="offline") + + yield res_ip, linode_id + + delete_target_id(target="linodes", id=linode_id) diff --git a/tests/integration/linodes/test_linodes.py b/tests/integration/linodes/test_linodes.py index 9b0d361f3..4f898dc2a 100644 --- a/tests/integration/linodes/test_linodes.py +++ b/tests/integration/linodes/test_linodes.py @@ -18,6 +18,7 @@ linode_min_req, linode_with_authorization_key, linode_with_label, + linode_with_reserved_ip, linode_wo_image, test_linode_instance, ) @@ -319,3 +320,46 @@ def test_create_linode_disk_encryption_disabled(linode_cloud_firewall): assert linode_id in res and "disabled" in res delete_target_id(target="linodes", id=linode_id) + + +def test_display_linode_with_res_ipv4(linode_with_reserved_ip): + res_ip, linode_id = linode_with_reserved_ip + result = exec_test_command( + BASE_CMDS["linodes"] + + [ + "view", + linode_id, + "--text", + "--no-headers", + "--no-defaults" + ] + ) + + assert linode_id in result + assert res_ip in result + + +def test_linode_allocate_res_ipv4(test_linode_instance, create_reserved_ip): + linode_id = test_linode_instance + res_ip = create_reserved_ip["address"] + new_headers = ["reserved", "tags"] + + result = exec_test_command( + BASE_CMDS["linodes"] + + [ + "ip-add", + linode_id, + "--address", + res_ip, + "--type", + "ipv4", + "--public", + "true", + "--text", + "--delimiter", + ",", + ] + ).splitlines() + + assert_headers_in_lines(new_headers, [result[0].split(",")]) + assert res_ip in result[1] From 88e790c8724dd35d8b0faa6845a9241414f5505c Mon Sep 17 00:00:00 2001 From: Maciej Wilk Date: Thu, 23 Jul 2026 13:04:16 +0200 Subject: [PATCH 07/10] Remove obsolete import from test_tags --- tests/integration/tags/test_tags.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/integration/tags/test_tags.py b/tests/integration/tags/test_tags.py index 4022cd746..1e5990e53 100644 --- a/tests/integration/tags/test_tags.py +++ b/tests/integration/tags/test_tags.py @@ -11,9 +11,6 @@ exec_test_command, get_random_text, ) -from tests.integration.networking.fixtures import ( # noqa: F401 - create_reserved_ip, -) @pytest.fixture(scope="session") From dc5fd13d2cba44b0edb3e96bbe3c138e55e4d7c5 Mon Sep 17 00:00:00 2001 From: Maciej Wilk Date: Thu, 23 Jul 2026 15:18:19 +0200 Subject: [PATCH 08/10] Mark Configurable VPC IPv4 tests as skipped --- tests/integration/vpc/test_vpc.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/integration/vpc/test_vpc.py b/tests/integration/vpc/test_vpc.py index 6da63355c..2d2fc4080 100644 --- a/tests/integration/vpc/test_vpc.py +++ b/tests/integration/vpc/test_vpc.py @@ -389,6 +389,7 @@ def test_list_vpc_ipv6s_address(): assert header in lines[0] +@pytest.mark.skip(reason="Skipped because Configurable VPC IPv4 not released by TechDoc yet") def test_get_vpc_default_ranges(): headers = ["default_ipv4_ranges", "forbidden_ipv4_ranges"] @@ -401,6 +402,7 @@ def test_get_vpc_default_ranges(): assert isinstance(result[headers[1]], list) +@pytest.mark.skip(reason="Skipped because Configurable VPC IPv4 not released by TechDoc yet") @pytest.mark.parametrize( "create_vpc_with_ipv4, expected", [ @@ -423,6 +425,7 @@ def test_vpc_with_ipv4(create_vpc_with_ipv4, expected): assert len(result["ipv4"]) == expected +@pytest.mark.skip(reason="Skipped because Configurable VPC IPv4 not released by TechDoc yet") @pytest.mark.parametrize( "create_vpc_with_ipv4, updated", [ @@ -450,6 +453,7 @@ def test_vpc_update_with_ipv4(create_vpc_with_ipv4, updated): assert result["ipv4"][0]["range"] == updated +@pytest.mark.skip(reason="Skipped because Configurable VPC IPv4 not released by TechDoc yet") def test_vpc_with_forbidden_ipv4_fail(): forbidden_ipv4 = exec_test_command( BASE_CMD From 1168d52f83cf4d4af36be63b516d0a9823eccef8 Mon Sep 17 00:00:00 2001 From: Maciej Wilk Date: Thu, 23 Jul 2026 16:16:21 +0200 Subject: [PATCH 09/10] Update MySQL engine version to 8.4 --- tests/integration/database/fixtures.py | 2 +- tests/integration/database/test_database_engine_config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/database/fixtures.py b/tests/integration/database/fixtures.py index 40212682d..c897b7fcd 100644 --- a/tests/integration/database/fixtures.py +++ b/tests/integration/database/fixtures.py @@ -58,7 +58,7 @@ def mysql_cluster(): "--label", mysql_database_label, "--engine", - "mysql/8", + "mysql/8.4", "--text", "--delimiter", ",", diff --git a/tests/integration/database/test_database_engine_config.py b/tests/integration/database/test_database_engine_config.py index 55c7fa8a9..f0611901c 100644 --- a/tests/integration/database/test_database_engine_config.py +++ b/tests/integration/database/test_database_engine_config.py @@ -404,7 +404,7 @@ def mysql_db_engine_config(linode_cloud_firewall): + [ "mysql-create", "--engine", - "mysql/8", + "mysql/8.4", "--label", label, "--region", From a441226d5deff6c001d866634172891c18a0d581 Mon Sep 17 00:00:00 2001 From: Maciej Wilk Date: Mon, 27 Jul 2026 11:02:57 +0200 Subject: [PATCH 10/10] Linter --- tests/integration/linodes/test_linodes.py | 8 +------- .../nodebalancers/test_node_balancers.py | 1 - tests/integration/vpc/test_vpc.py | 16 ++++++++++++---- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tests/integration/linodes/test_linodes.py b/tests/integration/linodes/test_linodes.py index 4f898dc2a..4bbb70bef 100644 --- a/tests/integration/linodes/test_linodes.py +++ b/tests/integration/linodes/test_linodes.py @@ -326,13 +326,7 @@ def test_display_linode_with_res_ipv4(linode_with_reserved_ip): res_ip, linode_id = linode_with_reserved_ip result = exec_test_command( BASE_CMDS["linodes"] - + [ - "view", - linode_id, - "--text", - "--no-headers", - "--no-defaults" - ] + + ["view", linode_id, "--text", "--no-headers", "--no-defaults"] ) assert linode_id in result diff --git a/tests/integration/nodebalancers/test_node_balancers.py b/tests/integration/nodebalancers/test_node_balancers.py index 43f6d064a..69564852a 100644 --- a/tests/integration/nodebalancers/test_node_balancers.py +++ b/tests/integration/nodebalancers/test_node_balancers.py @@ -5,7 +5,6 @@ from linodecli.exit_codes import ExitCodes from tests.integration.helpers import ( BASE_CMDS, - DEFAULT_REGION, exec_failing_test_command, exec_test_command, ) diff --git a/tests/integration/vpc/test_vpc.py b/tests/integration/vpc/test_vpc.py index 2d2fc4080..ccfadee00 100644 --- a/tests/integration/vpc/test_vpc.py +++ b/tests/integration/vpc/test_vpc.py @@ -389,7 +389,9 @@ def test_list_vpc_ipv6s_address(): assert header in lines[0] -@pytest.mark.skip(reason="Skipped because Configurable VPC IPv4 not released by TechDoc yet") +@pytest.mark.skip( + reason="Skipped because Configurable VPC IPv4 not released by TechDoc yet" +) def test_get_vpc_default_ranges(): headers = ["default_ipv4_ranges", "forbidden_ipv4_ranges"] @@ -402,7 +404,9 @@ def test_get_vpc_default_ranges(): assert isinstance(result[headers[1]], list) -@pytest.mark.skip(reason="Skipped because Configurable VPC IPv4 not released by TechDoc yet") +@pytest.mark.skip( + reason="Skipped because Configurable VPC IPv4 not released by TechDoc yet" +) @pytest.mark.parametrize( "create_vpc_with_ipv4, expected", [ @@ -425,7 +429,9 @@ def test_vpc_with_ipv4(create_vpc_with_ipv4, expected): assert len(result["ipv4"]) == expected -@pytest.mark.skip(reason="Skipped because Configurable VPC IPv4 not released by TechDoc yet") +@pytest.mark.skip( + reason="Skipped because Configurable VPC IPv4 not released by TechDoc yet" +) @pytest.mark.parametrize( "create_vpc_with_ipv4, updated", [ @@ -453,7 +459,9 @@ def test_vpc_update_with_ipv4(create_vpc_with_ipv4, updated): assert result["ipv4"][0]["range"] == updated -@pytest.mark.skip(reason="Skipped because Configurable VPC IPv4 not released by TechDoc yet") +@pytest.mark.skip( + reason="Skipped because Configurable VPC IPv4 not released by TechDoc yet" +) def test_vpc_with_forbidden_ipv4_fail(): forbidden_ipv4 = exec_test_command( BASE_CMD