poky: refresh thud: b904775c2b..7c76c5d78b

Update poky to thud HEAD.

Adam Trhon (1):
      icecc-env: don't raise error when icecc not installed

Alexander Kanavin (1):
      openssl10: update to 1.0.2q

Armin Kuster (1):
      perl: add testdepends for ssh

Bruce Ashfield (2):
      linux-yocto/4.18: update to v4.18.26
      linux-yocto/4.18: update to v4.18.27

Changqing Li (1):
      checklayer: generate locked-sigs.inc under builddir

Dan Dedrick (2):
      devtool: remove duplicate overrides
      devtool: improve git repo checks before check_commits logic

Daniel Ammann (1):
      ref-manual: Typo found and fixed.

Douglas Royds (2):
      openssl ptest: Strip build host paths from configdata.pm
      openssl: Strip perl version from installed ptest configdata.pm file

Dustin Bain (1):
      busybox: update to 1.29.3

Jan Kiszka (1):
      oe-git-proxy: Avoid resolving NO_PROXY against local files

Jens Rehsack (1):
      avahi: avoid depending on skipped package

Jonas Bonn (1):
      keymaps: tighten package write dependency

Kai Kang (1):
      selftest/wic: update test case test_qemu

Khem Raj (3):
      openssl10: Fix mutliple include assumptions for bn.h in opensslconf.h
      send-error-report: Use https instead of http protocol
      multilib_header_wrapper.h: Use #pragma once

Leonardo Augusto (1):
      scripts/lib/wic/engine: Fix cp's target path for ext* filesystems

Liu Haitao (1):
      iw: fix parsing of WEP keys

Mingli Yu (1):
      logrotate.py: restore /etc/logrotate.d/wtmp

Otavio Salvador (1):
      linux-firmware: Bump to 710963f revision

Ovidiu Panait (1):
      ghostscript: Fix CVE-2019-6116

Peter Kjellerstedt (1):
      libaio: Extend to native

Richard Purdie (23):
      package: Add pkg_postinst_ontarget to PACKAGEVARS
      oeqa/runtime/ptest: Avoid traceback for tests with no section
      oeqa/utils/logparser: Simplify ptest log parsing code
      oeqa/logparser: Further simplification/clarification
      oeqa/logparser: Reform the ptest results parser
      oeqa/utils/logparser: Add in support for duration, exitcode and logs by section
      oeqa/logparser: Improve results handling
      oeqa/logparser: Various misc cleanups
      oeqa/runtime/ptest: Ensure OOM errors are logged
      scripts/contrib/build-perf-test-wrapper.sh: Improve interaction with autobuilder automation
      scripts/contrib/build-perf-test.sh: Remove it
      oe-build-perf-report: Allow branch without hostname
      oe-build-perf-report: Allow commits from different branches
      oe-build-perf-report: Improve branch comparision handling
      oe-build-perf-report: Fix missing buildstats comparisions
      wic/engine: Fix missing parted autobuilder failures
      lib/buildstats: Improve error message
      scripts/oe-git-archive: Separate out functionality to library function
      oe-build-perf-report/gitarchive: Move common useful functions to library
      bitbake: runqueue: Fix dependency loop analysis 'hangs'
      bitbake: runqueue: Filter out multiconfig dependencies from BB_TASKDEPDATA
      bitbake: siggen: Fix multiconfig corner case
      bitbake: cooker: Tweak multiconfig dependency resolution

Robert Yang (5):
      bluez5: Fix a race issue for tools
      yocto-check-layer-wrapper: Fix path for oe-init-build-env
      checklayer: Avoid adding the layer if it is already present
      runqemu: Let qemuparams override default settings
      runqemu: Make QB_MEM easier to set

Ross Burton (3):
      e2fsprogs: fix file system generation with large files
      linux-firmware: recommend split up packages
      linux-firmware: split out liquidio firmware

Scott Rifenbark (2):
      poky.ent: Updated "meta-intel" version to "10.1"
      overview-manual, mega-manual: Updated Package Feeds diagram

Serhey Popovych (1):
      openssl: Skip assembler optimized code for powerpc64 with musl

William Bourque (1):
      wic/engine.py: Load paths from PATH environment variable

