From nobody Wed Nov 5 15:55:26 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1497395287294429.2048018785108; Tue, 13 Jun 2017 16:08:07 -0700 (PDT) Received: from localhost ([::1]:45630 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dKuus-0006wR-0S for importer@patchew.org; Tue, 13 Jun 2017 19:08:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43972) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dKutS-0005LY-D5 for qemu-devel@nongnu.org; Tue, 13 Jun 2017 19:06:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dKutQ-0001y6-Sf for qemu-devel@nongnu.org; Tue, 13 Jun 2017 19:06:38 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43304) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dKutQ-0001xv-Kh for qemu-devel@nongnu.org; Tue, 13 Jun 2017 19:06:36 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A12E480C0A for ; Tue, 13 Jun 2017 23:06:35 +0000 (UTC) Received: from localhost (ovpn-116-27.gru2.redhat.com [10.97.116.27]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3045490703; Tue, 13 Jun 2017 23:06:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A12E480C0A Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=ehabkost@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com A12E480C0A From: Eduardo Habkost To: qemu-devel@nongnu.org Date: Tue, 13 Jun 2017 20:06:27 -0300 Message-Id: <20170613230627.17942-4-ehabkost@redhat.com> In-Reply-To: <20170613230627.17942-1-ehabkost@redhat.com> References: <20170613230627.17942-1-ehabkost@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Tue, 13 Jun 2017 23:06:35 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 3/3] device-crash-test: Mode for testing -object X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Extend the device-crash-test script so it can test backend objects, too. The new mode can be enabled using the "-O" option. The script already found a crash using the following command-line: $ qemu-system-x86_64 -S -machine none -object colo-compare,id=3Dtest-obje= ct (qemu-system-x86_64:3812): GLib-CRITICAL **: g_main_loop_quit: assertion = 'loop !=3D NULL' failed Segmentation fault (core dumped) The crash above was added to the script whitelist so it will still generate error messages but won't generate fatal errors. Signed-off-by: Eduardo Habkost --- scripts/device-crash-test | 101 +++++++++++++++++++++++++++++++++---------= ---- 1 file changed, 74 insertions(+), 27 deletions(-) diff --git a/scripts/device-crash-test b/scripts/device-crash-test index 5f90e9bb54..be5369425d 100755 --- a/scripts/device-crash-test +++ b/scripts/device-crash-test @@ -171,6 +171,10 @@ ERROR_WHITELIST =3D [ # this fails on some machine-types, but not all, so they don't have ex= pected=3DTrue: {'device':'vmgenid'}, # vmgenid requires DMA write support in fw_cfg, = which this machine type does not provide =20 + # silence exitcode=3D1 errors caused by -object, as most of them will = complain + # about missing options. + {'object': '.*', 'log':".*"}, + # Silence INFO messages for errors that are common on multiple # devices/machines: {'log':r"No '[\w-]+' bus found for device '[\w-]+'"}, @@ -231,6 +235,7 @@ ERROR_WHITELIST =3D [ {'exitcode':-11, 'device':'cs4231a', 'loglevel':logging.ERROR, 'expect= ed':True}, {'exitcode':-11, 'device':'arm-gicv3', 'loglevel':logging.ERROR, 'expe= cted':True}, {'exitcode':-11, 'machine':'isapc', 'device':'.*-iommu', 'loglevel':lo= gging.ERROR, 'expected':True}, + {'exitcode':-11, 'object':'colo-compare', 'loglevel':logging.ERROR, 'e= xpected':True}, =20 # everything else (including SIGABRT and SIGSEGV) will be a fatal erro= r: {'exitcode':None, 'fatal':True, 'loglevel':logging.FATAL}, @@ -245,14 +250,17 @@ def whitelistTestCaseMatch(wl, t): results/output match the entry. See whitelistResultMatch(). """ return (('machine' not in wl or - 'machine' not in t or - re.match(wl['machine'] + '$', t['machine'])) and + ('machine' in t and + re.match(wl['machine'] + '$', t['machine']))) and ('accel' not in wl or 'accel' not in t or re.match(wl['accel'] + '$', t['accel'])) and ('device' not in wl or - 'device' not in t or - re.match(wl['device'] + '$', t['device']))) + ('device' in t and + re.match(wl['device'] + '$', t['device']))) and + ('object' not in wl or + ('object' in t and + re.match(wl['object'] + '$', t['object'])))) =20 =20 def whitelistCandidates(t): @@ -330,29 +338,50 @@ def infoQDM(vm): =20 =20 class QemuBinaryInfo(object): - def __init__(self, binary, devtype): - if devtype is None: - devtype =3D 'device' + def __init__(self, binary, basetypes): + """Constructor =20 + @basetypes: device types to be queried in advance using qom-list-t= ypes + """ self.binary =3D binary self._machine_info =3D {} =20 - dbg("devtype: %r", devtype) + dbg("basetypes: %r", basetypes) args =3D ['-S', '-machine', 'none,accel=3Dkvm:tcg'] dbg("querying info for QEMU binary: %s", binary) vm =3D QEMUMachine(binary=3Dbinary, args=3Dargs) vm.launch() try: - self.alldevs =3D set(qomListTypeNames(vm, implements=3Ddevtype= , abstract=3DFalse)) + self.type_lists =3D {} + for bt in basetypes: + self.type_lists[bt] =3D \ + set(qomListTypeNames(vm, implements=3Dbt, abstract=3DF= alse)) # there's no way to query DeviceClass::user_creatable using QM= P, # so use 'info qdm': self.no_user_devs =3D set([d['name'] for d in infoQDM(vm, ) if= d['no-user']]) self.machines =3D list(m['name'] for m in vm.command('query-ma= chines')) - self.user_devs =3D self.alldevs.difference(self.no_user_devs) self.kvm_available =3D vm.command('query-kvm')['enabled'] finally: vm.shutdown() =20 + def getTypes(self, basetype): + """Return list of subtypes of @basetype + + @basetype must be in the basetypes list used when + constructing the QemuBinaryObject, so it can be + loaded in advance. + """ + return self.type_lists[basetype] + + def getUserDevs(self, devtype): + """Return list of user-creatable devices that implement a devtype + + @devtype must be in the basetypes list used when + constructing the QemuBinaryObject, so it can be + loaded in advance. + """ + return self.getTypes(devtype).difference(self.no_user_devs) + def machineInfo(self, machine): """Query for information on a specific machine-type =20 @@ -386,7 +415,8 @@ BINARY_INFO =3D {} =20 def getBinaryInfo(args, binary): if binary not in BINARY_INFO: - BINARY_INFO[binary] =3D QemuBinaryInfo(binary, args.devtype) + BINARY_INFO[binary] =3D QemuBinaryInfo(binary, + [args.devtype, 'user-creatabl= e']) return BINARY_INFO[binary] =20 =20 @@ -397,14 +427,20 @@ def checkOneCase(args, testcase): or None on success """ binary =3D testcase['binary'] - accel =3D testcase['accel'] - machine =3D testcase['machine'] - device =3D testcase['device'] =20 dbg("will test: %r", testcase) =20 - args =3D ['-S', '-machine', '%s,accel=3D%s' % (machine, accel), - '-device', qemuOptsEscape(device)] + args =3D ['-S'] + if 'machine' in testcase: + m =3D testcase['machine'] + if 'accel' in testcase: + m +=3D ',accel=3D%s' % (testcase['accel']) + args.extend(['-machine', m]) + if 'device' in testcase: + args.extend(['-device', qemuOptsEscape(testcase['device'])]) + if 'object' in testcase: + args.extend(['-object', '%s,id=3Dtest-object' % (qemuOptsEscape(te= stcase['object']))]) + cmdline =3D ' '.join([binary] + args) dbg("will launch QEMU: %s", cmdline) vm =3D QEMUMachine(binary=3Dbinary, args=3Dargs) @@ -449,16 +485,20 @@ def machinesToTest(args, testcase): =20 =20 def devicesToTest(args, testcase): - return getBinaryInfo(args, testcase['binary']).user_devs + return getBinaryInfo(args, testcase['binary']).getUserDevs(args.devtyp= e) =20 +def objectsToTest(args, testcase): + return getBinaryInfo(args, testcase['binary']).getTypes('user-creatabl= e') =20 -TESTCASE_VARIABLES =3D [ - ('binary', binariesToTest), - ('accel', accelsToTest), - ('machine', machinesToTest), - ('device', devicesToTest), -] - +def testCaseVariables(args, testcase): + """Generate list of test case variables over which we will iterate""" + yield ('binary', binariesToTest) + if 'device' in testcase or args.mode =3D=3D 'device': + yield ('accel', accelsToTest) + yield ('machine', machinesToTest) + yield ('device', devicesToTest) + elif 'object' in testcase or args.mode =3D=3D 'object': + yield ('object', objectsToTest) =20 def genCases1(args, testcases, var, fn): """Generate new testcases for one variable @@ -482,7 +522,7 @@ def genCases(args, testcase): """Generate test cases for all variables """ cases =3D [testcase.copy()] - for var, fn in TESTCASE_VARIABLES: + for var, fn in testCaseVariables(args, testcase): dbg("var: %r, fn: %r", var, fn) cases =3D genCases1(args, cases, var, fn) return cases @@ -534,7 +574,13 @@ def main(): parser.add_argument('--dry-run', action=3D'store_true', help=3D"Don't run any tests, just generate list") parser.add_argument('-D', '--devtype', metavar=3D'TYPE', - help=3D"Test only device types that implement TYPE= ") + help=3D"Test only device types that implement TYPE= ", + default=3D"device") + parser.add_argument('-M', '--mode', metavar=3D'MODE', + help=3D"Test mode (object, device)", choices=3D['o= bject', 'device'], + default=3D'device') + parser.add_argument('-O', '--object', action=3D'store_const', const=3D= 'object', + dest=3D'mode') parser.add_argument('-Q', '--quick', action=3D'store_true', default=3D= True, help=3D"Quick mode: skip test cases that are expec= ted to fail") parser.add_argument('-F', '--full', action=3D'store_false', dest=3D'qu= ick', @@ -578,7 +624,8 @@ def main(): expected_match =3D findExpectedResult(t) if (args.quick and (expected_match or - not getBinaryInfo(args, t['binary']).machineInfo(t['machi= ne'])['runnable'])): + ('machine' in t and + not getBinaryInfo(args, t['binary']).machineInfo(t['mach= ine'])['runnable']))): dbg("skipped: %s", formatTestCase(t)) skipped +=3D 1 continue --=20 2.11.0.259.g40922b1