From a06adda886efc727ded149ac33c13fef3719fd34 Mon Sep 17 00:00:00 2001 From: Daniel Mil Date: Tue, 20 Sep 2022 14:54:21 -0700 Subject: [PATCH 1/4] Function for cleaning layer reference list --- .../terraform/hooks/prepare/__init__.py | 0 .../terraform/hooks/prepare/layer_linking.py | 34 +++++++++++++++ .../terraform/test_layer_linking.py | 43 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 samcli/hook_packages/terraform/hooks/prepare/__init__.py create mode 100644 samcli/hook_packages/terraform/hooks/prepare/layer_linking.py create mode 100644 tests/unit/hook_packages/terraform/test_layer_linking.py diff --git a/samcli/hook_packages/terraform/hooks/prepare/__init__.py b/samcli/hook_packages/terraform/hooks/prepare/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/samcli/hook_packages/terraform/hooks/prepare/layer_linking.py b/samcli/hook_packages/terraform/hooks/prepare/layer_linking.py new file mode 100644 index 0000000000..ba5357c146 --- /dev/null +++ b/samcli/hook_packages/terraform/hooks/prepare/layer_linking.py @@ -0,0 +1,34 @@ +from typing import List + + +def _clean_references_list(references: List[str]) -> List[str]: + """ + Return a new copy of the complete references list. + + e.g. given a list of references like + [ + 'aws_lambda_layer_version.layer1[0].arn', + 'aws_lambda_layer_version.layer1[0]', + 'aws_lambda_layer_version.layer1', + ] + We want only the first complete reference ('aws_lambda_layer_version.layer1[0].arn') + + Parameters + ---------- + references: List[str] + A list of reference strings + + Returns + ------- + List[str] + A copy of a cleaned list of reference strings + """ + cleaned_references = [] + references.sort(reverse=True) + if not references: + return [] + cleaned_references.append(references[0]) + for i in range(1, len(references)): + if not cleaned_references[-1].startswith(references[i]): + cleaned_references.append(references[i]) + return cleaned_references diff --git a/tests/unit/hook_packages/terraform/test_layer_linking.py b/tests/unit/hook_packages/terraform/test_layer_linking.py new file mode 100644 index 0000000000..fe48e31068 --- /dev/null +++ b/tests/unit/hook_packages/terraform/test_layer_linking.py @@ -0,0 +1,43 @@ +from unittest import TestCase + +from nose_parameterized import parameterized + +from samcli.hook_packages.terraform.hooks.prepare.layer_linking import _clean_references_list + + +class TestLayerLinking(TestCase): + @parameterized.expand( + [ + ([], []), + (["aws_lambda_layer_version.layer1[0].arn"], ["aws_lambda_layer_version.layer1[0].arn"]), + (["aws_lambda_layer_version.layer1[0]"], ["aws_lambda_layer_version.layer1[0]"]), + (["aws_lambda_layer_version.layer1"], ["aws_lambda_layer_version.layer1"]), + ( + [ + "aws_lambda_layer_version.layer1[0].arn", + "aws_lambda_layer_version.layer1[0]", + "aws_lambda_layer_version.layer1", + ], + ["aws_lambda_layer_version.layer1[0].arn"], + ), + ( + [ + "aws_lambda_layer_version.layer1[0].arn", + "aws_lambda_layer_version.layer1[0]", + "aws_lambda_layer_version.layer1", + "module.const_layer1.layer_arn", + "module.const_layer1", + "module.const_layer2.layer_arn", + "module.const_layer2", + ], + [ + "module.const_layer2.layer_arn", + "module.const_layer1.layer_arn", + "aws_lambda_layer_version.layer1[0].arn", + ], + ), + ] + ) + def test_clean_references_list(self, references, expected): + cleaned_references = _clean_references_list(references) + self.assertEqual(cleaned_references, expected) From 6b9569f43d6f100f0ce7301791ab8ede7fdd355a Mon Sep 17 00:00:00 2001 From: Daniel Mil Date: Wed, 21 Sep 2022 09:48:45 -0700 Subject: [PATCH 2/4] Merge from upstream --- .../hook_packages/terraform/hooks/prepare/layer_linking.py | 5 +++++ tests/unit/hook_packages/terraform/test_layer_linking.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/samcli/hook_packages/terraform/hooks/prepare/layer_linking.py b/samcli/hook_packages/terraform/hooks/prepare/layer_linking.py index ba5357c146..f59b75c973 100644 --- a/samcli/hook_packages/terraform/hooks/prepare/layer_linking.py +++ b/samcli/hook_packages/terraform/hooks/prepare/layer_linking.py @@ -1,3 +1,8 @@ +""" +Use Terraform plan to link resources together +e.g. linking layers to functions +""" + from typing import List diff --git a/tests/unit/hook_packages/terraform/test_layer_linking.py b/tests/unit/hook_packages/terraform/test_layer_linking.py index fe48e31068..12a30fe6cf 100644 --- a/tests/unit/hook_packages/terraform/test_layer_linking.py +++ b/tests/unit/hook_packages/terraform/test_layer_linking.py @@ -1,6 +1,6 @@ from unittest import TestCase -from nose_parameterized import parameterized +from parameterized import parameterized from samcli.hook_packages.terraform.hooks.prepare.layer_linking import _clean_references_list From fcef01fbac4a5ff1f39919eed0612fda8b33ffe7 Mon Sep 17 00:00:00 2001 From: Daniel Mil Date: Wed, 21 Sep 2022 10:35:43 -0700 Subject: [PATCH 3/4] Add test case for for each --- tests/unit/hook_packages/terraform/test_layer_linking.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/unit/hook_packages/terraform/test_layer_linking.py b/tests/unit/hook_packages/terraform/test_layer_linking.py index 12a30fe6cf..363c145ecd 100644 --- a/tests/unit/hook_packages/terraform/test_layer_linking.py +++ b/tests/unit/hook_packages/terraform/test_layer_linking.py @@ -36,6 +36,14 @@ class TestLayerLinking(TestCase): "aws_lambda_layer_version.layer1[0].arn", ], ), + ( + [ + 'aws_lambda_layer_version.layer1["key1"].arn', + 'aws_lambda_layer_version.layer1["key1"]', + "aws_lambda_layer_version.layer1", + ], + ['aws_lambda_layer_version.layer1["key1"].arn'] + ), ] ) def test_clean_references_list(self, references, expected): From a66c722682c6864f74ceb4b76570cdd2b647a68d Mon Sep 17 00:00:00 2001 From: Daniel Mil Date: Wed, 21 Sep 2022 11:28:26 -0700 Subject: [PATCH 4/4] Don't mutate existing reference list --- .../terraform/hooks/prepare/layer_linking.py | 10 +++++----- .../terraform/test_layer_linking.py | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/samcli/hook_packages/terraform/hooks/prepare/layer_linking.py b/samcli/hook_packages/terraform/hooks/prepare/layer_linking.py index f59b75c973..729f4e4834 100644 --- a/samcli/hook_packages/terraform/hooks/prepare/layer_linking.py +++ b/samcli/hook_packages/terraform/hooks/prepare/layer_linking.py @@ -29,11 +29,11 @@ def _clean_references_list(references: List[str]) -> List[str]: A copy of a cleaned list of reference strings """ cleaned_references = [] - references.sort(reverse=True) + copied_references = sorted(references, reverse=True) if not references: return [] - cleaned_references.append(references[0]) - for i in range(1, len(references)): - if not cleaned_references[-1].startswith(references[i]): - cleaned_references.append(references[i]) + cleaned_references.append(copied_references[0]) + for i in range(1, len(copied_references)): + if not cleaned_references[-1].startswith(copied_references[i]): + cleaned_references.append(copied_references[i]) return cleaned_references diff --git a/tests/unit/hook_packages/terraform/test_layer_linking.py b/tests/unit/hook_packages/terraform/test_layer_linking.py index 363c145ecd..d3b9c7a015 100644 --- a/tests/unit/hook_packages/terraform/test_layer_linking.py +++ b/tests/unit/hook_packages/terraform/test_layer_linking.py @@ -1,3 +1,4 @@ +from copy import deepcopy from unittest import TestCase from parameterized import parameterized @@ -42,10 +43,25 @@ class TestLayerLinking(TestCase): 'aws_lambda_layer_version.layer1["key1"]', "aws_lambda_layer_version.layer1", ], - ['aws_lambda_layer_version.layer1["key1"].arn'] + ['aws_lambda_layer_version.layer1["key1"].arn'], ), ] ) def test_clean_references_list(self, references, expected): cleaned_references = _clean_references_list(references) self.assertEqual(cleaned_references, expected) + + def test_ensure_original_references_not_mutated(self): + references = [ + "aws_lambda_layer_version.layer1[0].arn", + "aws_lambda_layer_version.layer1[0]", + "aws_lambda_layer_version.layer1", + "module.const_layer1.layer_arn", + "module.const_layer1", + "module.const_layer2.layer_arn", + "module.const_layer2", + ] + original_references = deepcopy(references) + cleaned_references_list = _clean_references_list(references) + self.assertEqual(references, original_references) + self.assertNotEqual(references, cleaned_references_list)