Openembedded Core Discussions
 help / color / mirror / Atom feed
* [PATCH 0/2] resulttool improvements
@ 2019-04-19  2:57 Joshua Watt
  2019-04-19  2:57 ` [PATCH 1/2] resulttool: Load results from URL Joshua Watt
  2019-04-19  2:57 ` [PATCH 2/2] resulttool: Add log subcommand Joshua Watt
  0 siblings, 2 replies; 5+ messages in thread
From: Joshua Watt @ 2019-04-19  2:57 UTC (permalink / raw)
  To: openembedded-core

Implements 2 improvements to resulttool:
 1) Result files can be loaded over http or https
 2) Adds a new subcommand to extract logs from result data

Joshua Watt (2):
  resulttool: Load results from URL
  resulttool: Add log subcommand

 scripts/lib/resulttool/log.py         | 56 +++++++++++++++++++++++++++
 scripts/lib/resulttool/merge.py       |  8 ++--
 scripts/lib/resulttool/regression.py  |  6 +--
 scripts/lib/resulttool/report.py      |  2 +-
 scripts/lib/resulttool/resultutils.py | 23 +++++++++--
 scripts/lib/resulttool/store.py       |  4 +-
 scripts/resulttool                    |  2 +
 7 files changed, 87 insertions(+), 14 deletions(-)
 create mode 100644 scripts/lib/resulttool/log.py

-- 
2.20.1



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] resulttool: Load results from URL
  2019-04-19  2:57 [PATCH 0/2] resulttool improvements Joshua Watt
@ 2019-04-19  2:57 ` Joshua Watt
  2019-04-19  2:57 ` [PATCH 2/2] resulttool: Add log subcommand Joshua Watt
  1 sibling, 0 replies; 5+ messages in thread
From: Joshua Watt @ 2019-04-19  2:57 UTC (permalink / raw)
  To: openembedded-core

Adds support for resulttool to load JSON files directly from a http://
or https:// URL

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 scripts/lib/resulttool/merge.py       |  8 ++++----
 scripts/lib/resulttool/regression.py  |  4 ++--
 scripts/lib/resulttool/report.py      |  2 +-
 scripts/lib/resulttool/resultutils.py | 23 +++++++++++++++++++----
 scripts/lib/resulttool/store.py       |  4 ++--
 5 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/scripts/lib/resulttool/merge.py b/scripts/lib/resulttool/merge.py
index 3e4b7a38ad1..7159463f6ed 100644
--- a/scripts/lib/resulttool/merge.py
+++ b/scripts/lib/resulttool/merge.py
@@ -17,7 +17,7 @@ import json
 import resulttool.resultutils as resultutils
 
 def merge(args, logger):
-    if os.path.isdir(args.target_results):
+    if resultutils.is_url(args.target_results) or os.path.isdir(args.target_results):
         results = resultutils.load_resultsdata(args.target_results, configmap=resultutils.store_map)
         resultutils.append_resultsdata(results, args.base_results, configmap=resultutils.store_map)
         resultutils.save_resultsdata(results, args.target_results)
@@ -31,12 +31,12 @@ def merge(args, logger):
 
 def register_commands(subparsers):
     """Register subcommands from this plugin"""
-    parser_build = subparsers.add_parser('merge', help='merge test result files/directories',
-                                         description='merge the results from multiple files/directories into the target file or directory',
+    parser_build = subparsers.add_parser('merge', help='merge test result files/directories/URLs',
+                                         description='merge the results from multiple files/directories/URLs into the target file or directory',
                                          group='setup')
     parser_build.set_defaults(func=merge)
     parser_build.add_argument('base_results',
-                              help='the results file/directory to import')
+                              help='the results file/directory/URL to import')
     parser_build.add_argument('target_results',
                               help='the target file or directory to merge the base_results with')
 
