From 00e122a7b3a839f5ce8b819cb1bfe92cf3781eda Mon Sep 17 00:00:00 2001 From: Brad Bishop Date: Sat, 5 Oct 2019 11:10:57 -0400 Subject: poky: subtree update:81f9e815d3..03d4d9d68f MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adrian Bunk (1): json-c: Don't --enable-rdrand Alessio Igor Bogani (2): wic: Using the right rootfs size during prepare_rootfs rootfs-postcommands: Avoid use of an hard-coded value Alexander Kanavin (1): binutils: drop UPSTREAM_VERSION_UNKNOWN Alexandre Bard (1): systemd: Expose resolv-conf alternative only when resolved is built Andre McCurdy (1): ffmpeg: enable more verbose build logs André Draszik (4): ruby: drop long-merged CVE patches ruby: configure mis-detects isnan/isinf on musl ruby: fix non-IPv6 support packagegroup: fix a comment regarding PACKAGE_ARCH Bruce Ashfield (6): linux-yocto/5.2: update to v5.2.13 linux-yocto/4.19: update to v4.19.72 linux-yocto/5.2: update to v5.2.14 linux-yocto/5.2: update to v5.2.16 linux-yocto/5.2: update to v5.2.17 yocto-bsps: update to v5.2.17 Böszörményi Zoltán via Openembedded-core (1): classes/image-live.bbclass: Don't hardcode cpio.gz Changqing Li (2): devtool.py: change to do clean before remove-layer devtool.py: fix buildclean test Chen Qi (1): systemd: fix NFS regression Dan Tran (1): unzip: Fix CVE-2019-13232 David Reyna (2): bitbake: toaster: issues in import layer when clicking 'add layer' bitbake: toaster: improve warnings when adding dependency to packages Diego Rondini (2): initramfs-framework: fix var name initramfs-framework: support PARTLABEL option Douglas Royds (1): icecc: Don't use icecc when INHIBIT_DEFAULT_DEPS is set He Zhe (1): ltp: Fix hang of cve test cases Heiko Schocher (1): kernel.fitimage.bbclass: remove ramdisk_ctype Jacob Kroon (1): bitbake: tests/data: Test combinations of _append together with override Joe Slater (1): bash-completion: add image feature Jonathan Marler (1): package: Multiple shlib_providers for the same file should error Joshua Watt (8): classes/reproducible_build: Move SDE deploy to another directory oeqa: Test multiconfig parsing bitbake: cookerdata: Add mc conffiles hashes to cache hash bitbake: hashserve: Add missing import bitbake: siggen: Fix attribute error when hashserver fails bitbake: hashserv: Don't daemonize server process local.conf.sample: Add Hash Equivalence classes/reproducible_build: Create SDE destination Khem Raj (7): musl: Fix riscv64 CAS functions qemuriscv: Do not blacklist clang anymore sdk: Install nativesdk locales for all TCLIBC variants strace: Upgrade to 5.3 packagegroups: All groups are not allarch musl: Fix __riscv_mc* containers to match glibc core-image-sato-sdk-ptest: Remove valgrind ptests for riscv Konrad Scherer (1): gen-lockedsig-cache: Replace glob lookup with hash to filename lookup Lei Maohui (1): bluez5: update patch to fix do_patch error when PATCHTOOL = "patch". Li Zhou (1): shadow: use relaxed usernames for all Limeng (1): u-boot: add CVE patches for u-boot Nathan Rossi (2): oeqa/core/utils/concurrencytest.py: Handle exceptions and details oeqa/core/case.py: Encode binary data of log Niclas Svensson (1): devtool: finish: Keep patches ordered when updating bbappend Otavio Salvador (1): mesa: Add freedreno PACKAGECONFIG option Peter Kjellerstedt (3): systemd: Make it build with hwdb disabled devtool: finish: Add suppport for the --no-clean option lib/oe/lsb: Make sure the distro ID is always lowercased Randy MacLeod (1): ffmpeg: update from 4.2 to 4.2.1 Richard Purdie (17): Revert "meta-extsdk: Either an sstate task is a proper task or it isn't" sstatesig: Fix hash equivlanency locked signature issues oeqa/selftest/signing: Fix for hash equivlance server lib/sstatesig: Fix class inheritance problems populate_sdk_ext: Fix for hash equiv bitbake: runqueue: Fix task migration problems bitbake: siggen: Ensure setscenetasks list is available to worker context bitbake: runqueue: Change task migration behaviour for rerunning setscene tasks bitbake: siggen/runqueue: Fix signature mismatch issues bitbake: siggen: Avoid writing misleading sigdata files bitbake: runqueue: Save unihashes more frequently bitbake: runqueue: Small performance optimisation bitbake: siggen: Remove full path from unitaskhashes keys bitbake: tests/runqueue: Fix hashserve shutdown race base: Improve module import error message sanity.conf: Bump minimum bitbake version bitbake: bitbake: Bump verison 1.43.1 -> 1.43.2 Robert Yang (6): cases/bbtests.py: test_bitbake_g(): Check base-files rather than busybox expect: Fix configure error for nativesdk net-tools: Fix installed-vs-shipped for nativesdk expect: Fix buffer overflow error when build in long path apr: Check for libtoolize rather than libtool lttng-ust: Fix for --enable-python-agent Ross Burton (12): oeqa/selftest/reproducible: test ipkgs too distcc: clean up the UI install logic distcc: use --enable-tcp-insecure instead of --make-me-a-botnet distcc: split into client and server packages json-c: clean up recipe json-c: use GitHub for upstream release checking bitbake: fetch2/git: refactor check for git-lfs command bitbake: tests/fetch: add test case for git-lfs handling python3: move runpy to core pango: fix the failing testiter test case opkg: remove redundant systemd inherit lttng-ust: update patch Signed-off-by Trevor Gamblin (5): python3-subunit: ensure runtime dependencies are present python3-pip: ensure pickle is installed lighttpd: remove fam as a PACKAGECONFIG option tiff: fix CVE-2019-14973 opkg: remove pathfinder PACKAGECONFIG option Wang Quanyang (1): kexec-tools: fix arm kexec failure for __NR_kexec_file_load Yi Zhao (1): python: add tk-lib as runtime dependency for python-tkinter Change-Id: I0570125d49f7e4bc3bbf70508cbfd7e10bdbc032 Signed-off-by: Brad Bishop --- poky/meta/lib/oeqa/core/case.py | 4 +- poky/meta/lib/oeqa/core/utils/concurrencytest.py | 31 +++++++++------- poky/meta/lib/oeqa/selftest/case.py | 17 ++++++--- poky/meta/lib/oeqa/selftest/cases/bbtests.py | 5 ++- poky/meta/lib/oeqa/selftest/cases/devtool.py | 15 ++++---- poky/meta/lib/oeqa/selftest/cases/multiconfig.py | 45 ++++++++++++++++++----- poky/meta/lib/oeqa/selftest/cases/reproducible.py | 2 +- poky/meta/lib/oeqa/selftest/cases/signing.py | 7 +++- 8 files changed, 84 insertions(+), 42 deletions(-) (limited to 'poky/meta/lib/oeqa') diff --git a/poky/meta/lib/oeqa/core/case.py b/poky/meta/lib/oeqa/core/case.py index 180635ac6..aae451fef 100644 --- a/poky/meta/lib/oeqa/core/case.py +++ b/poky/meta/lib/oeqa/core/case.py @@ -59,7 +59,7 @@ class OEPTestResultTestCase: """ @staticmethod def _compress_log(log): - logdata = log.encode("utf-8") + logdata = log.encode("utf-8") if isinstance(log, str) else log logdata = zlib.compress(logdata) logdata = base64.b64encode(logdata).decode("utf-8") return {"compressed" : logdata} @@ -80,7 +80,7 @@ class OEPTestResultTestCase: if log is not None: sections[section]["log"] = self._compress_log(log) elif logfile is not None: - with open(logfile, "r") as f: + with open(logfile, "rb") as f: sections[section]["log"] = self._compress_log(f.read()) if duration is not None: diff --git a/poky/meta/lib/oeqa/core/utils/concurrencytest.py b/poky/meta/lib/oeqa/core/utils/concurrencytest.py index 6293cf94e..0f7b3dcc1 100644 --- a/poky/meta/lib/oeqa/core/utils/concurrencytest.py +++ b/poky/meta/lib/oeqa/core/utils/concurrencytest.py @@ -78,29 +78,29 @@ class ProxyTestResult: def __init__(self, target): self.result = target - def _addResult(self, method, test, *args, **kwargs): + def _addResult(self, method, test, *args, exception = False, **kwargs): return method(test, *args, **kwargs) - def addError(self, test, *args, **kwargs): - self._addResult(self.result.addError, test, *args, **kwargs) + def addError(self, test, err = None, **kwargs): + self._addResult(self.result.addError, test, err, exception = True, **kwargs) - def addFailure(self, test, *args, **kwargs): - self._addResult(self.result.addFailure, test, *args, **kwargs) + def addFailure(self, test, err = None, **kwargs): + self._addResult(self.result.addFailure, test, err, exception = True, **kwargs) - def addSuccess(self, test, *args, **kwargs): - self._addResult(self.result.addSuccess, test, *args, **kwargs) + def addSuccess(self, test, **kwargs): + self._addResult(self.result.addSuccess, test, **kwargs) - def addExpectedFailure(self, test, *args, **kwargs): - self._addResult(self.result.addExpectedFailure, test, *args, **kwargs) + def addExpectedFailure(self, test, err = None, **kwargs): + self._addResult(self.result.addExpectedFailure, test, err, exception = True, **kwargs) - def addUnexpectedSuccess(self, test, *args, **kwargs): - self._addResult(self.result.addUnexpectedSuccess, test, *args, **kwargs) + def addUnexpectedSuccess(self, test, **kwargs): + self._addResult(self.result.addUnexpectedSuccess, test, **kwargs) def __getattr__(self, attr): return getattr(self.result, attr) class ExtraResultsDecoderTestResult(ProxyTestResult): - def _addResult(self, method, test, *args, **kwargs): + def _addResult(self, method, test, *args, exception = False, **kwargs): if "details" in kwargs and "extraresults" in kwargs["details"]: if isinstance(kwargs["details"]["extraresults"], Content): kwargs = kwargs.copy() @@ -114,7 +114,7 @@ class ExtraResultsDecoderTestResult(ProxyTestResult): return method(test, *args, **kwargs) class ExtraResultsEncoderTestResult(ProxyTestResult): - def _addResult(self, method, test, *args, **kwargs): + def _addResult(self, method, test, *args, exception = False, **kwargs): if hasattr(test, "extraresults"): extras = lambda : [json.dumps(test.extraresults).encode()] kwargs = kwargs.copy() @@ -123,6 +123,11 @@ class ExtraResultsEncoderTestResult(ProxyTestResult): else: kwargs["details"] = kwargs["details"].copy() kwargs["details"]["extraresults"] = Content(ContentType("application", "json", {'charset': 'utf8'}), extras) + # if using details, need to encode any exceptions into the details obj, + # testtools does not handle "err" and "details" together. + if "details" in kwargs and exception and (len(args) >= 1 and args[0] is not None): + kwargs["details"]["traceback"] = testtools.content.TracebackContent(args[0], test) + args = [] return method(test, *args, **kwargs) # diff --git a/poky/meta/lib/oeqa/selftest/case.py b/poky/meta/lib/oeqa/selftest/case.py index d207a0af0..ac3308d8a 100644 --- a/poky/meta/lib/oeqa/selftest/case.py +++ b/poky/meta/lib/oeqa/selftest/case.py @@ -193,13 +193,20 @@ to ensure accurate results.") self.logger.debug("Adding path '%s' to be cleaned up when test is over" % path) self._track_for_cleanup.append(path) - def write_config(self, data): - """Write to /conf/selftest.inc""" + def write_config(self, data, multiconfig=None): + """Write to config file""" + if multiconfig: + multiconfigdir = "%s/conf/multiconfig" % self.builddir + os.makedirs(multiconfigdir, exist_ok=True) + dest_path = '%s/%s.conf' % (multiconfigdir, multiconfig) + self.track_for_cleanup(dest_path) + else: + dest_path = self.testinc_path - self.logger.debug("Writing to: %s\n%s\n" % (self.testinc_path, data)) - ftools.write_file(self.testinc_path, data) + self.logger.debug("Writing to: %s\n%s\n" % (dest_path, data)) + ftools.write_file(dest_path, data) - if self.tc.custommachine and 'MACHINE' in data: + if not multiconfig and self.tc.custommachine and 'MACHINE' in data: machine = get_bb_var('MACHINE') self.logger.warning('MACHINE overridden: %s' % machine) diff --git a/poky/meta/lib/oeqa/selftest/cases/bbtests.py b/poky/meta/lib/oeqa/selftest/cases/bbtests.py index 8e59bafae..9461c7ed1 100644 --- a/poky/meta/lib/oeqa/selftest/cases/bbtests.py +++ b/poky/meta/lib/oeqa/selftest/cases/bbtests.py @@ -118,11 +118,12 @@ class BitbakeTests(OESelftestTestCase): self.assertIn(task, result.output, msg="Couldn't find %s task.") def test_bitbake_g(self): - result = bitbake('-g core-image-minimal') + recipe = 'base-files' + result = bitbake('-g %s' % recipe) for f in ['pn-buildlist', 'task-depends.dot']: self.addCleanup(os.remove, f) self.assertTrue('Task dependencies saved to \'task-depends.dot\'' in result.output, msg = "No task dependency \"task-depends.dot\" file was generated for the given task target. bitbake output: %s" % result.output) - self.assertTrue('busybox' in ftools.read_file(os.path.join(self.builddir, 'task-depends.dot')), msg = "No \"busybox\" dependency found in task-depends.dot file.") + self.assertTrue(recipe in ftools.read_file(os.path.join(self.builddir, 'task-depends.dot')), msg = "No \"%s\" dependency found in task-depends.dot file." % recipe) def test_image_manifest(self): bitbake('core-image-minimal') diff --git a/poky/meta/lib/oeqa/selftest/cases/devtool.py b/poky/meta/lib/oeqa/selftest/cases/devtool.py index 6fe145c99..3a25da203 100644 --- a/poky/meta/lib/oeqa/selftest/cases/devtool.py +++ b/poky/meta/lib/oeqa/selftest/cases/devtool.py @@ -518,8 +518,8 @@ class DevtoolModifyTests(DevtoolBase): tempdir = tempfile.mkdtemp(prefix='devtoolqa') self.track_for_cleanup(tempdir) self.track_for_cleanup(self.workspacedir) - self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') self.add_command_to_tearDown('bitbake -c clean mdadm') + self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') result = runCmd('devtool modify mdadm -x %s' % tempdir) self.assertExists(os.path.join(tempdir, 'Makefile'), 'Extracted source could not be found') self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created') @@ -587,8 +587,8 @@ class DevtoolModifyTests(DevtoolBase): self.track_for_cleanup(tempdir_m4) self.track_for_cleanup(builddir_m4) self.track_for_cleanup(self.workspacedir) - self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') self.add_command_to_tearDown('bitbake -c clean mdadm m4') + self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') self.write_recipeinc('m4', 'EXTERNALSRC_BUILD = "%s"\ndo_clean() {\n\t:\n}\n' % builddir_m4) try: runCmd('devtool modify mdadm -x %s' % tempdir_mdadm) @@ -604,6 +604,7 @@ class DevtoolModifyTests(DevtoolBase): bitbake('mdadm m4 -c buildclean') assertNoFile(tempdir_mdadm, 'mdadm') assertNoFile(builddir_m4, 'src/m4') + runCmd('echo "#Trigger rebuild" >> %s/Makefile' % tempdir_mdadm) bitbake('mdadm m4 -c compile') assertFile(tempdir_mdadm, 'mdadm') assertFile(builddir_m4, 'src/m4') @@ -683,8 +684,8 @@ class DevtoolModifyTests(DevtoolBase): tempdir = tempfile.mkdtemp(prefix='devtoolqa') self.track_for_cleanup(tempdir) self.track_for_cleanup(self.workspacedir) - self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe) + self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir)) self.assertExists(os.path.join(tempdir, 'Makefile.am'), 'Extracted source could not be found') self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created. devtool output: %s' % result.output) @@ -715,8 +716,8 @@ class DevtoolModifyTests(DevtoolBase): tempdir = tempfile.mkdtemp(prefix='devtoolqa') self.track_for_cleanup(tempdir) self.track_for_cleanup(self.workspacedir) - self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe) + self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir)) self.assertExists(os.path.join(tempdir, 'configure.ac'), 'Extracted source could not be found') self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created') @@ -1246,8 +1247,8 @@ class DevtoolExtractTests(DevtoolBase): tempdir = tempfile.mkdtemp(prefix='devtoolqa') self.track_for_cleanup(tempdir) self.track_for_cleanup(self.workspacedir) - self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe) + self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir)) # Test that deploy-target at this point fails (properly) result = runCmd('devtool deploy-target -n %s root@localhost' % testrecipe, ignore_status=True) @@ -1297,8 +1298,8 @@ class DevtoolExtractTests(DevtoolBase): self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory') image = 'core-image-minimal' self.track_for_cleanup(self.workspacedir) - self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') self.add_command_to_tearDown('bitbake -c clean %s' % image) + self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') bitbake('%s -c clean' % image) # Add target and native recipes to workspace recipes = ['mdadm', 'parted-native'] @@ -1707,8 +1708,8 @@ class DevtoolUpgradeTests(DevtoolBase): self.track_for_cleanup(tempdir) self.track_for_cleanup(tempdir_cfg) self.track_for_cleanup(self.workspacedir) - self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') self.add_command_to_tearDown('bitbake -c clean %s' % kernel_provider) + self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') #Step 1 #Here is just generated the config file instead of all the kernel to optimize the #time of executing this test case. diff --git a/poky/meta/lib/oeqa/selftest/cases/multiconfig.py b/poky/meta/lib/oeqa/selftest/cases/multiconfig.py index d21bf0a41..39b92f243 100644 --- a/poky/meta/lib/oeqa/selftest/cases/multiconfig.py +++ b/poky/meta/lib/oeqa/selftest/cases/multiconfig.py @@ -3,16 +3,16 @@ # import os +import textwrap from oeqa.selftest.case import OESelftestTestCase from oeqa.utils.commands import bitbake -import oeqa.utils.ftools as ftools class MultiConfig(OESelftestTestCase): def test_multiconfig(self): """ - Test that a simple multiconfig build works. This uses the mcextend class and the - multiconfig-image-packager test recipe to build a core-image-full-cmdline image which + Test that a simple multiconfig build works. This uses the mcextend class and the + multiconfig-image-packager test recipe to build a core-image-full-cmdline image which contains a tiny core-image-minimal and a musl core-image-minimal, installed as packages. """ @@ -28,20 +28,45 @@ DISTRO = "poky" TCLIBC = "musl" TMPDIR = "${TOPDIR}/tmp-mc-musl" """ + self.write_config(muslconfig, 'musl') tinyconfig = """ MACHINE = "qemux86" DISTRO = "poky-tiny" TMPDIR = "${TOPDIR}/tmp-mc-tiny" """ - - multiconfigdir = self.builddir + "/conf/multiconfig" - os.makedirs(multiconfigdir, exist_ok=True) - self.track_for_cleanup(multiconfigdir + "/musl.conf") - ftools.write_file(multiconfigdir + "/musl.conf", muslconfig) - self.track_for_cleanup(multiconfigdir + "/tiny.conf") - ftools.write_file(multiconfigdir + "/tiny.conf", tinyconfig) + self.write_config(tinyconfig, 'tiny') # Build a core-image-minimal bitbake('core-image-full-cmdline') + def test_multiconfig_reparse(self): + """ + Test that changes to a multiconfig conf file are correctly detected and + cause a reparse/rebuild of a recipe. + """ + config = textwrap.dedent('''\ + MCTESTVAR = "test" + BBMULTICONFIG = "test" + ''') + self.write_config(config) + + testconfig = textwrap.dedent('''\ + MCTESTVAR_append = "1" + ''') + self.write_config(testconfig, 'test') + + # Check that the 1) the task executed and 2) that it output the correct + # value. Note "bitbake -e" is not used because it always reparses the + # recipe and we want to ensure that the automatic reparsing and parse + # caching is detected. + result = bitbake('mc:test:multiconfig-test-parse -c showvar') + self.assertIn('MCTESTVAR=test1', result.output.splitlines()) + + testconfig = textwrap.dedent('''\ + MCTESTVAR_append = "2" + ''') + self.write_config(testconfig, 'test') + + result = bitbake('mc:test:multiconfig-test-parse -c showvar') + self.assertIn('MCTESTVAR=test2', result.output.splitlines()) diff --git a/poky/meta/lib/oeqa/selftest/cases/reproducible.py b/poky/meta/lib/oeqa/selftest/cases/reproducible.py index eee09d3fb..c235c139e 100644 --- a/poky/meta/lib/oeqa/selftest/cases/reproducible.py +++ b/poky/meta/lib/oeqa/selftest/cases/reproducible.py @@ -72,7 +72,7 @@ def compare_file(reference, test, diffutils_sysroot): return result class ReproducibleTests(OESelftestTestCase): - package_classes = ['deb'] + package_classes = ['deb', 'ipk'] images = ['core-image-minimal'] def setUpLocal(self): diff --git a/poky/meta/lib/oeqa/selftest/cases/signing.py b/poky/meta/lib/oeqa/selftest/cases/signing.py index b390f37d8..5c4e01b2c 100644 --- a/poky/meta/lib/oeqa/selftest/cases/signing.py +++ b/poky/meta/lib/oeqa/selftest/cases/signing.py @@ -180,6 +180,8 @@ class LockedSignatures(OESelftestTestCase): AutomatedBy: Daniel Istrate """ + import uuid + test_recipe = 'ed' locked_sigs_file = 'locked-sigs.inc' @@ -197,9 +199,10 @@ class LockedSignatures(OESelftestTestCase): bitbake(test_recipe) # Make a change that should cause the locked task signature to change + # Use uuid so hash equivalance server isn't triggered recipe_append_file = test_recipe + '_' + get_bb_var('PV', test_recipe) + '.bbappend' recipe_append_path = os.path.join(self.testlayer_path, 'recipes-test', test_recipe, recipe_append_file) - feature = 'SUMMARY += "test locked signature"\n' + feature = 'SUMMARY_${PN} = "test locked signature%s"\n' % uuid.uuid4() os.mkdir(os.path.join(self.testlayer_path, 'recipes-test', test_recipe)) write_file(recipe_append_path, feature) @@ -210,7 +213,7 @@ class LockedSignatures(OESelftestTestCase): ret = bitbake(test_recipe) # Verify you get the warning and that the real task *isn't* run (i.e. the locked signature has worked) - patt = r'WARNING: The %s:do_package sig is computed to be \S+, but the sig is locked to \S+ in SIGGEN_LOCKEDSIGS\S+' % test_recipe + patt = r'The %s:do_package sig is computed to be \S+, but the sig is locked to \S+ in SIGGEN_LOCKEDSIGS\S+' % test_recipe found_warn = re.search(patt, ret.output) self.assertIsNotNone(found_warn, "Didn't find the expected warning message. Output: %s" % ret.output) -- cgit v1.2.3