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