Xulin Sun (1):
      openssl: fix multilib file install conflicts

Zheng Ruoqin (1):
      mdadm: add init and service scripts

Change-Id: Ib14c2fb69d25d84aa3d4bf0a6715bba57d1eb900
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
diff --git a/poky/meta/lib/oeqa/utils/logparser.py b/poky/meta/lib/oeqa/utils/logparser.py
index 0670627..32fde14 100644
--- a/poky/meta/lib/oeqa/utils/logparser.py
+++ b/poky/meta/lib/oeqa/utils/logparser.py
@@ -3,124 +3,86 @@
 import sys
 import os
 import re
-from . import ftools
-
 
 # A parser that can be used to identify weather a line is a test result or a section statement.
-class Lparser(object):
-
-    def __init__(self, test_0_pass_regex, test_0_fail_regex, test_0_skip_regex, section_0_begin_regex=None, section_0_end_regex=None, **kwargs):
-        # Initialize the arguments dictionary
-        if kwargs:
-            self.args = kwargs
-        else:
-            self.args = {}
-
-        # Add the default args to the dictionary
-        self.args['test_0_pass_regex'] = test_0_pass_regex
-        self.args['test_0_fail_regex'] = test_0_fail_regex
-        self.args['test_0_skip_regex'] = test_0_skip_regex
-        if section_0_begin_regex:
-            self.args['section_0_begin_regex'] = section_0_begin_regex
-        if section_0_end_regex:
-            self.args['section_0_end_regex'] = section_0_end_regex
-
-        self.test_possible_status = ['pass', 'fail', 'error', 'skip']
-        self.section_possible_status = ['begin', 'end']
-
-        self.initialized = False
-
-
-    # Initialize the parser with the current configuration
-    def init(self):
-
-        # extra arguments can be added by the user to define new test and section categories. They must follow a pre-defined pattern: <type>_<category_name>_<status>_regex
-        self.test_argument_pattern = "^test_(.+?)_(%s)_regex" % '|'.join(map(str, self.test_possible_status))
-        self.section_argument_pattern = "^section_(.+?)_(%s)_regex" % '|'.join(map(str, self.section_possible_status))
-
-        # Initialize the test and section regex dictionaries
-        self.test_regex = {}
-        self.section_regex ={}
-
-        for arg, value in self.args.items():
-            if not value:
-                raise Exception('The value of provided argument %s is %s. Should have a valid value.' % (key, value))
-            is_test =  re.search(self.test_argument_pattern, arg)
-            is_section = re.search(self.section_argument_pattern, arg)
-            if is_test:
-                if not is_test.group(1) in self.test_regex:
-                    self.test_regex[is_test.group(1)] = {}
-                self.test_regex[is_test.group(1)][is_test.group(2)] = re.compile(value)
-            elif is_section:
-                if not is_section.group(1) in self.section_regex:
-                    self.section_regex[is_section.group(1)] = {}
-                self.section_regex[is_section.group(1)][is_section.group(2)] = re.compile(value)
-            else:
-                # TODO: Make these call a traceback instead of a simple exception..
-                raise Exception("The provided argument name does not correspond to any valid type. Please give one of the following types:\nfor tests: %s\nfor sections: %s" % (self.test_argument_pattern, self.section_argument_pattern))
-
-        self.initialized = True
-
-    # Parse a line and return a tuple containing the type of result (test/section) and its category, status and name
-    def parse_line(self, line):
-        if not self.initialized:
-            raise Exception("The parser is not initialized..")
-
-        for test_category, test_status_list in self.test_regex.items():
-            for test_status, status_regex in test_status_list.items():
-                test_name = status_regex.search(line)
-                if test_name:
-                    return ['test', test_category, test_status, test_name.group(1)]
-
-        for section_category, section_status_list in self.section_regex.items():
-            for section_status, status_regex in section_status_list.items():
-                section_name = status_regex.search(line)
-                if section_name:
-                    return ['section', section_category, section_status, section_name.group(1)]
-        return None
-
-
-class Result(object):
-
+class PtestParser(object):
     def __init__(self):
-        self.result_dict = {}
+        self.results = {}
+        self.sections = {}
 
