1*760c253cSXin Li#!/usr/bin/env python3 2*760c253cSXin Li# -*- coding: utf-8 -*- 3*760c253cSXin Li 4*760c253cSXin Li# Copyright 2011 The ChromiumOS Authors 5*760c253cSXin Li# Use of this source code is governed by a BSD-style license that can be 6*760c253cSXin Li# found in the LICENSE file. 7*760c253cSXin Li 8*760c253cSXin Li"""The unittest of experiment_file.""" 9*760c253cSXin Li 10*760c253cSXin Liimport io 11*760c253cSXin Liimport unittest 12*760c253cSXin Li 13*760c253cSXin Lifrom experiment_file import ExperimentFile 14*760c253cSXin Li 15*760c253cSXin Li 16*760c253cSXin LiEXPERIMENT_FILE_1 = """ 17*760c253cSXin Li board: x86-alex 18*760c253cSXin Li remote: chromeos-alex3 19*760c253cSXin Li perf_args: record -a -e cycles 20*760c253cSXin Li benchmark: PageCycler { 21*760c253cSXin Li iterations: 3 22*760c253cSXin Li } 23*760c253cSXin Li 24*760c253cSXin Li image1 { 25*760c253cSXin Li chromeos_image: /usr/local/google/cros_image1.bin 26*760c253cSXin Li } 27*760c253cSXin Li 28*760c253cSXin Li image2 { 29*760c253cSXin Li remote: chromeos-lumpy1 30*760c253cSXin Li chromeos_image: /usr/local/google/cros_image2.bin 31*760c253cSXin Li } 32*760c253cSXin Li """ 33*760c253cSXin Li 34*760c253cSXin LiEXPERIMENT_FILE_2 = """ 35*760c253cSXin Li board: x86-alex 36*760c253cSXin Li remote: chromeos-alex3 37*760c253cSXin Li iterations: 3 38*760c253cSXin Li 39*760c253cSXin Li benchmark: PageCycler { 40*760c253cSXin Li } 41*760c253cSXin Li 42*760c253cSXin Li benchmark: AndroidBench { 43*760c253cSXin Li iterations: 2 44*760c253cSXin Li } 45*760c253cSXin Li 46*760c253cSXin Li image1 { 47*760c253cSXin Li chromeos_image:/usr/local/google/cros_image1.bin 48*760c253cSXin Li } 49*760c253cSXin Li 50*760c253cSXin Li image2 { 51*760c253cSXin Li chromeos_image: /usr/local/google/cros_image2.bin 52*760c253cSXin Li } 53*760c253cSXin Li """ 54*760c253cSXin Li 55*760c253cSXin LiEXPERIMENT_FILE_3 = """ 56*760c253cSXin Li board: x86-alex 57*760c253cSXin Li remote: chromeos-alex3 58*760c253cSXin Li iterations: 3 59*760c253cSXin Li 60*760c253cSXin Li benchmark: PageCycler { 61*760c253cSXin Li } 62*760c253cSXin Li 63*760c253cSXin Li image1 { 64*760c253cSXin Li chromeos_image:/usr/local/google/cros_image1.bin 65*760c253cSXin Li } 66*760c253cSXin Li 67*760c253cSXin Li image1 { 68*760c253cSXin Li chromeos_image: /usr/local/google/cros_image2.bin 69*760c253cSXin Li } 70*760c253cSXin Li """ 71*760c253cSXin Li 72*760c253cSXin LiEXPERIMENT_FILE_4 = """ 73*760c253cSXin Li board: x86-alex 74*760c253cSXin Li remote: chromeos-alex3 75*760c253cSXin Li iterations: 3 76*760c253cSXin Li 77*760c253cSXin Li benchmark: webrtc { 78*760c253cSXin Li test_args: --story-filter=datachannel 79*760c253cSXin Li } 80*760c253cSXin Li 81*760c253cSXin Li benchmark: webrtc { 82*760c253cSXin Li test_args: --story-tag-filter=smoothness 83*760c253cSXin Li } 84*760c253cSXin Li 85*760c253cSXin Li image1 { 86*760c253cSXin Li chromeos_image:/usr/local/google/cros_image1.bin 87*760c253cSXin Li } 88*760c253cSXin Li """ 89*760c253cSXin Li 90*760c253cSXin LiDUT_CONFIG_EXPERIMENT_FILE_GOOD = """ 91*760c253cSXin Li board: kevin64 92*760c253cSXin Li remote: chromeos-kevin.cros 93*760c253cSXin Li turbostat: False 94*760c253cSXin Li intel_pstate: no_hwp 95*760c253cSXin Li cooldown_temp: 38 96*760c253cSXin Li cooldown_time: 5 97*760c253cSXin Li governor: powersave 98*760c253cSXin Li cpu_usage: exclusive_cores 99*760c253cSXin Li cpu_freq_pct: 50 100*760c253cSXin Li top_interval: 5 101*760c253cSXin Li 102*760c253cSXin Li benchmark: speedometer { 103*760c253cSXin Li iterations: 3 104*760c253cSXin Li suite: telemetry_Crosperf 105*760c253cSXin Li } 106*760c253cSXin Li 107*760c253cSXin Li image1 { 108*760c253cSXin Li chromeos_image:/usr/local/google/cros_image1.bin 109*760c253cSXin Li } 110*760c253cSXin Li """ 111*760c253cSXin Li 112*760c253cSXin LiDUT_CONFIG_EXPERIMENT_FILE_BAD_GOV = """ 113*760c253cSXin Li board: kevin64 114*760c253cSXin Li remote: chromeos-kevin.cros 115*760c253cSXin Li intel_pstate: active 116*760c253cSXin Li governor: misspelled_governor 117*760c253cSXin Li 118*760c253cSXin Li benchmark: speedometer2 { 119*760c253cSXin Li iterations: 3 120*760c253cSXin Li suite: telemetry_Crosperf 121*760c253cSXin Li } 122*760c253cSXin Li """ 123*760c253cSXin Li 124*760c253cSXin LiDUT_CONFIG_EXPERIMENT_FILE_BAD_CPUUSE = """ 125*760c253cSXin Li board: kevin64 126*760c253cSXin Li remote: chromeos-kevin.cros 127*760c253cSXin Li turbostat: False 128*760c253cSXin Li governor: ondemand 129*760c253cSXin Li cpu_usage: unknown 130*760c253cSXin Li 131*760c253cSXin Li benchmark: speedometer2 { 132*760c253cSXin Li iterations: 3 133*760c253cSXin Li suite: telemetry_Crosperf 134*760c253cSXin Li } 135*760c253cSXin Li 136*760c253cSXin Li image1 { 137*760c253cSXin Li chromeos_image:/usr/local/google/cros_image1.bin 138*760c253cSXin Li } 139*760c253cSXin Li """ 140*760c253cSXin Li 141*760c253cSXin LiOUTPUT_FILE = """board: x86-alex 142*760c253cSXin Liremote: chromeos-alex3 143*760c253cSXin Liperf_args: record -a -e cycles 144*760c253cSXin Li 145*760c253cSXin Libenchmark: PageCycler { 146*760c253cSXin Li\titerations: 3 147*760c253cSXin Li} 148*760c253cSXin Li 149*760c253cSXin Lilabel: image1 { 150*760c253cSXin Li\tchromeos_image: /usr/local/google/cros_image1.bin 151*760c253cSXin Li\tremote: chromeos-alex3 152*760c253cSXin Li} 153*760c253cSXin Li 154*760c253cSXin Lilabel: image2 { 155*760c253cSXin Li\tchromeos_image: /usr/local/google/cros_image2.bin 156*760c253cSXin Li\tremote: chromeos-lumpy1 157*760c253cSXin Li}\n\n""" 158*760c253cSXin Li 159*760c253cSXin Li 160*760c253cSXin Liclass ExperimentFileTest(unittest.TestCase): 161*760c253cSXin Li """The main class for Experiment File test.""" 162*760c253cSXin Li 163*760c253cSXin Li def testLoadExperimentFile1(self): 164*760c253cSXin Li input_file = io.StringIO(EXPERIMENT_FILE_1) 165*760c253cSXin Li experiment_file = ExperimentFile(input_file) 166*760c253cSXin Li global_settings = experiment_file.GetGlobalSettings() 167*760c253cSXin Li self.assertEqual(global_settings.GetField("remote"), ["chromeos-alex3"]) 168*760c253cSXin Li self.assertEqual( 169*760c253cSXin Li global_settings.GetField("perf_args"), "record -a -e cycles" 170*760c253cSXin Li ) 171*760c253cSXin Li benchmark_settings = experiment_file.GetSettings("benchmark") 172*760c253cSXin Li self.assertEqual(len(benchmark_settings), 1) 173*760c253cSXin Li self.assertEqual(benchmark_settings[0].name, "PageCycler") 174*760c253cSXin Li self.assertEqual(benchmark_settings[0].GetField("iterations"), 3) 175*760c253cSXin Li 176*760c253cSXin Li label_settings = experiment_file.GetSettings("label") 177*760c253cSXin Li self.assertEqual(len(label_settings), 2) 178*760c253cSXin Li self.assertEqual(label_settings[0].name, "image1") 179*760c253cSXin Li self.assertEqual( 180*760c253cSXin Li label_settings[0].GetField("chromeos_image"), 181*760c253cSXin Li "/usr/local/google/cros_image1.bin", 182*760c253cSXin Li ) 183*760c253cSXin Li self.assertEqual( 184*760c253cSXin Li label_settings[1].GetField("remote"), ["chromeos-lumpy1"] 185*760c253cSXin Li ) 186*760c253cSXin Li self.assertEqual( 187*760c253cSXin Li label_settings[0].GetField("remote"), ["chromeos-alex3"] 188*760c253cSXin Li ) 189*760c253cSXin Li 190*760c253cSXin Li def testOverrideSetting(self): 191*760c253cSXin Li input_file = io.StringIO(EXPERIMENT_FILE_2) 192*760c253cSXin Li experiment_file = ExperimentFile(input_file) 193*760c253cSXin Li global_settings = experiment_file.GetGlobalSettings() 194*760c253cSXin Li self.assertEqual(global_settings.GetField("remote"), ["chromeos-alex3"]) 195*760c253cSXin Li 196*760c253cSXin Li benchmark_settings = experiment_file.GetSettings("benchmark") 197*760c253cSXin Li self.assertEqual(len(benchmark_settings), 2) 198*760c253cSXin Li self.assertEqual(benchmark_settings[0].name, "PageCycler") 199*760c253cSXin Li self.assertEqual(benchmark_settings[0].GetField("iterations"), 3) 200*760c253cSXin Li self.assertEqual(benchmark_settings[1].name, "AndroidBench") 201*760c253cSXin Li self.assertEqual(benchmark_settings[1].GetField("iterations"), 2) 202*760c253cSXin Li 203*760c253cSXin Li def testDuplicateLabel(self): 204*760c253cSXin Li input_file = io.StringIO(EXPERIMENT_FILE_3) 205*760c253cSXin Li self.assertRaises(Exception, ExperimentFile, input_file) 206*760c253cSXin Li 207*760c253cSXin Li def testDuplicateBenchmark(self): 208*760c253cSXin Li input_file = io.StringIO(EXPERIMENT_FILE_4) 209*760c253cSXin Li experiment_file = ExperimentFile(input_file) 210*760c253cSXin Li benchmark_settings = experiment_file.GetSettings("benchmark") 211*760c253cSXin Li self.assertEqual(benchmark_settings[0].name, "webrtc") 212*760c253cSXin Li self.assertEqual( 213*760c253cSXin Li benchmark_settings[0].GetField("test_args"), 214*760c253cSXin Li "--story-filter=datachannel", 215*760c253cSXin Li ) 216*760c253cSXin Li self.assertEqual(benchmark_settings[1].name, "webrtc") 217*760c253cSXin Li self.assertEqual( 218*760c253cSXin Li benchmark_settings[1].GetField("test_args"), 219*760c253cSXin Li "--story-tag-filter=smoothness", 220*760c253cSXin Li ) 221*760c253cSXin Li 222*760c253cSXin Li def testCanonicalize(self): 223*760c253cSXin Li input_file = io.StringIO(EXPERIMENT_FILE_1) 224*760c253cSXin Li experiment_file = ExperimentFile(input_file) 225*760c253cSXin Li res = experiment_file.Canonicalize() 226*760c253cSXin Li self.assertEqual(res, OUTPUT_FILE) 227*760c253cSXin Li 228*760c253cSXin Li def testLoadDutConfigExperimentFile_Good(self): 229*760c253cSXin Li input_file = io.StringIO(DUT_CONFIG_EXPERIMENT_FILE_GOOD) 230*760c253cSXin Li experiment_file = ExperimentFile(input_file) 231*760c253cSXin Li global_settings = experiment_file.GetGlobalSettings() 232*760c253cSXin Li self.assertEqual(global_settings.GetField("turbostat"), False) 233*760c253cSXin Li self.assertEqual(global_settings.GetField("intel_pstate"), "no_hwp") 234*760c253cSXin Li self.assertEqual(global_settings.GetField("governor"), "powersave") 235*760c253cSXin Li self.assertEqual( 236*760c253cSXin Li global_settings.GetField("cpu_usage"), "exclusive_cores" 237*760c253cSXin Li ) 238*760c253cSXin Li self.assertEqual(global_settings.GetField("cpu_freq_pct"), 50) 239*760c253cSXin Li self.assertEqual(global_settings.GetField("cooldown_time"), 5) 240*760c253cSXin Li self.assertEqual(global_settings.GetField("cooldown_temp"), 38) 241*760c253cSXin Li self.assertEqual(global_settings.GetField("top_interval"), 5) 242*760c253cSXin Li 243*760c253cSXin Li def testLoadDutConfigExperimentFile_WrongGovernor(self): 244*760c253cSXin Li input_file = io.StringIO(DUT_CONFIG_EXPERIMENT_FILE_BAD_GOV) 245*760c253cSXin Li with self.assertRaises(RuntimeError) as msg: 246*760c253cSXin Li ExperimentFile(input_file) 247*760c253cSXin Li self.assertRegex(str(msg.exception), "governor: misspelled_governor") 248*760c253cSXin Li self.assertRegex( 249*760c253cSXin Li str(msg.exception), 250*760c253cSXin Li "Invalid enum value for field 'governor'." 251*760c253cSXin Li r" Must be one of \(performance, powersave, userspace, ondemand," 252*760c253cSXin Li r" conservative, schedutils, sched, interactive\)", 253*760c253cSXin Li ) 254*760c253cSXin Li 255*760c253cSXin Li def testLoadDutConfigExperimentFile_WrongCpuUsage(self): 256*760c253cSXin Li input_file = io.StringIO(DUT_CONFIG_EXPERIMENT_FILE_BAD_CPUUSE) 257*760c253cSXin Li with self.assertRaises(RuntimeError) as msg: 258*760c253cSXin Li ExperimentFile(input_file) 259*760c253cSXin Li self.assertRegex(str(msg.exception), "cpu_usage: unknown") 260*760c253cSXin Li self.assertRegex( 261*760c253cSXin Li str(msg.exception), 262*760c253cSXin Li "Invalid enum value for field 'cpu_usage'." 263*760c253cSXin Li r" Must be one of \(all, big_only, little_only, exclusive_cores\)", 264*760c253cSXin Li ) 265*760c253cSXin Li 266*760c253cSXin Li 267*760c253cSXin Liif __name__ == "__main__": 268*760c253cSXin Li unittest.main() 269