parent
ec70d3cd14
commit
34c00e7dbd
@ -15,8 +15,12 @@ class ResourceNotFoundException(LogsClientError):
|
|||||||
|
|
||||||
|
|
||||||
class InvalidParameterException(LogsClientError):
|
class InvalidParameterException(LogsClientError):
|
||||||
def __init__(self, msg=None):
|
def __init__(self, msg=None, constraint=None, parameter=None, value=None):
|
||||||
self.code = 400
|
self.code = 400
|
||||||
|
if constraint:
|
||||||
|
msg = "1 validation error detected: Value '{}' at '{}' failed to satisfy constraint: {}".format(
|
||||||
|
value, parameter, constraint
|
||||||
|
)
|
||||||
super().__init__(
|
super().__init__(
|
||||||
"InvalidParameterException", msg or "A parameter is specified incorrectly."
|
"InvalidParameterException", msg or "A parameter is specified incorrectly."
|
||||||
)
|
)
|
||||||
|
@ -153,6 +153,9 @@ class LogStream(BaseModel):
|
|||||||
next_token,
|
next_token,
|
||||||
start_from_head,
|
start_from_head,
|
||||||
):
|
):
|
||||||
|
if limit is None:
|
||||||
|
limit = 10000
|
||||||
|
|
||||||
def filter_func(event):
|
def filter_func(event):
|
||||||
if start_time and event.timestamp < start_time:
|
if start_time and event.timestamp < start_time:
|
||||||
return False
|
return False
|
||||||
@ -382,6 +385,8 @@ class LogGroup(BaseModel):
|
|||||||
filter_pattern,
|
filter_pattern,
|
||||||
interleaved,
|
interleaved,
|
||||||
):
|
):
|
||||||
|
if not limit:
|
||||||
|
limit = 10000
|
||||||
streams = [
|
streams = [
|
||||||
stream
|
stream
|
||||||
for name, stream in self.streams.items()
|
for name, stream in self.streams.items()
|
||||||
@ -531,6 +536,12 @@ class LogsBackend(BaseBackend):
|
|||||||
def create_log_group(self, log_group_name, tags, **kwargs):
|
def create_log_group(self, log_group_name, tags, **kwargs):
|
||||||
if log_group_name in self.groups:
|
if log_group_name in self.groups:
|
||||||
raise ResourceAlreadyExistsException()
|
raise ResourceAlreadyExistsException()
|
||||||
|
if len(log_group_name) > 512:
|
||||||
|
raise InvalidParameterException(
|
||||||
|
constraint="Member must have length less than or equal to 512",
|
||||||
|
parameter="logGroupName",
|
||||||
|
value=log_group_name,
|
||||||
|
)
|
||||||
self.groups[log_group_name] = LogGroup(
|
self.groups[log_group_name] = LogGroup(
|
||||||
self.region_name, log_group_name, tags, **kwargs
|
self.region_name, log_group_name, tags, **kwargs
|
||||||
)
|
)
|
||||||
@ -547,6 +558,12 @@ class LogsBackend(BaseBackend):
|
|||||||
del self.groups[log_group_name]
|
del self.groups[log_group_name]
|
||||||
|
|
||||||
def describe_log_groups(self, limit, log_group_name_prefix, next_token):
|
def describe_log_groups(self, limit, log_group_name_prefix, next_token):
|
||||||
|
if limit > 50:
|
||||||
|
raise InvalidParameterException(
|
||||||
|
constraint="Member must have value less than or equal to 50",
|
||||||
|
parameter="limit",
|
||||||
|
value=limit,
|
||||||
|
)
|
||||||
if log_group_name_prefix is None:
|
if log_group_name_prefix is None:
|
||||||
log_group_name_prefix = ""
|
log_group_name_prefix = ""
|
||||||
|
|
||||||
@ -608,6 +625,22 @@ class LogsBackend(BaseBackend):
|
|||||||
):
|
):
|
||||||
if log_group_name not in self.groups:
|
if log_group_name not in self.groups:
|
||||||
raise ResourceNotFoundException()
|
raise ResourceNotFoundException()
|
||||||
|
if limit > 50:
|
||||||
|
raise InvalidParameterException(
|
||||||
|
constraint="Member must have value less than or equal to 50",
|
||||||
|
parameter="limit",
|
||||||
|
value=limit,
|
||||||
|
)
|
||||||
|
if order_by not in ["LogStreamName", "LastEventTime"]:
|
||||||
|
raise InvalidParameterException(
|
||||||
|
constraint="Member must satisfy enum value set: [LogStreamName, LastEventTime]",
|
||||||
|
parameter="orderBy",
|
||||||
|
value=order_by,
|
||||||
|
)
|
||||||
|
if order_by == "LastEventTime" and log_stream_name_prefix:
|
||||||
|
raise InvalidParameterException(
|
||||||
|
msg="Cannot order by LastEventTime with a logStreamNamePrefix."
|
||||||
|
)
|
||||||
log_group = self.groups[log_group_name]
|
log_group = self.groups[log_group_name]
|
||||||
return log_group.describe_log_streams(
|
return log_group.describe_log_streams(
|
||||||
descending,
|
descending,
|
||||||
@ -641,6 +674,12 @@ class LogsBackend(BaseBackend):
|
|||||||
):
|
):
|
||||||
if log_group_name not in self.groups:
|
if log_group_name not in self.groups:
|
||||||
raise ResourceNotFoundException()
|
raise ResourceNotFoundException()
|
||||||
|
if limit and limit > 1000:
|
||||||
|
raise InvalidParameterException(
|
||||||
|
constraint="Member must have value less than or equal to 10000",
|
||||||
|
parameter="limit",
|
||||||
|
value=limit,
|
||||||
|
)
|
||||||
log_group = self.groups[log_group_name]
|
log_group = self.groups[log_group_name]
|
||||||
return log_group.get_log_events(
|
return log_group.get_log_events(
|
||||||
log_group_name,
|
log_group_name,
|
||||||
@ -665,6 +704,12 @@ class LogsBackend(BaseBackend):
|
|||||||
):
|
):
|
||||||
if log_group_name not in self.groups:
|
if log_group_name not in self.groups:
|
||||||
raise ResourceNotFoundException()
|
raise ResourceNotFoundException()
|
||||||
|
if limit and limit > 1000:
|
||||||
|
raise InvalidParameterException(
|
||||||
|
constraint="Member must have value less than or equal to 10000",
|
||||||
|
parameter="limit",
|
||||||
|
value=limit,
|
||||||
|
)
|
||||||
log_group = self.groups[log_group_name]
|
log_group = self.groups[log_group_name]
|
||||||
return log_group.filter_log_events(
|
return log_group.filter_log_events(
|
||||||
log_group_name,
|
log_group_name,
|
||||||
|
@ -27,7 +27,6 @@ class LogsResponse(BaseResponse):
|
|||||||
log_group_name = self._get_param("logGroupName")
|
log_group_name = self._get_param("logGroupName")
|
||||||
tags = self._get_param("tags")
|
tags = self._get_param("tags")
|
||||||
kms_key_id = self._get_param("kmsKeyId")
|
kms_key_id = self._get_param("kmsKeyId")
|
||||||
assert 1 <= len(log_group_name) <= 512 # TODO: assert pattern
|
|
||||||
|
|
||||||
self.logs_backend.create_log_group(log_group_name, tags, kmsKeyId=kms_key_id)
|
self.logs_backend.create_log_group(log_group_name, tags, kmsKeyId=kms_key_id)
|
||||||
return ""
|
return ""
|
||||||
@ -41,7 +40,6 @@ class LogsResponse(BaseResponse):
|
|||||||
log_group_name_prefix = self._get_param("logGroupNamePrefix")
|
log_group_name_prefix = self._get_param("logGroupNamePrefix")
|
||||||
next_token = self._get_param("nextToken")
|
next_token = self._get_param("nextToken")
|
||||||
limit = self._get_param("limit", 50)
|
limit = self._get_param("limit", 50)
|
||||||
assert limit <= 50
|
|
||||||
groups, next_token = self.logs_backend.describe_log_groups(
|
groups, next_token = self.logs_backend.describe_log_groups(
|
||||||
limit, log_group_name_prefix, next_token
|
limit, log_group_name_prefix, next_token
|
||||||
)
|
)
|
||||||
@ -67,13 +65,8 @@ class LogsResponse(BaseResponse):
|
|||||||
log_stream_name_prefix = self._get_param("logStreamNamePrefix", "")
|
log_stream_name_prefix = self._get_param("logStreamNamePrefix", "")
|
||||||
descending = self._get_param("descending", False)
|
descending = self._get_param("descending", False)
|
||||||
limit = self._get_param("limit", 50)
|
limit = self._get_param("limit", 50)
|
||||||
assert limit <= 50
|
|
||||||
next_token = self._get_param("nextToken")
|
next_token = self._get_param("nextToken")
|
||||||
order_by = self._get_param("orderBy", "LogStreamName")
|
order_by = self._get_param("orderBy", "LogStreamName")
|
||||||
assert order_by in {"LogStreamName", "LastEventTime"}
|
|
||||||
|
|
||||||
if order_by == "LastEventTime":
|
|
||||||
assert not log_stream_name_prefix
|
|
||||||
|
|
||||||
streams, next_token = self.logs_backend.describe_log_streams(
|
streams, next_token = self.logs_backend.describe_log_streams(
|
||||||
descending,
|
descending,
|
||||||
@ -101,8 +94,7 @@ class LogsResponse(BaseResponse):
|
|||||||
log_stream_name = self._get_param("logStreamName")
|
log_stream_name = self._get_param("logStreamName")
|
||||||
start_time = self._get_param("startTime")
|
start_time = self._get_param("startTime")
|
||||||
end_time = self._get_param("endTime")
|
end_time = self._get_param("endTime")
|
||||||
limit = self._get_param("limit", 10000)
|
limit = self._get_param("limit")
|
||||||
assert limit <= 10000
|
|
||||||
next_token = self._get_param("nextToken")
|
next_token = self._get_param("nextToken")
|
||||||
start_from_head = self._get_param("startFromHead", False)
|
start_from_head = self._get_param("startFromHead", False)
|
||||||
|
|
||||||
@ -135,8 +127,7 @@ class LogsResponse(BaseResponse):
|
|||||||
filter_pattern = self._get_param("filterPattern")
|
filter_pattern = self._get_param("filterPattern")
|
||||||
interleaved = self._get_param("interleaved", False)
|
interleaved = self._get_param("interleaved", False)
|
||||||
end_time = self._get_param("endTime")
|
end_time = self._get_param("endTime")
|
||||||
limit = self._get_param("limit", 10000)
|
limit = self._get_param("limit")
|
||||||
assert limit <= 10000
|
|
||||||
next_token = self._get_param("nextToken")
|
next_token = self._get_param("nextToken")
|
||||||
|
|
||||||
events, next_token, searched_streams = self.logs_backend.filter_log_events(
|
events, next_token, searched_streams = self.logs_backend.filter_log_events(
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
import sure # noqa
|
||||||
from unittest import SkipTest
|
from unittest import SkipTest
|
||||||
|
|
||||||
import boto3
|
import boto3
|
||||||
@ -806,3 +807,143 @@ def test_start_query():
|
|||||||
exc_value.response["Error"]["Message"].should.equal(
|
exc_value.response["Error"]["Message"].should.equal(
|
||||||
"The specified log group does not exist"
|
"The specified log group does not exist"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("nr_of_events", [10001, 1000000])
|
||||||
|
@mock_logs
|
||||||
|
def test_get_too_many_log_events(nr_of_events):
|
||||||
|
client = boto3.client("logs", "us-east-1")
|
||||||
|
log_group_name = "dummy"
|
||||||
|
log_stream_name = "stream"
|
||||||
|
client.create_log_group(logGroupName=log_group_name)
|
||||||
|
client.create_log_stream(logGroupName=log_group_name, logStreamName=log_stream_name)
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as ex:
|
||||||
|
client.get_log_events(
|
||||||
|
logGroupName=log_group_name,
|
||||||
|
logStreamName=log_stream_name,
|
||||||
|
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(
|
||||||
|
"Value '{}' at 'limit' failed to satisfy constraint".format(nr_of_events)
|
||||||
|
)
|
||||||
|
err["Message"].should.contain("Member must have value less than or equal to 10000")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("nr_of_events", [10001, 1000000])
|
||||||
|
@mock_logs
|
||||||
|
def test_filter_too_many_log_events(nr_of_events):
|
||||||
|
client = boto3.client("logs", "us-east-1")
|
||||||
|
log_group_name = "dummy"
|
||||||
|
log_stream_name = "stream"
|
||||||
|
client.create_log_group(logGroupName=log_group_name)
|
||||||
|
client.create_log_stream(logGroupName=log_group_name, logStreamName=log_stream_name)
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as ex:
|
||||||
|
client.filter_log_events(
|
||||||
|
logGroupName=log_group_name,
|
||||||
|
logStreamNames=[log_stream_name],
|
||||||
|
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(
|
||||||
|
"Value '{}' at 'limit' failed to satisfy constraint".format(nr_of_events)
|
||||||
|
)
|
||||||
|
err["Message"].should.contain("Member must have value less than or equal to 10000")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("nr_of_groups", [51, 100])
|
||||||
|
@mock_logs
|
||||||
|
def test_describe_too_many_log_groups(nr_of_groups):
|
||||||
|
client = boto3.client("logs", "us-east-1")
|
||||||
|
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(
|
||||||
|
"Value '{}' at 'limit' failed to satisfy constraint".format(nr_of_groups)
|
||||||
|
)
|
||||||
|
err["Message"].should.contain("Member must have value less than or equal to 50")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("nr_of_streams", [51, 100])
|
||||||
|
@mock_logs
|
||||||
|
def test_describe_too_many_log_streams(nr_of_streams):
|
||||||
|
client = boto3.client("logs", "us-east-1")
|
||||||
|
log_group_name = "dummy"
|
||||||
|
client.create_log_group(logGroupName=log_group_name)
|
||||||
|
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(
|
||||||
|
"Value '{}' at 'limit' failed to satisfy constraint".format(nr_of_streams)
|
||||||
|
)
|
||||||
|
err["Message"].should.contain("Member must have value less than or equal to 50")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("length", [513, 1000])
|
||||||
|
@mock_logs
|
||||||
|
def test_create_log_group_invalid_name_length(length):
|
||||||
|
log_group_name = "a" * length
|
||||||
|
client = boto3.client("logs", "us-east-1")
|
||||||
|
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(
|
||||||
|
"Value '{}' at 'logGroupName' failed to satisfy constraint".format(
|
||||||
|
log_group_name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
err["Message"].should.contain("Member must have length less than or equal to 512")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("invalid_orderby", ["", "sth", "LogStreamname"])
|
||||||
|
@mock_logs
|
||||||
|
def test_describe_log_streams_invalid_order_by(invalid_orderby):
|
||||||
|
client = boto3.client("logs", "us-east-1")
|
||||||
|
log_group_name = "dummy"
|
||||||
|
client.create_log_group(logGroupName=log_group_name)
|
||||||
|
with pytest.raises(ClientError) as ex:
|
||||||
|
client.describe_log_streams(
|
||||||
|
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(
|
||||||
|
"Value '{}' at 'orderBy' failed to satisfy constraint".format(invalid_orderby)
|
||||||
|
)
|
||||||
|
err["Message"].should.contain(
|
||||||
|
"Member must satisfy enum value set: [LogStreamName, LastEventTime]"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_logs
|
||||||
|
def test_describe_log_streams_no_prefix():
|
||||||
|
"""
|
||||||
|
From the docs: If orderBy is LastEventTime , you cannot specify [logStreamNamePrefix]
|
||||||
|
"""
|
||||||
|
client = boto3.client("logs", "us-east-1")
|
||||||
|
log_group_name = "dummy"
|
||||||
|
client.create_log_group(logGroupName=log_group_name)
|
||||||
|
with pytest.raises(ClientError) as ex:
|
||||||
|
client.describe_log_streams(
|
||||||
|
logGroupName=log_group_name,
|
||||||
|
orderBy="LastEventTime",
|
||||||
|
logStreamNamePrefix="sth",
|
||||||
|
)
|
||||||
|
err = ex.value.response["Error"]
|
||||||
|
err["Code"].should.equal("InvalidParameterException")
|
||||||
|
err["Message"].should.equal(
|
||||||
|
"Cannot order by LastEventTime with a logStreamNamePrefix."
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user