xref: /aosp_15_r20/external/toolchain-utils/crosperf/experiment_file_unittest.py (revision 760c253c1ed00ce9abd48f8546f08516e57485fe)
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