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