Skip to content

Commit 1483fc7

Browse files
committedMay 29, 2024
Add unit tests for coriolisclient.v1.logging.py module
1 parent c204677 commit 1483fc7

File tree

2 files changed

+279
-0
lines changed

2 files changed

+279
-0
lines changed
 

‎coriolisclient/tests/v1/data/logs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test_chunk1test_chunk2
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
# Copyright 2024 Cloudbase Solutions Srl
2+
# All Rights Reserved.
3+
4+
import ddt
5+
import os
6+
import requests
7+
from unittest import mock
8+
9+
from keystoneauth1.exceptions import http
10+
11+
from coriolisclient import exceptions
12+
from coriolisclient.tests import test_base
13+
from coriolisclient.v1 import logging
14+
15+
16+
@ddt.ddt
17+
class LoggingClientTestCase(
18+
test_base.CoriolisBaseTestCase):
19+
"""Test suite for the Coriolis v1 Logging Client."""
20+
21+
@mock.patch.object(logging.LoggingClient, '_get_endpoint_url')
22+
def setUp(self, mock_get_endpoint_url):
23+
mock_get_endpoint_url.return_value = mock.sentinel.ep_url
24+
mock_client = mock.Mock()
25+
super(LoggingClientTestCase, self).setUp()
26+
self.logger = logging.LoggingClient(mock_client)
27+
28+
@mock.patch.object(logging.LoggingClient, '_get_endpoint_url')
29+
def test__init__(self, mock_get_endpoint_url):
30+
mock_get_endpoint_url.side_effect = Exception
31+
32+
with self.assertLogs(logger=logging.LOG, level="WARNING"):
33+
logger = logging.LoggingClient(None)
34+
35+
self.assertEqual(
36+
None,
37+
logger._ep_url
38+
)
39+
40+
def test_get_endpoint_url(self):
41+
self.logger._cli.get_endpoint.return_value = "url/endpoint_url/"
42+
43+
result = self.logger._get_endpoint_url(mock.sentinel.name)
44+
45+
self.assertEqual(
46+
"url/endpoint_url",
47+
result
48+
)
49+
self.logger._cli.get_endpoint.assert_called_once_with(
50+
service_type=mock.sentinel.name)
51+
52+
def test_get_endpoint_url_not_found(self):
53+
self.logger._cli.get_endpoint.return_value = None
54+
55+
self.assertRaises(
56+
exceptions.LoggingEndpointNotFound,
57+
self.logger._get_endpoint_url,
58+
mock.sentinel.name
59+
)
60+
self.logger._cli.get_endpoint.assert_called_once_with(
61+
service_type=mock.sentinel.name)
62+
63+
def test_get_endpoint_url_http_unauthorized(self):
64+
self.logger._cli.get_endpoint.side_effect = http.Unauthorized
65+
66+
with self.assertLogs(logger=logging.LOG, level="ERROR"):
67+
self.assertRaises(
68+
exceptions.HTTPAuthError,
69+
self.logger._get_endpoint_url,
70+
mock.sentinel.name
71+
)
72+
self.logger._cli.get_endpoint.assert_called_once_with(
73+
service_type=mock.sentinel.name)
74+
75+
@ddt.data(
76+
{
77+
"query_args": {
78+
"arg1": None,
79+
"arg2": None
80+
},
81+
"is_websocket": True,
82+
"expected_result":
83+
"ws:///None/sentinel.resource"
84+
},
85+
{
86+
"query_args": {
87+
"arg1": None,
88+
"arg2": "mock_arg2"
89+
},
90+
"_ep_url": "https:///ep_url",
91+
"is_websocket": True,
92+
"expected_result":
93+
"wss:///ep_url/sentinel.resource?arg2=mock_arg2"
94+
},
95+
{
96+
"query_args": {
97+
"arg1": "mock_arg1",
98+
"arg2": "mock_arg2"
99+
},
100+
"_ep_url": "https:///ep_url",
101+
"is_websocket": False,
102+
"expected_result": "https:///ep_url/sentinel.resource"
103+
"?arg1=mock_arg1&arg2=mock_arg2"
104+
}
105+
)
106+
@mock.patch.object(logging.LoggingClient, '_get_endpoint_url')
107+
def test_construct_url(self, data, mock_get_endpoint_url):
108+
self.logger._ep_url = None
109+
mock_get_endpoint_url.return_value = data.get("_ep_url", None)
110+
111+
result = self.logger._construct_url(
112+
mock.sentinel.resource,
113+
data.get("query_args"),
114+
is_websocket=data.get("is_websocket", False),
115+
)
116+
117+
self.assertEqual(
118+
data.get("expected_result"),
119+
result
120+
)
121+
122+
@ddt.data(
123+
(None, None, False, False),
124+
("1", 1, False, False),
125+
("1234567890123456789", None, True, True),
126+
("abc", None, True, True),
127+
("", None, True, True),
128+
("10s", mock.ANY, False, True),
129+
)
130+
@ddt.unpack
131+
def test_convert_period_to_timestamp(
132+
self,
133+
period,
134+
expected_result,
135+
raises,
136+
has_logs
137+
):
138+
if raises is False:
139+
if has_logs is False:
140+
result = self.logger._convert_period_to_timestamp(period)
141+
else:
142+
with self.assertLogs(logger=logging.LOG, level="WARNING"):
143+
result = self.logger._convert_period_to_timestamp(period)
144+
self.assertEqual(
145+
expected_result,
146+
result
147+
)
148+
else:
149+
with self.assertLogs(logger=logging.LOG, level="WARNING"):
150+
self.assertRaises(
151+
exceptions.CoriolisException,
152+
self.logger._convert_period_to_timestamp,
153+
period
154+
)
155+
156+
@mock.patch.object(requests, "get")
157+
@mock.patch.object(logging.LoggingClient, "_construct_url")
158+
@mock.patch.object(logging.LoggingClient, "_convert_period_to_timestamp")
159+
def test_download_logs(
160+
self,
161+
mock_convert_period_to_timestamp,
162+
mock_construct_url,
163+
mock_get
164+
):
165+
logs_path = os.path.dirname(os.path.realpath(__file__))
166+
logs_path = os.path.join(logs_path, 'data')
167+
logs_path = os.path.join(logs_path, 'logs.yml')
168+
mock_r = mock.Mock()
169+
mock_r.iter_content.return_value = [b'test_chunk1', b'test_chunk2']
170+
mock_get.return_value.__enter__.return_value = mock_r
171+
with open(logs_path, "w") as fd:
172+
fd.write("test_logs")
173+
174+
self.logger.download_logs(
175+
mock.sentinel.app,
176+
logs_path,
177+
start_time=mock.sentinel.start_time,
178+
end_time=mock.sentinel.end_time
179+
)
180+
181+
with open(logs_path, "r") as fd:
182+
result = fd.read()
183+
self.assertEqual(
184+
result,
185+
"test_chunk1test_chunk2"
186+
)
187+
mock_get.assert_called_once_with(
188+
mock_construct_url.return_value,
189+
headers=self.logger._auth_headers,
190+
stream=True
191+
)
192+
mock_construct_url.assert_called_once_with(
193+
"logs/sentinel.app/",
194+
{
195+
"start_date": mock_convert_period_to_timestamp.return_value,
196+
"end_date": mock_convert_period_to_timestamp.return_value,
197+
}
198+
)
199+
200+
def test_download_logs_no_app(self):
201+
self.assertRaises(
202+
exceptions.CoriolisException,
203+
self.logger.download_logs,
204+
"",
205+
None
206+
)
207+
208+
@mock.patch.object(requests, "get")
209+
def test_list_logs(self, mock_get):
210+
mock_get.return_value.raise_for_status.return_value = None
211+
mock_get.return_value.json.return_value = {
212+
"logs": ["mock_log1", "mock_log2"]
213+
}
214+
215+
result = self.logger.list_logs()
216+
217+
self.assertEqual(
218+
['mock_log1', 'mock_log2'],
219+
result
220+
)
221+
222+
223+
class CoriolisLogDownloadManagerTestCase(
224+
test_base.CoriolisBaseTestCase):
225+
"""Test suite for the Coriolis v1 Coriolis Log Download Manager."""
226+
227+
def setUp(self):
228+
mock_client = mock.Mock()
229+
super(CoriolisLogDownloadManagerTestCase, self).setUp()
230+
self.logger = logging.CoriolisLogDownloadManager(mock_client)
231+
self.logger._coriolis_cli = mock.Mock()
232+
self.logger.resource_class = mock.Mock()
233+
234+
def test_list(self):
235+
self.logger._coriolis_cli.list_logs.return_value = [
236+
"mock_log1", "mock_log2"]
237+
238+
result = self.logger.list()
239+
240+
self.assertEqual(
241+
[self.logger.resource_class.return_value,
242+
self.logger.resource_class.return_value],
243+
result
244+
)
245+
self.logger.resource_class.assert_has_calls([
246+
mock.call(self.logger, "mock_log1", loaded=True),
247+
mock.call(self.logger, "mock_log2", loaded=True)
248+
])
249+
250+
def test_get(self):
251+
result = self.logger.get(
252+
mock.sentinel.app,
253+
mock.sentinel.to,
254+
start_time=mock.sentinel.start_time,
255+
end_time=mock.sentinel.end_time,
256+
)
257+
258+
self.assertEqual(
259+
self.logger._coriolis_cli.download_logs.return_value,
260+
result
261+
)
262+
self.logger._coriolis_cli.download_logs.assert_called_once_with(
263+
mock.sentinel.app,
264+
mock.sentinel.to,
265+
start_time=mock.sentinel.start_time,
266+
end_time=mock.sentinel.end_time,
267+
)
268+
269+
def test_stream(self):
270+
self.logger.stream(
271+
app_name=mock.sentinel.app_name,
272+
severity=mock.sentinel.severity,
273+
)
274+
275+
self.logger._coriolis_cli.stream_logs.assert_called_once_with(
276+
app_name=mock.sentinel.app_name,
277+
severity=mock.sentinel.severity,
278+
)

0 commit comments

Comments
 (0)
Failed to load comments.