xref: /aosp_15_r20/external/toolchain-utils/crosperf/settings_factory.py (revision 760c253c1ed00ce9abd48f8546f08516e57485fe)
1# -*- coding: utf-8 -*-
2# Copyright 2013 The ChromiumOS Authors
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Setting files for global, benchmark and labels."""
7
8
9from field import BooleanField
10from field import EnumField
11from field import FloatField
12from field import IntegerField
13from field import ListField
14from field import TextField
15from settings import Settings
16
17
18class BenchmarkSettings(Settings):
19    """Settings used to configure individual benchmarks."""
20
21    def __init__(self, name):
22        super(BenchmarkSettings, self).__init__(name, "benchmark")
23        self.AddField(
24            TextField(
25                "test_name",
26                description="The name of the test to run. "
27                "Defaults to the name of the benchmark.",
28            )
29        )
30        self.AddField(
31            TextField(
32                "test_args",
33                description="Arguments to be passed to the " "test.",
34            )
35        )
36        self.AddField(
37            IntegerField(
38                "iterations",
39                required=False,
40                default=0,
41                description="Number of iterations to run the test. "
42                "If not set, will run each benchmark test the optimum number of "
43                "times to get a stable result.",
44            )
45        )
46        self.AddField(
47            TextField(
48                "suite",
49                default="test_that",
50                description="The type of the benchmark.",
51            )
52        )
53        self.AddField(
54            IntegerField(
55                "retries",
56                default=0,
57                description="Number of times to retry a " "benchmark run.",
58            )
59        )
60        self.AddField(
61            BooleanField(
62                "run_local",
63                description="Run benchmark harness on the DUT. "
64                "Currently only compatible with the suite: "
65                "telemetry_Crosperf.",
66                required=False,
67                default=True,
68            )
69        )
70        self.AddField(
71            FloatField(
72                "weight",
73                default=0.0,
74                description="Weight of the benchmark for CWP approximation",
75            )
76        )
77
78
79class LabelSettings(Settings):
80    """Settings for each label."""
81
82    def __init__(self, name):
83        super(LabelSettings, self).__init__(name, "label")
84        self.AddField(
85            TextField(
86                "chromeos_image",
87                required=False,
88                description="The path to the image to run tests "
89                "on, for local/custom-built images. See the "
90                "'build' option for official or trybot images.",
91            )
92        )
93        self.AddField(
94            TextField(
95                "autotest_path",
96                required=False,
97                description="Autotest directory path relative to chroot which "
98                "has autotest files for the image to run tests requiring autotest "
99                "files.",
100            )
101        )
102        self.AddField(
103            TextField(
104                "debug_path",
105                required=False,
106                description="Debug info directory relative to chroot which has "
107                "symbols and vmlinux that can be used by perf tool.",
108            )
109        )
110        self.AddField(
111            TextField(
112                "chromeos_root",
113                description="The path to a chromeos checkout which "
114                "contains a src/scripts directory. Defaults to "
115                "the chromeos checkout which contains the "
116                "chromeos_image.",
117            )
118        )
119        self.AddField(
120            ListField(
121                "remote",
122                description="A comma-separated list of IPs of chromeos"
123                "devices to run experiments on.",
124            )
125        )
126        self.AddField(
127            TextField(
128                "image_args",
129                required=False,
130                default="",
131                description="Extra arguments to pass to " "image_chromeos.py.",
132            )
133        )
134        self.AddField(
135            TextField(
136                "cache_dir",
137                default="",
138                description="The cache dir for this image.",
139            )
140        )
141        self.AddField(
142            TextField(
143                "compiler",
144                default="gcc",
145                description="The compiler used to build the "
146                "ChromeOS image (gcc or llvm).",
147            )
148        )
149        self.AddField(
150            TextField(
151                "chrome_src",
152                description="The path to the source of chrome. "
153                "This is used to run telemetry benchmarks. "
154                "The default one is the src inside chroot.",
155                required=False,
156                default="",
157            )
158        )
159        self.AddField(
160            TextField(
161                "build",
162                description="The xbuddy specification for an "
163                "official or trybot image to use for tests. "
164                "'/remote' is assumed, and the board is given "
165                "elsewhere, so omit the '/remote/<board>/' xbuddy "
166                "prefix.",
167                required=False,
168                default="",
169            )
170        )
171
172
173class GlobalSettings(Settings):
174    """Settings that apply per-experiment."""
175
176    def __init__(self, name):
177        super(GlobalSettings, self).__init__(name, "global")
178        self.AddField(
179            TextField(
180                "name",
181                description="The name of the experiment. Just an "
182                "identifier.",
183            )
184        )
185        self.AddField(
186            TextField(
187                "board",
188                description="The target board for running "
189                "experiments on, e.g. x86-alex.",
190            )
191        )
192        self.AddField(
193            BooleanField(
194                "crosfleet",
195                description="Whether to run experiments via crosfleet.",
196                default=False,
197            )
198        )
199        self.AddField(
200            ListField(
201                "remote",
202                description="A comma-separated list of IPs of "
203                "chromeos devices to run experiments on.",
204            )
205        )
206        self.AddField(
207            BooleanField(
208                "rerun_if_failed",
209                description="Whether to re-run failed test runs or not.",
210                default=False,
211            )
212        )
213        self.AddField(
214            BooleanField(
215                "rm_chroot_tmp",
216                default=False,
217                description="Whether to remove the test_that "
218                "result in the chroot.",
219            )
220        )
221        self.AddField(
222            ListField(
223                "email",
224                description="Space-separated list of email "
225                "addresses to send email to.",
226            )
227        )
228        self.AddField(
229            BooleanField(
230                "rerun",
231                description="Whether to ignore the cache and "
232                "for tests to be re-run.",
233                default=False,
234            )
235        )
236        self.AddField(
237            BooleanField(
238                "ignore_cache",
239                description='Alias of "rerun" to ignore cache.',
240                default=False,
241            )
242        )
243        self.AddField(
244            BooleanField(
245                "same_specs",
246                default=True,
247                description="Ensure cached runs are run on the "
248                "same kind of devices which are specified as a "
249                "remote.",
250            )
251        )
252        self.AddField(
253            BooleanField(
254                "same_machine",
255                default=False,
256                description="Ensure cached runs are run on the same remote.",
257            )
258        )
259        self.AddField(
260            BooleanField(
261                "use_file_locks",
262                default=False,
263                description="DEPRECATED: Whether to use the file locks "
264                "or AFE server lock mechanism.",
265            )
266        )
267        self.AddField(
268            IntegerField(
269                "iterations",
270                required=False,
271                default=0,
272                description="Number of iterations to run all tests. "
273                "If not set, will run each benchmark test the optimum number of "
274                "times to get a stable result.",
275            )
276        )
277        self.AddField(
278            TextField(
279                "chromeos_root",
280                description="The path to a chromeos checkout which "
281                "contains a src/scripts directory. Defaults to "
282                "the chromeos checkout which contains the "
283                "chromeos_image.",
284            )
285        )
286        self.AddField(
287            TextField(
288                "logging_level",
289                default="average",
290                description="The level of logging desired. "
291                "Options are 'quiet', 'average', and 'verbose'.",
292            )
293        )
294        self.AddField(
295            IntegerField(
296                "acquire_timeout",
297                default=0,
298                description="Number of seconds to wait for "
299                "machine before exit if all the machines in "
300                "the experiment file are busy. Default is 0.",
301            )
302        )
303        self.AddField(
304            TextField(
305                "perf_args",
306                default="",
307                description="The optional profile command. It "
308                "enables perf commands to record perforamance "
309                "related counters. It must start with perf "
310                "command record or stat followed by arguments.",
311            )
312        )
313        self.AddField(
314            BooleanField(
315                "download_debug",
316                default=True,
317                description="Download compressed debug symbols alongwith "
318                "image. This can provide more info matching symbols for"
319                "profiles, but takes larger space. By default, download"
320                "it only when perf_args is specified.",
321            )
322        )
323        self.AddField(
324            TextField(
325                "cache_dir",
326                default="",
327                description="The abs path of cache dir. "
328                "Default is /home/$(whoami)/cros_scratch.",
329            )
330        )
331        self.AddField(
332            BooleanField(
333                "cache_only",
334                default=False,
335                description="Whether to use only cached "
336                "results (do not rerun failed tests).",
337            )
338        )
339        self.AddField(
340            BooleanField(
341                "no_email",
342                default=False,
343                description="Whether to disable the email to "
344                "user after crosperf finishes.",
345            )
346        )
347        self.AddField(
348            BooleanField(
349                "json_report",
350                default=False,
351                description="Whether to generate a json version "
352                "of the report, for archiving.",
353            )
354        )
355        self.AddField(
356            BooleanField(
357                "show_all_results",
358                default=False,
359                description="When running Telemetry tests, "
360                "whether to all the results, instead of just "
361                "the default (summary) results.",
362            )
363        )
364        self.AddField(
365            TextField(
366                "share_cache",
367                default="",
368                description="Path to alternate cache whose data "
369                "you want to use. It accepts multiple directories "
370                'separated by a ",".',
371            )
372        )
373        self.AddField(
374            TextField("results_dir", default="", description="The results dir.")
375        )
376        self.AddField(
377            BooleanField(
378                "compress_results",
379                default=True,
380                description="Whether to compress all test results other than "
381                "reports into a tarball to save disk space.",
382            )
383        )
384        self.AddField(
385            TextField(
386                "locks_dir",
387                default="",
388                description="An alternate directory to use for "
389                "storing/checking machine file locks for local machines. "
390                "By default the file locks directory is "
391                "/google/data/rw/users/mo/mobiletc-prebuild/locks.\n"
392                "WARNING: If you use your own locks directory, "
393                "there is no guarantee that someone else might not "
394                "hold a lock on the same machine in a different "
395                "locks directory.",
396            )
397        )
398        self.AddField(
399            TextField(
400                "chrome_src",
401                description="The path to the source of chrome. "
402                "This is used to run telemetry benchmarks. "
403                "The default one is the src inside chroot.",
404                required=False,
405                default="",
406            )
407        )
408        self.AddField(
409            IntegerField(
410                "retries",
411                default=0,
412                description="Number of times to retry a " "benchmark run.",
413            )
414        )
415        self.AddField(
416            TextField(
417                "cwp_dso",
418                description="The DSO type that we want to use for "
419                "CWP approximation. This is used to run telemetry "
420                "benchmarks. Valid DSO types can be found from dso_list "
421                "in experiment_factory.py. The default value is set to "
422                "be empty.",
423                required=False,
424                default="",
425            )
426        )
427        self.AddField(
428            BooleanField(
429                "enable_aslr",
430                description="Enable ASLR on the machine to run the "
431                "benchmarks. ASLR is disabled by default",
432                required=False,
433                default=False,
434            )
435        )
436        self.AddField(
437            BooleanField(
438                "ignore_min_max",
439                description="When doing math for the raw results, "
440                "ignore min and max values to reduce noise.",
441                required=False,
442                default=False,
443            )
444        )
445        self.AddField(
446            TextField(
447                "intel_pstate",
448                description="Intel Pstate mode.\n"
449                'Supported modes: "active", "passive", "no_hwp".\n'
450                'Default is "no_hwp" which disables hardware pstates to avoid '
451                "noise in benchmarks.",
452                required=False,
453                default="no_hwp",
454            )
455        )
456        self.AddField(
457            BooleanField(
458                "turbostat",
459                description="Run turbostat process in the background"
460                " of a benchmark. Enabled by default.",
461                required=False,
462                default=True,
463            )
464        )
465        self.AddField(
466            FloatField(
467                "top_interval",
468                description="Run top command in the background of a benchmark with"
469                " interval of sampling specified in seconds.\n"
470                "Recommended values 1-5. Lower number provides more accurate"
471                " data.\n"
472                "With 0 - do not run top.\n"
473                "NOTE: Running top with interval 1-5 sec has insignificant"
474                " performance impact (performance degradation does not exceed"
475                " 0.3%%, measured on x86_64, ARM32, and ARM64). "
476                "The default value is 1.",
477                required=False,
478                default=1,
479            )
480        )
481        self.AddField(
482            IntegerField(
483                "cooldown_temp",
484                required=False,
485                default=40,
486                description="Wait until CPU temperature goes down below"
487                " specified temperature in Celsius"
488                " prior starting a benchmark. "
489                "By default the value is set to 40 degrees.",
490            )
491        )
492        self.AddField(
493            IntegerField(
494                "cooldown_time",
495                required=False,
496                default=10,
497                description="Wait specified time in minutes allowing"
498                " CPU to cool down. Zero value disables cooldown. "
499                "The default value is 10 minutes.",
500            )
501        )
502        self.AddField(
503            EnumField(
504                "governor",
505                options=[
506                    "performance",
507                    "powersave",
508                    "userspace",
509                    "ondemand",
510                    "conservative",
511                    "schedutils",
512                    "sched",
513                    "interactive",
514                ],
515                default="performance",
516                required=False,
517                description="Setup CPU governor for all cores.\n"
518                "For more details refer to:\n"
519                "https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt. "
520                'Default is "performance" governor.',
521            )
522        )
523        self.AddField(
524            EnumField(
525                "cpu_usage",
526                options=[
527                    "all",
528                    "big_only",
529                    "little_only",
530                    "exclusive_cores",
531                ],
532                default="all",
533                required=False,
534                description="Restrict usage of CPUs to decrease CPU interference.\n"
535                '"all" - no restrictions;\n'
536                '"big-only", "little-only" - enable only big/little cores,'
537                " applicable only on ARM;\n"
538                '"exclusive-cores" - (for future use)'
539                " isolate cores for exclusive use of benchmark processes. "
540                "By default use all CPUs.",
541            )
542        )
543        self.AddField(
544            IntegerField(
545                "cpu_freq_pct",
546                required=False,
547                default=95,
548                description="Setup CPU frequency to a supported value less than"
549                " or equal to a percent of max_freq. "
550                "CPU frequency is reduced to 95%% by default to reduce thermal "
551                "throttling.",
552            )
553        )
554        self.AddField(
555            BooleanField(
556                "no_lock",
557                default=False,
558                description="Do not attempt to lock the DUT."
559                " Useful when lock is held externally, say with crosfleet.",
560            )
561        )
562        self.AddField(
563            BooleanField(
564                "keep_stateful",
565                default=False,
566                description="When flashing a ChromeOS image keep the stateful"
567                " partition, i.e. don't use --clobber-stateful. This option"
568                " is useful to keep ssh keys, wi-fi settings and so on.",
569            )
570        )
571
572
573class SettingsFactory(object):
574    """Factory class for building different types of Settings objects.
575
576    This factory is currently hardcoded to produce settings for ChromeOS
577    experiment files. The idea is that in the future, other types
578    of settings could be produced.
579    """
580
581    def GetSettings(self, name, settings_type):
582        if settings_type == "label" or not settings_type:
583            return LabelSettings(name)
584        if settings_type == "global":
585            return GlobalSettings(name)
586        if settings_type == "benchmark":
587            return BenchmarkSettings(name)
588
589        raise TypeError("Invalid settings type: '%s'." % settings_type)
590