xref: /aosp_15_r20/external/autotest/client/common_lib/test_unittest.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Li#!/usr/bin/python3
2*9c5db199SXin Li#pylint: disable-msg=C0111
3*9c5db199SXin Li"""Unit Tests for autotest.client.common_lib.test"""
4*9c5db199SXin Li
5*9c5db199SXin Lifrom __future__ import absolute_import
6*9c5db199SXin Lifrom __future__ import division
7*9c5db199SXin Lifrom __future__ import print_function
8*9c5db199SXin Li
9*9c5db199SXin Li__author__ = '[email protected] (Gregory P. Smith)'
10*9c5db199SXin Li
11*9c5db199SXin Liimport json
12*9c5db199SXin Liimport tempfile
13*9c5db199SXin Liimport unittest
14*9c5db199SXin Liimport common
15*9c5db199SXin Liimport mock as pymock
16*9c5db199SXin Liimport os
17*9c5db199SXin Liimport shutil
18*9c5db199SXin Liimport six
19*9c5db199SXin Lifrom six.moves import range
20*9c5db199SXin Li
21*9c5db199SXin Lifrom autotest_lib.client.common_lib import test
22*9c5db199SXin Lifrom autotest_lib.client.common_lib.test_utils import mock
23*9c5db199SXin Li
24*9c5db199SXin Li
25*9c5db199SXin Liclass TestTestCase(unittest.TestCase):
26*9c5db199SXin Li    class _neutered_base_test(test.base_test):
27*9c5db199SXin Li        """A child class of base_test to avoid calling the constructor."""
28*9c5db199SXin Li        def __init__(self, *args, **kwargs):
29*9c5db199SXin Li            class MockJob(object):
30*9c5db199SXin Li                pass
31*9c5db199SXin Li            class MockProfilerManager(object):
32*9c5db199SXin Li                def active(self):
33*9c5db199SXin Li                    return False
34*9c5db199SXin Li                def present(self):
35*9c5db199SXin Li                    return True
36*9c5db199SXin Li            self.job = MockJob()
37*9c5db199SXin Li            self.job.default_profile_only = False
38*9c5db199SXin Li            self.job.profilers = MockProfilerManager()
39*9c5db199SXin Li            self.job.test_retry = 0
40*9c5db199SXin Li            self.job.fast = False
41*9c5db199SXin Li            self._new_keyval = False
42*9c5db199SXin Li            self.iteration = 0
43*9c5db199SXin Li            self.tagged_testname = 'neutered_base_test'
44*9c5db199SXin Li            self.before_iteration_hooks = []
45*9c5db199SXin Li            self.after_iteration_hooks = []
46*9c5db199SXin Li
47*9c5db199SXin Li            self.crash_reporter_dir = tempfile.mkdtemp()
48*9c5db199SXin Li            # Make a temp dir for the test-in-prog file to be created.
49*9c5db199SXin Li            self.test_in_prog_file = os.path.join(self.crash_reporter_dir,
50*9c5db199SXin Li                                                  "test-in-prog")
51*9c5db199SXin Li
52*9c5db199SXin Li    def setUp(self):
53*9c5db199SXin Li        self.god = mock.mock_god()
54*9c5db199SXin Li        self.test = self._neutered_base_test()
55*9c5db199SXin Li
56*9c5db199SXin Li
57*9c5db199SXin Li    def tearDown(self):
58*9c5db199SXin Li        self.god.unstub_all()
59*9c5db199SXin Li        shutil.rmtree(self.test.crash_reporter_dir)
60*9c5db199SXin Li
61*9c5db199SXin Li
62*9c5db199SXin Li
63*9c5db199SXin Liclass Test_base_test_execute(TestTestCase):
64*9c5db199SXin Li    # Test the various behaviors of the base_test.execute() method.
65*9c5db199SXin Li    def setUp(self):
66*9c5db199SXin Li        TestTestCase.setUp(self)
67*9c5db199SXin Li        self.god.stub_function(self.test, 'run_once_profiling')
68*9c5db199SXin Li        self.god.stub_function(self.test, 'postprocess')
69*9c5db199SXin Li        self.god.stub_function(self.test, 'process_failed_constraints')
70*9c5db199SXin Li
71*9c5db199SXin Li
72*9c5db199SXin Li    def test_call_run_once(self):
73*9c5db199SXin Li        # setup
74*9c5db199SXin Li        self.god.stub_function(self.test, 'drop_caches_between_iterations')
75*9c5db199SXin Li        self.god.stub_function(self.test, 'run_once')
76*9c5db199SXin Li        self.god.stub_function(self.test, 'postprocess_iteration')
77*9c5db199SXin Li        self.god.stub_function(self.test, 'analyze_perf_constraints')
78*9c5db199SXin Li        before_hook = self.god.create_mock_function('before_hook')
79*9c5db199SXin Li        after_hook = self.god.create_mock_function('after_hook')
80*9c5db199SXin Li        self.test.register_before_iteration_hook(before_hook)
81*9c5db199SXin Li        self.test.register_after_iteration_hook(after_hook)
82*9c5db199SXin Li
83*9c5db199SXin Li        # tests the test._call_run_once implementation
84*9c5db199SXin Li        self.test.drop_caches_between_iterations.expect_call()
85*9c5db199SXin Li        before_hook.expect_call(self.test)
86*9c5db199SXin Li        self.test.run_once.expect_call(1, 2, arg='val')
87*9c5db199SXin Li        self.test.postprocess_iteration.expect_call()
88*9c5db199SXin Li        self.test.analyze_perf_constraints.expect_call([])
89*9c5db199SXin Li        after_hook.expect_call(self.test)
90*9c5db199SXin Li        self.test._call_run_once([], False, None, (1, 2), {'arg': 'val'})
91*9c5db199SXin Li        self.god.check_playback()
92*9c5db199SXin Li
93*9c5db199SXin Li
94*9c5db199SXin Li    def test_call_run_once_with_exception(self):
95*9c5db199SXin Li        # setup
96*9c5db199SXin Li        self.god.stub_function(self.test, 'drop_caches_between_iterations')
97*9c5db199SXin Li        self.god.stub_function(self.test, 'run_once')
98*9c5db199SXin Li        before_hook = self.god.create_mock_function('before_hook')
99*9c5db199SXin Li        after_hook = self.god.create_mock_function('after_hook')
100*9c5db199SXin Li        self.test.register_before_iteration_hook(before_hook)
101*9c5db199SXin Li        self.test.register_after_iteration_hook(after_hook)
102*9c5db199SXin Li        error = Exception('fail')
103*9c5db199SXin Li
104*9c5db199SXin Li        # tests the test._call_run_once implementation
105*9c5db199SXin Li        self.test.drop_caches_between_iterations.expect_call()
106*9c5db199SXin Li        before_hook.expect_call(self.test)
107*9c5db199SXin Li        self.test.run_once.expect_call(1, 2, arg='val').and_raises(error)
108*9c5db199SXin Li        after_hook.expect_call(self.test)
109*9c5db199SXin Li        try:
110*9c5db199SXin Li            self.test._call_run_once([], False, None, (1, 2), {'arg': 'val'})
111*9c5db199SXin Li        except:
112*9c5db199SXin Li            pass
113*9c5db199SXin Li        self.god.check_playback()
114*9c5db199SXin Li
115*9c5db199SXin Li
116*9c5db199SXin Li    def _expect_call_run_once(self):
117*9c5db199SXin Li        self.test._call_run_once.expect_call((), False, None, (), {})
118*9c5db199SXin Li
119*9c5db199SXin Li
120*9c5db199SXin Li    def test_execute_test_length(self):
121*9c5db199SXin Li        # test that test_length overrides iterations and works.
122*9c5db199SXin Li        self.god.stub_function(self.test, '_call_run_once')
123*9c5db199SXin Li
124*9c5db199SXin Li        self._expect_call_run_once()
125*9c5db199SXin Li        self._expect_call_run_once()
126*9c5db199SXin Li        self._expect_call_run_once()
127*9c5db199SXin Li        self.test.run_once_profiling.expect_call(None)
128*9c5db199SXin Li        self.test.postprocess.expect_call()
129*9c5db199SXin Li        self.test.process_failed_constraints.expect_call()
130*9c5db199SXin Li
131*9c5db199SXin Li        if six.PY2:
132*9c5db199SXin Li            fake_time = iter(range(4)).next
133*9c5db199SXin Li        else:
134*9c5db199SXin Li            fake_time = iter(range(4)).__next__
135*9c5db199SXin Li        self.test.execute(iterations=1, test_length=3, _get_time=fake_time)
136*9c5db199SXin Li        self.god.check_playback()
137*9c5db199SXin Li
138*9c5db199SXin Li
139*9c5db199SXin Li    def test_execute_iterations(self):
140*9c5db199SXin Li        # test that iterations works.
141*9c5db199SXin Li        self.god.stub_function(self.test, '_call_run_once')
142*9c5db199SXin Li
143*9c5db199SXin Li        iterations = 2
144*9c5db199SXin Li        for _ in range(iterations):
145*9c5db199SXin Li            self._expect_call_run_once()
146*9c5db199SXin Li        self.test.run_once_profiling.expect_call(None)
147*9c5db199SXin Li        self.test.postprocess.expect_call()
148*9c5db199SXin Li        self.test.process_failed_constraints.expect_call()
149*9c5db199SXin Li
150*9c5db199SXin Li        self.test.execute(iterations=iterations)
151*9c5db199SXin Li        self.god.check_playback()
152*9c5db199SXin Li
153*9c5db199SXin Li
154*9c5db199SXin Li    def _mock_calls_for_execute_no_iterations(self):
155*9c5db199SXin Li        self.test.run_once_profiling.expect_call(None)
156*9c5db199SXin Li        self.test.postprocess.expect_call()
157*9c5db199SXin Li        self.test.process_failed_constraints.expect_call()
158*9c5db199SXin Li
159*9c5db199SXin Li
160*9c5db199SXin Li    def test_execute_iteration_zero(self):
161*9c5db199SXin Li        # test that iterations=0 works.
162*9c5db199SXin Li        self._mock_calls_for_execute_no_iterations()
163*9c5db199SXin Li
164*9c5db199SXin Li        self.test.execute(iterations=0)
165*9c5db199SXin Li        self.god.check_playback()
166*9c5db199SXin Li
167*9c5db199SXin Li
168*9c5db199SXin Li    def test_execute_profile_only(self):
169*9c5db199SXin Li        # test that profile_only=True works.
170*9c5db199SXin Li        self.god.stub_function(self.test, 'drop_caches_between_iterations')
171*9c5db199SXin Li        self.test.drop_caches_between_iterations.expect_call()
172*9c5db199SXin Li        self.test.run_once_profiling.expect_call(None)
173*9c5db199SXin Li        self.test.drop_caches_between_iterations.expect_call()
174*9c5db199SXin Li        self.test.run_once_profiling.expect_call(None)
175*9c5db199SXin Li        self.test.postprocess.expect_call()
176*9c5db199SXin Li        self.test.process_failed_constraints.expect_call()
177*9c5db199SXin Li        self.test.execute(profile_only=True, iterations=2)
178*9c5db199SXin Li        self.god.check_playback()
179*9c5db199SXin Li
180*9c5db199SXin Li
181*9c5db199SXin Li    def test_execute_default_profile_only(self):
182*9c5db199SXin Li        # test that profile_only=True works.
183*9c5db199SXin Li        self.god.stub_function(self.test, 'drop_caches_between_iterations')
184*9c5db199SXin Li        for _ in range(3):
185*9c5db199SXin Li            self.test.drop_caches_between_iterations.expect_call()
186*9c5db199SXin Li            self.test.run_once_profiling.expect_call(None)
187*9c5db199SXin Li        self.test.postprocess.expect_call()
188*9c5db199SXin Li        self.test.process_failed_constraints.expect_call()
189*9c5db199SXin Li        self.test.job.default_profile_only = True
190*9c5db199SXin Li        self.test.execute(iterations=3)
191*9c5db199SXin Li        self.god.check_playback()
192*9c5db199SXin Li
193*9c5db199SXin Li
194*9c5db199SXin Li    def test_execute_postprocess_profiled_false(self):
195*9c5db199SXin Li        # test that postprocess_profiled_run=False works
196*9c5db199SXin Li        self.god.stub_function(self.test, '_call_run_once')
197*9c5db199SXin Li
198*9c5db199SXin Li        self.test._call_run_once.expect_call((), False, False, (), {})
199*9c5db199SXin Li        self.test.run_once_profiling.expect_call(False)
200*9c5db199SXin Li        self.test.postprocess.expect_call()
201*9c5db199SXin Li        self.test.process_failed_constraints.expect_call()
202*9c5db199SXin Li
203*9c5db199SXin Li        self.test.execute(postprocess_profiled_run=False, iterations=1)
204*9c5db199SXin Li        self.god.check_playback()
205*9c5db199SXin Li
206*9c5db199SXin Li
207*9c5db199SXin Li    def test_execute_postprocess_profiled_true(self):
208*9c5db199SXin Li        # test that postprocess_profiled_run=True works
209*9c5db199SXin Li        self.god.stub_function(self.test, '_call_run_once')
210*9c5db199SXin Li
211*9c5db199SXin Li        self.test._call_run_once.expect_call((), False, True, (), {})
212*9c5db199SXin Li        self.test.run_once_profiling.expect_call(True)
213*9c5db199SXin Li        self.test.postprocess.expect_call()
214*9c5db199SXin Li        self.test.process_failed_constraints.expect_call()
215*9c5db199SXin Li
216*9c5db199SXin Li        self.test.execute(postprocess_profiled_run=True, iterations=1)
217*9c5db199SXin Li        self.god.check_playback()
218*9c5db199SXin Li
219*9c5db199SXin Li
220*9c5db199SXin Li    def test_output_single_perf_value(self):
221*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
222*9c5db199SXin Li
223*9c5db199SXin Li        self.test.output_perf_value("Test", 1, units="ms", higher_is_better=True)
224*9c5db199SXin Li
225*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
226*9c5db199SXin Li        expected_result = {"Test": {"summary": {"units": "ms", "type": "scalar",
227*9c5db199SXin Li                           "value": 1, "improvement_direction": "up"}}}
228*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
229*9c5db199SXin Li
230*9c5db199SXin Li    def test_output_perf_value_with_custom_resultsdir(self):
231*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
232*9c5db199SXin Li
233*9c5db199SXin Li        resultsdir = self.test.resultsdir + "/tests/tmp"
234*9c5db199SXin Li        self.test.output_perf_value("Test", 1, units="ms",higher_is_better=True,
235*9c5db199SXin Li                                    resultsdir=resultsdir)
236*9c5db199SXin Li
237*9c5db199SXin Li        f = open(self.test.resultsdir + "/tests/tmp/results-chart.json")
238*9c5db199SXin Li        expected_result = {"Test": {"summary": {"units": "ms", "type": "scalar",
239*9c5db199SXin Li                           "value": 1, "improvement_direction": "up"}}}
240*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
241*9c5db199SXin Li
242*9c5db199SXin Li
243*9c5db199SXin Li    def test_output_single_perf_value_twice(self):
244*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
245*9c5db199SXin Li
246*9c5db199SXin Li        self.test.output_perf_value("Test", 1, units="ms", higher_is_better=True)
247*9c5db199SXin Li        self.test.output_perf_value("Test", 2, units="ms", higher_is_better=True)
248*9c5db199SXin Li
249*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
250*9c5db199SXin Li        expected_result = {"Test": {"summary": {"units": "ms",
251*9c5db199SXin Li                           "type": "list_of_scalar_values", "values": [1, 2],
252*9c5db199SXin Li                           "improvement_direction": "up"}}}
253*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
254*9c5db199SXin Li
255*9c5db199SXin Li
256*9c5db199SXin Li    def test_output_single_perf_value_three_times(self):
257*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
258*9c5db199SXin Li
259*9c5db199SXin Li        self.test.output_perf_value("Test", 1, units="ms",
260*9c5db199SXin Li                                    higher_is_better=True)
261*9c5db199SXin Li        self.test.output_perf_value("Test", 2, units="ms", higher_is_better=True)
262*9c5db199SXin Li        self.test.output_perf_value("Test", 3, units="ms", higher_is_better=True)
263*9c5db199SXin Li
264*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
265*9c5db199SXin Li        expected_result = {"Test": {"summary": {"units": "ms",
266*9c5db199SXin Li                           "type": "list_of_scalar_values", "values": [1, 2, 3],
267*9c5db199SXin Li                           "improvement_direction": "up"}}}
268*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
269*9c5db199SXin Li
270*9c5db199SXin Li
271*9c5db199SXin Li    def test_output_list_perf_value(self):
272*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
273*9c5db199SXin Li
274*9c5db199SXin Li        self.test.output_perf_value("Test", [1, 2, 3], units="ms",
275*9c5db199SXin Li                                    higher_is_better=False)
276*9c5db199SXin Li
277*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
278*9c5db199SXin Li        expected_result = {"Test": {"summary": {"units": "ms",
279*9c5db199SXin Li                           "type": "list_of_scalar_values", "values": [1, 2, 3],
280*9c5db199SXin Li                           "improvement_direction": "down"}}}
281*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
282*9c5db199SXin Li
283*9c5db199SXin Li
284*9c5db199SXin Li    def test_output_single_then_list_perf_value(self):
285*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
286*9c5db199SXin Li        self.test.output_perf_value("Test", 1, units="ms",
287*9c5db199SXin Li                                    higher_is_better=False)
288*9c5db199SXin Li        self.test.output_perf_value("Test", [4, 3, 2], units="ms",
289*9c5db199SXin Li                                    higher_is_better=False)
290*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
291*9c5db199SXin Li        expected_result = {"Test": {"summary": {"units": "ms",
292*9c5db199SXin Li                           "type": "list_of_scalar_values",
293*9c5db199SXin Li                           "values": [1, 4, 3, 2],
294*9c5db199SXin Li                           "improvement_direction": "down"}}}
295*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
296*9c5db199SXin Li
297*9c5db199SXin Li
298*9c5db199SXin Li    def test_output_list_then_list_perf_value(self):
299*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
300*9c5db199SXin Li        self.test.output_perf_value("Test", [1, 2, 3], units="ms",
301*9c5db199SXin Li                                    higher_is_better=False)
302*9c5db199SXin Li        self.test.output_perf_value("Test", [4, 3, 2], units="ms",
303*9c5db199SXin Li                                    higher_is_better=False)
304*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
305*9c5db199SXin Li        expected_result = {"Test": {"summary": {"units": "ms",
306*9c5db199SXin Li                           "type": "list_of_scalar_values",
307*9c5db199SXin Li                           "values": [1, 2, 3, 4, 3, 2],
308*9c5db199SXin Li                           "improvement_direction": "down"}}}
309*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
310*9c5db199SXin Li
311*9c5db199SXin Li
312*9c5db199SXin Li    def test_output_single_perf_value_input_string(self):
313*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
314*9c5db199SXin Li
315*9c5db199SXin Li        self.test.output_perf_value("Test", u'-0.34', units="ms",
316*9c5db199SXin Li                                    higher_is_better=True)
317*9c5db199SXin Li
318*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
319*9c5db199SXin Li        expected_result = {"Test": {"summary": {"units": "ms", "type": "scalar",
320*9c5db199SXin Li                           "value": -0.34, "improvement_direction": "up"}}}
321*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
322*9c5db199SXin Li
323*9c5db199SXin Li
324*9c5db199SXin Li    def test_output_single_perf_value_input_list_of_string(self):
325*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
326*9c5db199SXin Li
327*9c5db199SXin Li        self.test.output_perf_value("Test", [0, u'-0.34', 1], units="ms",
328*9c5db199SXin Li                                    higher_is_better=True)
329*9c5db199SXin Li
330*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
331*9c5db199SXin Li        expected_result = {"Test": {"summary": {"units": "ms",
332*9c5db199SXin Li                           "type": "list_of_scalar_values",
333*9c5db199SXin Li                           "values": [0, -0.34, 1],
334*9c5db199SXin Li                           "improvement_direction": "up"}}}
335*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
336*9c5db199SXin Li
337*9c5db199SXin Li    def test_output_list_then_replace_list_perf_value(self):
338*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
339*9c5db199SXin Li        self.test.output_perf_value("Test", [1, 2, 3], units="ms",
340*9c5db199SXin Li                                    higher_is_better=False)
341*9c5db199SXin Li        self.test.output_perf_value("Test", [4, 5, 6], units="ms",
342*9c5db199SXin Li                                    higher_is_better=False,
343*9c5db199SXin Li                                    replace_existing_values=True)
344*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
345*9c5db199SXin Li        expected_result = {"Test": {"summary": {"units": "ms",
346*9c5db199SXin Li                           "type": "list_of_scalar_values",
347*9c5db199SXin Li                           "values": [4, 5, 6],
348*9c5db199SXin Li                           "improvement_direction": "down"}}}
349*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
350*9c5db199SXin Li
351*9c5db199SXin Li    def test_output_single_then_replace_list_perf_value(self):
352*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
353*9c5db199SXin Li        self.test.output_perf_value("Test", 3, units="ms",
354*9c5db199SXin Li                                    higher_is_better=False)
355*9c5db199SXin Li        self.test.output_perf_value("Test", [4, 5, 6], units="ms",
356*9c5db199SXin Li                                    higher_is_better=False,
357*9c5db199SXin Li                                    replace_existing_values=True)
358*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
359*9c5db199SXin Li        expected_result = {"Test": {"summary": {"units": "ms",
360*9c5db199SXin Li                           "type": "list_of_scalar_values",
361*9c5db199SXin Li                           "values": [4, 5, 6],
362*9c5db199SXin Li                           "improvement_direction": "down"}}}
363*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
364*9c5db199SXin Li
365*9c5db199SXin Li    def test_output_list_then_replace_single_perf_value(self):
366*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
367*9c5db199SXin Li        self.test.output_perf_value("Test", [1,2,3], units="ms",
368*9c5db199SXin Li                                    higher_is_better=False)
369*9c5db199SXin Li        self.test.output_perf_value("Test", 4, units="ms",
370*9c5db199SXin Li                                    higher_is_better=False,
371*9c5db199SXin Li                                    replace_existing_values=True)
372*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
373*9c5db199SXin Li        expected_result = {"Test": {"summary": {"units": "ms",
374*9c5db199SXin Li                           "type": "scalar",
375*9c5db199SXin Li                           "value": 4,
376*9c5db199SXin Li                           "improvement_direction": "down"}}}
377*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
378*9c5db199SXin Li
379*9c5db199SXin Li    def test_output_single_then_replace_single_perf_value(self):
380*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
381*9c5db199SXin Li        self.test.output_perf_value("Test", 1, units="ms",
382*9c5db199SXin Li                                    higher_is_better=False)
383*9c5db199SXin Li        self.test.output_perf_value("Test", 2, units="ms",
384*9c5db199SXin Li                                    higher_is_better=False,
385*9c5db199SXin Li                                    replace_existing_values=True)
386*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
387*9c5db199SXin Li        expected_result = {"Test": {"summary": {"units": "ms",
388*9c5db199SXin Li                           "type": "scalar",
389*9c5db199SXin Li                           "value": 2,
390*9c5db199SXin Li                           "improvement_direction": "down"}}}
391*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
392*9c5db199SXin Li
393*9c5db199SXin Li    def test_output_perf_then_replace_certain_perf_value(self):
394*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
395*9c5db199SXin Li        self.test.output_perf_value("Test1", 1, units="ms",
396*9c5db199SXin Li                                    higher_is_better=False)
397*9c5db199SXin Li        self.test.output_perf_value("Test2", 2, units="ms",
398*9c5db199SXin Li                                    higher_is_better=False)
399*9c5db199SXin Li        self.test.output_perf_value("Test3", 3, units="ms",
400*9c5db199SXin Li                                    higher_is_better=False)
401*9c5db199SXin Li        self.test.output_perf_value("Test2", -1, units="ms",
402*9c5db199SXin Li                                    higher_is_better=False,
403*9c5db199SXin Li                                    replace_existing_values=True)
404*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
405*9c5db199SXin Li        expected_result = {"Test1": {"summary":
406*9c5db199SXin Li                                       {"units": "ms",
407*9c5db199SXin Li                                        "type": "scalar",
408*9c5db199SXin Li                                        "value": 1,
409*9c5db199SXin Li                                        "improvement_direction": "down"}},
410*9c5db199SXin Li                           "Test2": {"summary":
411*9c5db199SXin Li                                       {"units": "ms",
412*9c5db199SXin Li                                        "type": "scalar",
413*9c5db199SXin Li                                        "value": -1,
414*9c5db199SXin Li                                        "improvement_direction": "down"}},
415*9c5db199SXin Li                           "Test3": {"summary":
416*9c5db199SXin Li                                       {"units": "ms",
417*9c5db199SXin Li                                        "type": "scalar",
418*9c5db199SXin Li                                        "value": 3,
419*9c5db199SXin Li                                        "improvement_direction": "down"}}}
420*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
421*9c5db199SXin Li
422*9c5db199SXin Li    def test_chart_supplied(self):
423*9c5db199SXin Li        self.test.resultsdir = tempfile.mkdtemp()
424*9c5db199SXin Li
425*9c5db199SXin Li        test_data = [("tcp_tx", "ch006_mode11B_none", "BT_connected_but_not_streaming", 0),
426*9c5db199SXin Li                     ("tcp_tx", "ch006_mode11B_none", "BT_streaming_audiofile", 5),
427*9c5db199SXin Li                     ("tcp_tx", "ch006_mode11B_none", "BT_disconnected_again", 0),
428*9c5db199SXin Li                     ("tcp_rx", "ch006_mode11B_none", "BT_connected_but_not_streaming", 0),
429*9c5db199SXin Li                     ("tcp_rx", "ch006_mode11B_none", "BT_streaming_audiofile", 8),
430*9c5db199SXin Li                     ("tcp_rx", "ch006_mode11B_none", "BT_disconnected_again", 0),
431*9c5db199SXin Li                     ("udp_tx", "ch006_mode11B_none", "BT_connected_but_not_streaming", 0),
432*9c5db199SXin Li                     ("udp_tx", "ch006_mode11B_none", "BT_streaming_audiofile", 6),
433*9c5db199SXin Li                     ("udp_tx", "ch006_mode11B_none", "BT_disconnected_again", 0),
434*9c5db199SXin Li                     ("udp_rx", "ch006_mode11B_none", "BT_connected_but_not_streaming", 0),
435*9c5db199SXin Li                     ("udp_rx", "ch006_mode11B_none", "BT_streaming_audiofile", 8),
436*9c5db199SXin Li                     ("udp_rx", "ch006_mode11B_none", "BT_streaming_audiofile", 9),
437*9c5db199SXin Li                     ("udp_rx", "ch006_mode11B_none", "BT_disconnected_again", 0)]
438*9c5db199SXin Li
439*9c5db199SXin Li
440*9c5db199SXin Li        for (config_tag, ap_config_tag, bt_tag, drop) in test_data:
441*9c5db199SXin Li            self.test.output_perf_value(config_tag + '_' + bt_tag + '_drop',
442*9c5db199SXin Li                                        drop,
443*9c5db199SXin Li                                        units='percent_drop',
444*9c5db199SXin Li                                        higher_is_better=False,
445*9c5db199SXin Li                                        graph=ap_config_tag + '_drop')
446*9c5db199SXin Li        f = open(self.test.resultsdir + "/results-chart.json")
447*9c5db199SXin Li        expected_result = {
448*9c5db199SXin Li          "ch006_mode11B_none_drop": {
449*9c5db199SXin Li            "udp_tx_BT_streaming_audiofile_drop": {
450*9c5db199SXin Li              "units": "percent_drop",
451*9c5db199SXin Li              "type": "scalar",
452*9c5db199SXin Li              "value": 6.0,
453*9c5db199SXin Li              "improvement_direction": "down"
454*9c5db199SXin Li            },
455*9c5db199SXin Li            "udp_rx_BT_disconnected_again_drop": {
456*9c5db199SXin Li              "units": "percent_drop",
457*9c5db199SXin Li              "type": "scalar",
458*9c5db199SXin Li              "value": 0.0,
459*9c5db199SXin Li              "improvement_direction": "down"
460*9c5db199SXin Li            },
461*9c5db199SXin Li            "tcp_tx_BT_disconnected_again_drop": {
462*9c5db199SXin Li              "units": "percent_drop",
463*9c5db199SXin Li              "type": "scalar",
464*9c5db199SXin Li              "value": 0.0,
465*9c5db199SXin Li              "improvement_direction": "down"
466*9c5db199SXin Li            },
467*9c5db199SXin Li            "tcp_rx_BT_streaming_audiofile_drop": {
468*9c5db199SXin Li              "units": "percent_drop",
469*9c5db199SXin Li              "type": "scalar",
470*9c5db199SXin Li              "value": 8.0,
471*9c5db199SXin Li              "improvement_direction": "down"
472*9c5db199SXin Li            },
473*9c5db199SXin Li            "udp_tx_BT_connected_but_not_streaming_drop": {
474*9c5db199SXin Li              "units": "percent_drop",
475*9c5db199SXin Li              "type": "scalar",
476*9c5db199SXin Li              "value": 0.0,
477*9c5db199SXin Li              "improvement_direction": "down"
478*9c5db199SXin Li            },
479*9c5db199SXin Li            "tcp_tx_BT_connected_but_not_streaming_drop": {
480*9c5db199SXin Li              "units": "percent_drop",
481*9c5db199SXin Li              "type": "scalar",
482*9c5db199SXin Li              "value": 0.0,
483*9c5db199SXin Li              "improvement_direction": "down"
484*9c5db199SXin Li            },
485*9c5db199SXin Li            "udp_tx_BT_disconnected_again_drop": {
486*9c5db199SXin Li              "units": "percent_drop",
487*9c5db199SXin Li              "type": "scalar",
488*9c5db199SXin Li              "value": 0.0,
489*9c5db199SXin Li              "improvement_direction": "down"
490*9c5db199SXin Li            },
491*9c5db199SXin Li            "tcp_tx_BT_streaming_audiofile_drop": {
492*9c5db199SXin Li              "units": "percent_drop",
493*9c5db199SXin Li              "type": "scalar",
494*9c5db199SXin Li              "value": 5.0,
495*9c5db199SXin Li              "improvement_direction": "down"
496*9c5db199SXin Li            },
497*9c5db199SXin Li            "tcp_rx_BT_connected_but_not_streaming_drop": {
498*9c5db199SXin Li              "units": "percent_drop",
499*9c5db199SXin Li              "type": "scalar",
500*9c5db199SXin Li              "value": 0.0,
501*9c5db199SXin Li              "improvement_direction": "down"
502*9c5db199SXin Li            },
503*9c5db199SXin Li            "udp_rx_BT_connected_but_not_streaming_drop": {
504*9c5db199SXin Li              "units": "percent_drop",
505*9c5db199SXin Li              "type": "scalar",
506*9c5db199SXin Li              "value": 0.0,
507*9c5db199SXin Li              "improvement_direction": "down"
508*9c5db199SXin Li            },
509*9c5db199SXin Li            "udp_rx_BT_streaming_audiofile_drop": {
510*9c5db199SXin Li              "units": "percent_drop",
511*9c5db199SXin Li              "type": "list_of_scalar_values",
512*9c5db199SXin Li              "values": [
513*9c5db199SXin Li                8.0,
514*9c5db199SXin Li                9.0
515*9c5db199SXin Li              ],
516*9c5db199SXin Li              "improvement_direction": "down"
517*9c5db199SXin Li            },
518*9c5db199SXin Li            "tcp_rx_BT_disconnected_again_drop": {
519*9c5db199SXin Li              "units": "percent_drop",
520*9c5db199SXin Li              "type": "scalar",
521*9c5db199SXin Li              "value": 0.0,
522*9c5db199SXin Li              "improvement_direction": "down"
523*9c5db199SXin Li            }
524*9c5db199SXin Li          }
525*9c5db199SXin Li        }
526*9c5db199SXin Li        self.maxDiff = None
527*9c5db199SXin Li        self.assertDictEqual(expected_result, json.loads(f.read()))
528*9c5db199SXin Li
529*9c5db199SXin Liclass Test_runtest(unittest.TestCase):
530*9c5db199SXin Li    _TEST_CONTENTS = """
531*9c5db199SXin Lifrom autotest_lib.client.common_lib import test
532*9c5db199SXin Li
533*9c5db199SXin Liclass mocktest(test.base_test):
534*9c5db199SXin Li    version = 1
535*9c5db199SXin Li    def initialize(self, host, arg1=None):
536*9c5db199SXin Li        self.job.initialize_mock(host, arg1)
537*9c5db199SXin Li
538*9c5db199SXin Li    def warmup(self, host):
539*9c5db199SXin Li        self.job.warmup_mock(host)
540*9c5db199SXin Li
541*9c5db199SXin Li    def run_once(self, arg2):
542*9c5db199SXin Li        self.job.run_once_mock(arg2)
543*9c5db199SXin Li
544*9c5db199SXin Li    def cleanup(self, **kwargs):
545*9c5db199SXin Li        self.job.cleanup_mock(**kwargs)
546*9c5db199SXin Li    """
547*9c5db199SXin Li    def setUp(self):
548*9c5db199SXin Li        self.workdir = tempfile.mkdtemp()
549*9c5db199SXin Li        self.testname = 'mocktest'
550*9c5db199SXin Li        testdir = os.path.join(self.workdir, 'tests')
551*9c5db199SXin Li        resultdir = os.path.join(self.workdir, 'results')
552*9c5db199SXin Li        tmpdir = os.path.join(self.workdir, 'tmp')
553*9c5db199SXin Li
554*9c5db199SXin Li        self.test_in_prog_file = os.path.join(tmpdir, "test-in-prog")
555*9c5db199SXin Li
556*9c5db199SXin Li        os.makedirs(os.path.join(testdir, self.testname))
557*9c5db199SXin Li        os.makedirs(os.path.join(resultdir, self.testname))
558*9c5db199SXin Li        os.makedirs(tmpdir)
559*9c5db199SXin Li
560*9c5db199SXin Li        self.job = pymock.MagicMock(testdir=testdir, resultdir=resultdir,
561*9c5db199SXin Li                                    tmpdir=tmpdir, site_testdir=None)
562*9c5db199SXin Li
563*9c5db199SXin Li        with open(os.path.join(self.job.testdir, self.testname,
564*9c5db199SXin Li                  '{}.py'.format(self.testname)), 'w') as f:
565*9c5db199SXin Li            f.write(self._TEST_CONTENTS)
566*9c5db199SXin Li
567*9c5db199SXin Li    def tearDown(self):
568*9c5db199SXin Li        shutil.rmtree(self.workdir)
569*9c5db199SXin Li
570*9c5db199SXin Li    def test_runtest(self):
571*9c5db199SXin Li        all_args = {'host': 'hostvalue', 'arg1': 'value1', 'arg2': 'value2'}
572*9c5db199SXin Li        test.runtest(self.job,
573*9c5db199SXin Li                     self.testname,
574*9c5db199SXin Li                     '', (),
575*9c5db199SXin Li                     all_args,
576*9c5db199SXin Li                     override_test_in_prog_file=self.test_in_prog_file)
577*9c5db199SXin Li        self.job.initialize_mock.assert_called_with('hostvalue', 'value1')
578*9c5db199SXin Li        self.job.warmup_mock.assert_called_with('hostvalue')
579*9c5db199SXin Li        self.job.run_once_mock.assert_called_with('value2')
580*9c5db199SXin Li        self.job.cleanup_mock.assert_called_with(**all_args)
581*9c5db199SXin Li
582*9c5db199SXin Liif __name__ == '__main__':
583*9c5db199SXin Li    unittest.main()
584