From baf68b5a3f575dfc4cf672d9117f940d93e0dee4 Mon Sep 17 00:00:00 2001 From: Terry Wilson Date: Fri, 28 Apr 2017 13:55:21 -0500 Subject: [PATCH] Allow choosing vlog levels to patch and restoring the vlog Change-Id: I99bd8e5deec3cf92aebe8402c3c7b7d7a670556c --- ovsdbapp/backend/ovs_idl/fixtures.py | 32 ++++++++++ ovsdbapp/backend/ovs_idl/vlog.py | 60 ++++++++++++++++--- .../tests/unit/backend/ovs_idl/test_vlog.py | 50 ++++++++++++++++ requirements.txt | 1 + 4 files changed, 135 insertions(+), 8 deletions(-) create mode 100644 ovsdbapp/backend/ovs_idl/fixtures.py create mode 100644 ovsdbapp/tests/unit/backend/ovs_idl/test_vlog.py diff --git a/ovsdbapp/backend/ovs_idl/fixtures.py b/ovsdbapp/backend/ovs_idl/fixtures.py new file mode 100644 index 00000000..d94bd658 --- /dev/null +++ b/ovsdbapp/backend/ovs_idl/fixtures.py @@ -0,0 +1,32 @@ +# 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 + +import fixtures + +from ovsdbapp.backend.ovs_idl import vlog + + +class OvsdbVlogFixture(fixtures.Fixture): + def __init__(self, *args, **kwargs): + """Constructor for the OvsdbVlogVixture + + The OvsdbVlogFixture will call vlog.use_python_logger with any args or + kwargs passed and call vlog.reset_logger() on cleanup + """ + self.args = args + self.kwargs = kwargs + + def _setUp(self): + vlog.use_python_logger(*self.args, **self.kwargs) + self.addCleanup(vlog.reset_logger) diff --git a/ovsdbapp/backend/ovs_idl/vlog.py b/ovsdbapp/backend/ovs_idl/vlog.py index 98b7fc52..0092b5bf 100644 --- a/ovsdbapp/backend/ovs_idl/vlog.py +++ b/ovsdbapp/backend/ovs_idl/vlog.py @@ -12,20 +12,64 @@ # License for the specific language governing permissions and limitations # under the License. +import collections import logging from ovs import vlog -LOG = logging.getLogger(__name__) +_LOG = logging.getLogger(__name__) + +# Map local log LEVELS to local LOG functions +CRITICAL = _LOG.critical +ERROR = _LOG.error +WARN = _LOG.warn +INFO = _LOG.info +DEBUG = _LOG.debug + +_LOG_MAPPING = collections.OrderedDict(( + (CRITICAL, vlog.Vlog.emer), + (ERROR, vlog.Vlog.err), + (WARN, vlog.Vlog.warn), + (INFO, vlog.Vlog.info), + (DEBUG, vlog.Vlog.dbg), +)) +ALL_LEVELS = tuple(_LOG_MAPPING.keys()) -def use_python_logger(): - """Replace the OVS IDL logger functions with our logger""" +def _original_vlog_fn(level): + """Get the original unpatched OVS vlog function for level""" + return _LOG_MAPPING[level] + + +def _current_vlog_fn(level): + """Get the currently used OVS vlog function mapped to level""" + return getattr(vlog.Vlog, _LOG_MAPPING[level].__name__) + + +def use_python_logger(levels=ALL_LEVELS, max_level=None): + """Replace the OVS vlog functions with our logger + + :param: levels: log levels *from this module* e.g. [vlog.WARN] + :type: levels: iterable + :param: max_level: the maximum level to log + :type: max_level: vlog level, CRITICAL, ERROR, WARN, INFO, or DEBUG + """ + + if max_level: + levels = levels[:-levels.index(max_level)] # NOTE(twilson) Replace functions directly instead of subclassing so that # debug messages contain the correct function/filename/line information - vlog.Vlog.emer = LOG.critical - vlog.Vlog.err = LOG.error - vlog.Vlog.warn = LOG.warning - vlog.Vlog.info = LOG.info - vlog.Vlog.dbg = LOG.debug + for log in levels: + setattr(vlog.Vlog, _LOG_MAPPING[log].__name__, log) + + +def reset_logger(): + """Reset the OVS vlog functions to their original values""" + for log in ALL_LEVELS: + setattr(vlog.Vlog, _LOG_MAPPING[log].__name__, _LOG_MAPPING[log]) + + +def is_patched(level): + """Test if the vlog level is patched""" + return _current_vlog_fn(level) != _original_vlog_fn(level) diff --git a/ovsdbapp/tests/unit/backend/ovs_idl/test_vlog.py b/ovsdbapp/tests/unit/backend/ovs_idl/test_vlog.py new file mode 100644 index 00000000..6a46664b --- /dev/null +++ b/ovsdbapp/tests/unit/backend/ovs_idl/test_vlog.py @@ -0,0 +1,50 @@ +# 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 ovsdbapp.backend.ovs_idl import fixtures +from ovsdbapp.backend.ovs_idl import vlog +from ovsdbapp.tests import base + + +class TestOvsdbVlog(base.TestCase): + def setUp(self): + super(TestOvsdbVlog, self).setUp() + self.useFixture(fixtures.OvsdbVlogFixture()) + + def test_vlog_patched(self): + for log_fn in vlog.ALL_LEVELS: + self.assertTrue(vlog.is_patched(log_fn)) + + def test_vlog_reset(self): + vlog.reset_logger() + for log_fn in vlog.ALL_LEVELS: + self.assertFalse(vlog.is_patched(log_fn)) + + def test_vlog_patch_all_but_debug(self): + vlog.reset_logger() + removed_level = vlog.DEBUG + levels = set(vlog.ALL_LEVELS) - set([removed_level]) + vlog.use_python_logger(levels) + for lvl in levels: + self.assertTrue(vlog.is_patched(lvl)) + self.assertFalse(vlog.is_patched(removed_level)) + + def test_vlog_max_level(self): + vlog.reset_logger() + max_level = vlog.WARN + vlog.use_python_logger(max_level=max_level) + patched_levels = (vlog.CRITICAL, vlog.ERROR, vlog.WARN) + unpatched_levels = (vlog.INFO, vlog.DEBUG) + for lvl in patched_levels: + self.assertTrue(vlog.is_patched(lvl)) + for lvl in unpatched_levels: + self.assertFalse(vlog.is_patched(lvl)) diff --git a/requirements.txt b/requirements.txt index 6d719778..6269b434 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,5 +2,6 @@ # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. +fixtures>=3.0.0 # Apache-2.0/BSD ovs>=2.7.0 # Apache-2.0 pbr!=2.1.0,>=2.0.0 # Apache-2.0