From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Sony.onmicrosoft.com; s=selector1-Sony-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=DSMxRAKl9ZZA3FimS2Ow2xZBP7jag2fwjDIY29raJ6k=; b=DrOE/2Z5f7nZku0L2pCSMJRILhliG42lThZmEY6QGcjTYjXyJXUx6IdoDsnpfh4xSlHla9le7aixR2EXDgVV+1fp07Sst8xTtr4x0l8L+zj8gbBi+tt+5nYhRJj0qBLi7S/m34EFwvWbx5C7x9tnVJjw7eiDfgdh4nJ6okQ0IzU= From: Date: Wed, 18 Apr 2018 03:38:07 +0000 Message-ID: Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: [Fuego] [PATCH] ftc: add support for tguid matching in where clauses List-Id: Mailing list for the Fuego test framework List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Tim.Bird@sony.com, daniel.sangorrin@toshiba.co.jp, fuego@lists.linuxfoundation.org > -----Original Message----- > From: Tim Bird > > -----Original Message----- > > From: Daniel Sangorrin > > > > Note: it would be nice to use the tguid in the where clause. >=20 > Indeed. I'll take a look at this and see if I can add it. Here's an attempt at something ... Hope it's useful! -- Tim ---- Where clauses are used to filter results in ftc list-runs and ftc gen-report. Add support for using 'tguid' and 'tguid:result' as where-clause arguments. This allows fun stuff like: $ ftc gen-report --where "test=3DLTP,tguid:result=3DFAIL" $ ftc gen-report --where "test=3DDhrystone,tguid:result<15000000" $ ftc gen-report --where "tguid=3D~[DW].*Score" $ ftc gen-report --where "tguid=3D~.*udp.*" Signed-off-by: Tim Bird --- engine/scripts/ftc | 109 ++++++++++++++++++++++++++++++++++++++++++-------= ---- 1 file changed, 87 insertions(+), 22 deletions(-) diff --git a/engine/scripts/ftc b/engine/scripts/ftc index 4574eba..5b4d23d 100755 --- a/engine/scripts/ftc +++ b/engine/scripts/ftc @@ -85,14 +85,16 @@ where_help =3D \ to filter the list of runs. Each where clause is separated by a comma. A 'where clause' consists of a field_name, an operator and a value. Allowed field names are: test, type, spec, board, start_time, result, - batch_id, status, and build_number. + batch_id, status, build_number, tguid, and tguid:result. Allowed operators are: '=3D','<','<=3D','>','>=3D','!=3D','=3D~'. The '= =3D~' operator means the value is a regular expression to match, for the indicated fiel= d. Here are some example where options: --where test=3DLTP --where test=3Dbonnie,board=3Dbeaglebone --where "start_time>2 hours ago" - --where batch_id=3D12""" + --where batch_id=3D12 + --where tguid=3D~.*udp.* + --where tguid:result=3DFAIL""" =20 # format for command_help mapping with: key=3Dname, value=3D(summary, long= description) command_help =3D { @@ -963,6 +965,9 @@ class run_class: except: return "" =20 + def __repr__(self): + return self.run_id + =20 # return a map of {'': board_instance } def get_fuego_boards(conf): @@ -1909,6 +1914,36 @@ class where_class: def __repr__(self): return "where(%s, %s, %s)" % (self.field_name, self.op, self.value) =20 + def check_value(self, run_value): + if self.op =3D=3D "=3D": + return run_value =3D=3D self.value + elif self.op =3D=3D "!=3D": + return run_value !=3D self.value + elif self.op =3D=3D "=3D~": + return re.match(self.value, run_value) + elif self.op =3D=3D "<=3D": + try: + return float(run_value) <=3D float(self.value) + except ValueError: + return False + elif self.op =3D=3D ">=3D": + try: + return float(run_value) >=3D float(self.value) + except ValueError: + return False + elif self.op =3D=3D "<": + try: + return float(run_value) < float(self.value) + except ValueError: + return False + elif self.op =3D=3D ">": + try: + return float(run_value) > float(self.value) + except ValueError: + return False + + return False + def match(self, run): # some fields can be found without loading the run.json file # examples are: "test", "type", "spec", "board", "num" @@ -1928,25 +1963,39 @@ class where_class: try: run_value =3D run.__dict__[self.field_name] except: - print("Error: did not find field '%s' in loaded run data f= or run %s" % (self.field_name, run.run_id)) - return False + pass =20 - if self.op =3D=3D "=3D": - return run_value =3D=3D self.value - elif self.op =3D=3D "!=3D": - return run_value !=3D self.value - elif self.op =3D=3D "=3D~": - return re.match(self.value, run_value) - elif self.op =3D=3D "<=3D": - return float(run_value) <=3D float(self.value) - elif self.op =3D=3D ">=3D": - return float(run_value) >=3D float(self.value) - elif self.op =3D=3D "<": - return float(run_value) < float(self.value) - elif self.op =3D=3D ">": - return float(run_value) > float(self.value) + if found: + return self.check_value(run_value) + + # check run data for tguid and tguid:result (on each tguid) + if self.field_name=3D=3D"tguid": + cur_tguid =3D run.next_tguid("") + while cur_tguid: + if self.check_value(cur_tguid): + return True + cur_tguid =3D run.next_tguid(cur_tguid) + return False + + if self.field_name=3D=3D"tguid:result": + cur_tguid =3D run.next_tguid("") + while cur_tguid: + if self.check_value(run.get_field("result", cur_tguid)): + return True + cur_tguid =3D run.next_tguid(cur_tguid) + return False + + print("Error: did not find field '%s' in loaded run data for run %= s" % (self.field_name, run.run_id)) return False =20 + def match_tguid(self, run, tguid): + # check run data for tguid match + if self.field_name=3D=3D"tguid": + return self.check_value(tguid) + + if self.field_name=3D=3D"tguid:result": + return self.check_value(run.get_field("result", tguid)) + =20 # returns a where_list (list of where tuples) # each where tuple is (field_name, operation, value) @@ -1956,7 +2005,7 @@ def parse_where(where_string): op_list =3D ["!=3D", "=3D~", "<=3D", ">=3D", "=3D", "<", ">"] #field_list =3D ["testcase", "test","type","spec","board","host","sinc= e"] field_list =3D ["test", "type", "spec", "board", "start_time", "result= ", - "batch_id", "status", "build_number"] + "batch_id", "status", "build_number", "tguid", "tguid:result"] where_list =3D [] for clause in where_string.split(","): where =3D None @@ -2058,7 +2107,7 @@ def get_report_header_data(run_list, run_map, header_= fields): # list of field names. # In each subsequent list is a list of values corresponding to the # requested fields, from the run data -def get_report_data(run_list, run_map, fields): +def get_report_data(run_list, run_map, fields, where_list): # first element is list of field names report_data =3D [fields] =20 @@ -2071,6 +2120,11 @@ def get_report_data(run_list, run_map, fields): run.get_run_data_from_json_file() cur_tguid =3D "" =20 + where_list_has_tguid_field =3D False + for where in where_list: + if where.field_name.startswith("tguid"): + where_list_has_tguid_field =3D True + done =3D False while not done: cur_tguid =3D run.next_tguid(cur_tguid) @@ -2091,7 +2145,17 @@ def get_report_data(run_list, run_map, fields): if cur_tguid =3D=3D "default": continue =20 - # at this point, we have a (run, tguid) with data + # at this point, we have a (run, cur_tguid) with data + + # check to see if we need to filter this entry + if where_list_has_tguid_field: + match =3D True + for where in where_list: + if where.field_name.startswith("tguid"): + if not where.match_tguid(run, cur_tguid): + match =3D False + if not match: + continue =20 # get the values of the fields for this entry value_list =3D [] @@ -2387,6 +2451,7 @@ def do_gen_report(conf, options): where_list =3D parse_where(where_str) run_list =3D filter_runs(run_map, where_list) else: + where_list =3D [] run_list =3D run_map.keys() =20 if not run_list: @@ -2455,7 +2520,7 @@ def do_gen_report(conf, options): =20 # get data for report header_data =3D get_report_header_data(run_list, run_map, header_field= s) - report_data =3D get_report_data(run_list, run_map, fields) + report_data =3D get_report_data(run_list, run_map, fields, where_list) =20 if fmt =3D=3D "txt": report =3D gen_txt_report(header_data, report_data) --=20 2.1.4