diff options
Diffstat (limited to 'tests')
40 files changed, 541 insertions, 113 deletions
diff --git a/tests/Makefile.include b/tests/Makefile.include index 75893838e5..f42f3dfa72 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -342,6 +342,8 @@ qapi-schema += alternate-array.json qapi-schema += alternate-base.json qapi-schema += alternate-clash.json qapi-schema += alternate-conflict-dict.json +qapi-schema += alternate-conflict-enum-bool.json +qapi-schema += alternate-conflict-enum-int.json qapi-schema += alternate-conflict-string.json qapi-schema += alternate-empty.json qapi-schema += alternate-nested.json diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c index a16cefca73..8e432e9ab6 100644 --- a/tests/check-qom-proplist.c +++ b/tests/check-qom-proplist.c @@ -23,6 +23,9 @@ #include "qapi/error.h" #include "qom/object.h" #include "qemu/module.h" +#include "qemu/option.h" +#include "qemu/config-file.h" +#include "qom/object_interfaces.h" #define TYPE_DUMMY "qemu-dummy" @@ -162,6 +165,10 @@ static const TypeInfo dummy_info = { .instance_finalize = dummy_finalize, .class_size = sizeof(DummyObjectClass), .class_init = dummy_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_USER_CREATABLE }, + { } + } }; @@ -320,6 +327,14 @@ static const TypeInfo dummy_backend_info = { .class_size = sizeof(DummyBackendClass), }; +static QemuOptsList qemu_object_opts = { + .name = "object", + .implied_opt_name = "qom-type", + .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head), + .desc = { + { } + }, +}; static void test_dummy_createv(void) @@ -388,6 +403,46 @@ static void test_dummy_createlist(void) object_unparent(OBJECT(dobj)); } +static void test_dummy_createcmdl(void) +{ + QemuOpts *opts; + DummyObject *dobj; + Error *err = NULL; + const char *params = TYPE_DUMMY \ + ",id=dev0," \ + "bv=yes,sv=Hiss hiss hiss,av=platypus"; + + qemu_add_opts(&qemu_object_opts); + opts = qemu_opts_parse(&qemu_object_opts, params, true, &err); + g_assert(err == NULL); + g_assert(opts); + + dobj = DUMMY_OBJECT(user_creatable_add_opts(opts, &err)); + g_assert(err == NULL); + g_assert(dobj); + g_assert_cmpstr(dobj->sv, ==, "Hiss hiss hiss"); + g_assert(dobj->bv == true); + g_assert(dobj->av == DUMMY_PLATYPUS); + + user_creatable_del("dev0", &err); + g_assert(err == NULL); + error_free(err); + + /* + * cmdline-parsing via qemu_opts_parse() results in a QemuOpts entry + * corresponding to the Object's ID to be added to the QemuOptsList + * for objects. To avoid having this entry conflict with future + * Objects using the same ID (which can happen in cases where + * qemu_opts_parse() is used to parse the object params, such as + * with hmp_object_add() at the time of this comment), we need to + * check for this in user_creatable_del() and remove the QemuOpts if + * it is present. + * + * The below check ensures this works as expected. + */ + g_assert_null(qemu_opts_find(&qemu_object_opts, "dev0")); +} + static void test_dummy_badenum(void) { Error *err = NULL; @@ -525,6 +580,7 @@ int main(int argc, char **argv) g_test_add_func("/qom/proplist/createlist", test_dummy_createlist); g_test_add_func("/qom/proplist/createv", test_dummy_createv); + g_test_add_func("/qom/proplist/createcmdline", test_dummy_createcmdl); g_test_add_func("/qom/proplist/badenum", test_dummy_badenum); g_test_add_func("/qom/proplist/getenum", test_dummy_getenum); g_test_add_func("/qom/proplist/iterator", test_dummy_iterator); diff --git a/tests/ide-test.c b/tests/ide-test.c index 139ebc0ec6..bfd79ddbdc 100644 --- a/tests/ide-test.c +++ b/tests/ide-test.c @@ -796,11 +796,13 @@ static void cdrom_pio_impl(int nblocks) int i, j; uint8_t data; uint16_t limit; + size_t ret; /* Prepopulate the CDROM with an interesting pattern */ generate_pattern(pattern, patt_len, ATAPI_BLOCK_SIZE); fh = fopen(tmp_path, "w+"); - fwrite(pattern, ATAPI_BLOCK_SIZE, patt_blocks, fh); + ret = fwrite(pattern, ATAPI_BLOCK_SIZE, patt_blocks, fh); + g_assert_cmpint(ret, ==, patt_blocks); fclose(fh); ide_test_start("-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 " @@ -880,6 +882,7 @@ static void test_cdrom_pio_large(void) static void test_cdrom_dma(void) { static const size_t len = ATAPI_BLOCK_SIZE; + size_t ret; char *pattern = g_malloc(ATAPI_BLOCK_SIZE * 16); char *rx = g_malloc0(len); uintptr_t guest_buf; @@ -896,7 +899,8 @@ static void test_cdrom_dma(void) generate_pattern(pattern, ATAPI_BLOCK_SIZE * 16, ATAPI_BLOCK_SIZE); fh = fopen(tmp_path, "w+"); - fwrite(pattern, ATAPI_BLOCK_SIZE, 16, fh); + ret = fwrite(pattern, ATAPI_BLOCK_SIZE, 16, fh); + g_assert_cmpint(ret, ==, 16); fclose(fh); send_dma_request(CMD_PACKET, 0, 1, prdt, 1, send_scsi_cdb_read10); diff --git a/tests/libqtest.c b/tests/libqtest.c index 84ecbd2bd8..4a5492a603 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -160,7 +160,10 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args) const char *qemu_binary; qemu_binary = getenv("QTEST_QEMU_BINARY"); - g_assert(qemu_binary != NULL); + if (!qemu_binary) { + fprintf(stderr, "Environment variable QTEST_QEMU_BINARY required\n"); + exit(1); + } s = g_malloc(sizeof(*s)); diff --git a/tests/numa-test.c b/tests/numa-test.c index c3475d6d5e..3f636840b1 100644 --- a/tests/numa-test.c +++ b/tests/numa-test.c @@ -92,7 +92,7 @@ static QList *get_cpus(QDict **resp) *resp = qmp("{ 'execute': 'query-cpus' }"); g_assert(*resp); g_assert(qdict_haskey(*resp, "return")); - return qdict_get_qlist(*resp, "return"); + return qdict_get_qlist(*resp, "return"); } static void test_query_cpus(const void *data) @@ -100,7 +100,7 @@ static void test_query_cpus(const void *data) char *cli; QDict *resp; QList *cpus; - const QObject *e; + QObject *e; cli = make_cli(data, "-smp 8 -numa node,cpus=0-3 -numa node,cpus=4-7"); qtest_start(cli); @@ -124,6 +124,7 @@ static void test_query_cpus(const void *data) } else { g_assert_cmpint(node, ==, 1); } + qobject_decref(e); } QDECREF(resp); @@ -136,7 +137,7 @@ static void pc_numa_cpu(const void *data) char *cli; QDict *resp; QList *cpus; - const QObject *e; + QObject *e; cli = make_cli(data, "-cpu pentium -smp 8,sockets=2,cores=2,threads=2 " "-numa node,nodeid=0 -numa node,nodeid=1 " @@ -176,6 +177,7 @@ static void pc_numa_cpu(const void *data) } else { g_assert(false); } + qobject_decref(e); } QDECREF(resp); @@ -188,7 +190,7 @@ static void spapr_numa_cpu(const void *data) char *cli; QDict *resp; QList *cpus; - const QObject *e; + QObject *e; cli = make_cli(data, "-smp 4,cores=4 " "-numa node,nodeid=0 -numa node,nodeid=1 " @@ -220,6 +222,7 @@ static void spapr_numa_cpu(const void *data) } else { g_assert(false); } + qobject_decref(e); } QDECREF(resp); @@ -232,7 +235,7 @@ static void aarch64_numa_cpu(const void *data) char *cli; QDict *resp; QList *cpus; - const QObject *e; + QObject *e; cli = make_cli(data, "-smp 2 " "-numa node,nodeid=0 -numa node,nodeid=1 " @@ -262,6 +265,7 @@ static void aarch64_numa_cpu(const void *data) } else { g_assert(false); } + qobject_decref(e); } QDECREF(resp); diff --git a/tests/postcopy-test.c b/tests/postcopy-test.c index e86f87656a..8142f2ab90 100644 --- a/tests/postcopy-test.c +++ b/tests/postcopy-test.c @@ -16,7 +16,7 @@ #include "qemu/option.h" #include "qemu/range.h" #include "qemu/sockets.h" -#include "sysemu/char.h" +#include "chardev/char.h" #include "sysemu/sysemu.h" #include "hw/nvram/chrp_nvram.h" diff --git a/tests/qapi-schema/alternate-clash.json b/tests/qapi-schema/alternate-clash.json index 6d73bc527b..9a59b88ced 100644 --- a/tests/qapi-schema/alternate-clash.json +++ b/tests/qapi-schema/alternate-clash.json @@ -5,4 +5,4 @@ # the implicit Alt1Kind enum, we would still have a collision with the # resulting C union trying to have two members named 'a_b'. { 'alternate': 'Alt1', - 'data': { 'a-b': 'str', 'a_b': 'int' } } + 'data': { 'a-b': 'bool', 'a_b': 'int' } } diff --git a/tests/qapi-schema/alternate-conflict-dict.json b/tests/qapi-schema/alternate-conflict-dict.json index d566cca816..3d7881279c 100644 --- a/tests/qapi-schema/alternate-conflict-dict.json +++ b/tests/qapi-schema/alternate-conflict-dict.json @@ -1,4 +1,4 @@ -# we reject alternates with multiple object branches +# alternate branches of object type conflict with each other { 'struct': 'One', 'data': { 'name': 'str' } } { 'struct': 'Two', diff --git a/tests/qapi-schema/alternate-conflict-enum-bool.err b/tests/qapi-schema/alternate-conflict-enum-bool.err new file mode 100644 index 0000000000..0dfc00242d --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-enum-bool.err @@ -0,0 +1 @@ +tests/qapi-schema/alternate-conflict-enum-bool.json:4: Alternate 'Alt' member 'two' can't be distinguished from member 'one' diff --git a/tests/qapi-schema/alternate-conflict-enum-bool.exit b/tests/qapi-schema/alternate-conflict-enum-bool.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-enum-bool.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/alternate-conflict-enum-bool.json b/tests/qapi-schema/alternate-conflict-enum-bool.json new file mode 100644 index 0000000000..bff25c3147 --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-enum-bool.json @@ -0,0 +1,6 @@ +# alternate branch of 'enum' type that conflicts with bool +{ 'enum': 'Enum', + 'data': [ 'aus', 'off' ] } +{ 'alternate': 'Alt', + 'data': { 'one': 'Enum', + 'two': 'bool' } } diff --git a/tests/qapi-schema/alternate-conflict-enum-bool.out b/tests/qapi-schema/alternate-conflict-enum-bool.out new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-enum-bool.out diff --git a/tests/qapi-schema/alternate-conflict-enum-int.err b/tests/qapi-schema/alternate-conflict-enum-int.err new file mode 100644 index 0000000000..2cc8e7b9aa --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-enum-int.err @@ -0,0 +1 @@ +tests/qapi-schema/alternate-conflict-enum-int.json:4: Alternate 'Alt' member 'two' can't be distinguished from member 'one' diff --git a/tests/qapi-schema/alternate-conflict-enum-int.exit b/tests/qapi-schema/alternate-conflict-enum-int.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-enum-int.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/alternate-conflict-enum-int.json b/tests/qapi-schema/alternate-conflict-enum-int.json new file mode 100644 index 0000000000..beb428c10b --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-enum-int.json @@ -0,0 +1,6 @@ +# alternate branches of 'enum' type that conflicts with numbers +{ 'enum': 'Enum', + 'data': [ '1', '2', '3' ] } +{ 'alternate': 'Alt', + 'data': { 'one': 'Enum', + 'two': 'int' } } diff --git a/tests/qapi-schema/alternate-conflict-enum-int.out b/tests/qapi-schema/alternate-conflict-enum-int.out new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/qapi-schema/alternate-conflict-enum-int.out diff --git a/tests/qapi-schema/alternate-conflict-string.err b/tests/qapi-schema/alternate-conflict-string.err index fc523b0879..fe2f188295 100644 --- a/tests/qapi-schema/alternate-conflict-string.err +++ b/tests/qapi-schema/alternate-conflict-string.err @@ -1 +1 @@ -tests/qapi-schema/alternate-conflict-string.json:4: Alternate 'Alt' member 'two' can't be distinguished from member 'one' +tests/qapi-schema/alternate-conflict-string.json:2: Alternate 'Alt' member 'two' can't be distinguished from member 'one' diff --git a/tests/qapi-schema/alternate-conflict-string.json b/tests/qapi-schema/alternate-conflict-string.json index 72f04a820a..85adbd4adc 100644 --- a/tests/qapi-schema/alternate-conflict-string.json +++ b/tests/qapi-schema/alternate-conflict-string.json @@ -1,6 +1,4 @@ -# we reject alternates with multiple string-like branches -{ 'enum': 'Enum', - 'data': [ 'hello', 'world' ] } +# alternate branches of 'str' type conflict with all scalar types { 'alternate': 'Alt', 'data': { 'one': 'str', - 'two': 'Enum' } } + 'two': 'int' } } diff --git a/tests/qapi-schema/alternate-nested.json b/tests/qapi-schema/alternate-nested.json index 8e22186491..f2b9632f75 100644 --- a/tests/qapi-schema/alternate-nested.json +++ b/tests/qapi-schema/alternate-nested.json @@ -1,5 +1,5 @@ # we reject a nested alternate branch { 'alternate': 'Alt1', - 'data': { 'name': 'str', 'value': 'int' } } + 'data': { 'name': 'bool', 'value': 'int' } } { 'alternate': 'Alt2', 'data': { 'nested': 'Alt1', 'b': 'bool' } } diff --git a/tests/qapi-schema/args-alternate.json b/tests/qapi-schema/args-alternate.json index 69e94d4819..824d69c1d5 100644 --- a/tests/qapi-schema/args-alternate.json +++ b/tests/qapi-schema/args-alternate.json @@ -1,3 +1,3 @@ # we do not allow alternate arguments -{ 'alternate': 'Alt', 'data': { 'case1': 'int', 'case2': 'str' } } +{ 'alternate': 'Alt', 'data': { 'case1': 'int', 'case2': 'bool' } } { 'command': 'oops', 'data': 'Alt' } diff --git a/tests/qapi-schema/doc-bad-alternate-member.json b/tests/qapi-schema/doc-bad-alternate-member.json index 738635ca8f..fa4143da4c 100644 --- a/tests/qapi-schema/doc-bad-alternate-member.json +++ b/tests/qapi-schema/doc-bad-alternate-member.json @@ -6,4 +6,4 @@ # @bb: b ## { 'alternate': 'AorB', - 'data': { 'a': 'str', 'b': 'int' } } + 'data': { 'a': 'bool', 'b': 'int' } } diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 842ea3c5e3..17649c6398 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -93,19 +93,22 @@ { 'struct': 'WrapAlternate', 'data': { 'alt': 'UserDefAlternate' } } { 'alternate': 'UserDefAlternate', - 'data': { 'udfu': 'UserDefFlatUnion', 's': 'str', 'i': 'int' } } + 'data': { 'udfu': 'UserDefFlatUnion', 'e': 'EnumOne', 'i': 'int' } } { 'struct': 'UserDefC', 'data': { 'string1': 'str', 'string2': 'str' } } # for testing use of 'number' within alternates -{ 'alternate': 'AltStrBool', 'data': { 's': 'str', 'b': 'bool' } } -{ 'alternate': 'AltStrNum', 'data': { 's': 'str', 'n': 'number' } } -{ 'alternate': 'AltNumStr', 'data': { 'n': 'number', 's': 'str' } } -{ 'alternate': 'AltStrInt', 'data': { 's': 'str', 'i': 'int' } } +{ 'alternate': 'AltEnumBool', 'data': { 'e': 'EnumOne', 'b': 'bool' } } +{ 'alternate': 'AltEnumNum', 'data': { 'e': 'EnumOne', 'n': 'number' } } +{ 'alternate': 'AltNumEnum', 'data': { 'n': 'number', 'e': 'EnumOne' } } +{ 'alternate': 'AltEnumInt', 'data': { 'e': 'EnumOne', 'i': 'int' } } { 'alternate': 'AltIntNum', 'data': { 'i': 'int', 'n': 'number' } } { 'alternate': 'AltNumInt', 'data': { 'n': 'number', 'i': 'int' } } +# for testing use of 'str' within alternates +{ 'alternate': 'AltStrObj', 'data': { 's': 'str', 'o': 'TestStruct' } } + # for testing native lists { 'union': 'UserDefNativeListUnion', 'data': { 'integer': ['int'], diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 9d99c4eebb..9f68610dc2 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -1,27 +1,31 @@ -alternate AltIntNum +alternate AltEnumBool + tag type + case e: EnumOne + case b: bool +alternate AltEnumInt tag type + case e: EnumOne case i: int - case n: number -alternate AltNumInt +alternate AltEnumNum tag type + case e: EnumOne case n: number - case i: int -alternate AltNumStr +alternate AltIntNum tag type + case i: int case n: number - case s: str -alternate AltStrBool +alternate AltNumEnum tag type - case s: str - case b: bool -alternate AltStrInt + case n: number + case e: EnumOne +alternate AltNumInt tag type - case s: str + case n: number case i: int -alternate AltStrNum +alternate AltStrObj tag type case s: str - case n: number + case o: TestStruct event EVENT_A None boxed=False event EVENT_B None @@ -66,7 +70,7 @@ object UserDefA alternate UserDefAlternate tag type case udfu: UserDefFlatUnion - case s: str + case e: EnumOne case i: int object UserDefB member intb: int optional=False diff --git a/tests/qapi-schema/returns-alternate.json b/tests/qapi-schema/returns-alternate.json index 972390c06b..f87371811b 100644 --- a/tests/qapi-schema/returns-alternate.json +++ b/tests/qapi-schema/returns-alternate.json @@ -1,3 +1,3 @@ # we reject returns if it is an alternate type -{ 'alternate': 'Alt', 'data': { 'a': 'int', 'b': 'str' } } +{ 'alternate': 'Alt', 'data': { 'a': 'int', 'b': 'bool' } } { 'command': 'oops', 'returns': 'Alt' } diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040 index 5bdaf3d48d..9d381d9b72 100755 --- a/tests/qemu-iotests/040 +++ b/tests/qemu-iotests/040 @@ -70,7 +70,9 @@ class ImageCommitTestCase(iotests.QMPTestCase): self.wait_for_complete() class TestSingleDrive(ImageCommitTestCase): - image_len = 1 * 1024 * 1024 + # Need some space after the copied data so that throttling is effective in + # tests that use it rather than just completing the job immediately + image_len = 2 * 1024 * 1024 test_len = 1 * 1024 * 256 def setUp(self): @@ -79,7 +81,9 @@ class TestSingleDrive(ImageCommitTestCase): qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img) qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', backing_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img) - self.vm = iotests.VM().add_drive(test_img) + self.vm = iotests.VM().add_drive(test_img, interface="none") + self.vm.add_device("virtio-scsi-pci") + self.vm.add_device("scsi-hd,id=scsi0,drive=drive0") self.vm.launch() def tearDown(self): @@ -131,6 +135,33 @@ class TestSingleDrive(ImageCommitTestCase): self.assert_qmp(result, 'error/class', 'GenericError') self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % mid_img) + # When the job is running on a BB that is automatically deleted on hot + # unplug, the job is cancelled when the device disappears + def test_hot_unplug(self): + if self.image_len == 0: + return + + self.assert_no_active_block_jobs() + result = self.vm.qmp('block-commit', device='drive0', top=mid_img, + base=backing_img, speed=(self.image_len / 4)) + self.assert_qmp(result, 'return', {}) + result = self.vm.qmp('device_del', id='scsi0') + self.assert_qmp(result, 'return', {}) + + cancelled = False + deleted = False + while not cancelled or not deleted: + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'DEVICE_DELETED': + self.assert_qmp(event, 'data/device', 'scsi0') + deleted = True + elif event['event'] == 'BLOCK_JOB_CANCELLED': + self.assert_qmp(event, 'data/device', 'drive0') + cancelled = True + else: + self.fail("Unexpected event %s" % (event['event'])) + + self.assert_no_active_block_jobs() class TestRelativePaths(ImageCommitTestCase): image_len = 1 * 1024 * 1024 diff --git a/tests/qemu-iotests/040.out b/tests/qemu-iotests/040.out index 4fd1c2dcd2..6d9bee1a4b 100644 --- a/tests/qemu-iotests/040.out +++ b/tests/qemu-iotests/040.out @@ -1,5 +1,5 @@ -......................... +........................... ---------------------------------------------------------------------- -Ran 25 tests +Ran 27 tests OK diff --git a/tests/qemu-iotests/083.out b/tests/qemu-iotests/083.out index 0c13888ba1..a24c6bfece 100644 --- a/tests/qemu-iotests/083.out +++ b/tests/qemu-iotests/083.out @@ -69,10 +69,12 @@ read failed: Input/output error === Check disconnect 4 reply === +read failed read failed: Input/output error === Check disconnect 8 reply === +read failed read failed: Input/output error === Check disconnect before data === diff --git a/tests/qemu-iotests/183 b/tests/qemu-iotests/183 new file mode 100755 index 0000000000..20268ff7a1 --- /dev/null +++ b/tests/qemu-iotests/183 @@ -0,0 +1,140 @@ +#!/bin/bash +# +# Test old-style block migration (migrate -b) +# +# Copyright (C) 2017 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <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! + +MIG_SOCKET="${TEST_DIR}/migrate" + +_cleanup() +{ + rm -f "${MIG_SOCKET}" + rm -f "${TEST_IMG}.dest" + _cleanup_test_img + _cleanup_qemu +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter +. ./common.qemu + +_supported_fmt qcow2 raw qed dmg quorum +_supported_proto file +_supported_os Linux + +size=64M +_make_test_img $size +TEST_IMG="${TEST_IMG}.dest" _make_test_img $size + +echo +echo === Starting VMs === +echo + +qemu_comm_method="qmp" + +_launch_qemu \ + -drive file="${TEST_IMG}",cache=$CACHEMODE,driver=$IMGFMT,id=disk +src=$QEMU_HANDLE +_send_qemu_cmd $src "{ 'execute': 'qmp_capabilities' }" 'return' + +_launch_qemu \ + -drive file="${TEST_IMG}.dest",cache=$CACHEMODE,driver=$IMGFMT,id=disk \ + -incoming "unix:${MIG_SOCKET}" +dest=$QEMU_HANDLE +_send_qemu_cmd $dest "{ 'execute': 'qmp_capabilities' }" 'return' + +echo +echo === Write something on the source === +echo + +_send_qemu_cmd $src \ + "{ 'execute': 'human-monitor-command', + 'arguments': { 'command-line': + 'qemu-io disk \"write -P 0x55 0 64k\"' } }" \ + 'return' +_send_qemu_cmd $src \ + "{ 'execute': 'human-monitor-command', + 'arguments': { 'command-line': + 'qemu-io disk \"read -P 0x55 0 64k\"' } }" \ + 'return' + +echo +echo === Do block migration to destination === +echo + +reply="$(_send_qemu_cmd $src \ + "{ 'execute': 'migrate', + 'arguments': { 'uri': 'unix:${MIG_SOCKET}', 'blk': true } }" \ + 'return\|error')" +echo "$reply" +if echo "$reply" | grep "compiled without old-style" > /dev/null; then + _notrun "migrate -b support not compiled in" +fi + +QEMU_COMM_TIMEOUT=0.1 qemu_cmd_repeat=50 silent=yes \ + _send_qemu_cmd $src "{ 'execute': 'query-migrate' }" '"status": "completed"' +_send_qemu_cmd $src "{ 'execute': 'query-status' }" "return" + +echo +echo === Do some I/O on the destination === +echo + +# It is important that we use the BlockBackend of the guest device here instead +# of the node name, which would create a new BlockBackend and not test whether +# the guest has the necessary permissions to access the image now +silent=yes _send_qemu_cmd $dest "" "100 %" +_send_qemu_cmd $dest "{ 'execute': 'query-status' }" "return" +_send_qemu_cmd $dest \ + "{ 'execute': 'human-monitor-command', + 'arguments': { 'command-line': + 'qemu-io disk \"read -P 0x55 0 64k\"' } }" \ + 'return' +_send_qemu_cmd $dest \ + "{ 'execute': 'human-monitor-command', + 'arguments': { 'command-line': + 'qemu-io disk \"write -P 0x66 1M 64k\"' } }" \ + 'return' + +echo +echo === Shut down and check image === +echo + +_send_qemu_cmd $src '{"execute":"quit"}' 'return' +_send_qemu_cmd $dest '{"execute":"quit"}' 'return' +wait=1 _cleanup_qemu + +_check_test_img +TEST_IMG="${TEST_IMG}.dest" _check_test_img + +$QEMU_IO -c 'write -P 0x66 1M 64k' "$TEST_IMG" | _filter_qemu_io +$QEMU_IMG compare "$TEST_IMG.dest" "$TEST_IMG" + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/183.out b/tests/qemu-iotests/183.out new file mode 100644 index 0000000000..103fdc778b --- /dev/null +++ b/tests/qemu-iotests/183.out @@ -0,0 +1,46 @@ +QA output created by 183 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 +Formatting 'TEST_DIR/t.IMGFMT.dest', fmt=IMGFMT size=67108864 + +=== Starting VMs === + +{"return": {}} +{"return": {}} + +=== Write something on the source === + +wrote 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{"return": ""} +read 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{"return": ""} + +=== Do block migration to destination === + +{"return": {}} +{"return": {"status": "postmigrate", "singlestep": false, "running": false}} + +=== Do some I/O on the destination === + +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESUME"} +{"return": {"status": "running", "singlestep": false, "running": true}} +read 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{"return": ""} +wrote 65536/65536 bytes at offset 1048576 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +{"return": ""} + +=== Shut down and check image === + +{"return": {}} +{"return": {}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}} +No errors were found on the image. +No errors were found on the image. +wrote 65536/65536 bytes at offset 1048576 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Images are identical. +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 5c8ea0f95c..a6acafffd7 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -174,3 +174,4 @@ 179 rw auto quick 181 rw auto migration 182 rw auto quick +183 rw auto migration diff --git a/tests/rtc-test.c b/tests/rtc-test.c index a086efd120..e78f701afb 100644 --- a/tests/rtc-test.c +++ b/tests/rtc-test.c @@ -14,6 +14,7 @@ #include "qemu/osdep.h" #include "libqtest.h" +#include "qemu/timer.h" #include "hw/timer/mc146818rtc_regs.h" static uint8_t base = 0x70; @@ -542,6 +543,52 @@ static void register_b_set_flag(void) g_assert_cmpint(cmos_read(RTC_CENTURY), ==, 0x20); } +#define RTC_PERIOD_CODE1 13 /* 8 Hz */ +#define RTC_PERIOD_CODE2 15 /* 2 Hz */ + +#define RTC_PERIOD_TEST_NR 50 + +static uint64_t wait_periodic_interrupt(uint64_t real_time) +{ + while (!get_irq(RTC_ISA_IRQ)) { + real_time = clock_step_next(); + } + + g_assert((cmos_read(RTC_REG_C) & REG_C_PF) != 0); + return real_time; +} + +static void periodic_timer(void) +{ + int i; + uint64_t period_clocks, period_time, start_time, real_time; + + /* disable all interrupts. */ + cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) & + ~(REG_B_PIE | REG_B_AIE | REG_B_UIE)); + cmos_write(RTC_REG_A, RTC_PERIOD_CODE1); + /* enable periodic interrupt after properly configure the period. */ + cmos_write(RTC_REG_B, cmos_read(RTC_REG_B) | REG_B_PIE); + + start_time = real_time = clock_step_next(); + + for (i = 0; i < RTC_PERIOD_TEST_NR; i++) { + cmos_write(RTC_REG_A, RTC_PERIOD_CODE1); + real_time = wait_periodic_interrupt(real_time); + cmos_write(RTC_REG_A, RTC_PERIOD_CODE2); + real_time = wait_periodic_interrupt(real_time); + } + + period_clocks = periodic_period_to_clock(RTC_PERIOD_CODE1) + + periodic_period_to_clock(RTC_PERIOD_CODE2); + period_clocks *= RTC_PERIOD_TEST_NR; + period_time = periodic_clock_to_ns(period_clocks); + + real_time -= start_time; + g_assert_cmpint(ABS((int64_t)(real_time - period_time)), <=, + NANOSECONDS_PER_SECOND * 0.5); +} + int main(int argc, char **argv) { QTestState *s = NULL; @@ -564,6 +611,8 @@ int main(int argc, char **argv) qtest_add_func("/rtc/set-year/1980", set_year_1980); qtest_add_func("/rtc/misc/register_b_set_flag", register_b_set_flag); qtest_add_func("/rtc/misc/fuzz-registers", fuzz_registers); + qtest_add_func("/rtc/periodic/interrupt", periodic_timer); + ret = g_test_run(); if (s) { diff --git a/tests/test-char.c b/tests/test-char.c index 124d0c5439..9e361c8d09 100644 --- a/tests/test-char.c +++ b/tests/test-char.c @@ -4,7 +4,7 @@ #include "qemu-common.h" #include "qemu/config-file.h" #include "qemu/sockets.h" -#include "sysemu/char.h" +#include "chardev/char-fe.h" #include "sysemu/sysemu.h" #include "qapi/error.h" #include "qom/qom-qobject.h" @@ -97,8 +97,7 @@ static void char_stdio_test_subprocess(void) ret = qemu_chr_fe_write(&be, (void *)"buf", 4); g_assert_cmpint(ret, ==, 4); - qemu_chr_fe_deinit(&be); - object_unparent(OBJECT(chr)); + qemu_chr_fe_deinit(&be, true); } static void char_stdio_test(void) @@ -146,8 +145,7 @@ static void char_ringbuf_test(void) g_assert_cmpstr(data, ==, ""); g_free(data); - qemu_chr_fe_deinit(&be); - object_unparent(OBJECT(chr)); + qemu_chr_fe_deinit(&be, true); /* check alias */ opts = qemu_opts_create(qemu_find_opts("chardev"), "memory-label", @@ -231,9 +229,8 @@ static void char_mux_test(void) g_assert_cmpint(strlen(data), !=, 0); g_free(data); - qemu_chr_fe_deinit(&chr_be1); - qemu_chr_fe_deinit(&chr_be2); - object_unparent(OBJECT(chr)); + qemu_chr_fe_deinit(&chr_be1, false); + qemu_chr_fe_deinit(&chr_be2, true); } typedef struct SocketIdleData { @@ -396,8 +393,7 @@ static void char_pipe_test(void) g_assert_cmpint(fe.read_count, ==, 8); g_assert_cmpstr(fe.read_buf, ==, "pipe-in"); - qemu_chr_fe_deinit(&be); - object_unparent(OBJECT(chr)); + qemu_chr_fe_deinit(&be, true); g_assert(g_unlink(in) == 0); g_assert(g_unlink(out) == 0); @@ -454,6 +450,32 @@ static void char_udp_test(void) g_free(tmp); } +#ifdef HAVE_CHARDEV_SERIAL +static void char_serial_test(void) +{ + QemuOpts *opts; + Chardev *chr; + + opts = qemu_opts_create(qemu_find_opts("chardev"), "serial-id", + 1, &error_abort); + qemu_opt_set(opts, "backend", "serial", &error_abort); + qemu_opt_set(opts, "path", "/dev/null", &error_abort); + + chr = qemu_chr_new_from_opts(opts, NULL); + g_assert_nonnull(chr); + /* TODO: add more tests with a pty */ + object_unparent(OBJECT(chr)); + + /* test tty alias */ + qemu_opt_set(opts, "backend", "tty", &error_abort); + chr = qemu_chr_new_from_opts(opts, NULL); + g_assert_nonnull(chr); + object_unparent(OBJECT(chr)); + + qemu_opts_del(opts); +} +#endif + static void char_file_test(void) { char *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL); @@ -511,8 +533,7 @@ static void char_file_test(void) g_assert_cmpint(fe.read_count, ==, 8); g_assert_cmpstr(fe.read_buf, ==, "fifo-in"); - qemu_chr_fe_deinit(&be); - object_unref(OBJECT(chr)); + qemu_chr_fe_deinit(&be, true); g_unlink(fifo); g_free(fifo); } @@ -549,7 +570,7 @@ static void char_null_test(void) error_free_or_abort(&err); /* deinit & reinit */ - qemu_chr_fe_deinit(&be); + qemu_chr_fe_deinit(&be, false); qemu_chr_fe_init(&be, chr, &error_abort); qemu_chr_fe_set_open(&be, true); @@ -563,8 +584,7 @@ static void char_null_test(void) ret = qemu_chr_fe_write(&be, (void *)"buf", 4); g_assert_cmpint(ret, ==, 4); - qemu_chr_fe_deinit(&be); - object_unparent(OBJECT(chr)); + qemu_chr_fe_deinit(&be, true); } static void char_invalid_test(void) @@ -603,6 +623,9 @@ int main(int argc, char **argv) g_test_add_func("/char/file", char_file_test); g_test_add_func("/char/socket", char_socket_test); g_test_add_func("/char/udp", char_udp_test); +#ifdef HAVE_CHARDEV_SERIAL + g_test_add_func("/char/serial", char_serial_test); +#endif return g_test_run(); } diff --git a/tests/test-clone-visitor.c b/tests/test-clone-visitor.c index df0c045512..96982163e4 100644 --- a/tests/test-clone-visitor.c +++ b/tests/test-clone-visitor.c @@ -42,29 +42,28 @@ static void test_clone_struct(void) static void test_clone_alternate(void) { - AltStrBool *b_src, *s_src, *b_dst, *s_dst; + AltEnumBool *b_src, *s_src, *b_dst, *s_dst; - b_src = g_new0(AltStrBool, 1); + b_src = g_new0(AltEnumBool, 1); b_src->type = QTYPE_QBOOL; b_src->u.b = true; - s_src = g_new0(AltStrBool, 1); + s_src = g_new0(AltEnumBool, 1); s_src->type = QTYPE_QSTRING; - s_src->u.s = g_strdup("World"); + s_src->u.e = ENUM_ONE_VALUE1; - b_dst = QAPI_CLONE(AltStrBool, b_src); + b_dst = QAPI_CLONE(AltEnumBool, b_src); g_assert(b_dst); g_assert_cmpint(b_dst->type, ==, b_src->type); g_assert_cmpint(b_dst->u.b, ==, b_src->u.b); - s_dst = QAPI_CLONE(AltStrBool, s_src); + s_dst = QAPI_CLONE(AltEnumBool, s_src); g_assert(s_dst); g_assert_cmpint(s_dst->type, ==, s_src->type); - g_assert_cmpstr(s_dst->u.s, ==, s_src->u.s); - g_assert(s_dst->u.s != s_src->u.s); + g_assert_cmpint(s_dst->u.e, ==, s_src->u.e); - qapi_free_AltStrBool(b_src); - qapi_free_AltStrBool(s_src); - qapi_free_AltStrBool(b_dst); - qapi_free_AltStrBool(s_dst); + qapi_free_AltEnumBool(b_src); + qapi_free_AltEnumBool(s_src); + qapi_free_AltEnumBool(b_dst); + qapi_free_AltEnumBool(s_dst); } static void test_clone_native_list(void) diff --git a/tests/test-keyval.c b/tests/test-keyval.c index c556b1b117..c3be00524c 100644 --- a/tests/test-keyval.c +++ b/tests/test-keyval.c @@ -614,22 +614,26 @@ static void test_keyval_visit_alternate(void) Error *err = NULL; Visitor *v; QDict *qdict; - AltNumStr *ans; + AltStrObj *aso; AltNumInt *ani; + AltEnumBool *aeb; /* * Can't do scalar alternate variants other than string. You get * the string variant if there is one, else an error. + * TODO make it work for unambiguous cases like AltEnumBool below */ - qdict = keyval_parse("a=1,b=2", NULL, &error_abort); + qdict = keyval_parse("a=1,b=2,c=on", NULL, &error_abort); v = qobject_input_visitor_new_keyval(QOBJECT(qdict)); QDECREF(qdict); visit_start_struct(v, NULL, NULL, 0, &error_abort); - visit_type_AltNumStr(v, "a", &ans, &error_abort); - g_assert_cmpint(ans->type, ==, QTYPE_QSTRING); - g_assert_cmpstr(ans->u.s, ==, "1"); - qapi_free_AltNumStr(ans); - visit_type_AltNumInt(v, "a", &ani, &err); + visit_type_AltStrObj(v, "a", &aso, &error_abort); + g_assert_cmpint(aso->type, ==, QTYPE_QSTRING); + g_assert_cmpstr(aso->u.s, ==, "1"); + qapi_free_AltStrObj(aso); + visit_type_AltNumInt(v, "b", &ani, &err); + error_free_or_abort(&err); + visit_type_AltEnumBool(v, "c", &aeb, &err); error_free_or_abort(&err); visit_end_struct(v, NULL); visit_free(v); diff --git a/tests/test-qobject-input-visitor.c b/tests/test-qobject-input-visitor.c index f965743b6e..6b997a177d 100644 --- a/tests/test-qobject-input-visitor.c +++ b/tests/test-qobject-input-visitor.c @@ -278,11 +278,17 @@ static void test_visitor_in_number_str_keyval(TestInputVisitorData *data, { double res = 0, value = 3.14; Visitor *v; + Error *err = NULL; v = visitor_input_test_init_full(data, true, "\"3.14\""); visit_type_number(v, NULL, &res, &error_abort); g_assert_cmpfloat(res, ==, value); + + v = visitor_input_test_init_full(data, true, "\"inf\""); + + visit_type_number(v, NULL, &res, &err); + error_free_or_abort(&err); } static void test_visitor_in_number_str_fail(TestInputVisitorData *data, @@ -531,10 +537,10 @@ static void test_visitor_in_alternate(TestInputVisitorData *data, g_assert_cmpint(tmp->u.i, ==, 42); qapi_free_UserDefAlternate(tmp); - v = visitor_input_test_init(data, "'string'"); + v = visitor_input_test_init(data, "'value1'"); visit_type_UserDefAlternate(v, NULL, &tmp, &error_abort); g_assert_cmpint(tmp->type, ==, QTYPE_QSTRING); - g_assert_cmpstr(tmp->u.s, ==, "string"); + g_assert_cmpint(tmp->u.e, ==, ENUM_ONE_VALUE1); qapi_free_UserDefAlternate(tmp); v = visitor_input_test_init(data, "{'integer':1, 'string':'str', " @@ -559,10 +565,10 @@ static void test_visitor_in_alternate(TestInputVisitorData *data, g_assert_cmpint(wrap->alt->u.i, ==, 42); qapi_free_WrapAlternate(wrap); - v = visitor_input_test_init(data, "{ 'alt': 'string' }"); + v = visitor_input_test_init(data, "{ 'alt': 'value1' }"); visit_type_WrapAlternate(v, NULL, &wrap, &error_abort); g_assert_cmpint(wrap->alt->type, ==, QTYPE_QSTRING); - g_assert_cmpstr(wrap->alt->u.s, ==, "string"); + g_assert_cmpint(wrap->alt->u.e, ==, ENUM_ONE_VALUE1); qapi_free_WrapAlternate(wrap); v = visitor_input_test_init(data, "{ 'alt': {'integer':1, 'string':'str', " @@ -582,37 +588,37 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data, { Visitor *v; Error *err = NULL; - AltStrBool *asb; - AltStrNum *asn; - AltNumStr *ans; - AltStrInt *asi; + AltEnumBool *aeb; + AltEnumNum *aen; + AltNumEnum *ans; + AltEnumInt *asi; AltIntNum *ain; AltNumInt *ani; /* Parsing an int */ v = visitor_input_test_init(data, "42"); - visit_type_AltStrBool(v, NULL, &asb, &err); + visit_type_AltEnumBool(v, NULL, &aeb, &err); error_free_or_abort(&err); - qapi_free_AltStrBool(asb); + qapi_free_AltEnumBool(aeb); v = visitor_input_test_init(data, "42"); - visit_type_AltStrNum(v, NULL, &asn, &error_abort); - g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); - g_assert_cmpfloat(asn->u.n, ==, 42); - qapi_free_AltStrNum(asn); + visit_type_AltEnumNum(v, NULL, &aen, &error_abort); + g_assert_cmpint(aen->type, ==, QTYPE_QFLOAT); + g_assert_cmpfloat(aen->u.n, ==, 42); + qapi_free_AltEnumNum(aen); v = visitor_input_test_init(data, "42"); - visit_type_AltNumStr(v, NULL, &ans, &error_abort); + visit_type_AltNumEnum(v, NULL, &ans, &error_abort); g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(ans->u.n, ==, 42); - qapi_free_AltNumStr(ans); + qapi_free_AltNumEnum(ans); v = visitor_input_test_init(data, "42"); - visit_type_AltStrInt(v, NULL, &asi, &error_abort); + visit_type_AltEnumInt(v, NULL, &asi, &error_abort); g_assert_cmpint(asi->type, ==, QTYPE_QINT); g_assert_cmpint(asi->u.i, ==, 42); - qapi_free_AltStrInt(asi); + qapi_free_AltEnumInt(asi); v = visitor_input_test_init(data, "42"); visit_type_AltIntNum(v, NULL, &ain, &error_abort); @@ -629,26 +635,26 @@ static void test_visitor_in_alternate_number(TestInputVisitorData *data, /* Parsing a double */ v = visitor_input_test_init(data, "42.5"); - visit_type_AltStrBool(v, NULL, &asb, &err); + visit_type_AltEnumBool(v, NULL, &aeb, &err); error_free_or_abort(&err); - qapi_free_AltStrBool(asb); + qapi_free_AltEnumBool(aeb); v = visitor_input_test_init(data, "42.5"); - visit_type_AltStrNum(v, NULL, &asn, &error_abort); - g_assert_cmpint(asn->type, ==, QTYPE_QFLOAT); - g_assert_cmpfloat(asn->u.n, ==, 42.5); - qapi_free_AltStrNum(asn); + visit_type_AltEnumNum(v, NULL, &aen, &error_abort); + g_assert_cmpint(aen->type, ==, QTYPE_QFLOAT); + g_assert_cmpfloat(aen->u.n, ==, 42.5); + qapi_free_AltEnumNum(aen); v = visitor_input_test_init(data, "42.5"); - visit_type_AltNumStr(v, NULL, &ans, &error_abort); + visit_type_AltNumEnum(v, NULL, &ans, &error_abort); g_assert_cmpint(ans->type, ==, QTYPE_QFLOAT); g_assert_cmpfloat(ans->u.n, ==, 42.5); - qapi_free_AltNumStr(ans); + qapi_free_AltNumEnum(ans); v = visitor_input_test_init(data, "42.5"); - visit_type_AltStrInt(v, NULL, &asi, &err); + visit_type_AltEnumInt(v, NULL, &asi, &err); error_free_or_abort(&err); - qapi_free_AltStrInt(asi); + qapi_free_AltEnumInt(asi); v = visitor_input_test_init(data, "42.5"); visit_type_AltIntNum(v, NULL, &ain, &error_abort); diff --git a/tests/test-qobject-output-visitor.c b/tests/test-qobject-output-visitor.c index 94b9518e40..4e8fdf1397 100644 --- a/tests/test-qobject-output-visitor.c +++ b/tests/test-qobject-output-visitor.c @@ -406,12 +406,12 @@ static void test_visitor_out_alternate(TestOutputVisitorData *data, visitor_reset(data); tmp = g_new0(UserDefAlternate, 1); tmp->type = QTYPE_QSTRING; - tmp->u.s = g_strdup("hello"); + tmp->u.e = ENUM_ONE_VALUE1; visit_type_UserDefAlternate(data->ov, NULL, &tmp, &error_abort); qstr = qobject_to_qstring(visitor_get(data)); g_assert(qstr); - g_assert_cmpstr(qstring_get_str(qstr), ==, "hello"); + g_assert_cmpstr(qstring_get_str(qstr), ==, "value1"); qapi_free_UserDefAlternate(tmp); diff --git a/tests/test-vmstate.c b/tests/test-vmstate.c index 25389bcce4..c52aff96d6 100644 --- a/tests/test-vmstate.c +++ b/tests/test-vmstate.c @@ -27,7 +27,8 @@ #include "qemu-common.h" #include "migration/migration.h" #include "migration/vmstate.h" -#include "migration/qemu-file.h" +#include "migration/qemu-file-types.h" +#include "../migration/qemu-file.h" #include "../migration/qemu-file-channel.h" #include "qemu/coroutine.h" #include "io/channel-file.h" diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c index 6c71e46391..4166ce54b7 100644 --- a/tests/test-x86-cpuid-compat.c +++ b/tests/test-x86-cpuid-compat.c @@ -313,6 +313,44 @@ int main(int argc, char **argv) add_cpuid_test("x86/cpuid/auto-xlevel2/pc-2.7", "-machine pc-i440fx-2.7 -cpu 486,+xstore", "xlevel2", 0); + /* + * QEMU 1.4.0 had auto-level enabled for CPUID[7], already, + * and the compat code that sets default level shouldn't + * disable the auto-level=7 code: + */ + add_cpuid_test("x86/cpuid/auto-level7/pc-i440fx-1.4/off", + "-machine pc-i440fx-1.4 -cpu Nehalem", + "level", 2); + add_cpuid_test("x86/cpuid/auto-level7/pc-i440fx-1.5/on", + "-machine pc-i440fx-1.4 -cpu Nehalem,+smap", + "level", 7); + add_cpuid_test("x86/cpuid/auto-level7/pc-i440fx-2.3/off", + "-machine pc-i440fx-2.3 -cpu Penryn", + "level", 4); + add_cpuid_test("x86/cpuid/auto-level7/pc-i440fx-2.3/on", + "-machine pc-i440fx-2.3 -cpu Penryn,+erms", + "level", 7); + add_cpuid_test("x86/cpuid/auto-level7/pc-i440fx-2.9/off", + "-machine pc-i440fx-2.9 -cpu Conroe", + "level", 10); + add_cpuid_test("x86/cpuid/auto-level7/pc-i440fx-2.9/on", + "-machine pc-i440fx-2.9 -cpu Conroe,+erms", + "level", 10); + + /* + * xlevel doesn't have any feature that triggers auto-level + * code on old machine-types. Just check that the compat code + * is working correctly: + */ + add_cpuid_test("x86/cpuid/xlevel-compat/pc-i440fx-2.3", + "-machine pc-i440fx-2.3 -cpu SandyBridge", + "xlevel", 0x8000000a); + add_cpuid_test("x86/cpuid/xlevel-compat/pc-i440fx-2.4/npt-off", + "-machine pc-i440fx-2.4 -cpu SandyBridge,", + "xlevel", 0x80000008); + add_cpuid_test("x86/cpuid/xlevel-compat/pc-i440fx-2.4/npt-on", + "-machine pc-i440fx-2.4 -cpu SandyBridge,+npt", + "xlevel", 0x80000008); /* Test feature parsing */ add_feature_test("x86/cpuid/features/plus", diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c index 9095af267e..b3cc045765 100644 --- a/tests/vhost-user-test.c +++ b/tests/vhost-user-test.c @@ -16,7 +16,7 @@ #include "qemu/option.h" #include "qemu/range.h" #include "qemu/sockets.h" -#include "sysemu/char.h" +#include "chardev/char-fe.h" #include "sysemu/sysemu.h" #include "libqos/libqos.h" #include "libqos/pci-pc.h" @@ -488,10 +488,8 @@ static inline void test_server_connect(TestServer *server) static gboolean _test_server_free(TestServer *server) { int i; - Chardev *chr = qemu_chr_fe_get_driver(&server->chr); - qemu_chr_fe_deinit(&server->chr); - object_unparent(OBJECT(chr)); + qemu_chr_fe_deinit(&server->chr, true); for (i = 0; i < server->fds_num; i++) { close(server->fds[i]); diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c index 8b0f77a63e..eff71df81f 100644 --- a/tests/virtio-scsi-test.c +++ b/tests/virtio-scsi-test.c @@ -149,7 +149,7 @@ static QVirtIOSCSI *qvirtio_scsi_pci_init(int slot) vs->qs = qvirtio_scsi_start("-drive file=blkdebug::null-co://," "if=none,id=dr1,format=raw,file.align=4k " - "-device scsi-disk,drive=dr1,lun=0,scsi-id=1"); + "-device scsi-hd,drive=dr1,lun=0,scsi-id=1"); dev = qvirtio_pci_device_find(vs->qs->pcibus, VIRTIO_ID_SCSI); vs->dev = (QVirtioDevice *)dev; g_assert(dev != NULL); |