diff mbox series

[v4,4/5] iotests: Add VMDK tests for blockdev-create

Message ID 20181207115343.6747-5-kwolf@redhat.com
State New
Headers show
Series vmdk: Implement blockdev-create | expand

Commit Message

Kevin Wolf Dec. 7, 2018, 11:53 a.m. UTC
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 tests/qemu-iotests/237     | 233 +++++++++++++++++++++++++
 tests/qemu-iotests/237.out | 347 +++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/group   |   1 +
 3 files changed, 581 insertions(+)
 create mode 100755 tests/qemu-iotests/237
 create mode 100644 tests/qemu-iotests/237.out

Comments

Markus Armbruster Dec. 7, 2018, 1:02 p.m. UTC | #1
Kevin Wolf <kwolf@redhat.com> writes:

> Signed-off-by: Fam Zheng <famz@redhat.com>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  tests/qemu-iotests/237     | 233 +++++++++++++++++++++++++
>  tests/qemu-iotests/237.out | 347 +++++++++++++++++++++++++++++++++++++
>  tests/qemu-iotests/group   |   1 +
>  3 files changed, 581 insertions(+)
>  create mode 100755 tests/qemu-iotests/237
>  create mode 100644 tests/qemu-iotests/237.out
>
> diff --git a/tests/qemu-iotests/237 b/tests/qemu-iotests/237
> new file mode 100755
> index 0000000000..e04a1ac6be
> --- /dev/null
> +++ b/tests/qemu-iotests/237
> @@ -0,0 +1,233 @@
> +#!/usr/bin/env python
> +#
> +# Test vmdk and file image creation
> +#
> +# Copyright (C) 2018 Red Hat, Inc.
> +#
> +# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
> +#
> +# 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 <http://www.gnu.org/licenses/>.
> +#
> +
> +import iotests
> +from iotests import imgfmt
> +
> +iotests.verify_image_format(supported_fmts=['vmdk'])
> +
> +def blockdev_create(vm, options):
> +    result = vm.qmp_log('blockdev-create', job_id='job0', options=options)
> +
> +    if 'return' in result:
> +        assert result['return'] == {}
> +        vm.run_job('job0')
> +    iotests.log("")
> +
> +with iotests.FilePath('t.vmdk') as disk_path, \
> +     iotests.FilePath('t.vmdk.1') as extent1_path, \
> +     iotests.FilePath('t.vmdk.2') as extent2_path, \
> +     iotests.FilePath('t.vmdk.3') as extent3_path, \
> +     iotests.VM() as vm:
> +
> +    #
> +    # Successful image creation (defaults)
> +    #
> +    iotests.log("=== Successful image creation (defaults) ===")
> +    iotests.log("")
> +
> +    size = 5 * 1024 * 1024 * 1024
> +
> +    vm.launch()
> +    blockdev_create(vm, { 'driver': 'file',
> +                          'filename': disk_path,
> +                          'size': 0 })
> +
> +    vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
> +               node_name='imgfile')
> +
> +    blockdev_create(vm, { 'driver': imgfmt,
> +                          'file': 'imgfile',
> +                          'size': size })
> +    vm.shutdown()
> +
> +    iotests.img_info_log(disk_path)
> +
> +    #
> +    # Successful image creation (inline blockdev-add, explicit defaults)
> +    #
> +    iotests.log("=== Successful image creation (inline blockdev-add, explicit defaults) ===")
> +    iotests.log("")
> +
> +    # Choose a different size to show that we got a new image
> +    size = 64 * 1024 * 1024
> +
> +    vm.launch()
> +    blockdev_create(vm, { 'driver': 'file',
> +                          'filename': disk_path,
> +                          'size': 0 })
> +
> +    blockdev_create(vm, { 'driver': imgfmt,
> +                          'file': {
> +                              'driver': 'file',
> +                              'filename': disk_path,
> +                          },
> +                          'size': size,
> +                          'extents': [],
> +                          'subformat': 'monolithicSparse',
> +                          'adapter-type': 'ide',
> +                          'hwversion': '4',
> +                          'zeroed-grain': False })
> +    vm.shutdown()
> +
> +    iotests.img_info_log(disk_path)
> +
> +    #
> +    # Successful image creation (non-default options)
> +    #
> +    iotests.log("=== Successful image creation (with non-default options) ===")
> +    iotests.log("")
> +
> +    # Choose a different size to show that we got a new image
> +    size = 32 * 1024 * 1024
> +
> +    vm.launch()
> +    blockdev_create(vm, { 'driver': 'file',
> +                          'filename': disk_path,
> +                          'size': 0 })
> +
> +    blockdev_create(vm, { 'driver': imgfmt,
> +                          'file': {
> +                              'driver': 'file',
> +                              'filename': disk_path,
> +                          },
> +                          'size': size,
> +                          'extents': [],
> +                          'subformat': 'monolithicSparse',
> +                          'adapter-type': 'buslogic',
> +                          'zeroed-grain': True })
> +    vm.shutdown()
> +
> +    iotests.img_info_log(disk_path)
> +
> +    #
> +    # Invalid BlockdevRef
> +    #
> +    iotests.log("=== Invalid BlockdevRef ===")
> +    iotests.log("")
> +
> +    vm.launch()
> +    blockdev_create(vm, { 'driver': imgfmt,
> +                          'file': "this doesn't exist",
> +                          'size': size })
> +    vm.shutdown()
> +
> +    #
> +    # Adapter types
> +    #
> +
> +    iotests.log("=== Adapter types ===")
> +    iotests.log("")
> +
> +    vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
> +
> +    # Valid
> +    iotests.log("== Valid adapter types ==")
> +    iotests.log("")
> +
> +    vm.launch()
> +    for adapter_type in [ 'ide', 'buslogic', 'lsilogic', 'legacyESX' ]:
> +        blockdev_create(vm, { 'driver': imgfmt,
> +                              'file': 'node0',
> +                              'size': size,
> +                              'adapter-type': adapter_type })
> +    vm.shutdown()
> +
> +    # Invalid
> +    iotests.log("== Invalid adapter types ==")
> +    iotests.log("")
> +
> +    vm.launch()
> +    for adapter_type in [ 'foo', 'IDE', 'legacyesx', 1 ]:
> +        blockdev_create(vm, { 'driver': imgfmt,
> +                              'file': 'node0',
> +                              'size': size,
> +                              'adapter-type': adapter_type })
> +    vm.shutdown()
> +
> +    #
> +    # Other subformats
> +    #
> +    iotests.log("=== Other subformats ===")
> +    iotests.log("")
> +
> +    for path in [ extent1_path, extent2_path, extent3_path ]:
> +        msg = iotests.qemu_img_pipe('create', '-f', imgfmt, path, '0')
> +        iotests.log(msg, [iotests.filter_testfiles])
> +

