aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rwxr-xr-xtests/qemu-iotests/tests/qsd-jobs86
-rw-r--r--tests/qemu-iotests/tests/qsd-jobs.out32
-rw-r--r--tests/qtest/qmp-cmd-test.c16
-rw-r--r--tests/qtest/test-netfilter.c54
-rw-r--r--tests/unit/check-qom-proplist.c77
-rw-r--r--tests/unit/test-char.c6
6 files changed, 205 insertions, 66 deletions
diff --git a/tests/qemu-iotests/tests/qsd-jobs b/tests/qemu-iotests/tests/qsd-jobs
new file mode 100755
index 0000000000..972b6b3898
--- /dev/null
+++ b/tests/qemu-iotests/tests/qsd-jobs
@@ -0,0 +1,86 @@
+#!/usr/bin/env bash
+# group: rw auto quick qsd
+#
+# Job tests related specifically to qemu-storage-daemon
+#
+# Copyright (C) 2021 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"
+
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+ rm -f "$SOCK_DIR/nbd.sock"
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+cd ..
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto generic
+
+size=128M
+
+TEST_IMG="$TEST_IMG.base" _make_test_img $size
+_make_test_img -b "$TEST_IMG.base" -F $IMGFMT
+
+echo
+echo "=== Job still present at shutdown ==="
+echo
+
+# Just make sure that this doesn't crash
+$QSD --chardev stdio,id=stdio --monitor chardev=stdio \
+ --blockdev node-name=file0,driver=file,filename="$TEST_IMG" \
+ --blockdev node-name=fmt0,driver=qcow2,file=file0 <<EOF | _filter_qmp
+{"execute":"qmp_capabilities"}
+{"execute": "block-commit", "arguments": {"device": "fmt0", "job-id": "job0"}}
+{"execute": "quit"}
+EOF
+
+echo
+echo "=== Streaming can't get permission on base node ==="
+echo
+
+# Just make sure that this doesn't crash
+$QSD --chardev stdio,id=stdio --monitor chardev=stdio \
+ --blockdev node-name=file_base,driver=file,filename="$TEST_IMG.base" \
+ --blockdev node-name=fmt_base,driver=qcow2,file=file_base \
+ --blockdev node-name=file_overlay,driver=file,filename="$TEST_IMG" \
+ --blockdev node-name=fmt_overlay,driver=qcow2,file=file_overlay,backing=fmt_base \
+ --nbd-server addr.type=unix,addr.path="$SOCK_DIR/nbd.sock" \
+ --export type=nbd,id=export1,node-name=fmt_base,writable=on,name=export1 \
+ <<EOF | _filter_qmp
+{"execute": "qmp_capabilities"}
+{"execute": "block-stream",
+ "arguments": {"device": "fmt_overlay", "job-id": "job0"}}
+{"execute": "quit"}
+EOF
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
+
diff --git a/tests/qemu-iotests/tests/qsd-jobs.out b/tests/qemu-iotests/tests/qsd-jobs.out
new file mode 100644
index 0000000000..05e1165e80
--- /dev/null
+++ b/tests/qemu-iotests/tests/qsd-jobs.out
@@ -0,0 +1,32 @@
+QA output created by qsd-jobs
+Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT
+
+=== Job still present at shutdown ===
+
+QMP_VERSION
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "job0"}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "standby", "id": "job0"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "job0"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "job0"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "job0"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "job0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "job0"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
+
+=== Streaming can't get permission on base node ===
+
+QMP_VERSION
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "job0"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "job0"}}
+{"error": {"class": "GenericError", "desc": "Conflicts with use by a block device as 'root', which uses 'write' on fmt_base"}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_EXPORT_DELETED", "data": {"id": "export1"}}
+*** done
diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c
index 1c7186e53c..c98b78d033 100644
--- a/tests/qtest/qmp-cmd-test.c
+++ b/tests/qtest/qmp-cmd-test.c
@@ -230,14 +230,14 @@ static void test_object_add_failure_modes(void)
/* attempt to create 2 objects with duplicate id */
resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
" {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
- " 'props': {'size': 1048576 } } }");
+ " 'size': 1048576 } }");
g_assert_nonnull(resp);
g_assert(qdict_haskey(resp, "return"));
qobject_unref(resp);
resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
" {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
- " 'props': {'size': 1048576 } } }");
+ " 'size': 1048576 } }");
g_assert_nonnull(resp);
qmp_expect_error_and_unref(resp, "GenericError");
@@ -251,14 +251,14 @@ static void test_object_add_failure_modes(void)
/* attempt to create an object with a property of a wrong type */
resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
" {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
- " 'props': {'size': '1048576' } } }");
+ " 'size': '1048576' } }");
g_assert_nonnull(resp);
/* now do it right */
qmp_expect_error_and_unref(resp, "GenericError");
resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
" {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
- " 'props': {'size': 1048576 } } }");
+ " 'size': 1048576 } }");
g_assert_nonnull(resp);
g_assert(qdict_haskey(resp, "return"));
qobject_unref(resp);
@@ -273,14 +273,14 @@ static void test_object_add_failure_modes(void)
/* attempt to create an object without the id */
resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
" {'qom-type': 'memory-backend-ram',"
- " 'props': {'size': 1048576 } } }");
+ " 'size': 1048576 } }");
g_assert_nonnull(resp);
qmp_expect_error_and_unref(resp, "GenericError");
/* now do it right */
resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
" {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
- " 'props': {'size': 1048576 } } }");
+ " 'size': 1048576 } }");
g_assert_nonnull(resp);
g_assert(qdict_haskey(resp, "return"));
qobject_unref(resp);
@@ -295,14 +295,14 @@ static void test_object_add_failure_modes(void)
/* attempt to set a non existing property */
resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
" {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
- " 'props': {'sized': 1048576 } } }");
+ " 'sized': 1048576 } }");
g_assert_nonnull(resp);
qmp_expect_error_and_unref(resp, "GenericError");
/* now do it right */
resp = qtest_qmp(qts, "{'execute': 'object-add', 'arguments':"
" {'qom-type': 'memory-backend-ram', 'id': 'ram1',"
- " 'props': {'size': 1048576 } } }");
+ " 'size': 1048576 } }");
g_assert_nonnull(resp);
g_assert(qdict_haskey(resp, "return"));
qobject_unref(resp);
diff --git a/tests/qtest/test-netfilter.c b/tests/qtest/test-netfilter.c
index 22927ee6ab..785b6f3226 100644
--- a/tests/qtest/test-netfilter.c
+++ b/tests/qtest/test-netfilter.c
@@ -21,11 +21,10 @@ static void add_one_netfilter(void)
" 'arguments': {"
" 'qom-type': 'filter-buffer',"
" 'id': 'qtest-f0',"
- " 'props': {"
- " 'netdev': 'qtest-bn0',"
- " 'queue': 'rx',"
- " 'interval': 1000"
- "}}}");
+ " 'netdev': 'qtest-bn0',"
+ " 'queue': 'rx',"
+ " 'interval': 1000"
+ "}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
@@ -49,11 +48,10 @@ static void remove_netdev_with_one_netfilter(void)
" 'arguments': {"
" 'qom-type': 'filter-buffer',"
" 'id': 'qtest-f0',"
- " 'props': {"
- " 'netdev': 'qtest-bn0',"
- " 'queue': 'rx',"
- " 'interval': 1000"
- "}}}");
+ " 'netdev': 'qtest-bn0',"
+ " 'queue': 'rx',"
+ " 'interval': 1000"
+ "}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
@@ -87,11 +85,10 @@ static void add_multi_netfilter(void)
" 'arguments': {"
" 'qom-type': 'filter-buffer',"
" 'id': 'qtest-f0',"
- " 'props': {"
- " 'netdev': 'qtest-bn0',"
- " 'queue': 'rx',"
- " 'interval': 1000"
- "}}}");
+ " 'netdev': 'qtest-bn0',"
+ " 'queue': 'rx',"
+ " 'interval': 1000"
+ "}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
@@ -101,11 +98,10 @@ static void add_multi_netfilter(void)
" 'arguments': {"
" 'qom-type': 'filter-buffer',"
" 'id': 'qtest-f1',"
- " 'props': {"
- " 'netdev': 'qtest-bn0',"
- " 'queue': 'rx',"
- " 'interval': 1000"
- "}}}");
+ " 'netdev': 'qtest-bn0',"
+ " 'queue': 'rx',"
+ " 'interval': 1000"
+ "}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
@@ -137,11 +133,10 @@ static void remove_netdev_with_multi_netfilter(void)
" 'arguments': {"
" 'qom-type': 'filter-buffer',"
" 'id': 'qtest-f0',"
- " 'props': {"
- " 'netdev': 'qtest-bn0',"
- " 'queue': 'rx',"
- " 'interval': 1000"
- "}}}");
+ " 'netdev': 'qtest-bn0',"
+ " 'queue': 'rx',"
+ " 'interval': 1000"
+ "}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
@@ -151,11 +146,10 @@ static void remove_netdev_with_multi_netfilter(void)
" 'arguments': {"
" 'qom-type': 'filter-buffer',"
" 'id': 'qtest-f1',"
- " 'props': {"
- " 'netdev': 'qtest-bn0',"
- " 'queue': 'rx',"
- " 'interval': 1000"
- "}}}");
+ " 'netdev': 'qtest-bn0',"
+ " 'queue': 'rx',"
+ " 'interval': 1000"
+ "}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
diff --git a/tests/unit/check-qom-proplist.c b/tests/unit/check-qom-proplist.c
index 1b76581980..48503e0dff 100644
--- a/tests/unit/check-qom-proplist.c
+++ b/tests/unit/check-qom-proplist.c
@@ -21,6 +21,9 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
+#include "qapi/qobject-input-visitor.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qobject.h"
#include "qom/object.h"
#include "qemu/module.h"
#include "qemu/option.h"
@@ -398,44 +401,74 @@ static void test_dummy_createlist(void)
object_unparent(OBJECT(dobj));
}
+static bool test_create_obj(QDict *qdict, Error **errp)
+{
+ Visitor *v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
+ Object *obj = user_creatable_add_type(TYPE_DUMMY, "dev0", qdict, v, errp);
+
+ visit_free(v);
+ object_unref(obj);
+ return !!obj;
+}
+
static void test_dummy_createcmdl(void)
{
- QemuOpts *opts;
+ QDict *qdict;
DummyObject *dobj;
Error *err = NULL;
- const char *params = TYPE_DUMMY \
- ",id=dev0," \
- "bv=yes,sv=Hiss hiss hiss,av=platypus";
+ bool created, help;
+ const char *params = "bv=yes,sv=Hiss hiss hiss,av=platypus";
+ /* Needed for user_creatable_del. */
qemu_add_opts(&qemu_object_opts);
- opts = qemu_opts_parse(&qemu_object_opts, params, true, &err);
+
+ qdict = keyval_parse(params, "qom-type", &help, &err);
g_assert(err == NULL);
- g_assert(opts);
+ g_assert(qdict);
+ g_assert(!help);
- dobj = DUMMY_OBJECT(user_creatable_add_opts(opts, &err));
+ created = test_create_obj(qdict, &err);
+ g_assert(created);
g_assert(err == NULL);
+ qobject_unref(qdict);
+
+ dobj = DUMMY_OBJECT(object_resolve_path_component(object_get_objects_root(),
+ "dev0"));
g_assert(dobj);
g_assert_cmpstr(dobj->sv, ==, "Hiss hiss hiss");
g_assert(dobj->bv == true);
g_assert(dobj->av == DUMMY_PLATYPUS);
+ qdict = keyval_parse(params, "qom-type", &help, &err);
+ created = test_create_obj(qdict, &err);
+ g_assert(!created);
+ g_assert(err);
+ g_assert(object_resolve_path_component(object_get_objects_root(), "dev0")
+ == OBJECT(dobj));
+ qobject_unref(qdict);
+ error_free(err);
+ err = NULL;
+
+ qdict = keyval_parse(params, "qom-type", &help, &err);
user_creatable_del("dev0", &error_abort);
+ g_assert(object_resolve_path_component(object_get_objects_root(), "dev0")
+ == NULL);
- object_unref(OBJECT(dobj));
-
- /*
- * 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"));
+ created = test_create_obj(qdict, &err);
+ g_assert(created);
+ g_assert(err == NULL);
+ qobject_unref(qdict);
+
+ dobj = DUMMY_OBJECT(object_resolve_path_component(object_get_objects_root(),
+ "dev0"));
+ g_assert(dobj);
+ g_assert_cmpstr(dobj->sv, ==, "Hiss hiss hiss");
+ g_assert(dobj->bv == true);
+ g_assert(dobj->av == DUMMY_PLATYPUS);
+ g_assert(object_resolve_path_component(object_get_objects_root(), "dev0")
+ == OBJECT(dobj));
+
+ object_unparent(OBJECT(dobj));
}
static void test_dummy_badenum(void)
diff --git a/tests/unit/test-char.c b/tests/unit/test-char.c
index 755d54c15e..5b3b48ebac 100644
--- a/tests/unit/test-char.c
+++ b/tests/unit/test-char.c
@@ -1199,12 +1199,6 @@ static void char_serial_test(void)
/* 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, &error_abort);
- g_assert_nonnull(chr);
- object_unparent(OBJECT(chr));
-
qemu_opts_del(opts);
}
#endif