qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, jsnow@redhat.com, armbru@redhat.com
Subject: [PATCH v3 6/6] tests/qapi-schema: Test cases for aliases
Date: Thu, 12 Aug 2021 18:11:31 +0200	[thread overview]
Message-ID: <20210812161131.92017-7-kwolf@redhat.com> (raw)
In-Reply-To: <20210812161131.92017-1-kwolf@redhat.com>

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 tests/unit/test-qobject-input-visitor.c       | 218 ++++++++++++++++++
 tests/qapi-schema/alias-bad-type.err          |   2 +
 tests/qapi-schema/alias-bad-type.json         |   3 +
 tests/qapi-schema/alias-bad-type.out          |   0
 tests/qapi-schema/alias-missing-source.err    |   2 +
 tests/qapi-schema/alias-missing-source.json   |   3 +
 tests/qapi-schema/alias-missing-source.out    |   0
 tests/qapi-schema/alias-name-bad-type.err     |   2 +
 tests/qapi-schema/alias-name-bad-type.json    |   3 +
 tests/qapi-schema/alias-name-bad-type.out     |   0
 tests/qapi-schema/alias-name-conflict.err     |   2 +
 tests/qapi-schema/alias-name-conflict.json    |   4 +
 tests/qapi-schema/alias-name-conflict.out     |   0
 tests/qapi-schema/alias-recursive.err         |   2 +
 tests/qapi-schema/alias-recursive.json        |   4 +
 tests/qapi-schema/alias-recursive.out         |   0
 tests/qapi-schema/alias-source-bad-type.err   |   2 +
 tests/qapi-schema/alias-source-bad-type.json  |   3 +
 tests/qapi-schema/alias-source-bad-type.out   |   0
 .../alias-source-elem-bad-type.err            |   2 +
 .../alias-source-elem-bad-type.json           |   3 +
 .../alias-source-elem-bad-type.out            |   0
 tests/qapi-schema/alias-source-empty.err      |   2 +
 tests/qapi-schema/alias-source-empty.json     |   3 +
 tests/qapi-schema/alias-source-empty.out      |   0
 .../alias-source-inexistent-variants.err      |   2 +
 .../alias-source-inexistent-variants.json     |  12 +
 .../alias-source-inexistent-variants.out      |   0
 tests/qapi-schema/alias-source-inexistent.err |   2 +
 .../qapi-schema/alias-source-inexistent.json  |   3 +
 tests/qapi-schema/alias-source-inexistent.out |   0
 .../alias-source-non-object-path.err          |   2 +
 .../alias-source-non-object-path.json         |   3 +
 .../alias-source-non-object-path.out          |   0
 .../alias-source-non-object-wildcard.err      |   2 +
 .../alias-source-non-object-wildcard.json     |   3 +
 .../alias-source-non-object-wildcard.out      |   0
 ...lias-source-optional-wildcard-indirect.err |   2 +
 ...ias-source-optional-wildcard-indirect.json |   6 +
 ...lias-source-optional-wildcard-indirect.out |   0
 .../alias-source-optional-wildcard.err        |   2 +
 .../alias-source-optional-wildcard.json       |   5 +
 .../alias-source-optional-wildcard.out        |   0
 tests/qapi-schema/alias-unknown-key.err       |   3 +
 tests/qapi-schema/alias-unknown-key.json      |   3 +
 tests/qapi-schema/alias-unknown-key.out       |   0
 tests/qapi-schema/aliases-bad-type.err        |   2 +
 tests/qapi-schema/aliases-bad-type.json       |   3 +
 tests/qapi-schema/aliases-bad-type.out        |   0
 tests/qapi-schema/meson.build                 |  16 ++
 tests/qapi-schema/qapi-schema-test.json       |  26 +++
 tests/qapi-schema/qapi-schema-test.out        |  31 +++
 52 files changed, 388 insertions(+)
 create mode 100644 tests/qapi-schema/alias-bad-type.err
 create mode 100644 tests/qapi-schema/alias-bad-type.json
 create mode 100644 tests/qapi-schema/alias-bad-type.out
 create mode 100644 tests/qapi-schema/alias-missing-source.err
 create mode 100644 tests/qapi-schema/alias-missing-source.json
 create mode 100644 tests/qapi-schema/alias-missing-source.out
 create mode 100644 tests/qapi-schema/alias-name-bad-type.err
 create mode 100644 tests/qapi-schema/alias-name-bad-type.json
 create mode 100644 tests/qapi-schema/alias-name-bad-type.out
 create mode 100644 tests/qapi-schema/alias-name-conflict.err
 create mode 100644 tests/qapi-schema/alias-name-conflict.json
 create mode 100644 tests/qapi-schema/alias-name-conflict.out
 create mode 100644 tests/qapi-schema/alias-recursive.err
 create mode 100644 tests/qapi-schema/alias-recursive.json
 create mode 100644 tests/qapi-schema/alias-recursive.out
 create mode 100644 tests/qapi-schema/alias-source-bad-type.err
 create mode 100644 tests/qapi-schema/alias-source-bad-type.json
 create mode 100644 tests/qapi-schema/alias-source-bad-type.out
 create mode 100644 tests/qapi-schema/alias-source-elem-bad-type.err
 create mode 100644 tests/qapi-schema/alias-source-elem-bad-type.json
 create mode 100644 tests/qapi-schema/alias-source-elem-bad-type.out
 create mode 100644 tests/qapi-schema/alias-source-empty.err
 create mode 100644 tests/qapi-schema/alias-source-empty.json
 create mode 100644 tests/qapi-schema/alias-source-empty.out
 create mode 100644 tests/qapi-schema/alias-source-inexistent-variants.err
 create mode 100644 tests/qapi-schema/alias-source-inexistent-variants.json
 create mode 100644 tests/qapi-schema/alias-source-inexistent-variants.out
 create mode 100644 tests/qapi-schema/alias-source-inexistent.err
 create mode 100644 tests/qapi-schema/alias-source-inexistent.json
 create mode 100644 tests/qapi-schema/alias-source-inexistent.out
 create mode 100644 tests/qapi-schema/alias-source-non-object-path.err
 create mode 100644 tests/qapi-schema/alias-source-non-object-path.json
 create mode 100644 tests/qapi-schema/alias-source-non-object-path.out
 create mode 100644 tests/qapi-schema/alias-source-non-object-wildcard.err
 create mode 100644 tests/qapi-schema/alias-source-non-object-wildcard.json
 create mode 100644 tests/qapi-schema/alias-source-non-object-wildcard.out
 create mode 100644 tests/qapi-schema/alias-source-optional-wildcard-indirect.err
 create mode 100644 tests/qapi-schema/alias-source-optional-wildcard-indirect.json
 create mode 100644 tests/qapi-schema/alias-source-optional-wildcard-indirect.out
 create mode 100644 tests/qapi-schema/alias-source-optional-wildcard.err
 create mode 100644 tests/qapi-schema/alias-source-optional-wildcard.json
 create mode 100644 tests/qapi-schema/alias-source-optional-wildcard.out
 create mode 100644 tests/qapi-schema/alias-unknown-key.err
 create mode 100644 tests/qapi-schema/alias-unknown-key.json
 create mode 100644 tests/qapi-schema/alias-unknown-key.out
 create mode 100644 tests/qapi-schema/aliases-bad-type.err
 create mode 100644 tests/qapi-schema/aliases-bad-type.json
 create mode 100644 tests/qapi-schema/aliases-bad-type.out

