Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aws
GitHub Repository: aws/aws-cli
Path: blob/develop/tests/unit/customizations/configure/test_writer.py
1569 views
1
# Copyright 2016 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 tempfile
15
import shutil
16
17
from awscli.customizations.configure.writer import ConfigFileWriter
18
from awscli.testutils import unittest, skip_if_windows
19
20
21
class TestConfigFileWriter(unittest.TestCase):
22
23
def setUp(self):
24
self.dirname = tempfile.mkdtemp()
25
self.config_filename = os.path.join(self.dirname, 'config')
26
self.writer = ConfigFileWriter()
27
28
def tearDown(self):
29
shutil.rmtree(self.dirname)
30
31
def assert_update_config(self, original_config_contents, updated_data,
32
updated_config_contents):
33
# Given the original_config, when it's updated with update_data,
34
# it should produce updated_config_contents.
35
with open(self.config_filename, 'w') as f:
36
f.write(original_config_contents)
37
self.writer.update_config(updated_data, self.config_filename)
38
with open(self.config_filename, 'r') as f:
39
new_contents = f.read()
40
if new_contents != updated_config_contents:
41
self.fail("Config file contents do not match.\n"
42
"Expected contents:\n"
43
"%s\n\n"
44
"Actual Contents:\n"
45
"%s\n" % (updated_config_contents, new_contents))
46
47
def test_update_single_existing_value(self):
48
original = '[default]\nfoo = 1\nbar = 1'
49
updated = '[default]\nfoo = newvalue\nbar = 1'
50
self.assert_update_config(
51
original, {'foo': 'newvalue'}, updated)
52
53
def test_update_value_with_square_brackets(self):
54
original = '[default]\nfoo = old[value]\nbar = 1'
55
updated = '[default]\nfoo = new[value]\nbar = 1'
56
self.assert_update_config(
57
original, {'foo': 'new[value]'}, updated)
58
59
def test_update_single_existing_value_no_spaces(self):
60
original = '[default]\nfoo=1\nbar=1'
61
updated = '[default]\nfoo = newvalue\nbar=1'
62
self.assert_update_config(
63
original, {'foo': 'newvalue'}, updated)
64
65
def test_update_single_new_values(self):
66
expected = '[default]\nfoo = 1\nbar = 2\nbaz = newvalue\n'
67
self.assert_update_config(
68
'[default]\nfoo = 1\nbar = 2',
69
{'baz': 'newvalue'}, expected)
70
71
def test_handles_no_spaces(self):
72
expected = '[default]\nfoo=1\nbar=2\nbaz = newvalue\n'
73
self.assert_update_config(
74
'[default]\nfoo=1\nbar=2',
75
{'baz': 'newvalue'}, expected)
76
77
def test_insert_values_in_middle_section(self):
78
original_contents = (
79
'[a]\n'
80
'foo = bar\n'
81
'baz = bar\n'
82
'\n'
83
'[b]\n'
84
'\n'
85
'foo = bar\n'
86
'[c]\n'
87
'foo = bar\n'
88
'baz = bar\n'
89
)
90
expected_contents = (
91
'[a]\n'
92
'foo = bar\n'
93
'baz = bar\n'
94
'\n'
95
'[b]\n'
96
'\n'
97
'foo = newvalue\n'
98
'[c]\n'
99
'foo = bar\n'
100
'baz = bar\n'
101
)
102
self.assert_update_config(
103
original_contents,
104
{'foo': 'newvalue', '__section__': 'b'},
105
expected_contents)
106
107
def test_insert_new_value_in_middle_section(self):
108
original_contents = (
109
'[a]\n'
110
'foo = bar\n'
111
'\n'
112
'[b]\n'
113
'\n'
114
'foo = bar\n'
115
'\n'
116
'[c]\n'
117
'foo = bar\n'
118
)
119
expected_contents = (
120
'[a]\n'
121
'foo = bar\n'
122
'\n'
123
'[b]\n'
124
'\n'
125
'foo = bar\n'
126
'newvalue = newvalue\n'
127
'\n'
128
'[c]\n'
129
'foo = bar\n'
130
)
131
self.assert_update_config(
132
original_contents,
133
{'newvalue': 'newvalue', '__section__': 'b'},
134
expected_contents)
135
136
def test_new_config_file(self):
137
self.assert_update_config(
138
'\n',
139
{'foo': 'value'},
140
'\n[default]\nfoo = value\n')
141
142
def test_section_does_not_exist(self):
143
original_contents = (
144
'[notdefault]\n'
145
'foo = bar\n'
146
'baz = bar\n'
147
'\n'
148
'\n'
149
'\n'
150
'[other "section"]\n'
151
'\n'
152
'foo = bar\n'
153
)
154
appended_contents = (
155
'[default]\n'
156
'foo = value\n'
157
)
158
self.assert_update_config(
159
original_contents,
160
{'foo': 'value'},
161
original_contents + appended_contents)
162
163
def test_config_file_does_not_exist(self):
164
self.writer.update_config({'foo': 'value'}, self.config_filename)
165
with open(self.config_filename, 'r') as f:
166
new_contents = f.read()
167
self.assertEqual(new_contents, '[default]\nfoo = value\n')
168
169
@skip_if_windows("Test not valid on windows.")
170
def test_permissions_on_new_file(self):
171
self.writer.update_config({'foo': 'value'}, self.config_filename)
172
with open(self.config_filename, 'r') as f:
173
f.read()
174
self.assertEqual(os.stat(self.config_filename).st_mode & 0xFFF, 0o600)
175
176
def test_update_config_with_comments(self):
177
original = (
178
'[default]\n'
179
'#foo = 1\n'
180
'bar = 1\n'
181
)
182
self.assert_update_config(
183
original, {'foo': 'newvalue'},
184
'[default]\n'
185
'#foo = 1\n'
186
'bar = 1\n'
187
'foo = newvalue\n'
188
)
189
190
def test_update_config_with_commented_section(self):
191
original = (
192
'#[default]\n'
193
'[default]\n'
194
'#foo = 1\n'
195
'bar = 1\n'
196
)
197
self.assert_update_config(
198
original, {'foo': 'newvalue'},
199
'#[default]\n'
200
'[default]\n'
201
'#foo = 1\n'
202
'bar = 1\n'
203
'foo = newvalue\n'
204
)
205
206
def test_spaces_around_key_names(self):
207
original = (
208
'[default]\n'
209
'foo = 1\n'
210
'bar = 1\n'
211
)
212
self.assert_update_config(
213
original, {'foo': 'newvalue'},
214
'[default]\n'
215
'foo = newvalue\n'
216
'bar = 1\n'
217
)
218
219
def test_unquoted_profile_name(self):
220
original = (
221
'[profile foobar]\n'
222
'foo = 1\n'
223
'bar = 1\n'
224
)
225
self.assert_update_config(
226
original, {'foo': 'newvalue', '__section__': 'profile foobar'},
227
'[profile foobar]\n'
228
'foo = newvalue\n'
229
'bar = 1\n'
230
)
231
232
def test_double_quoted_profile_name(self):
233
original = (
234
'[profile "foobar"]\n'
235
'foo = 1\n'
236
'bar = 1\n'
237
)
238
self.assert_update_config(
239
original, {'foo': 'newvalue', '__section__': 'profile foobar'},
240
'[profile "foobar"]\n'
241
'foo = newvalue\n'
242
'bar = 1\n'
243
)
244
245
def test_profile_with_multiple_spaces(self):
246
original = (
247
'[profile "two spaces"]\n'
248
'foo = 1\n'
249
'bar = 1\n'
250
)
251
self.assert_update_config(
252
original, {
253
'foo': 'newvalue', '__section__': 'profile two spaces'},
254
'[profile "two spaces"]\n'
255
'foo = newvalue\n'
256
'bar = 1\n'
257
)
258
259
def test_nested_attributes_new_file(self):
260
original = ''
261
self.assert_update_config(
262
original, {'__section__': 'default',
263
's3': {'signature_version': 's3v4'}},
264
'[default]\n'
265
's3 =\n'
266
' signature_version = s3v4\n')
267
268
def test_add_to_nested_with_nested_in_the_middle(self):
269
original = (
270
'[default]\n'
271
's3 =\n'
272
' other = foo\n'
273
'ec2 = bar\n'
274
)
275
self.assert_update_config(
276
original, {'__section__': 'default',
277
's3': {'signature_version': 'newval'}},
278
'[default]\n'
279
's3 =\n'
280
' other = foo\n'
281
' signature_version = newval\n'
282
'ec2 = bar\n')
283
284
def test_add_to_nested_with_nested_in_the_end(self):
285
original = (
286
'[default]\n'
287
's3 =\n'
288
' other = foo\n'
289
)
290
self.assert_update_config(
291
original, {'__section__': 'default',
292
's3': {'signature_version': 'newval'}},
293
'[default]\n'
294
's3 =\n'
295
' other = foo\n'
296
' signature_version = newval\n')
297
298
def test_update_nested_attribute(self):
299
original = (
300
'[default]\n'
301
's3 =\n'
302
' signature_version = originalval\n'
303
)
304
self.assert_update_config(
305
original, {'__section__': 'default',
306
's3': {'signature_version': 'newval'}},
307
'[default]\n'
308
's3 =\n'
309
' signature_version = newval\n')
310
311
def test_updated_nested_attribute_new_section(self):
312
original = (
313
'[default]\n'
314
's3 =\n'
315
' other = foo\n'
316
'[profile foo]\n'
317
'foo = bar\n'
318
)
319
self.assert_update_config(
320
original, {'__section__': 'default',
321
's3': {'signature_version': 'newval'}},
322
'[default]\n'
323
's3 =\n'
324
' other = foo\n'
325
' signature_version = newval\n'
326
'[profile foo]\n'
327
'foo = bar\n')
328
329
def test_update_nested_attr_no_prior_nesting(self):
330
original = (
331
'[default]\n'
332
'foo = bar\n'
333
'[profile foo]\n'
334
'foo = bar\n'
335
)
336
self.assert_update_config(
337
original, {'__section__': 'default',
338
's3': {'signature_version': 'newval'}},
339
'[default]\n'
340
'foo = bar\n'
341
's3 =\n'
342
' signature_version = newval\n'
343
'[profile foo]\n'
344
'foo = bar\n')
345
346
def test_can_handle_empty_section(self):
347
original = (
348
'[default]\n'
349
'[preview]\n'
350
'cloudfront = true\n'
351
)
352
self.assert_update_config(
353
original, {'region': 'us-west-2', '__section__': 'default'},
354
'[default]\n'
355
'region = us-west-2\n'
356
'[preview]\n'
357
'cloudfront = true\n'
358
)
359
360
def test_appends_newline_on_new_section(self):
361
original = (
362
'[preview]\n'
363
'cloudfront = true'
364
)
365
self.assert_update_config(
366
original, {'region': 'us-west-2', '__section__': 'new-section'},
367
'[preview]\n'
368
'cloudfront = true\n'
369
'[new-section]\n'
370
'region = us-west-2\n'
371
)
372
373