You lost

  +    vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))

here since v3.  Intentional?

> +    vm.add_blockdev('driver=file,filename=%s,node-name=ext1' % (extent1_path))
> +    vm.add_blockdev('driver=file,filename=%s,node-name=ext2' % (extent2_path))
> +    vm.add_blockdev('driver=file,filename=%s,node-name=ext3' % (extent3_path))
[...]
Markus Armbruster Dec. 7, 2018, 1:12 p.m. UTC | #2
git-am complains

    Applying: iotests: Add VMDK tests for blockdev-create
    .git/rebase-apply/patch:281: trailing whitespace.
                format: 
    .git/rebase-apply/patch:308: trailing whitespace.
                format: 
    .git/rebase-apply/patch:335: trailing whitespace.
                format: 
    .git/rebase-apply/patch:600: new blank line at EOF.
    +
    warning: 4 lines add whitespace errors.
Kevin Wolf Dec. 7, 2018, 2:45 p.m. UTC | #3
Am 07.12.2018 um 14:12 hat Markus Armbruster geschrieben:
> git-am complains
> 
>     Applying: iotests: Add VMDK tests for blockdev-create
>     .git/rebase-apply/patch:281: trailing whitespace.
>                 format: 
>     .git/rebase-apply/patch:308: trailing whitespace.
>                 format: 
>     .git/rebase-apply/patch:335: trailing whitespace.
>                 format: 
>     .git/rebase-apply/patch:600: new blank line at EOF.
>     +
>     warning: 4 lines add whitespace errors.

