Skip to content

Commit

Permalink
Tests print coverage report. Tests extended a bit.
Browse files Browse the repository at this point in the history
	modified:   tests/test_it.py
	modified:   tox.ini
  • Loading branch information
vlcinsky committed Jan 21, 2016
1 parent 345d38e commit de318db
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 122 deletions.
280 changes: 158 additions & 122 deletions tests/test_it.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,29 @@
from io import StringIO

from botocore.compat import total_seconds
from botocore.client import ClientError
from botocore.auth import NoCredentialsError

from termcolor import colored

try:
from mock import patch, Mock, call
from mock import patch, Mock
except ImportError:
from unittest.mock import patch, Mock, call
from unittest.mock import patch, Mock

from awslogs import AWSLogs
from awslogs.exceptions import UnknownDateError
from awslogs.bin import main


class TestAWSLogs(unittest.TestCase):
def mapkeys(keys, rec_lst):
"""Convert list of list into list of dicts with given keys
>>> keys = ["a", "b", "c"]
>>> rec_lst = [[1, 2, 3], [4, 5, 6]]
>>> mapkeys(keys, rec_lst)
[{"a": 1, "b": 2, "c": 3}, {"a": 4, "b": 5, "c": 6}]
"""
return [dict(zip(keys, vals)) for vals in rec_lst]

def _stream(self, name, start=0, end=sys.maxsize):
return {'logStreamName': name,
'firstEventTimestamp': start,
'lastEventTimestamp': end}

class TestAWSLogsDatetimeParse(unittest.TestCase):
@patch('boto3.client')
@patch('awslogs.core.datetime')
def test_parse_datetime(self, datetime_mock, botoclient):
Expand All @@ -37,73 +38,102 @@ def test_parse_datetime(self, datetime_mock, botoclient):
datetime_mock.utcnow.return_value = datetime(2015, 1, 1, 3, 0, 0, 0)
datetime_mock.return_value = datetime(1970, 1, 1)

def epoch(dt):
def iso2epoch(iso_str):
dt = datetime.strptime(iso_str, "%Y-%m-%d %H:%M:%S")
return int(total_seconds(dt - datetime(1970, 1, 1)) * 1000)

self.assertEqual(awslogs.parse_datetime(''), None)
self.assertEqual(awslogs.parse_datetime(None), None)

