From 155cb48bca9b66fa5188e5c1c63adf696cd6d127 Mon Sep 17 00:00:00 2001 From: Akihiro MOTOKI Date: Sat, 7 Sep 2013 02:10:57 +0900 Subject: [PATCH] Make neutron.common.log.log print module path Closes-Bug: #1221663 neutron.common.log.log is useful for logging arguments of a method. It outputs class name and method name, but module path is not output. A module path is useful to search the log message. Change-Id: Ic2903da750cc13980d5cdee153bb079f7d4ee122 --- neutron/common/log.py | 5 +- neutron/tests/unit/test_common_log.py | 70 +++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 neutron/tests/unit/test_common_log.py diff --git a/neutron/common/log.py b/neutron/common/log.py index fcc57b896..85e4dce80 100644 --- a/neutron/common/log.py +++ b/neutron/common/log.py @@ -25,10 +25,11 @@ def log(method): """Decorator helping to log method calls.""" def wrapper(*args, **kwargs): instance = args[0] - data = {"class_name": instance.__class__.__name__, + data = {"class_name": (instance.__class__.__module__ + '.' + + instance.__class__.__name__), "method_name": method.__name__, "args": args[1:], "kwargs": kwargs} LOG.debug(_('%(class_name)s method %(method_name)s' - ' called with arguments %(args)s %(kwargs)s '), data) + ' called with arguments %(args)s %(kwargs)s'), data) return method(*args, **kwargs) return wrapper diff --git a/neutron/tests/unit/test_common_log.py b/neutron/tests/unit/test_common_log.py new file mode 100644 index 000000000..318613a1b --- /dev/null +++ b/neutron/tests/unit/test_common_log.py @@ -0,0 +1,70 @@ +# Copyright (c) 2013 OpenStack Foundation. +# +# 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 mock + +from neutron.common import log as call_log +from neutron.tests import base + + +MODULE_NAME = 'neutron.tests.unit.test_common_log' + + +class TargetKlass(object): + + @call_log.log + def test_method(self, arg1, arg2, *args, **kwargs): + pass + + +class TestCallLog(base.BaseTestCase): + def setUp(self): + super(TestCallLog, self).setUp() + self.klass = TargetKlass() + self.expected_format = ('%(class_name)s method %(method_name)s ' + 'called with arguments %(args)s %(kwargs)s') + self.expected_data = {'class_name': MODULE_NAME + '.TargetKlass', + 'method_name': 'test_method', + 'args': (), + 'kwargs': {}} + + def test_call_log_all_args(self): + self.expected_data['args'] = (10, 20) + with mock.patch.object(call_log.LOG, 'debug') as log_debug: + self.klass.test_method(10, 20) + log_debug.assert_called_once_with(self.expected_format, + self.expected_data) + + def test_call_log_all_kwargs(self): + self.expected_data['kwargs'] = {'arg1': 10, 'arg2': 20} + with mock.patch.object(call_log.LOG, 'debug') as log_debug: + self.klass.test_method(arg1=10, arg2=20) + log_debug.assert_called_once_with(self.expected_format, + self.expected_data) + + def test_call_log_known_args_unknown_args_kwargs(self): + self.expected_data['args'] = (10, 20, 30) + self.expected_data['kwargs'] = {'arg4': 40} + with mock.patch.object(call_log.LOG, 'debug') as log_debug: + self.klass.test_method(10, 20, 30, arg4=40) + log_debug.assert_called_once_with(self.expected_format, + self.expected_data) + + def test_call_log_known_args_kwargs_unknown_kwargs(self): + self.expected_data['args'] = (10,) + self.expected_data['kwargs'] = {'arg2': 20, 'arg3': 30, 'arg4': 40} + with mock.patch.object(call_log.LOG, 'debug') as log_debug: + self.klass.test_method(10, arg2=20, arg3=30, arg4=40) + log_debug.assert_called_once_with(self.expected_format, + self.expected_data)