diff --git a/scripts/lib/resulttool/regression.py b/scripts/lib/resulttool/regression.py
index bdf531dedf1..aecb9da9ce5 100644
--- a/scripts/lib/resulttool/regression.py
+++ b/scripts/lib/resulttool/regression.py
@@ -161,9 +161,9 @@ def register_commands(subparsers):
                                          group='analysis')
     parser_build.set_defaults(func=regression)
     parser_build.add_argument('base_result',
-                              help='base result file/directory for the comparison')
+                              help='base result file/directory/URL for the comparison')
     parser_build.add_argument('target_result',
-                              help='target result file/directory to compare with')
+                              help='target result file/directory/URL to compare with')
     parser_build.add_argument('-b', '--base-result-id', default='',
                               help='(optional) filter the base results to this result ID')
     parser_build.add_argument('-t', '--target-result-id', default='',
diff --git a/scripts/lib/resulttool/report.py b/scripts/lib/resulttool/report.py
index 90086209e35..8ae42728e45 100644
--- a/scripts/lib/resulttool/report.py
+++ b/scripts/lib/resulttool/report.py
@@ -143,7 +143,7 @@ def register_commands(subparsers):
                                          group='analysis')
     parser_build.set_defaults(func=report)
     parser_build.add_argument('source_dir',
-                              help='source file/directory that contain the test result files to summarise')
+                              help='source file/directory/URL that contain the test result files to summarise')
     parser_build.add_argument('--branch', '-B', default='master', help="Branch to find commit in")
     parser_build.add_argument('--commit', help="Revision to report")
     parser_build.add_argument('-t', '--tag', default='',
diff --git a/scripts/lib/resulttool/resultutils.py b/scripts/lib/resulttool/resultutils.py
index ad40ac8499d..aab312dd172 100644
--- a/scripts/lib/resulttool/resultutils.py
+++ b/scripts/lib/resulttool/resultutils.py
@@ -16,6 +16,8 @@ import os
 import json
 import scriptpath
 import copy
+import urllib
+import posixpath
 scriptpath.add_oe_lib_path()
 
 flatten_map = {
@@ -40,20 +42,33 @@ store_map = {
     "manual": ['TEST_TYPE', 'TEST_MODULE', 'MACHINE', 'IMAGE_BASENAME']
 }
 
+def is_url(p):
+    """
+    Helper for determining if the given path is a URL
+    """
+    return p.startswith('http://') or p.startswith('https://')
+
 #
 # Load the json file and append the results data into the provided results dict
 #
 def append_resultsdata(results, f, configmap=store_map):
     if type(f) is str:
-        with open(f, "r") as filedata:
-            data = json.load(filedata)
+        if is_url(f):
+            with urllib.request.urlopen(f) as response:
+                data = json.loads(response.read().decode('utf-8'))
+            url = urllib.parse.urlparse(f)
+            testseries = posixpath.basename(posixpath.dirname(url.path))
+        else:
+            with open(f, "r") as filedata:
+                data = json.load(filedata)
+            testseries = os.path.basename(os.path.dirname(f))
     else:
         data = f
     for res in data:
         if "configuration" not in data[res] or "result" not in data[res]:
             raise ValueError("Test results data without configuration or result section?")
         if "TESTSERIES" not in data[res]["configuration"]:
-            data[res]["configuration"]["TESTSERIES"] = os.path.basename(os.path.dirname(f))
+            data[res]["configuration"]["TESTSERIES"] = testseries
         testtype = data[res]["configuration"].get("TEST_TYPE")
         if testtype not in configmap:
             raise ValueError("Unknown test type %s" % testtype)
@@ -69,7 +84,7 @@ def append_resultsdata(results, f, configmap=store_map):
 #
 def load_resultsdata(source, configmap=store_map):
     results = {}
-    if os.path.isfile(source):
+    if is_url(source) or os.path.isfile(source):
         append_resultsdata(results, source, configmap)
         return results
     for root, dirs, files in os.walk(source):
diff --git a/scripts/lib/resulttool/store.py b/scripts/lib/resulttool/store.py
index e4a08075287..acdfbd94fdf 100644
--- a/scripts/lib/resulttool/store.py
+++ b/scripts/lib/resulttool/store.py
@@ -29,7 +29,7 @@ def store(args, logger):
     try:
         results = {}
         logger.info('Reading files from %s' % args.source)
-        if os.path.isfile(args.source):
+        if resultutils.is_url(args.source) or os.path.isfile(args.source):
             resultutils.append_resultsdata(results, args.source)
         else:
             for root, dirs,  files in os.walk(args.source):
@@ -92,7 +92,7 @@ def register_commands(subparsers):
                                          group='setup')
     parser_build.set_defaults(func=store)
     parser_build.add_argument('source',
-                              help='source file or directory that contain the test result files to be stored')
+                              help='source file/directory/URL that contain the test result files to be stored')
     parser_build.add_argument('git_dir',
                               help='the location of the git repository to store the results in')
     parser_build.add_argument('-a', '--all', action='store_true',
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] resulttool: Add log subcommand
  2019-04-19  2:57 [PATCH 0/2] resulttool improvements Joshua Watt
  2019-04-19  2:57 ` [PATCH 1/2] resulttool: Load results from URL Joshua Watt
@ 2019-04-19  2:57 ` Joshua Watt
  2019-04-19  5:05   ` akuster808
  1 sibling, 1 reply; 5+ messages in thread
From: Joshua Watt @ 2019-04-19  2:57 UTC (permalink / raw)
  To: openembedded-core

Adds a subcommand for dumping various logs from test results

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 scripts/lib/resulttool/log.py        | 56 ++++++++++++++++++++++++++++
 scripts/lib/resulttool/regression.py |  2 +-
 scripts/resulttool                   |  2 +
 3 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 scripts/lib/resulttool/log.py

diff --git a/scripts/lib/resulttool/log.py b/scripts/lib/resulttool/log.py
new file mode 100644
index 00000000000..5584f2d0a99
--- /dev/null
+++ b/scripts/lib/resulttool/log.py
@@ -0,0 +1,56 @@
+# resulttool - Show logs
+#
+# Copyright (c) 2019 Garmin International
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+import resulttool.resultutils as resultutils
+
+def show_ptest(result, ptest, logger):
+    if 'ptestresult.sections' in result:
+        if ptest in result['ptestresult.sections'] and 'log' in result['ptestresult.sections'][ptest]:
+            print(result['ptestresult.sections'][ptest]['log'])
+            return 0
+
+    print("ptest '%s' not found" % ptest)
+    return 1
+
+def log(args, logger):
+    results = resultutils.load_resultsdata(args.source)
+    for path in results:
+        for res in results[path]:
+            if 'result' not in results[path][res]:
+                continue
+            r = results[path][res]['result']
+
+            if args.raw:
+                if 'ptestresult.rawlogs' in r:
+                    print(r['ptestresult.rawlogs']['log'])
+                else:
+                    print('Raw logs not found')
+                    return 1
+
+            for ptest in args.ptest:
+                if not show_ptest(r, ptest, logger):
+                    return 1
+
+def register_commands(subparsers):
+    """Register subcommands from this plugin"""
+    parser = subparsers.add_parser('log', help='show logs',
+                                         description='show the logs from test results',
+                                         group='analysis')
+    parser.set_defaults(func=log)
+    parser.add_argument('source',
+            help='the results file/directory/URL to import')
+    parser.add_argument('--ptest', action='append', default=[],
+            help='show logs for a ptest')
+    parser.add_argument('--raw', action='store_true',
+            help='show raw logs')
+
diff --git a/scripts/lib/resulttool/regression.py b/scripts/lib/resulttool/regression.py
index aecb9da9ce5..fa90ab1e522 100644
--- a/scripts/lib/resulttool/regression.py
+++ b/scripts/lib/resulttool/regression.py
@@ -64,7 +64,7 @@ def regression_common(args, logger, base_results, target_results):
         if a in target_results:
             base = list(base_results[a].keys())
             target = list(target_results[a].keys())
-            # We may have multiple base/targets which are for different configurations. Start by 
+            # We may have multiple base/targets which are for different configurations. Start by
             # removing any pairs which match
             for c in base.copy():
                 for b in target.copy():
diff --git a/scripts/resulttool b/scripts/resulttool
index 18ac1019236..9477667a870 100755
--- a/scripts/resulttool
+++ b/scripts/resulttool
@@ -49,6 +49,7 @@ import resulttool.store
 import resulttool.regression
 import resulttool.report
 import resulttool.manualexecution
+import resulttool.log
 logger = scriptutils.logger_create('resulttool')
 
 def main():
@@ -66,6 +67,7 @@ def main():
     subparsers.add_subparser_group('analysis', 'analysis', 100)
     resulttool.regression.register_commands(subparsers)
     resulttool.report.register_commands(subparsers)
+    resulttool.log.register_commands(subparsers)
 
     args = parser.parse_args()
     if args.debug:
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] resulttool: Add log subcommand
  2019-04-19  2:57 ` [PATCH 2/2] resulttool: Add log subcommand Joshua Watt