This is in the reference output, so trailing whitespace/blank lines are
actually correct.

Kevin
Eric Blake Dec. 7, 2018, 3:40 p.m. UTC | #4
On 12/7/18 8:45 AM, Kevin Wolf wrote:
> Am 07.12.2018 um 14:12 hat Markus Armbruster geschrieben:
>> git-am complains
>>
>>      Applying: iotests: Add VMDK tests for blockdev-create
>>      .git/rebase-apply/patch:281: trailing whitespace.
>>                  format:
>>      .git/rebase-apply/patch:308: trailing whitespace.
>>                  format:
>>      .git/rebase-apply/patch:335: trailing whitespace.
>>                  format:
>>      .git/rebase-apply/patch:600: new blank line at EOF.
>>      +
>>      warning: 4 lines add whitespace errors.
> 
> This is in the reference output, so trailing whitespace/blank lines are
> actually correct.

Ah, but doesn't ./check already ignore differences in trailing 
whitespace present in the actual running that is not present in the 
*.out files, precisely so we don't have to check in trailing whitespace 
reference outputs?
Kevin Wolf Dec. 7, 2018, 4:42 p.m. UTC | #5
Am 07.12.2018 um 16:40 hat Eric Blake geschrieben:
> On 12/7/18 8:45 AM, Kevin Wolf wrote:
> > Am 07.12.2018 um 14:12 hat Markus Armbruster geschrieben:
> > > git-am complains
> > > 
> > >      Applying: iotests: Add VMDK tests for blockdev-create
> > >      .git/rebase-apply/patch:281: trailing whitespace.
> > >                  format:
> > >      .git/rebase-apply/patch:308: trailing whitespace.
> > >                  format:
> > >      .git/rebase-apply/patch:335: trailing whitespace.
> > >                  format:
> > >      .git/rebase-apply/patch:600: new blank line at EOF.
> > >      +
> > >      warning: 4 lines add whitespace errors.
> > 
> > This is in the reference output, so trailing whitespace/blank lines are
> > actually correct.
> 
> Ah, but doesn't ./check already ignore differences in trailing whitespace
> present in the actual running that is not present in the *.out files,
> precisely so we don't have to check in trailing whitespace reference
> outputs?

It does ignore whitespace changes, so even if we remove that whitespace,
the test won't fail. But I don't think that's a good reason to check in
inaccurate reference output.

There are a few test cases that have a reference output like this and
it's always annoying: When I later add a new subtest, I add the new test
code, review the ./check output and if it looks good, I do something
like 'cp 237.out.bad 237.out'. At that point, I'll have to manually
revert completely unrelated whitespace changes again.

Some 'git am' warnings feel like the lesser evil to me.

Kevin
Eric Blake Dec. 7, 2018, 4:52 p.m. UTC | #6
On 12/7/18 10:42 AM, Kevin Wolf wrote:
> Am 07.12.2018 um 16:40 hat Eric Blake geschrieben:
>> On 12/7/18 8:45 AM, Kevin Wolf wrote:
>>> Am 07.12.2018 um 14:12 hat Markus Armbruster geschrieben:
>>>> git-am complains
>>>>
>>>>       Applying: iotests: Add VMDK tests for blockdev-create
>>>>       .git/rebase-apply/patch:281: trailing whitespace.
>>>>                   format:
>>>>       .git/rebase-apply/patch:308: trailing whitespace.
>>>>                   format:
>>>>       .git/rebase-apply/patch:335: trailing whitespace.
>>>>                   format:
>>>>       .git/rebase-apply/patch:600: new blank line at EOF.
>>>>       +
>>>>       warning: 4 lines add whitespace errors.
>>>
>>> This is in the reference output, so trailing whitespace/blank lines are
>>> actually correct.
>>
>> Ah, but doesn't ./check already ignore differences in trailing whitespace
>> present in the actual running that is not present in the *.out files,
>> precisely so we don't have to check in trailing whitespace reference
>> outputs?
> 
> It does ignore whitespace changes, so even if we remove that whitespace,
> the test won't fail. But I don't think that's a good reason to check in
> inaccurate reference output.
> 
> There are a few test cases that have a reference output like this and
> it's always annoying: When I later add a new subtest, I add the new test
> code, review the ./check output and if it looks good, I do something
> like 'cp 237.out.bad 237.out'. At that point, I'll have to manually
> revert completely unrelated whitespace changes again.

