Skip to content
This repository was archived by the owner on Jun 30, 2021. It is now read-only.

Commit 2a2448b

Browse files
authored
Merge pull request #7 from awslabs/unzip-s3
Unzip stream of bytes from s3 and log job result in lambda
2 parents 3cbfeb9 + 0e103e2 commit 2a2448b

File tree

3 files changed

+42
-9
lines changed

3 files changed

+42
-9
lines changed

src/codepipelinehelper.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def put_job_success(job_id, sar_response):
1616
job_id {str} -- The unique ID for the job generated by AWS CodePipeline
1717
sar_response {dict} -- The result from invoking serverlessrepo.publish_application()
1818
"""
19-
LOG.info('Putting job success result...')
19+
LOG.info('Putting job success result=%s', sar_response)
2020
CODEPIPELINE.put_job_success_result(
2121
jobId=job_id,
2222
executionDetails={
@@ -33,7 +33,7 @@ def put_job_failure(job_id, e):
3333
job_id {str} -- The unique ID for the job generated by AWS CodePipeline
3434
e {Exception} -- The exception from invoking serverlessrepo.publish_application()
3535
"""
36-
LOG.info('Putting job failure result...')
36+
LOG.info('Putting job failure result=%s', e)
3737
CODEPIPELINE.put_job_failure_result(
3838
jobId=job_id,
3939
failureDetails={

src/s3helper.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import lambdalogging
44

55
import boto3
6+
import zipfile
7+
import io
68

79
LOG = lambdalogging.getLogger(__name__)
810

@@ -35,8 +37,10 @@ def get_input_artifact(event):
3537
key = artifact_s3_location['objectKey']
3638

3739
response = S3.get_object(Bucket=bucket, Key=key)
38-
LOG.info('{}/{} fetched. {} bytes.', bucket, key, response['ContentLength'])
39-
return response.get('Body').read().decode(response['ContentLength'])
40+
LOG.info('%s/%s fetched. %s bytes.', bucket, key, response['ContentLength'])
41+
42+
zipped_content_as_bytes = response.get('Body').read()
43+
return _unzip_as_string(zipped_content_as_bytes)
4044

4145

4246
def _find_artifact_in_list(input_artifacts):
@@ -58,3 +62,18 @@ def _find_artifact_in_list(input_artifacts):
5862
return artifact
5963

6064
raise RuntimeError('Unable to find the artifact with name ' + PACKAGED_TEMPLATE)
65+
66+
67+
def _unzip_as_string(data):
68+
"""Unzip stream of data in bytes as string.
69+
70+
Arguments:
71+
data {bytes} -- Zipped data as bytes
72+
73+
Returns:
74+
str -- Unzipped data as string
75+
76+
"""
77+
z = zipfile.ZipFile(io.BytesIO(data))
78+
unzipped_data = z.read(z.infolist()[0])
79+
return unzipped_data.decode()

test/unit/test_s3helper.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,43 @@ def mock_boto3(mocker):
1414
return s3helper.boto3
1515

1616

17-
def test_get_input_artifact(mock_boto3):
17+
@pytest.fixture
18+
def mock_zipfile(mocker):
19+
mocker.patch.object(s3helper, 'zipfile')
20+
return s3helper.zipfile
21+
22+
23+
def test_get_input_artifact(mock_boto3, mock_zipfile):
24+
zipped_content_as_bytes = b'zipped_packaged_template_content'
25+
expected_result = 'packaged_template_content'
26+
1827
mock_s3 = MagicMock()
1928
mock_boto3.client.return_value = mock_s3
20-
mock_s3.get_object.return_value.get.return_value.read.return_value.decode.return_value = 'packaged_template_content'
29+
mock_s3.get_object.return_value.get.return_value.read.return_value = zipped_content_as_bytes
30+
mock_zipfile_object = MagicMock()
31+
mock_zipfile.ZipFile.return_value = mock_zipfile_object
32+
mock_zipfile_object.read.return_value = bytes(expected_result, encoding='utf-8')
2133

22-
s3helper.get_input_artifact(mock_codepipeline_event)
34+
assert s3helper.get_input_artifact(mock_codepipeline_event) == expected_result
2335

2436
mock_s3.get_object.assert_called_once_with(
2537
Bucket='sample-pipeline-artifact-store-bucket',
2638
Key='sample-artifact-key'
2739
)
2840

2941

30-
def test_get_input_artifact_unable_to_find_artifact(mock_boto3):
42+
def test_get_input_artifact_unable_to_find_artifact(mock_boto3, mock_zipfile):
3143
mock_s3 = MagicMock()
3244
mock_boto3.client.return_value = mock_s3
3345

3446
with pytest.raises(RuntimeError, match='Unable to find the artifact with name ' + s3helper.PACKAGED_TEMPLATE):
3547
s3helper.get_input_artifact(mock_codepipeline_event_no_artifact_found)
3648

3749
mock_s3.get_object.assert_not_called()
50+
mock_zipfile.assert_not_called()
3851

3952

40-
def test_get_input_artifact_unable_to_get_artifact(mock_boto3):
53+
def test_get_input_artifact_unable_to_get_artifact(mock_boto3, mock_zipfile):
4154
exception_thrown = ClientError(
4255
{
4356
"Error": {
@@ -59,3 +72,4 @@ def test_get_input_artifact_unable_to_get_artifact(mock_boto3):
5972
Bucket='sample-pipeline-artifact-store-bucket',
6073
Key='sample-artifact-key'
6174
)
75+
mock_zipfile.assert_not_called()

0 commit comments

Comments
 (0)