@ 2019-04-19  5:05   ` akuster808
  2019-04-19 13:14     ` Joshua Watt
  0 siblings, 1 reply; 5+ messages in thread
From: akuster808 @ 2019-04-19  5:05 UTC (permalink / raw)
  To: Joshua Watt, openembedded-core



On 4/18/19 7:57 PM, Joshua Watt wrote:
> Adds a subcommand for dumping various logs from test results
>
> Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
> ---
>  scripts/lib/resulttool/log.py        | 56 ++++++++++++++++++++++++++++
>  scripts/lib/resulttool/regression.py |  2 +-
>  scripts/resulttool                   |  2 +
>  3 files changed, 59 insertions(+), 1 deletion(-)
>  create mode 100644 scripts/lib/resulttool/log.py
>
> diff --git a/scripts/lib/resulttool/log.py b/scripts/lib/resulttool/log.py
> new file mode 100644
> index 00000000000..5584f2d0a99
> --- /dev/null
> +++ b/scripts/lib/resulttool/log.py
> @@ -0,0 +1,56 @@
> +# resulttool - Show logs
> +#
> +# Copyright (c) 2019 Garmin International
> +#
> +# This program is free software; you can redistribute it and/or modify it
> +# under the terms and conditions of the GNU General Public License,
> +# version 2, as published by the Free Software Foundation.
> +#
> +# This program is distributed in the hope it will be useful, but WITHOUT
> +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> +# more details.
> +#
> +import resulttool.resultutils as resultutils
> +
> +def show_ptest(result, ptest, logger):
> +    if 'ptestresult.sections' in result:
> +        if ptest in result['ptestresult.sections'] and 'log' in result['ptestresult.sections'][ptest]:
> +            print(result['ptestresult.sections'][ptest]['log'])
> +            return 0
> +
> +    print("ptest '%s' not found" % ptest)
> +    return 1
> +
> +def log(args, logger):
> +    results = resultutils.load_resultsdata(args.source)
> +    for path in results:
> +        for res in results[path]:
> +            if 'result' not in results[path][res]:
> +                continue
> +            r = results[path][res]['result']
> +
> +            if args.raw:
> +                if 'ptestresult.rawlogs' in r:
> +                    print(r['ptestresult.rawlogs']['log'])
> +                else:
> +                    print('Raw logs not found')
> +                    return 1
> +
> +            for ptest in args.ptest:
> +                if not show_ptest(r, ptest, logger):
> +                    return 1
> +
> +def register_commands(subparsers):
> +    """Register subcommands from this plugin"""
> +    parser = subparsers.add_parser('log', help='show logs',
> +                                         description='show the logs from test results',
> +                                         group='analysis')
> +    parser.set_defaults(func=log)
> +    parser.add_argument('source',
> +            help='the results file/directory/URL to import')
> +    parser.add_argument('--ptest', action='append', default=[],
> +            help='show logs for a ptest')
> +    parser.add_argument('--raw', action='store_true',
> +            help='show raw logs')
> +
> diff --git a/scripts/lib/resulttool/regression.py b/scripts/lib/resulttool/regression.py
> index aecb9da9ce5..fa90ab1e522 100644
> --- a/scripts/lib/resulttool/regression.py
> +++ b/scripts/lib/resulttool/regression.py
> @@ -64,7 +64,7 @@ def regression_common(args, logger, base_results, target_results):
>          if a in target_results:
>              base = list(base_results[a].keys())
>              target = list(target_results[a].keys())
> -            # We may have multiple base/targets which are for different configurations. Start by 
> +            # We may have multiple base/targets which are for different configurations. Start by
This change looks the same to me so what am I missing?