-    def store(self, section, test, status):
-        if not section in self.result_dict:
-            self.result_dict[section] = []
+    def parse(self, logfile):
+        test_regex = {}
+        test_regex['PASSED'] = re.compile(r"^PASS:(.+)")
+        test_regex['FAILED'] = re.compile(r"^FAIL:(.+)")
+        test_regex['SKIPPED'] = re.compile(r"^SKIP:(.+)")
 
-        self.result_dict[section].append((test, status))
+        section_regex = {}
+        section_regex['begin'] = re.compile(r"^BEGIN: .*/(.+)/ptest")
+        section_regex['end'] = re.compile(r"^END: .*/(.+)/ptest")
+        section_regex['duration'] = re.compile(r"^DURATION: (.+)")
+        section_regex['exitcode'] = re.compile(r"^ERROR: Exit status is (.+)")
+        section_regex['timeout'] = re.compile(r"^TIMEOUT: .*/(.+)/ptest")
 
-    # sort tests by the test name(the first element of the tuple), for each section. This can be helpful when using git to diff for changes by making sure they are always in the same order.
-    def sort_tests(self):
-        for package in self.result_dict:
-            sorted_results = sorted(self.result_dict[package], key=lambda tup: tup[0])
-            self.result_dict[package] = sorted_results
+        def newsection():
+            return { 'name': "No-section", 'log': "" }
+
+        current_section = newsection()
+
+        with open(logfile, errors='replace') as f:
+            for line in f:
+                result = section_regex['begin'].search(line)
+                if result:
+                    current_section['name'] = result.group(1)
+                    continue
+
+                result = section_regex['end'].search(line)
+                if result:
+                    if current_section['name'] != result.group(1):
+                        bb.warn("Ptest END log section mismatch %s vs. %s" % (current_section['name'], result.group(1)))
+                    if current_section['name'] in self.sections:
+                        bb.warn("Ptest duplicate section for %s" % (current_section['name']))
+                    self.sections[current_section['name']] = current_section
+                    del self.sections[current_section['name']]['name']
+                    current_section = newsection()
+                    continue
+
+                result = section_regex['timeout'].search(line)
+                if result:
+                    if current_section['name'] != result.group(1):
+                        bb.warn("Ptest TIMEOUT log section mismatch %s vs. %s" % (current_section['name'], result.group(1)))
+                    current_section['timeout'] = True
+                    continue
+
+                for t in ['duration', 'exitcode']:
+                    result = section_regex[t].search(line)
+                    if result:
+                        current_section[t] = result.group(1)
+                        continue
+
+                current_section['log'] = current_section['log'] + line 
+
+                for t in test_regex:
+                    result = test_regex[t].search(line)
+                    if result:
+                        if current_section['name'] not in self.results:
+                            self.results[current_section['name']] = {}
+                        self.results[current_section['name']][result.group(1)] = t
+
+        return self.results, self.sections
 
     # Log the results as files. The file name is the section name and the contents are the tests in that section.
-    def log_as_files(self, target_dir, test_status):
-        status_regex = re.compile('|'.join(map(str, test_status)))
-        if not type(test_status) == type([]):
-            raise Exception("test_status should be a list. Got " + str(test_status) + " instead.")
+    def results_as_files(self, target_dir):
         if not os.path.exists(target_dir):
             raise Exception("Target directory does not exist: %s" % target_dir)
 
-        for section, test_results in self.result_dict.items():
-            prefix = ''
-            for x in test_status:
-                prefix +=x+'.'
+        for section in self.results:
+            prefix = 'No-section'
             if section:
-                prefix += section
+                prefix = section
             section_file = os.path.join(target_dir, prefix)
             # purge the file contents if it exists
-            open(section_file, 'w').close()
-            for test_result in test_results:
-                (test_name, status) = test_result
-                # we log only the tests with status in the test_status list
-                match_status = status_regex.search(status)
-                if match_status:
-                    ftools.append_file(section_file, status + ": " + test_name)
+            with open(section_file, 'w') as f:
+                for test_name in sorted(self.results[section]):
+                    status = self.results[section][test_name]
+                    f.write(status + ": " + test_name + "\n")
 
-    # Not yet implemented!
-    def log_to_lava(self):
-        pass