Code Cleanup and adding unit tests
[osm/common.git] / osm_common / tests / test_dbmongo.py
1 #######################################################################################
2 # Copyright ETSI Contributors and Others.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain 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,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13 # implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #######################################################################################
17
18 import logging
19 from urllib.parse import quote
20
21 from osm_common.dbbase import DbException, FakeLock
22 from osm_common.dbmongo import DbMongo
23 from pymongo import MongoClient
24 import pytest
25
26
27 def db_status_exception_message():
28 return "database exception Wrong database status"
29
30
31 def db_version_exception_message():
32 return "database exception Invalid database version"
33
34
35 def mock_get_one_status_not_enabled(a, b, c, fail_on_empty=False, fail_on_more=True):
36 return {"status": "ERROR", "version": "", "serial": ""}
37
38
39 def mock_get_one_wrong_db_version(a, b, c, fail_on_empty=False, fail_on_more=True):
40 return {"status": "ENABLED", "version": "4.0", "serial": "MDY4OA=="}
41
42
43 def db_generic_exception(exception):
44 return exception
45
46
47 def db_generic_exception_message(message):
48 return f"database exception {message}"
49
50
51 def test_constructor():
52 db = DbMongo(lock=True)
53 assert db.logger == logging.getLogger("db")
54 assert db.db is None
55 assert db.client is None
56 assert db.database_key is None
57 assert db.secret_obtained is False
58 assert db.lock.acquire() is True
59
60
61 def test_constructor_with_logger():
62 logger_name = "db_mongo"
63 db = DbMongo(logger_name=logger_name, lock=False)
64 assert db.logger == logging.getLogger(logger_name)
65 assert db.db is None
66 assert db.client is None
67 assert db.database_key is None
68 assert db.secret_obtained is False
69 assert type(db.lock) == FakeLock
70
71
72 @pytest.mark.parametrize(
73 "config, target_version, serial, lock",
74 [
75 (
76 {
77 "logger_name": "mongo_logger",
78 "commonkey": "common",
79 "uri": "mongo:27017",
80 "replicaset": "rs0",
81 "name": "osmdb",
82 "loglevel": "CRITICAL",
83 },
84 "5.0",
85 "MDY=",
86 True,
87 ),
88 (
89 {
90 "logger_name": "mongo_logger",
91 "commonkey": "common",
92 "masterpassword": "master",
93 "uri": "mongo:27017",
94 "replicaset": "rs0",
95 "name": "osmdb",
96 "loglevel": "CRITICAL",
97 },
98 "5.0",
99 "MDY=",
100 False,
101 ),
102 (
103 {
104 "logger_name": "logger",
105 "uri": "mongo:27017",
106 "name": "newdb",
107 "commonkey": "common",
108 },
109 "3.6",
110 "",
111 True,
112 ),
113 (
114 {
115 "uri": "mongo:27017",
116 "commonkey": "common",
117 "name": "newdb",
118 },
119 "5.0",
120 "MDIy",
121 False,
122 ),
123 (
124 {
125 "uri": "mongo:27017",
126 "masterpassword": "common",
127 "name": "newdb",
128 "loglevel": "CRITICAL",
129 },
130 "4.4",
131 "OTA=",
132 False,
133 ),
134 (
135 {
136 "uri": "mongo",
137 "masterpassword": "common",
138 "name": "osmdb",
139 "loglevel": "CRITICAL",
140 },
141 "4.4",
142 "OTA=",
143 True,
144 ),
145 (
146 {
147 "logger_name": "mongo_logger",
148 "commonkey": "common",
149 "uri": quote("user4:password4@mongo"),
150 "replicaset": "rs0",
151 "name": "osmdb",
152 "loglevel": "CRITICAL",
153 },
154 "5.0",
155 "NTM=",
156 True,
157 ),
158 (
159 {
160 "logger_name": "logger",
161 "uri": quote("user3:password3@mongo:27017"),
162 "name": "newdb",
163 "commonkey": "common",
164 },
165 "4.0",
166 "NjEx",
167 False,
168 ),
169 (
170 {
171 "uri": quote("user2:password2@mongo:27017"),
172 "commonkey": "common",
173 "name": "newdb",
174 },
175 "5.0",
176 "cmV0MzI=",
177 False,
178 ),
179 (
180 {
181 "uri": quote("user1:password1@mongo:27017"),
182 "commonkey": "common",
183 "masterpassword": "master",
184 "name": "newdb",
185 "loglevel": "CRITICAL",
186 },
187 "4.0",
188 "MjMyNQ==",
189 False,
190 ),
191 (
192 {
193 "uri": quote("user1:password1@mongo"),
194 "masterpassword": "common",
195 "name": "newdb",
196 "loglevel": "CRITICAL",
197 },
198 "4.0",
199 "MjMyNQ==",
200 True,
201 ),
202 ],
203 )
204 def test_db_connection_with_valid_config(
205 config, target_version, serial, lock, monkeypatch
206 ):
207 def mock_get_one(a, b, c, fail_on_empty=False, fail_on_more=True):
208 return {"status": "ENABLED", "version": target_version, "serial": serial}
209
210 monkeypatch.setattr(DbMongo, "get_one", mock_get_one)
211 db = DbMongo(lock=lock)
212 db.db_connect(config, target_version)
213 assert (
214 db.logger == logging.getLogger(config.get("logger_name"))
215 if config.get("logger_name")
216 else logging.getLogger("db")
217 )
218 assert type(db.client) == MongoClient
219 assert db.database_key == "common"
220 assert db.logger.getEffectiveLevel() == 50 if config.get("loglevel") else 20
221
222
223 @pytest.mark.parametrize(
224 "config, target_version, version_data, expected_exception_message",
225 [
226 (
227 {
228 "logger_name": "mongo_logger",
229 "commonkey": "common",
230 "uri": "mongo:27017",
231 "replicaset": "rs2",
232 "name": "osmdb",
233 "loglevel": "CRITICAL",
234 },
235 "4.0",
236 mock_get_one_status_not_enabled,
237 db_status_exception_message(),
238 ),
239 (
240 {
241 "logger_name": "mongo_logger",
242 "commonkey": "common",
243 "uri": "mongo:27017",
244 "replicaset": "rs4",
245 "name": "osmdb",
246 "loglevel": "CRITICAL",
247 },
248 "5.0",
249 mock_get_one_wrong_db_version,
250 db_version_exception_message(),
251 ),
252 (
253 {
254 "logger_name": "mongo_logger",
255 "commonkey": "common",
256 "uri": quote("user2:pa@word2@mongo:27017"),
257 "replicaset": "rs0",
258 "name": "osmdb",
259 "loglevel": "DEBUG",
260 },
261 "4.0",
262 mock_get_one_status_not_enabled,
263 db_status_exception_message(),
264 ),
265 (
266 {
267 "logger_name": "mongo_logger",
268 "commonkey": "common",
269 "uri": quote("username:pass1rd@mongo:27017"),
270 "replicaset": "rs0",
271 "name": "osmdb",
272 "loglevel": "DEBUG",
273 },
274 "5.0",
275 mock_get_one_wrong_db_version,
276 db_version_exception_message(),
277 ),
278 ],
279 )
280 def test_db_connection_db_status_error(
281 config, target_version, version_data, expected_exception_message, monkeypatch
282 ):
283 monkeypatch.setattr(DbMongo, "get_one", version_data)
284 db = DbMongo(lock=False)
285 with pytest.raises(DbException) as exception_info:
286 db.db_connect(config, target_version)
287 assert str(exception_info.value).startswith(expected_exception_message)
288
289
290 @pytest.mark.parametrize(
291 "config, target_version, lock, expected_exception",
292 [
293 (
294 {
295 "logger_name": "mongo_logger",
296 "commonkey": "common",
297 "uri": "27017@/:",
298 "replicaset": "rs0",
299 "name": "osmdb",
300 "loglevel": "CRITICAL",
301 },
302 "4.0",
303 True,
304 db_generic_exception(DbException),
305 ),
306 (
307 {
308 "logger_name": "mongo_logger",
309 "commonkey": "common",
310 "uri": "user@pass",
311 "replicaset": "rs0",
312 "name": "osmdb",
313 "loglevel": "CRITICAL",
314 },
315 "4.0",
316 False,
317 db_generic_exception(DbException),
318 ),
319 (
320 {
321 "logger_name": "mongo_logger",
322 "commonkey": "common",
323 "uri": "user@pass:27017",
324 "replicaset": "rs0",
325 "name": "osmdb",
326 "loglevel": "CRITICAL",
327 },
328 "4.0",
329 True,
330 db_generic_exception(DbException),
331 ),
332 (
333 {
334 "logger_name": "mongo_logger",
335 "commonkey": "common",
336 "uri": "",
337 "replicaset": "rs0",
338 "name": "osmdb",
339 "loglevel": "CRITICAL",
340 },
341 "5.0",
342 False,
343 db_generic_exception(TypeError),
344 ),
345 (
346 {
347 "logger_name": "mongo_logger",
348 "commonkey": "common",
349 "uri": "user2::@mon:27017",
350 "replicaset": "rs0",
351 "name": "osmdb",
352 "loglevel": "DEBUG",
353 },
354 "4.0",
355 True,
356 db_generic_exception(ValueError),
357 ),
358 (
359 {
360 "logger_name": "mongo_logger",
361 "commonkey": "common",
362 "replicaset": 33,
363 "uri": "user2@@mongo:27017",
364 "name": "osmdb",
365 "loglevel": "DEBUG",
366 },
367 "5.0",
368 False,
369 db_generic_exception(TypeError),
370 ),
371 ],
372 )
373 def test_db_connection_with_invalid_uri(
374 config, target_version, lock, expected_exception, monkeypatch
375 ):
376 def mock_get_one(a, b, c, fail_on_empty=False, fail_on_more=True):
377 pass
378
379 monkeypatch.setattr(DbMongo, "get_one", mock_get_one)
380 db = DbMongo(lock=lock)
381 with pytest.raises(expected_exception) as exception_info:
382 db.db_connect(config, target_version)
383 assert type(exception_info.value) == expected_exception
384
385
386 @pytest.mark.parametrize(
387 "config, target_version, expected_exception",
388 [
389 (
390 {
391 "logger_name": "mongo_logger",
392 "commonkey": "common",
393 "replicaset": "rs0",
394 "name": "osmdb",
395 "loglevel": "CRITICAL",
396 },
397 "",
398 db_generic_exception(TypeError),
399 ),
400 (
401 {
402 "logger_name": "mongo_logger",
403 "uri": "mongo:27017",
404 "replicaset": "rs0",
405 "loglevel": "CRITICAL",
406 },
407 "4.0",
408 db_generic_exception(KeyError),
409 ),
410 (
411 {
412 "replicaset": "rs0",
413 "loglevel": "CRITICAL",
414 },
415 None,
416 db_generic_exception(KeyError),
417 ),
418 (
419 {
420 "logger_name": "mongo_logger",
421 "commonkey": "common",
422 "uri": "",
423 "replicaset": "rs0",
424 "name": "osmdb",
425 "loglevel": "CRITICAL",
426 },
427 "5.0",
428 db_generic_exception(TypeError),
429 ),
430 (
431 {
432 "logger_name": "mongo_logger",
433 "name": "osmdb",
434 },
435 "4.0",
436 db_generic_exception(TypeError),
437 ),
438 (
439 {
440 "logger_name": "logger",
441 "replicaset": "",
442 "uri": "user2@@mongo:27017",
443 },
444 "5.0",
445 db_generic_exception(KeyError),
446 ),
447 ],
448 )
449 def test_db_connection_with_missing_parameters(
450 config, target_version, expected_exception, monkeypatch
451 ):
452 def mock_get_one(a, b, c, fail_on_empty=False, fail_on_more=True):
453 return
454
455 monkeypatch.setattr(DbMongo, "get_one", mock_get_one)
456 db = DbMongo(lock=False)
457 with pytest.raises(expected_exception) as exception_info:
458 db.db_connect(config, target_version)
459 assert type(exception_info.value) == expected_exception
460
461
462 @pytest.mark.parametrize(
463 "config, expected_exception_message",
464 [
465 (
466 {
467 "logger_name": "mongo_logger",
468 "commonkey": "common",
469 "uri": "mongo:27017",
470 "replicaset": "rs0",
471 "name": "osmdb1",
472 "loglevel": "CRITICAL",
473 },
474 "MongoClient crashed",
475 ),
476 (
477 {
478 "logger_name": "mongo_logger",
479 "commonkey": "common",
480 "uri": "username:pas1ed@mongo:27017",
481 "replicaset": "rs1",
482 "name": "osmdb2",
483 "loglevel": "DEBUG",
484 },
485 "MongoClient crashed",
486 ),
487 ],
488 )
489 def test_db_connection_with_invalid_mongoclient(
490 config, expected_exception_message, monkeypatch
491 ):
492 def generate_exception(a, b, replicaSet=None):
493 raise DbException(expected_exception_message)
494
495 monkeypatch.setattr(MongoClient, "__init__", generate_exception)
496 db = DbMongo()
497 with pytest.raises(DbException) as exception_info:
498 db.db_connect(config)
499 assert str(exception_info.value) == db_generic_exception_message(
500 expected_exception_message
501 )