blob: 6e6e3e2caf33ed91bd91703f7acc2317c4af1fe8 [file] [log] [blame]
Alex0989ecf2022-03-29 13:43:21 -05001# Author: Alex Savatieiev (osavatieiev@mirantis.com; a.savex@gmail.com)
2# Copyright 2019-2022 Mirantis, Inc.
Alex265f45e2019-04-23 18:51:23 -05003import contextlib
4import io
Alex3bc95f62020-03-05 17:00:04 -06005import os
Alex265f45e2019-04-23 18:51:23 -05006import sys
7import unittest
Alex3bc95f62020-03-05 17:00:04 -06008import logging
9
10from copy import deepcopy
11
12tests_dir = os.path.dirname(__file__)
13tests_dir = os.path.normpath(tests_dir)
14tests_dir = os.path.abspath(tests_dir)
Alex265f45e2019-04-23 18:51:23 -050015
16
17class CfgCheckerTestBase(unittest.TestCase):
18 dummy_base_var = 0
Alex3bc95f62020-03-05 17:00:04 -060019 last_stderr = ""
20 last_stdout = ""
Alex265f45e2019-04-23 18:51:23 -050021
Alex3bc95f62020-03-05 17:00:04 -060022 def _safe_import(self, _str):
23 if "." not in _str:
24 return self._safe_import_module(_str)
25 else:
26 return self._safe_import_class(_str)
27
28 def _safe_import_class(self, _str):
29 _import_msg = ""
30 attrs = _str.split('.')
31 _import_msg, _module = self._safe_import_module(attrs[0])
32 if _import_msg:
33 return _import_msg, _module
34 else:
35 for attr_name in attrs[1:]:
36 _module = getattr(_module, attr_name)
37 return "", _module
38
39 @staticmethod
40 def _safe_import_module(_str, *args, **kwargs):
Alex265f45e2019-04-23 18:51:23 -050041 _import_msg = ""
42 _module = None
43
44 try:
Alex3bc95f62020-03-05 17:00:04 -060045 _module = __import__(_str, *args, **kwargs)
Alex265f45e2019-04-23 18:51:23 -050046 except ImportError as e:
47 _import_msg = e.message
48
49 return _import_msg, _module
50
Alex3bc95f62020-03-05 17:00:04 -060051 @staticmethod
52 def _safe_run(_obj, *args, **kwargs):
53 _m = ""
54 try:
55 _r = _obj(*args, **kwargs)
56 except Exception as ex:
57 if hasattr(ex, 'message'):
58 _m = "{}: {}".format(str(_obj), ex.message)
59 elif hasattr(ex, 'msg'):
60 _m = "{}: {}".format(str(_obj), ex.msg)
61 else:
62 _m = "{}: {}".format(str(_obj), "<no message>")
63 return _r, _m
64
65 def run_main(self, args_list):
66 _module_name = 'cfg_checker.cfg_check'
67 _m = self._try_import(_module_name)
68 with self.save_arguments():
69 with self.redirect_output():
70 with self.assertRaises(SystemExit) as ep:
71 sys.argv = ["fake.py"] + args_list
72 _m.cfg_check.config_check_entrypoint()
73 return ep.exception.code
74
75 def run_cli(self, command, args_list):
76 _module_name = 'cfg_checker.cli.command'
77 _m = self._try_import(_module_name)
78 with self.save_arguments():
79 with self.redirect_output():
80 with self.assertRaises(SystemExit) as ep:
81 import sys
82 sys.argv = ["fake.py"] + args_list
83 _m.cli.command.cli_command(
84 "Fake run for '{} {}'".format(
85 command,
86 " ".join(args_list)
87 ),
88 command
89 )
90 return ep.exception.code
91
Alex265f45e2019-04-23 18:51:23 -050092 @contextlib.contextmanager
93 def redirect_output(self):
94 save_stdout = sys.stdout
95 save_stderr = sys.stderr
Alex3bc95f62020-03-05 17:00:04 -060096 sys.stdout = io.StringIO()
97 sys.stderr = io.StringIO()
98 logging.disable(logging.CRITICAL)
Alex265f45e2019-04-23 18:51:23 -050099 yield
100 sys.stdout = save_stdout
101 sys.stderr = save_stderr
Alex3bc95f62020-03-05 17:00:04 -0600102
103 @contextlib.contextmanager
104 def save_arguments(self):
105 _argv = deepcopy(sys.argv)
106 yield
107 sys.argv = _argv
108
109 def _try_import(self, module_name):
110 with self.redirect_output():
111 _msg, _m = self._safe_import_module(module_name)
112
113 self.assertEqual(
114 len(_msg),
115 0,
116 "Error importing '{}': {}".format(
117 module_name,
118 _msg
119 )
120 )
121
122 return _m