From nobody Tue Nov 26 18:13:56 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; 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=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1705688120; cv=none; d=zohomail.com; s=zohoarc; b=OHRMlTTXmxvhLc6XtyZUw6SjE5ASz0ZVa7dWm9yLK5f9fB5vEWqelAl+fgbadFajc9rTocq6FDYynekAfo0Q77J2jFraHSuLbzi64VzsgrQOe3j2V5+Gk2Uy98vZblkOKw4pHPsPheotb4rUwtFwyNXEtb58NuMawdM2pyU7VHQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1705688120; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=xX/LqETDPHHCAR/ixbnRDJdbnZadDBuYH5MHn0GrT44=; b=l+GEBvqI1KPTlFq4dvjlRBw6gz1OqgvTHfVnlu/SvexnoPsEct70Hy2DM/kMt3A2EjdupZ2MIxilfpNGtBxy7FHxBUnJGvUJWB5bC2fAko4nFebFqOgmA43UzB4LvDIbHF3Zzo9nZBFvxDZ+4G9MyNOtmbxq4lGPZU7JH1iQb4E= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; 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=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1705688120486975.3658861229344; Fri, 19 Jan 2024 10:15:20 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rQtNL-0001ih-PW; Fri, 19 Jan 2024 13:13:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rQtNE-0001eH-Hf for qemu-devel@nongnu.org; Fri, 19 Jan 2024 13:13:50 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rQtN9-0007dZ-9R for qemu-devel@nongnu.org; Fri, 19 Jan 2024 13:13:47 -0500 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-117-JIGSowUWNAq30O0xFNTt-A-1; Fri, 19 Jan 2024 13:13:38 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D989A86794D; Fri, 19 Jan 2024 18:13:37 +0000 (UTC) Received: from merkur.fritz.box (unknown [10.39.194.86]) by smtp.corp.redhat.com (Postfix) with ESMTP id 31002494; Fri, 19 Jan 2024 18:13:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1705688022; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xX/LqETDPHHCAR/ixbnRDJdbnZadDBuYH5MHn0GrT44=; b=N1w1sfeM0U9BsbH+d35nbC/zWJsvUnuDlpwCKGXvdge0zrdM9alVF/icESzPV/o27d8o/e Dhzu2fguRBjG/2j4RLw1vgiVfOXszr/BJf3Nke7zIqG+nD42+2owNm/K/edx9mhllOW6Ll Ndu/30HwNfHxOlmxEwO3ZICclZenLAc= X-MC-Unique: JIGSowUWNAq30O0xFNTt-A-1 From: Kevin Wolf To: qemu-block@nongnu.org Cc: kwolf@redhat.com, qemu-devel@nongnu.org Subject: [PULL 06/14] iotests: port 141 to Python for reliable QMP testing Date: Fri, 19 Jan 2024 19:13:19 +0100 Message-ID: <20240119181327.236745-7-kwolf@redhat.com> In-Reply-To: <20240119181327.236745-1-kwolf@redhat.com> References: <20240119181327.236745-1-kwolf@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.1 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; Received-SPF: pass client-ip=170.10.129.124; envelope-from=kwolf@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -45 X-Spam_score: -4.6 X-Spam_bar: ---- X-Spam_report: (-4.6 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-2.519, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 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-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1705688121905100003 Content-Type: text/plain; charset="utf-8" From: Stefan Hajnoczi The common.qemu bash functions allow tests to interact with the QMP monitor of a QEMU process. I spent two days trying to update 141 when the order of the test output changed, but found it would still fail occassionally because printf() and QMP events race with synchronous QMP communication. I gave up and ported 141 to the existing Python API for QMP tests. The Python API is less affected by the order in which QEMU prints output because it does not print all QMP traffic by default. The next commit changes the order in which QMP messages are received. Make 141 reliable first. Cc: Hanna Czenczek Signed-off-by: Stefan Hajnoczi Message-ID: <20240118144823.1497953-3-stefanha@redhat.com> Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- tests/qemu-iotests/141 | 307 ++++++++++++++++--------------------- tests/qemu-iotests/141.out | 200 ++++++------------------ 2 files changed, 176 insertions(+), 331 deletions(-) diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141 index a37030ee17..a7d3985a02 100755 --- a/tests/qemu-iotests/141 +++ b/tests/qemu-iotests/141 @@ -1,9 +1,12 @@ -#!/usr/bin/env bash +#!/usr/bin/env python3 # group: rw auto quick # # Test case for ejecting BDSs with block jobs still running on them # -# Copyright (C) 2016 Red Hat, Inc. +# Originally written in bash by Hanna Czenczek, ported to Python by Stefan +# Hajnoczi. +# +# Copyright Red Hat # # 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 @@ -19,177 +22,129 @@ # along with this program. If not, see . # =20 -# creator -owner=3Dhreitz@redhat.com - -seq=3D"$(basename $0)" -echo "QA output created by $seq" - -status=3D1 # failure is the default! - -_cleanup() -{ - _cleanup_qemu - _cleanup_test_img - for img in "$TEST_DIR"/{b,m,o}.$IMGFMT; do - _rm_test_img "$img" - done -} -trap "_cleanup; exit \$status" 0 1 2 3 15 - -# get standard environment, filters and checks -. ./common.rc -. ./common.filter -. ./common.qemu - -# Needs backing file and backing format support -_supported_fmt qcow2 qed -_supported_proto file -_supported_os Linux - - -test_blockjob() -{ - _send_qemu_cmd $QEMU_HANDLE \ - "{'execute': 'blockdev-add', - 'arguments': { - 'node-name': 'drv0', - 'driver': '$IMGFMT', - 'file': { - 'driver': 'file', - 'filename': '$TEST_IMG' - }}}" \ - 'return' - - # If "$2" is an event, we may or may not see it before the - # {"return": {}}. Therefore, filter the {"return": {}} out both - # here and in the next command. (Naturally, if we do not see it - # here, we will see it before the next command can be executed, - # so it will appear in the next _send_qemu_cmd's output.) - _send_qemu_cmd $QEMU_HANDLE \ - "$1" \ - "$2" \ - | _filter_img_create | _filter_qmp_empty_return - - # We want this to return an error because the block job is still runni= ng - _send_qemu_cmd $QEMU_HANDLE \ - "{'execute': 'blockdev-del', - 'arguments': {'node-name': 'drv0'}}" \ - 'error' | _filter_generated_node_ids | _filter_qmp_empty_return - - _send_qemu_cmd $QEMU_HANDLE \ - "{'execute': 'block-job-cancel', - 'arguments': {'device': 'job0'}}" \ - "$3" - - _send_qemu_cmd $QEMU_HANDLE \ - "{'execute': 'blockdev-del', - 'arguments': {'node-name': 'drv0'}}" \ - 'return' -} - - -TEST_IMG=3D"$TEST_DIR/b.$IMGFMT" _make_test_img 1M -TEST_IMG=3D"$TEST_DIR/m.$IMGFMT" _make_test_img -b "$TEST_DIR/b.$IMGFMT" -= F $IMGFMT 1M -_make_test_img -b "$TEST_DIR/m.$IMGFMT" 1M -F $IMGFMT - -_launch_qemu -nodefaults - -_send_qemu_cmd $QEMU_HANDLE \ - "{'execute': 'qmp_capabilities'}" \ - 'return' - -echo -echo '=3D=3D=3D Testing drive-backup =3D=3D=3D' -echo - -# drive-backup will not send BLOCK_JOB_READY by itself, and cancelling the= job -# will consequently result in BLOCK_JOB_CANCELLED being emitted. - -test_blockjob \ - "{'execute': 'drive-backup', - 'arguments': {'job-id': 'job0', - 'device': 'drv0', - 'target': '$TEST_DIR/o.$IMGFMT', - 'format': '$IMGFMT', - 'sync': 'none'}}" \ - 'return' \ - '"status": "null"' - -echo -echo '=3D=3D=3D Testing drive-mirror =3D=3D=3D' -echo - -# drive-mirror will send BLOCK_JOB_READY basically immediately, and cancel= ling -# the job will consequently result in BLOCK_JOB_COMPLETED being emitted. - -test_blockjob \ - "{'execute': 'drive-mirror', - 'arguments': {'job-id': 'job0', - 'device': 'drv0', - 'target': '$TEST_DIR/o.$IMGFMT', - 'format': '$IMGFMT', - 'sync': 'none'}}" \ - 'BLOCK_JOB_READY' \ - '"status": "null"' - -echo -echo '=3D=3D=3D Testing active block-commit =3D=3D=3D' -echo - -# An active block-commit will send BLOCK_JOB_READY basically immediately, = and -# cancelling the job will consequently result in BLOCK_JOB_COMPLETED being -# emitted. - -test_blockjob \ - "{'execute': 'block-commit', - 'arguments': {'job-id': 'job0', 'device': 'drv0'}}" \ - 'BLOCK_JOB_READY' \ - '"status": "null"' - -echo -echo '=3D=3D=3D Testing non-active block-commit =3D=3D=3D' -echo - -# Give block-commit something to work on, otherwise it would be done -# immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would work = just -# fine without the block job still running. - -$QEMU_IO -c 'write 0 1M' "$TEST_DIR/m.$IMGFMT" | _filter_qemu_io - -test_blockjob \ - "{'execute': 'block-commit', - 'arguments': {'job-id': 'job0', - 'device': 'drv0', - 'top': '$TEST_DIR/m.$IMGFMT', - 'speed': 1}}" \ - 'return' \ - '"status": "null"' - -echo -echo '=3D=3D=3D Testing block-stream =3D=3D=3D' -echo - -# Give block-stream something to work on, otherwise it would be done -# immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS would work = just -# fine without the block job still running. - -$QEMU_IO -c 'write 0 1M' "$TEST_DIR/b.$IMGFMT" | _filter_qemu_io - -# With some data to stream (and @speed set to 1), block-stream will not co= mplete -# until we send the block-job-cancel command. - -test_blockjob \ - "{'execute': 'block-stream', - 'arguments': {'job-id': 'job0', - 'device': 'drv0', - 'speed': 1}}" \ - 'return' \ - '"status": "null"' - -_cleanup_qemu - -# success, all done -echo "*** done" -rm -f $seq.full -status=3D0 +import iotests + +# Common filters to mask values that vary in the test output +QMP_FILTERS =3D [iotests.filter_qmp_testfiles, \ + iotests.filter_qmp_imgfmt] + + +class TestCase: + def __init__(self, name, vm, image_path, cancel_event): + self.name =3D name + self.vm =3D vm + self.image_path =3D image_path + self.cancel_event =3D cancel_event + + def __enter__(self): + iotests.log(f'=3D=3D=3D Testing {self.name} =3D=3D=3D') + self.vm.qmp_log('blockdev-add', \ + node_name=3D'drv0', \ + driver=3Diotests.imgfmt, \ + file=3D{'driver': 'file', 'filename': self.image_p= ath}, \ + filters=3DQMP_FILTERS) + + def __exit__(self, *exc_details): + # This is expected to fail because the job still exists + self.vm.qmp_log('blockdev-del', node_name=3D'drv0', \ + filters=3D[iotests.filter_qmp_generated_node_ids]) + + self.vm.qmp_log('block-job-cancel', device=3D'job0') + event =3D self.vm.event_wait(self.cancel_event) + iotests.log(event, filters=3D[iotests.filter_qmp_event]) + + # This time it succeeds + self.vm.qmp_log('blockdev-del', node_name=3D'drv0') + + # Separate test cases in output + iotests.log('') + + +def main() -> None: + with iotests.FilePath('bottom', 'middle', 'top', 'target') as \ + (bottom_path, middle_path, top_path, target_path), \ + iotests.VM() as vm: + + iotests.log('Creating bottom <- middle <- top backing file chain..= .') + IMAGE_SIZE=3D'1M' + iotests.qemu_img_create('-f', iotests.imgfmt, bottom_path, IMAGE_S= IZE) + iotests.qemu_img_create('-f', iotests.imgfmt, \ + '-F', iotests.imgfmt, \ + '-b', bottom_path, \ + middle_path, \ + IMAGE_SIZE) + iotests.qemu_img_create('-f', iotests.imgfmt, \ + '-F', iotests.imgfmt, \ + '-b', middle_path, \ + top_path, \ + IMAGE_SIZE) + + iotests.log('Starting VM...') + vm.add_args('-nodefaults') + vm.launch() + + # drive-backup will not send BLOCK_JOB_READY by itself, and cancel= ling + # the job will consequently result in BLOCK_JOB_CANCELLED being + # emitted. + with TestCase('drive-backup', vm, top_path, 'BLOCK_JOB_CANCELLED'): + vm.qmp_log('drive-backup', \ + job_id=3D'job0', \ + device=3D'drv0', \ + target=3Dtarget_path, \ + format=3Diotests.imgfmt, \ + sync=3D'none', \ + filters=3DQMP_FILTERS) + + # drive-mirror will send BLOCK_JOB_READY basically immediately, and + # cancelling the job will consequently result in BLOCK_JOB_COMPLET= ED + # being emitted. + with TestCase('drive-mirror', vm, top_path, 'BLOCK_JOB_COMPLETED'): + vm.qmp_log('drive-mirror', \ + job_id=3D'job0', \ + device=3D'drv0', \ + target=3Dtarget_path, \ + format=3Diotests.imgfmt, \ + sync=3D'none', \ + filters=3DQMP_FILTERS) + event =3D vm.event_wait('BLOCK_JOB_READY') + assert event is not None # silence mypy + iotests.log(event, filters=3D[iotests.filter_qmp_event]) + + # An active block-commit will send BLOCK_JOB_READY basically + # immediately, and cancelling the job will consequently result in + # BLOCK_JOB_COMPLETED being emitted. + with TestCase('active block-commit', vm, top_path, \ + 'BLOCK_JOB_COMPLETED'): + vm.qmp_log('block-commit', \ + job_id=3D'job0', \ + device=3D'drv0') + event =3D vm.event_wait('BLOCK_JOB_READY') + assert event is not None # silence mypy + iotests.log(event, filters=3D[iotests.filter_qmp_event]) + + # Give block-commit something to work on, otherwise it would be do= ne + # immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS wou= ld + # work just fine without the block job still running. + iotests.qemu_io(middle_path, '-c', f'write 0 {IMAGE_SIZE}') + with TestCase('non-active block-commit', vm, top_path, \ + 'BLOCK_JOB_CANCELLED'): + vm.qmp_log('block-commit', \ + job_id=3D'job0', \ + device=3D'drv0', \ + top=3Dmiddle_path, \ + speed=3D1, \ + filters=3D[iotests.filter_qmp_testfiles]) + + # Give block-stream something to work on, otherwise it would be do= ne + # immediately, send a BLOCK_JOB_COMPLETED and ejecting the BDS wou= ld + # work just fine without the block job still running. + iotests.qemu_io(bottom_path, '-c', f'write 0 {IMAGE_SIZE}') + with TestCase('block-stream', vm, top_path, 'BLOCK_JOB_CANCELLED'): + vm.qmp_log('block-stream', \ + job_id=3D'job0', \ + device=3D'drv0', \ + speed=3D1) + +if __name__ =3D=3D '__main__': + iotests.script_main(main, supported_fmts=3D['qcow2', 'qed'], + supported_protocols=3D['file']) diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out index 63203d9944..91b7ba50af 100644 --- a/tests/qemu-iotests/141.out +++ b/tests/qemu-iotests/141.out @@ -1,179 +1,69 @@ -QA output created by 141 -Formatting 'TEST_DIR/b.IMGFMT', fmt=3DIMGFMT size=3D1048576 -Formatting 'TEST_DIR/m.IMGFMT', fmt=3DIMGFMT size=3D1048576 backing_file= =3DTEST_DIR/b.IMGFMT backing_fmt=3DIMGFMT -Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D1048576 backing_file= =3DTEST_DIR/m.IMGFMT backing_fmt=3DIMGFMT -{'execute': 'qmp_capabilities'} -{"return": {}} - +Creating bottom <- middle <- top backing file chain... +Starting VM... =3D=3D=3D Testing drive-backup =3D=3D=3D - -{'execute': 'blockdev-add', - 'arguments': { - 'node-name': 'drv0', - 'driver': 'IMGFMT', - 'file': { - 'driver': 'file', - 'filename': 'TEST_DIR/t.IMGFMT' - }}} -{"return": {}} -{'execute': 'drive-backup', -'arguments': {'job-id': 'job0', -'device': 'drv0', -'target': 'TEST_DIR/o.IMGFMT', -'format': 'IMGFMT', -'sync': 'none'}} -Formatting 'TEST_DIR/o.IMGFMT', fmt=3DIMGFMT size=3D1048576 backing_file= =3DTEST_DIR/t.IMGFMT backing_fmt=3DIMGFMT -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} -{'execute': 'blockdev-del', - 'arguments': {'node-name': 'drv0'}} +{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"dr= iver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}} +{"return": {}} +{"execute": "drive-backup", "arguments": {"device": "drv0", "format": "IMG= FMT", "job-id": "job0", "sync": "none", "target": "TEST_DIR/PID-target"}} +{"return": {}} +{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: node is = used as backing hd of 'NODE_NAME'"}} -{'execute': 'block-job-cancel', - 'arguments': {'device': 'job0'}} +{"execute": "block-job-cancel", "arguments": {"device": "job0"}} {"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset= ": 0, "speed": 0, "type": "backup"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} -{'execute': 'blockdev-del', - 'arguments': {'node-name': 'drv0'}} +{"data": {"device": "job0", "len": 1048576, "offset": 0, "speed": 0, "type= ": "backup"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseconds":= "USECS", "seconds": "SECS"}} +{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} {"return": {}} =20 =3D=3D=3D Testing drive-mirror =3D=3D=3D - -{'execute': 'blockdev-add', - 'arguments': { - 'node-name': 'drv0', - 'driver': 'IMGFMT', - 'file': { - 'driver': 'file', - 'filename': 'TEST_DIR/t.IMGFMT' - }}} -{"return": {}} -{'execute': 'drive-mirror', -'arguments': {'job-id': 'job0', -'device': 'drv0', -'target': 'TEST_DIR/o.IMGFMT', -'format': 'IMGFMT', -'sync': 'none'}} -Formatting 'TEST_DIR/o.IMGFMT', fmt=3DIMGFMT size=3D1048576 backing_file= =3DTEST_DIR/t.IMGFMT backing_fmt=3DIMGFMT -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "spe= ed": 0, "type": "mirror"}} -{'execute': 'blockdev-del', - 'arguments': {'node-name': 'drv0'}} +{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"dr= iver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}} +{"return": {}} +{"execute": "drive-mirror", "arguments": {"device": "drv0", "format": "IMG= FMT", "job-id": "job0", "sync": "none", "target": "TEST_DIR/PID-target"}} +{"return": {}} +{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mi= rror"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", = "seconds": "SECS"}} +{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block de= vice is in use by block job: mirror"}} -{'execute': 'block-job-cancel', - 'arguments': {'device': 'job0'}} +{"execute": "block-job-cancel", "arguments": {"device": "job0"}} {"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, = "speed": 0, "type": "mirror"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} -{'execute': 'blockdev-del', - 'arguments': {'node-name': 'drv0'}} +{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "mi= rror"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USEC= S", "seconds": "SECS"}} +{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} {"return": {}} =20 =3D=3D=3D Testing active block-commit =3D=3D=3D - -{'execute': 'blockdev-add', - 'arguments': { - 'node-name': 'drv0', - 'driver': 'IMGFMT', - 'file': { - 'driver': 'file', - 'filename': 'TEST_DIR/t.IMGFMT' - }}} -{"return": {}} -{'execute': 'block-commit', -'arguments': {'job-id': 'job0', 'device': 'drv0'}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "spe= ed": 0, "type": "commit"}} -{'execute': 'blockdev-del', - 'arguments': {'node-name': 'drv0'}} +{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"dr= iver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}} +{"return": {}} +{"execute": "block-commit", "arguments": {"device": "drv0", "job-id": "job= 0"}} +{"return": {}} +{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "co= mmit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", = "seconds": "SECS"}} +{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block de= vice is in use by block job: commit"}} -{'execute': 'block-job-cancel', - 'arguments': {'device': 'job0'}} +{"execute": "block-job-cancel", "arguments": {"device": "job0"}} {"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, = "speed": 0, "type": "commit"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} -{'execute': 'blockdev-del', - 'arguments': {'node-name': 'drv0'}} +{"data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "co= mmit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USEC= S", "seconds": "SECS"}} +{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} {"return": {}} =20 =3D=3D=3D Testing non-active block-commit =3D=3D=3D - -wrote 1048576/1048576 bytes at offset 0 -1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -{'execute': 'blockdev-add', - 'arguments': { - 'node-name': 'drv0', - 'driver': 'IMGFMT', - 'file': { - 'driver': 'file', - 'filename': 'TEST_DIR/t.IMGFMT' - }}} -{"return": {}} -{'execute': 'block-commit', -'arguments': {'job-id': 'job0', -'device': 'drv0', -'top': 'TEST_DIR/m.IMGFMT', -'speed': 1}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} -{'execute': 'blockdev-del', - 'arguments': {'node-name': 'drv0'}} +{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"dr= iver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}} +{"return": {}} +{"execute": "block-commit", "arguments": {"device": "drv0", "job-id": "job= 0", "speed": 1, "top": "TEST_DIR/PID-middle"}} +{"return": {}} +{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block de= vice is in use by block job: commit"}} -{'execute': 'block-job-cancel', - 'arguments': {'device': 'job0'}} +{"execute": "block-job-cancel", "arguments": {"device": "job0"}} {"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset= ": 524288, "speed": 1, "type": "commit"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} -{'execute': 'blockdev-del', - 'arguments': {'node-name': 'drv0'}} +{"data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, = "type": "commit"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseco= nds": "USECS", "seconds": "SECS"}} +{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} {"return": {}} =20 =3D=3D=3D Testing block-stream =3D=3D=3D - -wrote 1048576/1048576 bytes at offset 0 -1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -{'execute': 'blockdev-add', - 'arguments': { - 'node-name': 'drv0', - 'driver': 'IMGFMT', - 'file': { - 'driver': 'file', - 'filename': 'TEST_DIR/t.IMGFMT' - }}} -{"return": {}} -{'execute': 'block-stream', -'arguments': {'job-id': 'job0', -'device': 'drv0', -'speed': 1}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}} -{'execute': 'blockdev-del', - 'arguments': {'node-name': 'drv0'}} +{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"dr= iver": "file", "filename": "TEST_DIR/PID-top"}, "node-name": "drv0"}} +{"return": {}} +{"execute": "block-stream", "arguments": {"device": "drv0", "job-id": "job= 0", "speed": 1}} +{"return": {}} +{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} {"error": {"class": "GenericError", "desc": "Node 'drv0' is busy: block de= vice is in use by block job: stream"}} -{'execute': 'block-job-cancel', - 'arguments': {'device': 'job0'}} +{"execute": "block-job-cancel", "arguments": {"device": "job0"}} {"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "aborting", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "BLOCK_JOB_CANCELLED", "data": {"device": "job0", "len": 1048576, "offset= ": 524288, "speed": 1, "type": "stream"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event"= : "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}} -{'execute': 'blockdev-del', - 'arguments': {'node-name': 'drv0'}} +{"data": {"device": "job0", "len": 1048576, "offset": 524288, "speed": 1, = "type": "stream"}, "event": "BLOCK_JOB_CANCELLED", "timestamp": {"microseco= nds": "USECS", "seconds": "SECS"}} +{"execute": "blockdev-del", "arguments": {"node-name": "drv0"}} {"return": {}} -*** done + --=20 2.43.0