Commit 5ba141dc authored by Kevin Wolf's avatar Kevin Wolf
Browse files

qemu-iotests: Rewrite 210 for blockdev-create job



This rewrites the test case 210 to work with the new x-blockdev-create
job rather than the old synchronous version of the command.

All of the test cases stay the same as before, but in order to be able
to implement proper job handling, the test case is rewritten in Python.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
Reviewed-by: default avatarJeff Cody <jcody@redhat.com>
parent 00af1935
Loading
Loading
Loading
Loading
+165 −228
Original line number Diff line number Diff line
#!/bin/bash
#!/usr/bin/env python
#
# Test luks 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
@@ -18,152 +20,128 @@
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

# creator
owner=kwolf@redhat.com

seq=`basename $0`
echo "QA output created by $seq"

here=`pwd`
status=1	# failure is the default!

# get standard environment, filters and checks
. ./common.rc
. ./common.filter

_supported_fmt luks
_supported_proto file
_supported_os Linux

function do_run_qemu()
{
    echo Testing: "$@"
    $QEMU -nographic -qmp stdio -serial none "$@"
    echo
}

function run_qemu()
{
    do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp \
                          | _filter_qemu | _filter_imgfmt \
                          | _filter_actual_image_size
}

echo
echo "=== Successful image creation (defaults) ==="
echo

size=$((128 * 1024 * 1024))

run_qemu -object secret,id=keysec0,data="foo" <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "x-blockdev-create",
  "arguments": {
      "driver": "file",
      "filename": "$TEST_IMG_FILE",
      "size": 0
  }
}
{ "execute": "blockdev-add",
  "arguments": {
      "driver": "file",
      "node-name": "imgfile",
      "filename": "$TEST_IMG_FILE"
  }
}
{ "execute": "x-blockdev-create",
  "arguments": {
      "driver": "$IMGFMT",
      "file": "imgfile",
      "key-secret": "keysec0",
      "size": $size,
      "iter-time": 10
  }
}
{ "execute": "quit" }
EOF

_img_info --format-specific | _filter_img_info --format-specific

echo
echo "=== Successful image creation (with non-default options) ==="
echo

# Choose a different size to show that we got a new image
size=$((64 * 1024 * 1024))

run_qemu -object secret,id=keysec0,data="foo" <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "x-blockdev-create",
  "arguments": {
      "driver": "file",
      "filename": "$TEST_IMG_FILE",
      "size": 0
  }
}
{ "execute": "x-blockdev-create",
  "arguments": {
      "driver": "$IMGFMT",
      "file": {
          "driver": "file",
          "filename": "$TEST_IMG_FILE"
import iotests
from iotests import imgfmt

iotests.verify_image_format(supported_fmts=['luks'])
iotests.verify_protocol(supported=['file'])

def blockdev_create(vm, options):
    result = vm.qmp_log('x-blockdev-create', job_id='job0', options=options)

    if 'return' in result:
        assert result['return'] == {}
        vm.run_job('job0')
    iotests.log("")

with iotests.FilePath('t.luks') as disk_path, \
     iotests.VM() as vm:

    vm.add_object('secret,id=keysec0,data=foo')

    #
    # Successful image creation (defaults)
    #
    iotests.log("=== Successful image creation (defaults) ===")
    iotests.log("")

    size = 128 * 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',
                          'key-secret': 'keysec0',
                          'size': size,
                          'iter-time': 10 })
    vm.shutdown()

    # TODO Proper support for images to be used with imgopts and/or protocols
    iotests.img_info_log(
        'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path),
        filter_path=disk_path,
        extra_args=['--object', 'secret,id=keysec0,data=foo'],
        imgopts=True)

    #
    # Successful image creation (with non-default options)
    #
    iotests.log("=== Successful image creation (with non-default options) ===")
    iotests.log("")

    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,
      "key-secret": "keysec0",
      "cipher-alg": "twofish-128",
      "cipher-mode": "ctr",
      "ivgen-alg": "plain64",
      "ivgen-hash-alg": "md5",
      "hash-alg": "sha1",
      "iter-time": 10
  }
}
{ "execute": "quit" }
EOF

_img_info --format-specific | _filter_img_info --format-specific

echo
echo "=== Invalid BlockdevRef ==="
echo

run_qemu <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "x-blockdev-create",
  "arguments": {
      "driver": "$IMGFMT",
      "file": "this doesn't exist",
      "size": $size
  }
}
{ "execute": "quit" }
EOF

echo
echo "=== Zero size ==="
echo

