* [Fuego] [PATCH] ftc: add support for tguid matching in where clauses
@ 2018-04-18 3:38 Tim.Bird
2018-04-19 1:12 ` Daniel Sangorrin
0 siblings, 1 reply; 2+ messages in thread
From: Tim.Bird @ 2018-04-18 3:38 UTC (permalink / raw)
To: Tim.Bird, daniel.sangorrin, fuego
> -----Original Message-----
> From: Tim Bird
> > -----Original Message-----
> > From: Daniel Sangorrin
> >
> > Note: it would be nice to use the tguid in the where clause.
>
> 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=LTP,tguid:result=FAIL"
$ ftc gen-report --where "test=Dhrystone,tguid:result<15000000"
$ ftc gen-report --where "tguid=~[DW].*Score"
$ ftc gen-report --where "tguid=~.*udp.*"
Signed-off-by: Tim Bird <tim.bird@sony.com>
---
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 = \
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: '=','<','<=','>','>=','!=','=~'. The '=~' operator
means the value is a regular expression to match, for the indicated field.
Here are some example where options:
--where test=LTP
--where test=bonnie,board=beaglebone
--where "start_time>2 hours ago"
- --where batch_id=12"""
+ --where batch_id=12
+ --where tguid=~.*udp.*
+ --where tguid:result=FAIL"""
# format for command_help mapping with: key=name, value=(summary, long description)
command_help = {
@@ -963,6 +965,9 @@ class run_class:
except:
return ""
+ def __repr__(self):
+ return self.run_id
+
# return a map of {'<board_name>': 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)
+ def check_value(self, run_value):
+ if self.op == "=":
+ return run_value == self.value
+ elif self.op == "!=":
+ return run_value != self.value
+ elif self.op == "=~":
+ return re.match(self.value, run_value)
+ elif self.op == "<=":
+ try:
+ return float(run_value) <= float(self.value)
+ except ValueError:
+ return False
+ elif self.op == ">=":
+ try:
+ return float(run_value) >= float(self.value)
+ except ValueError:
+ return False
+ elif self.op == "<":
+ try:
+ return float(run_value) < float(self.value)
+ except ValueError:
+ return False
+ elif self.op == ">":
+ 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 = run.__dict__[self.field_name]
except:
- print("Error: did not find field '%s' in loaded run data for run %s" % (self.field_name, run.run_id))
- return False
+ pass
- if self.op == "=":
- return run_value == self.value
- elif self.op == "!=":
- return run_value != self.value
- elif self.op == "=~":
- return re.match(self.value, run_value)
- elif self.op == "<=":
- return float(run_value) <= float(self.value)
- elif self.op == ">=":
- return float(run_value) >= float(self.value)
- elif self.op == "<":
- return float(run_value) < float(self.value)
- elif self.op == ">":
- 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=="tguid":
+ cur_tguid = run.next_tguid("")
+ while cur_tguid:
+ if self.check_value(cur_tguid):
+ return True
+ cur_tguid = run.next_tguid(cur_tguid)
+ return False
+
+ if self.field_name=="tguid:result":
+ cur_tguid = run.next_tguid("")
+ while cur_tguid:
+ if self.check_value(run.get_field("result", cur_tguid)):
+ return True
+ cur_tguid = 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
+ def match_tguid(self, run, tguid):
+ # check run data for tguid match
+ if self.field_name=="tguid":
+ return self.check_value(tguid)
+
+ if self.field_name=="tguid:result":
+ return self.check_value(run.get_field("result", tguid))
+
# 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 = ["!=", "=~", "<=", ">=", "=", "<", ">"]
#field_list = ["testcase", "test","type","spec","board","host","since"]
field_list = ["test", "type", "spec", "board", "start_time", "result",
- "batch_id", "status", "build_number"]
+ "batch_id", "status", "build_number", "tguid", "tguid:result"]
where_list = []
for clause in where_string.split(","):
where = 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 = [fields]
@@ -2071,6 +2120,11 @@ def get_report_data(run_list, run_map, fields):
run.get_run_data_from_json_file()
cur_tguid = ""
+ where_list_has_tguid_field = False
+ for where in where_list:
+ if where.field_name.startswith("tguid"):
+ where_list_has_tguid_field = True
+
done = False
while not done:
cur_tguid = run.next_tguid(cur_tguid)
@@ -2091,7 +2145,17 @@ def get_report_data(run_list, run_map, fields):
if cur_tguid == "default":
continue
- # 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 = True
+ for where in where_list:
+ if where.field_name.startswith("tguid"):
+ if not where.match_tguid(run, cur_tguid):
+ match = False
+ if not match:
+ continue
# get the values of the fields for this entry
value_list = []
@@ -2387,6 +2451,7 @@ def do_gen_report(conf, options):
where_list = parse_where(where_str)
run_list = filter_runs(run_map, where_list)
else:
+ where_list = []
run_list = run_map.keys()
if not run_list:
@@ -2455,7 +2520,7 @@ def do_gen_report(conf, options):
# get data for report
header_data = get_report_header_data(run_list, run_map, header_fields)
- report_data = get_report_data(run_list, run_map, fields)
+ report_data = get_report_data(run_list, run_map, fields, where_list)
if fmt == "txt":
report = gen_txt_report(header_data, report_data)
--
2.1.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [Fuego] [PATCH] ftc: add support for tguid matching in where clauses
2018-04-18 3:38 [Fuego] [PATCH] ftc: add support for tguid matching in where clauses Tim.Bird
@ 2018-04-19 1:12 ` Daniel Sangorrin
0 siblings, 0 replies; 2+ messages in thread
From: Daniel Sangorrin @ 2018-04-19 1:12 UTC (permalink / raw)
To: Tim.Bird, fuego
> > -----Original Message-----
> > From: Tim Bird
> > > -----Original Message-----
> > > From: Daniel Sangorrin
> > >
> > > Note: it would be nice to use the tguid in the where clause.
> >
> > 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!
Wow thanks a lot for this!! it works well and it's super useful.
Thanks,
Daniel
> ----
> 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=LTP,tguid:result=FAIL"
> $ ftc gen-report --where "test=Dhrystone,tguid:result<15000000"
> $ ftc gen-report --where "tguid=~[DW].*Score"
> $ ftc gen-report --where "tguid=~.*udp.*"
>
> Signed-off-by: Tim Bird <tim.bird@sony.com>
> ---
> 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 = \
> 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: '=','<','<=','>','>=','!=','=~'. The '=~' operator
> means the value is a regular expression to match, for the indicated field.
> Here are some example where options:
> --where test=LTP
> --where test=bonnie,board=beaglebone
> --where "start_time>2 hours ago"
> - --where batch_id=12"""
> + --where batch_id=12
> + --where tguid=~.*udp.*
> + --where tguid:result=FAIL"""
>
> # format for command_help mapping with: key=name, value=(summary, long
> description)
> command_help = {
> @@ -963,6 +965,9 @@ class run_class:
> except:
> return ""
>
> + def __repr__(self):
> + return self.run_id
> +
>
> # return a map of {'<board_name>': 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)
>
> + def check_value(self, run_value):
> + if self.op == "=":
> + return run_value == self.value
> + elif self.op == "!=":
> + return run_value != self.value
> + elif self.op == "=~":
> + return re.match(self.value, run_value)
> + elif self.op == "<=":
> + try:
> + return float(run_value) <= float(self.value)
> + except ValueError:
> + return False
> + elif self.op == ">=":
> + try:
> + return float(run_value) >= float(self.value)
> + except ValueError:
> + return False
> + elif self.op == "<":
> + try:
> + return float(run_value) < float(self.value)
> + except ValueError:
> + return False
> + elif self.op == ">":
> + 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 = run.__dict__[self.field_name]
> except:
> - print("Error: did not find field '%s' in loaded run data for run %s" %
> (self.field_name, run.run_id))
> - return False
> + pass
>
> - if self.op == "=":
> - return run_value == self.value
> - elif self.op == "!=":
> - return run_value != self.value
> - elif self.op == "=~":
> - return re.match(self.value, run_value)
> - elif self.op == "<=":
> - return float(run_value) <= float(self.value)
> - elif self.op == ">=":
> - return float(run_value) >= float(self.value)
> - elif self.op == "<":
> - return float(run_value) < float(self.value)
> - elif self.op == ">":
> - 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=="tguid":
> + cur_tguid = run.next_tguid("")
> + while cur_tguid:
> + if self.check_value(cur_tguid):
> + return True
> + cur_tguid = run.next_tguid(cur_tguid)
> + return False
> +
> + if self.field_name=="tguid:result":
> + cur_tguid = run.next_tguid("")
> + while cur_tguid:
> + if self.check_value(run.get_field("result", cur_tguid)):
> + return True
> + cur_tguid = 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
>
> + def match_tguid(self, run, tguid):
> + # check run data for tguid match
> + if self.field_name=="tguid":
> + return self.check_value(tguid)
> +
> + if self.field_name=="tguid:result":
> + return self.check_value(run.get_field("result", tguid))
> +
>
> # 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 = ["!=", "=~", "<=", ">=", "=", "<", ">"]
> #field_list = ["testcase", "test","type","spec","board","host","since"]
> field_list = ["test", "type", "spec", "board", "start_time", "result",
> - "batch_id", "status", "build_number"]
> + "batch_id", "status", "build_number", "tguid", "tguid:result"]
> where_list = []
> for clause in where_string.split(","):
> where = 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 = [fields]
>
> @@ -2071,6 +2120,11 @@ def get_report_data(run_list, run_map, fields):
> run.get_run_data_from_json_file()
> cur_tguid = ""
>
> + where_list_has_tguid_field = False
> + for where in where_list:
> + if where.field_name.startswith("tguid"):
> + where_list_has_tguid_field = True
> +
> done = False
> while not done:
> cur_tguid = run.next_tguid(cur_tguid)
> @@ -2091,7 +2145,17 @@ def get_report_data(run_list, run_map, fields):
> if cur_tguid == "default":
> continue
>
> - # 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 = True
> + for where in where_list:
> + if where.field_name.startswith("tguid"):
> + if not where.match_tguid(run, cur_tguid):
> + match = False
> + if not match:
> + continue
>
> # get the values of the fields for this entry
> value_list = []
> @@ -2387,6 +2451,7 @@ def do_gen_report(conf, options):
> where_list = parse_where(where_str)
> run_list = filter_runs(run_map, where_list)
> else:
> + where_list = []
> run_list = run_map.keys()
>
> if not run_list:
> @@ -2455,7 +2520,7 @@ def do_gen_report(conf, options):
>
> # get data for report
> header_data = get_report_header_data(run_list, run_map, header_fields)
> - report_data = get_report_data(run_list, run_map, fields)
> + report_data = get_report_data(run_list, run_map, fields, where_list)
>
> if fmt == "txt":
> report = gen_txt_report(header_data, report_data)
> --
> 2.1.4
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-04-19 1:12 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-18 3:38 [Fuego] [PATCH] ftc: add support for tguid matching in where clauses Tim.Bird
2018-04-19 1:12 ` Daniel Sangorrin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.