From patchwork Tue Feb 26 23:03:57 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Schopp X-Patchwork-Id: 223427 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 D48BF2C007A for ; Wed, 27 Feb 2013 10:07:02 +1100 (EST) Received: from localhost ([::1]:44737 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UATbw-0002DO-Tm for incoming@patchwork.ozlabs.org; Tue, 26 Feb 2013 18:07:00 -0500 Received: from eggs.gnu.org ([208.118.235.92]:41913) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UATbf-0001vX-3g for qemu-devel@nongnu.org; Tue, 26 Feb 2013 18:06:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UATbV-0004FO-KE for qemu-devel@nongnu.org; Tue, 26 Feb 2013 18:06:42 -0500 Received: from e9.ny.us.ibm.com ([32.97.182.139]:54609) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UATbV-0004En-EZ for qemu-devel@nongnu.org; Tue, 26 Feb 2013 18:06:33 -0500 Received: from /spool/local by e9.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 26 Feb 2013 18:06:32 -0500 Received: from d01dlp02.pok.ibm.com (9.56.250.167) by e9.ny.us.ibm.com (192.168.1.109) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 26 Feb 2013 18:06:30 -0500 Received: from d01relay03.pok.ibm.com (d01relay03.pok.ibm.com [9.56.227.235]) by d01dlp02.pok.ibm.com (Postfix) with ESMTP id 3919B6E805D for ; Tue, 26 Feb 2013 18:06:28 -0500 (EST) Received: from d01av03.pok.ibm.com (d01av03.pok.ibm.com [9.56.224.217]) by d01relay03.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id r1QN6TiZ298356 for ; Tue, 26 Feb 2013 18:06:29 -0500 Received: from d01av03.pok.ibm.com (loopback [127.0.0.1]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id r1QN6SAQ019735 for ; Tue, 26 Feb 2013 20:06:29 -0300 Received: from jschopp-w520 (jschopp-w520.austin.ibm.com [9.41.105.206]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id r1QN6SSq019702; Tue, 26 Feb 2013 20:06:28 -0300 Received: by jschopp-w520 (Postfix, from userid 1000) id A6F4B50014B; Tue, 26 Feb 2013 17:06:27 -0600 (CST) Message-Id: <20130226230627.565283939@linux.vnet.ibm.com> User-Agent: quilt/0.60-1 Date: Tue, 26 Feb 2013 17:03:57 -0600 From: jschopp@linux.vnet.ibm.com To: qemu-devel@nongnu.org X-Content-Scanned: Fidelis XPS MAILER x-cbid: 13022623-7182-0000-0000-00000589B590 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 32.97.182.139 Cc: Stefan Berger Subject: [Qemu-devel] [PATCH 3/3] asn1 visitor 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 These patches implement asn1 ber visitors for encoding and decoding data. References: <20130226230354.982917686@linux.vnet.ibm.com> Content-Disposition: inline; filename=asn1_tests.diff Signed-off-by: Stefan Berger Signed-off-by: Joel Schopp --- tests/Makefile | 12 + tests/test-ber-visitor.c | 518 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 530 insertions(+) Index: b/tests/test-ber-visitor.c =================================================================== --- /dev/null +++ b/tests/test-ber-visitor.c @@ -0,0 +1,518 @@ +/* + * BER Output Visitor unit-tests. + * + * Copyright (C) 2011 Red Hat Inc. + * Copyright (C) 2011 IBM Corporation + * + * Authors: + * Luiz Capitulino + * Stefan Berger + * + * 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 "qemu-common.h" +#include "ber/ber-output-visitor.h" +#include "ber/ber-input-visitor.h" +#include "hw/hw.h" +#include "include/qapi/visitor.h" + + +typedef struct TestInputOutputVisitorData { + QEMUFile *qoutfile; + BEROutputVisitor *bov; + Visitor *ov; + + QEMUFile *qinfile; + BERInputVisitor *biv; + Visitor *iv; +} TestInputOutputVisitor; + +static void visitor_output_setup(TestInputOutputVisitor *data, + BERTypePC ber_type_pc) +{ + data->qoutfile = qemu_bufopen("w", NULL); + + data->bov = ber_output_visitor_new(data->qoutfile, ber_type_pc); + g_assert(data->bov != NULL); + + data->ov = ber_output_get_visitor(data->bov); + g_assert(data->ov != NULL); +} + +static void visitor_output_setup_primitive(TestInputOutputVisitor *data, + const void *unused) +{ + visitor_output_setup(data, BER_TYPE_PRIMITIVE); +} + +static void visitor_output_setup_constructed(TestInputOutputVisitor *data, + const void *unused) +{ + visitor_output_setup(data, BER_TYPE_CONSTRUCTED); +} + +static void visitor_input_setup(TestInputOutputVisitor *data) +{ + const QEMUSizedBuffer *qsb = qemu_buf_get(data->qoutfile); + QEMUSizedBuffer *new_qsb = qsb_clone(qsb); + g_assert(new_qsb != NULL); + + data->qinfile = qemu_bufopen("r", new_qsb); + g_assert(data->qinfile != NULL); + + data->biv = ber_input_visitor_new(data->qinfile, ~0); + g_assert(data->biv != NULL); + + data->iv = ber_input_get_visitor(data->biv); + g_assert(data->iv != NULL); +} + +static void visitor_output_teardown(TestInputOutputVisitor *data, + const void *unused) +{ + ber_output_visitor_cleanup(data->bov); + data->bov = NULL; + data->ov = NULL; + + ber_input_visitor_cleanup(data->biv); + data->biv = NULL; + data->iv = NULL; + + if (data->qinfile) { + qemu_fclose(data->qinfile); + } + if (data->qoutfile) { + qemu_fclose(data->qoutfile); + } +} + +static void test_visitor_out_int(TestInputOutputVisitor *data, + const void *unused) +{ + int64_t value_in = -42, value_out = 0; + Error *errp = NULL; + + visit_type_int(data->ov, &value_in, NULL, &errp); + g_assert(error_is_set(&errp) == 0); + + visitor_input_setup(data); + + visit_type_int(data->iv, &value_out, NULL, &errp); + g_assert_cmpint(value_out, ==, -42); +} + +static void test_visitor_out_bool(TestInputOutputVisitor *data, + const void *unused) +{ + Error *errp = NULL; + bool value_in = true, value_out = false; + + visit_type_bool(data->ov, &value_in, NULL, &errp); + g_assert(error_is_set(&errp) == 0); + + visitor_input_setup(data); + + visit_type_bool(data->iv, &value_out, NULL, &errp); + g_assert_cmpint(value_out, ==, true); + +} + +static void test_visitor_out_string(TestInputOutputVisitor *data, + const void *unused) +{ + char *string_in = (char *) "Q E M U", *string_out = NULL; + Error *errp = NULL; + + visit_type_str(data->ov, &string_in, NULL, &errp); + g_assert(error_is_set(&errp) == 0); + + visitor_input_setup(data); + + visit_type_str(data->iv, &string_out, NULL, &errp); + + g_assert_cmpstr(string_out, ==, string_in); + g_free(string_out); +} + +static void test_visitor_out_no_string(TestInputOutputVisitor *data, + const void *unused) +{ + char *string_in = NULL, *string_out = NULL; + Error *errp = NULL; + + /* A null string should return "" */ + visit_type_str(data->ov, &string_in, NULL, &errp); + g_assert(error_is_set(&errp) == 0); + g_assert(qsb_get_length(qemu_buf_get(data->qoutfile)) == 2); + + visitor_input_setup(data); + + visit_type_str(data->iv, &string_out, NULL, &errp); + g_assert_cmpstr(string_out, ==, ""); + + g_free(string_out); +} + +typedef struct SimpleStruct { + int64_t integer; + bool boolean; + char *string; +} SimpleStruct; + +static void visit_type_SimpleStruct(Visitor *v, SimpleStruct **obj, + const char *name, Error **errp) +{ + visit_start_struct(v, (void **)obj, "SimpleStruct", name, + sizeof(SimpleStruct), errp); + + visit_type_int(v, &(*obj)->integer, "integer", errp); + visit_type_bool(v, &(*obj)->boolean, "boolean", errp); + visit_type_str(v, &(*obj)->string, "string", errp); + + visit_end_struct(v, errp); +} + +static void test_visitor_out_struct(TestInputOutputVisitor *data, + const void *unused) +{ + SimpleStruct test_struct = { + .integer = 42, + .boolean = false, + .string = (char *)"foo" + }; + SimpleStruct *p_in = &test_struct, *p_out = NULL; + Error *errp = NULL; + + visit_type_SimpleStruct(data->ov, &p_in, NULL, &errp); + g_assert(!error_is_set(&errp)); + + visitor_input_setup(data); + + visit_type_SimpleStruct(data->iv, &p_out, NULL, &errp); + + g_assert_cmpint(p_out->integer, ==, 42); + g_assert_cmpint(p_out->boolean, ==, 0); + g_assert_cmpstr(p_out->string, ==, "foo"); + + g_free(p_out->string); + g_free(p_out); +} + +static void visit_type_SimpleStructArray(Visitor *v, SimpleStruct **obj, + const char *name, + size_t elem_count, size_t elem_size, + Error **errp) +{ + size_t i; + + visit_start_array(v, (void **)obj, name, elem_count, elem_size, errp); + + for (i = 0; i < elem_count; i++) { + SimpleStruct *s = &((*obj)[i]); + visit_type_SimpleStruct(v, &s, "SimpleStruct", errp); + visit_next_array(v, errp); + } + + visit_end_array(v, errp); +} + +static void test_visitor_out_array(TestInputOutputVisitor *data, + const void *unused) +{ + SimpleStruct test_struct[] = { + { + .integer = 42, + .boolean = false, + .string = (char *)"foo" + }, { + .integer = 1000, + .boolean = true, + .string = (char *)"bar" + } + }; + SimpleStruct *p_in = test_struct, *p_out = NULL; + Error *errp = NULL; + + visit_type_SimpleStructArray(data->ov, &p_in, NULL, + ARRAY_SIZE(test_struct), + sizeof(test_struct[0]), &errp); + g_assert(!error_is_set(&errp)); + + visitor_input_setup(data); + + visit_type_SimpleStructArray(data->iv, &p_out, NULL, + ARRAY_SIZE(test_struct), + sizeof(test_struct[0]), &errp); + + g_assert_cmpint(p_out[0].integer, ==, 42); + g_assert_cmpint(p_out[0].boolean, ==, 0); + g_assert_cmpstr(p_out[0].string, ==, "foo"); + + g_assert_cmpint(p_out[1].integer, ==, 1000); + g_assert_cmpint(p_out[1].boolean, ==, 1); + g_assert_cmpstr(p_out[1].string, ==, "bar"); + + g_free(p_out[0].string); + g_free(p_out[1].string); + g_free(p_out); +} + +typedef struct NestedStruct { + int64_t integer; + bool boolean; + SimpleStruct simpleStruct[2]; + char *string; +} NestedStruct; + +static void visit_type_NestedStruct(Visitor *v, NestedStruct **obj, + const char *name, Error **errp) +{ + unsigned int i; + + visit_start_struct(v, (void **)obj, "NestedStruct", name, + sizeof(NestedStruct), errp); + + visit_type_int(v, &(*obj)->integer, "integer", errp); + visit_type_bool(v, &(*obj)->boolean, "boolean", errp); + + for (i = 0; i < ARRAY_SIZE((*obj)->simpleStruct); i++) { + SimpleStruct *simple = &(*obj)->simpleStruct[i]; + visit_type_SimpleStruct(v, &simple, "SimpleStruct", errp); + } + + visit_type_str(v, &(*obj)->string, "string", errp); + + visit_end_struct(v, errp); +} + +static void test_visitor_out_nested_struct(TestInputOutputVisitor *data, + const void *unused) +{ + NestedStruct nested_struct = { + .integer = 42, + .boolean = true, + .simpleStruct = { + { + .integer = 1000, + .boolean = false, + .string = (char *)"Hello", + }, { + .integer = 2000, + .boolean = false, + .string = (char *)"world!", + }, + }, + .string = (char *)"bar", + }; + NestedStruct *p_in = &nested_struct, *p_out = NULL; + Error *errp = NULL; + unsigned int i; + + visit_type_NestedStruct(data->ov, &p_in, NULL, &errp); + g_assert(!error_is_set(&errp)); + + visitor_input_setup(data); + + visit_type_NestedStruct(data->iv, &p_out, NULL, &errp); + + g_assert_cmpint(p_out->integer, ==, 42); + g_assert_cmpint(p_out->boolean, ==, true); + + g_assert_cmpint(p_out->simpleStruct[0].integer, ==, 1000); + g_assert_cmpint(p_out->simpleStruct[0].boolean, ==, 0); + g_assert_cmpstr(p_out->simpleStruct[0].string , ==, "Hello"); + + g_assert_cmpint(p_out->simpleStruct[1].integer, ==, 2000); + g_assert_cmpint(p_out->simpleStruct[1].boolean, ==, 0); + g_assert_cmpstr(p_out->simpleStruct[1].string , ==, "world!"); + + g_assert_cmpstr(p_out->string, ==, "bar"); + + g_free(p_out->string); + for (i = 0; i < ARRAY_SIZE(p_out->simpleStruct); i++) { + g_free(p_out->simpleStruct[i].string); + } + g_free(p_out); +} + +typedef struct SimpleStringList { + char *value; + struct SimpleStringList *next; +} SimpleStringList; + +static void visit_type_SimpleStringList(Visitor *m, SimpleStringList ** obj, + const char *name, Error **errp) +{ + GenericList *i, **head = (GenericList **)obj; + + visit_start_list(m, name, errp); + + for (*head = i = visit_next_list(m, head, errp); + i; + i = visit_next_list(m, &i, errp)) { + SimpleStringList *native_i = (SimpleStringList *)i; + visit_type_str(m, &native_i->value, NULL, errp); + } + + visit_end_list(m, errp); +} + +static void test_visitor_out_list(TestInputOutputVisitor *data, + const void *unused) +{ + SimpleStringList test_list = { + .value = (char *)"hello", + .next = &(SimpleStringList) { + .value = (char *)"world", + .next = NULL, + }, + }; + SimpleStringList *p_in = &test_list, *p_out = NULL, *iter = NULL, *_iter; + Error *errp = NULL; + + visit_type_SimpleStringList(data->ov, &p_in, "SimpleStringList", &errp); + g_assert(!error_is_set(&errp)); + + visitor_input_setup(data); + + visit_type_SimpleStringList(data->iv, &p_out, "SimpleStringList", &errp); + g_assert(!error_is_set(&errp)); + + iter = p_out; + g_assert_cmpstr(iter->value, ==, "hello"); + iter = iter->next; + g_assert_cmpstr(iter->value, ==, "world"); + + for (iter = p_out; iter; iter = _iter) { + _iter = iter->next; + g_free(iter->value); + g_free(iter); + } +} + +typedef struct SimpleStructList { + SimpleStruct *value; + struct SimpleStructList *next; +} SimpleStructList; + +static void visit_type_SimpleStructList(Visitor *m, SimpleStructList ** obj, + const char *name, Error **errp) +{ + GenericList *i, **head = (GenericList **)obj; + + visit_start_list(m, name, errp); + + for (*head = i = visit_next_list(m, head, errp); + i; + i = visit_next_list(m, &i, errp)) { + SimpleStructList *native_i = (SimpleStructList *)i; + visit_type_SimpleStruct(m, &native_i->value, NULL, errp); + } + + visit_end_list(m, errp); +} + +static void test_visitor_out_simplestruct_list(TestInputOutputVisitor *data, + const void *unused) +{ + SimpleStructList test_list = { + .value = &(SimpleStruct) { + .string = (char *)"hello", + .integer = 1000, + .boolean = false, + }, + .next = &(SimpleStructList) { + .value = &(SimpleStruct) { + .string = (char *)"world", + .integer = 2000, + .boolean = true, + }, + .next = NULL, + }, + }; + SimpleStructList *p_in = &test_list, *p_out = NULL, *iter = NULL, *_iter; + Error *errp = NULL; + + visit_type_SimpleStructList(data->ov, &p_in, "SimpleStructList", &errp); + g_assert(!error_is_set(&errp)); + + visitor_input_setup(data); + + visit_type_SimpleStructList(data->iv, &p_out, "SimpleStructList", &errp); + g_assert(!error_is_set(&errp)); + + iter = p_out; + g_assert_cmpstr(iter->value->string, ==, "hello"); + iter = iter->next; + g_assert_cmpstr(iter->value->string, ==, "world"); + + for (iter = p_out; iter; iter = _iter) { + _iter = iter->next; + g_free(iter->value->string); + g_free(iter->value); + g_free(iter); + } +} + +static void test_visitor_test_add(const char *testpath, + BERTypePC ber_type, + TestInputOutputVisitor *data, + void (*test_func)(TestInputOutputVisitor *data, const void *user_data)) +{ + char path[64]; + void (*setup)(TestInputOutputVisitor *data, const void *unused); + + switch (ber_type) { + case BER_TYPE_PRIMITIVE: + snprintf(path, sizeof(path), "/primitive%s", testpath); + setup = visitor_output_setup_primitive; + break; + default: + snprintf(path, sizeof(path), "/constructed%s", testpath); + setup = visitor_output_setup_constructed; + break; + } + + g_test_add(path, TestInputOutputVisitor, data, setup, + test_func, visitor_output_teardown); +} + +int main(int argc, char **argv) +{ + TestInputOutputVisitor out_visitor_data; + BERTypePC types[] = {BER_TYPE_CONSTRUCTED, BER_TYPE_PRIMITIVE}; + int i; + + g_test_init(&argc, &argv, NULL); + + for (i = 0; i < ARRAY_SIZE(types); i++) { + test_visitor_test_add("/visitor/output/int", types[i], + &out_visitor_data, test_visitor_out_int); + test_visitor_test_add("/visitor/output/bool", types[i], + &out_visitor_data, test_visitor_out_bool); + test_visitor_test_add("/visitor/output/string", types[i], + &out_visitor_data, test_visitor_out_string); + test_visitor_test_add("/visitor/output/no-string", types[i], + &out_visitor_data, test_visitor_out_no_string); + test_visitor_test_add("/visitor/output/struct", types[i], + &out_visitor_data, test_visitor_out_struct); + test_visitor_test_add("/visitor/output/array", types[i], + &out_visitor_data, test_visitor_out_array); + test_visitor_test_add("/visitor/output/nested-struct", types[i], + &out_visitor_data, + test_visitor_out_nested_struct); + test_visitor_test_add("/visitor/output/list", types[i], + &out_visitor_data, test_visitor_out_list); + test_visitor_test_add("/visitor/output/simplestruct_list", types[i], + &out_visitor_data, + test_visitor_out_simplestruct_list); + } + + g_test_run(); + + return 0; +} Index: b/tests/Makefile =================================================================== --- a/tests/Makefile +++ b/tests/Makefile @@ -23,6 +23,10 @@ check-unit-y += tests/test-string-input- gcov-files-test-string-input-visitor-y = qapi/string-input-visitor.c check-unit-y += tests/test-string-output-visitor$(EXESUF) gcov-files-test-string-output-visitor-y = qapi/string-output-visitor.c +check-unit-y += tests/test-ber-visitor$(EXESUF) +gcov-files-test-vistor-y = ber/ + + check-unit-y += tests/test-coroutine$(EXESUF) ifeq ($(CONFIG_WIN32),y) gcov-files-test-coroutine-y = coroutine-win32.c @@ -134,6 +138,14 @@ tests/fdc-test$(EXESUF): tests/fdc-test. tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/tmp105-test$(EXESUF): tests/tmp105-test.o +ber-dir = ber + +tests/test-ber-visitor.o : QEMU_CFLAGS += -I $(ber-dir) + +tests/test-ber-visitor.o: $(addprefix $(ber-dir)/, ber-common.c ber.h ber-input-visitor.c ber-input-visitor.h ber-output-visitor.c ber-output-visitor.h) $(ber-obj-y) +#tests/test-ber-visitor$(EXESUF): tests/test-ber-visitor.o $(tools-obj-y) $(ber-dir)/ber-output-visitor.o $(ber-dir)/ber-input-visitor.o $(ber-dir)/ber-common.o $(block-obj-y) qemu-file.o libqemustub.a $(qobject-obj-y) $(qapi-obj-y) +tests/test-ber-visitor$(EXESUF): tests/test-ber-visitor.o $(tools-obj-y) $(ber-dir)/ber-output-visitor.o $(ber-dir)/ber-input-visitor.o $(ber-dir)/ber-common.o $(block-obj-y) qemu-file.o libqemuutil.a libqemustub.a + # QTest rules TARGETS=$(patsubst %-softmmu,%, $(filter %-softmmu,$(TARGET_DIRS)))