Is it worth teaching iotests.img_info_log() to strip trailing 
whitespace?  Or even to teach qemu-img itself to quit generating 
trailing whitespace?

> 
> Some 'git am' warnings feel like the lesser evil to me.

True, and a comment in the commit message about intentionally triggering 
a known checkpatch flag goes a long ways to document why you want the 
trailing whitespace (assuming we don't instead decide to tackle a root 
cause of having the whitespace in the first place).
Kevin Wolf Dec. 7, 2018, 5:09 p.m. UTC | #7
Am 07.12.2018 um 17:52 hat Eric Blake geschrieben:
> On 12/7/18 10:42 AM, Kevin Wolf wrote:
> > Am 07.12.2018 um 16:40 hat Eric Blake geschrieben:
> > > On 12/7/18 8:45 AM, Kevin Wolf wrote:
> > > > Am 07.12.2018 um 14:12 hat Markus Armbruster geschrieben:
> > > > > git-am complains
> > > > > 
> > > > >       Applying: iotests: Add VMDK tests for blockdev-create
> > > > >       .git/rebase-apply/patch:281: trailing whitespace.
> > > > >                   format:
> > > > >       .git/rebase-apply/patch:308: trailing whitespace.
> > > > >                   format:
> > > > >       .git/rebase-apply/patch:335: trailing whitespace.
> > > > >                   format:
> > > > >       .git/rebase-apply/patch:600: new blank line at EOF.
> > > > >       +
> > > > >       warning: 4 lines add whitespace errors.
> > > > 
> > > > This is in the reference output, so trailing whitespace/blank lines are
> > > > actually correct.
> > > 
> > > Ah, but doesn't ./check already ignore differences in trailing whitespace
> > > present in the actual running that is not present in the *.out files,
> > > precisely so we don't have to check in trailing whitespace reference
> > > outputs?
> > 
> > It does ignore whitespace changes, so even if we remove that whitespace,
> > the test won't fail. But I don't think that's a good reason to check in
> > inaccurate reference output.
> > 
> > There are a few test cases that have a reference output like this and
> > it's always annoying: When I later add a new subtest, I add the new test
> > code, review the ./check output and if it looks good, I do something
> > like 'cp 237.out.bad 237.out'. At that point, I'll have to manually
> > revert completely unrelated whitespace changes again.
> 
> Is it worth teaching iotests.img_info_log() to strip trailing whitespace?
> Or even to teach qemu-img itself to quit generating trailing whitespace?

Not sure if it's worth it, but if someone proposed such a change, I
wouldn't object anyway.

> > Some 'git am' warnings feel like the lesser evil to me.
> 
> True, and a comment in the commit message about intentionally triggering a
> known checkpatch flag goes a long ways to document why you want the trailing
> whitespace (assuming we don't instead decide to tackle a root cause of
> having the whitespace in the first place).

Fair enough. Once it's merged, it doesn't make a difference any more,
but it could have made review a bit easier.

Kevin
diff mbox series

Patch

