summaryrefslogtreecommitdiffstats
path: root/tosca2heat/heat-translator-0.3.0/translator/hot/translate_inputs.py
blob: ea9f990efccaeb387e3158bf9604254fa26ee8d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import logging
from toscaparser.dataentity import DataEntity
from toscaparser.elements.scalarunit import ScalarUnit_Size
from toscaparser.utils.gettextutils import _
from toscaparser.utils.validateutils import TOSCAVersionProperty
from translator.hot.syntax.hot_parameter import HotParameter


INPUT_CONSTRAINTS = (CONSTRAINTS, DESCRIPTION, LENGTH, RANGE,
                     MIN, MAX, ALLOWED_VALUES, ALLOWED_PATTERN) = \
                    ('constraints', 'description', 'length', 'range',
                     'min', 'max', 'allowed_values', 'allowed_pattern')

TOSCA_CONSTRAINT_OPERATORS = (EQUAL, GREATER_THAN, GREATER_OR_EQUAL, LESS_THAN,
                              LESS_OR_EQUAL, IN_RANGE, VALID_VALUES, LENGTH,
                              MIN_LENGTH, MAX_LENGTH, PATTERN) = \
                             ('equal', 'greater_than', 'greater_or_equal',
                              'less_than', 'less_or_equal', 'in_range',
                              'valid_values', 'length', 'min_length',
                              'max_length', 'pattern')

TOSCA_TO_HOT_CONSTRAINTS_ATTRS = {'equal': 'allowed_values',
                                  'greater_than': 'range',
                                  'greater_or_equal': 'range',
                                  'less_than': 'range',
                                  'less_or_equal': 'range',
                                  'in_range': 'range',
                                  'valid_values': 'allowed_values',
                                  'length': 'length',
                                  'min_length': 'length',
                                  'max_length': 'length',
                                  'pattern': 'allowed_pattern'}

TOSCA_TO_HOT_INPUT_TYPES = {'string': 'string',
                            'integer': 'number',
                            'float': 'number',
                            'boolean': 'boolean',
                            'timestamp': 'string',
                            'scalar-unit.size': 'number',
                            'version': 'string',
                            'null': 'string',
                            'PortDef': 'number'}

log = logging.getLogger('heat-translator')


class TranslateInputs(object):
    '''Translate TOSCA Inputs to Heat Parameters.'''

    def __init__(self, inputs, parsed_params):
        self.inputs = inputs
        self.parsed_params = parsed_params

    def translate(self):
        return self._translate_inputs()

    def _translate_inputs(self):
        hot_inputs = []
        hot_default = None
        for input in self.inputs:
            hot_input_type = TOSCA_TO_HOT_INPUT_TYPES[input.type]

            if input.name in self.parsed_params:
                hot_default = DataEntity.validate_datatype(
                    input.type, self.parsed_params[input.name])
            elif input.default is not None:
                hot_default = DataEntity.validate_datatype(input.type,
                                                           input.default)
            else:
                log.warning(_("Need to specify a value "
                              "for input {0}").format(input.name))
                raise Exception(_("Need to specify a value "
                                  "for input {0}").format(input.name))
            if input.type == "scalar-unit.size":
                # Assumption here is to use this scalar-unit.size for size of
                # cinder volume in heat templates and will be in GB.
                # should add logic to support other types if needed.
                input_value = hot_default
                hot_default = (ScalarUnit_Size(hot_default).
                               get_num_from_scalar_unit('GiB'))
                if hot_default == 0:
                    log.warning(_('Unit value should be > 0.'))
                    raise Exception(_(
                        'Unit value should be > 0.'))
                elif int(hot_default) < hot_default:
                    hot_default = int(hot_default) + 1
                    log.warning(_("Cinder unit value should be in multiples"
                                  " of GBs. So corrected %(input_value)s "
                                  "to %(hot_default)s GB.")
                                % {'input_value': input_value,
                                   'hot_default': hot_default})
            if input.type == 'version':
                hot_default = TOSCAVersionProperty(hot_default).get_version()

            hot_constraints = []
            if input.constraints:
                for constraint in input.constraints:
                    constraint.validate(hot_default)
                    hc, hvalue = self._translate_constraints(
                        constraint.constraint_key, constraint.constraint_value)
                    hot_constraints.append({hc: hvalue})

            hot_inputs.append(HotParameter(name=input.name,
                                           type=hot_input_type,
                                           description=input.description,
                                           default=hot_default,
                                           constraints=hot_constraints))
        return hot_inputs

    def _translate_constraints(self, name, value):
        hot_constraint = TOSCA_TO_HOT_CONSTRAINTS_ATTRS[name]

        # Offset used to support less_than and greater_than.
        # TODO(anyone):  when parser supports float, verify this works
        offset = 1

        if name == EQUAL:
            hot_value = [value]
        elif name == GREATER_THAN:
            hot_value = {"min": value + offset}
        elif name == GREATER_OR_EQUAL:
            hot_value = {"min": value}
        elif name == LESS_THAN:
            hot_value = {"max": value - offset}
        elif name == LESS_OR_EQUAL:
            hot_value = {"max": value}
        elif name == IN_RANGE:
            # value is list type here
            min_value = min(value)
            max_value = max(value)
            hot_value = {"min": min_value, "max": max_value}
        elif name == LENGTH:
            hot_value = {"min": value, "max": value}
        elif name == MIN_LENGTH:
            hot_value = {"min": value}
        elif name == MAX_LENGTH:
            hot_value = {"max": value}
        else:
            hot_value = value
        return hot_constraint, hot_value
