Migrating to Python v3
- support for Python v3.8.x
- support for Python v3.5.x
- new tag, 2019.2.8
- updates class generation and iterators
- unittests updated with coverage >75%
- new coverage routines
- unittests profiling
- full fake data for unittests
- unittest testrun is ~1.5 seconds long
Bugfixes
- 34834, proper use of 'sudo' option
- multiple proper iterator use
- 37919, show warning when installed and candidate versions
are newer comparing to release version
Change-Id: Idd6b889f7ce94ae0c832e2f0a0346e4fdc3264a3
Related-PROD: PROD-34834 PROD-34664 PROD-34919
diff --git a/tests/test_base.py b/tests/test_base.py
index c4a627f..b30a6e5 100644
--- a/tests/test_base.py
+++ b/tests/test_base.py
@@ -1,29 +1,122 @@
import contextlib
import io
+import os
import sys
import unittest
+import logging
+
+from copy import deepcopy
+
+tests_dir = os.path.dirname(__file__)
+tests_dir = os.path.normpath(tests_dir)
+tests_dir = os.path.abspath(tests_dir)
class CfgCheckerTestBase(unittest.TestCase):
dummy_base_var = 0
+ last_stderr = ""
+ last_stdout = ""
- def _safe_import_module(self, _str):
+ def _safe_import(self, _str):
+ if "." not in _str:
+ return self._safe_import_module(_str)
+ else:
+ return self._safe_import_class(_str)
+
+ def _safe_import_class(self, _str):
+ _import_msg = ""
+ attrs = _str.split('.')
+ _import_msg, _module = self._safe_import_module(attrs[0])
+ if _import_msg:
+ return _import_msg, _module
+ else:
+ for attr_name in attrs[1:]:
+ _module = getattr(_module, attr_name)
+ return "", _module
+
+ @staticmethod
+ def _safe_import_module(_str, *args, **kwargs):
_import_msg = ""
_module = None
try:
- _module = __import__(_str)
+ _module = __import__(_str, *args, **kwargs)
except ImportError as e:
_import_msg = e.message
return _import_msg, _module
+ @staticmethod
+ def _safe_run(_obj, *args, **kwargs):
+ _m = ""
+ try:
+ _r = _obj(*args, **kwargs)
+ except Exception as ex:
+ if hasattr(ex, 'message'):
+ _m = "{}: {}".format(str(_obj), ex.message)
+ elif hasattr(ex, 'msg'):
+ _m = "{}: {}".format(str(_obj), ex.msg)
+ else:
+ _m = "{}: {}".format(str(_obj), "<no message>")
+ return _r, _m
+
+ def run_main(self, args_list):
+ _module_name = 'cfg_checker.cfg_check'
+ _m = self._try_import(_module_name)
+ with self.save_arguments():
+ with self.redirect_output():
+ with self.assertRaises(SystemExit) as ep:
+ sys.argv = ["fake.py"] + args_list
+ _m.cfg_check.config_check_entrypoint()
+ return ep.exception.code
+
+ def run_cli(self, command, args_list):
+ _module_name = 'cfg_checker.cli.command'
+ _m = self._try_import(_module_name)
+ with self.save_arguments():
+ with self.redirect_output():
+ with self.assertRaises(SystemExit) as ep:
+ import sys
+ sys.argv = ["fake.py"] + args_list
+ _m.cli.command.cli_command(
+ "Fake run for '{} {}'".format(
+ command,
+ " ".join(args_list)
+ ),
+ command
+ )
+ return ep.exception.code
+
@contextlib.contextmanager
def redirect_output(self):
save_stdout = sys.stdout
save_stderr = sys.stderr
- sys.stdout = io.BytesIO()
- sys.stderr = io.BytesIO()
+ sys.stdout = io.StringIO()
+ sys.stderr = io.StringIO()
+ logging.disable(logging.CRITICAL)
yield
+ self.last_stderr = sys.stderr.read()
+ self.last_stdout = sys.stdout.read()
sys.stdout = save_stdout
sys.stderr = save_stderr
+
+ @contextlib.contextmanager
+ def save_arguments(self):
+ _argv = deepcopy(sys.argv)
+ yield
+ sys.argv = _argv
+
+ def _try_import(self, module_name):
+ with self.redirect_output():
+ _msg, _m = self._safe_import_module(module_name)
+
+ self.assertEqual(
+ len(_msg),
+ 0,
+ "Error importing '{}': {}".format(
+ module_name,
+ _msg
+ )
+ )
+
+ return _m