Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aws
GitHub Repository: aws/aws-cli
Path: blob/develop/tests/integration/customizations/test_generatecliskeleton.py
1567 views
1
# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License"). You
4
# may not use this file except in compliance with the License. A copy of
5
# the License is located at
6
#
7
# http://aws.amazon.com/apache2.0/
8
#
9
# or in the "license" file accompanying this file. This file is
10
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
# ANY KIND, either express or implied. See the License for the specific
12
# language governing permissions and limitations under the License.
13
import os
14
import json
15
import logging
16
17
import pytest
18
19
from awscli.testutils import mock, unittest, aws, capture_output
20
from awscli.clidriver import create_clidriver
21
from awscli.customizations.preview import PREVIEW_SERVICES
22
23
24
class TestIntegGenerateCliSkeleton(unittest.TestCase):
25
"""This tests various services to see if the generated skeleton is correct
26
27
The operations and services selected are arbitrary. Tried to pick
28
operations that do not have many input options for the sake of readablity
29
and maintenance. These are essentially smoke tests. It is not trying to
30
test the different types of input shapes that can be generated in the
31
skeleton. It is only testing wheter the skeleton generator argument works
32
for various services.
33
"""
34
def _assert_skeleton_matches(self, actual_skeleton, expected_skeleton):
35
# Assert all expected keys are present, however there may be more
36
# keys in the actual skeleton generated if the API updates
37
for key, value in expected_skeleton.items():
38
self.assertEqual(value, actual_skeleton[key])
39
40
def test_generate_cli_skeleton_s3api(self):
41
p = aws('s3api delete-object --generate-cli-skeleton')
42
self.assertEqual(p.rc, 0)
43
expected_skeleton = {
44
'Bucket': '',
45
'BypassGovernanceRetention': True,
46
'Key': '',
47
'MFA': '',
48
'VersionId': '',
49
'RequestPayer': 'requester',
50
}
51
actual_skeleton = json.loads(p.stdout)
52
self._assert_skeleton_matches(actual_skeleton, expected_skeleton)
53
54
def test_generate_cli_skeleton_sqs(self):
55
p = aws('sqs change-message-visibility --generate-cli-skeleton')
56
self.assertEqual(p.rc, 0)
57
expected_skeleton = {
58
'QueueUrl': '',
59
'ReceiptHandle': '',
60
'VisibilityTimeout': 0,
61
}
62
actual_skeleton = json.loads(p.stdout)
63
self._assert_skeleton_matches(actual_skeleton, expected_skeleton)
64
65
def test_generate_cli_skeleton_iam(self):
66
p = aws('iam create-group --generate-cli-skeleton')
67
self.assertEqual(p.rc, 0)
68
expected_skeleton = {'Path': '', 'GroupName': ''}
69
actual_skeleton = json.loads(p.stdout)
70
self._assert_skeleton_matches(actual_skeleton, expected_skeleton)
71
72
73
def _all_commands():
74
environ = {
75
'AWS_DATA_PATH': os.environ['AWS_DATA_PATH'],
76
'AWS_DEFAULT_REGION': 'us-east-1',
77
'AWS_ACCESS_KEY_ID': 'access_key',
78
'AWS_SECRET_ACCESS_KEY': 'secret_key',
79
'AWS_CONFIG_FILE': '',
80
'AWS_SHARED_CREDENTIALS_FILE': '',
81
}
82
with mock.patch('os.environ', environ):
83
driver = create_clidriver()
84
help_command = driver.create_help_command()
85
for command_name, command_obj in help_command.command_table.items():
86
if command_name in PREVIEW_SERVICES:
87
# Skip over any preview services for now.
88
continue
89
sub_help = command_obj.create_help_command()
90
# This avoids command objects like ``PreviewModeCommand`` that
91
# do not exhibit any visible functionality (i.e. provides a command
92
# for the CLI).
93
if hasattr(sub_help, 'command_table'):
94
for sub_name, sub_command in sub_help.command_table.items():
95
op_help = sub_command.create_help_command()
96
arg_table = op_help.arg_table
97
if 'generate-cli-skeleton' in arg_table:
98
yield command_name, sub_name
99
100
101
@pytest.mark.parametrize(
102
"command_name, operation_name",
103
_all_commands()
104
)
105
def test_can_generate_skeletons_for_all_service_comands(command_name, operation_name):
106
command = '%s %s --generate-cli-skeleton' % (command_name,
107
operation_name)
108
stdout, stderr, _ = _run_cmd(command)
109
# Test that a valid JSON blob is emitted to stdout is valid.
110
try:
111
json.loads(stdout)
112
except ValueError as e:
113
raise AssertionError(
114
f"Could not generate CLI skeleton for command: {command_name} "
115
f"{operation_name}\n stdout:\n{stdout}\nstderr:\n{stderr}\n"
116
)
117
118
119
def _run_cmd(cmd, expected_rc=0):
120
logging.debug("Calling cmd: %s", cmd)
121
# Drivers do not seem to be reusable since the formatters seem to not clear
122
# themselves between runs. This is fine in practice since a driver is only
123
# called once but for tests it means we need to create a new driver for
124
# each test, which is far more heavyweight than it needs to be. Might be
125
# worth seeing if we can make drivers reusable to speed these up generated
126
# tests.
127
driver = create_clidriver()
128
if not isinstance(cmd, list):
129
cmdlist = cmd.split()
130
else:
131
cmdlist = cmd
132
133
with capture_output() as captured:
134
try:
135
rc = driver.main(cmdlist)
136
except SystemExit as e:
137
# We need to catch SystemExit so that we
138
# can get a proper rc and still present the
139
# stdout/stderr to the test runner so we can
140
# figure out what went wrong.
141
rc = e.code
142
stderr = captured.stderr.getvalue()
143
stdout = captured.stdout.getvalue()
144
assert rc == expected_rc, (
145
"Unexpected rc (expected: %s, actual: %s) for command: %s\n"
146
"stdout:\n%sstderr:\n%s" % (expected_rc, rc, cmd, stdout, stderr)
147
)
148
return stdout, stderr, rc
149
150