From: Steven Hardy Date: Thu, 23 Aug 2012 17:21:07 +0000 (+0100) Subject: heat API : Add api.aws.utils.extract_param_list X-Git-Tag: 2014.1~1503 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=7ff3bde24c40a94a1485d47d4a2865a5e018f358;p=openstack-build%2Fheat-build.git heat API : Add api.aws.utils.extract_param_list Add new common helper function which extracts AWS parameter lists Change-Id: Ic77ff6014a4f39d4fb5d59a1391f87cdd94f0f7f Signed-off-by: Steven Hardy --- diff --git a/heat/api/aws/utils.py b/heat/api/aws/utils.py index afce0a94..aecc509f 100644 --- a/heat/api/aws/utils.py +++ b/heat/api/aws/utils.py @@ -68,6 +68,52 @@ def extract_param_pairs(params, prefix='', keyname='', valuename=''): return dict(get_param_pairs()) +def extract_param_list(params, prefix=''): + """ + Extract a list-of-dicts based on parameters containing AWS style list + + MetricData.member.1.MetricName=buffers + MetricData.member.1.Unit=Bytes + MetricData.member.1.Value=231434333 + MetricData.member.2.MetricName=buffers2 + MetricData.member.2.Unit=Bytes + MetricData.member.2.Value=12345 + + This can be extracted by passing prefix=MetricData, resulting in a + list containing two dicts + """ + + key_re = re.compile(r"%s\.member\.([0-9]*?)\.(.*?)$" % (prefix)) + result = [] + for k in params: + keymatch = key_re.match(k) + if keymatch: + try: + index = int(keymatch.group(1)) + except ValueError: + # Regex match should mean this never happens.. + logger.error('Could not extract index %s' % keymatch.group(1)) + continue + + key = keymatch.group(2) + try: + value = params[k] + except KeyError: + logger.error('Could not extract parameter for %s' % key) + continue + + # We can't rely on list indexes being in-order, so + # populate the list with empty dicts up to the current + # index value if index > current list length + # We then merge the result into the appropriate dict + if index > len(result): + while len(result) < index: + result.append({}) + result[index - 1].update({key: value}) + + return result + + def reformat_dict_keys(keymap={}, inputdict={}): ''' Utility function for mapping one dict format to another diff --git a/heat/tests/test_api_aws.py b/heat/tests/test_api_aws.py index 40c8f085..ba3bf1f6 100644 --- a/heat/tests/test_api_aws.py +++ b/heat/tests/test_api_aws.py @@ -92,6 +92,97 @@ class AWSCommon(unittest.TestCase): valuename='ParameterValue') self.assertFalse(params) + def test_extract_param_list(self): + p = {'MetricData.member.1.MetricName': 'foo', + 'MetricData.member.1.Unit': 'Bytes', + 'MetricData.member.1.Value': 234333} + params = api_utils.extract_param_list(p, prefix='MetricData') + self.assertEqual(len(params), 1) + self.assertTrue('MetricName' in params[0]) + self.assertTrue('Unit' in params[0]) + self.assertTrue('Value' in params[0]) + self.assertEqual(params[0]['MetricName'], 'foo') + self.assertEqual(params[0]['Unit'], 'Bytes') + self.assertEqual(params[0]['Value'], 234333) + + def test_extract_param_list_garbage_prefix(self): + p = {'AMetricData.member.1.MetricName': 'foo', + 'MetricData.member.1.Unit': 'Bytes', + 'MetricData.member.1.Value': 234333} + params = api_utils.extract_param_list(p, prefix='MetricData') + self.assertEqual(len(params), 1) + self.assertTrue('MetricName' not in params[0]) + self.assertTrue('Unit' in params[0]) + self.assertTrue('Value' in params[0]) + self.assertEqual(params[0]['Unit'], 'Bytes') + self.assertEqual(params[0]['Value'], 234333) + + def test_extract_param_list_garbage_prefix2(self): + p = {'AMetricData.member.1.MetricName': 'foo', + 'BMetricData.member.1.Unit': 'Bytes', + 'CMetricData.member.1.Value': 234333} + params = api_utils.extract_param_list(p, prefix='MetricData') + self.assertEqual(len(params), 0) + + def test_extract_param_list_garbage_suffix(self): + p = {'MetricData.member.1.AMetricName': 'foo', + 'MetricData.member.1.Unit': 'Bytes', + 'MetricData.member.1.Value': 234333} + params = api_utils.extract_param_list(p, prefix='MetricData') + self.assertEqual(len(params), 1) + self.assertTrue('MetricName' not in params[0]) + self.assertTrue('Unit' in params[0]) + self.assertTrue('Value' in params[0]) + self.assertEqual(params[0]['Unit'], 'Bytes') + self.assertEqual(params[0]['Value'], 234333) + + def test_extract_param_list_multiple(self): + p = {'MetricData.member.1.MetricName': 'foo', + 'MetricData.member.1.Unit': 'Bytes', + 'MetricData.member.1.Value': 234333, + 'MetricData.member.2.MetricName': 'foo2', + 'MetricData.member.2.Unit': 'Bytes', + 'MetricData.member.2.Value': 12345} + params = api_utils.extract_param_list(p, prefix='MetricData') + self.assertEqual(len(params), 2) + self.assertTrue('MetricName' in params[0]) + self.assertTrue('MetricName' in params[1]) + self.assertEqual(params[0]['MetricName'], 'foo') + self.assertEqual(params[0]['Unit'], 'Bytes') + self.assertEqual(params[0]['Value'], 234333) + self.assertEqual(params[1]['MetricName'], 'foo2') + self.assertEqual(params[1]['Unit'], 'Bytes') + self.assertEqual(params[1]['Value'], 12345) + + def test_extract_param_list_multiple_missing(self): + # Handle case where there is an empty list item + p = {'MetricData.member.1.MetricName': 'foo', + 'MetricData.member.1.Unit': 'Bytes', + 'MetricData.member.1.Value': 234333, + 'MetricData.member.3.MetricName': 'foo2', + 'MetricData.member.3.Unit': 'Bytes', + 'MetricData.member.3.Value': 12345} + params = api_utils.extract_param_list(p, prefix='MetricData') + self.assertEqual(len(params), 3) + self.assertTrue('MetricName' in params[0]) + self.assertTrue('MetricName' in params[2]) + self.assertEqual(params[0]['MetricName'], 'foo') + self.assertEqual(params[0]['Unit'], 'Bytes') + self.assertEqual(params[0]['Value'], 234333) + self.assertEqual(params[2]['MetricName'], 'foo2') + self.assertEqual(params[2]['Unit'], 'Bytes') + self.assertEqual(params[2]['Value'], 12345) + + def test_extract_param_list_badindex(self): + p = {'MetricData.member.xyz.MetricName': 'foo', + 'MetricData.member.$!&^.Unit': 'Bytes', + 'MetricData.member.+.Value': 234333, + 'MetricData.member.--.MetricName': 'foo2', + 'MetricData.member._3.Unit': 'Bytes', + 'MetricData.member.-1000.Value': 12345} + params = api_utils.extract_param_list(p, prefix='MetricData') + self.assertEqual(len(params), 0) + def test_reformat_dict_keys(self): keymap = {"foo": "bar"} data = {"foo": 123}