• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python2
2# Copyright 2018 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import logging
7import unittest
8
9import common
10
11from autotest_lib.client.common_lib import error
12from autotest_lib.client.cros.video import histogram_verifier
13import mock
14
15
16class HistogramVerifierTest(unittest.TestCase):
17    """
18    Tests histogram_verifier's module methods.
19    """
20
21    HISTOGRAM_TEXT_1 = '\n'.join([
22        'Histogram: Media.Engagement.ScoreAtPlayback recorded 29 samples, '
23        'mean = 44.8 (flags = 0x41)',
24        '0   ------------------------------------O                             '
25        '        (6 = 20.7%)',
26        '1   ...',
27        '5   ------O                                                           '
28        '       (1 = 3.4%) {20.7%}',
29        '6   ...',
30        '10  ------O                                                           '
31        '        (1 = 3.4%) {24.1%}',
32        '11  ...',
33        '15  ------------------O                                               '
34        '        (3 = 10.3%) {27.6%}',
35        '16  ------------------------------O                                   '
36        '        (5 = 17.2%) {37.9%}',
37        '17  ...',
38        '89  ------------------------------------------------------------------'
39        '------O (12 = 41.4%) {55.2%}',
40        '90  ------O                                                           '
41        '        (1 = 3.4%) {96.6%}',
42        '91  ... '])
43
44
45    def test_parse_histogram(self):
46        """
47        Tests parse_histogram().
48        """
49        self.assertDictEqual(
50            {0: 6, 5: 1, 10: 1, 15: 3, 16: 5, 89: 12, 90: 1},
51            histogram_verifier.parse_histogram(self.HISTOGRAM_TEXT_1))
52        self.assertDictEqual({}, histogram_verifier.parse_histogram(''))
53
54    def test_subtract_histogram(self):
55        """
56        Tests subtract_histogram().
57        """
58        self.assertDictEqual({}, histogram_verifier.subtract_histogram({}, {}))
59        self.assertDictEqual(
60            {0: 10},
61            histogram_verifier.subtract_histogram({0: 10}, {}))
62        self.assertDictEqual(
63            {0: -10},
64            histogram_verifier.subtract_histogram({}, {0: 10}))
65        self.assertDictEqual(
66            {0: 10},
67            histogram_verifier.subtract_histogram({0: 10}, {}))
68        self.assertDictEqual(
69            {0: 1},
70            histogram_verifier.subtract_histogram({0: 1, 15:4}, {0:0, 15:4}))
71
72
73class PollHistogramDifferBase(unittest.TestCase):
74    """
75    Base class to test methods that polls HistogramDiffer.
76
77    It mocks HistogramDiffer.end() to facilitate its callers' unittest.
78    It mocks utils.Timer so that it times out on the third
79    sleep() call.
80    """
81    def setUp(self):
82        self.histogram_name = 'mock_histogram'
83        self.bucket_name = 'mock_bucket'
84        self.differ = histogram_verifier.HistogramDiffer(
85            None, self.histogram_name, begin=False)
86        self.differ.end = mock.Mock()
87
88        self.time_patcher = mock.patch.object(histogram_verifier.utils.Timer,
89                                              'sleep')
90        # Timeout at the third call of sleep().
91        self.sleep_mock = self.time_patcher.start()
92        self.sleep_mock.side_effect = [True, True, False]
93
94    def tearDown(self):
95        self.time_patcher.stop()
96
97
98class ExpectSoleBucketTest(PollHistogramDifferBase):
99    """
100    Tests histogram_verifier.expect_sole_bucket().
101    """
102    def test_diff_sole_bucket(self):
103        """
104        Tests expect_sole_bucket() with sole bucket.
105        """
106        self.differ.end.side_effect = [{self.bucket_name:1}]
107        self.assertTrue(histogram_verifier.expect_sole_bucket(
108            self.differ, self.bucket_name, self.bucket_name))
109
110    def test_diff_second_time(self):
111        """
112        Tests expect_sole_bucket() with sole bucket on the second poll.
113        """
114        # First time return empty.
115        self.differ.end.side_effect = [{}, {self.bucket_name:1}]
116        self.assertTrue(histogram_verifier.expect_sole_bucket(
117            self.differ, self.bucket_name, self.bucket_name))
118
119    def test_diff_more_than_one_bucket(self):
120        """
121        Tests expect_sole_bucket() with more than one bucket.
122        """
123        self.differ.end.side_effect = [{self.bucket_name:1, 'unexpected':1}]
124        with self.assertRaisesRegexp(
125                error.TestError,
126                '%s has bucket other than %s' % (self.histogram_name,
127                                                 self.bucket_name)):
128            histogram_verifier.expect_sole_bucket(self.differ, self.bucket_name,
129                                                  self.bucket_name)
130
131    def test_diff_nothing(self):
132        """
133        Tests expect_sole_bucket() with no bucket.
134        """
135        self.differ.end.side_effect = [{}, {}]
136        with self.assertRaisesRegexp(
137                error.TestError,
138                'Expect %s has %s' % (self.histogram_name, self.bucket_name)):
139            histogram_verifier.expect_sole_bucket(self.differ, self.bucket_name,
140                                                  self.bucket_name)
141
142    def test_diff_too_late(self):
143        """
144        Tests expect_sole_bucket() with bucket arrives too late.
145        """
146        # differ polls histogram diff twice. But the bucket comes at the third
147        # polling call.
148        self.differ.end.side_effect = [{}, {}, {self.bucket_name: 1}]
149        with self.assertRaisesRegexp(
150                error.TestError,
151                'Expect %s has %s' % (self.histogram_name, self.bucket_name)):
152            histogram_verifier.expect_sole_bucket(self.differ, self.bucket_name,
153                                                  self.bucket_name)
154
155class PollHistogramGrowTest(PollHistogramDifferBase):
156    """
157    Tests histogram_verifier.poll_histogram_grow().
158    """
159    def test_diff_sole_bucket(self):
160        """
161        Tests poll_histogram_grow() with sole bucket.
162        """
163        self.differ.end.side_effect = [{self.bucket_name:1}]
164        is_grow, histogram = histogram_verifier.poll_histogram_grow(
165            self.differ, self.bucket_name, self.bucket_name)
166        self.assertTrue(is_grow)
167        self.assertDictEqual({self.bucket_name:1}, histogram)
168
169    def test_diff_nochange(self):
170        """
171        Tests expect_sole_bucket() with sole bucket on the second poll.
172        """
173        self.differ.end.side_effect = [{}, {}, {}]
174        is_grow, histogram = histogram_verifier.poll_histogram_grow(
175            self.differ, self.bucket_name, self.bucket_name)
176        self.assertFalse(is_grow)
177        self.assertDictEqual({}, histogram)
178
179
180class HistogramDifferTest(unittest.TestCase):
181    """
182    Tests histogram_verifier.HistogramDiffer class.
183    """
184
185    HISTOGRAM_BEGIN = '\n'.join([
186        'Histogram: Media.GpuVideoDecoderInitializeStatus recorded 3521 samples'
187        ', mean = 2.7 (flags = 0x41)',
188        '0   ------------------------------------------------------------------'
189        '------O (2895 = 82.2%)',
190        '1   ...',
191        '15  ----------------O                                                 '
192        '        (626 = 17.8%) {82.2%}',
193        '16  ... '])
194
195    HISTOGRAM_END = '\n'.join([
196        'Histogram: Media.GpuVideoDecoderInitializeStatus recorded 3522 samples'
197        ', mean = 2.7 (flags = 0x41)',
198        '0   ------------------------------------------------------------------'
199        '------O (2896 = 82.2%)',
200        '1   ...',
201        '15  ----------------O                                                 '
202        '        (626 = 17.8%) {82.2%}',
203        '16  ... '])
204
205    HISTOGRAM_NAME = 'Media.GpuVideoDecoderInitializeStatus'
206
207    def test_init(self):
208        """
209        Tests __init__().
210        """
211        differ = histogram_verifier.HistogramDiffer(None, self.HISTOGRAM_NAME,
212                                                    begin=False)
213        self.assertEqual(self.HISTOGRAM_NAME, differ.histogram_name)
214        self.assertDictEqual({}, differ.begin_histogram)
215        self.assertDictEqual({}, differ.end_histogram)
216
217    def test_begin_end(self):
218        """
219        Tests HistogramDiffer's begin() and end().
220
221        Mocks out HistogramDiffer.get_histogram() to simplify test.
222        """
223
224        differ = histogram_verifier.HistogramDiffer(None, self.HISTOGRAM_NAME,
225                                                    begin=False)
226        differ._get_histogram = mock.Mock(
227            side_effect = [
228                (histogram_verifier.parse_histogram(self.HISTOGRAM_BEGIN),
229                 self.HISTOGRAM_BEGIN),
230                (histogram_verifier.parse_histogram(self.HISTOGRAM_END),
231                 self.HISTOGRAM_END)])
232        differ.begin()
233        self.assertDictEqual({0: 1}, differ.end())
234
235    def test_histogram_unchange(self):
236        """
237        Tests HistogramDiffer with histogram unchanged.
238
239        Expects no difference.
240        """
241        differ = histogram_verifier.HistogramDiffer(None, self.HISTOGRAM_NAME,
242                                                    begin=False)
243        differ._get_histogram = mock.Mock(
244            side_effect = [
245                (histogram_verifier.parse_histogram(self.HISTOGRAM_BEGIN),
246                 self.HISTOGRAM_BEGIN),
247                (histogram_verifier.parse_histogram(self.HISTOGRAM_BEGIN),
248                 self.HISTOGRAM_BEGIN)])
249        differ.begin()
250        self.assertDictEqual({}, differ.end())
251
252
253if __name__ == '__main__':
254    logging.basicConfig(
255        level=logging.DEBUG,
256        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
257    unittest.main()
258