Skip to content

Commit d281a2b

Browse files
committedNov 26, 2024
Add unit tests for coriolisclient.v1.logging.py module
1 parent b2ad9dc commit d281a2b

File tree

2 files changed

+284
-0
lines changed

2 files changed

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

0 commit comments

Comments
 (0)