• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3#   Copyright 2018 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17from mock import Mock
18from mock import patch
19import unittest
20from unittest import TestCase
21from acts.metrics.logger import LoggerProxy
22from acts.metrics.logger import MetricLogger
23
24CREATE_FROM_INSTANCE = (
25    'acts.metrics.logger.subscription_bundle.create_from_instance')
26LOGGING_ERROR = 'logging.error'
27LOGGING_DEBUG = 'logging.debug'
28GET_CONTEXT_FOR_EVENT = 'acts.metrics.logger.get_context_for_event'
29GET_FILE = 'acts.metrics.logger.inspect.getfile'
30MKDTEMP = 'acts.metrics.logger.tempfile.mkdtemp'
31PROTO_METRIC_PUBLISHER = 'acts.metrics.logger.ProtoMetricPublisher'
32TEST_CASE_LOGGER_PROXY = 'acts.metrics.logger.TestCaseLoggerProxy'
33TEST_CLASS_LOGGER_PROXY = 'acts.metrics.logger.TestClassLoggerProxy'
34
35
36class MetricLoggerTest(TestCase):
37    """Unit tests for the MetricLogger class."""
38
39    @patch(TEST_CASE_LOGGER_PROXY)
40    def test_for_test_case_returns_test_case_proxy(self, proxy_cls):
41        args = (Mock(), )
42        kwargs = {'mock' : Mock()}
43        logger = MetricLogger.for_test_case(*args, **kwargs)
44
45        proxy_cls.assert_called_once_with(MetricLogger, args, kwargs)
46
47    @patch(TEST_CLASS_LOGGER_PROXY)
48    def test_for_test_class_returns_test_class_proxy(self, proxy_cls):
49        args = (Mock(),)
50        kwargs = {'mock': Mock()}
51        logger = MetricLogger.for_test_class(*args, **kwargs)
52
53        proxy_cls.assert_called_once_with(MetricLogger, args, kwargs)
54
55    @patch(TEST_CASE_LOGGER_PROXY)
56    def test_for_test_case_works_on_subclases(self, proxy_cls):
57        class TestLogger(MetricLogger):
58            pass
59        args = (Mock(),)
60        kwargs = {'mock': Mock()}
61        logger = TestLogger.for_test_case(*args, **kwargs)
62
63        proxy_cls.assert_called_once_with(TestLogger, args, kwargs)
64
65    @patch(TEST_CLASS_LOGGER_PROXY)
66    def test_for_test_class_works_on_subclases(self, proxy_cls):
67        class TestLogger(MetricLogger):
68            pass
69        args = (Mock(),)
70        kwargs = {'mock': Mock()}
71        logger = TestLogger.for_test_class(*args, **kwargs)
72
73        proxy_cls.assert_called_once_with(TestLogger, args, kwargs)
74
75    def test_init_empty(self):
76        logger = MetricLogger()
77
78        self.assertIsNone(logger.context)
79        self.assertIsNone(logger.publisher)
80
81    def test_init_with_context_and_publisher(self):
82        context = Mock()
83        publisher = Mock()
84
85        logger = MetricLogger(context=context, publisher=publisher)
86
87        self.assertEqual(logger.context, context)
88        self.assertEqual(logger.publisher, publisher)
89
90    @patch(PROTO_METRIC_PUBLISHER)
91    @patch(GET_CONTEXT_FOR_EVENT)
92    def test_init_with_event(self, get_context, publisher_cls):
93        context = Mock()
94        publisher = Mock()
95        get_context.return_value = context
96        publisher_cls.return_value = publisher
97        event = Mock()
98
99        logger = MetricLogger(event=event)
100
101        get_context.assert_called_once_with(event)
102        publisher_cls.assert_called_once_with(context)
103        self.assertEqual(logger.context, context)
104        self.assertEqual(logger.publisher, publisher)
105
106    def test_start_has_default_impl(self):
107        logger = MetricLogger()
108        logger.start(Mock())
109
110    def test_end_has_default_impl(self):
111        logger = MetricLogger()
112        logger.end(Mock())
113
114
115class LoggerProxyTest(TestCase):
116
117    @patch(CREATE_FROM_INSTANCE)
118    def test_init(self, create_from_instance):
119        logger_cls = Mock()
120        logger_args = Mock()
121        logger_kwargs = Mock()
122        bundle = Mock()
123        create_from_instance.return_value = bundle
124        proxy = LoggerProxy(logger_cls,
125                            logger_args,
126                            logger_kwargs)
127
128        self.assertEqual(proxy._logger_cls, logger_cls)
129        self.assertEqual(proxy._logger_args, logger_args)
130        self.assertEqual(proxy._logger_kwargs, logger_kwargs)
131        self.assertIsNone(proxy._logger)
132        create_from_instance.assert_called_once_with(proxy)
133        bundle.register.assert_called_once_with()
134
135    @patch(CREATE_FROM_INSTANCE)
136    def test_setup_proxy(self, create_from_instance):
137        logger_cls = Mock()
138        logger_args = (Mock(), )
139        logger_kwargs = {'mock': Mock()}
140        bundle = Mock()
141        event = Mock()
142        create_from_instance.return_value = bundle
143        logger = Mock()
144        logger_cls.return_value = logger
145
146        proxy = LoggerProxy(logger_cls,
147                            logger_args,
148                            logger_kwargs)
149        proxy._setup_proxy(event)
150
151        logger_cls.assert_called_once_with(event=event,
152                                           *logger_args,
153                                           **logger_kwargs)
154        logger.start.assert_called_once_with(event)
155
156    @patch(CREATE_FROM_INSTANCE)
157    def test_teardown_proxy(self, create_from_instance):
158        logger_cls = Mock()
159        logger_args = (Mock(),)
160        logger_kwargs = {'mock': Mock()}
161        bundle = Mock()
162        event = Mock()
163        create_from_instance.return_value = bundle
164        logger = Mock()
165        logger_cls.return_value = logger
166
167        proxy = LoggerProxy(logger_cls,
168                            logger_args,
169                            logger_kwargs)
170        proxy._setup_proxy(event)
171        proxy._teardown_proxy(event)
172
173        logger.end.assert_called_once_with(event)
174        self.assertIsNone(proxy._logger)
175
176    @patch(LOGGING_DEBUG)
177    @patch(LOGGING_ERROR)
178    @patch(CREATE_FROM_INSTANCE)
179    def test_teardown_proxy_logs_upon_exception(self, create_from_instance,
180                                                logging_error, logging_debug):
181        logger_cls = Mock()
182        logger_args = (Mock(),)
183        logger_kwargs = {'mock': Mock()}
184        bundle = Mock()
185        event = Mock()
186        create_from_instance.return_value = bundle
187        logger = Mock()
188        logger.end.side_effect = ValueError('test')
189        logger_cls.return_value = logger
190
191        proxy = LoggerProxy(logger_cls,
192                            logger_args,
193                            logger_kwargs)
194        proxy._setup_proxy(event)
195        proxy._teardown_proxy(event)
196
197        self.assertTrue(logging_error.called)
198        self.assertTrue(logging_debug.called)
199        self.assertIsNone(proxy._logger)
200
201    @patch(CREATE_FROM_INSTANCE)
202    def test_getattr_forwards_to_logger(self, create_from_instance):
203        logger_cls = Mock()
204        logger_args = (Mock(),)
205        logger_kwargs = {'mock': Mock()}
206        bundle = Mock()
207        event = Mock()
208        create_from_instance.return_value = bundle
209        logger = Mock()
210        logger_cls.return_value = logger
211
212        proxy = LoggerProxy(logger_cls,
213                            logger_args,
214                            logger_kwargs)
215        proxy._setup_proxy(event)
216
217        self.assertEqual(proxy.some_attr, logger.some_attr)
218
219    @patch(CREATE_FROM_INSTANCE)
220    def test_getattr_with_no_logger_raises(self, create_from_instance):
221        bundle = Mock()
222        create_from_instance.return_value = bundle
223
224        proxy = LoggerProxy(Mock(), Mock(), Mock())
225
226        self.assertRaises(ValueError, lambda: proxy.some_attr)
227
228    @patch(CREATE_FROM_INSTANCE)
229    def test_setattr_forwards_to_logger(self, create_from_instance):
230        logger_cls = Mock()
231        logger_args = (Mock(),)
232        logger_kwargs = {'mock': Mock()}
233        bundle = Mock()
234        event = Mock()
235        create_from_instance.return_value = bundle
236        logger = Mock()
237        logger_cls.return_value = logger
238        value = Mock()
239
240        proxy = LoggerProxy(logger_cls,
241                            logger_args,
242                            logger_kwargs)
243        proxy._setup_proxy(event)
244        proxy.some_attr = value
245
246        self.assertEqual(logger.some_attr, value)
247
248    @patch(CREATE_FROM_INSTANCE)
249    def test_setattr_with_no_logger_raises(self, create_from_instance):
250        bundle = Mock()
251        create_from_instance.return_value = bundle
252        value = Mock()
253
254        proxy = LoggerProxy(Mock(), Mock(), Mock())
255
256        def try_set():
257            proxy.some_attr = value
258        self.assertRaises(ValueError, try_set)
259
260
261if __name__ == '__main__':
262    unittest.main()
263