All of lore.kernel.org
 help / color / mirror / Atom feed
From: <Tim.Bird@sony.com>
To: Tim.Bird@sony.com, daniel.sangorrin@toshiba.co.jp,
	fuego@lists.linuxfoundation.org
Subject: [Fuego] [PATCH] ftc: add support for tguid matching in where clauses
Date: Wed, 18 Apr 2018 03:38:07 +0000	[thread overview]
Message-ID: <ECADFF3FD767C149AD96A924E7EA6EAF7C11AA7B@USCULXMSG01.am.sony.com> (raw)

> -----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


             reply	other threads:[~2018-04-18  3:38 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-18  3:38 Tim.Bird [this message]
2018-04-19  1:12 ` [Fuego] [PATCH] ftc: add support for tguid matching in where clauses Daniel Sangorrin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ECADFF3FD767C149AD96A924E7EA6EAF7C11AA7B@USCULXMSG01.am.sony.com \
    --to=tim.bird@sony.com \
    --cc=daniel.sangorrin@toshiba.co.jp \
    --cc=fuego@lists.linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.