def test_invoke_mocking_bucket_invalid_json(self, mock_es, mock_es_index, mock_bucket, mock_change_file): mock_bucket.return_value = '{ }' valid_event_obj = json.loads(self.valid_event) with self.assertRaises(ValueError) as cm: index.lambda_handler(valid_event_obj, None) self.assertEqual('Invalid json file input', str(cm.exception))
def test_on_session_started_called(self, index_mock): index.lambda_handler(self.alexa_start, self.context) index_mock.assert_called_with( { 'requestId': self.alexa_start['request']['requestId'], 'sessionId': self.alexa_start['session']['sessionId'] }, self.alexa_start['session'])
def test_invoke_without_variables(self): os.environ.pop("lambda_action_on_process") os.environ.pop("my_endpoint_url") with self.assertRaises(ValueError) as cm: index.lambda_handler(None, None) self.assertEqual('Missing variables', str(cm.exception)) self.assertRaises(ValueError, index.lambda_handler, None, None) self.setUp()
def test_invalid_event(self): event = "Invalid Event object" response = index.lambda_handler(event, None) self.assertEqual("Oops! Error!", response["text"]) event = {"lang": "en-US"} response = index.lambda_handler(event, None) self.assertEqual("I could not find the desired data.", response["text"])
def test_invoke_with_invalid_event_just_bucket(self, mock_es, mock_es_index): invalid_event = '{ "Records":' \ ' [{ "s3":' \ ' { "bucket": ' \ ' { "name": "fake-bucket-name" } ' \ ' } ' \ ' }] ' \ '}' invalid_event_obj = json.loads(invalid_event) with self.assertRaises(ValueError) as cm: index.lambda_handler(invalid_event_obj, None) self.assertEqual('Invalid event record', str(cm.exception))
def test_search(self): url = 'https://www.example.com:443/bucket/_search?' + urlencode( dict( size=1000, _source=','.join([ 'key', 'version_id', 'updated', 'last_modified', 'size', 'user_meta' ]), )) def _callback(request): payload = json.loads(request.body) assert payload['query'] assert payload['query']['query_string'] assert payload['query']['query_string']['fields'] assert payload['query']['query_string']['query'] return 200, {}, json.dumps({'results': 'blah'}) self.requests_mock.add_callback(responses.GET, url, callback=_callback, content_type='application/json', match_querystring=False) query = { 'action': 'search', 'index': 'bucket', 'query': '123', } event = self._make_event(query) resp = lambda_handler(event, None) assert resp['statusCode'] == 200 assert json.loads(resp['body']) == {'results': 'blah'}
def test_search(self): url = 'https://www.example.com:443/bucket/_search?size=10&timeout=15s' def _callback(request): payload = json.loads(request.body) assert payload == {'q': 123} return 200, {}, json.dumps({'results': 'blah'}) self.requests_mock.add_callback(responses.GET, url, callback=_callback, content_type='application/json', match_querystring=True) query = { 'source': { 'q': 123 }, 'size': '10', } event = self._make_event('bucket', query) resp = lambda_handler(event, None) assert resp['statusCode'] == 200 assert json.loads(resp['body']) == {'results': 'blah'}
def test_missing_as_path(): setup_parameters() event = get_event() event['ResourceProperties'] = {'ParameterPaths': ['/no/such/path']} response = index.lambda_handler(event) assert response['Status'] == 'SUCCESS' assert response['Data'] == {}
def test_success_all(): setup_parameters() event = get_event() response = index.lambda_handler(event) data = response['Data'] assert response['Status'] == 'SUCCESS' assert response['StackId'] == event['StackId'] assert response['LogicalResourceId'] == event['LogicalResourceId'] assert len(response['PhysicalResourceId']) > 0 assert response['RequestId'] == event['RequestId'] for i in [params, params_as_path]: for k, v in i.items(): assert param_is_expected(data[k], v) for k in event['ResourceProperties']['ParameterPathsAsList']: expected = [ y[0] if y[1] != 'StringList' else [z.strip() for z in y[0].split(',')] for x, y in params_as_list.items() if x.startswith(k) ] assert len(expected) == len(data[k]) for v in expected: assert v in data[k]
def test_search_retry(self): """test standard search function""" url = 'https://www.example.com:443/bucket/_search?' + urlencode({ 'size': 1000, 'from': 0, '_source': ','.join([ 'key', 'version_id', 'updated', 'last_modified', 'size', 'user_meta', 'comment', 'handle', 'hash', 'tags', 'metadata', 'pointer_file', 'delete_marker', ]), 'terminate_after': 10000, }) def _callback(request): payload = json.loads(request.body) assert payload['query'] if retry < 2: assert payload['query']['query_string'] assert payload['query']['query_string']['fields'] assert payload['query']['query_string']['query'] else: assert payload['query']['simple_query_string'] return 200, {}, json.dumps({'results': 'blah'}) self.requests_mock.add_callback( responses.GET, url, callback=_callback, content_type='application/json', match_querystring=True, ) for retry in [0, 1, 2, 3]: query = { 'action': 'search', 'index': 'bucket', 'query': '123', 'retry': retry, } event = self._make_event(query) resp = lambda_handler(event, None) assert resp['statusCode'] == 200 assert json.loads(resp['body']) == {'results': 'blah'}
def test_delete(): event = get_event() event['RequestType'] = 'Delete' response = lambda_handler(event) assert response['Status'] == 'SUCCESS' assert response['StackId'] == event['StackId'] assert response['LogicalResourceId'] == event['LogicalResourceId'] assert response['RequestId'] == event['RequestId']
def test_stats(self): url = 'https://www.example.com:443/bucket/_search?' + urlencode( dict( timeout='15s', terminate_after=10000, size=0, _source='', )) def _callback(request): payload = json.loads(request.body) assert payload == { "query": { "match_all": {} }, "aggs": { "totalBytes": { "sum": { "field": 'size' } }, "exts": { "terms": { "field": 'ext' }, "aggs": { "size": { "sum": { "field": 'size' } } }, }, "updated": { "max": { "field": 'updated' } }, } } return 200, {}, json.dumps({'results': 'blah'}) self.requests_mock.add_callback(responses.GET, url, callback=_callback, content_type='application/json', match_querystring=True) query = { 'action': 'stats', 'index': 'bucket', } event = self._make_event(query) resp = lambda_handler(event, None) assert resp['statusCode'] == 200 assert json.loads(resp['body']) == {'results': 'blah'}
def test_no_such_hosted_zone(): event = get_event() response = lambda_handler(event) assert 'Status' in response assert response['Status'] == 'FAILED' assert response['StackId'] == event['StackId'] assert response['LogicalResourceId'] == event['LogicalResourceId'] assert response['RequestId'] == event['RequestId'] assert response['Reason'].startswith('An error occurred (')
def test_stats(self): url = 'https://www.example.com:443/bucket/_search?' + urlencode( dict( _source= 'false', # must match JSON; False will fail match_querystring size=0, )) def _callback(request): payload = json.loads(request.body) assert payload == { "query": { "match_all": {} }, "aggs": { "totalBytes": { "sum": { "field": "size" } }, "exts": { "terms": { "field": 'ext' }, "aggs": { "size": { "sum": { "field": "size" } } }, }, "totalPackageHandles": { "value_count": { "field": "handle" } }, } } # use 'all_gz' since it's not altered by the handler return 200, {}, json.dumps(ES_STATS_RESPONSES['all_gz']) self.requests_mock.add_callback(responses.GET, url, callback=_callback, content_type='application/json', match_querystring=True) query = { 'action': 'stats', 'index': 'bucket', } event = self._make_event(query) resp = lambda_handler(event, None) assert resp['statusCode'] == 200 assert json.loads(resp['body']) == ES_STATS_RESPONSES['all_gz']
def test_stats(self): """test overview statistics""" url = 'https://www.example.com:443/bucket/_search?' + urlencode( { '_source': 'false', # must match JSON; False will fail match_querystring 'size': 0, 'from': 0, }) def _callback(request): payload = json.loads(request.body) assert payload == { "query": { "term": { "delete_marker": False } }, "aggs": { "totalBytes": { "sum": { "field": 'size' } }, "exts": { "terms": { "field": 'ext' }, "aggs": { "size": { "sum": { "field": 'size' } } }, }, } } # use 'all_gz' since it's not altered by the handler return 200, {}, json.dumps(ES_STATS_RESPONSES['all_gz']) self.requests_mock.add_callback(responses.GET, url, callback=_callback, content_type='application/json', match_querystring=True) query = { 'action': 'stats', 'index': 'bucket', } event = self._make_event(query) resp = lambda_handler(event, None) assert resp['statusCode'] == 200 assert json.loads(resp['body']) == ES_STATS_RESPONSES['all_gz']
def test_ambiguous_params(): event = get_event() event['ResourceProperties']['DBClusterIdentifier'] = 'my-cluster' response = lambda_handler(event) assert 'Status' in response assert response['Status'] == 'FAILED' assert response['StackId'] == event['StackId'] assert response['LogicalResourceId'] == event['LogicalResourceId'] assert response['RequestId'] == event['RequestId'] assert response['Reason'] == MSG_AMBIGUOUS_PROPS
def test(self, urlopen_mock): test_url = 'https://example.com' test_data = b'blah' urlopen_mock.return_value = io.BytesIO(test_data) assert index.lambda_handler( test_url, mock.MagicMock()) == hashlib.sha256(test_data).hexdigest() urlopen_mock.assert_called_once_with(test_url) assert urlopen_mock.return_value.closed
def test_empty_params(): event = get_event() del event['ResourceProperties'] response = lambda_handler(event) assert 'Status' in response assert response['Status'] == 'FAILED' assert response['StackId'] == event['StackId'] assert response['LogicalResourceId'] == event['LogicalResourceId'] assert response['RequestId'] == event['RequestId'] assert response['Reason'] == MSG_EMPTY_PROPS
def test_missing_params(): event = get_event() event['ResourceProperties'] = {'SomeGarbage': 'DoNotWant'} response = lambda_handler(event) assert 'Status' in response assert response['Status'] == 'FAILED' assert response['StackId'] == event['StackId'] assert response['LogicalResourceId'] == event['LogicalResourceId'] assert response['RequestId'] == event['RequestId'] assert response['Reason'] == MSG_MISSING_PROP
def test_no_such_instance(): event = get_event() response = lambda_handler(event) assert 'Status' in response assert response['Status'] == 'FAILED' assert response['StackId'] == event['StackId'] assert response['LogicalResourceId'] == event['LogicalResourceId'] assert response['RequestId'] == event['RequestId'] assert response['Reason'] == 'An error occurred (DBInstanceNotFound) ' \ 'when calling the DescribeDBInstances ' \ 'operation: Database some-db not found.'
def test_no_such_vpc(): event = get_event() response = lambda_handler(event) assert 'Status' in response assert response['Status'] == 'FAILED' assert response['StackId'] == event['StackId'] assert response['LogicalResourceId'] == event['LogicalResourceId'] assert response['RequestId'] == event['RequestId'] assert response['Reason'] == 'An error occurred (InvalidVpcID.NotFound) ' \ 'when calling the DescribeVpcs operation: ' \ 'VpcID {\'changeme\'} does not exist.'
def skip_test_no_such_cluster(): event = get_event() event["ResourceProperties"] = {"DBClusterIdentifier": "some-cluster"} response = lambda_handler(event) assert 'Status' in response assert response['Status'] == 'FAILED' assert response['StackId'] == event['StackId'] assert response['LogicalResourceId'] == event['LogicalResourceId'] assert response['RequestId'] == event['RequestId'] assert response['Reason'] == 'An error occurred (DBClusterNotFound) ' \ 'when calling the DescribeDBClusters ' \ 'operation: Cluster some-cluster not found.'
def test_valid_event(self): result = {'temp_max': 50, 'temp_min': 20} mocked_request = mock.patch('index.get_weather_forecast', return_value=result) mocked_request.start() event = {"city" : "Toronto", "lang": "fr-FR"} response = index.lambda_handler(event, None) mocked_request.stop() self.assertIn("Les prévisions météo pour aujourd'hui dans la ville de Toronto est le maximum", response["text"])
def test_packages_bad(self): """test packages action with known bad index param""" query = { 'action': 'packages', 'index': 'bucket', 'body': { 'custom': 'body' }, 'size': 42, '_source': ['great', 'expectations'] } # try a known bad query event = self._make_event(query) resp = lambda_handler(event, None) assert resp['statusCode'] == 500
def test_success_basic(): hosted_zone_name = 'bestzoneevar.com.' hosted_zone_id = create_zone(hosted_zone_name) event = get_event() event['ResourceProperties']['HostedZoneId'] = hosted_zone_id response = lambda_handler(event) assert response['Status'] == 'SUCCESS' assert response['StackId'] == event['StackId'] assert response['LogicalResourceId'] == event['LogicalResourceId'] assert response['PhysicalResourceId'] == hosted_zone_id assert response['RequestId'] == event['RequestId'] data = response['Data'] assert data['Name'] == hosted_zone_name
def test_success_basic(): create_network() event = get_event() event['ResourceProperties']['VpcId'] = vpc_id response = lambda_handler(event) assert response['Status'] == 'SUCCESS' assert response['StackId'] == event['StackId'] assert response['LogicalResourceId'] == event['LogicalResourceId'] assert response['PhysicalResourceId'] == vpc_id assert response['RequestId'] == event['RequestId'] data = response['Data'] assert data['CidrBlock'] == vpc assert set(data['AvailabilityZones']) == set(subnets.keys()) assert set(data['SubnetIds']) == set(subnet_ids)
def _handle_request(self, req_body): parsed_url = urlparse(self.path) path = unquote(parsed_url.path) if path == LAMBDA_PATH or path.startswith(LAMBDA_PATH + '/'): query = dict(parse_qsl(parsed_url.query, keep_blank_values=True)) # BaseHTTPRequestHandler API gives us a case-insensitive dict # of headers, while the lambda API uses lowercase header names. # So change the keys to lowercase to match the lambda API. headers = {k.lower(): v for k, v in self.headers.items()} args = { 'httpMethod': self.command, 'path': path, 'pathParameters': { 'proxy': path[len(LAMBDA_PATH) + 1:] }, 'queryStringParameters': query or None, 'headers': headers or None, 'body': b64encode(req_body or b''), 'isBase64Encoded': True } result = lambda_handler(args, None) code = result['statusCode'] headers = result['headers'] body = result['body'] encoded = result.get("isBase64Encoded", False) if encoded: body = b64decode(body) else: body = body.encode() headers['Content-Length'] = str(len(body)) self.send_response(code) for name, value in headers.items(): self.send_header(name, value) self.end_headers() self.wfile.write(body) else: self.send_response(404) self.send_header('Content-Type', 'text/plain') self.end_headers() self.wfile.write(b'Not Found')
def test_packages_bad_from(self): """test packages action with known bad from param""" for from_value in [-1, 'one']: query = { 'action': 'packages', 'index': 'bucket_packages', 'body': { 'custom': 'body' }, 'size': 42, # this should barf 'from': from_value, '_source': ['great', 'expectations'] } # try a known bad query event = self._make_event(query) resp = lambda_handler(event, None) assert resp['statusCode'] == 500 assert 'int' in resp['body']
def test_filters_return_empty(): create_network() event = get_event() event['ResourceProperties']['VpcId'] = vpc_id event['ResourceProperties']['SubnetFilters'] = [{ 'Name': 'availabilityZone', 'Values': ['us-east-1z'] }] response = lambda_handler(event) assert response['Status'] == 'SUCCESS' assert response['StackId'] == event['StackId'] assert response['LogicalResourceId'] == event['LogicalResourceId'] assert response['PhysicalResourceId'] == vpc_id assert response['RequestId'] == event['RequestId'] data = response['Data'] assert data['CidrBlock'] == vpc assert len(data['AvailabilityZones']) == 0 assert len(data['SubnetIds']) == 0
def test_success_instance(): instance_id = 'my-rds-instance' database_name = 'my-database' engine = 'mysql' engine_version = '1.2.3' master_username = '******' # Create the database instance client = boto3.client('rds') client.create_db_instance(DBName=database_name, DBInstanceIdentifier=instance_id, AllocatedStorage=10, DBInstanceClass='t2.small', Engine=engine, EngineVersion=engine_version, MasterUsername=master_username, MasterUserPassword='******', EnableIAMDatabaseAuthentication=True) event = get_event() event['ResourceProperties']['DBInstanceIdentifier'] = instance_id response = lambda_handler(event) assert response['Status'] == 'SUCCESS' assert response['StackId'] == event['StackId'] assert response['LogicalResourceId'] == event['LogicalResourceId'] assert response['PhysicalResourceId'] == instance_id assert response['RequestId'] == event['RequestId'] data = response['Data'] assert data['MasterUsername'] == master_username assert data['DBName'] == database_name assert data['Engine'] == engine assert data['EngineVersion'] == engine_version assert 'Arn' in data assert 'Endpoint.Port' in data assert 'Endpoint.Address' in data assert 'ReadEndpoint.Address' in data assert data['ReadEndpoint.Address'] == data['Endpoint.Address']
import json import sys sys.path.insert(0, '../src') import index ## the Lambda source code file at ../src/index.py with open('events/alexa-start-session.json') as test_request: ## the request JSON stored in a separate file request_json = json.load(test_request) # print request_json myEvent = json.loads(json.dumps(request_json)) myContext = '{}' # print("testing your Lambda Python function") res = index.lambda_handler(myEvent, myContext) ## execute the source code print(res)