xref: /aosp_15_r20/external/toolchain-utils/update_telemetry_defaults.py (revision 760c253c1ed00ce9abd48f8546f08516e57485fe)
1*760c253cSXin Li#!/usr/bin/env python3
2*760c253cSXin Li# -*- coding: utf-8 -*-
3*760c253cSXin Li# Copyright 2020 The ChromiumOS Authors
4*760c253cSXin Li# Use of this source code is governed by a BSD-style license that can be
5*760c253cSXin Li# found in the LICENSE file.
6*760c253cSXin Li
7*760c253cSXin Li"""Script to maintain the Telemetry benchmark default results file.
8*760c253cSXin Li
9*760c253cSXin LiThis script allows the user to see and update the set of default
10*760c253cSXin Liresults to be used in generating reports from running the Telemetry
11*760c253cSXin Libenchmarks.
12*760c253cSXin Li"""
13*760c253cSXin Li
14*760c253cSXin Li
15*760c253cSXin Li__author__ = "[email protected] (Caroline Tice)"
16*760c253cSXin Li
17*760c253cSXin Liimport json
18*760c253cSXin Liimport os
19*760c253cSXin Liimport sys
20*760c253cSXin Li
21*760c253cSXin Lifrom cros_utils import misc
22*760c253cSXin Li
23*760c253cSXin Li
24*760c253cSXin LiDefaults = {}
25*760c253cSXin Li
26*760c253cSXin Li
27*760c253cSXin Liclass TelemetryDefaults(object):
28*760c253cSXin Li    """Class for handling telemetry default return result fields."""
29*760c253cSXin Li
30*760c253cSXin Li    DEFAULTS_FILE_NAME = "crosperf/default-telemetry-results.json"
31*760c253cSXin Li
32*760c253cSXin Li    def __init__(self):
33*760c253cSXin Li        # Get the Crosperf directory; that is where the defaults
34*760c253cSXin Li        # file should be.
35*760c253cSXin Li        dirname, __ = misc.GetRoot(__file__)
36*760c253cSXin Li        fullname = os.path.join(dirname, self.DEFAULTS_FILE_NAME)
37*760c253cSXin Li        self._filename = fullname
38*760c253cSXin Li        self._defaults = {}
39*760c253cSXin Li
40*760c253cSXin Li    def ReadDefaultsFile(self):
41*760c253cSXin Li        if os.path.exists(self._filename):
42*760c253cSXin Li            with open(self._filename, "r", encoding="utf-8") as fp:
43*760c253cSXin Li                self._defaults = json.load(fp)
44*760c253cSXin Li
45*760c253cSXin Li    def WriteDefaultsFile(self):
46*760c253cSXin Li        with open(self._filename, "w", encoding="utf-8") as fp:
47*760c253cSXin Li            json.dump(self._defaults, fp, indent=2)
48*760c253cSXin Li
49*760c253cSXin Li    def ListCurrentDefaults(self, benchmark="all"):
50*760c253cSXin Li        # Show user current defaults. By default, show all.  The user
51*760c253cSXin Li        # can specify the name of a particular benchmark to see only that
52*760c253cSXin Li        # benchmark's default values.
53*760c253cSXin Li        if len(self._defaults) == 0:
54*760c253cSXin Li            print("The benchmark default results are currently empty.")
55*760c253cSXin Li        if benchmark == "all":
56*760c253cSXin Li            for b in self._defaults.keys():
57*760c253cSXin Li                results = self._defaults[b]
58*760c253cSXin Li                out_str = b + " : "
59*760c253cSXin Li                for r in results:
60*760c253cSXin Li                    out_str += r + " "
61*760c253cSXin Li                print(out_str)
62*760c253cSXin Li        elif benchmark in self._defaults:
63*760c253cSXin Li            results = self._defaults[benchmark]
64*760c253cSXin Li            out_str = benchmark + " : "
65*760c253cSXin Li            for r in results:
66*760c253cSXin Li                out_str += r + " "
67*760c253cSXin Li            print(out_str)
68*760c253cSXin Li        else:
69*760c253cSXin Li            print("Error:  Unrecognized benchmark '%s'" % benchmark)
70*760c253cSXin Li
71*760c253cSXin Li    def AddDefault(self, benchmark, result):
72*760c253cSXin Li        if benchmark in self._defaults:
73*760c253cSXin Li            resultList = self._defaults[benchmark]
74*760c253cSXin Li        else:
75*760c253cSXin Li            resultList = []
76*760c253cSXin Li        resultList.append(result)
77*760c253cSXin Li        self._defaults[benchmark] = resultList
78*760c253cSXin Li        print("Updated results set for '%s': " % benchmark)
79*760c253cSXin Li        print("%s : %s" % (benchmark, repr(self._defaults[benchmark])))
80*760c253cSXin Li
81*760c253cSXin Li    def RemoveDefault(self, benchmark, result):
82*760c253cSXin Li        if benchmark in self._defaults:
83*760c253cSXin Li            resultList = self._defaults[benchmark]
84*760c253cSXin Li            if result in resultList:
85*760c253cSXin Li                resultList.remove(result)
86*760c253cSXin Li                print("Updated results set for '%s': " % benchmark)
87*760c253cSXin Li                print("%s : %s" % (benchmark, repr(self._defaults[benchmark])))
88*760c253cSXin Li            else:
89*760c253cSXin Li                print(
90*760c253cSXin Li                    "'%s' is not in '%s's default results list."
91*760c253cSXin Li                    % (result, benchmark)
92*760c253cSXin Li                )
93*760c253cSXin Li        else:
94*760c253cSXin Li            print("Cannot find benchmark named '%s'" % benchmark)
95*760c253cSXin Li
96*760c253cSXin Li    def GetDefault(self):
97*760c253cSXin Li        return self._defaults
98*760c253cSXin Li
99*760c253cSXin Li    def RemoveBenchmark(self, benchmark):
100*760c253cSXin Li        if benchmark in self._defaults:
101*760c253cSXin Li            del self._defaults[benchmark]
102*760c253cSXin Li            print("Deleted benchmark '%s' from list of benchmarks." % benchmark)
103*760c253cSXin Li        else:
104*760c253cSXin Li            print("Cannot find benchmark named '%s'" % benchmark)
105*760c253cSXin Li
106*760c253cSXin Li    def RenameBenchmark(self, old_name, new_name):
107*760c253cSXin Li        if old_name in self._defaults:
108*760c253cSXin Li            resultsList = self._defaults[old_name]
109*760c253cSXin Li            del self._defaults[old_name]
110*760c253cSXin Li            self._defaults[new_name] = resultsList
111*760c253cSXin Li            print("Renamed '%s' to '%s'." % (old_name, new_name))
112*760c253cSXin Li        else:
113*760c253cSXin Li            print("Cannot find benchmark named '%s'" % old_name)
114*760c253cSXin Li
115*760c253cSXin Li    def UsageError(self, user_input):
116*760c253cSXin Li        # Print error message, then show options
117*760c253cSXin Li        print("Error:Invalid user input: '%s'" % user_input)
118*760c253cSXin Li        self.ShowOptions()
119*760c253cSXin Li
120*760c253cSXin Li    def ShowOptions(self):
121*760c253cSXin Li        print(
122*760c253cSXin Li            """
123*760c253cSXin LiBelow are the valid user options and their arguments, and an explanation
124*760c253cSXin Liof what each option does.  You may either print out the full name of the
125*760c253cSXin Lioption, or you may use the first letter of the option.  Case (upper or
126*760c253cSXin Lilower) does not matter, for the command (case of the result name DOES matter):
127*760c253cSXin Li
128*760c253cSXin Li    (L)ist                           - List all current defaults
129*760c253cSXin Li    (L)ist <benchmark>               - List current defaults for benchmark
130*760c253cSXin Li    (H)elp                           - Show this information.
131*760c253cSXin Li    (A)dd <benchmark> <result>       - Add a default result for a particular
132*760c253cSXin Li                                       benchmark (appends to benchmark's list
133*760c253cSXin Li                                       of results, if list already exists)
134*760c253cSXin Li    (D)elete <benchmark> <result>    - Delete a default result for a
135*760c253cSXin Li                                       particular benchmark
136*760c253cSXin Li    (R)emove <benchmark>             - Remove an entire benchmark (and its
137*760c253cSXin Li                                       results)
138*760c253cSXin Li    (M)ove <old-benchmark> <new-benchmark>    - Rename a benchmark
139*760c253cSXin Li    (Q)uit                           - Exit this program, saving changes.
140*760c253cSXin Li    (T)erminate                      - Exit this program; abandon changes.
141*760c253cSXin Li
142*760c253cSXin Li"""
143*760c253cSXin Li        )
144*760c253cSXin Li
145*760c253cSXin Li    def GetUserInput(self):
146*760c253cSXin Li        # Prompt user
147*760c253cSXin Li        print("Enter option> ")
148*760c253cSXin Li        # Process user input
149*760c253cSXin Li        inp = sys.stdin.readline()
150*760c253cSXin Li        inp = inp[:-1]
151*760c253cSXin Li        # inp = inp.lower()
152*760c253cSXin Li        words = inp.split(" ")
153*760c253cSXin Li        option = words[0]
154*760c253cSXin Li        option = option.lower()
155*760c253cSXin Li        if option in ("h", "help"):
156*760c253cSXin Li            self.ShowOptions()
157*760c253cSXin Li        elif option in ("l", "list"):
158*760c253cSXin Li            if len(words) == 1:
159*760c253cSXin Li                self.ListCurrentDefaults()
160*760c253cSXin Li            else:
161*760c253cSXin Li                self.ListCurrentDefaults(benchmark=words[1])
162*760c253cSXin Li        elif option in ("a", "add"):
163*760c253cSXin Li            if len(words) < 3:
164*760c253cSXin Li                self.UsageError(inp)
165*760c253cSXin Li            else:
166*760c253cSXin Li                benchmark = words[1]
167*760c253cSXin Li                resultList = words[2:]
168*760c253cSXin Li                for r in resultList:
169*760c253cSXin Li                    self.AddDefault(benchmark, r)
170*760c253cSXin Li        elif option in ("d", "delete"):
171*760c253cSXin Li            if len(words) != 3:
172*760c253cSXin Li                self.UsageError(inp)
173*760c253cSXin Li            else:
174*760c253cSXin Li                benchmark = words[1]
175*760c253cSXin Li                result = words[2]
176*760c253cSXin Li                self.RemoveDefault(benchmark, result)
177*760c253cSXin Li        elif option in ("r", "remove"):
178*760c253cSXin Li            if len(words) != 2:
179*760c253cSXin Li                self.UsageError(inp)
180*760c253cSXin Li            else:
181*760c253cSXin Li                benchmark = words[1]
182*760c253cSXin Li                self.RemoveBenchmark(benchmark)
183*760c253cSXin Li        elif option in ("m", "move"):
184*760c253cSXin Li            if len(words) != 3:
185*760c253cSXin Li                self.UsageError(inp)
186*760c253cSXin Li            else:
187*760c253cSXin Li                old_name = words[1]
188*760c253cSXin Li                new_name = words[2]
189*760c253cSXin Li                self.RenameBenchmark(old_name, new_name)
190*760c253cSXin Li        elif option in ("q", "quit"):
191*760c253cSXin Li            self.WriteDefaultsFile()
192*760c253cSXin Li
193*760c253cSXin Li        return option in ("q", "quit", "t", "terminate")
194*760c253cSXin Li
195*760c253cSXin Li
196*760c253cSXin Lidef Main():
197*760c253cSXin Li    defaults = TelemetryDefaults()
198*760c253cSXin Li    defaults.ReadDefaultsFile()
199*760c253cSXin Li    defaults.ShowOptions()
200*760c253cSXin Li    done = defaults.GetUserInput()
201*760c253cSXin Li    while not done:
202*760c253cSXin Li        done = defaults.GetUserInput()
203*760c253cSXin Li    return 0
204*760c253cSXin Li
205*760c253cSXin Li
206*760c253cSXin Liif __name__ == "__main__":
207*760c253cSXin Li    retval = Main()
208*760c253cSXin Li    sys.exit(retval)
209