Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e3a6114
Create int tests for Reserved IPs #1
mawilk90 May 7, 2026
0041c67
Create int tests for Reserved IPs networking
mawilk90 May 8, 2026
7d87294
Add tests for reserved ip types, view and list + refactor existing
mawilk90 May 8, 2026
c38efc7
Extract fixtures.py for networking
mawilk90 May 8, 2026
439a3e6
Create test for tag creation with reserved_ipv4_addresses
mawilk90 May 8, 2026
ae89800
Add int test for ip-update, modify int test for ips-list
mawilk90 May 11, 2026
a488cd2
Linter fixes
mawilk90 May 12, 2026
cb4cd17
Suppress autoflake warnings for networking fixtures imports
mawilk90 May 12, 2026
dec6321
Reformat due to black issues
mawilk90 May 12, 2026
6cdc469
Merge branch 'dev' into feature/TPT-4280-linode-cli-add-integration-t…
mawilk90 May 13, 2026
f48d25b
Merge branch 'dev' into feature/TPT-4280-linode-cli-add-integration-t…
mawilk90 May 14, 2026
12536a2
Merge branch 'dev' into feature/TPT-4280-linode-cli-add-integration-t…
mawilk90 May 18, 2026
2823ac5
Merge branch 'dev' into feature/TPT-4280-linode-cli-add-integration-t…
mawilk90 Jun 1, 2026
7e047a3
Merge branch 'dev' into feature/TPT-4280-linode-cli-add-integration-t…
mawilk90 Jun 22, 2026
6a07bd9
Test updates and refactor after openapi.json fixes
mawilk90 Jun 22, 2026
ae58218
Linters
mawilk90 Jun 22, 2026
5ad1b28
Refactor test_get_reserved_ip_types
mawilk90 Jul 1, 2026
f591d89
Update tests/integration/linodes/helpers.py
mawilk90 Jul 2, 2026
3966d3c
Rename networking fixtures to avoid ambiguity with tests
mawilk90 Jul 9, 2026
ba0d552
Merge branch 'dev' into feature/TPT-4280-linode-cli-add-integration-t…
mawilk90 Jul 9, 2026
aadac1b
Linter
mawilk90 Jul 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion tests/integration/linodes/helpers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import os
import time

from tests.integration.helpers import (
Expand All @@ -7,7 +8,11 @@
)

DEFAULT_RANDOM_PASS = exec_test_command(["openssl", "rand", "-base64", "32"])
DEFAULT_REGION = "us-ord"
DEFAULT_REGION = (
"pl-labkrk-2"
if "devcloud" in os.getenv("LINODE_CLI_API_HOST", "")
else "us-ord"
)

