Skip to content

Commit

Permalink
Add inline json support and functional tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Illia Batozskyi committed Aug 6, 2020
1 parent e713790 commit 8175c75
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 2 deletions.
15 changes: 13 additions & 2 deletions awscli/customizations/cloudformation/deploy.py
Expand Up @@ -390,9 +390,20 @@ def _codepipeline_param_parser(self, data):
if isinstance(data, dict):
return data.get('Parameters', None)

def _parse_input_as_json(self, arg_value):
# In case of inline json input it'll be list where json string
# will be the first element
if arg_value:
if isinstance(arg_value, str):
return json.loads(arg_value)
try:
return json.loads(arg_value[0])
except json.JSONDecodeError:
return None

def parse_parameter_overrides(self, arg_value):
if isinstance(arg_value, str):
data = json.loads(arg_value)
data = self._parse_input_as_json(arg_value)
if data is not None:
parsers = [
self._cf_param_parser,
self._codepipeline_param_parser,
Expand Down
119 changes: 119 additions & 0 deletions tests/functional/cloudformation/test_deploy.py
Expand Up @@ -60,3 +60,122 @@ def test_does_return_zero_exit_code_on_empty_changeset(self):
def test_does_return_non_zero_exit_code_on_empty_changeset(self):
self.command += ' --fail-on-empty-changeset'
self.run_cmd(self.command, expected_rc=255)


class TestDeployCommandParameterOverrides(TestDeployCommand):
def setUp(self):
super(TestDeployCommandParameterOverrides, self).setUp()
template = '''{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters": {
"Key1": {
"Type": "String"
},
"Key2": {
"Type": "String"
}
}
}'''
path = self.files.create_file('template.json', template)
self.command = (
'cloudformation deploy --template-file %s '
'--stack-name Stack '
) % path

def _assert_parameters_parsed(self):
self.assertEqual(
self.operations_called[1][1]['Parameters'],
[
{'ParameterKey': 'Key1', 'ParameterValue': 'Value1'},
{'ParameterKey': 'Key2', 'ParameterValue': 'Value2'}
]
)

def test_parameter_overrides_shorthand(self):
self.command += ' --parameter-overrides Key1=Value1 Key2=Value2'
self.run_cmd(self.command)
self._assert_parameters_parsed()

def test_parameter_overrides_from_inline_original_json(self):
original_like_json = '["Key1=Value1","Key2=Value2"]'
path = self.files.create_file('param.json', original_like_json)
self.command += ' --parameter-overrides file://%s' % path
self.run_cmd(self.command)
self._assert_parameters_parsed()

def test_parameter_overrides_from_inline_cf_like_json(self):
cf_like_json = ('[{"ParameterKey":"Key1",'
'"ParameterValue":"Value1"},'
'{"ParameterKey":"Key2",'
'"ParameterValue":"Value2"}]')
self.command += ' --parameter-overrides %s' % cf_like_json
self.run_cmd(self.command)
self._assert_parameters_parsed()

def test_parameter_overrides_from_cf_like_json_file(self):
cf_like_json = '''
[
{"ParameterKey": "Key1", "ParameterValue": "Value1"},
{"ParameterKey": "Key2", "ParameterValue": "Value2"}
]
'''
path = self.files.create_file('param.json', cf_like_json)
self.command += ' --parameter-overrides file://%s' % path
self.run_cmd(self.command)
self._assert_parameters_parsed()

def test_parameter_overrides_from_invalid_cf_like_json_file(self):
cf_like_json = '''
[
{"ParameterKey": "Key1",
"ParameterValue": "Value1",
"RedundantKey": "RedundantValue"
},
{"ParameterKey": "Key2", "ParameterValue": "Value2"}
]
'''
path = self.files.create_file('param.json', cf_like_json)
self.command += ' --parameter-overrides file://%s' % path
_, err, _ = self.run_cmd(self.command, expected_rc=252)
self.assertTrue('CloudFormation like parameter JSON should have format'
in err)

def test_parameter_overrides_from_inline_codepipeline_like_json(self):
codepipeline_like_json = ('{"Parameters":{"Key1":"Value1",'
'"Key2":"Value2"}}')
self.command += ' --parameter-overrides %s' % codepipeline_like_json
self.run_cmd(self.command)
self._assert_parameters_parsed()

def test_parameter_overrides_from_codepipeline_like_json_file(self):
codepipeline_like_json = '''
{
"Parameters":
{"Key1": "Value1",
"Key2": "Value2"}
}
'''
path = self.files.create_file('param.json', codepipeline_like_json)
self.command += ' --parameter-overrides file://%s' % path
self.run_cmd(self.command)
self._assert_parameters_parsed()

def test_parameter_overrides_from_original_json_file(self):
original_like_json = '''
[
"Key1=Value1",
"Key2=Value2"
]
'''
path = self.files.create_file('param.json', original_like_json)
self.command += ' --parameter-overrides file://%s' % path
self.run_cmd(self.command, expected_rc=0)
self._assert_parameters_parsed()

def test_parameter_overrides_from_random_invalid_json(self):
cf_like_json = '{"SomeKey":[{"RedundantKey": "RedundantValue"}]}'
path = self.files.create_file('param.json', cf_like_json)
self.command += ' --parameter-overrides file://%s' % path
_, err, _ = self.run_cmd(self.command, expected_rc=255)
self.assertTrue("['SomeKey'] value passed to --parameter-overrides"
in err)
12 changes: 12 additions & 0 deletions tests/unit/customizations/cloudformation/test_deploy.py
Expand Up @@ -473,6 +473,18 @@ def test_parse_parameter_override_with_deploy_data_format_from_file(self):
result = self.deploy_command.parse_parameter_overrides(data)
self.assertEqual(result, output)

def test_parse_parameter_override_with_inline_json(self):
data = [json.dumps([
'Key1=Value1',
'Key2=[1,2,3]',
'Key3={"a":"val", "b": 2}'
])]
output = {"Key1": "Value1",
"Key2": '[1,2,3]',
"Key3": '{"a":"val", "b": 2}'}
result = self.deploy_command.parse_parameter_overrides(data)
self.assertEqual(result, output)

def test_parse_parameter_override_with_deploy_data_format(self):
"""
Tests that we can parse parameter arguments in
Expand Down

0 comments on commit 8175c75

Please sign in to comment.