run_qemu -blockdev driver=file,filename="$TEST_IMG_FILE",node-name=node0 \
         -object secret,id=keysec0,data="foo" <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "x-blockdev-create",
  "arguments": {
      "driver": "$IMGFMT",
      "file": "node0",
      "key-secret": "keysec0",
      "size": 0,
      "iter-time": 10
  }
}
{ "execute": "quit" }
EOF

_img_info | _filter_img_info


echo
echo "=== Invalid sizes ==="
echo
                          'size': size,
                          'key-secret': 'keysec0',
                          'cipher-alg': 'twofish-128',
                          'cipher-mode': 'ctr',
                          'ivgen-alg': 'plain64',
                          'ivgen-hash-alg': 'md5',
                          'hash-alg': 'sha1',
                          'iter-time': 10 })
    vm.shutdown()

    # TODO Proper support for images to be used with imgopts and/or protocols
    iotests.img_info_log(
        'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path),
        filter_path=disk_path,
        extra_args=['--object', 'secret,id=keysec0,data=foo'],
        imgopts=True)

    #
    # Invalid BlockdevRef
    #
    iotests.log("=== Invalid BlockdevRef ===")
    iotests.log("")

    size = 64 * 1024 * 1024

    vm.launch()
    blockdev_create(vm, { 'driver': imgfmt,
                          'file': "this doesn't exist",
                          'size': size })
    vm.shutdown()

    #
    # Zero size
    #
    iotests.log("=== Zero size ===")
    iotests.log("")

    vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
    vm.launch()
    blockdev_create(vm, { 'driver': imgfmt,
                          'file': 'node0',
                          'key-secret': 'keysec0',
                          'size': 0,
                          'iter-time': 10 })
    vm.shutdown()

    # TODO Proper support for images to be used with imgopts and/or protocols
    iotests.img_info_log(
        'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path),
        filter_path=disk_path,
        extra_args=['--object', 'secret,id=keysec0,data=foo'],
        imgopts=True)

    #
    # Invalid sizes
    #

    # TODO Negative image sizes aren't handled correctly, but this is a problem
    # with QAPI's implementation of the 'size' type and affects other commands as
@@ -173,75 +151,34 @@ echo
    # 2. 2^63 = 8 EB (qemu-img enforces image sizes less than this)
    # 3. 2^63 - 512 (generally valid, but with the crypto header the file will
    #                exceed 63 bits)
    iotests.log("=== Invalid sizes ===")
    iotests.log("")

run_qemu -blockdev driver=file,filename="$TEST_IMG_FILE",node-name=node0 \
         -object secret,id=keysec0,data="foo" <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "x-blockdev-create",
  "arguments": {
      "driver": "$IMGFMT",
      "file": "node0",
      "key-secret": "keysec0",
      "size": 18446744073709551104
  }
}
{ "execute": "x-blockdev-create",
  "arguments": {
      "driver": "$IMGFMT",
      "file": "node0",
      "key-secret": "keysec0",
      "size": 9223372036854775808
  }
}
{ "execute": "x-blockdev-create",
  "arguments": {
      "driver": "$IMGFMT",
      "file": "node0",
      "key-secret": "keysec0",
      "size": 9223372036854775296
  }
}
{ "execute": "quit" }
EOF

echo
echo "=== Resize image with invalid sizes ==="
echo

run_qemu -blockdev driver=file,filename="$TEST_IMG_FILE",node-name=node0 \
         -blockdev driver=luks,file=node0,key-secret=keysec0,node-name=node1 \
         -object secret,id=keysec0,data="foo" <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "block_resize",
  "arguments": {
      "node-name": "node1",
      "size": 9223372036854775296
  }
}
{ "execute": "block_resize",
  "arguments": {
      "node-name": "node1",
      "size": 9223372036854775808
  }
}
{ "execute": "block_resize",
  "arguments": {
      "node-name": "node1",
      "size": 18446744073709551104
  }
}
{ "execute": "block_resize",
  "arguments": {
      "node-name": "node1",
      "size": -9223372036854775808
  }
}
{ "execute": "quit" }
EOF

_img_info | _filter_img_info

