From nobody Thu Nov 13 20:38:28 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1582592302; cv=none; d=zohomail.com; s=zohoarc; b=K7SpnYqwEIOLD2DZ+OF6IH0MDAemV+H8ICJ7Nq/v9l+A0uNgoTeHFde3rfHQMAzThJuhh+3rUthkHVW6zikt2Y5nahRoEhBOFZCIZW5vkOIZ1Hk0VmbutlVMaD3W3A4K5fUM1i8iKyDMj43GswajdQD/OMT3Wh695gQJC11McR0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1582592302; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=c/wCudtQMl0134+X0MXUafJH6n/tbZq25GtZ65dP+LY=; b=fVzlc0AEqt5rd1P3tzPW+Hhn86tuXLa5OKS3z7UFPTiPQvHaK6txbRaR9/FXr+dGmH6Zdg8P/9iZKlBTH3B5fHGD89XeZUMvJs4HeH7hbwG5dOnSsMYERUOLLfw7rixzw4+Coj1YBg2DSM+XY+vY4DHnzvj7Kk3f5yRM8WpEnk0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1582592302500806.2427155508012; Mon, 24 Feb 2020 16:58:22 -0800 (PST) Received: from localhost ([::1]:46858 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j6OYH-00044R-4S for importer@patchew.org; Mon, 24 Feb 2020 19:58:21 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:55816) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1j6OWw-0002Cx-7S for qemu-devel@nongnu.org; Mon, 24 Feb 2020 19:56:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1j6OWt-00086N-6a for qemu-devel@nongnu.org; Mon, 24 Feb 2020 19:56:58 -0500 Received: from us-smtp-1.mimecast.com ([205.139.110.61]:36082 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1j6OWt-00084t-2S for qemu-devel@nongnu.org; Mon, 24 Feb 2020 19:56:55 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-388-MieQXN5tOp-L7Ka33cXJeQ-1; Mon, 24 Feb 2020 19:56:47 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9A23D1007268; Tue, 25 Feb 2020 00:56:46 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-182.bos.redhat.com [10.18.17.182]) by smtp.corp.redhat.com (Postfix) with ESMTP id AC7911CB; Tue, 25 Feb 2020 00:56:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1582592214; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=c/wCudtQMl0134+X0MXUafJH6n/tbZq25GtZ65dP+LY=; b=JMMc3oxIdahjK+MgfXJU7IGqsZkYnhthMiMU4NmRlEfUmY8gQzWuUCvTr6MZ0DF9OdQED8 gKzXXWdEkEpJcPslU1A4IMeoeYIZ+2rbwyDacL+NvInkwRdSZItC/blqN1aNUrD2h8iRot /x5KVj7JcssWQkBBeS7dYOEzSJSJvaU= X-MC-Unique: MieQXN5tOp-L7Ka33cXJeQ-1 From: John Snow To: qemu-devel@nongnu.org Subject: [PATCH 3/6] iotests: move bitmap helpers into their own file Date: Mon, 24 Feb 2020 19:56:38 -0500 Message-Id: <20200225005641.5478-4-jsnow@redhat.com> In-Reply-To: <20200225005641.5478-1-jsnow@redhat.com> References: <20200225005641.5478-1-jsnow@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 205.139.110.61 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , vsementsov@virtuozzo.com, Eduardo Habkost , qemu-block@nongnu.org, Markus Armbruster , Max Reitz , pkrempa@redhat.com, Cleber Rosa , John Snow Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" Signed-off-by: John Snow Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/257 | 110 +--------------------------- tests/qemu-iotests/bitmaps.py | 131 ++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 109 deletions(-) create mode 100644 tests/qemu-iotests/bitmaps.py diff --git a/tests/qemu-iotests/257 b/tests/qemu-iotests/257 index 004a433b8b..2a81f9e30c 100755 --- a/tests/qemu-iotests/257 +++ b/tests/qemu-iotests/257 @@ -24,120 +24,12 @@ import os =20 import iotests from iotests import log, qemu_img +from bitmaps import EmulatedBitmap, GROUPS =20 SIZE =3D 64 * 1024 * 1024 GRANULARITY =3D 64 * 1024 =20 =20 -class Pattern: - def __init__(self, byte, offset, size=3DGRANULARITY): - self.byte =3D byte - self.offset =3D offset - self.size =3D size - - def bits(self, granularity): - lower =3D self.offset // granularity - upper =3D (self.offset + self.size - 1) // granularity - return set(range(lower, upper + 1)) - - -class PatternGroup: - """Grouping of Pattern objects. Initialize with an iterable of Pattern= s.""" - def __init__(self, patterns): - self.patterns =3D patterns - - def bits(self, granularity): - """Calculate the unique bits dirtied by this pattern grouping""" - res =3D set() - for pattern in self.patterns: - res |=3D pattern.bits(granularity) - return res - - -GROUPS =3D [ - PatternGroup([ - # Batch 0: 4 clusters - Pattern('0x49', 0x0000000), - Pattern('0x6c', 0x0100000), # 1M - Pattern('0x6f', 0x2000000), # 32M - Pattern('0x76', 0x3ff0000)]), # 64M - 64K - PatternGroup([ - # Batch 1: 6 clusters (3 new) - Pattern('0x65', 0x0000000), # Full overwrite - Pattern('0x77', 0x00f8000), # Partial-left (1M-32K) - Pattern('0x72', 0x2008000), # Partial-right (32M+32K) - Pattern('0x69', 0x3fe0000)]), # Adjacent-left (64M - 128K) - PatternGroup([ - # Batch 2: 7 clusters (3 new) - Pattern('0x74', 0x0010000), # Adjacent-right - Pattern('0x69', 0x00e8000), # Partial-left (1M-96K) - Pattern('0x6e', 0x2018000), # Partial-right (32M+96K) - Pattern('0x67', 0x3fe0000, - 2*GRANULARITY)]), # Overwrite [(64M-128K)-64M) - PatternGroup([ - # Batch 3: 8 clusters (5 new) - # Carefully chosen such that nothing re-dirties the one cluster - # that copies out successfully before failure in Group #1. - Pattern('0xaa', 0x0010000, - 3*GRANULARITY), # Overwrite and 2x Adjacent-right - Pattern('0xbb', 0x00d8000), # Partial-left (1M-160K) - Pattern('0xcc', 0x2028000), # Partial-right (32M+160K) - Pattern('0xdd', 0x3fc0000)]), # New; leaving a gap to the right -] - - -class EmulatedBitmap: - def __init__(self, granularity=3DGRANULARITY): - self._bits =3D set() - self.granularity =3D granularity - - def dirty_bits(self, bits): - self._bits |=3D set(bits) - - def dirty_group(self, n): - self.dirty_bits(GROUPS[n].bits(self.granularity)) - - def clear(self): - self._bits =3D set() - - def clear_bits(self, bits): - self._bits -=3D set(bits) - - def clear_bit(self, bit): - self.clear_bits({bit}) - - def clear_group(self, n): - self.clear_bits(GROUPS[n].bits(self.granularity)) - - @property - def first_bit(self): - return sorted(self.bits)[0] - - @property - def bits(self): - return self._bits - - @property - def count(self): - return len(self.bits) - - def compare(self, qmp_bitmap): - """ - Print a nice human-readable message checking that a bitmap as repo= rted - by the QMP interface has as many bits set as we expect it to. - """ - - name =3D qmp_bitmap.get('name', '(anonymous)') - log("=3D Checking Bitmap {:s} =3D".format(name)) - - want =3D self.count - have =3D qmp_bitmap['count'] // qmp_bitmap['granularity'] - - log("expecting {:d} dirty sectors; have {:d}. {:s}".format( - want, have, "OK!" if want =3D=3D have else "ERROR!")) - log('') - - class Drive: """Represents, vaguely, a drive attached to a VM. Includes format, graph, and device information.""" diff --git a/tests/qemu-iotests/bitmaps.py b/tests/qemu-iotests/bitmaps.py new file mode 100644 index 0000000000..522fc25171 --- /dev/null +++ b/tests/qemu-iotests/bitmaps.py @@ -0,0 +1,131 @@ +# Bitmap-related helper utilities +# +# Copyright (c) 2020 John Snow for Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that 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. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# owner=3Djsnow@redhat.com + +from iotests import log + +GRANULARITY =3D 64 * 1024 + + +class Pattern: + def __init__(self, byte, offset, size=3DGRANULARITY): + self.byte =3D byte + self.offset =3D offset + self.size =3D size + + def bits(self, granularity): + lower =3D self.offset // granularity + upper =3D (self.offset + self.size - 1) // granularity + return set(range(lower, upper + 1)) + + +class PatternGroup: + """Grouping of Pattern objects. Initialize with an iterable of Pattern= s.""" + def __init__(self, patterns): + self.patterns =3D patterns + + def bits(self, granularity): + """Calculate the unique bits dirtied by this pattern grouping""" + res =3D set() + for pattern in self.patterns: + res |=3D pattern.bits(granularity) + return res + + +GROUPS =3D [ + PatternGroup([ + # Batch 0: 4 clusters + Pattern('0x49', 0x0000000), + Pattern('0x6c', 0x0100000), # 1M + Pattern('0x6f', 0x2000000), # 32M + Pattern('0x76', 0x3ff0000)]), # 64M - 64K + PatternGroup([ + # Batch 1: 6 clusters (3 new) + Pattern('0x65', 0x0000000), # Full overwrite + Pattern('0x77', 0x00f8000), # Partial-left (1M-32K) + Pattern('0x72', 0x2008000), # Partial-right (32M+32K) + Pattern('0x69', 0x3fe0000)]), # Adjacent-left (64M - 128K) + PatternGroup([ + # Batch 2: 7 clusters (3 new) + Pattern('0x74', 0x0010000), # Adjacent-right + Pattern('0x69', 0x00e8000), # Partial-left (1M-96K) + Pattern('0x6e', 0x2018000), # Partial-right (32M+96K) + Pattern('0x67', 0x3fe0000, + 2*GRANULARITY)]), # Overwrite [(64M-128K)-64M) + PatternGroup([ + # Batch 3: 8 clusters (5 new) + # Carefully chosen such that nothing re-dirties the one cluster + # that copies out successfully before failure in Group #1. + Pattern('0xaa', 0x0010000, + 3*GRANULARITY), # Overwrite and 2x Adjacent-right + Pattern('0xbb', 0x00d8000), # Partial-left (1M-160K) + Pattern('0xcc', 0x2028000), # Partial-right (32M+160K) + Pattern('0xdd', 0x3fc0000)]), # New; leaving a gap to the right +] + + +class EmulatedBitmap: + def __init__(self, granularity=3DGRANULARITY): + self._bits =3D set() + self.granularity =3D granularity + + def dirty_bits(self, bits): + self._bits |=3D set(bits) + + def dirty_group(self, n): + self.dirty_bits(GROUPS[n].bits(self.granularity)) + + def clear(self): + self._bits =3D set() + + def clear_bits(self, bits): + self._bits -=3D set(bits) + + def clear_bit(self, bit): + self.clear_bits({bit}) + + def clear_group(self, n): + self.clear_bits(GROUPS[n].bits(self.granularity)) + + @property + def first_bit(self): + return sorted(self.bits)[0] + + @property + def bits(self): + return self._bits + + @property + def count(self): + return len(self.bits) + + def compare(self, qmp_bitmap): + """ + Print a nice human-readable message checking that a bitmap as repo= rted + by the QMP interface has as many bits set as we expect it to. + """ + + name =3D qmp_bitmap.get('name', '(anonymous)') + log("=3D Checking Bitmap {:s} =3D".format(name)) + + want =3D self.count + have =3D qmp_bitmap['count'] // qmp_bitmap['granularity'] + + log("expecting {:d} dirty sectors; have {:d}. {:s}".format( + want, have, "OK!" if want =3D=3D have else "ERROR!")) + log('') --=20 2.21.1