From patchwork Thu May 23 18:20:28 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Capitulino X-Patchwork-Id: 246005 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 0623E2C02A7 for ; Fri, 24 May 2013 04:21:55 +1000 (EST) Received: from localhost ([::1]:56220 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ufa9B-00066H-41 for incoming@patchwork.ozlabs.org; Thu, 23 May 2013 14:21:53 -0400 Received: from eggs.gnu.org ([208.118.235.92]:49723) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ufa8B-0005Hu-TU for qemu-devel@nongnu.org; Thu, 23 May 2013 14:20:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ufa82-0003VF-Nv for qemu-devel@nongnu.org; Thu, 23 May 2013 14:20:51 -0400 Received: from mx1.redhat.com ([209.132.183.28]:7833) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ufa82-0003Uc-2Q for qemu-devel@nongnu.org; Thu, 23 May 2013 14:20:42 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r4NIKfxQ030498 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 23 May 2013 14:20:41 -0400 Received: from localhost (ovpn-113-86.phx2.redhat.com [10.3.113.86]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r4NIKesl027821; Thu, 23 May 2013 14:20:41 -0400 From: Luiz Capitulino To: qemu-devel@nongnu.org Date: Thu, 23 May 2013 14:20:28 -0400 Message-Id: <1369333232-24145-9-git-send-email-lcapitulino@redhat.com> In-Reply-To: <1369333232-24145-1-git-send-email-lcapitulino@redhat.com> References: <1369333232-24145-1-git-send-email-lcapitulino@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: aliguori@us.ibm.com Subject: [Qemu-devel] [PULL 08/12] qapi: add native list coverage for visitor serialization 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 From: Michael Roth Signed-off-by: Michael Roth Reviewed-by: Laszlo Ersek Reviewed-by: Amos Kong Signed-off-by: Luiz Capitulino --- tests/test-visitor-serialization.c | 451 +++++++++++++++++++++++++++++++++++-- 1 file changed, 433 insertions(+), 18 deletions(-) diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c index fed6810..ee7916b 100644 --- a/tests/test-visitor-serialization.c +++ b/tests/test-visitor-serialization.c @@ -23,6 +23,25 @@ #include "qapi/qmp-output-visitor.h" #include "qapi/string-input-visitor.h" #include "qapi/string-output-visitor.h" +#include "qapi-types.h" +#include "qapi-visit.h" +#include "qapi/dealloc-visitor.h" + +enum PrimitiveTypeKind { + PTYPE_STRING = 0, + PTYPE_BOOLEAN, + PTYPE_NUMBER, + PTYPE_INTEGER, + PTYPE_U8, + PTYPE_U16, + PTYPE_U32, + PTYPE_U64, + PTYPE_S8, + PTYPE_S16, + PTYPE_S32, + PTYPE_S64, + PTYPE_EOL, +}; typedef struct PrimitiveType { union { @@ -40,26 +59,42 @@ typedef struct PrimitiveType { int64_t s64; intmax_t max; } value; - enum { - PTYPE_STRING = 0, - PTYPE_BOOLEAN, - PTYPE_NUMBER, - PTYPE_INTEGER, - PTYPE_U8, - PTYPE_U16, - PTYPE_U32, - PTYPE_U64, - PTYPE_S8, - PTYPE_S16, - PTYPE_S32, - PTYPE_S64, - PTYPE_EOL, - } type; + enum PrimitiveTypeKind type; const char *description; } PrimitiveType; +typedef struct PrimitiveList { + union { + strList *strings; + boolList *booleans; + numberList *numbers; + intList *integers; + int8List *s8_integers; + int16List *s16_integers; + int32List *s32_integers; + int64List *s64_integers; + uint8List *u8_integers; + uint16List *u16_integers; + uint32List *u32_integers; + uint64List *u64_integers; + } value; + enum PrimitiveTypeKind type; + const char *description; +} PrimitiveList; + /* test helpers */ +typedef void (*VisitorFunc)(Visitor *v, void **native, Error **errp); + +static void dealloc_helper(void *native_in, VisitorFunc visit, Error **errp) +{ + QapiDeallocVisitor *qdv = qapi_dealloc_visitor_new(); + + visit(qapi_dealloc_get_visitor(qdv), &native_in, errp); + + qapi_dealloc_visitor_cleanup(qdv); +} + static void visit_primitive_type(Visitor *v, void **native, Error **errp) { PrimitiveType *pt = *native; @@ -105,6 +140,51 @@ static void visit_primitive_type(Visitor *v, void **native, Error **errp) } } +static void visit_primitive_list(Visitor *v, void **native, Error **errp) +{ + PrimitiveList *pl = *native; + switch (pl->type) { + case PTYPE_STRING: + visit_type_strList(v, &pl->value.strings, NULL, errp); + break; + case PTYPE_BOOLEAN: + visit_type_boolList(v, &pl->value.booleans, NULL, errp); + break; + case PTYPE_NUMBER: + visit_type_numberList(v, &pl->value.numbers, NULL, errp); + break; + case PTYPE_INTEGER: + visit_type_intList(v, &pl->value.integers, NULL, errp); + break; + case PTYPE_S8: + visit_type_int8List(v, &pl->value.s8_integers, NULL, errp); + break; + case PTYPE_S16: + visit_type_int16List(v, &pl->value.s16_integers, NULL, errp); + break; + case PTYPE_S32: + visit_type_int32List(v, &pl->value.s32_integers, NULL, errp); + break; + case PTYPE_S64: + visit_type_int64List(v, &pl->value.s64_integers, NULL, errp); + break; + case PTYPE_U8: + visit_type_uint8List(v, &pl->value.u8_integers, NULL, errp); + break; + case PTYPE_U16: + visit_type_uint16List(v, &pl->value.u16_integers, NULL, errp); + break; + case PTYPE_U32: + visit_type_uint32List(v, &pl->value.u32_integers, NULL, errp); + break; + case PTYPE_U64: + visit_type_uint64List(v, &pl->value.u64_integers, NULL, errp); + break; + default: + g_assert(false); + } +} + typedef struct TestStruct { int64_t integer; @@ -206,12 +286,11 @@ static void visit_nested_struct_list(Visitor *v, void **native, Error **errp) /* test cases */ -typedef void (*VisitorFunc)(Visitor *v, void **native, Error **errp); - typedef enum VisitorCapabilities { VCAP_PRIMITIVES = 1, VCAP_STRUCTURES = 2, VCAP_LISTS = 4, + VCAP_PRIMITIVE_LISTS = 8, } VisitorCapabilities; typedef struct SerializeOps { @@ -270,6 +349,328 @@ static void test_primitives(gconstpointer opaque) g_free(pt_copy); } +static void test_primitive_lists(gconstpointer opaque) +{ + TestArgs *args = (TestArgs *) opaque; + const SerializeOps *ops = args->ops; + PrimitiveType *pt = args->test_data; + PrimitiveList pl = { .value = { 0 } }; + PrimitiveList pl_copy = { .value = { 0 } }; + PrimitiveList *pl_copy_ptr = &pl_copy; + Error *err = NULL; + void *serialize_data; + void *cur_head = NULL; + int i; + + pl.type = pl_copy.type = pt->type; + + /* build up our list of primitive types */ + for (i = 0; i < 32; i++) { + switch (pl.type) { + case PTYPE_STRING: { + strList *tmp = g_new0(strList, 1); + tmp->value = g_strdup(pt->value.string); + if (pl.value.strings == NULL) { + pl.value.strings = tmp; + } else { + tmp->next = pl.value.strings; + pl.value.strings = tmp; + } + break; + } + case PTYPE_INTEGER: { + intList *tmp = g_new0(intList, 1); + tmp->value = pt->value.integer; + if (pl.value.integers == NULL) { + pl.value.integers = tmp; + } else { + tmp->next = pl.value.integers; + pl.value.integers = tmp; + } + break; + } + case PTYPE_S8: { + int8List *tmp = g_new0(int8List, 1); + tmp->value = pt->value.s8; + if (pl.value.s8_integers == NULL) { + pl.value.s8_integers = tmp; + } else { + tmp->next = pl.value.s8_integers; + pl.value.s8_integers = tmp; + } + break; + } + case PTYPE_S16: { + int16List *tmp = g_new0(int16List, 1); + tmp->value = pt->value.s16; + if (pl.value.s16_integers == NULL) { + pl.value.s16_integers = tmp; + } else { + tmp->next = pl.value.s16_integers; + pl.value.s16_integers = tmp; + } + break; + } + case PTYPE_S32: { + int32List *tmp = g_new0(int32List, 1); + tmp->value = pt->value.s32; + if (pl.value.s32_integers == NULL) { + pl.value.s32_integers = tmp; + } else { + tmp->next = pl.value.s32_integers; + pl.value.s32_integers = tmp; + } + break; + } + case PTYPE_S64: { + int64List *tmp = g_new0(int64List, 1); + tmp->value = pt->value.s64; + if (pl.value.s64_integers == NULL) { + pl.value.s64_integers = tmp; + } else { + tmp->next = pl.value.s64_integers; + pl.value.s64_integers = tmp; + } + break; + } + case PTYPE_U8: { + uint8List *tmp = g_new0(uint8List, 1); + tmp->value = pt->value.u8; + if (pl.value.u8_integers == NULL) { + pl.value.u8_integers = tmp; + } else { + tmp->next = pl.value.u8_integers; + pl.value.u8_integers = tmp; + } + break; + } + case PTYPE_U16: { + uint16List *tmp = g_new0(uint16List, 1); + tmp->value = pt->value.u16; + if (pl.value.u16_integers == NULL) { + pl.value.u16_integers = tmp; + } else { + tmp->next = pl.value.u16_integers; + pl.value.u16_integers = tmp; + } + break; + } + case PTYPE_U32: { + uint32List *tmp = g_new0(uint32List, 1); + tmp->value = pt->value.u32; + if (pl.value.u32_integers == NULL) { + pl.value.u32_integers = tmp; + } else { + tmp->next = pl.value.u32_integers; + pl.value.u32_integers = tmp; + } + break; + } + case PTYPE_U64: { + uint64List *tmp = g_new0(uint64List, 1); + tmp->value = pt->value.u64; + if (pl.value.u64_integers == NULL) { + pl.value.u64_integers = tmp; + } else { + tmp->next = pl.value.u64_integers; + pl.value.u64_integers = tmp; + } + break; + } + case PTYPE_NUMBER: { + numberList *tmp = g_new0(numberList, 1); + tmp->value = pt->value.number; + if (pl.value.numbers == NULL) { + pl.value.numbers = tmp; + } else { + tmp->next = pl.value.numbers; + pl.value.numbers = tmp; + } + break; + } + case PTYPE_BOOLEAN: { + boolList *tmp = g_new0(boolList, 1); + tmp->value = pt->value.boolean; + if (pl.value.booleans == NULL) { + pl.value.booleans = tmp; + } else { + tmp->next = pl.value.booleans; + pl.value.booleans = tmp; + } + break; + } + default: + g_assert(0); + } + } + + ops->serialize((void **)&pl, &serialize_data, visit_primitive_list, &err); + ops->deserialize((void **)&pl_copy_ptr, serialize_data, visit_primitive_list, &err); + + g_assert(err == NULL); + i = 0; + + /* compare our deserialized list of primitives to the original */ + do { + switch (pl_copy.type) { + case PTYPE_STRING: { + strList *ptr; + if (cur_head) { + ptr = cur_head; + cur_head = ptr->next; + } else { + cur_head = ptr = pl_copy.value.strings; + } + g_assert_cmpstr(pt->value.string, ==, ptr->value); + break; + } + case PTYPE_INTEGER: { + intList *ptr; + if (cur_head) { + ptr = cur_head; + cur_head = ptr->next; + } else { + cur_head = ptr = pl_copy.value.integers; + } + g_assert_cmpint(pt->value.integer, ==, ptr->value); + break; + } + case PTYPE_S8: { + int8List *ptr; + if (cur_head) { + ptr = cur_head; + cur_head = ptr->next; + } else { + cur_head = ptr = pl_copy.value.s8_integers; + } + g_assert_cmpint(pt->value.s8, ==, ptr->value); + break; + } + case PTYPE_S16: { + int16List *ptr; + if (cur_head) { + ptr = cur_head; + cur_head = ptr->next; + } else { + cur_head = ptr = pl_copy.value.s16_integers; + } + g_assert_cmpint(pt->value.s16, ==, ptr->value); + break; + } + case PTYPE_S32: { + int32List *ptr; + if (cur_head) { + ptr = cur_head; + cur_head = ptr->next; + } else { + cur_head = ptr = pl_copy.value.s32_integers; + } + g_assert_cmpint(pt->value.s32, ==, ptr->value); + break; + } + case PTYPE_S64: { + int64List *ptr; + if (cur_head) { + ptr = cur_head; + cur_head = ptr->next; + } else { + cur_head = ptr = pl_copy.value.s64_integers; + } + g_assert_cmpint(pt->value.s64, ==, ptr->value); + break; + } + case PTYPE_U8: { + uint8List *ptr; + if (cur_head) { + ptr = cur_head; + cur_head = ptr->next; + } else { + cur_head = ptr = pl_copy.value.u8_integers; + } + g_assert_cmpint(pt->value.u8, ==, ptr->value); + break; + } + case PTYPE_U16: { + uint16List *ptr; + if (cur_head) { + ptr = cur_head; + cur_head = ptr->next; + } else { + cur_head = ptr = pl_copy.value.u16_integers; + } + g_assert_cmpint(pt->value.u16, ==, ptr->value); + break; + } + case PTYPE_U32: { + uint32List *ptr; + if (cur_head) { + ptr = cur_head; + cur_head = ptr->next; + } else { + cur_head = ptr = pl_copy.value.u32_integers; + } + g_assert_cmpint(pt->value.u32, ==, ptr->value); + break; + } + case PTYPE_U64: { + uint64List *ptr; + if (cur_head) { + ptr = cur_head; + cur_head = ptr->next; + } else { + cur_head = ptr = pl_copy.value.u64_integers; + } + g_assert_cmpint(pt->value.u64, ==, ptr->value); + break; + } + case PTYPE_NUMBER: { + numberList *ptr; + GString *double_expected = g_string_new(""); + GString *double_actual = g_string_new(""); + if (cur_head) { + ptr = cur_head; + cur_head = ptr->next; + } else { + cur_head = ptr = pl_copy.value.numbers; + } + /* we serialize with %f for our reference visitors, so rather than + * fuzzy floating math to test "equality", just compare the + * formatted values + */ + g_string_printf(double_expected, "%.6f", pt->value.number); + g_string_printf(double_actual, "%.6f", ptr->value); + g_assert_cmpstr(double_actual->str, ==, double_expected->str); + g_string_free(double_expected, true); + g_string_free(double_actual, true); + break; + } + case PTYPE_BOOLEAN: { + boolList *ptr; + if (cur_head) { + ptr = cur_head; + cur_head = ptr->next; + } else { + cur_head = ptr = pl_copy.value.booleans; + } + g_assert_cmpint(!!pt->value.boolean, ==, !!ptr->value); + break; + } + default: + g_assert(0); + } + i++; + } while (cur_head); + + g_assert_cmpint(i, ==, 33); + + ops->cleanup(serialize_data); + dealloc_helper(&pl, visit_primitive_list, &err); + g_assert(!err); + dealloc_helper(&pl_copy, visit_primitive_list, &err); + g_assert(!err); + g_free(args); +} + static void test_struct(gconstpointer opaque) { TestArgs *args = (TestArgs *) opaque; @@ -719,7 +1120,8 @@ static const SerializeOps visitors[] = { .serialize = qmp_serialize, .deserialize = qmp_deserialize, .cleanup = qmp_cleanup, - .caps = VCAP_PRIMITIVES | VCAP_STRUCTURES | VCAP_LISTS + .caps = VCAP_PRIMITIVES | VCAP_STRUCTURES | VCAP_LISTS | + VCAP_PRIMITIVE_LISTS }, { .type = "String", @@ -773,6 +1175,19 @@ static void add_visitor_type(const SerializeOps *ops) args->test_data = NULL; g_test_add_data_func(testname, args, test_nested_struct_list); } + + if (ops->caps & VCAP_PRIMITIVE_LISTS) { + i = 0; + while (pt_values[i].type != PTYPE_EOL) { + sprintf(testname, "%s/primitive_list/%s", testname_prefix, + pt_values[i].description); + args = g_malloc0(sizeof(*args)); + args->ops = ops; + args->test_data = &pt_values[i]; + g_test_add_data_func(testname, args, test_primitive_lists); + i++; + } + } } int main(int argc, char **argv)