Techdebt: Replace sure with regular assertions in Logs (#6620)

This commit is contained in:
Bert Blommers 2023-08-10 18:06:46 +00:00 committed by GitHub
parent 110cf01e8a
commit 38bd1af4d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 327 additions and 306 deletions

View File

@ -1,7 +1,6 @@
import base64
from io import BytesIO
import json
import sure # noqa # pylint: disable=unused-import
import time
from zipfile import ZipFile, ZIP_DEFLATED
import zlib
@ -52,10 +51,10 @@ def test_put_subscription_filter_update():
# then
response = client_logs.describe_subscription_filters(logGroupName=log_group_name)
response["subscriptionFilters"].should.have.length_of(1)
assert len(response["subscriptionFilters"]) == 1
sub_filter = response["subscriptionFilters"][0]
creation_time = sub_filter["creationTime"]
creation_time.should.be.a(int)
assert isinstance(creation_time, int)
sub_filter["destinationArn"] = "arn:aws:lambda:us-east-1:123456789012:function:test"
sub_filter["distribution"] = "ByLogStream"
sub_filter["logGroupName"] = "/test"
@ -73,9 +72,9 @@ def test_put_subscription_filter_update():
# then
response = client_logs.describe_subscription_filters(logGroupName=log_group_name)
response["subscriptionFilters"].should.have.length_of(1)
assert len(response["subscriptionFilters"]) == 1
sub_filter = response["subscriptionFilters"][0]
sub_filter["creationTime"].should.equal(creation_time)
assert sub_filter["creationTime"] == creation_time
sub_filter["destinationArn"] = "arn:aws:lambda:us-east-1:123456789012:function:test"
sub_filter["distribution"] = "ByLogStream"
sub_filter["logGroupName"] = "/test"
@ -94,10 +93,10 @@ def test_put_subscription_filter_update():
# then
ex = e.value
ex.operation_name.should.equal("PutSubscriptionFilter")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("LimitExceededException")
ex.response["Error"]["Message"].should.equal("Resource limit exceeded.")
assert ex.operation_name == "PutSubscriptionFilter"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert ex.response["Error"]["Code"] == "LimitExceededException"
assert ex.response["Error"]["Message"] == "Resource limit exceeded."
@mock_lambda
@ -137,9 +136,9 @@ def test_put_subscription_filter_with_lambda():
# then
response = client_logs.describe_subscription_filters(logGroupName=log_group_name)
response["subscriptionFilters"].should.have.length_of(1)
assert len(response["subscriptionFilters"]) == 1
sub_filter = response["subscriptionFilters"][0]
sub_filter["creationTime"].should.be.a(int)
assert isinstance(sub_filter["creationTime"], int)
sub_filter["destinationArn"] = "arn:aws:lambda:us-east-1:123456789012:function:test"
sub_filter["distribution"] = "ByLogStream"
sub_filter["logGroupName"] = "/test"
@ -170,19 +169,19 @@ def test_put_subscription_filter_with_lambda():
response = json.loads(
zlib.decompress(base64.b64decode(data), 16 + zlib.MAX_WBITS).decode("utf-8")
)
response["messageType"].should.equal("DATA_MESSAGE")
response["owner"].should.equal("123456789012")
response["logGroup"].should.equal("/test")
response["logStream"].should.equal("stream")
response["subscriptionFilters"].should.equal(["test"])
assert response["messageType"] == "DATA_MESSAGE"
assert response["owner"] == "123456789012"
assert response["logGroup"] == "/test"
assert response["logStream"] == "stream"
assert response["subscriptionFilters"] == ["test"]
log_events = sorted(response["logEvents"], key=lambda log_event: log_event["id"])
log_events.should.have.length_of(2)
log_events[0]["id"].should.be.a(int)
log_events[0]["message"].should.equal("test")
log_events[0]["timestamp"].should.equal(ts_0)
log_events[1]["id"].should.be.a(int)
log_events[1]["message"].should.equal("test 2")
log_events[1]["timestamp"].should.equal(ts_1)
assert len(log_events) == 2
assert isinstance(log_events[0]["id"], int)
assert log_events[0]["message"] == "test"
assert log_events[0]["timestamp"] == ts_0
assert isinstance(log_events[1]["id"], int)
assert log_events[1]["message"] == "test 2"
assert log_events[1]["timestamp"] == ts_1
@mock_lambda
@ -242,19 +241,19 @@ def test_subscription_filter_applies_to_new_streams():
response = json.loads(
zlib.decompress(base64.b64decode(data), 16 + zlib.MAX_WBITS).decode("utf-8")
)
response["messageType"].should.equal("DATA_MESSAGE")
response["owner"].should.equal("123456789012")
response["logGroup"].should.equal("/test")
response["logStream"].should.equal("stream")
response["subscriptionFilters"].should.equal(["test"])
assert response["messageType"] == "DATA_MESSAGE"
assert response["owner"] == "123456789012"
assert response["logGroup"] == "/test"
assert response["logStream"] == "stream"
assert response["subscriptionFilters"] == ["test"]
log_events = sorted(response["logEvents"], key=lambda log_event: log_event["id"])
log_events.should.have.length_of(2)
log_events[0]["id"].should.be.a(int)
log_events[0]["message"].should.equal("test")
log_events[0]["timestamp"].should.equal(ts_0)
log_events[1]["id"].should.be.a(int)
log_events[1]["message"].should.equal("test 2")
log_events[1]["timestamp"].should.equal(ts_1)
assert len(log_events) == 2
assert isinstance(log_events[0]["id"], int)
assert log_events[0]["message"] == "test"
assert log_events[0]["timestamp"] == ts_0
assert isinstance(log_events[1]["id"], int)
assert log_events[1]["message"] == "test 2"
assert log_events[1]["timestamp"] == ts_1
@mock_s3
@ -303,9 +302,9 @@ def test_put_subscription_filter_with_firehose():
# then
response = client_logs.describe_subscription_filters(logGroupName=log_group_name)
response["subscriptionFilters"].should.have.length_of(1)
assert len(response["subscriptionFilters"]) == 1
_filter = response["subscriptionFilters"][0]
_filter["creationTime"].should.be.a(int)
assert isinstance(_filter["creationTime"], int)
_filter["destinationArn"] = firehose_arn
_filter["distribution"] = "ByLogStream"
_filter["logGroupName"] = "/firehose-test"
@ -333,19 +332,19 @@ def test_put_subscription_filter_with_firehose():
zlib.decompress(message["Body"].read(), 16 + zlib.MAX_WBITS).decode("utf-8")
)
response["messageType"].should.equal("DATA_MESSAGE")
response["owner"].should.equal("123456789012")
response["logGroup"].should.equal("/firehose-test")
response["logStream"].should.equal("delivery-stream")
response["subscriptionFilters"].should.equal(["firehose-test"])
assert response["messageType"] == "DATA_MESSAGE"
assert response["owner"] == "123456789012"
assert response["logGroup"] == "/firehose-test"
assert response["logStream"] == "delivery-stream"
assert response["subscriptionFilters"] == ["firehose-test"]
log_events = sorted(response["logEvents"], key=lambda log_event: log_event["id"])
log_events.should.have.length_of(2)
log_events[0]["id"].should.be.a(int)
log_events[0]["message"].should.equal("test")
log_events[0]["timestamp"].should.equal(ts_0)
log_events[1]["id"].should.be.a(int)
log_events[1]["message"].should.equal("test 2")
log_events[1]["timestamp"].should.equal(ts_1)
assert len(log_events) == 2
assert isinstance(log_events[0]["id"], int)
assert log_events[0]["message"] == "test"
assert log_events[0]["timestamp"] == ts_0
assert isinstance(log_events[1]["id"], int)
assert log_events[1]["message"] == "test 2"
assert log_events[1]["timestamp"] == ts_1
@mock_iam
@ -436,7 +435,7 @@ def test_delete_subscription_filter():
# then
response = client_logs.describe_subscription_filters(logGroupName=log_group_name)
response["subscriptionFilters"].should.have.length_of(0)
assert len(response["subscriptionFilters"]) == 0
@mock_lambda
@ -474,12 +473,10 @@ def test_delete_subscription_filter_errors():
# then
ex = e.value
ex.operation_name.should.equal("DeleteSubscriptionFilter")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("ResourceNotFoundException")
ex.response["Error"]["Message"].should.equal(
"The specified log group does not exist"
)
assert ex.operation_name == "DeleteSubscriptionFilter"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert ex.response["Error"]["Code"] == "ResourceNotFoundException"
assert ex.response["Error"]["Message"] == "The specified log group does not exist"
# when
with pytest.raises(ClientError) as e:
@ -489,11 +486,12 @@ def test_delete_subscription_filter_errors():
# then
ex = e.value
ex.operation_name.should.equal("DeleteSubscriptionFilter")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("ResourceNotFoundException")
ex.response["Error"]["Message"].should.equal(
"The specified subscription filter does not exist."
assert ex.operation_name == "DeleteSubscriptionFilter"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert ex.response["Error"]["Code"] == "ResourceNotFoundException"
assert (
ex.response["Error"]["Message"]
== "The specified subscription filter does not exist."
)
@ -524,11 +522,28 @@ def test_put_subscription_filter_errors():
# then
ex = e.value
ex.operation_name.should.equal("PutSubscriptionFilter")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("ResourceNotFoundException")
ex.response["Error"]["Message"].should.equal(
"The specified log group does not exist"
assert ex.operation_name == "PutSubscriptionFilter"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert ex.response["Error"]["Code"] == "ResourceNotFoundException"
assert ex.response["Error"]["Message"] == "The specified log group does not exist"
# when
with pytest.raises(ClientError) as e:
client.put_subscription_filter(
logGroupName="/test",
filterName="test",
filterPattern="",
destinationArn="arn:aws:lambda:us-east-1:123456789012:function:not-existing",
)
# then
ex = e.value
assert ex.operation_name == "PutSubscriptionFilter"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert ex.response["Error"]["Code"] == "InvalidParameterException"
assert (
ex.response["Error"]["Message"]
== "Could not execute the lambda function. Make sure you have given CloudWatch Logs permission to execute your function."
)
# when
@ -542,31 +557,12 @@ def test_put_subscription_filter_errors():
# then
ex = e.value
ex.operation_name.should.equal("PutSubscriptionFilter")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidParameterException")
ex.response["Error"]["Message"].should.equal(
"Could not execute the lambda function. "
"Make sure you have given CloudWatch Logs permission to execute your function."
)
# when
with pytest.raises(ClientError) as e:
client.put_subscription_filter(
logGroupName="/test",
filterName="test",
filterPattern="",
destinationArn="arn:aws:lambda:us-east-1:123456789012:function:not-existing",
)
# then
ex = e.value
ex.operation_name.should.equal("PutSubscriptionFilter")
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
ex.response["Error"]["Code"].should.contain("InvalidParameterException")
ex.response["Error"]["Message"].should.equal(
"Could not execute the lambda function. "
"Make sure you have given CloudWatch Logs permission to execute your function."
assert ex.operation_name == "PutSubscriptionFilter"
assert ex.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert ex.response["Error"]["Code"] == "InvalidParameterException"
assert (
ex.response["Error"]["Message"]
== "Could not execute the lambda function. Make sure you have given CloudWatch Logs permission to execute your function."
)
# when we pass an unknown kinesis ARN

View File

@ -1,6 +1,5 @@
import json
import time
import sure # noqa # pylint: disable=unused-import
from datetime import timedelta, datetime
from uuid import UUID
@ -136,8 +135,8 @@ def test_put_metric_filters_validation():
with pytest.raises(ClientError) as exc:
conn.put_metric_filter(**test_case["input"])
response = exc.value.response
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
response["Error"]["Code"].should.equal("InvalidParameterException")
assert response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert response["Error"]["Code"] == "InvalidParameterException"
@mock_logs
@ -164,8 +163,8 @@ def test_describe_metric_filters_validation():
with pytest.raises(ClientError) as exc:
conn.describe_metric_filters(**test_case["input"])
response = exc.value.response
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
response["Error"]["Code"].should.equal("InvalidParameterException")
assert response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert response["Error"]["Code"] == "InvalidParameterException"
@mock_logs
@ -216,7 +215,7 @@ def test_delete_metric_filter():
response = client.describe_metric_filters(
filterNamePrefix="filter", logGroupName="logGroupName2"
)
response.should.have.key("metricFilters").equals([])
assert response["metricFilters"] == []
@mock_logs
@ -235,12 +234,13 @@ def test_delete_metric_filter_invalid_filter_name(filter_name, failing_constrain
with pytest.raises(ClientError) as exc:
conn.delete_metric_filter(filterName=filter_name, logGroupName="valid")
response = exc.value.response
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
response["Error"]["Code"].should.equal("InvalidParameterException")
response["Error"]["Message"].should.contain(
assert response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert response["Error"]["Code"] == "InvalidParameterException"
assert (
f"Value '{filter_name}' at 'filterName' failed to satisfy constraint"
in response["Error"]["Message"]
)
response["Error"]["Message"].should.contain(failing_constraint)
assert failing_constraint in response["Error"]["Message"]
@mock_logs
@ -261,12 +261,13 @@ def test_delete_metric_filter_invalid_log_group_name(
with pytest.raises(ClientError) as exc:
conn.delete_metric_filter(filterName="valid", logGroupName=log_group_name)
response = exc.value.response
response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
response["Error"]["Code"].should.equal("InvalidParameterException")
response["Error"]["Message"].should.contain(
assert response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert response["Error"]["Code"] == "InvalidParameterException"
assert (
f"Value '{log_group_name}' at 'logGroupName' failed to satisfy constraint"
in response["Error"]["Message"]
)
response["Error"]["Message"].should.contain(failing_constraint)
assert failing_constraint in response["Error"]["Message"]
@mock_logs
@ -444,14 +445,14 @@ def test_create_log_group(kms_key_id):
response = conn.describe_log_groups()
# Then
response["logGroups"].should.have.length_of(1)
assert len(response["logGroups"]) == 1
log_group = response["logGroups"][0]
log_group.should_not.have.key("retentionInDays")
assert "retentionInDays" not in log_group
if kms_key_id:
log_group.should.have.key("kmsKeyId")
log_group["kmsKeyId"].should.equal(kms_key_id)
assert "kmsKeyId" in log_group
assert log_group["kmsKeyId"] == kms_key_id
@mock_logs
@ -482,8 +483,8 @@ def test_exceptions():
logEvents=[{"timestamp": 0, "message": "line"}],
)
error = ex.value.response["Error"]
error["Code"].should.equal("ResourceNotFoundException")
error["Message"].should.equal("The specified log stream does not exist.")
assert error["Code"] == "ResourceNotFoundException"
assert error["Message"] == "The specified log stream does not exist."
@mock_logs
@ -507,7 +508,7 @@ def test_put_logs():
next_sequence_token = put_results["nextSequenceToken"]
assert isinstance(next_sequence_token, str)
assert len(next_sequence_token) == 56
events.should.have.length_of(2)
assert len(events) == 2
@mock_logs
@ -534,9 +535,10 @@ def test_put_log_events_in_wrong_order():
sequenceToken="49599396607703531511419593985621160512859251095480828066",
)
err = exc.value.response["Error"]
err["Code"].should.equal("InvalidParameterException")
err["Message"].should.equal(
"Log events in a single PutLogEvents request must be in chronological order."
assert err["Code"] == "InvalidParameterException"
assert (
err["Message"]
== "Log events in a single PutLogEvents request must be in chronological order."
)
@ -556,9 +558,7 @@ def test_put_log_events_in_the_past(days_ago):
resp = conn.put_log_events(
logGroupName=log_group_name, logStreamName=log_stream_name, logEvents=messages
)
resp.should.have.key("rejectedLogEventsInfo").should.equal(
{"tooOldLogEventEndIndex": 0}
)
assert resp["rejectedLogEventsInfo"] == {"tooOldLogEventEndIndex": 0}
@mock_logs
@ -577,24 +577,22 @@ def test_put_log_events_in_the_future(minutes):
resp = conn.put_log_events(
logGroupName=log_group_name, logStreamName=log_stream_name, logEvents=messages
)
resp.should.have.key("rejectedLogEventsInfo").should.equal(
{"tooNewLogEventStartIndex": 0}
)
assert resp["rejectedLogEventsInfo"] == {"tooNewLogEventStartIndex": 0}
@mock_logs
def test_put_retention_policy():
conn = boto3.client("logs", TEST_REGION)
log_group_name = "dummy"
response = conn.create_log_group(logGroupName=log_group_name)
conn.create_log_group(logGroupName=log_group_name)
response = conn.put_retention_policy(logGroupName=log_group_name, retentionInDays=7)
conn.put_retention_policy(logGroupName=log_group_name, retentionInDays=7)
response = conn.describe_log_groups(logGroupNamePrefix=log_group_name)
assert len(response["logGroups"]) == 1
assert response["logGroups"][0].get("retentionInDays") == 7
response = conn.delete_log_group(logGroupName=log_group_name)
conn.delete_log_group(logGroupName=log_group_name)
@mock_logs
@ -693,10 +691,10 @@ def test_put_resource_policy_too_many():
policyName="too_many", policyDocument=json.dumps(json_policy_doc)
)
exc_value = exc.value
exc_value.operation_name.should.equal("PutResourcePolicy")
exc_value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
exc_value.response["Error"]["Code"].should.equal("LimitExceededException")
exc_value.response["Error"]["Message"].should.contain("Resource limit exceeded.")
assert exc_value.operation_name == "PutResourcePolicy"
assert exc_value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert exc_value.response["Error"]["Code"] == "LimitExceededException"
assert "Resource limit exceeded." in exc_value.response["Error"]["Message"]
# put_resource_policy on already created policy, shouldnt throw any error
client.put_resource_policy(
@ -728,11 +726,12 @@ def test_delete_resource_policy():
with pytest.raises(ClientError) as exc:
client.delete_resource_policy(policyName="non-existent")
exc_value = exc.value
exc_value.operation_name.should.equal("DeleteResourcePolicy")
exc_value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
exc_value.response["Error"]["Code"].should.equal("ResourceNotFoundException")
exc_value.response["Error"]["Message"].should.contain(
assert exc_value.operation_name == "DeleteResourcePolicy"
assert exc_value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert exc_value.response["Error"]["Code"] == "ResourceNotFoundException"
assert (
"Policy with name [non-existent] does not exist"
in exc_value.response["Error"]["Message"]
)
@ -784,15 +783,17 @@ def test_get_log_events():
logGroupName=log_group_name, logStreamName=log_stream_name, limit=10
)
resp["events"].should.have.length_of(10)
assert len(resp["events"]) == 10
for idx, (x, y) in enumerate(data[10:]):
resp["events"][idx]["timestamp"].should.equal(x)
resp["events"][idx]["message"].should.equal(y)
resp["nextForwardToken"].should.equal(
"f/00000000000000000000000000000000000000000000000000000019"
assert resp["events"][idx]["timestamp"] == x
assert resp["events"][idx]["message"] == y
assert (
resp["nextForwardToken"]
== "f/00000000000000000000000000000000000000000000000000000019"
)
resp["nextBackwardToken"].should.equal(
"b/00000000000000000000000000000000000000000000000000000010"
assert (
resp["nextBackwardToken"]
== "b/00000000000000000000000000000000000000000000000000000010"
)
resp = client.get_log_events(
@ -802,15 +803,17 @@ def test_get_log_events():
limit=20,
)
resp["events"].should.have.length_of(10)
assert len(resp["events"]) == 10
for idx, (x, y) in enumerate(data[0:10]):
resp["events"][idx]["timestamp"].should.equal(x)
resp["events"][idx]["message"].should.equal(y)
resp["nextForwardToken"].should.equal(
"f/00000000000000000000000000000000000000000000000000000009"
assert resp["events"][idx]["timestamp"] == x
assert resp["events"][idx]["message"] == y
assert (
resp["nextForwardToken"]
== "f/00000000000000000000000000000000000000000000000000000009"
)
resp["nextBackwardToken"].should.equal(
"b/00000000000000000000000000000000000000000000000000000000"
assert (
resp["nextBackwardToken"]
== "b/00000000000000000000000000000000000000000000000000000000"
)
resp = client.get_log_events(
@ -820,12 +823,14 @@ def test_get_log_events():
limit=10,
)
resp["events"].should.have.length_of(0)
resp["nextForwardToken"].should.equal(
"f/00000000000000000000000000000000000000000000000000000000"
assert len(resp["events"]) == 0
assert (
resp["nextForwardToken"]
== "f/00000000000000000000000000000000000000000000000000000000"
)
resp["nextBackwardToken"].should.equal(
"b/00000000000000000000000000000000000000000000000000000000"
assert (
resp["nextBackwardToken"]
== "b/00000000000000000000000000000000000000000000000000000000"
)
resp = client.get_log_events(
@ -835,15 +840,17 @@ def test_get_log_events():
limit=1,
)
resp["events"].should.have.length_of(1)
assert len(resp["events"]) == 1
x, y = data[1]
resp["events"][0]["timestamp"].should.equal(x)
resp["events"][0]["message"].should.equal(y)
resp["nextForwardToken"].should.equal(
"f/00000000000000000000000000000000000000000000000000000001"
assert resp["events"][0]["timestamp"] == x
assert resp["events"][0]["message"] == y
assert (
resp["nextForwardToken"]
== "f/00000000000000000000000000000000000000000000000000000001"
)
resp["nextBackwardToken"].should.equal(
"b/00000000000000000000000000000000000000000000000000000001"
assert (
resp["nextBackwardToken"]
== "b/00000000000000000000000000000000000000000000000000000001"
)
@ -872,15 +879,17 @@ def test_get_log_events_with_start_from_head():
startFromHead=True, # this parameter is only relevant without the usage of nextToken
)
resp["events"].should.have.length_of(10)
assert len(resp["events"]) == 10
for idx, (x, y) in enumerate(data[0:10]):
resp["events"][idx]["timestamp"].should.equal(x)
resp["events"][idx]["message"].should.equal(y)
resp["nextForwardToken"].should.equal(
"f/00000000000000000000000000000000000000000000000000000009"
assert resp["events"][idx]["timestamp"] == x
assert resp["events"][idx]["message"] == y
assert (
resp["nextForwardToken"]
== "f/00000000000000000000000000000000000000000000000000000009"
)
resp["nextBackwardToken"].should.equal(
"b/00000000000000000000000000000000000000000000000000000000"
assert (
resp["nextBackwardToken"]
== "b/00000000000000000000000000000000000000000000000000000000"
)
resp = client.get_log_events(
@ -890,15 +899,17 @@ def test_get_log_events_with_start_from_head():
limit=20,
)
resp["events"].should.have.length_of(10)
assert len(resp["events"]) == 10
for idx, (x, y) in enumerate(data[10:]):
resp["events"][idx]["timestamp"].should.equal(x)
resp["events"][idx]["message"].should.equal(y)
resp["nextForwardToken"].should.equal(
"f/00000000000000000000000000000000000000000000000000000019"
assert resp["events"][idx]["timestamp"] == x
assert resp["events"][idx]["message"] == y
assert (
resp["nextForwardToken"]
== "f/00000000000000000000000000000000000000000000000000000019"
)
resp["nextBackwardToken"].should.equal(
"b/00000000000000000000000000000000000000000000000000000010"
assert (
resp["nextBackwardToken"]
== "b/00000000000000000000000000000000000000000000000000000010"
)
resp = client.get_log_events(
@ -908,12 +919,14 @@ def test_get_log_events_with_start_from_head():
limit=10,
)
resp["events"].should.have.length_of(0)
resp["nextForwardToken"].should.equal(
"f/00000000000000000000000000000000000000000000000000000019"
assert len(resp["events"]) == 0
assert (
resp["nextForwardToken"]
== "f/00000000000000000000000000000000000000000000000000000019"
)
resp["nextBackwardToken"].should.equal(
"b/00000000000000000000000000000000000000000000000000000019"
assert (
resp["nextBackwardToken"]
== "b/00000000000000000000000000000000000000000000000000000019"
)
resp = client.get_log_events(
@ -923,15 +936,17 @@ def test_get_log_events_with_start_from_head():
limit=1,
)
resp["events"].should.have.length_of(1)
assert len(resp["events"]) == 1
x, y = data[18]
resp["events"][0]["timestamp"].should.equal(x)
resp["events"][0]["message"].should.equal(y)
resp["nextForwardToken"].should.equal(
"f/00000000000000000000000000000000000000000000000000000018"
assert resp["events"][0]["timestamp"] == x
assert resp["events"][0]["message"] == y
assert (
resp["nextForwardToken"]
== "f/00000000000000000000000000000000000000000000000000000018"
)
resp["nextBackwardToken"].should.equal(
"b/00000000000000000000000000000000000000000000000000000018"
assert (
resp["nextBackwardToken"]
== "b/00000000000000000000000000000000000000000000000000000018"
)
@ -950,11 +965,11 @@ def test_get_log_events_errors():
nextToken="n/00000000000000000000000000000000000000000000000000000000",
)
exc_value = exc.value
exc_value.operation_name.should.equal("GetLogEvents")
exc_value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
exc_value.response["Error"]["Code"].should.equal("InvalidParameterException")
exc_value.response["Error"]["Message"].should.contain(
"The specified nextToken is invalid."
assert exc_value.operation_name == "GetLogEvents"
assert exc_value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert exc_value.response["Error"]["Code"] == "InvalidParameterException"
assert (
"The specified nextToken is invalid." in exc_value.response["Error"]["Message"]
)
with pytest.raises(ClientError) as exc:
@ -964,11 +979,11 @@ def test_get_log_events_errors():
nextToken="not-existing-token",
)
exc_value = exc.value
exc_value.operation_name.should.equal("GetLogEvents")
exc_value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
exc_value.response["Error"]["Code"].should.equal("InvalidParameterException")
exc_value.response["Error"]["Message"].should.contain(
"The specified nextToken is invalid."
assert exc_value.operation_name == "GetLogEvents"
assert exc_value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert exc_value.response["Error"]["Code"] == "InvalidParameterException"
assert (
"The specified nextToken is invalid." in exc_value.response["Error"]["Message"]
)
@ -1049,7 +1064,7 @@ def test_describe_subscription_filters():
response = client.describe_subscription_filters(logGroupName=log_group_name)
# then
response["subscriptionFilters"].should.have.length_of(0)
assert len(response["subscriptionFilters"]) == 0
@mock_logs
@ -1063,11 +1078,12 @@ def test_describe_subscription_filters_errors():
# then
exc_value = exc.value
exc_value.operation_name.should.equal("DescribeSubscriptionFilters")
exc_value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
exc_value.response["Error"]["Code"].should.contain("ResourceNotFoundException")
exc_value.response["Error"]["Message"].should.equal(
"The specified log group does not exist"
assert exc_value.operation_name == "DescribeSubscriptionFilters"
assert exc_value.response["ResponseMetadata"]["HTTPStatusCode"] == 400
assert "ResourceNotFoundException" in exc_value.response["Error"]["Code"]
assert (
exc_value.response["Error"]["Message"]
== "The specified log group does not exist"
)
@ -1086,25 +1102,25 @@ def test_describe_log_groups_paging():
client.create_log_group(logGroupName=name)
resp = client.describe_log_groups()
resp["logGroups"].should.have.length_of(4)
resp.should_not.have.key("nextToken")
assert len(resp["logGroups"]) == 4
assert "nextToken" not in resp
resp = client.describe_log_groups(limit=2)
resp["logGroups"].should.have.length_of(2)
resp.should.have.key("nextToken")
assert len(resp["logGroups"]) == 2
assert "nextToken" in resp
resp = client.describe_log_groups(nextToken=resp["nextToken"], limit=1)
resp["logGroups"].should.have.length_of(1)
resp.should.have.key("nextToken")
assert len(resp["logGroups"]) == 1
assert "nextToken" in resp
resp = client.describe_log_groups(nextToken=resp["nextToken"])
resp["logGroups"].should.have.length_of(1)
resp["logGroups"][0]["logGroupName"].should.equal("/aws/lambda/lowercase-dev")
resp.should_not.have.key("nextToken")
assert len(resp["logGroups"]) == 1
assert resp["logGroups"][0]["logGroupName"] == "/aws/lambda/lowercase-dev"
assert "nextToken" not in resp
resp = client.describe_log_groups(nextToken="invalid-token")
resp["logGroups"].should.have.length_of(0)
resp.should_not.have.key("nextToken")
assert len(resp["logGroups"]) == 0
assert "nextToken" not in resp
@mock_logs
@ -1120,36 +1136,43 @@ def test_describe_log_streams_simple_paging():
# Get stream 1-10
resp = client.describe_log_streams(logGroupName=group_name)
resp["logStreams"].should.have.length_of(10)
resp.should_not.have.key("nextToken")
assert len(resp["logStreams"]) == 10
assert "nextToken" not in resp
# Get stream 1-4
resp = client.describe_log_streams(logGroupName=group_name, limit=4)
resp["logStreams"].should.have.length_of(4)
[stream["logStreamName"] for stream in resp["logStreams"]].should.equal(
["stream0", "stream1", "stream2", "stream3"]
)
resp.should.have.key("nextToken")
assert len(resp["logStreams"]) == 4
assert [stream["logStreamName"] for stream in resp["logStreams"]] == [
"stream0",
"stream1",
"stream2",
"stream3",
]
assert "nextToken" in resp
# Get stream 4-8
resp = client.describe_log_streams(
logGroupName=group_name, limit=4, nextToken=str(resp["nextToken"])
)
resp["logStreams"].should.have.length_of(4)
[stream["logStreamName"] for stream in resp["logStreams"]].should.equal(
["stream4", "stream5", "stream6", "stream7"]
)
resp.should.have.key("nextToken")
assert len(resp["logStreams"]) == 4
assert [stream["logStreamName"] for stream in resp["logStreams"]] == [
"stream4",
"stream5",
"stream6",
"stream7",
]
assert "nextToken" in resp
# Get stream 8-10
resp = client.describe_log_streams(
logGroupName=group_name, limit=4, nextToken=str(resp["nextToken"])
)
resp["logStreams"].should.have.length_of(2)
[stream["logStreamName"] for stream in resp["logStreams"]].should.equal(
["stream8", "stream9"]
)
resp.should_not.have.key("nextToken")
assert len(resp["logStreams"]) == 2
assert [stream["logStreamName"] for stream in resp["logStreams"]] == [
"stream8",
"stream9",
]
assert "nextToken" not in resp
@mock_logs
@ -1169,44 +1192,46 @@ def test_describe_log_streams_paging():
client.create_log_stream(logGroupName=log_group_name, logStreamName=name)
resp = client.describe_log_streams(logGroupName=log_group_name)
resp["logStreams"].should.have.length_of(4)
resp["logStreams"][0]["arn"].should.contain(log_group_name)
resp.should_not.have.key("nextToken")
assert len(resp["logStreams"]) == 4
assert log_group_name in resp["logStreams"][0]["arn"]
assert "nextToken" not in resp
resp = client.describe_log_streams(logGroupName=log_group_name, limit=2)
resp["logStreams"].should.have.length_of(2)
resp["logStreams"][0]["arn"].should.contain(log_group_name)
resp["nextToken"].should.equal(
f"{log_group_name}@{resp['logStreams'][1]['logStreamName']}"
assert len(resp["logStreams"]) == 2
assert log_group_name in resp["logStreams"][0]["arn"]
assert (
resp["nextToken"]
== f"{log_group_name}@{resp['logStreams'][1]['logStreamName']}"
)
resp = client.describe_log_streams(
logGroupName=log_group_name, nextToken=resp["nextToken"], limit=1
)
resp["logStreams"].should.have.length_of(1)
resp["logStreams"][0]["arn"].should.contain(log_group_name)
resp["nextToken"].should.equal(
f"{log_group_name}@{resp['logStreams'][0]['logStreamName']}"
assert len(resp["logStreams"]) == 1
assert log_group_name in resp["logStreams"][0]["arn"]
assert (
resp["nextToken"]
== f"{log_group_name}@{resp['logStreams'][0]['logStreamName']}"
)
resp = client.describe_log_streams(
logGroupName=log_group_name, nextToken=resp["nextToken"]
)
resp["logStreams"].should.have.length_of(1)
resp["logStreams"][0]["arn"].should.contain(log_group_name)
resp.should_not.have.key("nextToken")
assert len(resp["logStreams"]) == 1
assert log_group_name in resp["logStreams"][0]["arn"]
assert "nextToken" not in resp
resp = client.describe_log_streams(
logGroupName=log_group_name, nextToken="invalid-token"
)
resp["logStreams"].should.have.length_of(0)
resp.should_not.have.key("nextToken")
assert len(resp["logStreams"]) == 0
assert "nextToken" not in resp
resp = client.describe_log_streams(
logGroupName=log_group_name, nextToken="invalid@token"
)
resp["logStreams"].should.have.length_of(0)
resp.should_not.have.key("nextToken")
assert len(resp["logStreams"]) == 0
assert "nextToken" not in resp
@mock_logs
@ -1235,9 +1260,10 @@ def test_start_query():
# then
exc_value = exc.value
exc_value.response["Error"]["Code"].should.contain("ResourceNotFoundException")
exc_value.response["Error"]["Message"].should.equal(
"The specified log group does not exist"
assert "ResourceNotFoundException" in exc_value.response["Error"]["Code"]
assert (
exc_value.response["Error"]["Message"]
== "The specified log group does not exist"
)
@ -1257,12 +1283,13 @@ def test_get_too_many_log_events(nr_of_events):
limit=nr_of_events,
)
err = ex.value.response["Error"]
err["Code"].should.equal("InvalidParameterException")
err["Message"].should.contain("1 validation error detected")
err["Message"].should.contain(
assert err["Code"] == "InvalidParameterException"
assert "1 validation error detected" in err["Message"]
assert (
f"Value '{nr_of_events}' at 'limit' failed to satisfy constraint"
in err["Message"]
)
err["Message"].should.contain("Member must have value less than or equal to 10000")
assert "Member must have value less than or equal to 10000" in err["Message"]
@pytest.mark.parametrize("nr_of_events", [10001, 1000000])
@ -1281,12 +1308,13 @@ def test_filter_too_many_log_events(nr_of_events):
limit=nr_of_events,
)
err = ex.value.response["Error"]
err["Code"].should.equal("InvalidParameterException")
err["Message"].should.contain("1 validation error detected")
err["Message"].should.contain(
assert err["Code"] == "InvalidParameterException"
assert "1 validation error detected" in err["Message"]
assert (
f"Value '{nr_of_events}' at 'limit' failed to satisfy constraint"
in err["Message"]
)
err["Message"].should.contain("Member must have value less than or equal to 10000")
assert "Member must have value less than or equal to 10000" in err["Message"]
@pytest.mark.parametrize("nr_of_groups", [51, 100])
@ -1296,12 +1324,13 @@ def test_describe_too_many_log_groups(nr_of_groups):
with pytest.raises(ClientError) as ex:
client.describe_log_groups(limit=nr_of_groups)
err = ex.value.response["Error"]
err["Code"].should.equal("InvalidParameterException")
err["Message"].should.contain("1 validation error detected")
err["Message"].should.contain(
assert err["Code"] == "InvalidParameterException"
assert "1 validation error detected" in err["Message"]
assert (
f"Value '{nr_of_groups}' at 'limit' failed to satisfy constraint"
in err["Message"]
)
err["Message"].should.contain("Member must have value less than or equal to 50")
assert "Member must have value less than or equal to 50" in err["Message"]
@pytest.mark.parametrize("nr_of_streams", [51, 100])
@ -1313,12 +1342,13 @@ def test_describe_too_many_log_streams(nr_of_streams):
with pytest.raises(ClientError) as ex:
client.describe_log_streams(logGroupName=log_group_name, limit=nr_of_streams)
err = ex.value.response["Error"]
err["Code"].should.equal("InvalidParameterException")
err["Message"].should.contain("1 validation error detected")
err["Message"].should.contain(
assert err["Code"] == "InvalidParameterException"
assert "1 validation error detected" in err["Message"]
assert (
f"Value '{nr_of_streams}' at 'limit' failed to satisfy constraint"
in err["Message"]
)
err["Message"].should.contain("Member must have value less than or equal to 50")
assert "Member must have value less than or equal to 50" in err["Message"]
@pytest.mark.parametrize("length", [513, 1000])
@ -1329,12 +1359,13 @@ def test_create_log_group_invalid_name_length(length):
with pytest.raises(ClientError) as ex:
client.create_log_group(logGroupName=log_group_name)
err = ex.value.response["Error"]
err["Code"].should.equal("InvalidParameterException")
err["Message"].should.contain("1 validation error detected")
err["Message"].should.contain(
assert err["Code"] == "InvalidParameterException"
assert "1 validation error detected" in err["Message"]
assert (
f"Value '{log_group_name}' at 'logGroupName' failed to satisfy constraint"
in err["Message"]
)
err["Message"].should.contain("Member must have length less than or equal to 512")
assert "Member must have length less than or equal to 512" in err["Message"]
@pytest.mark.parametrize("invalid_orderby", ["", "sth", "LogStreamname"])
@ -1348,13 +1379,15 @@ def test_describe_log_streams_invalid_order_by(invalid_orderby):
logGroupName=log_group_name, orderBy=invalid_orderby
)
err = ex.value.response["Error"]
err["Code"].should.equal("InvalidParameterException")
err["Message"].should.contain("1 validation error detected")
err["Message"].should.contain(
assert err["Code"] == "InvalidParameterException"
assert "1 validation error detected" in err["Message"]
assert (
f"Value '{invalid_orderby}' at 'orderBy' failed to satisfy constraint"
in err["Message"]
)
err["Message"].should.contain(
assert (
"Member must satisfy enum value set: [LogStreamName, LastEventTime]"
in err["Message"]
)
@ -1373,10 +1406,8 @@ def test_describe_log_streams_no_prefix():
logStreamNamePrefix="sth",
)
err = ex.value.response["Error"]
err["Code"].should.equal("InvalidParameterException")
err["Message"].should.equal(
"Cannot order by LastEventTime with a logStreamNamePrefix."
)
assert err["Code"] == "InvalidParameterException"
assert err["Message"] == "Cannot order by LastEventTime with a logStreamNamePrefix."
@mock_s3

View File

@ -1,5 +1,4 @@
import boto3
import sure # noqa # pylint: disable=unused-import
from unittest import TestCase
from datetime import timedelta, datetime
@ -42,9 +41,9 @@ class TestLogFilterParameters(TestLogFilter):
)
events = res["events"]
for original_message, resulting_event in zip(messages, events):
resulting_event["eventId"].should.equal(str(resulting_event["eventId"]))
resulting_event["timestamp"].should.equal(original_message["timestamp"])
resulting_event["message"].should.equal(original_message["message"])
assert resulting_event["eventId"] == str(resulting_event["eventId"])
assert resulting_event["timestamp"] == original_message["timestamp"]
assert resulting_event["message"] == original_message["message"]
def test_put_log_events_now(self):
ts_1 = int(unix_time_millis())
@ -64,9 +63,7 @@ class TestLogFilterParameters(TestLogFilter):
)
# Message 2 was too new
resp.should.have.key("rejectedLogEventsInfo").should.equal(
{"tooNewLogEventStartIndex": 2}
)
assert resp["rejectedLogEventsInfo"] == {"tooNewLogEventStartIndex": 2}
# Message 0 and 1 were persisted though
events = self.conn.filter_log_events(
logGroupName=self.log_group_name,
@ -74,9 +71,9 @@ class TestLogFilterParameters(TestLogFilter):
limit=20,
)["events"]
messages = [e["message"] for e in events]
messages.should.contain("Message 0")
messages.should.contain("Message 1")
messages.shouldnt.contain("Message 2")
assert "Message 0" in messages
assert "Message 1" in messages
assert "Message 2" not in messages
def test_filter_logs_paging(self):
timestamp = int(unix_time_millis(datetime.utcnow()))
@ -96,8 +93,8 @@ class TestLogFilterParameters(TestLogFilter):
limit=20,
)
events = res["events"]
events.should.have.length_of(20)
res["nextToken"].should.equal("dummy@stream@" + events[-1]["eventId"])
assert len(events) == 20
assert res["nextToken"] == "dummy@stream@" + events[-1]["eventId"]
res = self.conn.filter_log_events(
logGroupName=self.log_group_name,
@ -106,13 +103,13 @@ class TestLogFilterParameters(TestLogFilter):
nextToken=res["nextToken"],
)
events += res["events"]
events.should.have.length_of(25)
res.should_not.have.key("nextToken")
assert len(events) == 25
assert "nextToken" not in res
for original_message, resulting_event in zip(messages, events):
resulting_event["eventId"].should.equal(str(resulting_event["eventId"]))
resulting_event["timestamp"].should.equal(original_message["timestamp"])
resulting_event["message"].should.equal(original_message["message"])
assert resulting_event["eventId"] == str(resulting_event["eventId"])
assert resulting_event["timestamp"] == original_message["timestamp"]
assert resulting_event["message"] == original_message["message"]
res = self.conn.filter_log_events(
logGroupName=self.log_group_name,
@ -120,8 +117,8 @@ class TestLogFilterParameters(TestLogFilter):
limit=20,
nextToken="wrong-group@stream@999",
)
res["events"].should.have.length_of(0)
res.should_not.have.key("nextToken")
assert len(res["events"]) == 0
assert "nextToken" not in res
def test_filter_logs_paging__unknown_token(self):
res = self.conn.filter_log_events(
@ -130,8 +127,8 @@ class TestLogFilterParameters(TestLogFilter):
limit=20,
nextToken="invalid-token",
)
res["events"].should.have.length_of(0)
res.should_not.have.key("nextToken")
assert len(res["events"]) == 0
assert "nextToken" not in res
@mock_logs
@ -159,7 +156,7 @@ class TestLogsFilterPattern(TestLogFilter):
logStreamNames=[self.log_stream_name],
filterPattern='{$.message = "hello"}',
)["events"]
events.should.have.length_of(6)
assert len(events) == 6
def test_simple_word_pattern(self):
events = self.conn.filter_log_events(
@ -168,7 +165,7 @@ class TestLogsFilterPattern(TestLogFilter):
filterPattern="hello",
)["events"]
messages = [e["message"] for e in events]
set(messages).should.equal({"hello", "hello cruela", "hello world"})
assert set(messages) == {"hello", "hello cruela", "hello world"}
def test_multiple_words_pattern(self):
events = self.conn.filter_log_events(
@ -177,7 +174,7 @@ class TestLogsFilterPattern(TestLogFilter):
filterPattern="goodbye world",
)["events"]
messages = [e["message"] for e in events]
set(messages).should.equal({"goodbye world", "goodbye cruel world"})
assert set(messages) == {"goodbye world", "goodbye cruel world"}
def test_quoted_pattern(self):
events = self.conn.filter_log_events(
@ -186,4 +183,4 @@ class TestLogsFilterPattern(TestLogFilter):
filterPattern='"hello cruel"',
)["events"]
messages = [e["message"] for e in events]
set(messages).should.equal({"hello cruela"})
assert set(messages) == {"hello cruela"}

View File

@ -1,5 +1,3 @@
import sure # noqa # pylint: disable=unused-import
from moto.logs.models import LogGroup
from tests import DEFAULT_ACCOUNT_ID
@ -22,5 +20,4 @@ def test_log_group_to_describe_dict():
expected_dict = dict(logGroupName=name, kmsKeyId=kms_key_id)
for attr, value in expected_dict.items():
describe_dict.should.have.key(attr)
describe_dict[attr].should.equal(value)
assert describe_dict[attr] == value