DEFAULT_TEST_IMAGE = exec_test_command(
[
Expand Down
70 changes: 70 additions & 0 deletions tests/integration/networking/fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import json

import pytest

from tests.integration.helpers import (
BASE_CMDS,
delete_target_id,
exec_test_command,
)
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)

yield linode_id

delete_target_id(target="linodes", id=linode_id)


@pytest.fixture(scope="package")
def get_linode_ids_shared_ipv4(linode_cloud_firewall):
target_region = "us-mia"

linode_ids = (
create_linode(
test_region=target_region, firewall_id=linode_cloud_firewall
),
create_linode(
test_region=target_region, firewall_id=linode_cloud_firewall
),
)

yield linode_ids

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
255 changes: 216 additions & 39 deletions tests/integration/networking/test_networking.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import ipaddress
import json
import re

Expand All @@ -6,41 +7,31 @@

from tests.integration.helpers import (
BASE_CMDS,
delete_target_id,
assert_headers_in_lines,
exec_test_command,
)
from tests.integration.linodes.helpers import (
create_linode,
create_linode_and_wait,
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,
)


@pytest.fixture(scope="package")
def test_linode_id(linode_cloud_firewall):
linode_id = create_linode_and_wait(firewall_id=linode_cloud_firewall)

yield linode_id

delete_target_id(target="linodes", id=linode_id)


@pytest.fixture(scope="package")
def test_linode_id_shared_ipv4(linode_cloud_firewall):
target_region = "us-mia"

linode_ids = (
create_linode(
test_region=target_region, firewall_id=linode_cloud_firewall
),
create_linode(
test_region=target_region, firewall_id=linode_cloud_firewall
),
)

yield linode_ids

for id in linode_ids:
delete_target_id(target="linodes", id=id)
RESERVED_IP_HEADERS = [
"address",
"type",
"public",
"rdns",
"region",
"linode_id",
"interface_id",
"reserved",
"gateway",
"prefix",
"subnet_mask",
"tags",
]


def has_shared_ip(linode_id: int, ip: str) -> bool:
Expand All @@ -61,15 +52,26 @@ def has_shared_ip(linode_id: int, ip: str) -> bool:
return False


def test_display_ips_for_available_linodes(test_linode_id):
def verify_reserved_ip(result):
assert isinstance(
ipaddress.ip_address(result["address"]), ipaddress.IPv4Address
)
assert result["type"] == "ipv4"
assert result["public"] == True
assert result["region"] == DEFAULT_REGION
assert not result["linode_id"]
assert result["reserved"] == True


def test_display_ips_for_available_linodes(get_linode_id):
result = exec_test_command(
BASE_CMDS["networking"]
+ ["ips-list", "--text", "--no-headers", "--delimiter", ","]
)

assert re.search(r"^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}", result)
assert re.search(
r"ipv4,True,[0-9]{1,3}\-[0-9]{1,3}\-[0-9]{1,3}\-[0-9]{1,3}\.ip.linodeusercontent.com,.*,[0-9][0-9][0-9][0-9][0-9][0-9][0-9]*",
r"ipv4,True,(False|True),[0-9]{1,3}\-[0-9]{1,3}\-[0-9]{1,3}\-[0-9]{1,3}\.ip\.linodeusercontent\.com,[0-9]*",
result,
)
assert re.search("ipv6,True,,.*,[0-9][0-9][0-9][0-9][0-9][0-9]*", result)
Expand All @@ -80,8 +82,8 @@ def test_display_ips_for_available_linodes(test_linode_id):


@pytest.mark.smoke
def test_view_an_ip_address(test_linode_id):
linode_id = test_linode_id
def test_view_an_ip_address(get_linode_id):
linode_id = get_linode_id
linode_ipv4 = exec_test_command(
[
"linode-cli",
Expand Down Expand Up @@ -119,8 +121,8 @@ def test_view_an_ip_address(test_linode_id):
), f"`interface_id` is not None or int: {data['interface_id']}"


def test_allocate_additional_private_ipv4_address(test_linode_id):
linode_id = test_linode_id
def test_allocate_additional_private_ipv4_address(get_linode_id):
linode_id = get_linode_id

result = exec_test_command(
BASE_CMDS["networking"]
Expand All @@ -145,10 +147,185 @@ def test_allocate_additional_private_ipv4_address(test_linode_id):
)


@pytest.mark.smoke
@pytest.mark.parametrize(
"create_reserved_ip, expected",
[("test", ["test"]), (None, [])],
indirect=["create_reserved_ip"],
)
def test_create_reserved_ip(create_reserved_ip, expected):
res_ip_data = create_reserved_ip
headers = list(res_ip_data.keys())

assert_headers_in_lines(RESERVED_IP_HEADERS, [headers])
verify_reserved_ip(res_ip_data)
assert res_ip_data["tags"] == expected


@pytest.mark.parametrize("create_reserved_ip", ["test"], indirect=True)
def test_update_reserved_ip_tags(create_reserved_ip):
res_ip_data = create_reserved_ip
assert res_ip_data["tags"] == ["test"]

result = json.loads(
exec_test_command(
BASE_CMDS["networking"]
+ [
"reserved-ip-update",
"--tags",
"updated",
"--tags",
"updated2",
res_ip_data["address"],
"--json",
]
)
)[0]

verify_reserved_ip(result)
assert result["tags"] == ["updated", "updated2"]


def test_create_reserved_ip_assigned(create_reserved_ip, get_linode_id):
res_ip_data = create_reserved_ip
linode_id = get_linode_id

exec_test_command(
BASE_CMDS["networking"]
+ [
"ip-assign",
"--assignments.linode_id",
linode_id,
"--assignments.address",
res_ip_data["address"],
"--region",
DEFAULT_REGION,
]
)

result = json.loads(
exec_test_command(
BASE_CMDS["linodes"]
+ [
"ip-view",
linode_id,
res_ip_data["address"],
"--json",
]
)
)[0]
headers = list(result.keys())

assert_headers_in_lines(RESERVED_IP_HEADERS[:-1], [headers])
assert result["address"] == res_ip_data["address"]
assert result["linode_id"] == int(linode_id)
assert result["reserved"] == True
assert "tags" not in headers
assert "assigned_entity" in headers


def test_get_reserved_ip_types():
headers_exp = [
"id",
"label",
"price",
"region_prices",
]
result = json.loads(
exec_test_command(
BASE_CMDS["networking"]
+ [
"reserved-ip-types-list",
"--json",
]
)
)[0]
headers = list(result.keys())
prices = [result["price"]["hourly"], result["price"]["monthly"]]

assert_headers_in_lines(headers_exp, [headers])
assert result["id"] == "reserved-ipv4"
assert result["label"] == "Reserved IPv4"
assert any(price != 0 for price in prices)


def test_get_reserved_ip_view(create_reserved_ip):
res_ip_data = create_reserved_ip
result = json.loads(
exec_test_command(
BASE_CMDS["networking"]
+ [
"reserved-ip-view",
res_ip_data["address"],
"--json",
]
)
)[0]
headers = list(result.keys())

assert_headers_in_lines(RESERVED_IP_HEADERS, [headers])
verify_reserved_ip(result)


def test_get_reserved_ips_list(create_reserved_ip):
result = exec_test_command(
BASE_CMDS["networking"]
+ [
"reserved-ips-list",
"--text",
"--no-headers",
"--format",
"reserved",
]
).splitlines()

assert all(item == "True" for item in result)


def test_update_ephemeral_to_reserved(get_linode_id):
linode_id = get_linode_id

ephemeral_ip = exec_test_command(
BASE_CMDS["linodes"]
+ [
"view",
linode_id,
"--text",
"--no-headers",
"--format",
"ipv4",
]
).split(" ")[0]

exec_test_command(
BASE_CMDS["networking"]
+ [
"ip-update",
ephemeral_ip,
"--reserved",
"true",
]
)

is_reserved = exec_test_command(
BASE_CMDS["networking"]
+ [
"reserved-ip-view",
ephemeral_ip,
"--text",
"--no-headers",
"--format",
"reserved",
]
)

assert is_reserved == "True"


def test_share_ipv4_address(
test_linode_id_shared_ipv4, monkeypatch: MonkeyPatch
get_linode_ids_shared_ipv4, monkeypatch: MonkeyPatch
):
target_linode, parent_linode = test_linode_id_shared_ipv4
target_linode, parent_linode = get_linode_ids_shared_ipv4
monkeypatch.setenv("LINODE_CLI_API_VERSION", "v4beta")

# Allocate an IPv4 address on the parent Linode
Expand Down
Loading
Loading