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