def test_on_package_created_products(order, listener, table_name, event_bus_name): """ Test OnEvents function on a PackageCreated event when there are less products """ eventbridge = boto3.client("events") table = boto3.resource("dynamodb").Table(table_name) # pylint: disable=no-member # Store order in DynamoDB table table.put_item(Item=order) package_order = copy.deepcopy(order) removed_product = package_order["products"].pop(0) # Create the event event = { "Time": datetime.datetime.now(), "Source": "ecommerce.warehouse", "DetailType": "PackageCreated", "Resources": [order["orderId"]], "Detail": json.dumps(package_order), "EventBusName": event_bus_name } # Check events listener( "ecommerce.orders", lambda: eventbridge.put_events(Entries=[event]), lambda m: (order["orderId"] in m["resources"] and m[ "detail-type"] == "OrderModified" and "status" in m["detail"][ "changed"] and "products" in m["detail"]["changed"] and m[ "detail"]["new"]["status"] == "PACKAGED")) # Clean up table.delete_item(Key={"orderId": order["orderId"]})
def test_on_delivery_failed(order, listener, table_name, event_bus_name): """ Test OnEvents function on a DeliveryFailed event """ eventbridge = boto3.client("events") table = boto3.resource("dynamodb").Table(table_name) # pylint: disable=no-member # Store order in DynamoDB table table.put_item(Item=order) # Create the event event = { "Time": datetime.datetime.now(), "Source": "ecommerce.delivery", "DetailType": "DeliveryFailed", "Resources": [order["orderId"]], "Detail": json.dumps(order), "EventBusName": event_bus_name } # Check events listener( "ecommerce.orders", lambda: eventbridge.put_events(Entries=[event]), lambda m: (order["orderId"] in m["resources"] and m["detail-type"] == "OrderModified" and "status" in m["detail"]["changed"] and m["detail"]["new"]["status"] == "DELIVERY_FAILED")) # Clean up table.delete_item(Key={"orderId": order["orderId"]})
def test_table_update_failed(table_name, listener, order): """ Test that the TableUpdate function reacts to changes to DynamoDB and sends events to EventBridge """ table = boto3.resource("dynamodb").Table(table_name) # pylint: disable=no-member # Add a new item order["status"] = "NEW" table.put_item(Item=order) # Delete the item table.delete_item(Key={"orderId": order["orderId"]}) # Listen for messages on EventBridge through a listener SQS queue messages = listener("delivery") # Parse messages found = False for message in messages: print("MESSAGE RECEIVED:", message) body = json.loads(message["Body"]) if order["orderId"] in body["resources"]: found = True assert body["detail-type"] == "DeliveryFailed" assert found == True
def test_table_update_failed(table_name, listener, order): """ Test that the TableUpdate function reacts to changes to DynamoDB and sends events to EventBridge """ table = boto3.resource("dynamodb").Table(table_name) # pylint: disable=no-member # Add a new item order["status"] = "NEW" table.put_item(Item=order) # Listen for messages on EventBridge through a listener SQS queue listener( "ecommerce.delivery", lambda: table.delete_item(Key={"orderId": order["orderId"]}), lambda m: order["orderId"] in m["resources"] and m[ "detail-type"] == "DeliveryFailed")
def test_on_package_created_products(order, listener, table_name, event_bus_name): """ Test OnEvents function on a PackageCreated event when there are less products """ eventbridge = boto3.client("events") table = boto3.resource("dynamodb").Table(table_name) # pylint: disable=no-member # Store order in DynamoDB table table.put_item(Item=order) package_order = copy.deepcopy(order) removed_product = package_order["products"].pop(0) # Create the event event = { "Time": datetime.datetime.now(), "Source": "ecommerce.warehouse", "DetailType": "PackageCreated", "Resources": [order["orderId"]], "Detail": json.dumps(package_order), "EventBusName": event_bus_name } eventbridge.put_events(Entries=[event]) # Wait time.sleep(5) # Check the DynamoDB table response = table.get_item(Key={"orderId": order["orderId"]}) assert "Item" in response assert "status" in response["Item"] assert response["Item"]["status"] == "PACKAGED" assert len(response["Item"]["products"]) == len(package_order["products"]) assert removed_product["productId"] not in [ p["productId"] for p in response["Item"]["products"] ] # Check events messages = listener("orders", 5) found = False for message in messages: print("MESSAGE RECEIVED:", message) body = json.loads(message["Body"]) if order["orderId"] in body["resources"] and body[ "detail-type"] == "OrderModified": found = True assert "status" in body["detail"]["changed"] assert "products" in body["detail"]["changed"] assert body["detail"]["new"]["status"] == "PACKAGED" assert found == True # Clean up table.delete_item(Key={"orderId": order["orderId"]})
def test_table_update(table_name, listener, product): """ Test that the TableUpdate function reacts to changes to DynamoDB and sends events to EventBridge """ # Add a new item table = boto3.resource("dynamodb").Table(table_name) # pylint: disable=no-member # Listen for messages on EventBridge listener( "ecommerce.products", lambda: table.put_item(Item=product), lambda m: product["productId"] in m["resources"] and m[ "detail-type"] == "ProductCreated") # Listen for messages on EventBridge listener( "ecommerce.products", lambda: table.delete_item(Key={"productId": product["productId"]}), lambda m: product["productId"] in m["resources"] and m[ "detail-type"] == "ProductDeleted")
def test_sign_up(listener): """ Test that the SignUp function reacts to new users in Cognito User Pools and sends an event to EventBridge """ data = {} def gen_func(): email = "".join(random.choices(string.ascii_lowercase, k=20))+"@example.local" password = "".join( random.choices(string.ascii_uppercase, k=10) + random.choices(string.ascii_lowercase, k=10) + random.choices(string.digits, k=5) + random.choices(string.punctuation, k=3) ) # Create a new user response = cognito.admin_create_user( UserPoolId=COGNITO_USER_POOL, Username=email, UserAttributes=[{ "Name": "email", "Value": email }], # Do not send an email as this is a fake address MessageAction="SUPPRESS" ) data["user_id"] = response["User"]["Username"] def test_func(m): return data["user_id"] in m["resources"] and m["detail-type"] == "UserCreated" # Listen for messages on EventBridge listener("ecommerce.users", gen_func, test_func) cognito.admin_delete_user( UserPoolId=COGNITO_USER_POOL, Username=data["user_id"] )
def test_table_update(table_name, listener, order): """ Test that the TableUpdate function reacts to changes to DynamoDB and sends events to EventBridge """ table = boto3.resource("dynamodb").Table(table_name) # pylint: disable=no-member # Listen for messages on EventBridge listener( "ecommerce.orders", # Add a new item lambda: table.put_item(Item=order), lambda m: order["orderId"] in m["resources"] and m["detail-type"] == "OrderCreated") # Listen for messages on EventBridge listener( "ecommerce.orders", # Change the status to cancelled lambda: table.update_item(Key={"orderId": order["orderId"]}, UpdateExpression="set #s = :s", ExpressionAttributeNames={"#s": "status"}, ExpressionAttributeValues= {":s": "CANCELLED"}), lambda m: order["orderId"] in m["resources"] and m["detail-type"] == "OrderModified") # Listen for messages on EventBridge listener( "ecommerce.orders", # Delete the item lambda: table.delete_item(Key={"orderId": order["orderId"]}), lambda m: order["orderId"] in m["resources"] and m["detail-type"] == "OrderDeleted")
def test_table_update_completed(table_name, listener, order): """ Test that the TableUpdate function reacts to changes to DynamoDB and sends events to EventBridge """ table = boto3.resource("dynamodb").Table(table_name) # pylint: disable=no-member # Add a new item order["status"] = "IN_PROGRESS" table.put_item(Item=order) # Set the item to COMPLETED order["status"] = "COMPLETED" # Listen for messages on EventBridge listener( "ecommerce.delivery", lambda: table.put_item(Item=order), lambda m: order["orderId"] in m["resources"] and m[ "detail-type"] == "DeliveryCompleted") # Delete the item table.delete_item(Key={"orderId": order["orderId"]})
def test_listener(listener, event_bus_name): service_name = "ecommerce.test" resource = str(uuid.uuid4()) event_type = "TestEvent" events = boto3.client("events") listener(service_name, lambda: events.put_events(Entries=[{ "Time": datetime.datetime.utcnow(), "Source": service_name, "Resources": [resource], "DetailType": event_type, "Detail": "{}", "EventBusName": event_bus_name }]), lambda x: ( x["source"] == service_name and x["resources"][0] == resource and x["detail-type"] == event_type ) )
def test_table_update(table_name, listener, product): """ Test that the TableUpdate function reacts to changes to DynamoDB and sends events to EventBridge """ # Add a new item table = boto3.resource("dynamodb").Table(table_name) # pylint: disable=no-member table.put_item(Item=product) # Listen for messages on EventBridge through a listener SQS queue messages = listener("products") # Parse messages found = False for message in messages: print("MESSAGE RECEIVED:", message) body = json.loads(message["Body"]) if product["productId"] in body["resources"]: found = True assert body["detail-type"] == "ProductCreated" assert found == True # Delete the item table.delete_item(Key={"productId": product["productId"]}) # Listen for messages on EventBridge through a listener SQS queue messages = listener("products") # Parse messages found = False for message in messages: print("MESSAGE RECEIVED:", message) body = json.loads(message["Body"]) if product["productId"] in body["resources"]: found = True assert body["detail-type"] == "ProductDeleted" assert found == True
def test_table_update(table_name, metadata, products, listener): """ Test that the TableUpdate function reacts to changes to DynamoDB and sends events to EventBridge """ metadata = copy.deepcopy(metadata) # Create packaging request in DynamoDB table = boto3.resource("dynamodb").Table(table_name) # pylint: disable=no-member with table.batch_writer() as batch: for product in products: batch.put_item(Item=product) batch.put_item(Item=metadata) # Mark the packaging as completed metadata["status"] = "COMPLETED" # Listen for messages on EventBridge listener( "ecommerce.warehouse", lambda: table.put_item(Item=metadata), lambda m: metadata["orderId"] in m["resources"] and m[ "detail-type"] == "PackageCreated") # Clean up the table with table.batch_writer() as batch: table.delete_item(Key={ "orderId": metadata["orderId"], "productId": metadata["productId"] }) for product in products: table.delete_item(Key={ "orderId": product["orderId"], "productId": product["productId"] })
def test_on_delivery_failed(order, listener, table_name, event_bus_name): """ Test OnEvents function on a DeliveryFailed event """ eventbridge = boto3.client("events") table = boto3.resource("dynamodb").Table(table_name) # pylint: disable=no-member # Store order in DynamoDB table table.put_item(Item=order) # Create the event event = { "Time": datetime.datetime.now(), "Source": "ecommerce.delivery", "DetailType": "DeliveryFailed", "Resources": [order["orderId"]], "Detail": json.dumps(order), "EventBusName": event_bus_name } eventbridge.put_events(Entries=[event]) # Wait time.sleep(5) # Check the DynamoDB table response = table.get_item(Key={"orderId": order["orderId"]}) assert "Item" in response assert "status" in response["Item"] assert response["Item"]["status"] == "DELIVERY_FAILED" # Check events messages = listener("orders", 5) found = False for message in messages: print("MESSAGE RECEIVED:", message) body = json.loads(message["Body"]) if order["orderId"] in body["resources"] and body[ "detail-type"] == "OrderModified": found = True assert "status" in body["detail"]["changed"] assert body["detail"]["new"]["status"] == "DELIVERY_FAILED" assert found == True # Clean up table.delete_item(Key={"orderId": order["orderId"]})
def test_table_update(table_name, metadata, products, listener): """ Test that the TableUpdate function reacts to changes to DynamoDB and sends events to EventBridge """ metadata = copy.deepcopy(metadata) # Create packaging request in DynamoDB table = boto3.resource("dynamodb").Table(table_name) # pylint: disable=no-member with table.batch_writer() as batch: for product in products: batch.put_item(Item=product) batch.put_item(Item=metadata) # Mark the packaging as completed metadata["status"] = "COMPLETED" table.put_item(Item=metadata) # Listen for messages on EventBridge through a listener SQS queue messages = listener("warehouse", 15) # Parse messages found = False for message in messages: print("MESSAGE RECEIVED:", message) body = json.loads(message["Body"]) if metadata["orderId"] in body["resources"]: found = True assert body["detail-type"] == "PackageCreated" assert found == True # Clean up the table with table.batch_writer() as batch: table.delete_item(Key={ "orderId": metadata["orderId"], "productId": metadata["productId"] }) for product in products: table.delete_item(Key={ "orderId": product["orderId"], "productId": product["productId"] })
def test_sign_up(listener, user_id): """ Test that the SignUp function reacts to new users in Cognito User Pools and sends an event to EventBridge """ # Listen for messages on EventBridge through a listener SQS queue messages = listener("users") # Parse messages found = False for message in messages: print("MESSAGE RECEIVED:", message) body = json.loads(message["Body"]) if user_id in body["resources"]: found = True assert body["detail-type"] == "UserCreated" assert found == True
def test_table_update(table_name, listener, order): """ Test that the TableUpdate function reacts to changes to DynamoDB and sends events to EventBridge """ # Add a new item table = boto3.resource("dynamodb").Table(table_name) # pylint: disable=no-member table.put_item(Item=order) # Listen for messages on EventBridge through a listener SQS queue messages = listener("orders") # Parse messages found = False for message in messages: print("MESSAGE RECEIVED:", message) body = json.loads(message["Body"]) if order["orderId"] in body["resources"]: found = True assert body["detail-type"] == "OrderCreated" assert found == True # Change the status to cancelled table.update_item(Key={"orderId": order["orderId"]}, UpdateExpression="set #s = :s", ExpressionAttributeNames={"#s": "status"}, ExpressionAttributeValues={":s": "CANCELLED"}) # Listen for messages on EventBridge through a listener SQS queue messages = listener("orders") # Parse messages found = False for message in messages: print("MESSAGE RECEIVED:", message) body = json.loads(message["Body"]) if order["orderId"] in body["resources"]: found = True assert body["detail-type"] == "OrderModified" detail = body["detail"] assert "changed" in detail assert "status" in detail["changed"] assert found == True # Delete the item table.delete_item(Key={"orderId": order["orderId"]}) # Listen for messages on EventBridge through a listener SQS queue messages = listener("orders") # Parse messages found = False for message in messages: print("MESSAGE RECEIVED:", message) body = json.loads(message["Body"]) if order["orderId"] in body["resources"]: found = True assert body["detail-type"] == "OrderDeleted" assert found == True