diff --git a/tests/qemu-iotests/237 b/tests/qemu-iotests/237
new file mode 100755
index 0000000000..e04a1ac6be
--- /dev/null
+++ b/tests/qemu-iotests/237
@@ -0,0 +1,233 @@ 
+#!/usr/bin/env python
+#
+# Test vmdk and file image creation
+#
+# Copyright (C) 2018 Red Hat, Inc.
+#
+# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+
+import iotests
+from iotests import imgfmt
+
+iotests.verify_image_format(supported_fmts=['vmdk'])
+
+def blockdev_create(vm, options):
+    result = vm.qmp_log('blockdev-create', job_id='job0', options=options)
+
+    if 'return' in result:
+        assert result['return'] == {}
+        vm.run_job('job0')
+    iotests.log("")
+
+with iotests.FilePath('t.vmdk') as disk_path, \
+     iotests.FilePath('t.vmdk.1') as extent1_path, \
+     iotests.FilePath('t.vmdk.2') as extent2_path, \
+     iotests.FilePath('t.vmdk.3') as extent3_path, \
+     iotests.VM() as vm:
+
+    #
+    # Successful image creation (defaults)
+    #
+    iotests.log("=== Successful image creation (defaults) ===")
+    iotests.log("")
+
+    size = 5 * 1024 * 1024 * 1024
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': 'file',
+                          'filename': disk_path,
+                          'size': 0 })
+
+    vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
+               node_name='imgfile')
+
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': 'imgfile',
+                          'size': size })
+    vm.shutdown()
+
+    iotests.img_info_log(disk_path)
+
+    #
+    # Successful image creation (inline blockdev-add, explicit defaults)
+    #
+    iotests.log("=== Successful image creation (inline blockdev-add, explicit defaults) ===")
+    iotests.log("")
+
+    # Choose a different size to show that we got a new image
+    size = 64 * 1024 * 1024
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': 'file',
+                          'filename': disk_path,
+                          'size': 0 })
+
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': {
+                              'driver': 'file',
+                              'filename': disk_path,
+                          },
+                          'size': size,
+                          'extents': [],
+                          'subformat': 'monolithicSparse',
+                          'adapter-type': 'ide',
+                          'hwversion': '4',
+                          'zeroed-grain': False })
+    vm.shutdown()
+
+    iotests.img_info_log(disk_path)
+
+    #
+    # Successful image creation (non-default options)
+    #
+    iotests.log("=== Successful image creation (with non-default options) ===")
+    iotests.log("")
+
+    # Choose a different size to show that we got a new image
+    size = 32 * 1024 * 1024
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': 'file',
+                          'filename': disk_path,
+                          'size': 0 })
+
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': {
+                              'driver': 'file',
+                              'filename': disk_path,
+                          },
+                          'size': size,
+                          'extents': [],
+                          'subformat': 'monolithicSparse',
+                          'adapter-type': 'buslogic',
+                          'zeroed-grain': True })
+    vm.shutdown()
+
+    iotests.img_info_log(disk_path)
+
+    #
+    # Invalid BlockdevRef
+    #
+    iotests.log("=== Invalid BlockdevRef ===")
+    iotests.log("")
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': "this doesn't exist",
+                          'size': size })
+    vm.shutdown()
+
+    #
+    # Adapter types
+    #
+
+    iotests.log("=== Adapter types ===")
+    iotests.log("")
+
+    vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
+
+    # Valid
+    iotests.log("== Valid adapter types ==")
+    iotests.log("")
+
+    vm.launch()
+    for adapter_type in [ 'ide', 'buslogic', 'lsilogic', 'legacyESX' ]:
+        blockdev_create(vm, { 'driver': imgfmt,
+                              'file': 'node0',
+                              'size': size,
+                              'adapter-type': adapter_type })
+    vm.shutdown()
+
+    # Invalid
+    iotests.log("== Invalid adapter types ==")
+    iotests.log("")
+
+    vm.launch()
+    for adapter_type in [ 'foo', 'IDE', 'legacyesx', 1 ]:
+        blockdev_create(vm, { 'driver': imgfmt,
+                              'file': 'node0',
+                              'size': size,
+                              'adapter-type': adapter_type })
+    vm.shutdown()
+
+    #
+    # Other subformats
+    #
+    iotests.log("=== Other subformats ===")
+    iotests.log("")
+
+    for path in [ extent1_path, extent2_path, extent3_path ]:
+        msg = iotests.qemu_img_pipe('create', '-f', imgfmt, path, '0')
+        iotests.log(msg, [iotests.filter_testfiles])
+
+    vm.add_blockdev('driver=file,filename=%s,node-name=ext1' % (extent1_path))
+    vm.add_blockdev('driver=file,filename=%s,node-name=ext2' % (extent2_path))
+    vm.add_blockdev('driver=file,filename=%s,node-name=ext3' % (extent3_path))
+
+    # Missing extent
+    iotests.log("== Missing extent ==")
+    iotests.log("")
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': 'node0',
+                          'size': size,
+                          'subformat': 'monolithicFlat' })
+    vm.shutdown()
+
+    # Correct extent
+    iotests.log("== Correct extent ==")
+    iotests.log("")
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': 'node0',
+                          'size': size,
+                          'subformat': 'monolithicFlat',
+                          'extents': ['ext1'] })
+    vm.shutdown()
+
+    # Extra extent
+    iotests.log("== Extra extent ==")
+    iotests.log("")
+
+    vm.launch()
+    blockdev_create(vm, { 'driver': imgfmt,
+                          'file': 'node0',
+                          'size': 512,
+                          'subformat': 'monolithicFlat',
+                          'extents': ['ext1', 'ext2', 'ext3'] })
+    vm.shutdown()
+
+    # Split formats
+    iotests.log("== Split formats ==")
+    iotests.log("")
+
+    for size in [ 512, 1073741824, 2147483648, 5368709120 ]:
+        for subfmt in [ 'twoGbMaxExtentFlat', 'twoGbMaxExtentSparse' ]:
+            iotests.log("= %s %d =" % (subfmt, size))
+            iotests.log("")
+
+            vm.launch()
+            blockdev_create(vm, { 'driver': imgfmt,
+                                  'file': 'node0',
+                                  'size': size,
+                                  'subformat': subfmt,
+                                  'extents': ['ext1', 'ext2', 'ext3'] })
+            vm.shutdown()
+
+            iotests.img_info_log(disk_path)
diff --git a/tests/qemu-iotests/237.out b/tests/qemu-iotests/237.out
new file mode 100644
index 0000000000..1aa9aad349
--- /dev/null
+++ b/tests/qemu-iotests/237.out
@@ -0,0 +1,347 @@ 
+=== Successful image creation (defaults) ===
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "size": 0}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "node_name": "imgfile"}}
+{"return": {}}
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "file": "imgfile", "size": 5368709120}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 5.0G (5368709120 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: monolithicSparse
+    extents:
+        [0]:
+            virtual size: 5368709120
+            filename: TEST_IMG
+            cluster size: 65536
+            format: 
+
+=== Successful image creation (inline blockdev-add, explicit defaults) ===
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "size": 0}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "ide", "driver": "vmdk", "extents": [], "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk"}, "hwversion": "4", "size": 67108864, "subformat": "monolithicSparse", "zeroed-grain": false}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 64M (67108864 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: monolithicSparse
+    extents:
+        [0]:
+            virtual size: 67108864
+            filename: TEST_IMG
+            cluster size: 65536
+            format: 
+
+=== Successful image creation (with non-default options) ===
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "size": 0}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "buslogic", "driver": "vmdk", "extents": [], "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk"}, "size": 33554432, "subformat": "monolithicSparse", "zeroed-grain": true}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 32M (33554432 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: monolithicSparse
+    extents:
+        [0]:
+            virtual size: 33554432
+            filename: TEST_IMG
+            cluster size: 65536
+            format: 
+
+=== Invalid BlockdevRef ===
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "file": "this doesn't exist", "size": 33554432}}}
+{"return": {}}
+Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+=== Adapter types ===
+
+== Valid adapter types ==
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "ide", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "buslogic", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "lsilogic", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "legacyESX", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+== Invalid adapter types ==
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "foo", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"error": {"class": "GenericError", "desc": "Invalid parameter 'foo'"}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "IDE", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"error": {"class": "GenericError", "desc": "Invalid parameter 'IDE'"}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "legacyesx", "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"error": {"class": "GenericError", "desc": "Invalid parameter 'legacyesx'"}}
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": 1, "driver": "vmdk", "file": "node0", "size": 33554432}}}
+{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'options.adapter-type', expected: string"}}
+
+=== Other subformats ===
+
+Formatting 'TEST_DIR/PID-t.vmdk.1', fmt=vmdk size=0 compat6=off hwversion=undefined
+
+Formatting 'TEST_DIR/PID-t.vmdk.2', fmt=vmdk size=0 compat6=off hwversion=undefined
+
+Formatting 'TEST_DIR/PID-t.vmdk.3', fmt=vmdk size=0 compat6=off hwversion=undefined
+
+== Missing extent ==
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "file": "node0", "size": 33554432, "subformat": "monolithicFlat"}}}
+{"return": {}}
+Job failed: Extent [0] not specified
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+== Correct extent ==
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 33554432, "subformat": "monolithicFlat"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+== Extra extent ==
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "monolithicFlat"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+== Split formats ==
+
+= twoGbMaxExtentFlat 512 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentFlat"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 512 (512 bytes)
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentFlat
+    extents:
+        [0]:
+            virtual size: 512
+            filename: TEST_IMG.1
+            format: FLAT
+
+= twoGbMaxExtentSparse 512 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentSparse"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 512 (512 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentSparse
+    extents:
+        [0]:
+            virtual size: 512
+            filename: TEST_IMG.1
+            cluster size: 65536
+            format: SPARSE
+
+= twoGbMaxExtentFlat 1073741824 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentFlat"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 1.0G (1073741824 bytes)
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentFlat
+    extents:
+        [0]:
+            virtual size: 1073741824
+            filename: TEST_IMG.1
+            format: FLAT
+
+= twoGbMaxExtentSparse 1073741824 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentSparse"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 1.0G (1073741824 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentSparse
+    extents:
+        [0]:
+            virtual size: 1073741824
+            filename: TEST_IMG.1
+            cluster size: 65536
+            format: SPARSE
+
+= twoGbMaxExtentFlat 2147483648 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentFlat"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 2.0G (2147483648 bytes)
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentFlat
+    extents:
+        [0]:
+            virtual size: 2147483648
+            filename: TEST_IMG.1
+            format: FLAT
+
+= twoGbMaxExtentSparse 2147483648 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentSparse"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 2.0G (2147483648 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentSparse
+    extents:
+        [0]:
+            virtual size: 2147483648
+            filename: TEST_IMG.1
+            cluster size: 65536
+            format: SPARSE
+
+= twoGbMaxExtentFlat 5368709120 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 5368709120, "subformat": "twoGbMaxExtentFlat"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 5.0G (5368709120 bytes)
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentFlat
+    extents:
+        [0]:
+            virtual size: 2147483648
+            filename: TEST_IMG.1
+            format: FLAT
+        [1]:
+            virtual size: 2147483648
+            filename: TEST_IMG.2
+            format: FLAT
+        [2]:
+            virtual size: 1073741824
+            filename: TEST_IMG.3
+            format: FLAT
+
+= twoGbMaxExtentSparse 5368709120 =
+
+{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 5368709120, "subformat": "twoGbMaxExtentSparse"}}}
+{"return": {}}
+{"execute": "job-dismiss", "arguments": {"id": "job0"}}
+{"return": {}}
+
+image: TEST_IMG
+file format: IMGFMT
+virtual size: 5.0G (5368709120 bytes)
+cluster_size: 65536
+Format specific information:
+    cid: XXXXXXXXXX
+    parent cid: XXXXXXXXXX
+    create type: twoGbMaxExtentSparse
+    extents:
+        [0]:
+            virtual size: 2147483648
+            filename: TEST_IMG.1
+            cluster size: 65536
+            format: SPARSE
+        [1]:
+            virtual size: 2147483648
+            filename: TEST_IMG.2
+            cluster size: 65536
+            format: SPARSE
+        [2]:
+            virtual size: 1073741824
+            filename: TEST_IMG.3
+            cluster size: 65536
+            format: SPARSE
+
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 61a6d98ebd..c4de595f29 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -233,3 +233,4 @@ 
 233 auto quick
 234 auto quick migration
 235 auto quick
+237 rw auto quick