From patchwork Tue Jul 24 17:20:51 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Roth X-Patchwork-Id: 172978 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 47B032C008C for ; Wed, 25 Jul 2012 03:23:26 +1000 (EST) Received: from localhost ([::1]:41564 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1StipQ-0006XK-D3 for incoming@patchwork.ozlabs.org; Tue, 24 Jul 2012 13:23:24 -0400 Received: from eggs.gnu.org ([208.118.235.92]:49820) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1StioP-00058L-NE for qemu-devel@nongnu.org; Tue, 24 Jul 2012 13:22:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1StioK-0000aa-Ec for qemu-devel@nongnu.org; Tue, 24 Jul 2012 13:22:21 -0400 Received: from mail-gg0-f173.google.com ([209.85.161.173]:38583) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1StioK-0000Z3-9Q for qemu-devel@nongnu.org; Tue, 24 Jul 2012 13:22:16 -0400 Received: by mail-gg0-f173.google.com with SMTP id p1so7006693ggn.4 for ; Tue, 24 Jul 2012 10:22:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=+/h8ekJdpyOI1eAfCq6EP8WN4x2zccMeMYwc9cHSygs=; b=QU8Ra5dfaHCWENejZWBRYDWKwxCJvA8sIU8B7Y7lt+7MVHf4bk/u87j0isVjRAReZa 2Eiy/kuNqphThHO97W+clh3LWnargRj16xDcjMDZG2qLY/BXZGJcsUHoAMQpU3pIK+kB PBR364EuosgRDNq9O3N1BbalLs+ZvAPBUSbKSZZPCmSmeDbbW8TpAEvU9B91waH+tfND RWGwVzM4gau1T6vaVpbmM1fJ+ILTm6IHjHYPn1ihqi4czo/0Oivr6/XVymsXS2AwSNzZ WaYAcSs9zAgr2MdXQO95pfalBCeGExwFyvZtvuPvLJGdDJV8zYqUsgC3X0EzdUPL9jrD 5r6w== Received: by 10.68.192.40 with SMTP id hd8mr29869862pbc.125.1343150535702; Tue, 24 Jul 2012 10:22:15 -0700 (PDT) Received: from loki.morrigu.org (cpe-72-179-62-111.austin.res.rr.com. [72.179.62.111]) by mx.google.com with ESMTPS id nh8sm12522083pbc.60.2012.07.24.10.22.12 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 24 Jul 2012 10:22:14 -0700 (PDT) From: Michael Roth To: qemu-devel@nongnu.org Date: Tue, 24 Jul 2012 12:20:51 -0500 Message-Id: <1343150454-4677-20-git-send-email-mdroth@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1343150454-4677-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1343150454-4677-1-git-send-email-mdroth@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.161.173 Cc: aliguori@us.ibm.com, quintela@redhat.com, owasserm@redhat.com, yamahata@valinux.co.jp, pbonzini@redhat.com, akong@redhat.com, afaerber@suse.de Subject: [Qemu-devel] [PATCH 19/22] qidl: unit tests X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Michael Roth --- Makefile | 2 + rules.mak | 15 +++- tests/Makefile | 8 +- tests/test-qidl-included.h | 31 ++++++++ tests/test-qidl-linked.c | 91 +++++++++++++++++++++++ tests/test-qidl-linked.h | 18 +++++ tests/test-qidl.c | 177 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 339 insertions(+), 3 deletions(-) create mode 100644 tests/test-qidl-included.h create mode 100644 tests/test-qidl-linked.c create mode 100644 tests/test-qidl-linked.h create mode 100644 tests/test-qidl.c diff --git a/Makefile b/Makefile index 82fc9f0..0711f14 100644 --- a/Makefile +++ b/Makefile @@ -232,6 +232,7 @@ clean: if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \ rm -f $$d/qemu-options.def; \ done + find -depth -name qidl-generated -type d -exec rm -rf {} \; VERSION ?= $(shell cat VERSION) @@ -402,6 +403,7 @@ qemu-doc.dvi qemu-doc.html qemu-doc.info qemu-doc.pdf: \ # rebuilt before other object files Makefile: $(GENERATED_HEADERS) + # Include automatically generated dependency files # All subdir dependencies come automatically from our recursive subdir rules -include $(wildcard *.d) diff --git a/rules.mak b/rules.mak index 60f3e96..3c46599 100644 --- a/rules.mak +++ b/rules.mak @@ -15,7 +15,20 @@ MAKEFLAGS += -rR QEMU_DGFLAGS += -MMD -MP -MT $@ -MF $(*D)/$(*F).d %.o: %.c - $(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<," CC $(TARGET_DIR)$@") + +%.qidl.c: %.c $(SRC_PATH)/qidl.h $(addprefix $(SRC_PATH)/scripts/,qidl.py qidl_parser.py qapi.py qapi_visit.py) + $(call rm -f $(*D)/qidl-generated/$(*F).qidl.c) + $(call quiet-command, $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(CFLAGS) -E -c -DQIDL_GEN $< | \ + $(PYTHON) $(SRC_PATH)/scripts/qidl.py --output-filepath=$(*D)/qidl-generated/$(*F).qidl.c || [ "$$?" -eq 2 ]) + +%.o: %.c %.qidl.c + $(if $(strip $(shell test -f $(*D)/qidl-generated/$(*F).qidl.c && echo "true")), \ + $(call quiet-command, \ + $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c \ + -include $< -o $@ -c -x c - <$(*D)/qidl-generated/$(*F).qidl.c,"qidl CC $@"), \ + $(call quiet-command, \ + $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c \ + -o $@ $<," CC $@")) ifeq ($(LIBTOOL),) %.lo: %.c diff --git a/tests/Makefile b/tests/Makefile index 7cfd3d8..7a82b53 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -15,6 +15,7 @@ check-unit-y += tests/test-string-output-visitor$(EXESUF) check-unit-y += tests/test-coroutine$(EXESUF) check-unit-y += tests/test-visitor-serialization$(EXESUF) check-unit-y += tests/test-iov$(EXESUF) +check-unit-y += tests/test-qidl$(EXESUF) check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh @@ -34,11 +35,12 @@ test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \ tests/test-coroutine.o tests/test-string-output-visitor.o \ tests/test-string-input-visitor.o tests/test-qmp-output-visitor.o \ tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \ - tests/test-qmp-commands.o tests/test-visitor-serialization.o + tests/test-qmp-commands.o tests/test-visitor-serialization.o \ + tests/test-qidl.o test-qapi-obj-y = $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y) test-qapi-obj-y += tests/test-qapi-visit.o tests/test-qapi-types.o -test-qapi-obj-y += module.o +test-qapi-obj-y += module.o $(qom-obj-y) $(test-obj-y): QEMU_INCLUDES += -Itests @@ -84,6 +86,8 @@ check-qtest-$(CONFIG_POSIX)=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET) qtest-obj-y = tests/libqtest.o $(oslib-obj-y) $(check-qtest-y): $(qtest-obj-y) +tests/test-qidl$(EXESUF): tests/test-qidl.o tests/test-qidl-linked.o $(test-qapi-obj-y) qapi/misc-qapi-visit.o + .PHONY: check-help check-help: @echo "Regression testing targets:" diff --git a/tests/test-qidl-included.h b/tests/test-qidl-included.h new file mode 100644 index 0000000..2aae51e --- /dev/null +++ b/tests/test-qidl-included.h @@ -0,0 +1,31 @@ +/* + * Unit-tests for QIDL-generated visitors/code + * + * Copyright IBM, Corp. 2012 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef TEST_QIDL_INCLUDED_H +#define TEST_QIDL_INCLUDED_H + +#include "qidl.h" + +QIDL_START(TestStructIncluded, state, properties) +typedef struct TestStructIncluded { + int32_t a QIDL(immutable); + int32_t b; + uint32_t c QIDL(immutable); + uint32_t d; + uint64_t e QIDL(immutable); + uint64_t f QIDL(property, "f", 42); + char *g QIDL(property, "g"); + char *h QIDL(immutable) QIDL(property, "h"); +} TestStructIncluded; +QIDL_END(TestStructIncluded) + +#endif diff --git a/tests/test-qidl-linked.c b/tests/test-qidl-linked.c new file mode 100644 index 0000000..b0d9896 --- /dev/null +++ b/tests/test-qidl-linked.c @@ -0,0 +1,91 @@ +/* + * Unit-tests for QIDL-generated visitors/code + * + * Copyright IBM, Corp. 2012 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qidl.h" +#include "test-qidl-linked.h" +#include "hw/qdev-properties.h" +#include "qapi/qmp-input-visitor.h" +#include "qapi/qmp-output-visitor.h" +#include "qapi/qapi-dealloc-visitor.h" + +QIDL_START(TestStructLinked, state, properties) +typedef struct TestStructLinked { + int32_t a QIDL(immutable); + int32_t b; + uint32_t c QIDL(immutable); + uint32_t d; + uint64_t e QIDL(immutable); + uint64_t f QIDL(property, "f", 42); + char *g QIDL(property, "g"); + char *h QIDL(immutable) QIDL(property, "h"); +} TestStructLinked; +QIDL_END(TestStructLinked) + +/* exercise generated code from annotations in objects we link against */ +void test_linked_object_annotations(gconstpointer opaque) +{ + TestStructLinked *s1, *s2 = NULL; + Property *props; + QmpInputVisitor *qiv; + QmpOutputVisitor *qov; + QObject *s1_obj; + Error *err = NULL; + + s1 = g_malloc0(sizeof(TestStructLinked)); + s1->a = 42; + s1->b = INT32_MAX; + s1->c = 43; + s1->d = UINT32_MAX; + s1->e = 44; + s1->f = UINT64_MAX; + s1->g = g_strdup("test string g"); + s1->h = g_strdup("test string h"); + + qov = qmp_output_visitor_new(); + QIDL_VISIT_TYPE(TestStructLinked, qmp_output_get_visitor(qov), &s1, NULL, &err); + g_assert(err == NULL); + + s1_obj = qmp_output_get_qobject(qov); + qiv = qmp_input_visitor_new(s1_obj); + + qobject_decref(s1_obj); + qmp_output_visitor_cleanup(qov); + g_free(s1->g); + g_free(s1->h); + g_free(s1); + + s2 = g_malloc0(sizeof(TestStructLinked)); + QIDL_VISIT_TYPE(TestStructLinked, qmp_input_get_visitor(qiv), &s2, NULL, &err); + g_assert(err == NULL); + + g_assert_cmpint(s2->a, ==, 0); + g_assert_cmpint(s2->b, ==, INT32_MAX); + g_assert_cmpint(s2->c, ==, 0); + g_assert_cmpint(s2->d, ==, UINT32_MAX); + g_assert_cmpint(s2->e, ==, 0); + g_assert_cmpint(s2->f, ==, UINT64_MAX); + g_assert_cmpstr(s2->g, ==, "test string g"); + g_assert(s2->h == NULL); + + qmp_input_visitor_cleanup(qiv); + g_free(s2->g); + g_free(s2); + + props = QIDL_PROPERTIES(TestStructLinked); + g_assert_cmpstr(props[0].name, ==, "f"); + g_assert_cmpint(props[0].defval, ==, 42); + g_assert_cmpstr(props[1].name, ==, "g"); + g_assert_cmpint(props[1].defval, ==, 0); + g_assert_cmpstr(props[2].name, ==, "h"); + g_assert_cmpint(props[2].defval, ==, 0); + g_assert(props[3].name == NULL); +} diff --git a/tests/test-qidl-linked.h b/tests/test-qidl-linked.h new file mode 100644 index 0000000..1b100a2 --- /dev/null +++ b/tests/test-qidl-linked.h @@ -0,0 +1,18 @@ +/* + * Unit-tests for QIDL-generated visitors/code + * + * Copyright IBM, Corp. 2012 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef TEST_QIDL_LINKED_H +#define TEST_QIDL_LINKED_H + +void test_linked_object_annotations(gconstpointer opaque); + +#endif diff --git a/tests/test-qidl.c b/tests/test-qidl.c new file mode 100644 index 0000000..a1d27a2 --- /dev/null +++ b/tests/test-qidl.c @@ -0,0 +1,177 @@ +/* + * Unit-tests for QIDL-generated visitors/code + * + * Copyright IBM, Corp. 2012 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include +#include +#include +#include "qidl.h" +#include "test-qidl-included.h" +#include "test-qidl-linked.h" +#include "hw/qdev-properties.h" +#include "qapi/qmp-input-visitor.h" +#include "qapi/qmp-output-visitor.h" +#include "qapi/qapi-dealloc-visitor.h" + +PropertyInfo qdev_prop_uint64; +PropertyInfo qdev_prop_string; + +QIDL_START(TestStructMain, state, properties) +typedef struct TestStructMain { + int32_t a QIDL(immutable); + int32_t b; + uint32_t c QIDL(immutable); + uint32_t d; + uint64_t e QIDL(immutable); + uint64_t f QIDL(property, "f", 42); + char *g QIDL(property, "g"); + char *h QIDL(immutable) QIDL(property, "h"); +} TestStructMain; +QIDL_END(TestStructMain) + +/* exercise generated code from annotations in main() object file */ +static void test_main_object_annotations(gconstpointer opaque) +{ + TestStructMain *s1, *s2 = NULL; + Property *props; + QmpInputVisitor *qiv; + QmpOutputVisitor *qov; + QObject *s1_obj; + Error *err = NULL; + + s1 = g_malloc0(sizeof(TestStructMain)); + s1->a = 42; + s1->b = INT32_MAX; + s1->c = 43; + s1->d = UINT32_MAX; + s1->e = 44; + s1->f = UINT64_MAX; + s1->g = g_strdup("test string g"); + s1->h = g_strdup("test string h"); + + qov = qmp_output_visitor_new(); + QIDL_VISIT_TYPE(TestStructMain, qmp_output_get_visitor(qov), &s1, NULL, &err); + g_assert(err == NULL); + + s1_obj = qmp_output_get_qobject(qov); + qiv = qmp_input_visitor_new(s1_obj); + + qobject_decref(s1_obj); + qmp_output_visitor_cleanup(qov); + g_free(s1->g); + g_free(s1->h); + g_free(s1); + + s2 = g_malloc0(sizeof(TestStructMain)); + QIDL_VISIT_TYPE(TestStructMain, qmp_input_get_visitor(qiv), &s2, NULL, &err); + g_assert(err == NULL); + + g_assert_cmpint(s2->a, ==, 0); + g_assert_cmpint(s2->b, ==, INT32_MAX); + g_assert_cmpint(s2->c, ==, 0); + g_assert_cmpint(s2->d, ==, UINT32_MAX); + g_assert_cmpint(s2->e, ==, 0); + g_assert_cmpint(s2->f, ==, UINT64_MAX); + g_assert_cmpstr(s2->g, ==, "test string g"); + g_assert(s2->h == NULL); + + qmp_input_visitor_cleanup(qiv); + g_free(s2->g); + g_free(s2); + + props = QIDL_PROPERTIES(TestStructMain); + g_assert_cmpstr(props[0].name, ==, "f"); + g_assert_cmpint(props[0].defval, ==, 42); + g_assert_cmpstr(props[1].name, ==, "g"); + g_assert_cmpint(props[1].defval, ==, 0); + g_assert_cmpstr(props[2].name, ==, "h"); + g_assert_cmpint(props[2].defval, ==, 0); + g_assert(props[3].name == NULL); +} + +/* exercise generated code from annotations in included header files */ +static void test_header_file_annotations(gconstpointer opaque) +{ + TestStructIncluded *s1, *s2 = NULL; + Property *props; + QmpInputVisitor *qiv; + QmpOutputVisitor *qov; + QObject *s1_obj; + Error *err = NULL; + + s1 = g_malloc0(sizeof(TestStructIncluded)); + s1->a = 42; + s1->b = INT32_MAX; + s1->c = 43; + s1->d = UINT32_MAX; + s1->e = 44; + s1->f = UINT64_MAX; + s1->g = g_strdup("test string g"); + s1->h = g_strdup("test string h"); + + qov = qmp_output_visitor_new(); + QIDL_VISIT_TYPE(TestStructIncluded, qmp_output_get_visitor(qov), &s1, NULL, &err); + g_assert(err == NULL); + + s1_obj = qmp_output_get_qobject(qov); + qiv = qmp_input_visitor_new(s1_obj); + + qobject_decref(s1_obj); + qmp_output_visitor_cleanup(qov); + g_free(s1->g); + g_free(s1->h); + g_free(s1); + + s2 = g_malloc0(sizeof(TestStructIncluded)); + QIDL_VISIT_TYPE(TestStructIncluded, qmp_input_get_visitor(qiv), &s2, NULL, &err); + g_assert(err == NULL); + + g_assert_cmpint(s2->a, ==, 0); + g_assert_cmpint(s2->b, ==, INT32_MAX); + g_assert_cmpint(s2->c, ==, 0); + g_assert_cmpint(s2->d, ==, UINT32_MAX); + g_assert_cmpint(s2->e, ==, 0); + g_assert_cmpint(s2->f, ==, UINT64_MAX); + g_assert_cmpstr(s2->g, ==, "test string g"); + g_assert(s2->h == NULL); + + qmp_input_visitor_cleanup(qiv); + g_free(s2->g); + g_free(s2); + + props = QIDL_PROPERTIES(TestStructIncluded); + g_assert_cmpstr(props[0].name, ==, "f"); + g_assert_cmpint(props[0].defval, ==, 42); + g_assert_cmpstr(props[1].name, ==, "g"); + g_assert_cmpint(props[1].defval, ==, 0); + g_assert_cmpstr(props[2].name, ==, "h"); + g_assert_cmpint(props[2].defval, ==, 0); + g_assert(props[3].name == NULL); +} + +int main(int argc, char **argv) +{ + module_call_init(MODULE_INIT_QOM); + module_call_init(MODULE_INIT_QIDL); + + g_test_init(&argc, &argv, NULL); + + g_test_add_data_func("/qidl/build_test/main_object_annotations", NULL, + test_main_object_annotations); + g_test_add_data_func("/qidl/build_test/linked_object_annotations", NULL, + test_linked_object_annotations); + g_test_add_data_func("/qidl/build_test/header_file_annotations", NULL, + test_header_file_annotations); + + g_test_run(); + + return 0; +}