Lambda: allow <fn_name>:<alias_name> (#6977)
This commit is contained in:
parent
5cabac5ccd
commit
d244885dbf
@ -1354,8 +1354,10 @@ class LambdaStorage(object):
|
||||
return None
|
||||
|
||||
def _get_function_aliases(self, function_name: str) -> Dict[str, LambdaAlias]:
|
||||
fn = self.get_function_by_name_or_arn(function_name)
|
||||
return self._aliases[fn.function_arn]
|
||||
fn = self.get_function_by_name_or_arn_with_qualifier(function_name)
|
||||
# Split ARN to retrieve an ARN without a qualifier present
|
||||
[arn, _, _] = self.split_function_arn(fn.function_arn)
|
||||
return self._aliases[arn]
|
||||
|
||||
def delete_alias(self, name: str, function_name: str) -> None:
|
||||
aliases = self._get_function_aliases(function_name)
|
||||
@ -1377,7 +1379,9 @@ class LambdaStorage(object):
|
||||
description: str,
|
||||
routing_config: str,
|
||||
) -> LambdaAlias:
|
||||
fn = self.get_function_by_name_or_arn(function_name, function_version)
|
||||
fn = self.get_function_by_name_or_arn_with_qualifier(
|
||||
function_name, function_version
|
||||
)
|
||||
aliases = self._get_function_aliases(function_name)
|
||||
if name in aliases:
|
||||
arn = f"arn:aws:lambda:{self.region_name}:{self.account_id}:function:{function_name}:{name}"
|
||||
@ -1406,34 +1410,71 @@ class LambdaStorage(object):
|
||||
alias = self.get_alias(name, function_name)
|
||||
|
||||
# errors if new function version doesn't exist
|
||||
self.get_function_by_name_or_arn(function_name, function_version)
|
||||
self.get_function_by_name_or_arn_with_qualifier(function_name, function_version)
|
||||
|
||||
alias.update(description, function_version, routing_config)
|
||||
return alias
|
||||
|
||||
def get_function_by_name(
|
||||
self, name: str, qualifier: Optional[str] = None
|
||||
) -> Optional[LambdaFunction]:
|
||||
def get_function_by_name_forbid_qualifier(self, name: str) -> LambdaFunction:
|
||||
"""
|
||||
Get function by name forbidding a qualifier
|
||||
:raises: UnknownFunctionException if function not found
|
||||
:raises: InvalidParameterValue if qualifier is provided
|
||||
"""
|
||||
|
||||
if name.count(":") == 1:
|
||||
raise InvalidParameterValueException("Cannot provide qualifier")
|
||||
|
||||
if name not in self._functions:
|
||||
return None
|
||||
raise self.construct_unknown_function_exception(name)
|
||||
|
||||
return self._get_latest(name)
|
||||
|
||||
def get_function_by_name_with_qualifier(
|
||||
self, name: str, qualifier: Optional[str] = None
|
||||
) -> LambdaFunction:
|
||||
"""
|
||||
Get function by name with an optional qualifier
|
||||
:raises: UnknownFunctionException if function not found
|
||||
"""
|
||||
|
||||
# Function name may contain an alias
|
||||
# <fn_name>:<alias_name>
|
||||
if ":" in name:
|
||||
# Prefer qualifier in name over qualifier arg
|
||||
[name, qualifier] = name.split(":")
|
||||
|
||||
# Find without qualifier
|
||||
if qualifier is None:
|
||||
return self._get_latest(name)
|
||||
return self.get_function_by_name_forbid_qualifier(name)
|
||||
|
||||
if name not in self._functions:
|
||||
raise self.construct_unknown_function_exception(name, qualifier)
|
||||
|
||||
# Find by latest
|
||||
if qualifier.lower() == "$latest":
|
||||
return self._functions[name]["latest"]
|
||||
|
||||
# Find by version
|
||||
found_version = self._get_version(name, qualifier)
|
||||
if found_version:
|
||||
return found_version
|
||||
|
||||
# Find by alias
|
||||
aliases = self._get_function_aliases(name)
|
||||
|
||||
if qualifier in aliases:
|
||||
alias = aliases[qualifier]
|
||||
return self._get_version(name, alias.function_version)
|
||||
alias_version = aliases[qualifier].function_version
|
||||
|
||||
return None
|
||||
# Find by alias pointing to latest
|
||||
if alias_version.lower() == "$latest":
|
||||
return self._functions[name]["latest"]
|
||||
|
||||
# Find by alias pointing to version
|
||||
found_alias = self._get_version(name, alias_version)
|
||||
if found_alias:
|
||||
return found_alias
|
||||
|
||||
raise self.construct_unknown_function_exception(name, qualifier)
|
||||
|
||||
def list_versions_by_function(self, name: str) -> Iterable[LambdaFunction]:
|
||||
if name not in self._functions:
|
||||
@ -1448,28 +1489,74 @@ class LambdaStorage(object):
|
||||
return sorted(aliases.values(), key=lambda alias: alias.name)
|
||||
|
||||
def get_arn(self, arn: str) -> Optional[LambdaFunction]:
|
||||
[arn_without_qualifier, _, _] = self.split_function_arn(arn)
|
||||
return self._arns.get(arn_without_qualifier, None)
|
||||
|
||||
def split_function_arn(self, arn: str) -> Tuple[str, str, Optional[str]]:
|
||||
"""
|
||||
Handy utility to parse an ARN into:
|
||||
- ARN without qualifier
|
||||
- Function name
|
||||
- Optional qualifier
|
||||
"""
|
||||
qualifier = None
|
||||
# Function ARN may contain an alias
|
||||
# arn:aws:lambda:region:account_id:function:<fn_name>:<alias_name>
|
||||
if ":" in arn.split(":function:")[-1]:
|
||||
qualifier = arn.split(":")[-1]
|
||||
# arn = arn:aws:lambda:region:account_id:function:<fn_name>
|
||||
arn = ":".join(arn.split(":")[0:-1])
|
||||
return self._arns.get(arn, None)
|
||||
name = arn.split(":")[-1]
|
||||
return arn, name, qualifier
|
||||
|
||||
def get_function_by_name_or_arn(
|
||||
def get_function_by_name_or_arn_forbid_qualifier(
|
||||
self, name_or_arn: str
|
||||
) -> LambdaFunction:
|
||||
"""
|
||||
Get function by name or arn forbidding a qualifier
|
||||
:raises: UnknownFunctionException if function not found
|
||||
:raises: InvalidParameterValue if qualifier is provided
|
||||
"""
|
||||
|
||||
if name_or_arn.startswith("arn:aws"):
|
||||
[_, name, qualifier] = self.split_function_arn(name_or_arn)
|
||||
|
||||
if qualifier is not None:
|
||||
raise InvalidParameterValueException("Cannot provide qualifier")
|
||||
|
||||
return self.get_function_by_name_forbid_qualifier(name)
|
||||
else:
|
||||
# name_or_arn is not an arn
|
||||
return self.get_function_by_name_forbid_qualifier(name_or_arn)
|
||||
|
||||
def get_function_by_name_or_arn_with_qualifier(
|
||||
self, name_or_arn: str, qualifier: Optional[str] = None
|
||||
) -> LambdaFunction:
|
||||
fn = self.get_function_by_name(name_or_arn, qualifier) or self.get_arn(
|
||||
name_or_arn
|
||||
)
|
||||
if fn is None:
|
||||
if name_or_arn.startswith("arn:aws"):
|
||||
arn = name_or_arn
|
||||
else:
|
||||
arn = make_function_arn(self.region_name, self.account_id, name_or_arn)
|
||||
if qualifier:
|
||||
"""
|
||||
Get function by name or arn with an optional qualifier
|
||||
:raises: UnknownFunctionException if function not found
|
||||
"""
|
||||
|
||||
if name_or_arn.startswith("arn:aws"):
|
||||
[_, name, qualifier_in_arn] = self.split_function_arn(name_or_arn)
|
||||
return self.get_function_by_name_with_qualifier(
|
||||
name, qualifier_in_arn or qualifier
|
||||
)
|
||||
else:
|
||||
return self.get_function_by_name_with_qualifier(name_or_arn, qualifier)
|
||||
|
||||
def construct_unknown_function_exception(
|
||||
self, name_or_arn: str, qualifier: Optional[str] = None
|
||||
) -> UnknownFunctionException:
|
||||
if name_or_arn.startswith("arn:aws"):
|
||||
arn = name_or_arn
|
||||
else:
|
||||
# name_or_arn is a function name with optional qualifier <func_name>[:<qualifier>]
|
||||
arn = make_function_arn(self.region_name, self.account_id, name_or_arn)
|
||||
# Append explicit qualifier to arn only if the name doesn't already have it
|
||||
if qualifier and ":" not in name_or_arn:
|
||||
arn = f"{arn}:{qualifier}"
|
||||
raise UnknownFunctionException(arn)
|
||||
return fn
|
||||
return UnknownFunctionException(arn)
|
||||
|
||||
def put_function(self, fn: LambdaFunction) -> None:
|
||||
valid_role = re.match(InvalidRoleFormat.pattern, fn.role)
|
||||
@ -1497,7 +1584,7 @@ class LambdaStorage(object):
|
||||
def publish_function(
|
||||
self, name_or_arn: str, description: str = ""
|
||||
) -> Optional[LambdaFunction]:
|
||||
function = self.get_function_by_name_or_arn(name_or_arn)
|
||||
function = self.get_function_by_name_or_arn_forbid_qualifier(name_or_arn)
|
||||
name = function.function_name
|
||||
if name not in self._functions:
|
||||
return None
|
||||
@ -1522,7 +1609,19 @@ class LambdaStorage(object):
|
||||
return fn
|
||||
|
||||
def del_function(self, name_or_arn: str, qualifier: Optional[str] = None) -> None:
|
||||
function = self.get_function_by_name_or_arn(name_or_arn, qualifier)
|
||||
# Qualifier may be explicitly passed or part of function name or ARN, extract it here
|
||||
if name_or_arn.startswith("arn:aws"):
|
||||
# Extract from ARN
|
||||
if ":" in name_or_arn.split(":function:")[-1]:
|
||||
qualifier = name_or_arn.split(":")[-1]
|
||||
else:
|
||||
# Extract from function name
|
||||
if ":" in name_or_arn:
|
||||
qualifier = name_or_arn.split(":")[1]
|
||||
|
||||
function = self.get_function_by_name_or_arn_with_qualifier(
|
||||
name_or_arn, qualifier
|
||||
)
|
||||
name = function.function_name
|
||||
if not qualifier:
|
||||
# Something is still reffing this so delete all arns
|
||||
@ -1534,8 +1633,11 @@ class LambdaStorage(object):
|
||||
|
||||
del self._functions[name]
|
||||
|
||||
elif qualifier == "$LATEST":
|
||||
self._functions[name]["latest"] = None
|
||||
else:
|
||||
if qualifier == "$LATEST":
|
||||
self._functions[name]["latest"] = None
|
||||
else:
|
||||
self._functions[name]["versions"].remove(function)
|
||||
|
||||
# If theres no functions left
|
||||
if (
|
||||
@ -1544,18 +1646,6 @@ class LambdaStorage(object):
|
||||
):
|
||||
del self._functions[name]
|
||||
|
||||
else:
|
||||
fn = self.get_function_by_name(name, qualifier)
|
||||
if fn:
|
||||
self._functions[name]["versions"].remove(fn)
|
||||
|
||||
# If theres no functions left
|
||||
if (
|
||||
not self._functions[name]["versions"]
|
||||
and not self._functions[name]["latest"]
|
||||
):
|
||||
del self._functions[name]
|
||||
|
||||
self._aliases[function.function_arn] = {}
|
||||
|
||||
def all(self) -> Iterable[LambdaFunction]:
|
||||
@ -1783,21 +1873,27 @@ class LambdaBackend(BaseBackend):
|
||||
The Qualifier-parameter is not yet implemented.
|
||||
Function URLs are not yet mocked, so invoking them will fail
|
||||
"""
|
||||
function = self._lambdas.get_function_by_name_or_arn(name_or_arn)
|
||||
function = self._lambdas.get_function_by_name_or_arn_forbid_qualifier(
|
||||
name_or_arn
|
||||
)
|
||||
return function.create_url_config(config)
|
||||
|
||||
def delete_function_url_config(self, name_or_arn: str) -> None:
|
||||
"""
|
||||
The Qualifier-parameter is not yet implemented
|
||||
"""
|
||||
function = self._lambdas.get_function_by_name_or_arn(name_or_arn)
|
||||
function = self._lambdas.get_function_by_name_or_arn_forbid_qualifier(
|
||||
name_or_arn
|
||||
)
|
||||
function.delete_url_config()
|
||||
|
||||
def get_function_url_config(self, name_or_arn: str) -> FunctionUrlConfig:
|
||||
"""
|
||||
The Qualifier-parameter is not yet implemented
|
||||
"""
|
||||
function = self._lambdas.get_function_by_name_or_arn(name_or_arn)
|
||||
function = self._lambdas.get_function_by_name_or_arn_forbid_qualifier(
|
||||
name_or_arn
|
||||
)
|
||||
if not function:
|
||||
raise UnknownFunctionException(arn=name_or_arn)
|
||||
return function.get_url_config()
|
||||
@ -1808,7 +1904,9 @@ class LambdaBackend(BaseBackend):
|
||||
"""
|
||||
The Qualifier-parameter is not yet implemented
|
||||
"""
|
||||
function = self._lambdas.get_function_by_name_or_arn(name_or_arn)
|
||||
function = self._lambdas.get_function_by_name_or_arn_forbid_qualifier(
|
||||
name_or_arn
|
||||
)
|
||||
return function.update_url_config(config)
|
||||
|
||||
def create_event_source_mapping(self, spec: Dict[str, Any]) -> EventSourceMapping:
|
||||
@ -1818,9 +1916,9 @@ class LambdaBackend(BaseBackend):
|
||||
raise RESTError("InvalidParameterValueException", f"Missing {param}")
|
||||
|
||||
# Validate function name
|
||||
func = self._lambdas.get_function_by_name_or_arn(spec.get("FunctionName", ""))
|
||||
if not func:
|
||||
raise RESTError("ResourceNotFoundException", "Invalid FunctionName")
|
||||
func = self._lambdas.get_function_by_name_or_arn_with_qualifier(
|
||||
spec.get("FunctionName", "")
|
||||
)
|
||||
|
||||
# Validate queue
|
||||
sqs_backend = sqs_backends[self.account_id][self.region_name]
|
||||
@ -1887,7 +1985,7 @@ class LambdaBackend(BaseBackend):
|
||||
def get_function(
|
||||
self, function_name_or_arn: str, qualifier: Optional[str] = None
|
||||
) -> LambdaFunction:
|
||||
return self._lambdas.get_function_by_name_or_arn(
|
||||
return self._lambdas.get_function_by_name_or_arn_with_qualifier(
|
||||
function_name_or_arn, qualifier
|
||||
)
|
||||
|
||||
@ -1912,7 +2010,9 @@ class LambdaBackend(BaseBackend):
|
||||
|
||||
for key in spec.keys():
|
||||
if key == "FunctionName":
|
||||
func = self._lambdas.get_function_by_name_or_arn(spec[key])
|
||||
func = self._lambdas.get_function_by_name_or_arn_with_qualifier(
|
||||
spec[key]
|
||||
)
|
||||
esm.function_arn = func.function_arn
|
||||
elif key == "BatchSize":
|
||||
esm.batch_size = spec[key]
|
||||
@ -2025,7 +2125,9 @@ class LambdaBackend(BaseBackend):
|
||||
}
|
||||
]
|
||||
}
|
||||
func = self._lambdas.get_function_by_name_or_arn(function_name, qualifier)
|
||||
func = self._lambdas.get_function_by_name_or_arn_with_qualifier(
|
||||
function_name, qualifier
|
||||
)
|
||||
func.invoke(json.dumps(event), {}, {})
|
||||
|
||||
def send_dynamodb_items(
|
||||
@ -2076,14 +2178,14 @@ class LambdaBackend(BaseBackend):
|
||||
func.invoke(json.dumps(event), {}, {}) # type: ignore[union-attr]
|
||||
|
||||
def list_tags(self, resource: str) -> Dict[str, str]:
|
||||
return self._lambdas.get_function_by_name_or_arn(resource).tags
|
||||
return self._lambdas.get_function_by_name_or_arn_with_qualifier(resource).tags
|
||||
|
||||
def tag_resource(self, resource: str, tags: Dict[str, str]) -> None:
|
||||
fn = self._lambdas.get_function_by_name_or_arn(resource)
|
||||
fn = self._lambdas.get_function_by_name_or_arn_with_qualifier(resource)
|
||||
fn.tags.update(tags)
|
||||
|
||||
def untag_resource(self, resource: str, tagKeys: List[str]) -> None:
|
||||
fn = self._lambdas.get_function_by_name_or_arn(resource)
|
||||
fn = self._lambdas.get_function_by_name_or_arn_with_qualifier(resource)
|
||||
for key in tagKeys:
|
||||
fn.tags.pop(key, None)
|
||||
|
||||
@ -2104,9 +2206,9 @@ class LambdaBackend(BaseBackend):
|
||||
return fn.get_code_signing_config()
|
||||
|
||||
def get_policy(self, function_name: str, qualifier: Optional[str] = None) -> str:
|
||||
fn = self._lambdas.get_function_by_name_or_arn(function_name, qualifier)
|
||||
if not fn:
|
||||
raise UnknownFunctionException(function_name)
|
||||
fn = self._lambdas.get_function_by_name_or_arn_with_qualifier(
|
||||
function_name, qualifier
|
||||
)
|
||||
return fn.policy.wire_format() # type: ignore[union-attr]
|
||||
|
||||
def update_function_code(
|
||||
@ -2125,7 +2227,7 @@ class LambdaBackend(BaseBackend):
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
fn = self.get_function(function_name, qualifier)
|
||||
|
||||
return fn.update_configuration(body) if fn else None
|
||||
return fn.update_configuration(body)
|
||||
|
||||
def invoke(
|
||||
self,
|
||||
@ -2139,12 +2241,9 @@ class LambdaBackend(BaseBackend):
|
||||
Invoking a Function with PackageType=Image is not yet supported.
|
||||
"""
|
||||
fn = self.get_function(function_name, qualifier)
|
||||
if fn:
|
||||
payload = fn.invoke(body, headers, response_headers)
|
||||
response_headers["Content-Length"] = str(len(payload))
|
||||
return payload
|
||||
else:
|
||||
return None
|
||||
payload = fn.invoke(body, headers, response_headers)
|
||||
response_headers["Content-Length"] = str(len(payload))
|
||||
return payload
|
||||
|
||||
def put_function_concurrency(
|
||||
self, function_name: str, reserved_concurrency: str
|
||||
|
@ -398,7 +398,17 @@ class LambdaResponse(BaseResponse):
|
||||
return 204, {}, ""
|
||||
|
||||
@staticmethod
|
||||
def _set_configuration_qualifier(configuration: Dict[str, Any], qualifier: str) -> Dict[str, Any]: # type: ignore[misc]
|
||||
def _set_configuration_qualifier(configuration: Dict[str, Any], function_name: str, qualifier: str) -> Dict[str, Any]: # type: ignore[misc]
|
||||
# Qualifier may be explicitly passed or part of function name or ARN, extract it here
|
||||
if function_name.startswith("arn:aws"):
|
||||
# Extract from ARN
|
||||
if ":" in function_name.split(":function:")[-1]:
|
||||
qualifier = function_name.split(":")[-1]
|
||||
else:
|
||||
# Extract from function name
|
||||
if ":" in function_name:
|
||||
qualifier = function_name.split(":")[1]
|
||||
|
||||
if qualifier is None or qualifier == "$LATEST":
|
||||
configuration["Version"] = "$LATEST"
|
||||
if qualifier == "$LATEST":
|
||||
@ -413,7 +423,7 @@ class LambdaResponse(BaseResponse):
|
||||
|
||||
code = fn.get_code()
|
||||
code["Configuration"] = self._set_configuration_qualifier(
|
||||
code["Configuration"], qualifier
|
||||
code["Configuration"], function_name, qualifier
|
||||
)
|
||||
return 200, {}, json.dumps(code)
|
||||
|
||||
@ -424,7 +434,7 @@ class LambdaResponse(BaseResponse):
|
||||
fn = self.backend.get_function(function_name, qualifier)
|
||||
|
||||
configuration = self._set_configuration_qualifier(
|
||||
fn.get_configuration(), qualifier
|
||||
fn.get_configuration(), function_name, qualifier
|
||||
)
|
||||
return 200, {}, json.dumps(configuration)
|
||||
|
||||
|
@ -591,6 +591,22 @@ def test_get_function():
|
||||
== f"arn:aws:lambda:us-west-2:{ACCOUNT_ID}:function:{function_name}:$LATEST"
|
||||
)
|
||||
|
||||
# Test get function with version
|
||||
result = conn.get_function(FunctionName=function_name, Qualifier="1")
|
||||
assert result["Configuration"]["Version"] == "1"
|
||||
assert (
|
||||
result["Configuration"]["FunctionArn"]
|
||||
== f"arn:aws:lambda:us-west-2:{ACCOUNT_ID}:function:{function_name}:1"
|
||||
)
|
||||
|
||||
# Test get function with version inside of name
|
||||
result = conn.get_function(FunctionName=f"{function_name}:1")
|
||||
assert result["Configuration"]["Version"] == "1"
|
||||
assert (
|
||||
result["Configuration"]["FunctionArn"]
|
||||
== f"arn:aws:lambda:us-west-2:{ACCOUNT_ID}:function:{function_name}:1"
|
||||
)
|
||||
|
||||
# Test get function when can't find function name
|
||||
with pytest.raises(conn.exceptions.ResourceNotFoundException):
|
||||
conn.get_function(FunctionName="junk", Qualifier="$LATEST")
|
||||
@ -724,6 +740,22 @@ def test_get_function_by_arn():
|
||||
result = conn.get_function(FunctionName=fnc["FunctionArn"])
|
||||
assert result["Configuration"]["FunctionName"] == function_name
|
||||
|
||||
# Test with version
|
||||
result = conn.get_function(FunctionName=fnc["FunctionArn"], Qualifier="1")
|
||||
assert (
|
||||
result["Configuration"]["FunctionArn"]
|
||||
== f"arn:aws:lambda:us-east-1:{ACCOUNT_ID}:function:{function_name}:1"
|
||||
)
|
||||
assert result["Configuration"]["Version"] == "1"
|
||||
|
||||
# Test with version inside of ARN
|
||||
result = conn.get_function(FunctionName=f"{fnc['FunctionArn']}:1")
|
||||
assert result["Configuration"]["Version"] == "1"
|
||||
assert (
|
||||
result["Configuration"]["FunctionArn"]
|
||||
== f"arn:aws:lambda:us-east-1:{ACCOUNT_ID}:function:{function_name}:1"
|
||||
)
|
||||
|
||||
|
||||
@mock_lambda
|
||||
@mock_s3
|
||||
@ -760,7 +792,7 @@ def test_delete_function():
|
||||
|
||||
assert success_result == {"ResponseMetadata": {"HTTPStatusCode": 204}}
|
||||
|
||||
func_list = conn.list_functions()["Functions"]
|
||||
func_list = conn.list_functions(FunctionVersion="ALL")["Functions"]
|
||||
our_functions = [f for f in func_list if f["FunctionName"] == function_name]
|
||||
assert len(our_functions) == 0
|
||||
|
||||
@ -1592,12 +1624,23 @@ def test_multiple_qualifiers():
|
||||
qualis = [fn["FunctionArn"].split(":")[-1] for fn in resp]
|
||||
assert qualis == ["$LATEST", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
|
||||
|
||||
# Test delete with function name and qualifier
|
||||
client.delete_function(FunctionName=fn_name, Qualifier="4")
|
||||
client.delete_function(FunctionName=fn_name, Qualifier="5")
|
||||
# Test delete with ARN and qualifier
|
||||
client.delete_function(
|
||||
FunctionName=f"arn:aws:lambda:us-east-1:{ACCOUNT_ID}:function:{fn_name}",
|
||||
Qualifier="5",
|
||||
)
|
||||
# Test delete with qualifier part of function name
|
||||
client.delete_function(FunctionName=fn_name + ":8")
|
||||
# Test delete with qualifier inside ARN
|
||||
client.delete_function(
|
||||
FunctionName=f"arn:aws:lambda:us-east-1:{ACCOUNT_ID}:function:{fn_name}:9"
|
||||
)
|
||||
|
||||
resp = client.list_versions_by_function(FunctionName=fn_name)["Versions"]
|
||||
qualis = [fn["FunctionArn"].split(":")[-1] for fn in resp]
|
||||
assert qualis == ["$LATEST", "1", "2", "3", "6", "7", "8", "9", "10"]
|
||||
assert qualis == ["$LATEST", "1", "2", "3", "6", "7", "10"]
|
||||
|
||||
fn = client.get_function(FunctionName=fn_name, Qualifier="6")["Configuration"]
|
||||
assert (
|
||||
@ -1606,6 +1649,18 @@ def test_multiple_qualifiers():
|
||||
)
|
||||
|
||||
|
||||
@mock_lambda
|
||||
def test_delete_non_existent():
|
||||
client = boto3.client("lambda", "us-east-1")
|
||||
|
||||
with pytest.raises(ClientError) as exc:
|
||||
client.delete_function(
|
||||
FunctionName=f"arn:aws:lambda:us-east-1:{ACCOUNT_ID}:function:nonexistent:9"
|
||||
)
|
||||
|
||||
assert exc.value.response["Error"]["Code"] == "ResourceNotFoundException"
|
||||
|
||||
|
||||
def test_get_role_name_utility_race_condition():
|
||||
# Play with these variables as needed to reproduce the error.
|
||||
max_workers, num_threads = 3, 15
|
||||
|
@ -394,9 +394,11 @@ def test_update_alias_routingconfig():
|
||||
|
||||
|
||||
@mock_lambda
|
||||
def test_get_function_using_alias():
|
||||
@pytest.mark.parametrize("qualifierIn", ["NAME", "SEPARATE", "BOTH"])
|
||||
def test_get_function_using_alias(qualifierIn):
|
||||
client = boto3.client("lambda", region_name="us-east-2")
|
||||
fn_name = str(uuid4())[0:6]
|
||||
fn_qualifier = "live"
|
||||
|
||||
client.create_function(
|
||||
FunctionName=fn_name,
|
||||
@ -408,9 +410,20 @@ def test_get_function_using_alias():
|
||||
client.publish_version(FunctionName=fn_name)
|
||||
client.publish_version(FunctionName=fn_name)
|
||||
|
||||
client.create_alias(FunctionName=fn_name, Name="live", FunctionVersion="1")
|
||||
client.create_alias(FunctionName=fn_name, Name=fn_qualifier, FunctionVersion="1")
|
||||
|
||||
fn = client.get_function(FunctionName=fn_name, Qualifier="live")["Configuration"]
|
||||
if qualifierIn == "NAME":
|
||||
fn = client.get_function(FunctionName=f"{fn_name}:{fn_qualifier}")[
|
||||
"Configuration"
|
||||
]
|
||||
elif qualifierIn == "SEPARATE":
|
||||
fn = client.get_function(FunctionName=fn_name, Qualifier=fn_qualifier)[
|
||||
"Configuration"
|
||||
]
|
||||
elif qualifierIn == "BOTH":
|
||||
fn = client.get_function(
|
||||
FunctionName=f"{fn_name}:{fn_qualifier}", Qualifier=fn_qualifier
|
||||
)["Configuration"]
|
||||
assert (
|
||||
fn["FunctionArn"]
|
||||
== f"arn:aws:lambda:us-east-2:{ACCOUNT_ID}:function:{fn_name}:1"
|
||||
|
Loading…
Reference in New Issue
Block a user