# success, all done
echo "*** done"
rm -f $seq.full
status=0
    vm.launch()
    for size in [ 18446744073709551104, 9223372036854775808, 9223372036854775296 ]:
        blockdev_create(vm, { 'driver': imgfmt,
                              'file': 'node0',
                              'key-secret': 'keysec0',
                              'size': size })
    vm.shutdown()

    #
    # Resize image with invalid sizes
    #
    iotests.log("=== Resize image with invalid sizes ===")
    iotests.log("")

    vm.add_blockdev('driver=luks,file=node0,key-secret=keysec0,node-name=node1')
    vm.launch()
    vm.qmp_log('block_resize', node_name='node1', size=9223372036854775296)
    vm.qmp_log('block_resize', node_name='node1', size=9223372036854775808)
    vm.qmp_log('block_resize', node_name='node1', size=18446744073709551104)
    vm.qmp_log('block_resize', node_name='node1', size=-9223372036854775808)
    vm.shutdown()

    # TODO Proper support for images to be used with imgopts and/or protocols
    iotests.img_info_log(
        'driver=luks,file.driver=file,file.filename=%s,key-secret=keysec0' % (disk_path),
        filter_path=disk_path,
        extra_args=['--object', 'secret,id=keysec0,data=foo'],
        imgopts=True)
+138 −59
Original line number Diff line number Diff line
QA output created by 210

=== Successful image creation (defaults) ===

Testing: -object secret,id=keysec0,data=foo
QMP_VERSION
{"return": {}}
{"return": {}}
{"return": {}}
{"return": {}}
{"return": {}}
{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}}
{u'return': {}}
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
{u'return': {}}

{'execute': 'blockdev-add', 'arguments': {'node_name': 'imgfile', 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}
{u'return': {}}
{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'imgfile', 'size': 134217728}}}
{u'return': {}}
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
{u'return': {}}

image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "key-secret": "keysec0"}
image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
file format: IMGFMT
virtual size: 128M (134217728 bytes)
encrypted: yes
Format specific information:
    ivgen alg: plain64
    hash alg: sha256
    cipher alg: aes-256
    uuid: 00000000-0000-0000-0000-000000000000
    uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
    cipher mode: xts
    slots:
        [0]:
            active: true
            iters: 1024
            iters: XXX
            key offset: 4096
            stripes: 4000
        [1]:
@@ -48,31 +50,34 @@ Format specific information:
            active: false
            key offset: 1810432
    payload offset: 2068480
    master key iters: 1024
    master key iters: XXX

=== Successful image creation (with non-default options) ===

Testing: -object secret,id=keysec0,data=foo
QMP_VERSION
{"return": {}}
{"return": {}}
{"return": {}}
{"return": {}}
{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'size': 0, 'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}}}
{u'return': {}}
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
{u'return': {}}

{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'hash-alg': 'sha1', 'cipher-mode': 'ctr', 'cipher-alg': 'twofish-128', 'file': {'driver': 'file', 'filename': 'TEST_DIR/PID-t.luks'}, 'iter-time': 10, 'ivgen-alg': 'plain64', 'ivgen-hash-alg': 'md5', 'driver': 'luks', 'size': 67108864}}}
{u'return': {}}
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
{u'return': {}}

image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "key-secret": "keysec0"}
image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
file format: IMGFMT
virtual size: 64M (67108864 bytes)
encrypted: yes
Format specific information:
    ivgen alg: plain64
    hash alg: sha1
    cipher alg: twofish-128
    uuid: 00000000-0000-0000-0000-000000000000
    uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
    cipher mode: ctr
    slots:
        [0]:
            active: true
            iters: 1024
            iters: XXX
            key offset: 4096
            stripes: 4000
        [1]:
@@ -97,56 +102,130 @@ Format specific information:
            active: false
            key offset: 462848
    payload offset: 528384
    master key iters: 1024
    master key iters: XXX

=== Invalid BlockdevRef ===

Testing:
QMP_VERSION
{"return": {}}
{"error": {"class": "GenericError", "desc": "Cannot find device=this doesn't exist nor node_name=this doesn't exist"}}
{"return": {}}
{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}

{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'driver': 'luks', 'file': "this doesn't exist", 'size': 67108864}}}
{u'return': {}}
Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
{u'return': {}}

=== Zero size ===

Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -object secret,id=keysec0,data=foo
QMP_VERSION
{"return": {}}
{"return": {}}
{"return": {}}
{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'iter-time': 10, 'driver': 'luks', 'file': 'node0', 'size': 0}}}
{u'return': {}}
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
{u'return': {}}

image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "key-secret": "keysec0"}
image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
file format: IMGFMT
virtual size: 0 (0 bytes)
encrypted: yes
Format specific information:
    ivgen alg: plain64
    hash alg: sha256
    cipher alg: aes-256
    uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
    cipher mode: xts
    slots:
        [0]:
            active: true
            iters: XXX
            key offset: 4096
            stripes: 4000
        [1]:
            active: false
            key offset: 262144
        [2]:
            active: false
            key offset: 520192
        [3]:
            active: false
            key offset: 778240
        [4]:
            active: false
            key offset: 1036288
        [5]:
            active: false
            key offset: 1294336
        [6]:
            active: false
            key offset: 1552384
        [7]:
            active: false
            key offset: 1810432
    payload offset: 2068480
    master key iters: XXX

