Path: blob/develop/tests/integration/customizations/test_generatecliskeleton.py
1567 views
# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.1#2# Licensed under the Apache License, Version 2.0 (the "License"). You3# may not use this file except in compliance with the License. A copy of4# the License is located at5#6# http://aws.amazon.com/apache2.0/7#8# or in the "license" file accompanying this file. This file is9# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF10# ANY KIND, either express or implied. See the License for the specific11# language governing permissions and limitations under the License.12import os13import json14import logging1516import pytest1718from awscli.testutils import mock, unittest, aws, capture_output19from awscli.clidriver import create_clidriver20from awscli.customizations.preview import PREVIEW_SERVICES212223class TestIntegGenerateCliSkeleton(unittest.TestCase):24"""This tests various services to see if the generated skeleton is correct2526The operations and services selected are arbitrary. Tried to pick27operations that do not have many input options for the sake of readablity28and maintenance. These are essentially smoke tests. It is not trying to29test the different types of input shapes that can be generated in the30skeleton. It is only testing wheter the skeleton generator argument works31for various services.32"""33def _assert_skeleton_matches(self, actual_skeleton, expected_skeleton):34# Assert all expected keys are present, however there may be more35# keys in the actual skeleton generated if the API updates36for key, value in expected_skeleton.items():37self.assertEqual(value, actual_skeleton[key])3839def test_generate_cli_skeleton_s3api(self):40p = aws('s3api delete-object --generate-cli-skeleton')41self.assertEqual(p.rc, 0)42expected_skeleton = {43'Bucket': '',44'BypassGovernanceRetention': True,45'Key': '',46'MFA': '',47'VersionId': '',48'RequestPayer': 'requester',49}50actual_skeleton = json.loads(p.stdout)51self._assert_skeleton_matches(actual_skeleton, expected_skeleton)5253def test_generate_cli_skeleton_sqs(self):54p = aws('sqs change-message-visibility --generate-cli-skeleton')55self.assertEqual(p.rc, 0)56expected_skeleton = {57'QueueUrl': '',58'ReceiptHandle': '',59'VisibilityTimeout': 0,60}61actual_skeleton = json.loads(p.stdout)62self._assert_skeleton_matches(actual_skeleton, expected_skeleton)6364def test_generate_cli_skeleton_iam(self):65p = aws('iam create-group --generate-cli-skeleton')66self.assertEqual(p.rc, 0)67expected_skeleton = {'Path': '', 'GroupName': ''}68actual_skeleton = json.loads(p.stdout)69self._assert_skeleton_matches(actual_skeleton, expected_skeleton)707172def _all_commands():73environ = {74'AWS_DATA_PATH': os.environ['AWS_DATA_PATH'],75'AWS_DEFAULT_REGION': 'us-east-1',76'AWS_ACCESS_KEY_ID': 'access_key',77'AWS_SECRET_ACCESS_KEY': 'secret_key',78'AWS_CONFIG_FILE': '',79'AWS_SHARED_CREDENTIALS_FILE': '',80}81with mock.patch('os.environ', environ):82driver = create_clidriver()83help_command = driver.create_help_command()84for command_name, command_obj in help_command.command_table.items():85if command_name in PREVIEW_SERVICES:86# Skip over any preview services for now.87continue88sub_help = command_obj.create_help_command()89# This avoids command objects like ``PreviewModeCommand`` that90# do not exhibit any visible functionality (i.e. provides a command91# for the CLI).92if hasattr(sub_help, 'command_table'):93for sub_name, sub_command in sub_help.command_table.items():94op_help = sub_command.create_help_command()95arg_table = op_help.arg_table96if 'generate-cli-skeleton' in arg_table:97yield command_name, sub_name9899100@pytest.mark.parametrize(101"command_name, operation_name",102_all_commands()103)104def test_can_generate_skeletons_for_all_service_comands(command_name, operation_name):105command = '%s %s --generate-cli-skeleton' % (command_name,106operation_name)107stdout, stderr, _ = _run_cmd(command)108# Test that a valid JSON blob is emitted to stdout is valid.109try:110json.loads(stdout)111except ValueError as e:112raise AssertionError(113f"Could not generate CLI skeleton for command: {command_name} "114f"{operation_name}\n stdout:\n{stdout}\nstderr:\n{stderr}\n"115)116117118def _run_cmd(cmd, expected_rc=0):119logging.debug("Calling cmd: %s", cmd)120# Drivers do not seem to be reusable since the formatters seem to not clear121# themselves between runs. This is fine in practice since a driver is only122# called once but for tests it means we need to create a new driver for123# each test, which is far more heavyweight than it needs to be. Might be124# worth seeing if we can make drivers reusable to speed these up generated125# tests.126driver = create_clidriver()127if not isinstance(cmd, list):128cmdlist = cmd.split()129else:130cmdlist = cmd131132with capture_output() as captured:133try:134rc = driver.main(cmdlist)135except SystemExit as e:136# We need to catch SystemExit so that we137# can get a proper rc and still present the138# stdout/stderr to the test runner so we can139# figure out what went wrong.140rc = e.code141stderr = captured.stderr.getvalue()142stdout = captured.stdout.getvalue()143assert rc == expected_rc, (144"Unexpected rc (expected: %s, actual: %s) for command: %s\n"145"stdout:\n%sstderr:\n%s" % (expected_rc, rc, cmd, stdout, stderr)146)147return stdout, stderr, rc148149150