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