- Armin
>              # removing any pairs which match
>              for c in base.copy():
>                  for b in target.copy():
> diff --git a/scripts/resulttool b/scripts/resulttool
> index 18ac1019236..9477667a870 100755
> --- a/scripts/resulttool
> +++ b/scripts/resulttool
> @@ -49,6 +49,7 @@ import resulttool.store
>  import resulttool.regression
>  import resulttool.report
>  import resulttool.manualexecution
> +import resulttool.log
>  logger = scriptutils.logger_create('resulttool')
>  
>  def main():
> @@ -66,6 +67,7 @@ def main():
>      subparsers.add_subparser_group('analysis', 'analysis', 100)
>      resulttool.regression.register_commands(subparsers)
>      resulttool.report.register_commands(subparsers)
> +    resulttool.log.register_commands(subparsers)
>  
>      args = parser.parse_args()
>      if args.debug:




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] resulttool: Add log subcommand
  2019-04-19  5:05   ` akuster808
@ 2019-04-19 13:14     ` Joshua Watt
  0 siblings, 0 replies; 5+ messages in thread
From: Joshua Watt @ 2019-04-19 13:14 UTC (permalink / raw)
  To: Armin Kuster; +Cc: OE-core

[-- Attachment #1: Type: text/plain, Size: 4989 bytes --]

On Fri, Apr 19, 2019, 12:05 AM akuster808 <akuster808@gmail.com> wrote:

>
>
> On 4/18/19 7:57 PM, Joshua Watt wrote:
> > Adds a subcommand for dumping various logs from test results
> >
> > Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
> > ---
> >  scripts/lib/resulttool/log.py        | 56 ++++++++++++++++++++++++++++
> >  scripts/lib/resulttool/regression.py |  2 +-
> >  scripts/resulttool                   |  2 +
> >  3 files changed, 59 insertions(+), 1 deletion(-)
> >  create mode 100644 scripts/lib/resulttool/log.py
> >
> > diff --git a/scripts/lib/resulttool/log.py
> b/scripts/lib/resulttool/log.py
> > new file mode 100644
> > index 00000000000..5584f2d0a99
> > --- /dev/null
> > +++ b/scripts/lib/resulttool/log.py
> > @@ -0,0 +1,56 @@
> > +# resulttool - Show logs
> > +#
> > +# Copyright (c) 2019 Garmin International
> > +#
> > +# This program is free software; you can redistribute it and/or modify
> it
> > +# under the terms and conditions of the GNU General Public License,
> > +# version 2, as published by the Free Software Foundation.
> > +#
> > +# This program is distributed in the hope it will be useful, but WITHOUT
> > +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> for
> > +# more details.
> > +#
> > +import resulttool.resultutils as resultutils
> > +
> > +def show_ptest(result, ptest, logger):
> > +    if 'ptestresult.sections' in result:
> > +        if ptest in result['ptestresult.sections'] and 'log' in
> result['ptestresult.sections'][ptest]:
> > +            print(result['ptestresult.sections'][ptest]['log'])
> > +            return 0
> > +
> > +    print("ptest '%s' not found" % ptest)
> > +    return 1
> > +
> > +def log(args, logger):
> > +    results = resultutils.load_resultsdata(args.source)
> > +    for path in results:
> > +        for res in results[path]:
> > +            if 'result' not in results[path][res]:
> > +                continue
> > +            r = results[path][res]['result']
> > +
> > +            if args.raw:
> > +                if 'ptestresult.rawlogs' in r:
> > +                    print(r['ptestresult.rawlogs']['log'])
> > +                else:
> > +                    print('Raw logs not found')
> > +                    return 1
> > +
> > +            for ptest in args.ptest:
> > +                if not show_ptest(r, ptest, logger):
> > +                    return 1
> > +
> > +def register_commands(subparsers):
> > +    """Register subcommands from this plugin"""
> > +    parser = subparsers.add_parser('log', help='show logs',
> > +                                         description='show the logs
> from test results',
> > +                                         group='analysis')
> > +    parser.set_defaults(func=log)
> > +    parser.add_argument('source',
> > +            help='the results file/directory/URL to import')
> > +    parser.add_argument('--ptest', action='append', default=[],
> > +            help='show logs for a ptest')
> > +    parser.add_argument('--raw', action='store_true',
> > +            help='show raw logs')
> > +
> > diff --git a/scripts/lib/resulttool/regression.py
> b/scripts/lib/resulttool/regression.py
> > index aecb9da9ce5..fa90ab1e522 100644
> > --- a/scripts/lib/resulttool/regression.py
> > +++ b/scripts/lib/resulttool/regression.py
> > @@ -64,7 +64,7 @@ def regression_common(args, logger, base_results,
> target_results):
> >          if a in target_results:
> >              base = list(base_results[a].keys())
> >              target = list(target_results[a].keys())
> > -            # We may have multiple base/targets which are for different
> configurations. Start by
> > +            # We may have multiple base/targets which are for different
> configurations. Start by
> This change looks the same to me so what am I missing?
>

It stripped off trailing whitespace and I missed removing it when staging.

- Armin
> >              # removing any pairs which match
> >              for c in base.copy():
> >                  for b in target.copy():
> > diff --git a/scripts/resulttool b/scripts/resulttool
> > index 18ac1019236..9477667a870 100755
> > --- a/scripts/resulttool
> > +++ b/scripts/resulttool
> > @@ -49,6 +49,7 @@ import resulttool.store
> >  import resulttool.regression
> >  import resulttool.report
> >  import resulttool.manualexecution
> > +import resulttool.log
> >  logger = scriptutils.logger_create('resulttool')
> >
> >  def main():
> > @@ -66,6 +67,7 @@ def main():
> >      subparsers.add_subparser_group('analysis', 'analysis', 100)
> >      resulttool.regression.register_commands(subparsers)
> >      resulttool.report.register_commands(subparsers)
> > +    resulttool.log.register_commands(subparsers)
> >
> >      args = parser.parse_args()
> >      if args.debug:
>
>
>

[-- Attachment #2: Type: text/html, Size: 6666 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-04-19 13:15 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-04-19  2:57 [PATCH 0/2] resulttool improvements Joshua Watt
2019-04-19  2:57 ` [PATCH 1/2] resulttool: Load results from URL Joshua Watt
2019-04-19  2:57 ` [PATCH 2/2] resulttool: Add log subcommand Joshua Watt
2019-04-19  5:05   ` akuster808
2019-04-19 13:14     ` Joshua Watt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox