From: Max Reitz <mreitz@redhat.com>
To: "Benoît Canet" <benoit.canet@irqsave.net>, qemu-devel@nongnu.org
Cc: kwolf@redhat.com, Benoit Canet <benoit@irqsave.net>, stefanha@redhat.com
Subject: Re: [Qemu-devel] [PATCH v9 4/4] qemu-iotests: Add TestRepairQuorum to 041 to test drive-mirror node-name mode.
Date: Sat, 14 Jun 2014 02:44:29 +0200 [thread overview]
Message-ID: <539B9AED.9060408@redhat.com> (raw)
In-Reply-To: <1402493053-13787-5-git-send-email-benoit.canet@irqsave.net>
On 11.06.2014 15:24, Benoît Canet wrote:
> The to-replace-node-name is designed to allow repairing of broken Quorum file.
"a broken Quorum file" or "broken Quorum files".
> This patch introduce a new class TestRepairQuorum testing that the feature
*introduces
> works.
> Some further work will be done on QEMU to improve the robutness of the tests.
*robustness
> Signed-off-by: Benoit Canet <benoit@irqsave.net>
> ---
> tests/qemu-iotests/041 | 196 ++++++++++++++++++++++++++++++++++++++++++++-
> tests/qemu-iotests/041.out | 4 +-
> 2 files changed, 194 insertions(+), 6 deletions(-)
>
> diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
> index ec470b2..c0480e1 100755
> --- a/tests/qemu-iotests/041
> +++ b/tests/qemu-iotests/041
> @@ -28,6 +28,12 @@ target_backing_img = os.path.join(iotests.test_dir, 'target-backing.img')
> test_img = os.path.join(iotests.test_dir, 'test.img')
> target_img = os.path.join(iotests.test_dir, 'target.img')
>
> +quorum_img1 = os.path.join(iotests.test_dir, 'quorum1.img')
> +quorum_img2 = os.path.join(iotests.test_dir, 'quorum2.img')
> +quorum_img3 = os.path.join(iotests.test_dir, 'quorum3.img')
> +quorum_repair_img = os.path.join(iotests.test_dir, 'quorum_repair.img')
> +quorum_snapshot_file = os.path.join(iotests.test_dir, 'quorum_snapshot.img')
> +
> class ImageMirroringTestCase(iotests.QMPTestCase):
> '''Abstract base class for image mirroring test cases'''
>
> @@ -42,8 +48,8 @@ class ImageMirroringTestCase(iotests.QMPTestCase):
> ready = True
>
> def wait_ready_and_cancel(self, drive='drive0'):
> - self.wait_ready(drive)
> - event = self.cancel_and_wait()
> + self.wait_ready(drive=drive)
> + event = self.cancel_and_wait(drive=drive)
My Python is very bad (if existent at all), but is this "drive=drive"
really necessary? Wouldn't simply "drive" suffice?
> self.assertEquals(event['event'], 'BLOCK_JOB_COMPLETED')
> self.assert_qmp(event, 'data/type', 'mirror')
> self.assert_qmp(event, 'data/offset', self.image_len)
> @@ -52,12 +58,12 @@ class ImageMirroringTestCase(iotests.QMPTestCase):
> def complete_and_wait(self, drive='drive0', wait_ready=True):
> '''Complete a block job and wait for it to finish'''
> if wait_ready:
> - self.wait_ready()
> + self.wait_ready(drive=drive)
>
> result = self.vm.qmp('block-job-complete', device=drive)
> self.assert_qmp(result, 'return', {})
>
> - event = self.wait_until_completed()
> + event = self.wait_until_completed(drive=drive)
> self.assert_qmp(event, 'data/type', 'mirror')
>
> class TestSingleDrive(ImageMirroringTestCase):
> @@ -718,5 +724,187 @@ class TestUnbackedSource(ImageMirroringTestCase):
> self.complete_and_wait()
> self.assert_no_active_block_jobs()
>
> +class TestRepairQuorum(ImageMirroringTestCase):
> + """ This class test quorum file repair using drive-mirror.
> + It's mostly a fork of TestSingleDrive """
> + image_len = 1 * 1024 * 1024 # MB
> + IMAGES = [ quorum_img1, quorum_img2, quorum_img3 ]
> +
> + def setUp(self):
> + self.vm = iotests.VM()
> +
> + # Add each individual quorum images
> + for i in self.IMAGES:
> + qemu_img('create', '-f', iotests.imgfmt, i,
> + str(TestSingleDrive.image_len))
> + # Assign a node name to each quorum image in order to manipulate
> + # them
> + opts = "node-name=img%i" % self.IMAGES.index(i)
> + self.vm = self.vm.add_drive(i, opts)
Just an idea: As you are constantly swapping out img1, why don't you
write some data to img2 and img3 and different data to img1 to test it
all how it's supposed to work?
> +
> + self.vm.launch()
> +
> + #assemble the quorum block device from the individual files
> + args = { "options" : { "driver": "quorum", "id": "quorum0",
> + "vote-threshold": 2, "children": [ "img0", "img1", "img2" ] } }
> + result = self.vm.qmp("blockdev-add", **args)
> + self.assert_qmp(result, 'return', {})
> +
> +
> + def tearDown(self):
> + self.vm.shutdown()
> + for i in self.IMAGES + [ quorum_repair_img ]:
> + # Do a try/except because the test may have deleted some images
> + try:
> + os.remove(i)
> + except OSError:
> + pass
> +
> + def test_complete(self):
> + self.assert_no_active_block_jobs()
> +
> + result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
> + node_name="repair0",
> + replaces="img1",
> + target=quorum_repair_img, format=iotests.imgfmt)
> + self.assert_qmp(result, 'return', {})
> +
> + self.complete_and_wait(drive="quorum0")
> + result = self.vm.qmp('query-named-block-nodes')
> + self.assert_qmp(result, 'return[0]/file', quorum_repair_img)
Hm, why do you know this is at index 0?
> + # TODO: a better test requiring some QEMU infrastructure will be added
> + # to check that this file is really driven by quorum
> + self.vm.shutdown()
> + self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img),
> + 'target image does not match source after mirroring')
> +
> + def test_cancel(self):
> + self.assert_no_active_block_jobs()
> +
> + result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
> + node_name="repair0",
> + replaces="img1",
> + target=quorum_repair_img, format=iotests.imgfmt)
> + self.assert_qmp(result, 'return', {})
> +
> + self.cancel_and_wait(drive="quorum0", force=True)
> + # here we check that the last registered quorum file has not been
> + # swapped out and unref
> + result = self.vm.qmp('query-named-block-nodes')
> + self.assert_qmp(result, 'return[0]/file', quorum_img3)
Why would img3 be affected at all? Aren't you trying to replace img1?
(Also, again, why index 0?)
> + self.vm.shutdown()
> +
> + def test_cancel_after_ready(self):
> + self.assert_no_active_block_jobs()
> +
> + result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
> + node_name="repair0",
> + replaces="img1",
> + target=quorum_repair_img, format=iotests.imgfmt)
> + self.assert_qmp(result, 'return', {})
> +
> + self.wait_ready_and_cancel(drive="quorum0")
> + result = self.vm.qmp('query-named-block-nodes')
> + # here we check that the last registered quorum file has not been
> + # swapped out and unref
> + self.assert_qmp(result, 'return[0]/file', quorum_img3)
Same here.
> + self.vm.shutdown()
> + self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img),
> + 'target image does not match source after mirroring')
> +
> + def test_pause(self):
> + self.assert_no_active_block_jobs()
> +
> + result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
> + node_name="repair0",
> + replaces="img1",
> + target=quorum_repair_img, format=iotests.imgfmt)
> + self.assert_qmp(result, 'return', {})
> +
> + result = self.vm.qmp('block-job-pause', device='quorum0')
> + self.assert_qmp(result, 'return', {})
> +
> + time.sleep(1)
> + result = self.vm.qmp('query-block-jobs')
> + offset = self.dictpath(result, 'return[0]/offset')
> +
> + time.sleep(1)
> + result = self.vm.qmp('query-block-jobs')
> + self.assert_qmp(result, 'return[0]/offset', offset)
> +
> + result = self.vm.qmp('block-job-resume', device='quorum0')
> + self.assert_qmp(result, 'return', {})
> +
> + self.complete_and_wait(drive="quorum0")
> + self.vm.shutdown()
> + self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img),
> + 'target image does not match source after mirroring')
> +
> + def test_medium_not_found(self):
> + result = self.vm.qmp('drive-mirror', device='ide1-cd0', sync='full',
I don't know whether this device is supposed to exist forever, but if it
disappears from default configuration one day, TestSingleDrive will
break as well, so it's probably fine.
Max
> + node_name='repair0',
> + replaces='img1',
> + target=quorum_repair_img, format=iotests.imgfmt)
> + self.assert_qmp(result, 'error/class', 'GenericError')
> +
> + def test_image_not_found(self):
> + result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
> + node_name='repair0',
> + replaces='img1',
> + mode='existing',
> + target=quorum_repair_img, format=iotests.imgfmt)
> + self.assert_qmp(result, 'error/class', 'GenericError')
> +
> + def test_device_not_found(self):
> + result = self.vm.qmp('drive-mirror', device='nonexistent', sync='full',
> + node_name='repair0',
> + replaces='img1',
> + target=quorum_repair_img, format=iotests.imgfmt)
> + self.assert_qmp(result, 'error/class', 'DeviceNotFound')
> +
> + def test_wrong_sync_mode(self):
> + result = self.vm.qmp('drive-mirror', device='quorum0',
> + node_name='repair0',
> + replaces='img1',
> + target=quorum_repair_img, format=iotests.imgfmt)
> + self.assert_qmp(result, 'error/class', 'GenericError')
> +
> + def test_no_node_name(self):
> + result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
> + replaces='img1',
> + target=quorum_repair_img, format=iotests.imgfmt)
> + self.assert_qmp(result, 'error/class', 'GenericError')
> +
> + def test_unexistant_replaces(self):
> + result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
> + node_name='repair0',
> + replaces='img77',
> + target=quorum_repair_img, format=iotests.imgfmt)
> + self.assert_qmp(result, 'error/class', 'GenericError')
> +
> + def test_after_a_quorum_snapshot(self):
> + result = self.vm.qmp('blockdev-snapshot-sync', node_name='img1',
> + snapshot_file=quorum_snapshot_file,
> + snapshot_node_name="snap1");
> +
> + result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
> + node_name='repair0',
> + replaces="img1",
> + target=quorum_repair_img, format=iotests.imgfmt)
> + self.assert_qmp(result, 'error/class', 'GenericError')
> +
> + result = self.vm.qmp('drive-mirror', device='quorum0', sync='full',
> + node_name='repair0',
> + replaces="snap1",
> + target=quorum_repair_img, format=iotests.imgfmt)
> + self.assert_qmp(result, 'return', {})
> +
> + self.complete_and_wait(drive="quorum0")
> + result = self.vm.qmp('query-named-block-nodes')
> + self.assert_qmp(result, 'return[0]/file', quorum_repair_img)
> + # TODO: a better test requiring some QEMU infrastructure will be added
> + # to check that this file is really driven by quorum
> + self.vm.shutdown()
> +
> if __name__ == '__main__':
> iotests.main(supported_fmts=['qcow2', 'qed'])
> diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
> index 6d9bee1..73e375a 100644
> --- a/tests/qemu-iotests/041.out
> +++ b/tests/qemu-iotests/041.out
> @@ -1,5 +1,5 @@
> -...........................
> +......................................
> ----------------------------------------------------------------------
> -Ran 27 tests
> +Ran 38 tests
>
> OK
next prev parent reply other threads:[~2014-06-14 0:44 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-11 13:24 [Qemu-devel] [PATCH v9 0/4] Quorum maintainance operations Benoît Canet
2014-06-11 13:24 ` [Qemu-devel] [PATCH v9 1/4] quorum: Add the rewrite-corrupted parameter to quorum Benoît Canet
2014-06-13 23:07 ` Max Reitz
2014-06-11 13:24 ` [Qemu-devel] [PATCH v9 2/4] block: Add node-name argument to drive-mirror Benoît Canet
2014-06-13 23:15 ` Max Reitz
2014-06-11 13:24 ` [Qemu-devel] [PATCH v9 3/4] block: Add replaces " Benoît Canet
2014-06-13 23:59 ` Max Reitz
2014-06-11 13:24 ` [Qemu-devel] [PATCH v9 4/4] qemu-iotests: Add TestRepairQuorum to 041 to test drive-mirror node-name mode Benoît Canet
2014-06-14 0:44 ` Max Reitz [this message]
2014-06-16 9:58 ` Benoît Canet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=539B9AED.9060408@redhat.com \
--to=mreitz@redhat.com \
--cc=benoit.canet@irqsave.net \
--cc=benoit@irqsave.net \
--cc=kwolf@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.