def test_list_function_versions(self): with self.app.test_request_context(): self._create_function(self.FUNCTION_NAME) lambda_api.publish_version(self.FUNCTION_NAME) lambda_api.publish_version(self.FUNCTION_NAME) result = json.loads( lambda_api.list_versions(self.FUNCTION_NAME).get_data()) for version in result['Versions']: # we need to remove this, since this is random, so we cannot know its value version.pop('RevisionId', None) latest_version = dict() latest_version['CodeSize'] = self.CODE_SIZE latest_version['CodeSha256'] = self.CODE_SHA_256 latest_version['FunctionArn'] = str( lambda_api.func_arn(self.FUNCTION_NAME)) + ':$LATEST' latest_version['FunctionName'] = str(self.FUNCTION_NAME) latest_version['Handler'] = str(self.HANDLER) latest_version['Runtime'] = str(self.RUNTIME) latest_version['Timeout'] = self.TIMEOUT latest_version['Description'] = '' latest_version['MemorySize'] = self.MEMORY_SIZE latest_version['Role'] = self.ROLE latest_version['KMSKeyArn'] = None latest_version['VpcConfig'] = None latest_version['LastModified'] = self.LAST_MODIFIED latest_version['TracingConfig'] = self.TRACING_CONFIG latest_version['Version'] = '$LATEST' latest_version['State'] = 'Active' latest_version['LastUpdateStatus'] = 'Successful' latest_version['PackageType'] = None version1 = dict(latest_version) version1['FunctionArn'] = str( lambda_api.func_arn(self.FUNCTION_NAME)) + ':1' version1['Version'] = '1' version2 = dict(latest_version) version2['FunctionArn'] = str( lambda_api.func_arn(self.FUNCTION_NAME)) + ':2' version2['Version'] = '2' expected_result = { 'Versions': sorted([latest_version, version1, version2], key=lambda k: str(k.get('Version'))) } self.assertDictEqual(expected_result, result)
def _create_function(self, function_name): arn = lambda_api.func_arn(function_name) lambda_api.arn_to_lambda[arn] = LambdaFunction(arn) lambda_api.arn_to_lambda[arn].versions = {'$LATEST': {'CodeSize': self.CODE_SIZE}} lambda_api.arn_to_lambda[arn].handler = self.HANDLER lambda_api.arn_to_lambda[arn].runtime = self.RUNTIME lambda_api.arn_to_lambda[arn].timeout = self.TIMEOUT lambda_api.arn_to_lambda[arn].envvars = {}
def test_list_tags(self): with self.app.test_request_context(): self._create_function(self.FUNCTION_NAME, self.TAGS) arn = lambda_api.func_arn(self.FUNCTION_NAME) response = self.client.get('{0}/tags/{1}'.format(lambda_api.PATH_ROOT, arn)) result = json.loads(response.get_data()) self.assertTrue('Tags' in result) self.assertDictEqual(self.TAGS, result['Tags'])
def test_list_aliases(self): self._create_function(self.FUNCTION_NAME) self.client.post('{0}/functions/{1}/versions'.format( lambda_api.PATH_ROOT, self.FUNCTION_NAME)) self.client.post('{0}/functions/{1}/aliases'.format( lambda_api.PATH_ROOT, self.FUNCTION_NAME), data=json.dumps({ 'Name': self.ALIAS2_NAME, 'FunctionVersion': '$LATEST' })) self.client.post('{0}/functions/{1}/aliases'.format( lambda_api.PATH_ROOT, self.FUNCTION_NAME), data=json.dumps({ 'Name': self.ALIAS_NAME, 'FunctionVersion': '1', 'Description': self.ALIAS_NAME })) response = self.client.get('{0}/functions/{1}/aliases'.format( lambda_api.PATH_ROOT, self.FUNCTION_NAME)) result = json.loads(response.get_data()) expected_result = { 'Aliases': [{ 'AliasArn': lambda_api.func_arn(self.FUNCTION_NAME) + ':' + self.ALIAS_NAME, 'FunctionVersion': '1', 'Name': self.ALIAS_NAME, 'Description': self.ALIAS_NAME }, { 'AliasArn': lambda_api.func_arn(self.FUNCTION_NAME) + ':' + self.ALIAS2_NAME, 'FunctionVersion': '$LATEST', 'Name': self.ALIAS2_NAME, 'Description': '' }] } self.assertDictEqual(expected_result, result)
def _update_function_code(self, function_name, tags={}): region = lambda_api.LambdaRegion.get() arn = lambda_api.func_arn(function_name) region.lambdas[arn].versions.update({ '$LATEST': {'CodeSize': self.CODE_SIZE, 'CodeSha256': self.UPDATED_CODE_SHA_256, 'RevisionId': self.REVISION_ID} })
def test_publish_non_existant_function_version_returns_error(self): with self.app.test_request_context(): result = json.loads( lambda_api.publish_version(self.FUNCTION_NAME).get_data()) self.assertEqual(self.RESOURCENOTFOUND_EXCEPTION, result['__type']) self.assertEqual( self.RESOURCENOTFOUND_MESSAGE % lambda_api.func_arn(self.FUNCTION_NAME), result['message'])
def test_lambda_subscribe_sns_topic(self): function_name = '{}-{}'.format(TEST_LAMBDA_FUNCTION_PREFIX, short_uid()) testutil.create_lambda_function(handler_file=TEST_LAMBDA_ECHO_FILE, func_name=function_name, runtime=LAMBDA_RUNTIME_PYTHON36) topic = self.sns_client.create_topic( Name=TEST_SNS_TOPIC_NAME ) topic_arn = topic['TopicArn'] self.sns_client.subscribe( TopicArn=topic_arn, Protocol='lambda', Endpoint=lambda_api.func_arn(function_name), ) subject = '[Subject] Test subject' message = 'Hello world.' self.sns_client.publish( TopicArn=topic_arn, Subject=subject, Message=message ) logs = aws_stack.connect_to_service('logs') def get_event_message(events): for event in events: raw_message = event['message'] if 'START' in raw_message or 'END' in raw_message or 'REPORT' in raw_message: continue return json.loads(raw_message) return None # wait for lambda executing def check_log_streams(): rs = logs.describe_log_streams( logGroupName='/aws/lambda/{}'.format(function_name) ) self.assertEqual(len(rs['logStreams']), 1) return rs['logStreams'][0]['logStreamName'] log_stream = retry(check_log_streams, retries=3, sleep=2) rs = logs.get_log_events( logGroupName='/aws/lambda/{}'.format(function_name), logStreamName=log_stream ) message = get_event_message(rs['events']) self.assertEqual(len(message['Records']), 1) notification = message['Records'][0]['Sns'] self.assertIn('Subject', notification) self.assertEqual(notification['Subject'], subject)
class TestLambdaEventInvokeConfig(unittest.TestCase): CODE_SIZE = 50 CODE_SHA_256 = '/u60ZpAA9bzZPVwb8d4390i5oqP1YAObUwV03CZvsWA=' MEMORY_SIZE = 128 ROLE = LAMBDA_TEST_ROLE LAST_MODIFIED = datetime.datetime.utcnow() REVISION_ID = 'e54dbcf8-e3ef-44ab-9af7-8dbef510608a' HANDLER = 'index.handler' RUNTIME = 'node.js4.3' TIMEOUT = 60 FUNCTION_NAME = 'test1' RETRY_ATTEMPTS = 5 EVENT_AGE = 360 DL_QUEUE = 'arn:aws:sqs:us-east-1:000000000000:dlQueue' LAMBDA_OBJ = LambdaFunction(lambda_api.func_arn('test1')) def _create_function(self, function_name, tags={}): self.LAMBDA_OBJ.versions = { '$LATEST': {'CodeSize': self.CODE_SIZE, 'CodeSha256': self.CODE_SHA_256, 'RevisionId': self.REVISION_ID} } self.LAMBDA_OBJ.handler = self.HANDLER self.LAMBDA_OBJ.runtime = self.RUNTIME self.LAMBDA_OBJ.timeout = self.TIMEOUT self.LAMBDA_OBJ.tags = tags self.LAMBDA_OBJ.envvars = {} self.LAMBDA_OBJ.last_modified = self.LAST_MODIFIED self.LAMBDA_OBJ.role = self.ROLE self.LAMBDA_OBJ.memory_size = self.MEMORY_SIZE # TODO: remove this test case. Already added it in integration test case def test_put_function_event_invoke_config(self): # creating a lambda function self._create_function(self.FUNCTION_NAME) # calling put_function_event_invoke_config payload = { 'DestinationConfig': { 'OnFailure': { 'Destination': self.DL_QUEUE } }, 'MaximumEventAgeInSeconds': self.EVENT_AGE, 'MaximumRetryAttempts': self.RETRY_ATTEMPTS } response = self.LAMBDA_OBJ.put_function_event_invoke_config( payload ) # checking if response is not None self.assertIsNotNone(response) # calling get_function_event_invoke_config response = self.LAMBDA_OBJ.get_function_event_invoke_config() # verifying set values self.assertEqual(response['FunctionArn'], self.LAMBDA_OBJ.id) self.assertEqual(response['MaximumRetryAttempts'], self.RETRY_ATTEMPTS) self.assertEqual(response['MaximumEventAgeInSeconds'], self.EVENT_AGE) self.assertEqual(response['DestinationConfig']['OnFailure']['Destination'], self.DL_QUEUE)
def _update_function_code(self, function_name, tags={}): arn = lambda_api.func_arn(function_name) lambda_api.ARN_TO_LAMBDA[arn].versions.update({ '$LATEST': { 'CodeSize': self.CODE_SIZE, 'CodeSha256': self.UPDATED_CODE_SHA_256, 'RevisionId': self.REVISION_ID } })
def test_list_function_versions(self): with self.app.test_request_context(): self._create_function(self.FUNCTION_NAME) lambda_api.publish_version(self.FUNCTION_NAME) lambda_api.publish_version(self.FUNCTION_NAME) result = json.loads( lambda_api.list_versions(self.FUNCTION_NAME).get_data()) for version in result["Versions"]: # we need to remove this, since this is random, so we cannot know its value version.pop("RevisionId", None) latest_version = dict() latest_version["CodeSize"] = self.CODE_SIZE latest_version["CodeSha256"] = self.CODE_SHA_256 latest_version["FunctionArn"] = ( str(lambda_api.func_arn(self.FUNCTION_NAME)) + ":$LATEST") latest_version["FunctionName"] = str(self.FUNCTION_NAME) latest_version["Handler"] = str(self.HANDLER) latest_version["Runtime"] = str(self.RUNTIME) latest_version["Timeout"] = self.TIMEOUT latest_version["Description"] = "" latest_version["MemorySize"] = self.MEMORY_SIZE latest_version["Role"] = self.ROLE latest_version["KMSKeyArn"] = None latest_version["VpcConfig"] = None latest_version["LastModified"] = isoformat_milliseconds( self.LAST_MODIFIED) + "+0000" latest_version["TracingConfig"] = self.TRACING_CONFIG latest_version["Version"] = "$LATEST" latest_version["State"] = "Active" latest_version["LastUpdateStatus"] = "Successful" latest_version["PackageType"] = None latest_version["ImageConfig"] = {} version1 = dict(latest_version) version1["FunctionArn"] = str( lambda_api.func_arn(self.FUNCTION_NAME)) + ":1" version1["Version"] = "1" expected_result = { "Versions": sorted([latest_version, version], key=lambda k: str(k.get("Version"))) } self.assertDictEqual(expected_result, result)
def test_get_non_existent_function_returns_error(self): with self.app.test_request_context(): result = json.loads( lambda_api.get_function( 'non_existent_function_name').get_data()) self.assertEqual(self.RESOURCENOTFOUND_EXCEPTION, result['__type']) self.assertEqual( self.RESOURCENOTFOUND_MESSAGE % lambda_api.func_arn('non_existent_function_name'), result['message'])
def test_tag_non_existent_function_returns_error(self): with self.app.test_request_context(): arn = lambda_api.func_arn('non-existent-function') response = self.client.post('{0}/tags/{1}'.format( lambda_api.PATH_ROOT, arn), data=json.dumps({'Tags': self.TAGS})) result = json.loads(response.get_data()) self.assertEqual(self.RESOURCENOTFOUND_EXCEPTION, result['__type']) self.assertEqual(self.RESOURCENOTFOUND_MESSAGE % arn, result['message'])
def _update_function_code(self, function_name, tags={}): region = lambda_api.LambdaRegion.get() arn = lambda_api.func_arn(function_name) region.lambdas[arn].versions.update({ "$LATEST": { "CodeSize": self.CODE_SIZE, "CodeSha256": self.UPDATED_CODE_SHA_256, "RevisionId": self.REVISION_ID, } })
def test_list_aliases(self): with self.app.test_request_context(): self._create_function(self.FUNCTION_NAME) lambda_api.publish_version(self.FUNCTION_NAME) flask.request.data = json.dumps({ 'Name': self.ALIAS2_NAME, 'FunctionVersion': '$LATEST' }) lambda_api.create_alias(self.FUNCTION_NAME).get_data() flask.request.data = json.dumps({ 'Name': self.ALIAS_NAME, 'FunctionVersion': '1', 'Description': self.ALIAS_NAME }) lambda_api.create_alias(self.FUNCTION_NAME).get_data() result = json.loads( lambda_api.list_aliases(self.FUNCTION_NAME).get_data()) expected_result = { 'Aliases': [{ 'AliasArn': lambda_api.func_arn(self.FUNCTION_NAME) + ':' + self.ALIAS_NAME, 'FunctionVersion': '1', 'Name': self.ALIAS_NAME, 'Description': self.ALIAS_NAME }, { 'AliasArn': lambda_api.func_arn(self.FUNCTION_NAME) + ':' + self.ALIAS2_NAME, 'FunctionVersion': '$LATEST', 'Name': self.ALIAS2_NAME, 'Description': '' }] } self.assertDictEqual(expected_result, result)
def _create_function(self, function_name): arn = lambda_api.func_arn(function_name) lambda_api.lambda_arn_to_versions[arn] = { '$LATEST': { 'CodeSize': self.CODE_SIZE } } lambda_api.lambda_arn_to_handler[arn] = self.HANDLER lambda_api.lambda_arn_to_runtime[arn] = self.RUNTIME lambda_api.lambda_arn_to_envvars[arn] = {}
def test_list_non_existant_function_aliases_returns_error(self): with self.app.test_request_context(): result = json.loads( lambda_api.list_aliases(self.FUNCTION_NAME).get_data()) self.assertEqual(self.RESOURCENOTFOUND_EXCEPTION, result["__type"]) self.assertEqual( self.RESOURCENOTFOUND_MESSAGE % lambda_api.func_arn(self.FUNCTION_NAME), result["message"], )
def test_publish_function_version(self): with self.app.test_request_context(): self._create_function(self.FUNCTION_NAME) result = json.loads(lambda_api.publish_version(self.FUNCTION_NAME).get_data()) result2 = json.loads(lambda_api.publish_version(self.FUNCTION_NAME).get_data()) expected_result = dict() expected_result['CodeSize'] = self.CODE_SIZE expected_result['FunctionArn'] = str(lambda_api.func_arn(self.FUNCTION_NAME)) + ':1' expected_result['FunctionName'] = str(self.FUNCTION_NAME) expected_result['Handler'] = str(self.HANDLER) expected_result['Runtime'] = str(self.RUNTIME) expected_result['Timeout'] = self.TIMEOUT expected_result['Version'] = '1' expected_result2 = dict(expected_result) expected_result2['FunctionArn'] = str(lambda_api.func_arn(self.FUNCTION_NAME)) + ':2' expected_result2['Version'] = '2' self.assertDictEqual(expected_result, result) self.assertDictEqual(expected_result2, result2)
def test_update_alias_on_non_existant_alias_returns_error(self): with self.app.test_request_context(): self._create_function(self.FUNCTION_NAME) result = json.loads( lambda_api.update_alias(self.FUNCTION_NAME, self.ALIAS_NAME).get_data()) alias_arn = lambda_api.func_arn( self.FUNCTION_NAME) + ':' + self.ALIAS_NAME self.assertEqual(self.ALIASNOTFOUND_EXCEPTION, result['__type']) self.assertEqual(self.ALIASNOTFOUND_MESSAGE % alias_arn, result['message'])
def test_publish_function_version(self): with self.app.test_request_context(): self._create_function(self.FUNCTION_NAME) result = json.loads( lambda_api.publish_version(self.FUNCTION_NAME).get_data()) result2 = json.loads( lambda_api.publish_version(self.FUNCTION_NAME).get_data()) result.pop( 'RevisionId', None ) # we need to remove this, since this is random, so we cannot know its value result2.pop( 'RevisionId', None ) # we need to remove this, since this is random, so we cannot know its value expected_result = dict() expected_result['CodeSize'] = self.CODE_SIZE expected_result['CodeSha256'] = self.CODE_SHA_256 expected_result['FunctionArn'] = str( lambda_api.func_arn(self.FUNCTION_NAME)) + ':1' expected_result['FunctionName'] = str(self.FUNCTION_NAME) expected_result['Handler'] = str(self.HANDLER) expected_result['Runtime'] = str(self.RUNTIME) expected_result['Timeout'] = self.TIMEOUT expected_result['Description'] = '' expected_result['MemorySize'] = self.MEMORY_SIZE expected_result['Role'] = self.ROLE expected_result['KMSKeyArn'] = None expected_result['VpcConfig'] = None expected_result['LastModified'] = self.LAST_MODIFIED expected_result['TracingConfig'] = self.TRACING_CONFIG expected_result['Version'] = '1' expected_result['State'] = 'Active' expected_result['LastUpdateStatus'] = 'Successful' expected_result['PackageType'] = None expected_result2 = dict(expected_result) expected_result2['FunctionArn'] = str( lambda_api.func_arn(self.FUNCTION_NAME)) + ':2' expected_result2['Version'] = '2' self.assertDictEqual(expected_result, result) self.assertDictEqual(expected_result2, result2)
def test_create_alias(self): self._create_function(self.FUNCTION_NAME) self.client.post('{0}/functions/{1}/versions'.format(lambda_api.PATH_ROOT, self.FUNCTION_NAME)) response = self.client.post('{0}/functions/{1}/aliases'.format(lambda_api.PATH_ROOT, self.FUNCTION_NAME), data=json.dumps({'Name': self.ALIAS_NAME, 'FunctionVersion': '1', 'Description': ''})) result = json.loads(response.get_data()) result.pop('RevisionId', None) # we need to remove this, since this is random, so we cannot know its value expected_result = {'AliasArn': lambda_api.func_arn(self.FUNCTION_NAME) + ':' + self.ALIAS_NAME, 'FunctionVersion': '1', 'Description': '', 'Name': self.ALIAS_NAME} self.assertDictEqual(expected_result, result)
def _create_function(self, function_name, tags={}): arn = lambda_api.func_arn(function_name) lambda_api.arn_to_lambda[arn] = LambdaFunction(arn) lambda_api.arn_to_lambda[arn].versions = { '$LATEST': {'CodeSize': self.CODE_SIZE, 'CodeSha256': self.CODE_SHA_256, 'RevisionId': self.REVISION_ID} } lambda_api.arn_to_lambda[arn].handler = self.HANDLER lambda_api.arn_to_lambda[arn].runtime = self.RUNTIME lambda_api.arn_to_lambda[arn].timeout = self.TIMEOUT lambda_api.arn_to_lambda[arn].tags = tags lambda_api.arn_to_lambda[arn].envvars = {} lambda_api.arn_to_lambda[arn].last_modified = self.LAST_MODIFIED lambda_api.arn_to_lambda[arn].role = self.ROLE lambda_api.arn_to_lambda[arn].memory_size = self.MEMORY_SIZE
def test_untag_resource(self): with self.app.test_request_context(): self._create_function(self.FUNCTION_NAME, tags=self.TAGS) arn = lambda_api.func_arn(self.FUNCTION_NAME) response = self.client.get('{0}/tags/{1}'.format(lambda_api.PATH_ROOT, arn)) result = json.loads(response.get_data()) self.assertTrue('Tags' in result) self.assertDictEqual(self.TAGS, result['Tags']) self.client.delete('{0}/tags/{1}'.format(lambda_api.PATH_ROOT, arn), query_string={'tagKeys': 'env'}) response = self.client.get('{0}/tags/{1}'.format(lambda_api.PATH_ROOT, arn)) result = json.loads(response.get_data()) self.assertTrue('Tags' in result) self.assertDictEqual({'hello': 'world'}, result['Tags'])
def test_create_alias_returns_error_if_already_exists(self): self._create_function(self.FUNCTION_NAME) self.client.post('{0}/functions/{1}/versions'.format(lambda_api.PATH_ROOT, self.FUNCTION_NAME)) data = json.dumps({'Name': self.ALIAS_NAME, 'FunctionVersion': '1', 'Description': ''}) self.client.post('{0}/functions/{1}/aliases'.format(lambda_api.PATH_ROOT, self.FUNCTION_NAME), data=data) response = self.client.post('{0}/functions/{1}/aliases'.format(lambda_api.PATH_ROOT, self.FUNCTION_NAME), data=data) result = json.loads(response.get_data()) alias_arn = lambda_api.func_arn(self.FUNCTION_NAME) + ':' + self.ALIAS_NAME self.assertEqual(self.ALIASEXISTS_EXCEPTION, result['__type']) self.assertEqual(self.ALIASEXISTS_MESSAGE % alias_arn, result['message'])
def test_put_subscription_filter_lambda(self, lambda_client, logs_client, create_lambda_function): test_lambda_name = f"test-lambda-function-{short_uid()}" # TODO add as fixture create_lambda_function( handler_file=TEST_LAMBDA_PYTHON3, libs=TEST_LAMBDA_LIBS, func_name=test_lambda_name, runtime=LAMBDA_RUNTIME_PYTHON36, ) lambda_client.invoke(FunctionName=test_lambda_name, Payload=b"{}") log_group_name = f"/aws/lambda/{test_lambda_name}" logs_client.put_subscription_filter( logGroupName=log_group_name, filterName="test", filterPattern="", destinationArn=func_arn(test_lambda_name), ) log_stream_name = f"test-log-stream-{short_uid()}" logs_client.create_log_stream(logGroupName=log_group_name, logStreamName=log_stream_name) logs_client.put_log_events( logGroupName=log_group_name, logStreamName=log_stream_name, logEvents=[ { "timestamp": now_utc(millis=True), "message": "test" }, { "timestamp": now_utc(millis=True), "message": "test 2" }, ], ) response = logs_client.describe_subscription_filters( logGroupName=log_group_name) assert len(response["subscriptionFilters"]) == 1 def check_invocation(): events = testutil.get_lambda_log_events(test_lambda_name) assert len(events) == 2 retry(check_invocation, retries=6, sleep=3.0)
def _create_function(self, function_name, tags={}): region = lambda_api.LambdaRegion.get() arn = lambda_api.func_arn(function_name) region.lambdas[arn] = LambdaFunction(arn) region.lambdas[arn].versions = { '$LATEST': {'CodeSize': self.CODE_SIZE, 'CodeSha256': self.CODE_SHA_256, 'RevisionId': self.REVISION_ID} } region.lambdas[arn].handler = self.HANDLER region.lambdas[arn].runtime = self.RUNTIME region.lambdas[arn].timeout = self.TIMEOUT region.lambdas[arn].tags = tags region.lambdas[arn].envvars = {} region.lambdas[arn].last_modified = self.LAST_MODIFIED region.lambdas[arn].role = self.ROLE region.lambdas[arn].memory_size = self.MEMORY_SIZE
def test_put_subscribe_policy(self): lambda_client = aws_stack.connect_to_service('lambda') log_client = aws_stack.connect_to_service('logs') testutil.create_lambda_function(handler_file=TEST_LAMBDA_PYTHON3, libs=TEST_LAMBDA_LIBS, func_name=TEST_LAMBDA_NAME_PY3, runtime=LAMBDA_RUNTIME_PYTHON36) lambda_client.invoke(FunctionName=TEST_LAMBDA_NAME_PY3, Payload=b'{}') log_group_name = '/aws/lambda/{}'.format(TEST_LAMBDA_NAME_PY3) log_client.put_subscription_filter( logGroupName=log_group_name, filterName='test', filterPattern='', destinationArn=func_arn(TEST_LAMBDA_NAME_PY3), ) stream = 'ls-%s' % short_uid() log_client.create_log_stream(logGroupName=log_group_name, logStreamName=stream) log_client.put_log_events( logGroupName=log_group_name, logStreamName=stream, logEvents=[ { 'timestamp': 0, 'message': 'test' }, { 'timestamp': 0, 'message': 'test 2' }, ], ) resp2 = log_client.describe_subscription_filters( logGroupName=log_group_name) self.assertEqual(len(resp2['subscriptionFilters']), 1) def check_invocation(): events = testutil.get_lambda_log_events(TEST_LAMBDA_NAME_PY3) self.assertEqual(len(events), 2) retry(check_invocation, retries=6, sleep=3.0)
def test_create_alias_returns_error_if_already_exists(self): with self.app.test_request_context(): self._create_function(self.FUNCTION_NAME) lambda_api.publish_version(self.FUNCTION_NAME) flask.request.data = json.dumps({ 'Name': self.ALIAS_NAME, 'FunctionVersion': '1', 'Description': '' }) lambda_api.create_alias(self.FUNCTION_NAME).get_data() result = json.loads( lambda_api.create_alias(self.FUNCTION_NAME).get_data()) alias_arn = lambda_api.func_arn( self.FUNCTION_NAME) + ':' + self.ALIAS_NAME self.assertEqual(self.ALIASEXISTS_EXCEPTION, result['__type']) self.assertEqual(self.ALIASEXISTS_MESSAGE % alias_arn, result['message'])
def test_destroy_idle_containers(self): # run these tests only for the "reuse containers" Lambda executor if not isinstance(lambda_api.LAMBDA_EXECUTOR, lambda_executors.LambdaExecutorReuseContainers): return executor = lambda_api.LAMBDA_EXECUTOR func_name = 'test_destroy_idle_containers' func_arn = lambda_api.func_arn(func_name) # make sure existing containers are gone executor.destroy_existing_docker_containers() self.assertEqual(len(executor.get_all_container_names()), 0) # deploy and invoke lambda without Docker zip_file = testutil.create_lambda_archive( load_file(TEST_LAMBDA_ENV), get_content=True, libs=TEST_LAMBDA_LIBS, runtime=LAMBDA_RUNTIME_PYTHON27 ) testutil.create_lambda_function( func_name=func_name, zip_file=zip_file, runtime=LAMBDA_RUNTIME_PYTHON27, envvars={'Hello': 'World'} ) self.assertEqual(len(executor.get_all_container_names()), 0) self.lambda_client.invoke(FunctionName=func_name, Payload=b'{}') self.assertEqual(len(executor.get_all_container_names()), 1) # try to destroy idle containers. executor.idle_container_destroyer() self.assertEqual(len(executor.get_all_container_names()), 1) # simulate an idle container executor.function_invoke_times[func_arn] = time.time() - lambda_executors.MAX_CONTAINER_IDLE_TIME_MS executor.idle_container_destroyer() self.assertEqual(len(executor.get_all_container_names()), 0) # clean up testutil.delete_lambda_function(func_name)
def test_untag_resource(self): with self.app.test_request_context(): self._create_function(self.FUNCTION_NAME, tags=self.TAGS) arn = lambda_api.func_arn(self.FUNCTION_NAME) response = self.client.get("{0}/tags/{1}".format( lambda_api.PATH_ROOT, arn)) result = json.loads(response.get_data()) self.assertTrue("Tags" in result) self.assertDictEqual(self.TAGS, result["Tags"]) self.client.delete( "{0}/tags/{1}".format(lambda_api.PATH_ROOT, arn), query_string={"tagKeys": "env"}, ) response = self.client.get("{0}/tags/{1}".format( lambda_api.PATH_ROOT, arn)) result = json.loads(response.get_data()) self.assertTrue("Tags" in result) self.assertDictEqual({"hello": "world"}, result["Tags"])
def test_tag_resource(self): with self.app.test_request_context(): self._create_function(self.FUNCTION_NAME) arn = lambda_api.func_arn(self.FUNCTION_NAME) response = self.client.get("{0}/tags/{1}".format( lambda_api.PATH_ROOT, arn)) result = json.loads(response.get_data()) self.assertTrue("Tags" in result) self.assertDictEqual({}, result["Tags"]) self.client.post( "{0}/tags/{1}".format(lambda_api.PATH_ROOT, arn), data=json.dumps({"Tags": self.TAGS}), ) response = self.client.get("{0}/tags/{1}".format( lambda_api.PATH_ROOT, arn)) result = json.loads(response.get_data()) self.assertTrue("Tags" in result) self.assertDictEqual(self.TAGS, result["Tags"])
def test_destroy_idle_containers(): # run these tests only for the "reuse containers" Lambda executor if not isinstance(lambda_api.LAMBDA_EXECUTOR, lambda_executors.LambdaExecutorReuseContainers): return executor = lambda_api.LAMBDA_EXECUTOR func_name = 'test_destroy_idle_containers' # create a new lambda lambda_client = aws_stack.connect_to_service('lambda') func_arn = lambda_api.func_arn(func_name) # make sure existing containers are gone executor.destroy_existing_docker_containers() assert len(executor.get_all_container_names()) == 0 # deploy and invoke lambda without Docker zip_file = testutil.create_lambda_archive(load_file(TEST_LAMBDA_ENV), get_content=True, libs=TEST_LAMBDA_LIBS, runtime=LAMBDA_RUNTIME_PYTHON27) testutil.create_lambda_function(func_name=func_name, zip_file=zip_file, runtime=LAMBDA_RUNTIME_PYTHON27, envvars={'Hello': 'World'}) assert len(executor.get_all_container_names()) == 0 lambda_client.invoke(FunctionName=func_name, Payload=b'{}') assert len(executor.get_all_container_names()) == 1 # try to destroy idle containers. executor.idle_container_destroyer() assert len(executor.get_all_container_names()) == 1 # simulate an idle container executor.function_invoke_times[func_arn] = time.time() - 610 executor.idle_container_destroyer() assert len(executor.get_all_container_names()) == 0
def test_prime_and_destroy_containers(): # run these tests only for the "reuse containers" Lambda executor if not isinstance(lambda_api.LAMBDA_EXECUTOR, lambda_executors.LambdaExecutorReuseContainers): return executor = lambda_api.LAMBDA_EXECUTOR func_name = 'test_prime_and_destroy_containers' # create a new lambda lambda_client = aws_stack.connect_to_service('lambda') func_arn = lambda_api.func_arn(func_name) # make sure existing containers are gone executor.cleanup() assert len(executor.get_all_container_names()) == 0 # deploy and invoke lambda without Docker zip_file = testutil.create_lambda_archive(load_file(TEST_LAMBDA_ENV), get_content=True, libs=TEST_LAMBDA_LIBS, runtime=LAMBDA_RUNTIME_PYTHON27) testutil.create_lambda_function(func_name=func_name, zip_file=zip_file, runtime=LAMBDA_RUNTIME_PYTHON27, envvars={'Hello': 'World'}) assert len(executor.get_all_container_names()) == 0 assert executor.function_invoke_times == {} # invoke a few times. durations = [] num_iterations = 3 for i in range(0, num_iterations + 1): prev_invoke_time = None if i > 0: prev_invoke_time = executor.function_invoke_times[func_arn] start_time = time.time() lambda_client.invoke(FunctionName=func_name, Payload=b'{}') duration = time.time() - start_time assert len(executor.get_all_container_names()) == 1 # ensure the last invoke time is being updated properly. if i > 0: assert executor.function_invoke_times[func_arn] > prev_invoke_time else: assert executor.function_invoke_times[func_arn] > 0 durations.append(duration) # the first call would have created the container. subsequent calls would reuse and be faster. for i in range(1, num_iterations + 1): assert durations[i] < durations[0] status = executor.get_docker_container_status(func_arn) assert status == 1 executor.cleanup() status = executor.get_docker_container_status(func_arn) assert status == 0 assert len(executor.get_all_container_names()) == 0