AWSLambda:list_functions() should only return the latest version by default (#4047)
This commit is contained in:
parent
a43c42ef21
commit
728c0c91b4
@ -964,7 +964,7 @@ class LambdaStorage(object):
|
||||
fn.policy = Policy(fn)
|
||||
self._arns[fn.function_arn] = fn
|
||||
|
||||
def publish_function(self, name_or_arn):
|
||||
def publish_function(self, name_or_arn, description=""):
|
||||
function = self.get_function_by_name_or_arn(name_or_arn)
|
||||
name = function.function_name
|
||||
if name not in self._functions:
|
||||
@ -975,6 +975,8 @@ class LambdaStorage(object):
|
||||
new_version = len(self._functions[name]["versions"]) + 1
|
||||
fn = copy.copy(self._functions[name]["latest"])
|
||||
fn.set_version(new_version)
|
||||
if description:
|
||||
fn.description = description
|
||||
|
||||
self._functions[name]["versions"].append(fn)
|
||||
self._arns[fn.function_arn] = fn
|
||||
@ -1028,13 +1030,26 @@ class LambdaStorage(object):
|
||||
result = []
|
||||
|
||||
for function_group in self._functions.values():
|
||||
if function_group["latest"] is not None:
|
||||
result.append(function_group["latest"])
|
||||
latest = copy.deepcopy(function_group["latest"])
|
||||
latest.function_arn = "{}:$LATEST".format(latest.function_arn)
|
||||
result.append(latest)
|
||||
|
||||
result.extend(function_group["versions"])
|
||||
|
||||
return result
|
||||
|
||||
def latest(self):
|
||||
"""
|
||||
Return the list of functions with version @LATEST
|
||||
:return:
|
||||
"""
|
||||
result = []
|
||||
for function_group in self._functions.values():
|
||||
if function_group["latest"] is not None:
|
||||
result.append(function_group["latest"])
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class LayerStorage(object):
|
||||
def __init__(self):
|
||||
@ -1091,6 +1106,9 @@ class LambdaBackend(BaseBackend):
|
||||
|
||||
if spec.get("Publish"):
|
||||
ver = self.publish_function(function_name)
|
||||
fn = copy.deepcopy(
|
||||
fn
|
||||
) # We don't want to change the actual version - just the return value
|
||||
fn.version = ver.version
|
||||
return fn
|
||||
|
||||
@ -1162,8 +1180,8 @@ class LambdaBackend(BaseBackend):
|
||||
def layers_versions_by_arn(self, layer_version_arn):
|
||||
return self._layers.get_layer_version_by_arn(layer_version_arn)
|
||||
|
||||
def publish_function(self, function_name):
|
||||
return self._lambdas.publish_function(function_name)
|
||||
def publish_function(self, function_name, description=""):
|
||||
return self._lambdas.publish_function(function_name, description)
|
||||
|
||||
def get_function(self, function_name_or_arn, qualifier=None):
|
||||
return self._lambdas.get_function_by_name_or_arn(
|
||||
@ -1210,8 +1228,10 @@ class LambdaBackend(BaseBackend):
|
||||
def delete_function(self, function_name, qualifier=None):
|
||||
return self._lambdas.del_function(function_name, qualifier)
|
||||
|
||||
def list_functions(self):
|
||||
return self._lambdas.all()
|
||||
def list_functions(self, func_version=None):
|
||||
if func_version == "ALL":
|
||||
return self._lambdas.all()
|
||||
return self._lambdas.latest()
|
||||
|
||||
def send_sqs_batch(self, function_arn, messages, queue_arn):
|
||||
success = True
|
||||
|
@ -236,11 +236,12 @@ class LambdaResponse(BaseResponse):
|
||||
return 404, response_headers, "{}"
|
||||
|
||||
def _list_functions(self, request, full_url, headers):
|
||||
querystring = self.querystring
|
||||
func_version = querystring.get("FunctionVersion", [None])[0]
|
||||
result = {"Functions": []}
|
||||
|
||||
for fn in self.lambda_backend.list_functions():
|
||||
for fn in self.lambda_backend.list_functions(func_version):
|
||||
json_data = fn.get_configuration()
|
||||
json_data["Version"] = "$LATEST"
|
||||
result["Functions"].append(json_data)
|
||||
|
||||
return 200, {}, json.dumps(result)
|
||||
@ -298,8 +299,9 @@ class LambdaResponse(BaseResponse):
|
||||
|
||||
def _publish_function(self, request, full_url, headers):
|
||||
function_name = self.path.rsplit("/", 2)[-2]
|
||||
description = self._get_param("Description")
|
||||
|
||||
fn = self.lambda_backend.publish_function(function_name)
|
||||
fn = self.lambda_backend.publish_function(function_name, description)
|
||||
if fn:
|
||||
config = fn.get_configuration()
|
||||
return 201, {}, json.dumps(config)
|
||||
|
@ -121,8 +121,40 @@ def test_lambda_regions(region):
|
||||
@mock_lambda
|
||||
def test_list_functions():
|
||||
conn = boto3.client("lambda", _lambda_region)
|
||||
result = conn.list_functions()
|
||||
result["Functions"].should.have.length_of(0)
|
||||
conn.list_functions()["Functions"].should.have.length_of(0)
|
||||
|
||||
function_name = "testFunction"
|
||||
|
||||
conn.create_function(
|
||||
FunctionName=function_name,
|
||||
Runtime="python3.7",
|
||||
Role=get_role_name(),
|
||||
Handler="lambda_function.lambda_handler",
|
||||
Code={"ZipFile": get_test_zip_file1()},
|
||||
)
|
||||
conn.list_functions()["Functions"].should.have.length_of(1)
|
||||
conn.publish_version(FunctionName=function_name, Description="v2")
|
||||
conn.list_functions()["Functions"].should.have.length_of(1)
|
||||
|
||||
# FunctionVersion=ALL means we should get a list of all versions
|
||||
result = conn.list_functions(FunctionVersion="ALL")["Functions"]
|
||||
result.should.have.length_of(2)
|
||||
|
||||
v1 = [f for f in result if f["Version"] == "1"][0]
|
||||
v1["Description"].should.equal("v2")
|
||||
v1["FunctionArn"].should.equal(
|
||||
"arn:aws:lambda:{}:{}:function:{}:1".format(
|
||||
_lambda_region, ACCOUNT_ID, function_name
|
||||
)
|
||||
)
|
||||
|
||||
latest = [f for f in result if f["Version"] == "$LATEST"][0]
|
||||
latest["Description"].should.equal("")
|
||||
latest["FunctionArn"].should.equal(
|
||||
"arn:aws:lambda:{}:{}:function:{}:$LATEST".format(
|
||||
_lambda_region, ACCOUNT_ID, function_name
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.network
|
||||
@ -772,14 +804,14 @@ def test_publish():
|
||||
Publish=False,
|
||||
)
|
||||
|
||||
function_list = conn.list_functions()
|
||||
function_list = conn.list_functions(FunctionVersion="ALL")
|
||||
function_list["Functions"].should.have.length_of(1)
|
||||
latest_arn = function_list["Functions"][0]["FunctionArn"]
|
||||
|
||||
res = conn.publish_version(FunctionName="testFunction")
|
||||
assert res["ResponseMetadata"]["HTTPStatusCode"] == 201
|
||||
|
||||
function_list = conn.list_functions()
|
||||
function_list = conn.list_functions(FunctionVersion="ALL")
|
||||
function_list["Functions"].should.have.length_of(2)
|
||||
|
||||
# #SetComprehension ;-)
|
||||
@ -815,8 +847,9 @@ def test_list_create_list_get_delete_list():
|
||||
|
||||
conn.list_functions()["Functions"].should.have.length_of(0)
|
||||
|
||||
function_name = "testFunction"
|
||||
conn.create_function(
|
||||
FunctionName="testFunction",
|
||||
FunctionName=function_name,
|
||||
Runtime="python2.7",
|
||||
Role=get_role_name(),
|
||||
Handler="lambda_function.lambda_handler",
|
||||
@ -837,10 +870,7 @@ def test_list_create_list_get_delete_list():
|
||||
"CodeSha256": hashlib.sha256(zip_content).hexdigest(),
|
||||
"CodeSize": len(zip_content),
|
||||
"Description": "test lambda function",
|
||||
"FunctionArn": "arn:aws:lambda:{}:{}:function:testFunction".format(
|
||||
_lambda_region, ACCOUNT_ID
|
||||
),
|
||||
"FunctionName": "testFunction",
|
||||
"FunctionName": function_name,
|
||||
"Handler": "lambda_function.lambda_handler",
|
||||
"MemorySize": 128,
|
||||
"Role": get_role_name(),
|
||||
@ -853,16 +883,48 @@ def test_list_create_list_get_delete_list():
|
||||
},
|
||||
"ResponseMetadata": {"HTTPStatusCode": 200},
|
||||
}
|
||||
func = conn.list_functions()["Functions"][0]
|
||||
func.pop("LastModified")
|
||||
func.should.equal(expected_function_result["Configuration"])
|
||||
functions = conn.list_functions()["Functions"]
|
||||
functions.should.have.length_of(1)
|
||||
functions[0]["FunctionArn"].should.equal(
|
||||
"arn:aws:lambda:{}:{}:function:{}".format(
|
||||
_lambda_region, ACCOUNT_ID, function_name
|
||||
)
|
||||
)
|
||||
functions = conn.list_functions(FunctionVersion="ALL")["Functions"]
|
||||
functions.should.have.length_of(2)
|
||||
|
||||
latest = [f for f in functions if f["Version"] == "$LATEST"][0]
|
||||
latest["FunctionArn"].should.equal(
|
||||
"arn:aws:lambda:{}:{}:function:{}:$LATEST".format(
|
||||
_lambda_region, ACCOUNT_ID, function_name
|
||||
)
|
||||
)
|
||||
latest.pop("FunctionArn")
|
||||
latest.pop("LastModified")
|
||||
latest.should.equal(expected_function_result["Configuration"])
|
||||
|
||||
published = [f for f in functions if f["Version"] != "$LATEST"][0]
|
||||
published["Version"].should.equal("1")
|
||||
published["FunctionArn"].should.equal(
|
||||
"arn:aws:lambda:{}:{}:function:{}:1".format(
|
||||
_lambda_region, ACCOUNT_ID, function_name
|
||||
)
|
||||
)
|
||||
|
||||
func = conn.get_function(FunctionName=function_name)
|
||||
|
||||
func["Configuration"]["FunctionArn"].should.equal(
|
||||
"arn:aws:lambda:{}:{}:function:{}".format(
|
||||
_lambda_region, ACCOUNT_ID, function_name
|
||||
)
|
||||
)
|
||||
|
||||
func = conn.get_function(FunctionName="testFunction")
|
||||
# this is hard to match against, so remove it
|
||||
func["ResponseMetadata"].pop("HTTPHeaders", None)
|
||||
# Botocore inserts retry attempts not seen in Python27
|
||||
func["ResponseMetadata"].pop("RetryAttempts", None)
|
||||
func["Configuration"].pop("LastModified")
|
||||
func["Configuration"].pop("FunctionArn")
|
||||
|
||||
func.should.equal(expected_function_result)
|
||||
conn.delete_function(FunctionName="testFunction")
|
||||
|
Loading…
Reference in New Issue
Block a user