=== Invalid sizes ===

Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -object secret,id=keysec0,data=foo
QMP_VERSION
{"return": {}}
{"error": {"class": "GenericError", "desc": "The requested file size is too large"}}
{"error": {"class": "GenericError", "desc": "The requested file size is too large"}}
{"error": {"class": "GenericError", "desc": "The requested file size is too large"}}
{"return": {}}
{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 18446744073709551104L}}}
{u'return': {}}
Job failed: The requested file size is too large
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
{u'return': {}}

{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775808L}}}
{u'return': {}}
Job failed: The requested file size is too large
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
{u'return': {}}

{'execute': 'x-blockdev-create', 'arguments': {'job_id': 'job0', 'options': {'key-secret': 'keysec0', 'driver': 'luks', 'file': 'node0', 'size': 9223372036854775296}}}
{u'return': {}}
Job failed: The requested file size is too large
{'execute': 'job-dismiss', 'arguments': {'id': 'job0'}}
{u'return': {}}

=== Resize image with invalid sizes ===

Testing: -blockdev driver=file,filename=TEST_DIR/t.IMGFMT,node-name=node0 -blockdev driver=IMGFMT,file=node0,key-secret=keysec0,node-name=node1 -object secret,id=keysec0,data=foo
QMP_VERSION
{"return": {}}
{"error": {"class": "GenericError", "desc": "The requested file size is too large"}}
{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'size', expected: integer"}}
{"error": {"class": "GenericError", "desc": "Invalid parameter type for 'size', expected: integer"}}
{"error": {"class": "GenericError", "desc": "Parameter 'size' expects a >0 size"}}
{"return": {}}
{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}

image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "key-secret": "keysec0"}
{'execute': 'block_resize', 'arguments': {'size': 9223372036854775296, 'node_name': 'node1'}}
{u'error': {u'class': u'GenericError', u'desc': u'The requested file size is too large'}}
{'execute': 'block_resize', 'arguments': {'size': 9223372036854775808L, 'node_name': 'node1'}}
{u'error': {u'class': u'GenericError', u'desc': u"Invalid parameter type for 'size', expected: integer"}}
{'execute': 'block_resize', 'arguments': {'size': 18446744073709551104L, 'node_name': 'node1'}}
{u'error': {u'class': u'GenericError', u'desc': u"Invalid parameter type for 'size', expected: integer"}}
{'execute': 'block_resize', 'arguments': {'size': -9223372036854775808, 'node_name': 'node1'}}
{u'error': {u'class': u'GenericError', u'desc': u"Parameter 'size' expects a >0 size"}}
image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"}
file format: IMGFMT
virtual size: 0 (0 bytes)
*** done
encrypted: yes
Format specific information:
    ivgen alg: plain64
    hash alg: sha256
    cipher alg: aes-256
    uuid: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
    cipher mode: xts
    slots:
        [0]:
            active: true
            iters: XXX
            key offset: 4096
            stripes: 4000
        [1]:
            active: false
            key offset: 262144
        [2]:
            active: false
            key offset: 520192
        [3]:
            active: false
            key offset: 778240
        [4]:
            active: false
            key offset: 1036288
        [5]:
            active: false
            key offset: 1294336
        [6]:
            active: false
            key offset: 1552384
        [7]:
            active: false
            key offset: 1810432
    payload offset: 2068480
    master key iters: XXX
+1 −1
Original line number Diff line number Diff line
@@ -208,9 +208,9 @@
207 rw auto
208 rw auto quick
209 rw auto quick
210 rw auto
# TODO The following commented out tests need to be reworked to work
# with the x-blockdev-create job
#210 rw auto
#211 rw auto quick
#212 rw auto quick
#213 rw auto quick
+10 −2
Original line number Diff line number Diff line
@@ -109,8 +109,16 @@ def qemu_img_pipe(*args):
        sys.stderr.write('qemu-img received signal %i: %s\n' % (-exitcode, ' '.join(qemu_img_args + list(args))))
    return subp.communicate()[0]

def img_info_log(filename, filter_path=None):
    output = qemu_img_pipe('info', '-f', imgfmt, filename)
def img_info_log(filename, filter_path=None, imgopts=False, extra_args=[]):
    args = [ 'info' ]
    if imgopts:
        args.append('--image-opts')
    else:
        args += [ '-f', imgfmt ]
    args += extra_args
    args.append(filename)

    output = qemu_img_pipe(*args)
    if not filter_path:
        filter_path = filename
    log(filter_img_info(output, filter_path))