Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2d3c2ca

Browse files
authored
fix snapshot reference replacement replacing parts of the snapshot keys (#9574)
1 parent a3afc5c commit 2d3c2ca

File tree

4 files changed

+40
-19
lines changed

4 files changed

+40
-19
lines changed

‎localstack/testing/snapshots/prototype.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ def add_transformers_list(
9191
for transformer in transformer_list:
9292
self.transformers.append((transformer, priority)) # TODO
9393

94-
def add_transformer(self, transformer: Transformer, *, priority: Optional[int] = 0):
94+
def add_transformer(
95+
self, transformer: Transformer | list[Transformer], *, priority: Optional[int] = 0
96+
):
9597
if isinstance(transformer, list):
9698
self.add_transformers_list(transformer, priority)
9799
else:
@@ -240,18 +242,21 @@ def _transform(self, tmp: dict) -> dict:
240242
if not self.update:
241243
self._remove_skip_verification_paths(tmp)
242244

243-
tmp = json.dumps(tmp, default=str)
244-
for sr in ctx.serialized_replacements:
245-
tmp = sr(tmp)
246-
247-
assert tmp
248-
try:
249-
tmp = json.loads(tmp)
250-
except JSONDecodeError:
251-
SNAPSHOT_LOGGER.error(f"could not decode json-string:\n{tmp}")
252-
return {}
253-
254-
return tmp
245+
replaced_tmp = {}
246+
# avoid replacements in snapshot keys
247+
for key, value in tmp.items():
248+
dumped_value = json.dumps(value, default=str)
249+
for sr in ctx.serialized_replacements:
250+
dumped_value = sr(dumped_value)
251+
252+
assert dumped_value
253+
try:
254+
replaced_tmp[key] = json.loads(dumped_value)
255+
except JSONDecodeError:
256+
SNAPSHOT_LOGGER.error(f"could not decode json-string:\n{tmp}")
257+
return {}
258+
259+
return replaced_tmp
255260

256261
def _order_dict(self, response) -> dict:
257262
if isinstance(response, dict):

‎tests/aws/services/lambda_/test_lambda.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,9 @@ def test_function_state(self, lambda_su_role, snapshot, create_lambda_function_a
263263
)
264264
@pytest.mark.parametrize("function_name_length", [1, 2])
265265
@markers.aws.validated
266-
def test_assume_role(self, create_lambda_function, aws_client, snapshot, function_name_length):
266+
def test_assume_role(
267+
self, create_lambda_function, aws_client, snapshot, function_name_length, account_id
268+
):
267269
"""Motivated by a GitHub issue where a single-character function name fails to start upon invocation
268270
due to an invalid role ARN: https://github.com/localstack/localstack/issues/9016
269271
Notice that the assumed role depends on the length of the function name because single-character functions
@@ -276,8 +278,14 @@ def test_assume_role(self, create_lambda_function, aws_client, snapshot, functio
276278
Unknown whether the 8-character hexadecimal number suffix after "lambda-autogenerated-" follows any pattern.
277279
"""
278280
lambda_autogen_role = "(?<=lambda-autogenerated-)([0-9a-f]{8})"
281+
# avoid any other transformers possible registering reference replacements (especially resource transformer)
282+
snapshot.transformers.clear()
279283
snapshot.add_transformer(
280-
snapshot.transform.regex(lambda_autogen_role, "<lambda-autogenerated-role-prefix>")
284+
[
285+
snapshot.transform.regex(account_id, "1" * 12),
286+
snapshot.transform.regex(lambda_autogen_role, "<lambda-autogenerated-role-prefix>"),
287+
snapshot.transform.regex(r'(?<=/)[a-zA-Z]{1,2}(?="|@)', "<function-name>"),
288+
]
281289
)
282290

283291
# Generate single-character name (matching [a-z]/i)

‎tests/aws/services/lambda_/test_lambda.snapshot.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3456,15 +3456,15 @@
34563456
}
34573457
},
34583458
"tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_assume_role[1]": {
3459-
"recorded-date": "10-10-2023, 14:55:53",
3459+
"recorded-date": "07-11-2023, 17:19:50",
34603460
"recorded-content": {
3461-
"invoke-result-assumed-role-arn": "arn:aws:sts::111111111111:assumed-role/lambda-autogenerated-<lambda-autogenerated-role-prefix>/<resource:1>"
3461+
"invoke-result-assumed-role-arn": "arn:aws:sts::111111111111:assumed-role/lambda-autogenerated-<lambda-autogenerated-role-prefix>/<function-name>@lambda_function"
34623462
}
34633463
},
34643464
"tests/aws/services/lambda_/test_lambda.py::TestLambdaBaseFeatures::test_assume_role[2]": {
3465-
"recorded-date": "10-10-2023, 14:55:58",
3465+
"recorded-date": "07-11-2023, 17:19:54",
34663466
"recorded-content": {
3467-
"invoke-result-assumed-role-arn": "arn:aws:sts::111111111111:assumed-role/lambda-autogenerated-<lambda-autogenerated-role-prefix>/<resource:1>"
3467+
"invoke-result-assumed-role-arn": "arn:aws:sts::111111111111:assumed-role/lambda-autogenerated-<lambda-autogenerated-role-prefix>/<function-name>"
34683468
}
34693469
}
34703470
}

‎tests/unit/utils/testing/test_snapshots.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ def test_match_order_reference_replacement(self):
9393
)
9494
sm._assert_all()
9595

96+
def test_reference_replacement_skip_outer_keys(self):
97+
"""Test if the reference replacement properly skips the snapshot keys on the outermost level"""
98+
sm = SnapshotSession(scope_key="A", verify=True, file_path="", update=False)
99+
sm.add_transformer(TransformerUtility.key_value("name"))
100+
sm.recorded_state = {"key_a": {"name": "<name:1>"}}
101+
sm.match("key_a", {"name": "key"})
102+
sm._assert_all()
103+
96104
def test_replacement_key_value(self):
97105
sm = SnapshotSession(scope_key="A", verify=True, file_path="", update=False)
98106
sm.add_transformer(

0 commit comments

Comments
 (0)