diff --git a/.gitignore b/.gitignore index 69e84b8ec..cf07c6873 100644 --- a/.gitignore +++ b/.gitignore @@ -50,7 +50,7 @@ doc/_build/ # Logs /logs -sys_test.log +*.log # Certs /ca.crt diff --git a/core/__init__.py b/core/__init__.py index e69de29bb..74b32bcc3 100644 --- a/core/__init__.py +++ b/core/__init__.py @@ -0,0 +1,17 @@ +# Copyright 2016 Mirantis, Inc. +# +# 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 + +logger = logging.getLogger('fuel-qa.{}'.format(__name__)) diff --git a/core/_tests/helpers/test_log_helpers.py b/core/_tests/helpers/test_log_helpers.py new file mode 100644 index 000000000..5ce83eed8 --- /dev/null +++ b/core/_tests/helpers/test_log_helpers.py @@ -0,0 +1,127 @@ +# Copyright 2016 Mirantis, Inc. +# +# 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. + +from __future__ import absolute_import +from __future__ import unicode_literals + +import logging +import unittest + +# pylint: disable=import-error +from mock import call +from mock import Mock +from mock import patch +# pylint: enable=import-error + +from core.helpers import log_helpers + +# pylint: disable=no-self-use + + +@patch('core.helpers.log_helpers.logger', autospec=True) +class TestLogWrap(unittest.TestCase): + def test_positive(self, logger): + @log_helpers.logwrap + def func(*args, **kwargs): + return 'complete with {} {}'.format(args, kwargs) + + call_args = 't', 'e' + call_kwargs = dict(s='s', t='t') + + result = func(*call_args, **call_kwargs) + self.assertEqual( + result, + 'complete with {} {}'.format(call_args, call_kwargs) + ) + + logger.assert_has_calls(( + call.debug( + "Calling: func with args: {} {}".format( + call_args, call_kwargs)), + call.debug( + "Done: func with result: {}".format(result)) + )) + + def test_negative(self, logger): + @log_helpers.logwrap + def func(*args, **kwargs): + raise ValueError(args, kwargs) + + call_args = 't', 'e' + call_kwargs = dict(s='s', t='t') + + with self.assertRaises(ValueError): + func(*call_args, **call_kwargs) + + logger.assert_has_calls(( + call.debug( + "Calling: func with args: {} {}".format( + call_args, call_kwargs)), + call.exception( + 'func raised: ValueError({}, {})\n'.format( + call_args, call_kwargs)) + )) + + +@patch('logging.StreamHandler') +@patch('core.helpers.log_helpers.logger', autospec=True) +class TestQuietLogger(unittest.TestCase): + def test_default(self, logger_obj, handler_cls): + handler = Mock() + handler.configure_mock(level=logging.INFO) + handler_cls.return_value = handler + + with log_helpers.QuietLogger(): + log_helpers.logger.warning('Test') + + handler.assert_has_calls(( + call.setLevel(logging.INFO + 1), + call.setLevel(logging.INFO) + )) + + logger_obj.assert_has_calls((call.warning('Test'), )) + + def test_upper_level(self, logger_obj, handler_cls): + handler = Mock() + handler.configure_mock(level=logging.INFO) + handler_cls.return_value = handler + + with log_helpers.QuietLogger(logging.WARNING): + log_helpers.logger.warning('Test') + + handler.assert_has_calls(( + call.setLevel(logging.WARNING + 1), + call.setLevel(logging.INFO) + )) + + logger_obj.assert_has_calls((call.warning('Test'), )) + + def test_lower_level(self, logger_obj, handler_cls): + handler = Mock() + handler.configure_mock(level=logging.INFO) + handler_cls.return_value = handler + + with log_helpers.QuietLogger(logging.DEBUG): + log_helpers.logger.warning('Test') + + handler.assert_has_calls(( + call.setLevel(logging.INFO), + )) + + logger_obj.assert_has_calls(( + call.debug( + 'QuietLogger requested lower level, than is already set. ' + 'Not changing level'), + call.warning('Test'), + )) diff --git a/core/_tests/helpers/test_setup_teardown.py b/core/_tests/helpers/test_setup_teardown.py index 2f1fe744b..d465487ab 100644 --- a/core/_tests/helpers/test_setup_teardown.py +++ b/core/_tests/helpers/test_setup_teardown.py @@ -1,3 +1,17 @@ +# Copyright 2016 Mirantis, Inc. +# +# 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. + from __future__ import absolute_import from __future__ import print_function diff --git a/core/_tests/models/test_collector_client.py b/core/_tests/models/test_collector_client.py index 1d1f20c63..16f348e78 100644 --- a/core/_tests/models/test_collector_client.py +++ b/core/_tests/models/test_collector_client.py @@ -1,3 +1,17 @@ +# Copyright 2016 Mirantis, Inc. +# +# 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. + from __future__ import absolute_import from __future__ import unicode_literals diff --git a/core/helpers/log_helpers.py b/core/helpers/log_helpers.py new file mode 100644 index 000000000..1fb28633d --- /dev/null +++ b/core/helpers/log_helpers.py @@ -0,0 +1,70 @@ +# Copyright 2016 Mirantis, Inc. +# +# 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. + +from __future__ import unicode_literals + +import functools +import logging + +from core import logger + + +def logwrap(func): + @functools.wraps(func) + def wrapped(*args, **kwargs): + logger.debug( + "Calling: {} with args: {} {}".format( + func.__name__, args, kwargs + ) + ) + try: + result = func(*args, **kwargs) + logger.debug( + "Done: {} with result: {}".format(func.__name__, result)) + except BaseException as e: + logger.exception( + '{func} raised: {exc!r}\n'.format(func=func.__name__, exc=e)) + raise + return result + return wrapped + + +class QuietLogger(object): + """Reduce logging level while context is executed.""" + + def __init__(self, upper_log_level=None): + """Reduce logging level while context is executed. + + :param upper_log_level: log level to ignore + :type upper_log_level: int + """ + self.log_level = upper_log_level + self.level = None + + def __enter__(self): + console = logging.StreamHandler() + self.level = console.level + if self.log_level is None: + self.log_level = self.level + elif self.log_level < self.level: + logger.debug( + 'QuietLogger requested lower level, than is already set. ' + 'Not changing level') + return + console.setLevel(self.log_level + 1) + + def __exit__(self, exc_type, exc_value, exc_tb): + logging.StreamHandler().setLevel(self.level) + +__all__ = ['logwrap', 'QuietLogger', 'logger'] diff --git a/core/models/collector_client.py b/core/models/collector_client.py index 2c7162b3c..31e2e5f72 100644 --- a/core/models/collector_client.py +++ b/core/models/collector_client.py @@ -16,7 +16,7 @@ from __future__ import unicode_literals import requests -from fuelweb_test import logwrap +from core.helpers.log_helpers import logwrap class CollectorClient(object): diff --git a/fuelweb_test/__init__.py b/fuelweb_test/__init__.py index 6a7c155a6..4162481e8 100644 --- a/fuelweb_test/__init__.py +++ b/fuelweb_test/__init__.py @@ -14,12 +14,13 @@ from __future__ import unicode_literals -import functools import logging.config import os -import traceback import warnings +from core.helpers.log_helpers import logwrap +from core.helpers.log_helpers import QuietLogger + from fuelweb_test.settings import LOGS_DIR if not os.path.exists(LOGS_DIR): @@ -100,40 +101,4 @@ warnings.filterwarnings( logger = logging.getLogger('fuel-qa.{}'.format(__name__)) - -def logwrap(func): - @functools.wraps(func) - def wrapped(*args, **kwargs): - logger.debug( - "Calling: {} with args: {} {}".format( - func.__name__, args, kwargs - ) - ) - try: - result = func(*args, **kwargs) - logger.debug( - "Done: {} with result: {}".format(func.__name__, result)) - except BaseException as e: - logger.error( - '{func} raised: {exc!r}\n' - 'Traceback: {tb!s}'.format( - func=func.__name__, exc=e, tb=traceback.format_exc())) - raise - return result - return wrapped - - -class QuietLogger(object): - """Reduce logging level while context is executed.""" - - def __init__(self, upper_log_level=logging.WARNING): - self.log_level = upper_log_level - self.storage = None - - def __enter__(self): - console = logging.StreamHandler() - self.storage = console.level - console.setLevel(self.log_level + 1) - - def __exit__(self, exc_type, exc_value, exc_tb): - logging.StreamHandler().setLevel(self.storage) +__all__ = ['QuietLogger', 'logwrap', 'logger'] diff --git a/fuelweb_test/helpers/checkers.py b/fuelweb_test/helpers/checkers.py index 7eecd312b..0b80bacc4 100644 --- a/fuelweb_test/helpers/checkers.py +++ b/fuelweb_test/helpers/checkers.py @@ -36,8 +36,9 @@ from six.moves import xrange # pylint: enable=redefined-builtin import yaml +from core.helpers.log_helpers import logwrap + from fuelweb_test import logger -from fuelweb_test import logwrap from fuelweb_test.helpers.ssh_manager import SSHManager from fuelweb_test.helpers.utils import get_mongo_partitions from fuelweb_test.settings import DNS_SUFFIX diff --git a/fuelweb_test/helpers/cic_maintenance_mode.py b/fuelweb_test/helpers/cic_maintenance_mode.py index c630dbacd..359dc166c 100644 --- a/fuelweb_test/helpers/cic_maintenance_mode.py +++ b/fuelweb_test/helpers/cic_maintenance_mode.py @@ -12,7 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. -from fuelweb_test import logwrap +from core.helpers.log_helpers import logwrap + from fuelweb_test.helpers.ssh_manager import SSHManager diff --git a/fuelweb_test/helpers/common.py b/fuelweb_test/helpers/common.py index be58a68a7..c0d6d1956 100644 --- a/fuelweb_test/helpers/common.py +++ b/fuelweb_test/helpers/common.py @@ -37,10 +37,11 @@ from six.moves import xrange from six.moves import urllib # pylint: enable=import-error +from core.helpers.log_helpers import logwrap + from fuelweb_test.helpers import checkers from fuelweb_test.helpers.ssh_manager import SSHManager from fuelweb_test import logger -from fuelweb_test import logwrap from fuelweb_test.settings import DISABLE_SSL from fuelweb_test.settings import PATH_TO_CERT from fuelweb_test.settings import VERIFY_SSL diff --git a/fuelweb_test/helpers/eb_tables.py b/fuelweb_test/helpers/eb_tables.py index 5c809d1a1..ae7011b51 100644 --- a/fuelweb_test/helpers/eb_tables.py +++ b/fuelweb_test/helpers/eb_tables.py @@ -14,7 +14,7 @@ import subprocess -from fuelweb_test import logwrap +from core.helpers.log_helpers import logwrap class Ebtables(object): diff --git a/fuelweb_test/helpers/fuel_actions.py b/fuelweb_test/helpers/fuel_actions.py index 51d493661..040ca521c 100644 --- a/fuelweb_test/helpers/fuel_actions.py +++ b/fuelweb_test/helpers/fuel_actions.py @@ -25,8 +25,9 @@ from proboscis.asserts import assert_true from six.moves import cStringIO import yaml +from core.helpers.log_helpers import logwrap + from fuelweb_test import logger -from fuelweb_test import logwrap from fuelweb_test.helpers.decorators import retry from fuelweb_test.helpers.regenerate_repo import regenerate_centos_repo from fuelweb_test.helpers.regenerate_repo import regenerate_ubuntu_repo diff --git a/fuelweb_test/helpers/log_server.py b/fuelweb_test/helpers/log_server.py index ecfc9e9be..b16d50f9c 100644 --- a/fuelweb_test/helpers/log_server.py +++ b/fuelweb_test/helpers/log_server.py @@ -16,7 +16,7 @@ import select import socket import threading -from fuelweb_test import logwrap +from core.helpers.log_helpers import logwrap class LogServer(threading.Thread): diff --git a/fuelweb_test/helpers/multiple_networks_hacks.py b/fuelweb_test/helpers/multiple_networks_hacks.py index bd34a0681..e2d935ef3 100644 --- a/fuelweb_test/helpers/multiple_networks_hacks.py +++ b/fuelweb_test/helpers/multiple_networks_hacks.py @@ -21,7 +21,8 @@ from proboscis.asserts import assert_equal -from fuelweb_test import logwrap +from core.helpers.log_helpers import logwrap + from fuelweb_test.helpers.ssh_manager import SSHManager diff --git a/fuelweb_test/helpers/security.py b/fuelweb_test/helpers/security.py index 342cdfa8e..2d6922f73 100644 --- a/fuelweb_test/helpers/security.py +++ b/fuelweb_test/helpers/security.py @@ -16,7 +16,8 @@ from random import randrange from proboscis.asserts import assert_equal -from fuelweb_test import logwrap +from core.helpers.log_helpers import logwrap + from fuelweb_test import logger from fuelweb_test.helpers.decorators import retry from fuelweb_test.settings import OPENSTACK_RELEASE diff --git a/fuelweb_test/helpers/ssl_helpers.py b/fuelweb_test/helpers/ssl_helpers.py index 6cfb50b01..963d272ca 100644 --- a/fuelweb_test/helpers/ssl_helpers.py +++ b/fuelweb_test/helpers/ssl_helpers.py @@ -16,9 +16,9 @@ import os from OpenSSL import crypto -from fuelweb_test import logger -from fuelweb_test import logwrap +from core.helpers.log_helpers import logwrap +from fuelweb_test import logger from fuelweb_test.settings import DISABLE_SSL from fuelweb_test.settings import PATH_TO_CERT from fuelweb_test.settings import PATH_TO_PEM diff --git a/fuelweb_test/helpers/utils.py b/fuelweb_test/helpers/utils.py index a91e41f34..16e7df17d 100644 --- a/fuelweb_test/helpers/utils.py +++ b/fuelweb_test/helpers/utils.py @@ -45,8 +45,9 @@ from six.moves import xrange # pylint: enable=redefined-builtin import yaml +from core.helpers.log_helpers import logwrap + from fuelweb_test import logger -from fuelweb_test import logwrap from fuelweb_test import settings from fuelweb_test.helpers.ssh_manager import SSHManager from gates_tests.helpers import exceptions diff --git a/fuelweb_test/models/environment.py b/fuelweb_test/models/environment.py index 250a1cd56..cce90fbdc 100644 --- a/fuelweb_test/models/environment.py +++ b/fuelweb_test/models/environment.py @@ -28,6 +28,8 @@ from proboscis.asserts import assert_true import six from core.models.collector_client import CollectorClient +from core.helpers.log_helpers import logwrap +from core.helpers.log_helpers import QuietLogger from fuelweb_test.helpers.decorators import revert_info from fuelweb_test.helpers.decorators import update_rpm_packages @@ -48,8 +50,6 @@ from fuelweb_test.models.fuel_web_client import FuelWebClient from fuelweb_test import settings from fuelweb_test.settings import CUSTOM_FUEL_SETTING_YAML from fuelweb_test.settings import iface_alias -from fuelweb_test import logwrap -from fuelweb_test import QuietLogger from fuelweb_test import logger diff --git a/fuelweb_test/models/fuel_web_client.py b/fuelweb_test/models/fuel_web_client.py index 9b380804c..7753e0da5 100644 --- a/fuelweb_test/models/fuel_web_client.py +++ b/fuelweb_test/models/fuel_web_client.py @@ -42,10 +42,11 @@ from proboscis.asserts import assert_raises from proboscis.asserts import assert_true import yaml +from core.helpers.log_helpers import logwrap +from core.helpers.log_helpers import QuietLogger + from fuelweb_test import logger -from fuelweb_test import logwrap from fuelweb_test import ostf_test_mapping -from fuelweb_test import QuietLogger from fuelweb_test.helpers import ceph from fuelweb_test.helpers import checkers from fuelweb_test.helpers import replace_repos diff --git a/fuelweb_test/models/nailgun_client.py b/fuelweb_test/models/nailgun_client.py index 08c574c98..edf12f384 100644 --- a/fuelweb_test/models/nailgun_client.py +++ b/fuelweb_test/models/nailgun_client.py @@ -17,7 +17,8 @@ from warnings import warn from keystoneauth1.identity import V2Password from keystoneauth1.session import Session as KeystoneSession -from fuelweb_test import logwrap +from core.helpers.log_helpers import logwrap + from fuelweb_test import logger from fuelweb_test.settings import FORCE_HTTPS_MASTER_NODE from fuelweb_test.settings import KEYSTONE_CREDS diff --git a/fuelweb_test/tests/test_cli_base.py b/fuelweb_test/tests/test_cli_base.py index de225831d..244cc45f2 100644 --- a/fuelweb_test/tests/test_cli_base.py +++ b/fuelweb_test/tests/test_cli_base.py @@ -24,12 +24,13 @@ from devops.helpers.helpers import wait from six.moves import urllib # pylint: enable=import-error +from core.helpers.log_helpers import logwrap + from fuelweb_test.helpers.checkers import fail_deploy from fuelweb_test.helpers.checkers import incomplete_deploy from fuelweb_test.helpers.checkers import incomplete_tasks from fuelweb_test.helpers.ssl_helpers import change_cluster_ssl_config from fuelweb_test.tests.base_test_case import TestBasic -from fuelweb_test import logwrap from fuelweb_test import logger from fuelweb_test.helpers.utils import hiera_json_out from fuelweb_test.settings import iface_alias diff --git a/fuelweb_test/tests/test_cpu_pinning.py b/fuelweb_test/tests/test_cpu_pinning.py index d01bee976..ee3791e8a 100644 --- a/fuelweb_test/tests/test_cpu_pinning.py +++ b/fuelweb_test/tests/test_cpu_pinning.py @@ -18,11 +18,12 @@ from keystoneauth1.exceptions import BadRequest from proboscis import asserts from proboscis import test +from core.helpers.log_helpers import logwrap + from fuelweb_test.helpers.decorators import log_snapshot_after_test from fuelweb_test.helpers import os_actions from fuelweb_test.helpers import utils from fuelweb_test import logger -from fuelweb_test import logwrap from fuelweb_test import settings from fuelweb_test.tests.base_test_case import SetupEnvironment from fuelweb_test.tests.base_test_case import TestBasic diff --git a/fuelweb_test/tests/test_net_templates_base.py b/fuelweb_test/tests/test_net_templates_base.py index 589143038..dff0aa943 100644 --- a/fuelweb_test/tests/test_net_templates_base.py +++ b/fuelweb_test/tests/test_net_templates_base.py @@ -18,8 +18,9 @@ from proboscis.asserts import assert_equal from proboscis.asserts import assert_true from proboscis.asserts import fail +from core.helpers.log_helpers import logwrap + from fuelweb_test import logger -from fuelweb_test import logwrap from fuelweb_test.helpers.utils import get_ip_listen_stats from fuelweb_test.tests.base_test_case import TestBasic diff --git a/fuelweb_test/tests/test_neutron_tun.py b/fuelweb_test/tests/test_neutron_tun.py index 27977bcbb..fad45b5a6 100644 --- a/fuelweb_test/tests/test_neutron_tun.py +++ b/fuelweb_test/tests/test_neutron_tun.py @@ -17,6 +17,8 @@ from proboscis.asserts import assert_equal from proboscis.asserts import assert_true from proboscis import test +from core.helpers.log_helpers import QuietLogger + from fuelweb_test.helpers.common import Common from fuelweb_test.helpers import checkers from fuelweb_test.helpers import os_actions @@ -27,7 +29,6 @@ from fuelweb_test.tests.base_test_case import SetupEnvironment from fuelweb_test.tests.base_test_case import TestBasic from fuelweb_test.tests.test_neutron_tun_base import NeutronTunHaBase from fuelweb_test import logger -from fuelweb_test import QuietLogger @test(groups=["ha_neutron_tun", "neutron", "smoke_neutron", "deployment"]) diff --git a/fuelweb_test/tests/tests_strength/test_failover_base.py b/fuelweb_test/tests/tests_strength/test_failover_base.py index 8f422f14b..44feaaccd 100644 --- a/fuelweb_test/tests/tests_strength/test_failover_base.py +++ b/fuelweb_test/tests/tests_strength/test_failover_base.py @@ -30,8 +30,9 @@ from six.moves import xrange # pylint: enable=redefined-builtin import yaml +from core.helpers.log_helpers import logwrap + from fuelweb_test import logger -from fuelweb_test import logwrap from fuelweb_test.helpers import os_actions from fuelweb_test.helpers.checkers import check_mysql from fuelweb_test.helpers.checkers import check_ping diff --git a/fuelweb_test/tests/tests_strength/test_neutron_base.py b/fuelweb_test/tests/tests_strength/test_neutron_base.py index b66aa10f9..40ff884b4 100644 --- a/fuelweb_test/tests/tests_strength/test_neutron_base.py +++ b/fuelweb_test/tests/tests_strength/test_neutron_base.py @@ -19,10 +19,11 @@ from proboscis.asserts import assert_equal from proboscis.asserts import assert_true from proboscis import SkipTest +from core.helpers.log_helpers import logwrap + from fuelweb_test.helpers.decorators import retry from fuelweb_test.helpers import os_actions from fuelweb_test import logger -from fuelweb_test import logwrap from fuelweb_test import settings from fuelweb_test.tests import base_test_case diff --git a/tox.ini b/tox.ini index ac52ec5ca..df78c4713 100644 --- a/tox.ini +++ b/tox.ini @@ -92,8 +92,6 @@ commands = sphinx-build -b html -d _build/doctrees . _build/html [testenv:cover] deps = - mock>=1.2 - pytest-cov {[testenv]deps} commands = py.test --cov-config .coveragerc --cov-report html --cov=core core/_tests