diff --git a/.github/workflows/e2e-suite-windows.yml b/.github/workflows/e2e-suite-windows.yml index 9c74681eb..66e9b7b3d 100644 --- a/.github/workflows/e2e-suite-windows.yml +++ b/.github/workflows/e2e-suite-windows.yml @@ -2,9 +2,17 @@ on: pull_request: workflow_dispatch: inputs: - test_path: - description: "The path from 'test/integration' to the target to be tested, e.g. 'cli'" + module: + description: "The module from 'test/integration' to the target to be tested, e.g. 'cli, domains, events, etc'" required: false + run_long_tests: + description: "Select True to run long tests, e.g. database, rebuild, etc" + required: false + type: choice + options: + - "True" + - "False" + default: "False" sha: description: 'The hash value of the commit.' required: true @@ -21,13 +29,6 @@ jobs: github.event_name == 'workflow_dispatch' && inputs.sha != '' steps: - - uses: actions-ecosystem/action-regex-match@v2 - id: validate-tests - with: - text: ${{ inputs.test_path }} - regex: '[^a-z0-9-:.\/_]' # Tests validation - flags: gi - # Check out merge commit - name: Checkout PR uses: actions/checkout@v4 @@ -72,7 +73,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - run: make INTEGRATION_TEST_PATH="${{ inputs.test_path }}" testint + - run: make MODULE="${{ inputs.module }}" RUN_LONG_TESTS="${{ inputs.run_long_tests }}" testint env: LINODE_CLI_TOKEN: ${{ secrets.LINODE_TOKEN_2 }} diff --git a/.github/workflows/e2e-suite.yml b/.github/workflows/e2e-suite.yml index d28252eb4..bc4163a78 100644 --- a/.github/workflows/e2e-suite.yml +++ b/.github/workflows/e2e-suite.yml @@ -10,6 +10,14 @@ on: module: description: "The module from 'test/integration' to the target to be tested, e.g. 'cli, domains, events, etc'" required: false + run_long_tests: + description: "Select True to run long tests, e.g. database, rebuild, etc" + required: false + type: choice + options: + - "True" + - "False" + default: "False" sha: description: 'The hash value of the commit.' required: true @@ -111,7 +119,7 @@ jobs: run: | timestamp=$(date +'%Y%m%d%H%M') report_filename="${timestamp}_cli_test_report.xml" - make testint TEST_ARGS="--junitxml=${report_filename}" MODULE="${{ inputs.module }}" + make testint TEST_ARGS="--junitxml=${report_filename}" MODULE="${{ inputs.module }}" RUN_LONG_TESTS="${{ inputs.run_long_tests }}" env: LINODE_CLI_TOKEN: ${{ env.LINODE_CLI_TOKEN }} diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 2a4f211fa..a0f283314 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -20,6 +20,7 @@ from tests.integration.helpers import ( delete_target_id, exec_test_command, + get_random_region_with_caps, get_random_text, ) from tests.integration.linodes.helpers_linodes import ( @@ -465,34 +466,6 @@ def nodebalancer_with_default_conf(linode_cloud_firewall): delete_target_id(target="nodebalancers", id=nodebalancer_id) -def get_regions_with_capabilities(capabilities): - regions = ( - exec_test_command( - [ - "linode-cli", - "regions", - "ls", - "--text", - "--no-headers", - "--format=id,capabilities", - ] - ) - .stdout.decode() - .rstrip() - ) - - regions = regions.split("\n") - - regions_with_all_caps = [] - - for region in regions: - region_name = region.split()[0] - if all(capability in region for capability in capabilities): - regions_with_all_caps.append(region_name) - - return regions_with_all_caps - - def create_vpc_w_subnet(): """ Creates and returns a VPC and a corresponding subnet. @@ -504,7 +477,7 @@ def create_vpc_w_subnet(): See: https://github.com/pytest-dev/pytest/issues/1216 """ - region = get_regions_with_capabilities(["VPCs"])[0] + region = get_random_region_with_caps(required_capabilities=["VPCs"]) vpc_label = str(time.time_ns()) + "label" subnet_label = str(time.time_ns()) + "label" diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 0136eb81d..dab183ed5 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -1,3 +1,4 @@ +import json import random import subprocess import time @@ -71,8 +72,8 @@ def delete_tag(arg: str): assert result.returncode == SUCCESS_STATUS_CODE -def delete_target_id(target: str, id: str, subcommand: str = "delete"): - command = ["linode-cli", target, subcommand, id] +def delete_target_id(target: str, id: str, delete_command: str = "delete"): + command = ["linode-cli", target, delete_command, id] result = exec_test_command(command) assert result.returncode == SUCCESS_STATUS_CODE @@ -168,3 +169,28 @@ def retry_exec_test_command_with_delay( assert process.returncode == 0, f"Command failed after {retries} retries" return process + + +def get_random_region_with_caps( + required_capabilities: List[str], site_type="core" +): + json_regions_data = ( + exec_test_command(["linode-cli", "regions", "ls", "--json"]) + .stdout.decode() + .strip() + ) + + # Parse regions JSON data + regions = json.loads(json_regions_data) + + matching_regions = [ + region + for region in regions + if all(cap in region["capabilities"] for cap in required_capabilities) + and region["site_type"] == site_type + ] + + # Extract the region ids + matching_region_ids = [region["id"] for region in matching_regions] + + return random.choice(matching_region_ids) if matching_region_ids else None diff --git a/tests/integration/linodes/helpers_linodes.py b/tests/integration/linodes/helpers_linodes.py index b16c26730..e6b7323e0 100644 --- a/tests/integration/linodes/helpers_linodes.py +++ b/tests/integration/linodes/helpers_linodes.py @@ -71,7 +71,9 @@ def wait_until(linode_id: "str", timeout, status: "str", period=5): return False -def create_linode(firewall_id: "str", test_region=DEFAULT_REGION): +def create_linode( + firewall_id: "str", test_region=DEFAULT_REGION, disk_encryption=False +): # create linode linode_id = ( exec_test_command( @@ -89,6 +91,8 @@ def create_linode(firewall_id: "str", test_region=DEFAULT_REGION): DEFAULT_RANDOM_PASS, "--firewall_id", firewall_id, + "--disk_encryption", + "enabled" if disk_encryption else "disabled", "--format=id", "--text", "--no-headers", @@ -183,73 +187,40 @@ def create_linode_and_wait( test_plan=DEFAULT_LINODE_TYPE, test_image=DEFAULT_TEST_IMAGE, test_region=DEFAULT_REGION, + disk_encryption=False, ): - linode_type = test_plan - - # key_pair = generate_random_ssh_key() + # Base command + command = [ + "linode-cli", + "linodes", + "create", + "--type", + test_plan, + "--region", + test_region, + "--image", + test_image, + "--root_pass", + DEFAULT_RANDOM_PASS, + "--firewall_id", + firewall_id, + "--format=id", + "--backups_enabled", + "true", + "--disk_encryption", + "enabled" if disk_encryption else "disabled", + "--text", + "--no-headers", + ] - output = "" - # if ssh key is successfully generated + # Add SSH key if provided if ssh_key: - output = ( - exec_test_command( - [ - "linode-cli", - "linodes", - "create", - "--type", - linode_type, - "--region", - test_region, - "--image", - test_image, - "--root_pass", - DEFAULT_RANDOM_PASS, - "--authorized_keys", - ssh_key, - "--firewall_id", - firewall_id, - "--format=id", - "--backups_enabled", - "true", - "--text", - "--no-headers", - ] - ) - .stdout.decode() - .rstrip() - ) - else: - output = ( - exec_test_command( - [ - "linode-cli", - "linodes", - "create", - "--type", - linode_type, - "--region", - "us-ord", - "--image", - test_image, - "--root_pass", - DEFAULT_RANDOM_PASS, - "--firewall_id", - firewall_id, - "--format=id", - "--backups_enabled", - "true", - "--text", - "--no-headers", - ] - ) - .stdout.decode() - .rstrip() - ) - linode_id = output + command.extend(["--authorized_keys", ssh_key]) + + linode_id = exec_test_command(command).stdout.decode().strip() # wait until linode is running, wait_until returns True when it is in running state - result = (wait_until(linode_id=linode_id, timeout=240, status="running"),) + result = wait_until(linode_id=linode_id, timeout=240, status="running") assert result, "linode failed to change status to running" @@ -275,3 +246,24 @@ def set_backups_enabled_in_account_settings(toggle: bool): result = exec_test_command(command).stdout.decode().rstrip() return result + + +def get_disk_ids(linode_id): + disk_ids = ( + exec_test_command( + BASE_CMD + + [ + "disks-list", + linode_id, + "--text", + "--no-headers", + "--format", + "id", + ] + ) + .stdout.decode() + .rstrip() + .splitlines() + ) + + return disk_ids diff --git a/tests/integration/linodes/test_backups.py b/tests/integration/linodes/test_backups.py index 474c6a756..dd5c904e7 100755 --- a/tests/integration/linodes/test_backups.py +++ b/tests/integration/linodes/test_backups.py @@ -131,8 +131,8 @@ def test_create_backup_with_backup_enabled(linode_backup_enabled): @pytest.mark.skipif( - os.environ.get("RUN_LONG_TESTS", None) != "TRUE", - reason="Skipping long-running Test, to run set RUN_LONG_TESTS=TRUE", + os.environ.get("RUN_LONG_TESTS", None) != "True", + reason="Skipping long-running Test, to run set RUN_LONG_TESTS=True", ) def test_take_snapshot_of_linode(): # get linode id after creation and wait for "running" status @@ -159,8 +159,8 @@ def test_take_snapshot_of_linode(): @pytest.mark.skipif( - os.environ.get("RUN_LONG_TESTS", None) != "TRUE", - reason="Skipping long-running Test, to run set RUN_LONG_TESTS=TRUE", + os.environ.get("RUN_LONG_TESTS", None) != "True", + reason="Skipping long-running Test, to run set RUN_LONG_TESTS=True", ) def test_view_the_snapshot(snapshot_of_linode): # get linode id after creation and wait for "running" status @@ -187,8 +187,8 @@ def test_view_the_snapshot(snapshot_of_linode): @pytest.mark.skipif( - os.environ.get("RUN_LONG_TESTS", None) != "TRUE", - reason="Skipping long-running Test, to run set RUN_LONG_TESTS=TRUE", + os.environ.get("RUN_LONG_TESTS", None) != "True", + reason="Skipping long-running Test, to run set RUN_LONG_TESTS=True", ) def test_cancel_backups(snapshot_of_linode): # get linode id after creation and wait for "running" status diff --git a/tests/integration/linodes/test_configs.py b/tests/integration/linodes/test_configs.py new file mode 100644 index 000000000..a934ab1d3 --- /dev/null +++ b/tests/integration/linodes/test_configs.py @@ -0,0 +1,447 @@ +import json +import time + +import pytest + +from tests.integration.conftest import create_vpc_w_subnet +from tests.integration.helpers import ( + assert_headers_in_lines, + delete_target_id, + exec_test_command, + get_random_region_with_caps, + get_random_text, + retry_exec_test_command_with_delay, +) +from tests.integration.linodes.helpers_linodes import ( + BASE_CMD, + create_linode, + get_disk_ids, +) + +TEST_REGION = get_random_region_with_caps( + required_capabilities=["Linodes", "VPCs"] +) + + +@pytest.fixture(scope="session", autouse=True) +def linode_instance_config_tests(linode_cloud_firewall): + + linode_id = create_linode( + firewall_id=linode_cloud_firewall, + disk_encryption=False, + test_region=TEST_REGION, + ) + + yield linode_id + + delete_target_id(target="linodes", id=linode_id) + + +@pytest.fixture(scope="session", autouse=True) +def linode_disk_config(linode_instance_config_tests): + linode_id = linode_instance_config_tests + + label = get_random_text(5) + "_config" + disk_id = get_disk_ids(linode_id=linode_id)[1] + + config_id = ( + exec_test_command( + BASE_CMD + + [ + "config-create", + linode_id, + "--label", + label, + "--devices.sda.disk_id", + disk_id, + "--no-headers", + "--format=id", + "--text", + ] + ) + .stdout.decode() + .rstrip() + ) + + yield config_id + + +@pytest.fixture(scope="session", autouse=True) +def test_vpc_w_subnet(request): + vpc_json = create_vpc_w_subnet() + vpc_id = str(vpc_json["id"]) + + yield vpc_id + + +@pytest.fixture(scope="session", autouse=True) +def cleanup_vpc(request, test_vpc_w_subnet): + # Register finalizer to delete VPC after the entire session, with a delay + def delayed_cleanup(): + time.sleep(5) # Delay if necessary + delete_target_id(target="vpcs", id=test_vpc_w_subnet) + + request.addfinalizer(delayed_cleanup) + + +@pytest.fixture(scope="session", autouse=True) +def config_vpc_interface( + linode_instance_config_tests, linode_disk_config, test_vpc_w_subnet +): + linode_id = linode_instance_config_tests + config_id = linode_disk_config + subnet_id = get_subnet_id(vpc_id=test_vpc_w_subnet) + + interface_id = ( + exec_test_command( + BASE_CMD + + [ + "config-interface-add", + linode_id, + config_id, + "--purpose", + "vpc", + "--primary", + "false", + "--subnet_id", + subnet_id, + "--ipv4.vpc", + "10.0.0.3", + "--text", + "--no-headers", + "--format", + "id", + ] + ) + .stdout.decode() + .rstrip() + ) + + yield interface_id + + retry_exec_test_command_with_delay( + BASE_CMD + + [ + "config-interface-delete", + linode_id, + config_id, + interface_id, + ] + ) + + +def create_vpc_w_subnet(): + vpc_label = get_random_text(5) + "vpc" + subnet_label = get_random_text(5) + "subnet" + + vpc_json = json.loads( + exec_test_command( + [ + "linode-cli", + "vpcs", + "create", + "--label", + vpc_label, + "--region", + TEST_REGION, + "--subnets.ipv4", + "10.0.0.0/24", + "--subnets.label", + subnet_label, + "--json", + "--suppress-warnings", + ] + ) + .stdout.decode() + .rstrip() + )[0] + + return vpc_json + + +def get_subnet_id(vpc_id): + subnet_id = ( + exec_test_command( + [ + "linode-cli", + "vpcs", + "subnets-list", + vpc_id, + "--text", + "--format=id", + "--no-headers", + ] + ) + .stdout.decode() + .rstrip() + ) + + return subnet_id + + +def test_config_create(linode_instance_config_tests): + linode_id = linode_instance_config_tests + + label = get_random_text(5) + "_config" + disk_id = get_disk_ids(linode_id=linode_id)[1] + + result = ( + exec_test_command( + BASE_CMD + + [ + "config-create", + linode_id, + "--label", + label, + "--devices.sda.disk_id", + disk_id, + "--text", + ] + ) + .stdout.decode() + .rstrip() + ) + + headers = ["id", "label", "kernel"] + + assert_headers_in_lines(headers, result.splitlines()) + assert label in result + + +def test_config_delete(linode_instance_config_tests): + linode_id = linode_instance_config_tests + + label = get_random_text(5) + "_config" + disk_id = get_disk_ids(linode_id=linode_id)[1] + + config_id = ( + exec_test_command( + BASE_CMD + + [ + "config-create", + linode_id, + "--label", + label, + "--devices.sda.disk_id", + disk_id, + "--no-headers", + "--format=id", + "--text", + ] + ) + .stdout.decode() + .rstrip() + ) + + res = retry_exec_test_command_with_delay( + BASE_CMD + + [ + "config-delete", + linode_id, + config_id, + ] + ) + + assert res.returncode == 0 + + +def test_config_update_label(linode_instance_config_tests, linode_disk_config): + linode_id = linode_instance_config_tests + config_id = linode_disk_config + + updated_label = get_random_text(4) + "_updatedconfig" + + res = ( + exec_test_command( + BASE_CMD + + [ + "config-update", + linode_id, + config_id, + "--label", + updated_label, + "--text", + ] + ) + .stdout.decode() + .rstrip() + ) + + headers = ["id", "label", "kernel"] + + assert_headers_in_lines(headers, res.splitlines()) + assert updated_label in res + + +def test_config_view(linode_instance_config_tests, linode_disk_config): + linode_id = linode_instance_config_tests + config_id = linode_disk_config + + res = ( + exec_test_command( + BASE_CMD + ["config-view", linode_id, config_id, "--text"] + ) + .stdout.decode() + .rstrip() + ) + + headers = ["id", "label", "kernel"] + + assert_headers_in_lines(headers, res.splitlines()) + assert config_id in res + + +def test_configs_list(linode_instance_config_tests): + linode_id = linode_instance_config_tests + + res = ( + exec_test_command(BASE_CMD + ["configs-list", linode_id, "--text"]) + .stdout.decode() + .rstrip() + ) + + headers = ["id", "label", "kernel"] + + assert_headers_in_lines(headers, res.splitlines()) + + +def test_config_interface_add_vlan( + linode_instance_config_tests, linode_disk_config +): + linode_id = linode_instance_config_tests + config_id = linode_disk_config + + label = get_random_text(5) + "vlan" + + res = ( + exec_test_command( + BASE_CMD + + [ + "config-interface-add", + linode_id, + config_id, + "--purpose", + "vlan", + "--primary", + "false", + "--label", + label, + "--text", + ] + ) + .stdout.decode() + .rstrip() + ) + + headers = ["id", "label", "purpose", "ipam_address"] + + assert_headers_in_lines(headers, res.splitlines()) + assert label in res + assert "vlan" in res + + +def test_config_interface_update( + linode_instance_config_tests, linode_disk_config, config_vpc_interface +): + linode_id = linode_instance_config_tests + config_id = linode_disk_config + interface_id = config_vpc_interface + + res = ( + exec_test_command( + BASE_CMD + + [ + "config-interface-update", + linode_id, + config_id, + interface_id, + "--ipv4.vpc", + "10.0.0.5", + "--text", + ] + ) + .stdout.decode() + .rstrip() + ) + + headers = ["id", "label", "purpose", "ipam_address"] + + assert_headers_in_lines(headers, res.splitlines()) + + +def test_config_interface_view( + linode_instance_config_tests, linode_disk_config, config_vpc_interface +): + linode_id = linode_instance_config_tests + config_id = linode_disk_config + interface_id = config_vpc_interface + + res = ( + exec_test_command( + BASE_CMD + + [ + "config-interface-view", + linode_id, + config_id, + interface_id, + "--text", + ] + ) + .stdout.decode() + .rstrip() + ) + + headers = ["id", "label", "purpose", "ipam_address"] + + assert_headers_in_lines(headers, res.splitlines()) + assert interface_id in res + + +def test_config_interfaces_list( + linode_instance_config_tests, linode_disk_config +): + linode_id = linode_instance_config_tests + config_id = linode_disk_config + + res = ( + exec_test_command( + BASE_CMD + + [ + "config-interfaces-list", + linode_id, + config_id, + "--text", + ] + ) + .stdout.decode() + .rstrip() + ) + + headers = ["id", "label", "purpose", "ipam_address"] + + assert_headers_in_lines(headers, res.splitlines()) + + +def config_interfaces_order( + linode_instance_config_tests, linode_disk_config, config_vpc_interface +): + linode_id = linode_instance_config_tests + config_id = linode_disk_config + interface_id = config_vpc_interface + + process = ( + exec_test_command( + BASE_CMD + + [ + "config-interfaces-order", + linode_id, + config_id, + "--ids", + interface_id, + ] + ) + .stdout.decode() + .rstrip() + ) + + assert process.returncode == 0 diff --git a/tests/integration/linodes/test_disk.py b/tests/integration/linodes/test_disk.py new file mode 100644 index 000000000..eaca689fa --- /dev/null +++ b/tests/integration/linodes/test_disk.py @@ -0,0 +1,214 @@ +import pytest + +from tests.integration.helpers import ( + assert_headers_in_lines, + delete_target_id, + exec_test_command, + get_random_region_with_caps, + get_random_text, + retry_exec_test_command_with_delay, + wait_for_condition, +) +from tests.integration.linodes.helpers_linodes import ( + BASE_CMD, + create_linode_and_wait, + get_disk_ids, + wait_until, +) + +TEST_REGION = get_random_region_with_caps(required_capabilities=["Linodes"]) + + +@pytest.fixture(scope="session", autouse=True) +def linode_instance_disk_tests(linode_cloud_firewall): + + linode_id = create_linode_and_wait( + firewall_id=linode_cloud_firewall, + disk_encryption=False, + test_region=TEST_REGION, + test_plan="g6-standard-4", + ) + + retry_exec_test_command_with_delay(BASE_CMD + ["shutdown", linode_id]) + + wait_until(linode_id=linode_id, timeout=240, status="offline") + + yield linode_id + + delete_target_id(target="linodes", id=linode_id) + + +def test_disk_resize_clone_and_create(linode_instance_disk_tests): + linode_id = linode_instance_disk_tests + + disk_id = get_disk_ids(linode_id=linode_id)[1] + + # resize disk + retry_exec_test_command_with_delay( + BASE_CMD + + [ + "disk-resize", + linode_id, + disk_id, + "--size", + "50", + ], + retries=3, + delay=10, + ) + + def disk_poll_func(): + status = ( + exec_test_command( + BASE_CMD + + [ + "disk-view", + linode_id, + disk_id, + "--text", + "--no-headers", + "--format=status", + ] + ) + .stdout.decode() + .rstrip() + ) + + return status == "ready" + + # Wait for the instance to be ready + wait_for_condition(15, 150, disk_poll_func) + + # clone disk + res = ( + retry_exec_test_command_with_delay( + BASE_CMD + + [ + "disk-clone", + linode_id, + disk_id, + "--text", + ], + retries=3, + delay=10, + ) + .stdout.decode() + .rstrip() + ) + + # #TODO:: Add "disk_encryption" when spec shows the header + headers = ["id", "label", "status", "size", "filesystem"] + + assert_headers_in_lines(headers, res.splitlines()) + + assert "Copy of" in res + assert "50" in res + + label = get_random_text(5) + "disk" + + # create new disk + res = ( + retry_exec_test_command_with_delay( + BASE_CMD + + [ + "disk-create", + linode_id, + "--size", + "15", + "--label", + label, + "--text", + ], + retries=3, + delay=10, + ) + .stdout.decode() + .rstrip() + ) + + # TODO:: Add "disk_encryption" when spec shows the header + headers = ["id", "label", "status", "size", "filesystem"] + + assert_headers_in_lines(headers, res.splitlines()) + + assert label in res + assert "15" in res + # assert "disabled" in res + + +def test_disk_reset_password(linode_instance_disk_tests): + linode_id = linode_instance_disk_tests + disk_id = get_disk_ids(linode_id)[1] + + res = retry_exec_test_command_with_delay( + BASE_CMD + + [ + "disk-reset-password", + linode_id, + disk_id, + "--password", + "ThIsIsRanDomPaSsWoRD", + "--text", + ], + retries=3, + delay=10, + ) + + assert res.returncode == 0 + + +def test_disk_update(linode_instance_disk_tests): + linode_id = linode_instance_disk_tests + disk_id = get_disk_ids(linode_id)[1] + + update_label = get_random_text(5) + "newdisk" + + res = ( + ( + retry_exec_test_command_with_delay( + BASE_CMD + + [ + "disk-update", + linode_id, + disk_id, + "--label", + update_label, + "--text", + ], + retries=3, + delay=10, + ) + ) + .stdout.decode() + .rstrip() + ) + + # TODO:: Add "disk_encryption" when spec shows the header + headers = ["id", "label", "status", "size", "filesystem"] + + assert_headers_in_lines(headers, res.splitlines()) + assert update_label in res + + +def test_disks_list(linode_instance_disk_tests): + linode_id = linode_instance_disk_tests + + res = ( + ( + retry_exec_test_command_with_delay( + BASE_CMD + + [ + "disks-list", + linode_id, + "--text", + ] + ) + ) + .stdout.decode() + .rstrip() + ) + + # TODO:: Add "disk_encryption" when spec shows the header + headers = ["id", "label", "status", "size", "filesystem"] + + assert_headers_in_lines(headers, res.splitlines()) diff --git a/tests/integration/linodes/test_linodes.py b/tests/integration/linodes/test_linodes.py index 8444ce1fd..1150d9fa7 100644 --- a/tests/integration/linodes/test_linodes.py +++ b/tests/integration/linodes/test_linodes.py @@ -9,12 +9,14 @@ delete_target_id, exec_failing_test_command, exec_test_command, + get_random_region_with_caps, ) from tests.integration.linodes.helpers_linodes import ( BASE_CMD, DEFAULT_LABEL, DEFAULT_RANDOM_PASS, DEFAULT_TEST_IMAGE, + create_linode, wait_until, ) @@ -23,7 +25,7 @@ @pytest.fixture(scope="package", autouse=True) -def setup_linodes(linode_cloud_firewall): +def test_linode_instance(linode_cloud_firewall): linode_id = ( exec_test_command( BASE_CMD @@ -61,6 +63,31 @@ def setup_linodes(linode_cloud_firewall): delete_target_id(target="linodes", id=linode_id) +@pytest.fixture +def test_disk_id(test_linode_instance): + linode_id = test_linode_instance + disk_id = ( + exec_test_command( + BASE_CMD + + [ + "disks-list", + linode_id, + "--text", + "--no-headers", + "--delimiter", + ",", + "--format", + "id", + ] + ) + .stdout.decode() + .rstrip() + .splitlines() + ) + first_id = disk_id[0].split(",")[0] + yield first_id + + def test_update_linode_with_a_image(): result = exec_test_command(BASE_CMD + ["update", "--help"]).stdout.decode() @@ -77,8 +104,8 @@ def test_create_linodes_with_a_label(linode_with_label): @pytest.mark.smoke -def test_view_linode_configuration(setup_linodes): - linode_id = setup_linodes +def test_view_linode_configuration(test_linode_instance): + linode_id = test_linode_instance result = exec_test_command( BASE_CMD + [ @@ -142,15 +169,15 @@ def test_create_linode_without_image_and_not_boot(linode_wo_image): assert "offline" in result -def test_list_linodes(setup_linodes): +def test_list_linodes(test_linode_instance): result = exec_test_command( BASE_CMD + ["list", "--format", "label", "--text", "--no-headers"] ).stdout.decode() assert linode_label in result -def test_add_tag_to_linode(setup_linodes): - linode_id = setup_linodes +def test_add_tag_to_linode(test_linode_instance): + linode_id = test_linode_instance unique_tag = "tag" + str(int(time.time())) result = exec_test_command( @@ -170,8 +197,8 @@ def test_add_tag_to_linode(setup_linodes): assert unique_tag in result -def list_disk_list(setup_linodes): - linode_id = setup_linodes +def list_disk_list(test_linode_instance): + linode_id = test_linode_instance res = ( exec_test_command( BASE_CMD @@ -191,49 +218,93 @@ def list_disk_list(setup_linodes): assert_headers_in_lines(headers, lines) -@pytest.fixture -def get_disk_id(setup_linodes): - linode_id = setup_linodes - disk_id = ( +def test_disk_view(test_linode_instance, test_disk_id): + linode_id = test_linode_instance + disk_id = test_disk_id + res = ( exec_test_command( BASE_CMD + [ - "disks-list", + "disk-view", linode_id, + disk_id, "--text", - "--no-headers", - "--delimiter", - ",", - "--format", - "id", + "--delimiter=,", ] ) .stdout.decode() .rstrip() - .splitlines() ) - first_id = disk_id[0].split(",")[0] - yield first_id + lines = res.splitlines() + + headers = ["id", "label"] + assert_headers_in_lines(headers, lines) + assert disk_id in res + +def test_create_linode_disk_encryption_enabled(linode_cloud_firewall): + test_region = get_random_region_with_caps( + required_capabilities=["Linodes", "Disk Encryption"] + ) + + linode_id = create_linode( + firewall_id=linode_cloud_firewall, + disk_encryption=True, + test_region=test_region, + ) -def test_disk_view(setup_linodes, get_disk_id): - linode_id = setup_linodes - disk_id = get_disk_id res = ( exec_test_command( BASE_CMD + [ - "disk-view", + "view", linode_id, - disk_id, "--text", "--delimiter=,", + "--format=id,disk_encryption", ] ) .stdout.decode() .rstrip() ) - lines = res.splitlines() - headers = ["id", "label"] - assert_headers_in_lines(headers, lines) + headers = ["id", "disk_encryption"] + assert_headers_in_lines(headers, res.splitlines()) + + assert linode_id in res and "enabled" in res + + delete_target_id(target="linodes", id=linode_id) + + +def test_create_linode_disk_encryption_disabled(linode_cloud_firewall): + test_region = get_random_region_with_caps( + required_capabilities=["Linodes", "Disk Encryption"] + ) + + linode_id = create_linode( + firewall_id=linode_cloud_firewall, + disk_encryption=False, + test_region=test_region, + ) + + res = ( + exec_test_command( + BASE_CMD + + [ + "view", + linode_id, + "--text", + "--delimiter=,", + "--format=id,disk_encryption", + ] + ) + .stdout.decode() + .rstrip() + ) + + headers = ["id", "disk_encryption"] + assert_headers_in_lines(headers, res.splitlines()) + + assert linode_id in res and "disabled" in res + + delete_target_id(target="linodes", id=linode_id) diff --git a/tests/integration/linodes/test_power_status.py b/tests/integration/linodes/test_power_status.py index 9365a1131..984035ad5 100644 --- a/tests/integration/linodes/test_power_status.py +++ b/tests/integration/linodes/test_power_status.py @@ -22,7 +22,7 @@ def test_linode_id(linode_cloud_firewall): @pytest.fixture -def create_linode_in_running_state(linode_cloud_firewall): +def linode_in_running_state(linode_cloud_firewall): linode_id = create_linode_and_wait(firewall_id=linode_cloud_firewall) yield linode_id @@ -31,7 +31,7 @@ def create_linode_in_running_state(linode_cloud_firewall): @pytest.fixture -def create_linode_in_running_state_for_reboot(linode_cloud_firewall): +def linode_in_running_state_for_reboot(linode_cloud_firewall): linode_id = create_linode_and_wait(firewall_id=linode_cloud_firewall) yield linode_id @@ -50,11 +50,9 @@ def test_create_linode_and_boot(test_linode_id): @pytest.mark.flaky(reruns=3, reruns_delay=2) -def test_reboot_linode(create_linode_in_running_state_for_reboot): +def test_reboot_linode(linode_in_running_state_for_reboot): # create linode and wait until it is in "running" state - linode_id = create_linode_in_running_state_for_reboot - # In case if the linode is not ready to reboot - wait_until(linode_id=linode_id, timeout=240, status="running") + linode_id = linode_in_running_state_for_reboot # reboot linode from "running" status retry_exec_test_command_with_delay( diff --git a/tests/integration/linodes/test_rebuild.py b/tests/integration/linodes/test_rebuild.py index eda84fe6d..707bebff0 100644 --- a/tests/integration/linodes/test_rebuild.py +++ b/tests/integration/linodes/test_rebuild.py @@ -7,6 +7,8 @@ delete_target_id, exec_failing_test_command, exec_test_command, + get_random_region_with_caps, + retry_exec_test_command_with_delay, ) from tests.integration.linodes.helpers_linodes import ( BASE_CMD, @@ -17,8 +19,15 @@ @pytest.fixture -def test_linode_id(linode_cloud_firewall): - linode_id = create_linode_and_wait(firewall_id=linode_cloud_firewall) +def linode_for_rebuild_tests(linode_cloud_firewall): + test_region = get_random_region_with_caps( + required_capabilities=["Linodes", "Disk Encryption"] + ) + linode_id = create_linode_and_wait( + firewall_id=linode_cloud_firewall, + disk_encryption=False, + test_region=test_region, + ) yield linode_id @@ -26,14 +35,14 @@ def test_linode_id(linode_cloud_firewall): @pytest.mark.flaky(reruns=3, reruns_delay=2) -def test_rebuild_fails_without_image(test_linode_id): +def test_rebuild_fails_without_image(linode_for_rebuild_tests): result = exec_failing_test_command( BASE_CMD + [ "rebuild", "--root_pass", DEFAULT_RANDOM_PASS, - test_linode_id, + linode_for_rebuild_tests, "--text", "--no-headers", ], @@ -44,8 +53,8 @@ def test_rebuild_fails_without_image(test_linode_id): assert "You must specify an image" in result -def test_rebuild_fails_with_invalid_image(test_linode_id): - linode_id = test_linode_id +def test_rebuild_fails_with_invalid_image(linode_for_rebuild_tests): + linode_id = linode_for_rebuild_tests rebuild_image = "bad/image" result = exec_failing_test_command( @@ -66,26 +75,13 @@ def test_rebuild_fails_with_invalid_image(test_linode_id): @pytest.mark.skipif( - os.environ.get("RUN_LONG_TESTS", None) != "TRUE", - reason="Skipping long-running Test, to run set RUN_LONG_TESTS=TRUE", + os.environ.get("RUN_LONG_TESTS", None) != "True", + reason="Skipping long-running Test, to run set RUN_LONG_TESTS=True", ) -def test_rebuild_a_linode(test_linode_id): - linode_id = test_linode_id - rebuild_image = ( - exec_test_command( - [ - "linode-cli", - "images", - "list", - "--text", - "--no-headers" "--format", - "id", - ] - ) - .stdout.decode() - .rstrip() - .splitlines()[4] - ) +@pytest.mark.flaky(reruns=3, reruns_delay=5) +def test_rebuild_a_linode(linode_for_rebuild_tests): + linode_id = linode_for_rebuild_tests + rebuild_image = "linode/alpine3.20" # trigger rebuild exec_test_command( @@ -117,3 +113,115 @@ def test_rebuild_a_linode(test_linode_id): + ["view", linode_id, "--format", "image", "--text", "--no-headers"] ).stdout.decode() assert rebuild_image in result + + +@pytest.mark.skipif( + os.environ.get("RUN_LONG_TESTS", None) != "True", + reason="Skipping long-running Test, to run set RUN_LONG_TESTS=True", +) +@pytest.mark.flaky(reruns=3, reruns_delay=5) +def test_rebuild_linode_disk_encryption_enabled(linode_for_rebuild_tests): + linode_id = linode_for_rebuild_tests + rebuild_image = "linode/alpine3.20" + + # trigger rebuild + retry_exec_test_command_with_delay( + BASE_CMD + + [ + "rebuild", + linode_id, + "--image", + rebuild_image, + "--root_pass", + DEFAULT_RANDOM_PASS, + "--text", + "--no-headers", + "--disk_encryption", + "enabled", + ], + retries=3, + delay=10, + ).stdout.decode() + + # check status for rebuilding + assert wait_until( + linode_id=linode_id, timeout=180, status="rebuilding" + ), "linode failed to change status to rebuilding.." + + # check if rebuilding finished + assert wait_until( + linode_id=linode_id, timeout=180, status="running" + ), "linode failed to change status to running from rebuilding.." + + result = exec_test_command( + BASE_CMD + + [ + "view", + linode_id, + "--format", + "image", + "--text", + "--no-headers", + "--format=id,image,disk_encryption", + ] + ).stdout.decode() + + assert "enabled" in result + assert rebuild_image in result + + +@pytest.mark.skipif( + os.environ.get("RUN_LONG_TESTS", None) != "True", + reason="Skipping long-running Test, to run set RUN_LONG_TESTS=True", +) +@pytest.mark.flaky(reruns=3, reruns_delay=5) +def test_rebuild_linode_disk_encryption_disabled(linode_for_rebuild_tests): + linode_id = linode_for_rebuild_tests + rebuild_image = "linode/alpine3.20" + + # trigger rebuild + retry_exec_test_command_with_delay( + BASE_CMD + + [ + "rebuild", + linode_id, + "--image", + rebuild_image, + "--root_pass", + DEFAULT_RANDOM_PASS, + "--text", + "--no-headers", + "--disk_encryption", + "disabled", + ], + retries=3, + delay=10, + ).stdout.decode() + + # check status for rebuilding + assert wait_until( + linode_id=linode_id, timeout=180, status="rebuilding" + ), "linode failed to change status to rebuilding.." + + # check if rebuilding finished + assert wait_until( + linode_id=linode_id, timeout=180, status="running" + ), "linode failed to change status to running from rebuilding.." + + result = retry_exec_test_command_with_delay( + BASE_CMD + + [ + "view", + linode_id, + "--format", + "image", + "--text", + "--no-headers", + "--format=id,image,disk_encryption", + ], + retries=3, + delay=10, + ).stdout.decode() + + assert "disabled" in result + assert rebuild_image in result diff --git a/tests/integration/linodes/test_resize.py b/tests/integration/linodes/test_resize.py index fc573ba36..5213cee7b 100644 --- a/tests/integration/linodes/test_resize.py +++ b/tests/integration/linodes/test_resize.py @@ -140,8 +140,8 @@ def test_resize_fail_to_invalid_plan(test_linode_id): @pytest.mark.skipif( - os.environ.get("RUN_LONG_TESTS", None) != "TRUE", - reason="Skipping long-running Test, to run set RUN_LONG_TESTS=TRUE", + os.environ.get("RUN_LONG_TESTS", None) != "True", + reason="Skipping long-running Test, to run set RUN_LONG_TESTS=True", ) def test_resize_to_next_size_plan(test_linode_id): linode_id = test_linode_id diff --git a/tests/integration/linodes/test_types.py b/tests/integration/linodes/test_types.py index 5cb962c86..a92b53fac 100644 --- a/tests/integration/linodes/test_types.py +++ b/tests/integration/linodes/test_types.py @@ -1,29 +1,27 @@ -import os -import subprocess -from typing import List - import pytest -env = os.environ.copy() -env["COLUMNS"] = "200" - - -def exec_test_command(args: List[str]): - process = subprocess.run( - args, - stdout=subprocess.PIPE, - env=env, - ) - return process +from tests.integration.helpers import assert_headers_in_lines, exec_test_command # verifying the DC pricing changes along with types @pytest.mark.smoke def test_linode_type(): - process = exec_test_command(["linode-cli", "linodes", "types"]) - output = process.stdout.decode() - assert " price.hourly " in output - assert " price.monthly " in output - assert " region_prices " in output - assert " hourly " in output - assert " monthly " in output + output = exec_test_command( + ["linode-cli", "linodes", "types", "--text"] + ).stdout.decode() + + headers = [ + "id", + "label", + "class", + "disk", + "memory", + "vcpus", + "gpus", + "network_out", + "transfer", + "price.hourly", + "price.monthly", + ] + + assert_headers_in_lines(headers, output.splitlines()) diff --git a/tests/integration/lke/test_clusters.py b/tests/integration/lke/test_clusters.py index 12b7c063d..3b214dba0 100644 --- a/tests/integration/lke/test_clusters.py +++ b/tests/integration/lke/test_clusters.py @@ -1,80 +1,225 @@ -import time - import pytest -from tests.integration.helpers import assert_headers_in_lines, exec_test_command +from tests.integration.helpers import ( + assert_headers_in_lines, + delete_target_id, + exec_test_command, + get_random_region_with_caps, + get_random_text, + retry_exec_test_command_with_delay, +) BASE_CMD = ["linode-cli", "lke"] -@pytest.mark.smoke -def test_deploy_an_lke_cluster(): - timestamp = str(time.time_ns()) - label = "cluster_test" + timestamp - - lke_version = ( +def get_lke_version_id(): + version_id = ( exec_test_command( BASE_CMD + [ "versions-list", "--text", "--no-headers", + "--delimiter", + ",", + "--format", + "id", ] ) .stdout.decode() .rstrip() - .splitlines()[0] + .splitlines() ) - result = exec_test_command( - BASE_CMD - + [ - "cluster-create", - "--region", - "us-ord", - "--label", - label, - "--node_pools.type", - "g6-standard-1", - "--node_pools.count", - "1", - "--node_pools.disks", - '[{"type":"ext4","size":1024}]', - "--k8s_version", - lke_version, - "--text", - "--delimiter", - ",", - "--no-headers", - "--format", - "label,region,k8s_version", - "--no-defaults", - ] - ).stdout.decode() - assert label + ",us-ord," + lke_version in result + first_id = version_id[0] + return first_id -@pytest.fixture -def get_cluster_id(): + +def get_node_pool_id(cluster_id): + cluster_id + nodepool_id = ( + exec_test_command( + BASE_CMD + + [ + "pools-list", + cluster_id, + "--text", + "--no-headers", + "--format", + "id", + ] + ) + .stdout.decode() + .rstrip() + .splitlines() + ) + + first_id = nodepool_id[0] + + return first_id + + +def get_pool_nodesid(cluster_id): + cluster_id + nodepool_id = ( + exec_test_command( + BASE_CMD + + [ + "pools-list", + cluster_id, + "--text", + "--no-headers", + "--format", + "nodes.id", + ] + ) + .stdout.decode() + .rstrip() + .splitlines() + ) + + first_id = nodepool_id[0] + + return first_id + + +def get_cluster_id(label: str): cluster_id = ( exec_test_command( BASE_CMD + [ "clusters-list", "--text", + "--format=id", + "--no-headers", + "--label", + label, + ] + ) + .stdout.decode() + .rstrip() + ) + + return cluster_id + + +@pytest.fixture +def test_lke_cluster(): + label = get_random_text(8) + "_cluster" + + test_region = get_random_region_with_caps( + required_capabilities=["Linodes", "Kubernetes"] + ) + lke_version = ( + exec_test_command( + BASE_CMD + + [ + "versions-list", + "--text", "--no-headers", + ] + ) + .stdout.decode() + .rstrip() + .splitlines()[0] + ) + + cluster_label = ( + exec_test_command( + BASE_CMD + + [ + "cluster-create", + "--region", + test_region, + "--label", + label, + "--node_pools.type", + "g6-standard-1", + "--node_pools.count", + "1", + "--node_pools.disks", + '[{"type":"ext4","size":1024}]', + "--k8s_version", + lke_version, + "--text", "--delimiter", ",", + "--no-headers", "--format", - "id", + "label", + "--no-defaults", + ] + ) + .stdout.decode() + .rstrip() + ) + + cluster_id = get_cluster_id(label=cluster_label) + + yield cluster_id + + delete_target_id( + target="lke", id=cluster_id, delete_command="cluster-delete" + ) + + +@pytest.mark.smoke +def test_deploy_an_lke_cluster(): + label = get_random_text(8) + "_cluster" + + test_region = get_random_region_with_caps( + required_capabilities=["Linodes", "Kubernetes"] + ) + lke_version = ( + exec_test_command( + BASE_CMD + + [ + "versions-list", + "--text", + "--no-headers", + ] + ) + .stdout.decode() + .rstrip() + .splitlines()[0] + ) + + cluster_label = ( + exec_test_command( + BASE_CMD + + [ + "cluster-create", + "--region", + test_region, + "--label", + label, + "--node_pools.type", + "g6-standard-1", + "--node_pools.count", + "1", + "--node_pools.disks", + '[{"type":"ext4","size":1024}]', + "--k8s_version", + lke_version, + "--text", + "--delimiter", + ",", + "--no-headers", + "--format=label", ] ) .stdout.decode() .rstrip() - .splitlines() ) - first_id = cluster_id[0] - yield first_id + + assert label == cluster_label + + cluster_id = get_cluster_id(label=cluster_label) + + delete_target_id( + target="lke", id=cluster_id, delete_command="cluster-delete" + ) def test_lke_cluster_list(): @@ -91,8 +236,8 @@ def test_lke_cluster_list(): assert_headers_in_lines(headers, lines) -def test_view_lke_cluster(get_cluster_id): - cluster_id = get_cluster_id +def test_view_lke_cluster(test_lke_cluster): + cluster_id = test_lke_cluster res = ( exec_test_command( @@ -106,9 +251,10 @@ def test_view_lke_cluster(get_cluster_id): assert_headers_in_lines(headers, lines) -def test_update_kubernetes_cluster(get_cluster_id): - cluster_id = get_cluster_id - new_label = "cluster_test" + str(time.time_ns()) +def test_update_kubernetes_cluster(test_lke_cluster): + cluster_id = test_lke_cluster + new_label = get_random_text(5) + "_updated_cluster" + updated_label = ( exec_test_command( BASE_CMD @@ -125,16 +271,18 @@ def test_update_kubernetes_cluster(get_cluster_id): .stdout.decode() .rstrip() ) + assert new_label == updated_label -@pytest.mark.flaky(reruns=3, reruns_delay=2) -def test_list_kubernetes_endpoint(get_cluster_id): - cluster_id = get_cluster_id +def test_list_kubernetes_endpoint(test_lke_cluster): + cluster_id = test_lke_cluster res = ( - exec_test_command( + retry_exec_test_command_with_delay( BASE_CMD - + ["api-endpoints-list", cluster_id, "--text", "--delimiter=,"] + + ["api-endpoints-list", cluster_id, "--text", "--delimiter=,"], + retries=3, + delay=30, ) .stdout.decode() .rstrip() @@ -145,8 +293,8 @@ def test_list_kubernetes_endpoint(get_cluster_id): assert_headers_in_lines(headers, lines) -def test_cluster_dashboard_url(get_cluster_id): - cluster_id = get_cluster_id +def test_cluster_dashboard_url(test_lke_cluster): + cluster_id = test_lke_cluster res = ( exec_test_command( BASE_CMD @@ -161,33 +309,8 @@ def test_cluster_dashboard_url(get_cluster_id): assert_headers_in_lines(headers, lines) -@pytest.fixture -def get_node_pool_id(get_cluster_id): - cluster_id = get_cluster_id - nodepool_id = ( - exec_test_command( - BASE_CMD - + [ - "pools-list", - cluster_id, - "--text", - "--no-headers", - "--delimiter", - ",", - "--format", - "id", - ] - ) - .stdout.decode() - .rstrip() - .splitlines() - ) - first_id = nodepool_id[0] - yield first_id - - -def test_node_pool_list(get_cluster_id): - cluster_id = get_cluster_id +def test_node_pool_list(test_lke_cluster): + cluster_id = test_lke_cluster res = ( exec_test_command( BASE_CMD + ["pools-list", cluster_id, "--text", "--delimiter=,"] @@ -201,9 +324,10 @@ def test_node_pool_list(get_cluster_id): assert_headers_in_lines(headers, lines) -def test_view_pool(get_cluster_id, get_node_pool_id): - cluster_id = get_cluster_id - node_pool_id = get_node_pool_id +def test_view_pool(test_lke_cluster): + cluster_id = test_lke_cluster + node_pool_id = get_node_pool_id(cluster_id) + res = ( exec_test_command( BASE_CMD @@ -212,17 +336,18 @@ def test_view_pool(get_cluster_id, get_node_pool_id): .stdout.decode() .rstrip() ) + lines = res.splitlines() headers = ["type", "labels.value"] assert_headers_in_lines(headers, lines) -@pytest.mark.skip(reason="BUG TPT-TPT-3145") -def test_update_node_pool(get_cluster_id, get_node_pool_id): - cluster_id = get_cluster_id - node_pool_id = get_node_pool_id - new_label = "cluster_test" + str(time.time_ns()) - updated_count = ( +def test_update_node_pool(test_lke_cluster): + cluster_id = test_lke_cluster + node_pool_id = get_node_pool_id(cluster_id) + new_label = get_random_text(8) + "updated_pool" + + result = ( exec_test_command( BASE_CMD + [ @@ -231,7 +356,7 @@ def test_update_node_pool(get_cluster_id, get_node_pool_id): node_pool_id, "--count", "5", - "--label.value", + "--labels.value", new_label, "--text", "--no-headers", @@ -241,13 +366,14 @@ def test_update_node_pool(get_cluster_id, get_node_pool_id): .stdout.decode() .rstrip() ) - assert new_label == updated_count + assert new_label in result + + +def test_view_node(test_lke_cluster): + cluster_id = test_lke_cluster + node_pool_id = get_pool_nodesid(cluster_id) -@pytest.mark.skip(reason="BUG TPT-TPT-3145") -def test_view_node(get_cluster_id, get_node_pool_id): - cluster_id = get_cluster_id - node_pool_id = get_node_pool_id res = ( exec_test_command( BASE_CMD @@ -256,36 +382,14 @@ def test_view_node(get_cluster_id, get_node_pool_id): .stdout.decode() .rstrip() ) + lines = res.splitlines() - headers = ["type", "labels.value"] + headers = ["id", "id,instance_id,status"] assert_headers_in_lines(headers, lines) -@pytest.fixture -def test_version_id(): - version_id = ( - exec_test_command( - BASE_CMD - + [ - "versions-list", - "--text", - "--no-headers", - "--delimiter", - ",", - "--format", - "id", - ] - ) - .stdout.decode() - .rstrip() - .splitlines() - ) - first_id = version_id[0] - yield first_id - - -def test_version_view(test_version_id): - version_id = test_version_id +def test_version_view(): + version_id = get_lke_version_id() res = ( exec_test_command( BASE_CMD + ["version-view", version_id, "--text", "--delimiter=,"] @@ -318,3 +422,93 @@ def test_list_lke_types(): assert_headers_in_lines(headers, lines) assert "LKE Standard Availability" in types assert "LKE High Availability" in types + + +def test_create_node_pool_default_to_disk_encryption_enabled(test_lke_cluster): + cluster_id = test_lke_cluster + + result = ( + exec_test_command( + BASE_CMD + + [ + "pool-create", + cluster_id, + "--count", + "1", + "--type", + "g6-standard-4", + "--text", + "--format=id,disk_encryption,type", + "--no-headers", + ] + ) + .stdout.decode() + .rstrip() + ) + + assert "enabled" in result + assert "g6-standard-4" in result + + +@pytest.fixture +def test_node_pool(test_lke_cluster): + cluster_id = test_lke_cluster + + node_pool_id = ( + exec_test_command( + BASE_CMD + + [ + "pool-create", + cluster_id, + "--count", + "1", + "--type", + "g6-standard-4", + "--text", + "--format=id", + "--no-headers", + ] + ) + .stdout.decode() + .rstrip() + ) + + yield node_pool_id + + +def test_pool_view(test_lke_cluster, test_node_pool): + cluster_id = test_lke_cluster + + node_pool_id = test_node_pool + + node_pool = ( + exec_test_command( + BASE_CMD + + [ + "pool-view", + cluster_id, + node_pool_id, + "--text", + ] + ) + .stdout.decode() + .rstrip() + ) + + lines = node_pool.splitlines() + + headers = [ + "autoscaler.enabled", + "autoscaler.max", + "autoscaler.min", + "count", + "disk_encryption", + "id", + "labels.key", + "labels.value", + "tags", + "taints", + "type", + ] + + assert_headers_in_lines(headers, lines) diff --git a/tests/integration/managed/test_managed.py b/tests/integration/managed/test_managed.py index c8e53478b..28baa23dd 100644 --- a/tests/integration/managed/test_managed.py +++ b/tests/integration/managed/test_managed.py @@ -101,7 +101,7 @@ def test_managed_contact_update(get_contact_id): ) assert update_name == unique_name1 delete_target_id( - target="managed", subcommand="contact-delete", id=contact_id + target="managed", delete_command="contact-delete", id=contact_id ) @@ -197,7 +197,7 @@ def test_managed_credentials_update(get_credential_id): ) assert update_label == new_label delete_target_id( - target="managed", subcommand="credential-revoke", id=credential_id + target="managed", delete_command="credential-revoke", id=credential_id ) diff --git a/tests/integration/obj/test_obj_bucket.py b/tests/integration/obj/test_obj_bucket.py index 637a702f8..17f86dae4 100644 --- a/tests/integration/obj/test_obj_bucket.py +++ b/tests/integration/obj/test_obj_bucket.py @@ -144,5 +144,5 @@ def test_obj_storage_key_update(get_key_id): ) assert new_label == updated_label delete_target_id( - target="object-storage", subcommand="keys-delete", id=key_id + target="object-storage", delete_command="keys-delete", id=key_id ) diff --git a/tests/integration/placements/test_placements.py b/tests/integration/placements/test_placements.py index 7fa2309da..a05b97d97 100644 --- a/tests/integration/placements/test_placements.py +++ b/tests/integration/placements/test_placements.py @@ -37,7 +37,7 @@ def create_placement_group(): ) yield placement_group_id delete_target_id( - target="placement", subcommand="group-delete", id=placement_group_id + target="placement", delete_command="group-delete", id=placement_group_id ) diff --git a/tests/integration/vpc/conftest.py b/tests/integration/vpc/conftest.py index a4e9f26be..4f7165aca 100644 --- a/tests/integration/vpc/conftest.py +++ b/tests/integration/vpc/conftest.py @@ -2,11 +2,12 @@ import pytest -from tests.integration.conftest import ( - create_vpc_w_subnet, - get_regions_with_capabilities, +from tests.integration.conftest import create_vpc_w_subnet +from tests.integration.helpers import ( + delete_target_id, + exec_test_command, + get_random_region_with_caps, ) -from tests.integration.helpers import delete_target_id, exec_test_command @pytest.fixture @@ -21,7 +22,7 @@ def test_vpc_w_subnet(): @pytest.fixture def test_vpc_wo_subnet(): - region = get_regions_with_capabilities(["VPCs"])[0] + region = get_random_region_with_caps(required_capabilities=["VPCs"]) label = str(time.time_ns()) + "label" diff --git a/tests/integration/vpc/test_vpc.py b/tests/integration/vpc/test_vpc.py index f03e5fdce..cee877212 100644 --- a/tests/integration/vpc/test_vpc.py +++ b/tests/integration/vpc/test_vpc.py @@ -4,10 +4,10 @@ import pytest from linodecli.exit_codes import ExitCodes -from tests.integration.conftest import get_regions_with_capabilities from tests.integration.helpers import ( exec_failing_test_command, exec_test_command, + get_random_region_with_caps, ) BASE_CMD = ["linode-cli", "vpcs"] @@ -161,7 +161,7 @@ def test_update_subnet(test_vpc_w_subnet): def test_fails_to_create_vpc_invalid_label(): invalid_label = "invalid_label" - region = get_regions_with_capabilities(["VPCs"])[0] + region = get_random_region_with_caps(required_capabilities=["VPCs"]) res = ( exec_failing_test_command( @@ -186,7 +186,7 @@ def test_fails_to_create_vpc_duplicate_label(test_vpc_wo_subnet): .stdout.decode() .rstrip() ) - region = get_regions_with_capabilities(["VPCs"])[0] + region = get_random_region_with_caps(required_capabilities=["VPCs"]) res = ( exec_failing_test_command( @@ -220,7 +220,6 @@ def test_fails_to_update_vpc_invalid_label(test_vpc_wo_subnet): def test_fails_to_create_vpc_subnet_w_invalid_label(test_vpc_wo_subnet): vpc_id = test_vpc_wo_subnet invalid_label = "invalid_label" - region = get_regions_with_capabilities(["VPCs"])[0] res = exec_failing_test_command( BASE_CMD