diff --git a/tests/unit/test-qobject-input-visitor.c b/tests/unit/test-qobject-input-visitor.c
index e41b91a2a6..f2891b6f5d 100644
--- a/tests/unit/test-qobject-input-visitor.c
+++ b/tests/unit/test-qobject-input-visitor.c
@@ -952,6 +952,214 @@ static void test_visitor_in_list_union_number(TestInputVisitorData *data,
     g_string_free(gstr_list, true);
 }
 
+static void test_visitor_in_alias_struct_local(TestInputVisitorData *data,
+                                               const void *unused)
+{
+    AliasStruct1 *tmp = NULL;
+    Error *err = NULL;
+    Visitor *v;
+
+    /* Can still specify the real member name with alias support */
+    v = visitor_input_test_init(data, "{ 'foo': 42 }");
+    visit_type_AliasStruct1(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->foo, ==, 42);
+    qapi_free_AliasStruct1(tmp);
+
+    /* The alias is a working alternative */
+    v = visitor_input_test_init(data, "{ 'bar': 42 }");
+    visit_type_AliasStruct1(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->foo, ==, 42);
+    qapi_free_AliasStruct1(tmp);
+
+    /* But you can't use both at the same time */
+    v = visitor_input_test_init(data, "{ 'foo': 5, 'bar': 42 }");
+    visit_type_AliasStruct1(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+}
+
+static void test_visitor_in_alias_struct_nested(TestInputVisitorData *data,
+                                                const void *unused)
+{
+    AliasStruct2 *tmp = NULL;
+    Error *err = NULL;
+    Visitor *v;
+
+    /* Can still specify the real member names with alias support */
+    v = visitor_input_test_init(data, "{ 'nested': { 'foo': 42 } }");
+    visit_type_AliasStruct2(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->nested->foo, ==, 42);
+    qapi_free_AliasStruct2(tmp);
+
+    /* The inner alias is a working alternative */
+    v = visitor_input_test_init(data, "{ 'nested': { 'bar': 42 } }");
+    visit_type_AliasStruct2(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->nested->foo, ==, 42);
+    qapi_free_AliasStruct2(tmp);
+
+    /* So is the outer alias */
+    v = visitor_input_test_init(data, "{ 'bar': 42 }");
+    visit_type_AliasStruct2(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->nested->foo, ==, 42);
+    qapi_free_AliasStruct2(tmp);
+
+    /* You can't use more than one option at the same time */
+    v = visitor_input_test_init(data, "{ 'bar': 5, 'nested': { 'foo': 42 } }");
+    visit_type_AliasStruct2(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+
+    v = visitor_input_test_init(data, "{ 'bar': 5, 'nested': { 'bar': 42 } }");
+    visit_type_AliasStruct2(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+
+    v = visitor_input_test_init(data, "{ 'nested': { 'foo': 42, 'bar': 42 } }");
+    visit_type_AliasStruct2(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+
+    v = visitor_input_test_init(data, "{ 'bar': 5, "
+                                      "  'nested': { 'foo': 42, 'bar': 42 } }");
+    visit_type_AliasStruct2(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+}
+
+static void test_visitor_in_alias_wildcard(TestInputVisitorData *data,
+                                           const void *unused)
+{
+    AliasStruct3 *tmp = NULL;
+    Error *err = NULL;
+    Visitor *v;
+
+    /* Can still specify the real member names with alias support */
+    v = visitor_input_test_init(data, "{ 'nested': { 'foo': 42 } }");
+    visit_type_AliasStruct3(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->nested->foo, ==, 42);
+    qapi_free_AliasStruct3(tmp);
+
+    /* The wildcard alias makes it work on the top level */
+    v = visitor_input_test_init(data, "{ 'foo': 42 }");
+    visit_type_AliasStruct3(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->nested->foo, ==, 42);
+    qapi_free_AliasStruct3(tmp);
+
+    /* It makes the inner alias available, too */
+    v = visitor_input_test_init(data, "{ 'bar': 42 }");
+    visit_type_AliasStruct3(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->nested->foo, ==, 42);
+    qapi_free_AliasStruct3(tmp);
+
+    /* You can't use more than one option at the same time */
+    v = visitor_input_test_init(data, "{ 'foo': 42, 'nested': { 'foo': 42 } }");
+    visit_type_AliasStruct3(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+
+    v = visitor_input_test_init(data, "{ 'bar': 42, 'nested': { 'foo': 42 } }");
+    visit_type_AliasStruct3(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+
+    v = visitor_input_test_init(data, "{ 'foo': 42, 'nested': { 'bar': 42 } }");
+    visit_type_AliasStruct3(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+
+    v = visitor_input_test_init(data, "{ 'bar': 42, 'nested': { 'bar': 42 } }");
+    visit_type_AliasStruct3(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+
+    v = visitor_input_test_init(data, "{ 'foo': 42, 'bar': 42 }");
+    visit_type_AliasStruct3(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+}
+
+static void test_visitor_in_alias_flat_union(TestInputVisitorData *data,
+                                             const void *unused)
+{
+    AliasFlatUnion *tmp = NULL;
+    Error *err = NULL;
+    Visitor *v;
+
+    /* Can still specify the real member name with alias support */
+    v = visitor_input_test_init(data, "{ 'tag': 'drei' }");
+    visit_type_AliasFlatUnion(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->tag, ==, FEATURE_ENUM1_DREI);
+    qapi_free_AliasFlatUnion(tmp);
+
+    /* Use alias for a base member (the discriminator even) */
+    v = visitor_input_test_init(data, "{ 'variant': 'zwei' }");
+    visit_type_AliasFlatUnion(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->tag, ==, FEATURE_ENUM1_ZWEI);
+    qapi_free_AliasFlatUnion(tmp);
+
+    /* Use alias for a variant member */
+    v = visitor_input_test_init(data, "{ 'tag': 'eins', 'bar': 42 }");
+    visit_type_AliasFlatUnion(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->tag, ==, FEATURE_ENUM1_EINS);
+    g_assert_cmpint(tmp->u.eins.foo, ==, 42);
+    qapi_free_AliasFlatUnion(tmp);
+
+    /* Both together */
+    v = visitor_input_test_init(data, "{ 'variant': 'eins', 'bar': 42 }");
+    visit_type_AliasFlatUnion(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->tag, ==, FEATURE_ENUM1_EINS);
+    g_assert_cmpint(tmp->u.eins.foo, ==, 42);
+    qapi_free_AliasFlatUnion(tmp);
+
+    /* You can't use more than one option at the same time for each alias */
+    v = visitor_input_test_init(data, "{ 'variant': 'zwei', 'tag': 'drei' }");
+    visit_type_AliasFlatUnion(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+
+    v = visitor_input_test_init(data, "{ 'tag': 'eins', 'foo': 6, 'bar': 9 }");
+    visit_type_AliasFlatUnion(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+}
+
+static void test_visitor_in_alias_simple_union(TestInputVisitorData *data,
+                                               const void *unused)
+{
+    AliasSimpleUnion *tmp = NULL;
+    Error *err = NULL;
+    Visitor *v;
+
+    /* Can still specify the real member name with alias support */
+    v = visitor_input_test_init(data, "{ 'type': 'eins', "
+                                      "  'data': { 'foo': 42 } }");
+    visit_type_AliasSimpleUnion(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->type, ==, ALIAS_SIMPLE_UNION_KIND_EINS);
+    g_assert_cmpint(tmp->u.eins.data->foo, ==, 42);
+    qapi_free_AliasSimpleUnion(tmp);
+
+    /* 'type' can be aliased */
+    v = visitor_input_test_init(data, "{ 'tag': 'eins', "
+                                      "  'data': { 'foo': 42 } }");
+    visit_type_AliasSimpleUnion(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->type, ==, ALIAS_SIMPLE_UNION_KIND_EINS);
+    g_assert_cmpint(tmp->u.eins.data->foo, ==, 42);
+    qapi_free_AliasSimpleUnion(tmp);
+
+    /* The wildcard alias makes it work on the top level */
+    v = visitor_input_test_init(data, "{ 'type': 'eins', 'foo': 42 }");
+    visit_type_AliasSimpleUnion(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->type, ==, ALIAS_SIMPLE_UNION_KIND_EINS);
+    g_assert_cmpint(tmp->u.eins.data->foo, ==, 42);
+    qapi_free_AliasSimpleUnion(tmp);
+
+    /* It makes the inner alias available, too */
+    v = visitor_input_test_init(data, "{ 'type': 'eins', 'bar': 42 }");
+    visit_type_AliasSimpleUnion(v, NULL, &tmp, &error_abort);
+    g_assert_cmpint(tmp->type, ==, ALIAS_SIMPLE_UNION_KIND_EINS);
+    g_assert_cmpint(tmp->u.eins.data->foo, ==, 42);
+    qapi_free_AliasSimpleUnion(tmp);
+
+    /* You can't use more than one option at the same time for each alias */
+    v = visitor_input_test_init(data, "{ 'type': 'eins', 'tag': 'eins' }");
+    visit_type_AliasSimpleUnion(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+
+    v = visitor_input_test_init(data, "{ 'type': 'eins', "
+                                      "  'bar': 123, "
+                                      "  'data': { 'foo': 312 } }");
+    visit_type_AliasSimpleUnion(v, NULL, &tmp, &err);
+    error_free_or_abort(&err);
+}
+
 static void input_visitor_test_add(const char *testpath,
                                    const void *user_data,
                                    void (*test_func)(TestInputVisitorData *data,
@@ -1350,6 +1558,16 @@ int main(int argc, char **argv)
                            NULL, test_visitor_in_list_union_string);
     input_visitor_test_add("/visitor/input/list_union/number",
                            NULL, test_visitor_in_list_union_number);
+    input_visitor_test_add("/visitor/input/alias/struct-local",
+                           NULL, test_visitor_in_alias_struct_local);
+    input_visitor_test_add("/visitor/input/alias/struct-nested",
+                           NULL, test_visitor_in_alias_struct_nested);
+    input_visitor_test_add("/visitor/input/alias/wildcard",
+                           NULL, test_visitor_in_alias_wildcard);
+    input_visitor_test_add("/visitor/input/alias/flat-union",
+                           NULL, test_visitor_in_alias_flat_union);
+    input_visitor_test_add("/visitor/input/alias/simple-union",
+                           NULL, test_visitor_in_alias_simple_union);
     input_visitor_test_add("/visitor/input/fail/struct",
                            NULL, test_visitor_in_fail_struct);
     input_visitor_test_add("/visitor/input/fail/struct-nested",
diff --git a/tests/qapi-schema/alias-bad-type.err b/tests/qapi-schema/alias-bad-type.err
new file mode 100644
index 0000000000..820e18ed9c
--- /dev/null
+++ b/tests/qapi-schema/alias-bad-type.err
@@ -0,0 +1,2 @@
+alias-bad-type.json: In struct 'AliasStruct0':
+alias-bad-type.json:1: 'aliases' members must be objects
diff --git a/tests/qapi-schema/alias-bad-type.json b/tests/qapi-schema/alias-bad-type.json
new file mode 100644
index 0000000000..0aa5d206fe
--- /dev/null
+++ b/tests/qapi-schema/alias-bad-type.json
@@ -0,0 +1,3 @@
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int' },
+  'aliases': [ 'must be an object' ] }
diff --git a/tests/qapi-schema/alias-bad-type.out b/tests/qapi-schema/alias-bad-type.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-missing-source.err b/tests/qapi-schema/alias-missing-source.err
new file mode 100644
index 0000000000..8b7d601fbf
--- /dev/null
+++ b/tests/qapi-schema/alias-missing-source.err
@@ -0,0 +1,2 @@
+alias-missing-source.json: In struct 'AliasStruct0':
+alias-missing-source.json:1: 'aliases' member misses key 'source'
diff --git a/tests/qapi-schema/alias-missing-source.json b/tests/qapi-schema/alias-missing-source.json
new file mode 100644
index 0000000000..b6c91a9488
--- /dev/null
+++ b/tests/qapi-schema/alias-missing-source.json
@@ -0,0 +1,3 @@
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int' },
+  'aliases': [ { 'name': 'bar' } ] }
diff --git a/tests/qapi-schema/alias-missing-source.out b/tests/qapi-schema/alias-missing-source.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-name-bad-type.err b/tests/qapi-schema/alias-name-bad-type.err
new file mode 100644
index 0000000000..489f45ff9b
--- /dev/null
+++ b/tests/qapi-schema/alias-name-bad-type.err
@@ -0,0 +1,2 @@
+alias-name-bad-type.json: In struct 'AliasStruct0':
+alias-name-bad-type.json:1: alias member 'name' requires a string name
diff --git a/tests/qapi-schema/alias-name-bad-type.json b/tests/qapi-schema/alias-name-bad-type.json
new file mode 100644
index 0000000000..17442d5939
--- /dev/null
+++ b/tests/qapi-schema/alias-name-bad-type.json
@@ -0,0 +1,3 @@
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int' },
+  'aliases': [ { 'name': ['bar'], 'source': ['foo'] } ] }
diff --git a/tests/qapi-schema/alias-name-bad-type.out b/tests/qapi-schema/alias-name-bad-type.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-name-conflict.err b/tests/qapi-schema/alias-name-conflict.err
new file mode 100644
index 0000000000..d5825a0285
--- /dev/null
+++ b/tests/qapi-schema/alias-name-conflict.err
@@ -0,0 +1,2 @@
+alias-name-conflict.json: In struct 'AliasStruct0':
+alias-name-conflict.json:1: alias 'bar' collides with member 'bar'
diff --git a/tests/qapi-schema/alias-name-conflict.json b/tests/qapi-schema/alias-name-conflict.json
new file mode 100644
index 0000000000..bdb5bd4eab
--- /dev/null
+++ b/tests/qapi-schema/alias-name-conflict.json
@@ -0,0 +1,4 @@
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int',
+            'bar': 'int' },
+  'aliases': [ { 'name': 'bar', 'source': ['foo'] } ] }
diff --git a/tests/qapi-schema/alias-name-conflict.out b/tests/qapi-schema/alias-name-conflict.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-recursive.err b/tests/qapi-schema/alias-recursive.err
new file mode 100644
index 0000000000..127ce019a8
--- /dev/null
+++ b/tests/qapi-schema/alias-recursive.err
@@ -0,0 +1,2 @@
+alias-recursive.json: In struct 'AliasStruct0':
+alias-recursive.json:1: alias 'baz' resolving to 'bar' makes 'bar' an alias for itself
diff --git a/tests/qapi-schema/alias-recursive.json b/tests/qapi-schema/alias-recursive.json
new file mode 100644
index 0000000000..e25b935324
--- /dev/null
+++ b/tests/qapi-schema/alias-recursive.json
@@ -0,0 +1,4 @@
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int' },
+  'aliases': [ { 'name': 'bar', 'source': ['baz'] },
+               { 'name': 'baz', 'source': ['bar'] } ] }
diff --git a/tests/qapi-schema/alias-recursive.out b/tests/qapi-schema/alias-recursive.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-source-bad-type.err b/tests/qapi-schema/alias-source-bad-type.err
new file mode 100644
index 0000000000..b1779cbb8e
--- /dev/null
+++ b/tests/qapi-schema/alias-source-bad-type.err
@@ -0,0 +1,2 @@
+alias-source-bad-type.json: In struct 'AliasStruct0':
+alias-source-bad-type.json:1: alias member 'source' must be an array
diff --git a/tests/qapi-schema/alias-source-bad-type.json b/tests/qapi-schema/alias-source-bad-type.json
new file mode 100644
index 0000000000..d6a7430ee3
--- /dev/null
+++ b/tests/qapi-schema/alias-source-bad-type.json
@@ -0,0 +1,3 @@
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int' },
+  'aliases': [ { 'name': 'bar', 'source': 'foo' } ] }
diff --git a/tests/qapi-schema/alias-source-bad-type.out b/tests/qapi-schema/alias-source-bad-type.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-source-elem-bad-type.err b/tests/qapi-schema/alias-source-elem-bad-type.err
new file mode 100644
index 0000000000..f73fbece77
--- /dev/null
+++ b/tests/qapi-schema/alias-source-elem-bad-type.err
@@ -0,0 +1,2 @@
+alias-source-elem-bad-type.json: In struct 'AliasStruct0':
+alias-source-elem-bad-type.json:1: member of alias member 'source' requires a string name
diff --git a/tests/qapi-schema/alias-source-elem-bad-type.json b/tests/qapi-schema/alias-source-elem-bad-type.json
new file mode 100644
index 0000000000..1d08f56492
--- /dev/null
+++ b/tests/qapi-schema/alias-source-elem-bad-type.json
@@ -0,0 +1,3 @@
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int' },
+  'aliases': [ { 'name': 'bar', 'source': ['foo', true] } ] }
diff --git a/tests/qapi-schema/alias-source-elem-bad-type.out b/tests/qapi-schema/alias-source-elem-bad-type.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-source-empty.err b/tests/qapi-schema/alias-source-empty.err
new file mode 100644
index 0000000000..2848e762cb
--- /dev/null
+++ b/tests/qapi-schema/alias-source-empty.err
@@ -0,0 +1,2 @@
+alias-source-empty.json: In struct 'AliasStruct0':
+alias-source-empty.json:1: alias member 'source' must not be empty
diff --git a/tests/qapi-schema/alias-source-empty.json b/tests/qapi-schema/alias-source-empty.json
new file mode 100644
index 0000000000..74b529de4a
--- /dev/null
+++ b/tests/qapi-schema/alias-source-empty.json
@@ -0,0 +1,3 @@
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int' },
+  'aliases': [ { 'name': 'bar', 'source': [] } ] }
diff --git a/tests/qapi-schema/alias-source-empty.out b/tests/qapi-schema/alias-source-empty.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-source-inexistent-variants.err b/tests/qapi-schema/alias-source-inexistent-variants.err
new file mode 100644
index 0000000000..a5d4a4c334
--- /dev/null
+++ b/tests/qapi-schema/alias-source-inexistent-variants.err
@@ -0,0 +1,2 @@
+alias-source-inexistent-variants.json: In union 'AliasStruct0':
+alias-source-inexistent-variants.json:7: alias 'test' has a source path that does not exist in any variant of union type 'AliasStruct0'
diff --git a/tests/qapi-schema/alias-source-inexistent-variants.json b/tests/qapi-schema/alias-source-inexistent-variants.json
new file mode 100644
index 0000000000..6328095b86
--- /dev/null
+++ b/tests/qapi-schema/alias-source-inexistent-variants.json
@@ -0,0 +1,12 @@
+{ 'enum': 'Variants',
+  'data': [ 'a', 'b' ] }
+{ 'struct': 'Variant0',
+  'data': { 'foo': 'int' } }
+{ 'struct': 'Variant1',
+  'data': { 'bar': 'int' } }
+{ 'union': 'AliasStruct0',
+  'base': { 'type': 'Variants' },
+  'discriminator': 'type',
+  'data': { 'a': 'Variant0',
+            'b': 'Variant1' },
+  'aliases': [ { 'name': 'test', 'source': ['baz'] } ] }
diff --git a/tests/qapi-schema/alias-source-inexistent-variants.out b/tests/qapi-schema/alias-source-inexistent-variants.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-source-inexistent.err b/tests/qapi-schema/alias-source-inexistent.err
new file mode 100644
index 0000000000..2d65d3f588
--- /dev/null
+++ b/tests/qapi-schema/alias-source-inexistent.err
@@ -0,0 +1,2 @@
+alias-source-inexistent.json: In struct 'AliasStruct0':
+alias-source-inexistent.json:1: alias 'bar' has inexistent source
diff --git a/tests/qapi-schema/alias-source-inexistent.json b/tests/qapi-schema/alias-source-inexistent.json
new file mode 100644
index 0000000000..5106d3609f
--- /dev/null
+++ b/tests/qapi-schema/alias-source-inexistent.json
@@ -0,0 +1,3 @@
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int' },
+  'aliases': [ { 'name': 'bar', 'source': ['baz'] } ] }
diff --git a/tests/qapi-schema/alias-source-inexistent.out b/tests/qapi-schema/alias-source-inexistent.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-source-non-object-path.err b/tests/qapi-schema/alias-source-non-object-path.err
new file mode 100644
index 0000000000..b3c748350f
--- /dev/null
+++ b/tests/qapi-schema/alias-source-non-object-path.err
@@ -0,0 +1,2 @@
+alias-source-non-object-path.json: In struct 'AliasStruct0':
+alias-source-non-object-path.json:1: alias 'bar' has non-object 'foo' in its source path
diff --git a/tests/qapi-schema/alias-source-non-object-path.json b/tests/qapi-schema/alias-source-non-object-path.json
new file mode 100644
index 0000000000..808a3e6281
--- /dev/null
+++ b/tests/qapi-schema/alias-source-non-object-path.json
@@ -0,0 +1,3 @@
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int' },
+  'aliases': [ { 'name': 'bar', 'source': ['foo', 'baz'] } ] }
diff --git a/tests/qapi-schema/alias-source-non-object-path.out b/tests/qapi-schema/alias-source-non-object-path.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-source-non-object-wildcard.err b/tests/qapi-schema/alias-source-non-object-wildcard.err
new file mode 100644
index 0000000000..4adc0d2281
--- /dev/null
+++ b/tests/qapi-schema/alias-source-non-object-wildcard.err
@@ -0,0 +1,2 @@
+alias-source-non-object-wildcard.json: In struct 'AliasStruct0':
+alias-source-non-object-wildcard.json:1: wildcard alias has non-object 'foo' in its source path
diff --git a/tests/qapi-schema/alias-source-non-object-wildcard.json b/tests/qapi-schema/alias-source-non-object-wildcard.json
new file mode 100644
index 0000000000..59ce1081ef
--- /dev/null
+++ b/tests/qapi-schema/alias-source-non-object-wildcard.json
@@ -0,0 +1,3 @@
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int' },
+  'aliases': [ { 'source': ['foo'] } ] }
diff --git a/tests/qapi-schema/alias-source-non-object-wildcard.out b/tests/qapi-schema/alias-source-non-object-wildcard.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-source-optional-wildcard-indirect.err b/tests/qapi-schema/alias-source-optional-wildcard-indirect.err
new file mode 100644
index 0000000000..b58b8ff00f
--- /dev/null
+++ b/tests/qapi-schema/alias-source-optional-wildcard-indirect.err
@@ -0,0 +1,2 @@
+alias-source-optional-wildcard-indirect.json: In struct 'AliasStruct0':
+alias-source-optional-wildcard-indirect.json:3: wildcard alias has optional object member 'nested' in its source path
diff --git a/tests/qapi-schema/alias-source-optional-wildcard-indirect.json b/tests/qapi-schema/alias-source-optional-wildcard-indirect.json
new file mode 100644
index 0000000000..fcf04969dc
--- /dev/null
+++ b/tests/qapi-schema/alias-source-optional-wildcard-indirect.json
@@ -0,0 +1,6 @@
+{ 'struct': 'Nested',
+  'data': { 'foo': 'int' } }
+{ 'struct': 'AliasStruct0',
+  'data': { '*nested': 'Nested' },
+  'aliases': [ { 'name': 'nested-alias', 'source': ['nested'] },
+               { 'source': ['nested-alias'] } ] }
diff --git a/tests/qapi-schema/alias-source-optional-wildcard-indirect.out b/tests/qapi-schema/alias-source-optional-wildcard-indirect.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-source-optional-wildcard.err b/tests/qapi-schema/alias-source-optional-wildcard.err
new file mode 100644
index 0000000000..e39200bd3d
--- /dev/null
+++ b/tests/qapi-schema/alias-source-optional-wildcard.err
@@ -0,0 +1,2 @@
+alias-source-optional-wildcard.json: In struct 'AliasStruct0':
+alias-source-optional-wildcard.json:3: wildcard alias has optional object member 'nested' in its source path
diff --git a/tests/qapi-schema/alias-source-optional-wildcard.json b/tests/qapi-schema/alias-source-optional-wildcard.json
new file mode 100644
index 0000000000..1a315f2ae0
--- /dev/null
+++ b/tests/qapi-schema/alias-source-optional-wildcard.json
@@ -0,0 +1,5 @@
+{ 'struct': 'Nested',
+  'data': { 'foo': 'int' } }
+{ 'struct': 'AliasStruct0',
+  'data': { '*nested': 'Nested' },
+  'aliases': [ { 'source': ['nested'] } ] }
diff --git a/tests/qapi-schema/alias-source-optional-wildcard.out b/tests/qapi-schema/alias-source-optional-wildcard.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/alias-unknown-key.err b/tests/qapi-schema/alias-unknown-key.err
new file mode 100644
index 0000000000..c7b8cb9498
--- /dev/null
+++ b/tests/qapi-schema/alias-unknown-key.err
@@ -0,0 +1,3 @@
+alias-unknown-key.json: In struct 'AliasStruct0':
+alias-unknown-key.json:1: 'aliases' member has unknown key 'known'
+Valid keys are 'name', 'source'.
diff --git a/tests/qapi-schema/alias-unknown-key.json b/tests/qapi-schema/alias-unknown-key.json
new file mode 100644
index 0000000000..cdb8fc3d07
--- /dev/null
+++ b/tests/qapi-schema/alias-unknown-key.json
@@ -0,0 +1,3 @@
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int' },
+  'aliases': [ { 'name': 'bar', 'source': ['foo'], 'known': false } ] }
diff --git a/tests/qapi-schema/alias-unknown-key.out b/tests/qapi-schema/alias-unknown-key.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/aliases-bad-type.err b/tests/qapi-schema/aliases-bad-type.err
new file mode 100644
index 0000000000..7ffe789ec0
--- /dev/null
+++ b/tests/qapi-schema/aliases-bad-type.err
@@ -0,0 +1,2 @@
+aliases-bad-type.json: In struct 'AliasStruct0':
+aliases-bad-type.json:1: 'aliases' must be an array
diff --git a/tests/qapi-schema/aliases-bad-type.json b/tests/qapi-schema/aliases-bad-type.json
new file mode 100644
index 0000000000..4bbf6d6b20
--- /dev/null
+++ b/tests/qapi-schema/aliases-bad-type.json
@@ -0,0 +1,3 @@
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int' },
+  'aliases': 'this must be an array' }
diff --git a/tests/qapi-schema/aliases-bad-type.out b/tests/qapi-schema/aliases-bad-type.out
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/qapi-schema/meson.build b/tests/qapi-schema/meson.build
index b8de58116a..f937de1c35 100644
--- a/tests/qapi-schema/meson.build
+++ b/tests/qapi-schema/meson.build
@@ -3,6 +3,22 @@ test_env.set('PYTHONPATH', meson.source_root() / 'scripts')
 test_env.set('PYTHONIOENCODING', 'utf-8')
 
 schemas = [
+  'alias-bad-type.json',
+  'aliases-bad-type.json',
+  'alias-missing-source.json',
+  'alias-name-bad-type.json',
+  'alias-name-conflict.json',
+  'alias-recursive.json',
+  'alias-source-bad-type.json',
+  'alias-source-elem-bad-type.json',
+  'alias-source-empty.json',
+  'alias-source-inexistent.json',
+  'alias-source-inexistent-variants.json',
+  'alias-source-non-object-path.json',
+  'alias-source-non-object-wildcard.json',
+  'alias-source-optional-wildcard.json',
+  'alias-source-optional-wildcard-indirect.json',
+  'alias-unknown-key.json',
   'alternate-any.json',
   'alternate-array.json',
   'alternate-base.json',
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 84b9d41f15..c5e81a883c 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -336,3 +336,29 @@
 
 { 'event': 'TEST_EVENT_FEATURES1',
   'features': [ 'deprecated' ] }
+
+# test  'aliases'
+
+{ 'struct': 'AliasStruct0',
+  'data': { 'foo': 'int' },
+  'aliases': [] }
+{ 'struct': 'AliasStruct1',
+  'data': { 'foo': 'int' },
+  'aliases': [ { 'name': 'bar', 'source': ['foo'] } ] }
+{ 'struct': 'AliasStruct2',
+  'data': { 'nested': 'AliasStruct1' },
+  'aliases': [ { 'name': 'bar', 'source': ['nested', 'foo'] } ] }
+{ 'struct': 'AliasStruct3',
+  'data': { 'nested': 'AliasStruct1' },
+  'aliases': [ { 'source': ['nested'] } ] }
+
+{ 'union': 'AliasFlatUnion',
+  'base': { 'tag': 'FeatureEnum1' },
+  'discriminator': 'tag',
+  'data': { 'eins': 'FeatureStruct1' },
+  'aliases': [ { 'name': 'variant', 'source': ['tag'] },
+               { 'name': 'bar', 'source': ['foo'] } ] }
+{ 'union': 'AliasSimpleUnion',
+  'data': { 'eins': 'AliasStruct1' },
+  'aliases': [ { 'source': ['data'] },
+               { 'name': 'tag', 'source': ['type'] } ] }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index e0b8a5f0b6..f6b8a98b7c 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -445,6 +445,37 @@ event TEST_EVENT_FEATURES0 FeatureStruct1
 event TEST_EVENT_FEATURES1 None
     boxed=False
     feature deprecated
+object AliasStruct0
+    member foo: int optional=False
+object AliasStruct1
+    member foo: int optional=False
+    alias bar -> foo
+object AliasStruct2
+    member nested: AliasStruct1 optional=False
+    alias bar -> nested.foo
+object AliasStruct3
+    member nested: AliasStruct1 optional=False
+    alias * -> nested.*
+object q_obj_AliasFlatUnion-base
+    member tag: FeatureEnum1 optional=False
+object AliasFlatUnion
+    base q_obj_AliasFlatUnion-base
+    alias variant -> tag
+    alias bar -> foo
+    tag tag
+    case eins: FeatureStruct1
+    case zwei: q_empty
+    case drei: q_empty
+object q_obj_AliasStruct1-wrapper
+    member data: AliasStruct1 optional=False
+enum AliasSimpleUnionKind
+    member eins
+object AliasSimpleUnion
+    member type: AliasSimpleUnionKind optional=False
+    alias * -> data.*
+    alias tag -> type
+    tag type
+    case eins: q_obj_AliasStruct1-wrapper
 module include/sub-module.json
 include sub-sub-module.json
 object SecondArrayRef
-- 
2.31.1



  parent reply	other threads:[~2021-08-12 16:17 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-12 16:11 [PATCH v3 0/6] qapi: Add support for aliases Kevin Wolf
2021-08-12 16:11 ` [PATCH v3 1/6] qapi: Add interfaces for alias support to Visitor Kevin Wolf
2021-08-12 16:11 ` [PATCH v3 2/6] qapi: Remember alias definitions in qobject-input-visitor Kevin Wolf
2021-08-12 16:11 ` [PATCH v3 3/6] qapi: Simplify full_name_nth() " Kevin Wolf
2021-08-12 16:11 ` [PATCH v3 4/6] qapi: Apply aliases " Kevin Wolf
2021-09-06 15:16   ` Markus Armbruster
2021-09-08 13:01     ` Kevin Wolf
2021-09-14  6:58       ` Markus Armbruster
2021-09-14  9:35         ` Kevin Wolf
2021-09-14 14:24           ` Markus Armbruster
2021-08-12 16:11 ` [PATCH v3 5/6] qapi: Add support for aliases Kevin Wolf
2021-09-06 15:24   ` Markus Armbruster
2021-09-09 16:39     ` Kevin Wolf
2021-09-14  8:42       ` Markus Armbruster
2021-09-14 11:00         ` Markus Armbruster
2021-09-14 14:24         ` Kevin Wolf
2021-09-16  7:49   ` Markus Armbruster
2021-08-12 16:11 ` Kevin Wolf [this message]
2021-09-06 15:28   ` [PATCH v3 6/6] tests/qapi-schema: Test cases " Markus Armbruster
2021-09-10 15:04     ` Kevin Wolf
2021-09-14  8:59       ` Markus Armbruster
2021-09-14 10:05         ` Kevin Wolf
2021-09-14 13:29           ` Markus Armbruster
2021-09-15  9:24             ` Kevin Wolf
2021-09-17  8:26               ` Markus Armbruster
2021-09-17 15:03                 ` Kevin Wolf
2021-10-02 13:33                   ` Markus Armbruster
2021-10-04 14:07                     ` Kevin Wolf
2021-10-05 13:49                       ` Markus Armbruster
2021-10-05 17:05                         ` Kevin Wolf
2021-10-06 13:11                           ` Markus Armbruster
2021-10-06 16:36                             ` Kevin Wolf
2021-10-07 11:06                               ` Markus Armbruster
2021-10-07 16:12                                 ` Kevin Wolf
2021-10-08 10:17                                   ` Markus Armbruster
2021-10-12 14:00                                     ` Kevin Wolf
2021-10-11  7:44                       ` Markus Armbruster
2021-10-12 14:36                         ` Kevin Wolf
2021-10-13  9:41                           ` Markus Armbruster
2021-10-13 11:10                             ` Markus Armbruster
2021-10-14  9:35                               ` Kevin Wolf
2021-08-24  9:36 ` [PATCH v3 0/6] qapi: Add support " Markus Armbruster
2021-09-06 15:32 ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210812161131.92017-7-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=armbru@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).