class="k">del os.environ[var] os.environ["OS_AUTH_URL"] = self._os_auth_url os.environ["OS_USERNAME"] = self._os_username os.environ["OS_PASSWORD"] = self._os_password os.environ["OS_TENANT_NAME"] = self._os_tenantname self.test = odl.ODLTests(case_name='odl', project_name='functest') self.defaultargs = {'odlusername': self._odl_username, 'odlpassword': self._odl_password, 'neutronip': self._keystone_ip, 'osauthurl': self._os_auth_url, 'osusername': self._os_username, 'ostenantname': self._os_tenantname, 'ospassword': self._os_password, 'odlip': self._keystone_ip, 'odlwebport': self._odl_webport, 'odlrestconfport': self._odl_restconfport, 'pushtodb': False} class ODLParseResultTesting(ODLTesting): """The class testing ODLTests.parse_results().""" # pylint: disable=missing-docstring _config = {'name': 'dummy', 'starttime': '20161216 16:00:00.000', 'endtime': '20161216 16:00:01.000'} @mock.patch('robot.api.ExecutionResult', side_effect=DataError) def test_raises_exc(self, mock_method): with self.assertRaises(DataError): self.test.parse_results() mock_method.assert_called_once_with( os.path.join(odl.ODLTests.res_dir, 'output.xml')) def _test_result(self, config, result): suite = mock.Mock() suite.configure_mock(**config) with mock.patch('robot.api.ExecutionResult', return_value=mock.Mock(suite=suite)): self.test.parse_results() self.assertEqual(self.test.result, result) self.assertEqual(self.test.start_time, timestamp_to_secs(config['starttime'])) self.assertEqual(self.test.stop_time, timestamp_to_secs(config['endtime'])) self.assertEqual(self.test.details, {'description': config['name'], 'tests': []}) def test_null_passed(self): self._config.update({'statistics.critical.passed': 0, 'statistics.critical.total': 20}) self._test_result(self._config, 0) def test_no_test(self): self._config.update({'statistics.critical.passed': 20, 'statistics.critical.total': 0}) self._test_result(self._config, 0) def test_half_success(self): self._config.update({'statistics.critical.passed': 10, 'statistics.critical.total': 20}) self._test_result(self._config, 50) def test_success(self): self._config.update({'statistics.critical.passed': 20, 'statistics.critical.total': 20}) self._test_result(self._config, 100) class ODLRobotTesting(ODLTesting): """The class testing ODLTests.set_robotframework_vars().""" # pylint: disable=missing-docstring @mock.patch('fileinput.input', side_effect=Exception()) def test_set_vars_ko(self, mock_method): self.assertFalse(self.test.set_robotframework_vars()) mock_method.assert_called_once_with( os.path.join(odl.ODLTests.odl_test_repo, 'csit/variables/Variables.py'), inplace=True) @mock.patch('fileinput.input', return_value=[]) def test_set_vars_empty(self, mock_method): self.assertTrue(self.test.set_robotframework_vars()) mock_method.assert_called_once_with( os.path.join(odl.ODLTests.odl_test_repo, 'csit/variables/Variables.py'), inplace=True) @mock.patch('sys.stdout', new_callable=six.StringIO) def _test_set_vars(self, msg1, msg2, *args): line = mock.MagicMock() line.__iter__.return_value = [msg1] with mock.patch('fileinput.input', return_value=line) as mock_method: self.assertTrue(self.test.set_robotframework_vars()) mock_method.assert_called_once_with( os.path.join(odl.ODLTests.odl_test_repo, 'csit/variables/Variables.py'), inplace=True) self.assertEqual(args[0].getvalue(), "{}\n".format(msg2)) def test_set_vars_auth_default(self): self._test_set_vars("AUTH = []", "AUTH = [u'admin', u'admin']") def test_set_vars_auth1(self): self._test_set_vars("AUTH1 = []", "AUTH1 = []") @mock.patch('sys.stdout', new_callable=six.StringIO) def test_set_vars_auth_foo(self, *args): line = mock.MagicMock() line.__iter__.return_value = ["AUTH = []"] with mock.patch('fileinput.input', return_value=line) as mock_method: self.assertTrue(self.test.set_robotframework_vars('foo', 'bar')) mock_method.assert_called_once_with( os.path.join(odl.ODLTests.odl_test_repo, 'csit/variables/Variables.py'), inplace=True) self.assertEqual(args[0].getvalue(), "AUTH = [u'{}', u'{}']\n".format('foo', 'bar')) class ODLMainTesting(ODLTesting): """The class testing ODLTests.run_suites().""" # pylint: disable=missing-docstring def _get_run_suites_kwargs(self, key=None): kwargs = {'odlusername': self._odl_username, 'odlpassword': self._odl_password, 'neutronip': self._neutron_ip, 'osauthurl': self._os_auth_url, 'osusername': self._os_username, 'ostenantname': self._os_tenantname, 'ospassword': self._os_password, 'odlip': self._sdn_controller_ip, 'odlwebport': self._odl_webport, 'odlrestconfport': self._odl_restconfport} if key: del kwargs[key] return kwargs def _test_run_suites(self, status, *args): kwargs = self._get_run_suites_kwargs() self.assertEqual(self.test.run_suites(**kwargs), status) if len(args) > 0: args[0].assert_called_once_with( odl.ODLTests.res_dir) if len(args) > 1: variable = ['KEYSTONE:{}'.format(self._keystone_ip), 'NEUTRON:{}'.format(self._neutron_ip), 'OS_AUTH_URL:"{}"'.format(self._os_auth_url), 'OSUSERNAME:"{}"'.format(self._os_username), 'OSTENANTNAME:"{}"'.format(self._os_tenantname), 'OSPASSWORD:"{}"'.format(self._os_password), 'ODL_SYSTEM_IP:{}'.format(self._sdn_controller_ip), 'PORT:{}'.format(self._odl_webport), 'RESTCONFPORT:{}'.format(self._odl_restconfport)] args[1].assert_called_once_with( odl.ODLTests.basic_suite_dir, odl.ODLTests.neutron_suite_dir, log='NONE', output=os.path.join(odl.ODLTests.res_dir, 'output.xml'), report='NONE', stdout=mock.ANY, variable=variable) if len(args) > 2: args[2].assert_called_with( os.path.join(odl.ODLTests.res_dir, 'stdout.txt')) def _test_no_keyword(self, key): kwargs = self._get_run_suites_kwargs(key) self.assertEqual(self.test.run_suites(**kwargs), testcase.TestCase.EX_RUN_ERROR) def test_no_odlusername(self): self._test_no_keyword('odlusername') def test_no_odlpassword(self): self._test_no_keyword('odlpassword') def test_no_neutronip(self): self._test_no_keyword('neutronip') def test_no_osauthurl(self): self._test_no_keyword('osauthurl') def test_no_osusername(self): self._test_no_keyword('osusername') def test_no_ostenantname(self): self._test_no_keyword('ostenantname') def test_no_ospassword(self): self._test_no_keyword('ospassword') def test_no_odlip(self): self._test_no_keyword('odlip') def test_no_odlwebport(self): self._test_no_keyword('odlwebport') def test_no_odlrestconfport(self): self._test_no_keyword('odlrestconfport') def test_set_vars_ko(self): with mock.patch.object(self.test, 'set_robotframework_vars', return_value=False) as mock_object: self._test_run_suites(testcase.TestCase.EX_RUN_ERROR) mock_object.assert_called_once_with( self._odl_username, self._odl_password) @mock.patch('os.makedirs', side_effect=Exception) def test_makedirs_exc(self, mock_method): with mock.patch.object(self.test, 'set_robotframework_vars', return_value=True), \ self.assertRaises(Exception): self._test_run_suites(testcase.TestCase.EX_RUN_ERROR, mock_method) @mock.patch('os.makedirs', side_effect=OSError) def test_makedirs_oserror(self, mock_method): with mock.patch.object(self.test, 'set_robotframework_vars', return_value=True): self._test_run_suites(testcase.TestCase.EX_RUN_ERROR, mock_method) @mock.patch('robot.run', side_effect=RobotError) @mock.patch('os.makedirs') def test_run_ko(self, *args): with mock.patch.object(self.test, 'set_robotframework_vars', return_value=True), \ self.assertRaises(RobotError): self._test_run_suites(testcase.TestCase.EX_RUN_ERROR, *args) @mock.patch('robot.run') @mock.patch('os.makedirs') def test_parse_results_ko(self, *args): with mock.patch.object(self.test, 'set_robotframework_vars', return_value=True), \ mock.patch.object(self.test, 'parse_results', side_effect=RobotError): self._test_run_suites(testcase.TestCase.EX_RUN_ERROR, *args) @mock.patch('robot.run') @mock.patch('os.makedirs') def test_ok(self, *args): with mock.patch.object(self.test, 'set_robotframework_vars', return_value=True), \ mock.patch.object(self.test, 'parse_results'): self._test_run_suites(testcase.TestCase.EX_OK, *args) @mock.patch('robot.run') @mock.patch('os.makedirs', side_effect=OSError(errno.EEXIST, '')) def test_makedirs_oserror17(self, *args): with mock.patch.object(self.test, 'set_robotframework_vars', return_value=True), \ mock.patch.object(self.test, 'parse_results'): self._test_run_suites(testcase.TestCase.EX_OK, *args) @mock.patch('robot.run', return_value=1) @mock.patch('os.makedirs') def test_testcases_in_failure(self, *args): with mock.patch.object(self.test, 'set_robotframework_vars', return_value=True), \ mock.patch.object(self.test, 'parse_results'): self._test_run_suites(testcase.TestCase.EX_OK, *args) class ODLRunTesting(ODLTesting): """The class testing ODLTests.run().""" # pylint: disable=missing-docstring def _test_no_env_var(self, var): with mock.patch('functest.utils.openstack_utils.get_endpoint', return_value="http://{}:9696".format( ODLTesting._neutron_ip)): del os.environ[var] self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR) def _test_run(self, status=testcase.TestCase.EX_OK, exception=None, **kwargs): odlip = kwargs['odlip'] if 'odlip' in kwargs else '127.0.0.3' odlwebport = kwargs['odlwebport'] if 'odlwebport' in kwargs else '8080' odlrestconfport = (kwargs['odlrestconfport'] if 'odlrestconfport' in kwargs else '8181') with mock.patch('functest.utils.openstack_utils.get_endpoint', return_value="http://{}:9696".format( ODLTesting._neutron_ip)): if exception: self.test.run_suites = mock.Mock(side_effect=exception) else: self.test.run_suites = mock.Mock(return_value=status) self.assertEqual(self.test.run(), status) self.test.run_suites.assert_called_once_with( odl.ODLTests.default_suites, neutronip=self._neutron_ip, odlip=odlip, odlpassword=self._odl_password, odlrestconfport=odlrestconfport, odlusername=self._odl_username, odlwebport=odlwebport, osauthurl=self._os_auth_url, ospassword=self._os_password, ostenantname=self._os_tenantname, osusername=self._os_username) def _test_multiple_suites(self, suites, status=testcase.TestCase.EX_OK, **kwargs): odlip = kwargs['odlip'] if 'odlip' in kwargs else '127.0.0.3' odlwebport = kwargs['odlwebport'] if 'odlwebport' in kwargs else '8080' odlrestconfport = (kwargs['odlrestconfport'] if 'odlrestconfport' in kwargs else '8181') with mock.patch('functest.utils.openstack_utils.get_endpoint', return_value="http://{}:9696".format( ODLTesting._neutron_ip)): self.test.run_suites = mock.Mock(return_value=status) self.assertEqual(self.test.run(suites=suites), status) self.test.run_suites.assert_called_once_with( suites, neutronip=self._neutron_ip, odlip=odlip, odlpassword=self._odl_password, odlrestconfport=odlrestconfport, odlusername=self._odl_username, odlwebport=odlwebport, osauthurl=self._os_auth_url, ospassword=self._os_password, ostenantname=self._os_tenantname, osusername=self._os_username) def test_exc(self): with mock.patch('functest.utils.openstack_utils.get_endpoint', side_effect=auth_plugins.MissingAuthPlugin()): self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR) def test_no_os_auth_url(self): self._test_no_env_var("OS_AUTH_URL") def test_no_os_username(self): self._test_no_env_var("OS_USERNAME") def test_no_os_password(self): self._test_no_env_var("OS_PASSWORD") def test_no_os_tenant_name(self): self._test_no_env_var("OS_TENANT_NAME") def test_run_suites_false(self): os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip self._test_run(testcase.TestCase.EX_RUN_ERROR, odlip=self._sdn_controller_ip, odlwebport=self._odl_webport) def test_run_suites_exc(self): with self.assertRaises(Exception): os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip self._test_run(status=testcase.TestCase.EX_RUN_ERROR, exception=Exception(), odlip=self._sdn_controller_ip, odlwebport=self._odl_webport) def test_no_sdn_controller_ip(self): with mock.patch('functest.utils.openstack_utils.get_endpoint', return_value="http://{}:9696".format( ODLTesting._neutron_ip)): self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR) def test_without_installer_type(self): os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip self._test_run(testcase.TestCase.EX_OK, odlip=self._sdn_controller_ip, odlwebport=self._odl_webport) def test_suites(self): os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip self._test_multiple_suites( [odl.ODLTests.basic_suite_dir], testcase.TestCase.EX_OK, odlip=self._sdn_controller_ip, odlwebport=self._odl_webport) def test_fuel(self): os.environ["INSTALLER_TYPE"] = "fuel" self._test_run(testcase.TestCase.EX_OK, odlip=self._neutron_ip, odlwebport='8282') def test_apex_no_controller_ip(self): with mock.patch('functest.utils.openstack_utils.get_endpoint', return_value="http://{}:9696".format( ODLTesting._neutron_ip)): os.environ["INSTALLER_TYPE"] = "apex" self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR) def test_apex(self): os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip os.environ["INSTALLER_TYPE"] = "apex" self._test_run(testcase.TestCase.EX_OK, odlip=self._sdn_controller_ip, odlwebport='8081', odlrestconfport='8081') def test_netvirt_no_controller_ip(self): with mock.patch('functest.utils.openstack_utils.get_endpoint', return_value="http://{}:9696".format( ODLTesting._neutron_ip)): os.environ["INSTALLER_TYPE"] = "netvirt" self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR) def test_netvirt(self): os.environ["SDN_CONTROLLER_IP"] = self._sdn_controller_ip os.environ["INSTALLER_TYPE"] = "netvirt" self._test_run(testcase.TestCase.EX_OK, odlip=self._sdn_controller_ip, odlwebport='8081', odlrestconfport='8081') def test_joid_no_controller_ip(self): with mock.patch('functest.utils.openstack_utils.get_endpoint', return_value="http://{}:9696".format( ODLTesting._neutron_ip)): os.environ["INSTALLER_TYPE"] = "joid" self.assertEqual(self.test.run(), testcase.TestCase.EX_RUN_ERROR) def test_joid(self): os.environ["SDN_CONTROLLER"] = self._sdn_controller_ip os.environ["INSTALLER_TYPE"] = "joid" self._test_run(testcase.TestCase.EX_OK, odlip=self._sdn_controller_ip, odlwebport='8080') def test_compass(self): os.environ["INSTALLER_TYPE"] = "compass" self._test_run(testcase.TestCase.EX_OK, odlip=self._neutron_ip, odlwebport='8181') class ODLArgParserTesting(ODLTesting): """The class testing ODLParser.""" # pylint: disable=missing-docstring def setUp(self): self.parser = odl.ODLParser() super(ODLArgParserTesting, self).setUp() def test_default(self): self.assertEqual(self.parser.parse_args(), self.defaultargs) def test_basic(self): self.defaultargs['neutronip'] = self._neutron_ip self.defaultargs['odlip'] = self._sdn_controller_ip self.assertEqual( self.parser.parse_args( ["--neutronip={}".format(self._neutron_ip), "--odlip={}".format(self._sdn_controller_ip)]), self.defaultargs) @mock.patch('sys.stderr', new_callable=six.StringIO) def test_fail(self, mock_method): self.defaultargs['foo'] = 'bar' with self.assertRaises(SystemExit): self.parser.parse_args(["--foo=bar"]) self.assertTrue(mock_method.getvalue().startswith("usage:")) def _test_arg(self, arg, value): self.defaultargs[arg] = value self.assertEqual( self.parser.parse_args(["--{}={}".format(arg, value)]), self.defaultargs) def test_odlusername(self): self._test_arg('odlusername', 'foo') def test_odlpassword(self): self._test_arg('odlpassword', 'foo') def test_osauthurl(self): self._test_arg('osauthurl', 'http://127.0.0.4:5000/v2') def test_neutronip(self): self._test_arg('neutronip', '127.0.0.4') def test_osusername(self): self._test_arg('osusername', 'foo') def test_ostenantname(self): self._test_arg('ostenantname', 'foo') def test_ospassword(self): self._test_arg('ospassword', 'foo') def test_odlip(self): self._test_arg('odlip', '127.0.0.4') def test_odlwebport(self): self._test_arg('odlwebport', '80') def test_odlrestconfport(self): self._test_arg('odlrestconfport', '80') def test_pushtodb(self): self.defaultargs['pushtodb'] = True self.assertEqual(self.parser.parse_args(["--{}".format('pushtodb')]), self.defaultargs) def test_multiple_args(self): self.defaultargs['neutronip'] = self._neutron_ip self.defaultargs['odlip'] = self._sdn_controller_ip self.assertEqual( self.parser.parse_args( ["--neutronip={}".format(self._neutron_ip), "--odlip={}".format(self._sdn_controller_ip)]), self.defaultargs) if __name__ == "__main__": logging.disable(logging.CRITICAL) unittest.main(verbosity=2)