Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aws
GitHub Repository: aws/aws-cli
Path: blob/develop/tests/unit/customizations/test_arguments.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
15
from awscli.testutils import mock, unittest, FileCreator, skip_if_windows
16
from awscli.testutils import unittest, FileCreator, skip_if_windows
17
from awscli.customizations.arguments import NestedBlobArgumentHoister
18
from awscli.customizations.arguments import OverrideRequiredArgsArgument
19
from awscli.customizations.arguments import StatefulArgument
20
from awscli.customizations.arguments import QueryOutFileArgument
21
from awscli.customizations.arguments import resolve_given_outfile_path
22
from awscli.customizations.arguments import is_parsed_result_successful
23
24
25
class TestOverrideRequiredArgsArgument(unittest.TestCase):
26
def setUp(self):
27
self.session = mock.Mock()
28
self.argument = OverrideRequiredArgsArgument(self.session)
29
30
# Set up a sample argument_table
31
self.argument_table = {}
32
self.mock_arg = mock.Mock()
33
self.mock_arg.required = True
34
self.argument_table['mock-arg'] = self.mock_arg
35
36
def test_register_argument_action(self):
37
register_args = self.session.register.call_args
38
self.assertEqual(register_args[0][0],
39
'before-building-argument-table-parser')
40
self.assertEqual(register_args[0][1],
41
self.argument.override_required_args)
42
43
def test_override_required_args_if_in_cmdline(self):
44
args = ['--no-required-args']
45
self.argument.override_required_args(self.argument_table, args)
46
self.assertFalse(self.mock_arg.required)
47
48
def test_no_override_required_args_if_not_in_cmdline(self):
49
args = []
50
self.argument.override_required_args(self.argument_table, args)
51
self.assertTrue(self.mock_arg.required)
52
53
54
class TestStatefulArgument(unittest.TestCase):
55
def test_persists_value_when_added_to_params(self):
56
self.session = mock.Mock()
57
arg = StatefulArgument('test')
58
arg.add_to_params({}, 'foo')
59
self.assertEqual('foo', arg.value)
60
61
62
class TestArgumentHelpers(unittest.TestCase):
63
def setUp(self):
64
self.files = FileCreator()
65
66
def tearDown(self):
67
self.files.remove_all()
68
69
def test_only_validates_filename_when_set(self):
70
resolve_given_outfile_path(None)
71
72
def test_works_with_valid_filename(self):
73
filename = self.files.create_file('valid', '')
74
self.assertEqual(filename, resolve_given_outfile_path(filename))
75
76
def test_works_with_relative_filename(self):
77
filename = '../valid'
78
self.assertEqual(filename, resolve_given_outfile_path(filename))
79
80
def test_raises_when_cannot_write_to_file(self):
81
filename = os.sep.join(['_path', 'not', '_exist_', 'file.xyz'])
82
with self.assertRaises(ValueError):
83
resolve_given_outfile_path(filename)
84
85
def test_checks_if_valid_result(self):
86
result = {'ResponseMetadata': {'HTTPStatusCode': 200}}
87
self.assertTrue(is_parsed_result_successful(result))
88
89
def test_checks_if_invalid_result(self):
90
result = {'ResponseMetadata': {'HTTPStatusCode': 300}}
91
self.assertFalse(is_parsed_result_successful(result))
92
93
94
class TestQueryFileArgument(unittest.TestCase):
95
def setUp(self):
96
self.files = FileCreator()
97
98
def tearDown(self):
99
self.files.remove_all()
100
101
def test_proxies_to_super_ctor(self):
102
session = mock.Mock()
103
arg = QueryOutFileArgument(session, 'foo', 'bar.baz', 'event', 0o600)
104
self.assertEqual('foo', arg.name)
105
self.assertEqual('bar.baz', arg.query)
106
107
def test_adds_default_help_text(self):
108
session = mock.Mock()
109
arg = QueryOutFileArgument(session, 'foo', 'bar.baz', 'event', 0o600)
110
self.assertEqual(('Saves the command output contents of bar.baz '
111
'to the given filename'), arg.documentation)
112
113
def test_does_not_add_help_text_if_set(self):
114
session = mock.Mock()
115
arg = QueryOutFileArgument(session, 'foo', 'bar.baz', 'event', 0o600,
116
help_text='abc')
117
self.assertEqual('abc', arg.documentation)
118
119
def test_saves_query_to_file(self):
120
outfile = self.files.create_file('not-empty-test', '')
121
session = mock.Mock()
122
arg = QueryOutFileArgument(session, 'foo', 'baz', 'event', 0o600)
123
arg.add_to_params({}, outfile)
124
arg.save_query({'ResponseMetadata': {'HTTPStatusCode': 200},
125
'baz': 'abc123'})
126
with open(outfile) as fp:
127
self.assertEqual('abc123', fp.read())
128
self.assertEqual(1, session.register.call_count)
129
session.register.assert_called_with('event', arg.save_query)
130
131
def test_does_not_save_when_not_set(self):
132
session = mock.Mock()
133
QueryOutFileArgument(session, 'foo', 'baz', 'event', 0o600)
134
self.assertEqual(0, session.register.call_count)
135
136
def test_saves_query_to_file_as_empty_string_when_none_result(self):
137
outfile = self.files.create_file('none-test', '')
138
session = mock.Mock()
139
arg = QueryOutFileArgument(session, 'foo', 'baz', 'event', 0o600)
140
arg.add_to_params({}, outfile)
141
arg.save_query({'ResponseMetadata': {'HTTPStatusCode': 200}})
142
with open(outfile) as fp:
143
self.assertEqual('', fp.read())
144
145
@skip_if_windows("Test not valid on windows.")
146
def test_permissions_on_created_file(self):
147
outfile = self.files.create_file('not-empty-test', '')
148
session = mock.Mock()
149
arg = QueryOutFileArgument(session, 'foo', 'baz', 'event', 0o600)
150
arg.add_to_params({}, outfile)
151
arg.save_query({'ResponseMetadata': {'HTTPStatusCode': 200},
152
'baz': 'abc123'})
153
with open(outfile) as fp:
154
fp.read()
155
self.assertEqual(os.stat(outfile).st_mode & 0xFFF, 0o600)
156
157
158
class TestNestedBlobArgumentHoister(unittest.TestCase):
159
def setUp(self):
160
self.blob_hoister = NestedBlobArgumentHoister(
161
'complexArgX', 'valueY', 'argY', 'argYDoc', '.argYDocAddendum')
162
163
self.arg_table = {
164
'complexArgX': mock.Mock(
165
required=True,
166
documentation='complexArgXDoc',
167
argument_model=mock.Mock(
168
members={
169
'valueY': mock.Mock(
170
type_name='blob',
171
)
172
}
173
)
174
)
175
}
176
177
def test_apply_to_arg_table(self):
178
self.blob_hoister(None, self.arg_table)
179
180
self.assertFalse(self.arg_table['complexArgX'].required)
181
self.assertEqual(
182
self.arg_table['complexArgX'].documentation,
183
'complexArgXDoc.argYDocAddendum')
184
185
argY = self.arg_table['argY']
186
self.assertFalse(argY.required)
187
self.assertEqual(argY.documentation, 'argYDoc')
188
self.assertEqual(argY.argument_model.type_name, 'blob')
189
190
def test_populates_underlying_complex_arg(self):
191
self.blob_hoister(None, self.arg_table)
192
argY = self.arg_table['argY']
193
194
# parameters bag doesn't
195
# already contain 'ComplexArgX'
196
parameters = {
197
'any': 'other',
198
}
199
argY.add_to_params(parameters, 'test-value')
200
self.assertEqual('other', parameters['any'])
201
self.assertEqual('test-value', parameters['ComplexArgX']['valueY'])
202
203
def test_preserves_member_values_in_underlying_complex_arg(self):
204
self.blob_hoister(None, self.arg_table)
205
argY = self.arg_table['argY']
206
207
# parameters bag already contains 'ComplexArgX'
208
# but that does not contain 'valueY'
209
parameters = {
210
'any': 'other',
211
'ComplexArgX': {
212
'another': 'one',
213
}
214
}
215
argY.add_to_params(parameters, 'test-value')
216
self.assertEqual('other', parameters['any'])
217
self.assertEqual('one', parameters['ComplexArgX']['another'])
218
self.assertEqual('test-value', parameters['ComplexArgX']['valueY'])
219
220
def test_overrides_target_member_in_underlying_complex_arg(self):
221
self.blob_hoister(None, self.arg_table)
222
argY = self.arg_table['argY']
223
224
# parameters bag already contains 'ComplexArgX'
225
# and that already contains 'valueY'
226
parameters = {
227
'any': 'other',
228
'ComplexArgX': {
229
'another': 'one',
230
'valueY': 'doomed',
231
}
232
}
233
argY.add_to_params(parameters, 'test-value')
234
self.assertEqual('other', parameters['any'])
235
self.assertEqual('one', parameters['ComplexArgX']['another'])
236
self.assertEqual('test-value', parameters['ComplexArgX']['valueY'])
237
238
def test_not_apply_to_mismatch_arg_type(self):
239
nonmatching_arg_table = {
240
'complexArgX': mock.Mock(
241
required=True,
242
documentation='complexArgXDoc',
243
argument_model=mock.Mock(
244
members={
245
'valueY': mock.Mock(
246
type_name='string',
247
)
248
}
249
)
250
)
251
}
252
253
self.blob_hoister(None, nonmatching_arg_table)
254
255
self.assertTrue(nonmatching_arg_table['complexArgX'].required)
256
self.assertEqual(
257
nonmatching_arg_table['complexArgX'].documentation, 'complexArgXDoc')
258
self.assertFalse('argY' in self.arg_table)
259
260