Skip to content

Commit

Permalink
Cleanup awslambda zipfile checking and add more tests (cloudtools#537)
Browse files Browse the repository at this point in the history
  • Loading branch information
markpeek authored and covataamos committed Oct 24, 2016
1 parent 207ed72 commit a0f51a0
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
19 changes: 19 additions & 0 deletions tests/test_awslambda.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,24 @@ def test_zip_file(self):
t.add_resource(lambda_func)
t.to_json()

def test_check_zip_file(self):
positive_tests = [
'a'*4096,
Join('', ['a'*4096]),
Join('', ['a', 10]),
Join('ab', ['a'*2047, 'a'*2047]),
GetAtt('foo', 'bar'),
]
for z in positive_tests:
Code.check_zip_file(z)
negative_tests = [
'a'*4097,
Join('', ['a'*4097]),
Join('abc', ['a'*2047, 'a'*2047]),
]
for z in negative_tests:
with self.assertRaises(ValueError):
Code.check_zip_file(z)

if __name__ == '__main__':
unittest.main()
44 changes: 39 additions & 5 deletions troposphere/awslambda.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from . import AWSObject, AWSProperty
from . import AWSObject, AWSProperty, Join
from .validators import positive_integer

MEMORY_VALUES = [x for x in range(128, 1600, 64)]
Expand All @@ -24,6 +24,43 @@ class Code(AWSProperty):
'ZipFile': (basestring, False)
}

@staticmethod
def check_zip_file(zip_file):
maxlength = 4096
toolong = (
"ZipFile length cannot exceed %d characters. For larger "
"source use S3Bucket/S3Key properties instead. "
"Current length: %d"
)

if zip_file is None:
return

if isinstance(zip_file, basestring):
zlength = len(zip_file)
if zlength > maxlength:
raise ValueError(toolong % (maxlength, zlength))
return
elif isinstance(zip_file, Join):
# This code tries to determine if this is a Join with all
# strings. If so, we try (best effort) to check the length.
delimiter, values = zip_file.data['Fn::Join']
if not isinstance(delimiter, basestring):
return

zlength = 0
if values:
for v in values:
# if it's not a list of strings, just return
if not isinstance(v, basestring):
return
zlength += len(v)
# account for the size of the delimeter between values
zlength += (len(values)-1) * len(delimiter)

if zlength > maxlength:
raise ValueError(toolong % (maxlength, zlength))

def validate(self):
zip_file = self.properties.get('ZipFile')
s3_bucket = self.properties.get('S3Bucket')
Expand All @@ -38,10 +75,7 @@ def validate(self):
raise ValueError(
"You can't specify both 'S3ObjectVersion' and 'ZipFile'"
)
if zip_file and len(zip_file) > 4096:
raise ValueError(
"ZipFile length cannot exceed 4096 characters. For larger source use S3Bucket/S3Key properties instead. Current length: %d" % len(zip_file)
)
Code.check_zip_file(zip_file)
if not zip_file and not (s3_bucket and s3_key):
raise ValueError(
"You must specify a bucket location (both the 'S3Bucket' and "
Expand Down

0 comments on commit a0f51a0

Please sign in to comment.