blob: 41f6eb8d0d4c6ebcaec4dfff00855837809d50e0 [file] [log] [blame]
Eduardo Sousaa0117812019-02-05 15:57:09 +00001# Copyright 2018 Whitestack, LLC
2# Copyright 2018 Telefonica S.A.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15#
16# For those usages not covered by the Apache License, Version 2.0 please
17# contact: esousa@whitestack.com or alfonso.tiernosepulveda@telefonica.com
18##
19
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010020import http
21import logging
22import pytest
23import tempfile
24import shutil
25import uuid
26import os
27import yaml
28import time
29import threading
30
31from unittest.mock import MagicMock
32from osm_common.msgbase import MsgException
33from osm_common.msglocal import MsgLocal
34
35__author__ = "Eduardo Sousa <eduardosousa@av.it.pt>"
36
tiernob20a9022018-05-22 12:07:05 +020037
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010038def valid_path():
39 return tempfile.gettempdir() + '/'
40
tiernob20a9022018-05-22 12:07:05 +020041
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010042def invalid_path():
43 return '/#tweeter/'
44
tiernob20a9022018-05-22 12:07:05 +020045
tierno1e9a3292018-11-05 18:18:45 +010046@pytest.fixture(scope="function", params=[True, False])
47def msg_local(request):
48 msg = MsgLocal(lock=request.param)
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010049 yield msg
50
tierno1e9a3292018-11-05 18:18:45 +010051 msg.disconnect()
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010052 if msg.path and msg.path != invalid_path() and msg.path != valid_path():
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010053 shutil.rmtree(msg.path)
54
tiernob20a9022018-05-22 12:07:05 +020055
tierno1e9a3292018-11-05 18:18:45 +010056@pytest.fixture(scope="function", params=[True, False])
57def msg_local_config(request):
58 msg = MsgLocal(lock=request.param)
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010059 msg.connect({"path": valid_path() + str(uuid.uuid4())})
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010060 yield msg
tiernob20a9022018-05-22 12:07:05 +020061
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010062 msg.disconnect()
63 if msg.path != invalid_path():
64 shutil.rmtree(msg.path)
65
tiernob20a9022018-05-22 12:07:05 +020066
tierno1e9a3292018-11-05 18:18:45 +010067@pytest.fixture(scope="function", params=[True, False])
68def msg_local_with_data(request):
69 msg = MsgLocal(lock=request.param)
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010070 msg.connect({"path": valid_path() + str(uuid.uuid4())})
tiernob20a9022018-05-22 12:07:05 +020071
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010072 msg.write("topic1", "key1", "msg1")
73 msg.write("topic1", "key2", "msg1")
74 msg.write("topic2", "key1", "msg1")
75 msg.write("topic2", "key2", "msg1")
76 msg.write("topic1", "key1", "msg2")
77 msg.write("topic1", "key2", "msg2")
78 msg.write("topic2", "key1", "msg2")
79 msg.write("topic2", "key2", "msg2")
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010080 yield msg
tiernob20a9022018-05-22 12:07:05 +020081
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010082 msg.disconnect()
83 if msg.path != invalid_path():
84 shutil.rmtree(msg.path)
85
tiernob20a9022018-05-22 12:07:05 +020086
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010087def empty_exception_message():
88 return "messaging exception "
89
tiernob20a9022018-05-22 12:07:05 +020090
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010091def test_constructor():
92 msg = MsgLocal()
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010093 assert msg.logger == logging.getLogger('msg')
tiernob20a9022018-05-22 12:07:05 +020094 assert msg.path is None
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +010095 assert len(msg.files_read) == 0
96 assert len(msg.files_write) == 0
97 assert len(msg.buffer) == 0
Eduardo Sousaacbbdf22018-05-03 15:47:41 +010098
tiernob20a9022018-05-22 12:07:05 +020099
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100100def test_constructor_with_logger():
101 logger_name = 'msg_local'
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100102 msg = MsgLocal(logger_name=logger_name)
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100103 assert msg.logger == logging.getLogger(logger_name)
tiernob20a9022018-05-22 12:07:05 +0200104 assert msg.path is None
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100105 assert len(msg.files_read) == 0
106 assert len(msg.files_write) == 0
107 assert len(msg.buffer) == 0
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100108
tiernob20a9022018-05-22 12:07:05 +0200109
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100110@pytest.mark.parametrize("config, logger_name, path", [
111 ({"logger_name": "msg_local", "path": valid_path()}, "msg_local", valid_path()),
112 ({"logger_name": "msg_local", "path": valid_path()[:-1]}, "msg_local", valid_path()),
113 ({"logger_name": "msg_local", "path": valid_path() + "test_it/"}, "msg_local", valid_path() + "test_it/"),
114 ({"logger_name": "msg_local", "path": valid_path() + "test_it"}, "msg_local", valid_path() + "test_it/"),
115 ({"path": valid_path()}, "msg", valid_path()),
116 ({"path": valid_path()[:-1]}, "msg", valid_path()),
117 ({"path": valid_path() + "test_it/"}, "msg", valid_path() + "test_it/"),
118 ({"path": valid_path() + "test_it"}, "msg", valid_path() + "test_it/")])
119def test_connect(msg_local, config, logger_name, path):
120 msg_local.connect(config)
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100121 assert msg_local.logger == logging.getLogger(logger_name)
122 assert msg_local.path == path
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100123 assert len(msg_local.files_read) == 0
124 assert len(msg_local.files_write) == 0
125 assert len(msg_local.buffer) == 0
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100126
tiernob20a9022018-05-22 12:07:05 +0200127
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100128@pytest.mark.parametrize("config", [
129 ({"logger_name": "msg_local", "path": invalid_path()}),
130 ({"path": invalid_path()})])
131def test_connect_with_exception(msg_local, config):
132 with pytest.raises(MsgException) as excinfo:
133 msg_local.connect(config)
134 assert str(excinfo.value).startswith(empty_exception_message())
135 assert excinfo.value.http_code == http.HTTPStatus.INTERNAL_SERVER_ERROR
136
tiernob20a9022018-05-22 12:07:05 +0200137
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100138def test_disconnect(msg_local_config):
tierno1e9a3292018-11-05 18:18:45 +0100139 files_read = msg_local_config.files_read.copy()
140 files_write = msg_local_config.files_write.copy()
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100141 msg_local_config.disconnect()
tierno1e9a3292018-11-05 18:18:45 +0100142 for f in files_read.values():
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100143 assert f.closed
tierno1e9a3292018-11-05 18:18:45 +0100144 for f in files_write.values():
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100145 assert f.closed
146
tiernob20a9022018-05-22 12:07:05 +0200147
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100148def test_disconnect_with_read(msg_local_config):
149 msg_local_config.read('topic1', blocks=False)
150 msg_local_config.read('topic2', blocks=False)
tierno1e9a3292018-11-05 18:18:45 +0100151 files_read = msg_local_config.files_read.copy()
152 files_write = msg_local_config.files_write.copy()
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100153 msg_local_config.disconnect()
tierno1e9a3292018-11-05 18:18:45 +0100154 for f in files_read.values():
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100155 assert f.closed
tierno1e9a3292018-11-05 18:18:45 +0100156 for f in files_write.values():
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100157 assert f.closed
158
tiernob20a9022018-05-22 12:07:05 +0200159
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100160def test_disconnect_with_write(msg_local_with_data):
tierno1e9a3292018-11-05 18:18:45 +0100161 files_read = msg_local_with_data.files_read.copy()
162 files_write = msg_local_with_data.files_write.copy()
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100163 msg_local_with_data.disconnect()
164
tierno1e9a3292018-11-05 18:18:45 +0100165 for f in files_read.values():
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100166 assert f.closed
167
tierno1e9a3292018-11-05 18:18:45 +0100168 for f in files_write.values():
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100169 assert f.closed
170
tiernob20a9022018-05-22 12:07:05 +0200171
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100172def test_disconnect_with_read_and_write(msg_local_with_data):
173 msg_local_with_data.read('topic1', blocks=False)
174 msg_local_with_data.read('topic2', blocks=False)
tierno1e9a3292018-11-05 18:18:45 +0100175 files_read = msg_local_with_data.files_read.copy()
176 files_write = msg_local_with_data.files_write.copy()
177
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100178 msg_local_with_data.disconnect()
tierno1e9a3292018-11-05 18:18:45 +0100179 for f in files_read.values():
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100180 assert f.closed
tierno1e9a3292018-11-05 18:18:45 +0100181 for f in files_write.values():
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100182 assert f.closed
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100183
tiernob20a9022018-05-22 12:07:05 +0200184
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100185@pytest.mark.parametrize("topic, key, msg", [
186 ("test_topic", "test_key", "test_msg"),
187 ("test", "test_key", "test_msg"),
188 ("test_topic", "test", "test_msg"),
189 ("test_topic", "test_key", "test"),
190 ("test_topic", "test_list", ["a", "b", "c"]),
191 ("test_topic", "test_tuple", ("c", "b", "a")),
192 ("test_topic", "test_dict", {"a": 1, "b": 2, "c": 3}),
193 ("test_topic", "test_number", 123),
194 ("test_topic", "test_float", 1.23),
195 ("test_topic", "test_boolean", True),
196 ("test_topic", "test_none", None)])
197def test_write(msg_local_config, topic, key, msg):
198 file_path = msg_local_config.path + topic
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100199 msg_local_config.write(topic, key, msg)
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100200 assert os.path.exists(file_path)
201
202 with open(file_path, 'r') as stream:
tierno6472e2b2019-09-02 16:04:16 +0000203 assert yaml.safe_load(stream) == {key: msg if not isinstance(msg, tuple) else list(msg)}
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100204
tiernob20a9022018-05-22 12:07:05 +0200205
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100206@pytest.mark.parametrize("topic, key, msg, times", [
207 ("test_topic", "test_key", "test_msg", 2),
208 ("test", "test_key", "test_msg", 3),
209 ("test_topic", "test", "test_msg", 4),
210 ("test_topic", "test_key", "test", 2),
211 ("test_topic", "test_list", ["a", "b", "c"], 3),
212 ("test_topic", "test_tuple", ("c", "b", "a"), 4),
213 ("test_topic", "test_dict", {"a": 1, "b": 2, "c": 3}, 2),
214 ("test_topic", "test_number", 123, 3),
215 ("test_topic", "test_float", 1.23, 4),
216 ("test_topic", "test_boolean", True, 2),
217 ("test_topic", "test_none", None, 3)])
218def test_write_with_multiple_calls(msg_local_config, topic, key, msg, times):
219 file_path = msg_local_config.path + topic
220
221 for _ in range(times):
222 msg_local_config.write(topic, key, msg)
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100223 assert os.path.exists(file_path)
224
225 with open(file_path, 'r') as stream:
226 for _ in range(times):
227 data = stream.readline()
tierno6472e2b2019-09-02 16:04:16 +0000228 assert yaml.safe_load(data) == {key: msg if not isinstance(msg, tuple) else list(msg)}
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100229
tiernob20a9022018-05-22 12:07:05 +0200230
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100231def test_write_exception(msg_local_config):
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100232 msg_local_config.files_write = MagicMock()
233 msg_local_config.files_write.__contains__.side_effect = Exception()
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100234
235 with pytest.raises(MsgException) as excinfo:
236 msg_local_config.write("test", "test", "test")
237 assert str(excinfo.value).startswith(empty_exception_message())
238 assert excinfo.value.http_code == http.HTTPStatus.INTERNAL_SERVER_ERROR
239
tiernob20a9022018-05-22 12:07:05 +0200240
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100241@pytest.mark.parametrize("topics, datas", [
242 (["topic"], [{"key": "value"}]),
243 (["topic1"], [{"key": "value"}]),
244 (["topic2"], [{"key": "value"}]),
245 (["topic", "topic1"], [{"key": "value"}]),
246 (["topic", "topic2"], [{"key": "value"}]),
247 (["topic1", "topic2"], [{"key": "value"}]),
248 (["topic", "topic1", "topic2"], [{"key": "value"}]),
249 (["topic"], [{"key": "value"}, {"key1": "value1"}]),
250 (["topic1"], [{"key": "value"}, {"key1": "value1"}]),
251 (["topic2"], [{"key": "value"}, {"key1": "value1"}]),
252 (["topic", "topic1"], [{"key": "value"}, {"key1": "value1"}]),
253 (["topic", "topic2"], [{"key": "value"}, {"key1": "value1"}]),
254 (["topic1", "topic2"], [{"key": "value"}, {"key1": "value1"}]),
255 (["topic", "topic1", "topic2"], [{"key": "value"}, {"key1": "value1"}])])
256def test_read(msg_local_with_data, topics, datas):
257 def write_to_topic(topics, datas):
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100258 # Allow msglocal to block while waiting
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100259 time.sleep(2)
260 for topic in topics:
261 for data in datas:
262 with open(msg_local_with_data.path + topic, "a+") as fp:
263 yaml.safe_dump(data, fp, default_flow_style=True, width=20000)
264 fp.flush()
265
266 # If file is not opened first, the messages written won't be seen
267 for topic in topics:
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100268 if topic not in msg_local_with_data.files_read:
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100269 msg_local_with_data.read(topic, blocks=False)
270
271 t = threading.Thread(target=write_to_topic, args=(topics, datas))
272 t.start()
273
274 for topic in topics:
275 for data in datas:
276 recv_topic, recv_key, recv_msg = msg_local_with_data.read(topic)
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100277 key = list(data.keys())[0]
278 val = data[key]
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100279 assert recv_topic == topic
280 assert recv_key == key
281 assert recv_msg == val
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100282 t.join()
283
tiernob20a9022018-05-22 12:07:05 +0200284
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100285@pytest.mark.parametrize("topics, datas", [
286 (["topic"], [{"key": "value"}]),
287 (["topic1"], [{"key": "value"}]),
288 (["topic2"], [{"key": "value"}]),
289 (["topic", "topic1"], [{"key": "value"}]),
290 (["topic", "topic2"], [{"key": "value"}]),
291 (["topic1", "topic2"], [{"key": "value"}]),
292 (["topic", "topic1", "topic2"], [{"key": "value"}]),
293 (["topic"], [{"key": "value"}, {"key1": "value1"}]),
294 (["topic1"], [{"key": "value"}, {"key1": "value1"}]),
295 (["topic2"], [{"key": "value"}, {"key1": "value1"}]),
296 (["topic", "topic1"], [{"key": "value"}, {"key1": "value1"}]),
297 (["topic", "topic2"], [{"key": "value"}, {"key1": "value1"}]),
298 (["topic1", "topic2"], [{"key": "value"}, {"key1": "value1"}]),
299 (["topic", "topic1", "topic2"], [{"key": "value"}, {"key1": "value1"}])])
300def test_read_non_block(msg_local_with_data, topics, datas):
301 def write_to_topic(topics, datas):
302 for topic in topics:
303 for data in datas:
304 with open(msg_local_with_data.path + topic, "a+") as fp:
305 yaml.safe_dump(data, fp, default_flow_style=True, width=20000)
306 fp.flush()
307
308 # If file is not opened first, the messages written won't be seen
309 for topic in topics:
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100310 if topic not in msg_local_with_data.files_read:
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100311 msg_local_with_data.read(topic, blocks=False)
312
313 t = threading.Thread(target=write_to_topic, args=(topics, datas))
314 t.start()
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100315 t.join()
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100316
317 for topic in topics:
318 for data in datas:
319 recv_topic, recv_key, recv_msg = msg_local_with_data.read(topic, blocks=False)
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100320 key = list(data.keys())[0]
321 val = data[key]
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100322 assert recv_topic == topic
323 assert recv_key == key
324 assert recv_msg == val
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100325
tiernob20a9022018-05-22 12:07:05 +0200326
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100327@pytest.mark.parametrize("topics, datas", [
328 (["topic"], [{"key": "value"}]),
329 (["topic1"], [{"key": "value"}]),
330 (["topic2"], [{"key": "value"}]),
331 (["topic", "topic1"], [{"key": "value"}]),
332 (["topic", "topic2"], [{"key": "value"}]),
333 (["topic1", "topic2"], [{"key": "value"}]),
334 (["topic", "topic1", "topic2"], [{"key": "value"}]),
335 (["topic"], [{"key": "value"}, {"key1": "value1"}]),
336 (["topic1"], [{"key": "value"}, {"key1": "value1"}]),
337 (["topic2"], [{"key": "value"}, {"key1": "value1"}]),
338 (["topic", "topic1"], [{"key": "value"}, {"key1": "value1"}]),
339 (["topic", "topic2"], [{"key": "value"}, {"key1": "value1"}]),
340 (["topic1", "topic2"], [{"key": "value"}, {"key1": "value1"}]),
341 (["topic", "topic1", "topic2"], [{"key": "value"}, {"key1": "value1"}])])
342def test_read_non_block_none(msg_local_with_data, topics, datas):
343 def write_to_topic(topics, datas):
344 time.sleep(2)
345 for topic in topics:
346 for data in datas:
347 with open(msg_local_with_data.path + topic, "a+") as fp:
348 yaml.safe_dump(data, fp, default_flow_style=True, width=20000)
349 fp.flush()
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100350 # If file is not opened first, the messages written won't be seen
351 for topic in topics:
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100352 if topic not in msg_local_with_data.files_read:
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100353 msg_local_with_data.read(topic, blocks=False)
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100354 t = threading.Thread(target=write_to_topic, args=(topics, datas))
355 t.start()
356
357 for topic in topics:
358 recv_data = msg_local_with_data.read(topic, blocks=False)
tiernob20a9022018-05-22 12:07:05 +0200359 assert recv_data is None
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100360 t.join()
361
tiernob20a9022018-05-22 12:07:05 +0200362
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100363@pytest.mark.parametrize("blocks", [
364 (True),
365 (False)])
366def test_read_exception(msg_local_with_data, blocks):
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100367 msg_local_with_data.files_read = MagicMock()
368 msg_local_with_data.files_read.__contains__.side_effect = Exception()
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100369
370 with pytest.raises(MsgException) as excinfo:
371 msg_local_with_data.read("topic1", blocks=blocks)
372 assert str(excinfo.value).startswith(empty_exception_message())
373 assert excinfo.value.http_code == http.HTTPStatus.INTERNAL_SERVER_ERROR
374
tiernob20a9022018-05-22 12:07:05 +0200375
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100376@pytest.mark.parametrize("topics, datas", [
377 (["topic"], [{"key": "value"}]),
378 (["topic1"], [{"key": "value"}]),
379 (["topic2"], [{"key": "value"}]),
380 (["topic", "topic1"], [{"key": "value"}]),
381 (["topic", "topic2"], [{"key": "value"}]),
382 (["topic1", "topic2"], [{"key": "value"}]),
383 (["topic", "topic1", "topic2"], [{"key": "value"}]),
384 (["topic"], [{"key": "value"}, {"key1": "value1"}]),
385 (["topic1"], [{"key": "value"}, {"key1": "value1"}]),
386 (["topic2"], [{"key": "value"}, {"key1": "value1"}]),
387 (["topic", "topic1"], [{"key": "value"}, {"key1": "value1"}]),
388 (["topic", "topic2"], [{"key": "value"}, {"key1": "value1"}]),
389 (["topic1", "topic2"], [{"key": "value"}, {"key1": "value1"}]),
390 (["topic", "topic1", "topic2"], [{"key": "value"}, {"key1": "value1"}])])
391def test_aioread(msg_local_with_data, event_loop, topics, datas):
392 def write_to_topic(topics, datas):
393 time.sleep(2)
394 for topic in topics:
395 for data in datas:
396 with open(msg_local_with_data.path + topic, "a+") as fp:
397 yaml.safe_dump(data, fp, default_flow_style=True, width=20000)
398 fp.flush()
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100399 # If file is not opened first, the messages written won't be seen
400 for topic in topics:
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100401 if topic not in msg_local_with_data.files_read:
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100402 msg_local_with_data.read(topic, blocks=False)
403
404 t = threading.Thread(target=write_to_topic, args=(topics, datas))
405 t.start()
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100406 for topic in topics:
407 for data in datas:
408 recv = event_loop.run_until_complete(msg_local_with_data.aioread(topic, event_loop))
409 recv_topic, recv_key, recv_msg = recv
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100410 key = list(data.keys())[0]
411 val = data[key]
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100412 assert recv_topic == topic
413 assert recv_key == key
414 assert recv_msg == val
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100415 t.join()
416
tiernob20a9022018-05-22 12:07:05 +0200417
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100418def test_aioread_exception(msg_local_with_data, event_loop):
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100419 msg_local_with_data.files_read = MagicMock()
420 msg_local_with_data.files_read.__contains__.side_effect = Exception()
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100421
422 with pytest.raises(MsgException) as excinfo:
423 event_loop.run_until_complete(msg_local_with_data.aioread("topic1", event_loop))
424 assert str(excinfo.value).startswith(empty_exception_message())
425 assert excinfo.value.http_code == http.HTTPStatus.INTERNAL_SERVER_ERROR
426
tiernob20a9022018-05-22 12:07:05 +0200427
Eduardo Sousaacbbdf22018-05-03 15:47:41 +0100428def test_aioread_general_exception(msg_local_with_data, event_loop):
429 msg_local_with_data.read = MagicMock()
430 msg_local_with_data.read.side_effect = Exception()
431
432 with pytest.raises(MsgException) as excinfo:
433 event_loop.run_until_complete(msg_local_with_data.aioread("topic1", event_loop))
434 assert str(excinfo.value).startswith(empty_exception_message())
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100435 assert excinfo.value.http_code == http.HTTPStatus.INTERNAL_SERVER_ERROR
436
tiernob20a9022018-05-22 12:07:05 +0200437
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100438@pytest.mark.parametrize("topic, key, msg", [
439 ("test_topic", "test_key", "test_msg"),
440 ("test", "test_key", "test_msg"),
441 ("test_topic", "test", "test_msg"),
442 ("test_topic", "test_key", "test"),
443 ("test_topic", "test_list", ["a", "b", "c"]),
444 ("test_topic", "test_tuple", ("c", "b", "a")),
445 ("test_topic", "test_dict", {"a": 1, "b": 2, "c": 3}),
446 ("test_topic", "test_number", 123),
447 ("test_topic", "test_float", 1.23),
448 ("test_topic", "test_boolean", True),
449 ("test_topic", "test_none", None)])
450def test_aiowrite(msg_local_config, event_loop, topic, key, msg):
451 file_path = msg_local_config.path + topic
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100452 event_loop.run_until_complete(msg_local_config.aiowrite(topic, key, msg))
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100453 assert os.path.exists(file_path)
454
455 with open(file_path, 'r') as stream:
tierno6472e2b2019-09-02 16:04:16 +0000456 assert yaml.safe_load(stream) == {key: msg if not isinstance(msg, tuple) else list(msg)}
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100457
tiernob20a9022018-05-22 12:07:05 +0200458
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100459@pytest.mark.parametrize("topic, key, msg, times", [
460 ("test_topic", "test_key", "test_msg", 2),
461 ("test", "test_key", "test_msg", 3),
462 ("test_topic", "test", "test_msg", 4),
463 ("test_topic", "test_key", "test", 2),
464 ("test_topic", "test_list", ["a", "b", "c"], 3),
465 ("test_topic", "test_tuple", ("c", "b", "a"), 4),
466 ("test_topic", "test_dict", {"a": 1, "b": 2, "c": 3}, 2),
467 ("test_topic", "test_number", 123, 3),
468 ("test_topic", "test_float", 1.23, 4),
469 ("test_topic", "test_boolean", True, 2),
470 ("test_topic", "test_none", None, 3)])
471def test_aiowrite_with_multiple_calls(msg_local_config, event_loop, topic, key, msg, times):
472 file_path = msg_local_config.path + topic
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100473 for _ in range(times):
474 event_loop.run_until_complete(msg_local_config.aiowrite(topic, key, msg))
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100475 assert os.path.exists(file_path)
476
477 with open(file_path, 'r') as stream:
478 for _ in range(times):
479 data = stream.readline()
tierno6472e2b2019-09-02 16:04:16 +0000480 assert yaml.safe_load(data) == {key: msg if not isinstance(msg, tuple) else list(msg)}
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100481
tiernob20a9022018-05-22 12:07:05 +0200482
Eduardo Sousaa7f8a6d2018-05-09 13:57:22 +0100483def test_aiowrite_exception(msg_local_config, event_loop):
484 msg_local_config.files_write = MagicMock()
485 msg_local_config.files_write.__contains__.side_effect = Exception()
486
487 with pytest.raises(MsgException) as excinfo:
488 event_loop.run_until_complete(msg_local_config.aiowrite("test", "test", "test"))
489 assert str(excinfo.value).startswith(empty_exception_message())
490 assert excinfo.value.http_code == http.HTTPStatus.INTERNAL_SERVER_ERROR