diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index 35a8a22f..f74d8195 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -28,6 +28,8 @@ "domains", "events", "image", + "images", + "image-sharegroups", "image-upload", "firewalls", "kernels", @@ -208,6 +210,6 @@ def get_random_region_with_caps( def assert_help_actions_list(expected_actions, help_output): - output_actions = re.findall("\│\s(\S+)\s*\│", help_output) + output_actions = re.findall(r"│\s(\S+(?:,\s)?\S+)\s*│", help_output) for expected_action in expected_actions: assert expected_action in output_actions diff --git a/tests/integration/sharegroups/fixtures.py b/tests/integration/sharegroups/fixtures.py new file mode 100644 index 00000000..488b1a02 --- /dev/null +++ b/tests/integration/sharegroups/fixtures.py @@ -0,0 +1,139 @@ +import pytest + +from tests.integration.helpers import ( + BASE_CMDS, + exec_test_command, + get_random_text, +) + + +@pytest.fixture +def get_region(): + regions = exec_test_command( + BASE_CMDS["regions"] + + [ + "list", + "--text", + "--no-headers", + "--delimiter", + ",", + "--format", + "id", + ] + ).splitlines() + first_id = regions[0] + yield first_id + + +def wait_for_image_status(id, expected_status, timeout=180, interval=5): + import time + + current_status = exec_test_command( + BASE_CMDS["images"] + + [ + "view", + id, + "--text", + "--no-headers", + "--delimiter", + ",", + "--format", + "status", + ] + ).splitlines() + timer = 0 + while current_status[0] != expected_status and timer < timeout: + time.sleep(interval) + timer += interval + current_status = exec_test_command( + BASE_CMDS["images"] + + [ + "view", + id, + "--text", + "--no-headers", + "--delimiter", + ",", + "--format", + "status", + ] + ).splitlines() + if timer >= timeout: + raise TimeoutError( + f"Created image did not reach status '{expected_status}' within {timeout} seconds." + ) + + +@pytest.fixture(scope="function") +def create_image_id(get_region): + linode_id = exec_test_command( + BASE_CMDS["linodes"] + + [ + "create", + "--image", + "linode/alpine3.22", + "--region", + get_region, + "--type", + "g6-nanode-1", + "--root_pass", + "aComplex@Password", + "--text", + "--no-headers", + "--delimiter", + ",", + "--format", + "id", + ] + ) + disks = exec_test_command( + BASE_CMDS["linodes"] + + [ + "disks-list", + linode_id, + "--text", + "--no-headers", + "--delimiter", + ",", + "--format", + "id", + ] + ).splitlines() + image_id = exec_test_command( + BASE_CMDS["images"] + + [ + "create", + "--label", + "linode-cli-test-image-sharing-image", + "--disk_id", + disks[0], + "--text", + "--no-headers", + "--delimiter", + ",", + "--format", + "id", + ] + ) + wait_for_image_status(image_id, "available") + yield linode_id, image_id + + +@pytest.fixture(scope="function") +def create_share_group(): + label = get_random_text(8) + "_sharegroup_cli_test" + share_group = exec_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "create", + "--label", + label, + "--text", + "--no-headers", + "--delimiter", + ",", + "--format", + "id,uuid", + ] + ).split(",") + yield share_group[0], share_group[1] diff --git a/tests/integration/sharegroups/test_images_sharegroups.py b/tests/integration/sharegroups/test_images_sharegroups.py new file mode 100644 index 00000000..1ab8bf34 --- /dev/null +++ b/tests/integration/sharegroups/test_images_sharegroups.py @@ -0,0 +1,426 @@ +from linodecli.exit_codes import ExitCodes +from tests.integration.helpers import ( + BASE_CMDS, + assert_headers_in_lines, + assert_help_actions_list, + delete_target_id, + exec_failing_test_command, + exec_test_command, + get_random_text, +) +from tests.integration.sharegroups.fixtures import ( # noqa: F401 + create_image_id, + create_share_group, + get_region, +) + + +def test_help_image_sharegroups(): + output = exec_test_command( + BASE_CMDS["image-sharegroups"] + ["--help", "--text", "--delimiter=,"] + ) + actions = [ + "create", + "delete, rm", + "image-add", + "image-remove", + "image-update", + "images-list", + "images-list-by-token", + "list, ls", + "member-add", + "member-delete", + "member-update", + "member-view", + "members-list", + "token-create", + "token-delete", + "token-update", + "token-view", + "tokens-list", + "update", + "view", + "view-by-token", + ] + assert_help_actions_list(actions, output) + + +def test_list_all_share_groups(): + result = exec_test_command( + BASE_CMDS["image-sharegroups"] + ["list", "--delimiter", ",", "--text"] + ) + lines = result.splitlines() + headers = [ + "id", + "label", + "uuid", + "description", + "is_suspended", + "images_count", + "members_count", + ] + assert_headers_in_lines(headers, lines) + + +def test_add_list_update_remove_image_to_share_group( + create_share_group, create_image_id +): + result_add_image = exec_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "image-add", + "--images.id", + create_image_id[1], + create_share_group[0], + "--delimiter", + ",", + "--text", + ] + ).splitlines() + headers = [ + "id", + "label", + "description", + "size", + "total_size", + "capabilities", + "is_public", + "is_shared", + "tags", + ] + assert_headers_in_lines(headers, result_add_image) + assert "linode-cli-test-image-sharing-image" in result_add_image[1] + + result_list = exec_test_command( + BASE_CMDS["image-sharegroups"] + + ["images-list", create_share_group[0], "--delimiter", ",", "--text"] + ).splitlines() + headers = [ + "id", + "label", + "description", + "size", + "total_size", + "capabilities", + "is_public", + "is_shared", + "tags", + ] + assert_headers_in_lines(headers, result_list) + assert "linode-cli-test-image-sharing-image" in result_list[1] + share_image_id = result_list[1].split(",")[0] + + result_update_image = exec_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "image-update", + create_share_group[0], + share_image_id, + "--label", + "updated_label", + "--description", + "Updated description.", + "--delimiter", + ",", + "--text", + ] + ).splitlines() + assert_headers_in_lines(headers, result_update_image) + assert "updated_label" in result_update_image[1] + assert "Updated description." in result_update_image[1] + + exec_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "image-remove", + create_share_group[0], + share_image_id, + "--delimiter", + ",", + "--text", + ] + ).splitlines() + + result_list = exec_test_command( + BASE_CMDS["image-sharegroups"] + + ["images-list", create_share_group[0], "--delimiter", ",", "--text"] + ) + assert "linode-cli-test-image-sharing-image" not in result_list + assert "updated_label" not in result_list + + delete_target_id(target="image-sharegroups", id=create_share_group[0]) + delete_target_id(target="images", id=create_image_id[1]) + delete_target_id(target="linodes", id=create_image_id[0]) + + +def test_try_add_member_use_invalid_token(create_share_group): + result = exec_failing_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "member-add", + "--token", + "notExistingToken", + "--label", + "test add member", + create_share_group[0], + "--delimiter", + ",", + "--text", + ], + expected_code=ExitCodes.REQUEST_FAILED, + ) + assert "Request failed: 500" in result + assert "Invalid token format" in result + + delete_target_id(target="image-sharegroups", id=create_share_group[0]) + + +def test_list_members_for_invalid_token(create_share_group): + result = exec_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "members-list", + "--token", + "notExistingToken", + create_share_group[0], + "--delimiter", + ",", + "--text", + ] + ).splitlines() + headers = ["token_uuid", "label", "status"] + assert_headers_in_lines(headers, result) + + delete_target_id(target="image-sharegroups", id=create_share_group[0]) + + +def test_try_revoke_membership_for_invalid_token(): + result = exec_failing_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "member-delete", + "9876543", + "notExistingToken", + "--delimiter", + ",", + "--text", + "--no-headers", + ], + expected_code=ExitCodes.REQUEST_FAILED, + ) + assert "Request failed: 404" in result + assert "Not found" in result + + +def test_try_update_membership_for_invalid_token(): + result = exec_failing_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "member-update", + "9876543", + "notExistingToken", + "--delimiter", + ",", + "--text", + "--no-headers", + "--label", + "update", + ], + expected_code=ExitCodes.REQUEST_FAILED, + ) + assert "Request failed: 404" in result + assert "Not found" in result + + +def test_try_view_membership_for_invalid_token(): + result = exec_failing_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "member-view", + "9876543", + "notExistingToken", + "--delimiter", + ",", + "--text", + "--no-headers", + ], + expected_code=ExitCodes.REQUEST_FAILED, + ) + assert "Request failed: 404" in result + assert "Not found" in result + + +def test_create_read_update_delete_share_group(): + group_label = get_random_text(8) + "_sharegroup_cli_test" + create_result = exec_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "create", + "--label", + group_label, + "--description", + "Test create", + "--delimiter", + ",", + "--text", + ] + ).splitlines() + headers = [ + "id", + "label", + "uuid", + "description", + "is_suspended", + "images_count", + "members_count", + ] + assert_headers_in_lines(headers, create_result) + assert group_label in create_result[1] + assert "Test create" in create_result[1] + share_group_id = create_result[1].split(",")[0] + + get_result = exec_test_command( + BASE_CMDS["image-sharegroups"] + + ["view", share_group_id, "--delimiter", ",", "--text"] + ).splitlines() + assert_headers_in_lines(headers, get_result) + assert group_label in get_result[1] + + update_result = exec_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "update", + "--description", + "Description update", + "--label", + group_label + "_updated", + share_group_id, + "--delimiter", + ",", + "--text", + ] + ).splitlines() + assert_headers_in_lines(headers, update_result) + assert group_label + "_updated" in update_result[1] + assert "Description update" in update_result[1] + + exec_test_command( + BASE_CMDS["image-sharegroups"] + ["delete", share_group_id] + ) + result_after_delete = exec_failing_test_command( + BASE_CMDS["image-sharegroups"] + + ["view", share_group_id, "--delimiter", ",", "--text"], + expected_code=ExitCodes.REQUEST_FAILED, + ) + assert "Request failed: 404" in result_after_delete + assert "Not found" in result_after_delete + + +def test_try_to_create_token(create_share_group): + share_group_uuid = create_share_group[1] + result = exec_failing_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "token-create", + "--label", + "cli_test", + "--valid_for_sharegroup_uuid", + share_group_uuid, + "--delimiter", + ",", + "--text", + ], + expected_code=ExitCodes.REQUEST_FAILED, + ) + assert "Request failed: 400" in result + assert "You may not create a token for your own sharegroup" in result + + delete_target_id(target="image-sharegroups", id=create_share_group[0]) + + +def test_try_read_invalid_token(): + result = exec_failing_test_command( + BASE_CMDS["image-sharegroups"] + + ["token-view", "36b0-4d52_invalid", "--delimiter", ",", "--text"], + expected_code=ExitCodes.REQUEST_FAILED, + ) + assert "Request failed: 404" in result + assert "Not found" in result + + +def test_try_to_update_invalid_token(): + result = exec_failing_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "token-update", + "--label", + "cli_test_update", + "36b0-4d52_invalid", + "--delimiter", + ",", + "--text", + ], + expected_code=ExitCodes.REQUEST_FAILED, + ) + assert "Request failed: 404" in result + assert "Not found" in result + + +def test_try_to_delete_token(): + result = exec_failing_test_command( + BASE_CMDS["image-sharegroups"] + + ["token-delete", "36b0-4d52_invalid", "--delimiter", ",", "--text"], + expected_code=ExitCodes.REQUEST_FAILED, + ) + assert "Request failed: 404" in result + assert "Not found" in result + + +def test_get_details_about_all_the_users_tokens(): + result = exec_test_command( + BASE_CMDS["image-sharegroups"] + + ["tokens-list", "--delimiter", ",", "--text"] + ) + lines = result.splitlines() + headers = [ + "token_uuid", + "label", + "status", + "valid_for_sharegroup_uuid", + "sharegroup_uuid", + "sharegroup_label", + ] + assert_headers_in_lines(headers, lines) + + +def test_try_to_list_all_shared_images_for_invalid_token(): + result = exec_failing_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "images-list-by-token", + "notExistingToken", + "--delimiter", + ",", + "--text", + ], + expected_code=ExitCodes.REQUEST_FAILED, + ) + assert "Request failed: 404" in result + assert "Not found" in result + + +def test_try_gets_details_about_your_share_group_for_invalid_token(): + result = exec_failing_test_command( + BASE_CMDS["image-sharegroups"] + + [ + "view-by-token", + "notExistingToken", + "--delimiter", + ",", + "--text", + "--no-headers", + ], + expected_code=ExitCodes.REQUEST_FAILED, + ) + assert "Request failed: 404" in result + assert "Not found" in result