self.assertEqual(awslogs.parse_datetime('1m'),
epoch(datetime(2015, 1, 1, 2, 59, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1m ago'),
epoch(datetime(2015, 1, 1, 2, 59, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1minute'),
epoch(datetime(2015, 1, 1, 2, 59, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1minute ago'),
epoch(datetime(2015, 1, 1, 2, 59, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1minutes'),
epoch(datetime(2015, 1, 1, 2, 59, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1minutes ago'),
epoch(datetime(2015, 1, 1, 2, 59, 0, 0)))

self.assertEqual(awslogs.parse_datetime('1h'),
epoch(datetime(2015, 1, 1, 2, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1h ago'),
epoch(datetime(2015, 1, 1, 2, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1hour'),
epoch(datetime(2015, 1, 1, 2, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1hour ago'),
epoch(datetime(2015, 1, 1, 2, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1hours'),
epoch(datetime(2015, 1, 1, 2, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1hours ago'),
epoch(datetime(2015, 1, 1, 2, 0, 0, 0)))

self.assertEqual(awslogs.parse_datetime('1d'),
epoch(datetime(2014, 12, 31, 3, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1d ago'),
epoch(datetime(2014, 12, 31, 3, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1day'),
epoch(datetime(2014, 12, 31, 3, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1day ago'),
epoch(datetime(2014, 12, 31, 3, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1days'),
epoch(datetime(2014, 12, 31, 3, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1days ago'),
epoch(datetime(2014, 12, 31, 3, 0, 0, 0)))

self.assertEqual(awslogs.parse_datetime('1w'),
epoch(datetime(2014, 12, 25, 3, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1w ago'),
epoch(datetime(2014, 12, 25, 3, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1week'),
epoch(datetime(2014, 12, 25, 3, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1week ago'),
epoch(datetime(2014, 12, 25, 3, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1weeks'),
epoch(datetime(2014, 12, 25, 3, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1weeks ago'),
epoch(datetime(2014, 12, 25, 3, 0, 0, 0)))

self.assertEqual(awslogs.parse_datetime('1/1/2013'),
epoch(datetime(2013, 1, 1, 0, 0, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1/1/2012 12:34'),
epoch(datetime(2012, 1, 1, 12, 34, 0, 0)))
self.assertEqual(awslogs.parse_datetime('1/1/2011 12:34:56'),
epoch(datetime(2011, 1, 1, 12, 34, 56, 0)))
plan = (('2015-01-01 02:59:00', '1m'),
('2015-01-01 02:59:00', '1m ago'),
('2015-01-01 02:59:00', '1minute'),
('2015-01-01 02:59:00', '1minute ago'),
('2015-01-01 02:59:00', '1minutes'),
('2015-01-01 02:59:00', '1minutes ago'),

('2015-01-01 02:00:00', '1h'),
('2015-01-01 02:00:00', '1h ago'),
('2015-01-01 02:00:00', '1hour'),
('2015-01-01 02:00:00', '1hour ago'),
('2015-01-01 02:00:00', '1hours'),
('2015-01-01 02:00:00', '1hours ago'),

('2014-12-31 03:00:00', '1d'),
('2014-12-31 03:00:00', '1d ago'),
('2014-12-31 03:00:00', '1day'),
('2014-12-31 03:00:00', '1day ago'),
('2014-12-31 03:00:00', '1days'),
('2014-12-31 03:00:00', '1days ago'),

('2014-12-25 03:00:00', '1w'),
('2014-12-25 03:00:00', '1w ago'),
('2014-12-25 03:00:00', '1week'),
('2014-12-25 03:00:00', '1week ago'),
('2014-12-25 03:00:00', '1weeks'),
('2014-12-25 03:00:00', '1weeks ago'),

('2013-01-01 00:00:00', '1/1/2013'),
('2012-01-01 12:34:00', '1/1/2012 12:34'),
('2011-01-01 12:34:56', '1/1/2011 12:34:56')
)

for expected_iso, dateutil_time in plan:
self.assertEqual(awslogs.parse_datetime(dateutil_time),
iso2epoch(expected_iso))

self.assertRaises(UnknownDateError, awslogs.parse_datetime, '???')


class TestAWSLogs(unittest.TestCase):

def _stream(self, name, start=0, end=sys.maxsize):
return {'logStreamName': name,
'firstEventTimestamp': start,
'lastEventTimestamp': end}

def set_ABCDE_logs(self, botoclient):
client = Mock()
botoclient.return_value = client
# awslogs = AWSLogs()

event_keys = ["eventId", "timestamp", "ingestionTime",
"message", "logStreamName"]
logs = [
{'events': mapkeys(event_keys,
[[1, 0, 5000, "Hello 1", "DDD"],
[2, 0, 5000, "Hello 2", "EEE"],
[3, 0, 5006, "Hello 3", "DDD"]]),
'nextToken': 'token'},
{'events': mapkeys(event_keys,
[[4, 0, 5000, "Hello 4", "EEE"],
[5, 0, 5000, "Hello 5", "DDD"],
[6, 0, 5009, "Hello 6", "EEE"]]),
'nextToken': 'token'},
{'events': []}
]

groups = [
{'logGroups': [{'logGroupName': 'AAA'},
{'logGroupName': 'BBB'},
{'logGroupName': 'CCC'}]},
]

streams = [
{'logStreams': [self._stream('DDD'),
self._stream('EEE')]}
]

def paginator(value):
mock = Mock()
mock.paginate.return_value = {
'describe_log_groups': groups,
'describe_log_streams': streams
}.get(value)
return mock

client.get_paginator.side_effect = paginator
client.filter_log_events.side_effect = logs

@patch('boto3.client')
def test_get_groups(self, botoclient):
client = Mock()
Expand All @@ -121,7 +151,8 @@ def test_get_groups(self, botoclient):
]

awslogs = AWSLogs()
self.assertEqual([g for g in awslogs.get_groups()], ['A', 'B', 'C', 'D', 'E', 'F', 'G'])
self.assertEqual([g for g in awslogs.get_groups()],
['A', 'B', 'C', 'D', 'E', 'F', 'G'])

@patch('boto3.client')
def test_get_streams(self, botoclient):
Expand All @@ -140,7 +171,8 @@ def test_get_streams(self, botoclient):
]

awslogs = AWSLogs(log_group_name='group')
self.assertEqual([g for g in awslogs.get_streams()], ['A', 'B', 'C', 'D', 'E', 'F', 'G'])
self.assertEqual([g for g in awslogs.get_streams()],
['A', 'B', 'C', 'D', 'E', 'F', 'G'])

@patch('boto3.client')
@patch('awslogs.core.AWSLogs.parse_datetime')
Expand All @@ -152,7 +184,7 @@ def test_get_streams_filtered_by_date(self, parse_datetime, botoclient):
self._stream('B', 0, 6),
self._stream('C'),
self._stream('D', sys.maxsize - 1, sys.maxsize)],
}
}
]
parse_datetime.side_effect = [5, 7]
awslogs = AWSLogs(log_group_name='group', start='5', end='7')
Expand Down Expand Up @@ -195,70 +227,75 @@ def test_get_streams_from_pattern(self, botoclient):
@patch('boto3.client')
@patch('sys.stdout', new_callable=StringIO)
def test_main_get(self, mock_stdout, botoclient):
client = Mock()
botoclient.return_value = client
awslogs = AWSLogs()
self.set_ABCDE_logs(botoclient)
main("awslogs get AAA DDD --no-color".split())

logs = [
{'events': [{'eventId': 1, 'message': 'Hello 1', 'logStreamName': 'DDD'},
{'eventId': 2, 'message': 'Hello 2', 'logStreamName': 'EEE'},
{'eventId': 3, 'message': 'Hello 3', 'logStreamName': 'DDD'}],
'nextToken': 'token'},
{'events': [{'eventId': 4, 'message': 'Hello 4', 'logStreamName': 'EEE'},
{'eventId': 5, 'message': 'Hello 5', 'logStreamName': 'DDD'},
{'eventId': 6, 'message': 'Hello 6', 'logStreamName': 'EEE'}],
'nextToken': 'token'},
{'events': []}
]
@patch('boto3.client')
@patch('sys.stdout', new_callable=StringIO)
def test_get_nogroup(self, mock_stdout, botoclient):
self.set_ABCDE_logs(botoclient)
main("awslogs get --no-group AAA DDD --no-color".split())

groups = [
{'logGroups': [{'logGroupName': 'AAA'},
{'logGroupName': 'BBB'},
{'logGroupName': 'CCC'}]},
]
self.assertEqual(
mock_stdout.getvalue(),
("DDD Hello 1\n"
"EEE Hello 2\n"
"DDD Hello 3\n"
"EEE Hello 4\n"
"DDD Hello 5\n"
"EEE Hello 6\n")
)

streams = [
{'logStreams': [self._stream('DDD'),
self._stream('EEE')]}
]
@patch('boto3.client')
@patch('sys.stdout', new_callable=StringIO)
def test_get_nostream(self, mock_stdout, botoclient):
self.set_ABCDE_logs(botoclient)
main("awslogs get --no-stream AAA DDD --no-color".split())

def paginator(value):
mock = Mock()
mock.paginate.return_value = {
'describe_log_groups': groups,
'describe_log_streams': streams
}.get(value)
return mock
self.assertEqual(
mock_stdout.getvalue(),
("AAA Hello 1\n"
"AAA Hello 2\n"
"AAA Hello 3\n"
"AAA Hello 4\n"
"AAA Hello 5\n"
"AAA Hello 6\n")
)

client.get_paginator.side_effect = paginator
client.filter_log_events.side_effect = logs
main("awslogs get AAA DDD --no-color".split())
@patch('boto3.client')
@patch('sys.stdout', new_callable=StringIO)
def test_get_nogroup_nostream(self, mock_stdout, botoclient):
self.set_ABCDE_logs(botoclient)
main("awslogs get --no-group --no-stream AAA DDD --no-color".split())

self.assertEqual(
mock_stdout.getvalue(),
("AAA DDD Hello 1\n"
"AAA EEE Hello 2\n"
"AAA DDD Hello 3\n"
"AAA EEE Hello 4\n"
"AAA DDD Hello 5\n"
"AAA EEE Hello 6\n")
("Hello 1\n"
"Hello 2\n"
"Hello 3\n"
"Hello 4\n"
"Hello 5\n"
"Hello 6\n")
)

@patch('boto3.client')
@patch('sys.stdout', new_callable=StringIO)
def test_main_get_deduplication(self, mock_stdout, botoclient):
client = Mock()
botoclient.return_value = client
awslogs = AWSLogs()

event_keys = ["eventId", "timestamp", "ingestionTime",
"message", "logStreamName"]
logs = [
{'events': [{'eventId': 1, 'message': 'Hello 1', 'logStreamName': 'DDD'},
{'eventId': 2, 'message': 'Hello 2', 'logStreamName': 'EEE'},
{'eventId': 3, 'message': 'Hello 3', 'logStreamName': 'DDD'}],
{'events': mapkeys(event_keys,
[[1, 0, 0, 'Hello 1', 'DDD'],
[2, 0, 0, 'Hello 2', 'EEE'],
[3, 0, 0, 'Hello 3', 'DDD']]),
'nextToken': 'token'},
{'events': [{'eventId': 1, 'message': 'Hello 1', 'logStreamName': 'DDD'},
{'eventId': 2, 'message': 'Hello 2', 'logStreamName': 'EEE'},
{'eventId': 3, 'message': 'Hello 3', 'logStreamName': 'DDD'}],
{'events': mapkeys(event_keys,
[[1, 0, 0, 'Hello 1', 'EEE'],
[2, 0, 0, 'Hello 2', 'DDD'],
[3, 0, 0, 'Hello 3', 'EEE']]),
'nextToken': 'token'},
{'events': []}
]
Expand Down Expand Up @@ -298,7 +335,6 @@ def paginator(value):
def test_main_groups(self, mock_stdout, botoclient):
client = Mock()
botoclient.return_value = client
awslogs = AWSLogs()

groups = [
{'logGroups': [{'logGroupName': 'AAA'},
Expand All @@ -321,7 +357,6 @@ def test_main_groups(self, mock_stdout, botoclient):
def test_main_streams(self, mock_stdout, botoclient):
client = Mock()
botoclient.return_value = client
awslogs = AWSLogs()

groups = [
{'logGroups': [{'logGroupName': 'AAA'},
Expand Down Expand Up @@ -356,7 +391,8 @@ def test_unknown_date_error(self, mock_stderr):
code = main("awslogs get AAA BBB -sX".split())
self.assertEqual(code, 3)
self.assertEqual(mock_stderr.getvalue(),
colored("awslogs doesn't understand 'X' as a date.\n", "red"))
colored("awslogs doesn't understand 'X' as a date.\n",
"red"))

@patch('awslogs.bin.AWSLogs')
@patch('sys.stderr', new_callable=StringIO)
Expand Down
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ envlist = py{26,27,33,34}
commands =
coverage run --source awslogs -m pytest -sv tests []
awslogs --help
coverage report
deps =
-rtest-requirements.txt

0 comments on commit de318db

Please sign in to comment.