From b699c4d7f85a5404be1d1ee9450331aea869b886 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Thu, 9 Jan 2014 23:04:45 +0100 Subject: sbus: Add meta data structures and code generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These metadata structures hold the information about all the details of a DBus interface. They are typically generated from the canonical XML form of the DBus interface, although they may also be hand crafted. Add some handy functions for looking up methods, props, signals, in the metadata of an interface. Currently lookups are just done by looking through an array. If performance becomes an issue (ie: very large interfaces) it would be really easy to sort things and use bsearch(). Later commits will include some definitions using this metadata and related functions. DBus interfaces are defined here: http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format The introspection data format has become the standard way to represent a DBus interface. For many examples see /usr/share/dbus-1/interfaces/ on a typical linux machine. A word about annotations. These are extra flags or values that can be assigned to anything. So far, the codegen supports this annotation: org.freedesktop.DBus.GLib.CSymbol - An annotation specified in the specification that tells us what C symbol to generate for a given interface or method. By default the codegen will build up a symbol name from the DBus name. It is possible to confuse the code generator into producing invalid C code (with strange method names, for example), but the C compiler catches such silliness right away. Add tests testing basic features of the codegen and poking through the metadata it creates. Also test the metadata lookup functions. Generated code is checked in for easy discovery. An example of the XML interface definitions can be found at: src/tests/sbus_codegen_tests.xml And an example of the generated header can be found here: src/tests/sbus_codegen_tests_generated.h Reviewed-by: Jakub Hrozek Reviewed-by: Sumit Bose Reviewed-by: Lukáš Slebodník Reviewed-by: Simo Sorce --- src/tests/sbus_codegen_tests.c | 166 +++++++++++++++++++++++++++++++ src/tests/sbus_codegen_tests.xml | 45 +++++++++ src/tests/sbus_codegen_tests_generated.c | 79 +++++++++++++++ src/tests/sbus_codegen_tests_generated.h | 24 +++++ 4 files changed, 314 insertions(+) create mode 100644 src/tests/sbus_codegen_tests.c create mode 100755 src/tests/sbus_codegen_tests.xml create mode 100644 src/tests/sbus_codegen_tests_generated.c create mode 100644 src/tests/sbus_codegen_tests_generated.h (limited to 'src/tests') diff --git a/src/tests/sbus_codegen_tests.c b/src/tests/sbus_codegen_tests.c new file mode 100644 index 000000000..6b2abf8bc --- /dev/null +++ b/src/tests/sbus_codegen_tests.c @@ -0,0 +1,166 @@ +/* + SSSD + + sbus_codegen tests. + + Authors: + Stef Walter + + Copyright (C) Red Hat, Inc 2014 + + 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 3 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 . +*/ + +#include +#include +#include +#include +#include + +#include "sbus/sssd_dbus_meta.h" +#include "tests/sbus_codegen_tests_generated.h" + +static const struct sbus_arg_meta * +find_arg(const struct sbus_arg_meta *args, + const char *name) +{ + const struct sbus_arg_meta *arg; + for (arg = args; arg->name != NULL; arg++) { + if (strcmp (arg->name, name) == 0) + return arg; + } + + return NULL; +} + +START_TEST(test_interfaces) +{ + ck_assert_str_eq(com_planetexpress_Ship_meta.name, "com.planetexpress.Ship"); + ck_assert(com_planetexpress_Ship_meta.methods != NULL); + ck_assert(com_planetexpress_Ship_meta.signals != NULL); + ck_assert(com_planetexpress_Ship_meta.properties != NULL); + + /* Explicit C Symbol */ + ck_assert_str_eq(test_pilot_meta.name, "com.planetexpress.Pilot"); + ck_assert(test_pilot_meta.methods == NULL); /* no methods */ + ck_assert(test_pilot_meta.signals == NULL); /* no signals */ + ck_assert(test_pilot_meta.properties != NULL); + +} +END_TEST + +START_TEST(test_methods) +{ + const struct sbus_method_meta *method; + const struct sbus_arg_meta *arg; + + method = sbus_meta_find_method(&com_planetexpress_Ship_meta, "MoveUniverse"); + ck_assert(method != NULL); + ck_assert_str_eq(method->name, "MoveUniverse"); + ck_assert(method->in_args != NULL); + ck_assert(method->out_args != NULL); + + arg = find_arg(method->in_args, "smoothly"); + ck_assert(arg != NULL); + ck_assert_str_eq(arg->name, "smoothly"); + ck_assert_str_eq(arg->type, "b"); + + arg = find_arg(method->out_args, "where_we_crashed"); + ck_assert(arg != NULL); + ck_assert_str_eq(arg->name, "where_we_crashed"); + ck_assert_str_eq(arg->type, "s"); +} +END_TEST + +START_TEST(test_properties) +{ + const struct sbus_property_meta *prop; + + prop = sbus_meta_find_property(&com_planetexpress_Ship_meta, "Color"); + ck_assert(prop != NULL); + ck_assert_str_eq(prop->name, "Color"); + ck_assert_str_eq(prop->type, "s"); + ck_assert_int_eq(prop->flags, SBUS_PROPERTY_READABLE); +} +END_TEST + +START_TEST(test_signals) +{ + const struct sbus_signal_meta *signal; + const struct sbus_arg_meta *arg; + + signal = sbus_meta_find_signal(&com_planetexpress_Ship_meta, "BecameSentient"); + ck_assert(signal != NULL); + ck_assert_str_eq(signal->name, "BecameSentient"); + ck_assert(signal->args != NULL); + + arg = find_arg(signal->args, "gender"); + ck_assert(arg != NULL); + ck_assert_str_eq(arg->name, "gender"); + ck_assert_str_eq(arg->type, "s"); +} +END_TEST + +Suite *create_suite(void) +{ + Suite *s = suite_create("sbus_codegen"); + + TCase *tc = tcase_create("defs"); + + /* Do some testing */ + tcase_add_test(tc, test_interfaces); + tcase_add_test(tc, test_methods); + tcase_add_test(tc, test_properties); + tcase_add_test(tc, test_signals); + + /* Add all test cases to the test suite */ + suite_add_tcase(s, tc); + + return s; +} + +int main(int argc, const char *argv[]) +{ + int opt; + poptContext pc; + int failure_count; + Suite *suite; + SRunner *sr; + + struct poptOption long_options[] = { + POPT_AUTOHELP + POPT_TABLEEND + }; + + pc = poptGetContext(argv[0], argc, argv, long_options, 0); + while ((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { + default: + fprintf(stderr, "\nInvalid option %s: %s\n\n", + poptBadOption(pc, 0), poptStrerror(opt)); + poptPrintUsage(pc, stderr, 0); + return 1; + } + } + poptFreeContext(pc); + + suite = create_suite(); + sr = srunner_create(suite); + srunner_set_fork_status(sr, CK_FORK); + /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ + srunner_run_all(sr, CK_ENV); + failure_count = srunner_ntests_failed(sr); + srunner_free(sr); + return (failure_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} diff --git a/src/tests/sbus_codegen_tests.xml b/src/tests/sbus_codegen_tests.xml new file mode 100755 index 000000000..0def3585a --- /dev/null +++ b/src/tests/sbus_codegen_tests.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/sbus_codegen_tests_generated.c b/src/tests/sbus_codegen_tests_generated.c new file mode 100644 index 000000000..556eea12c --- /dev/null +++ b/src/tests/sbus_codegen_tests_generated.c @@ -0,0 +1,79 @@ +/* The following definitions are auto-generated from sbus_codegen_tests.xml */ + +#include "util/util.h" +#include "sbus/sssd_dbus.h" +#include "sbus/sssd_dbus_meta.h" + +/* arguments for com.planetexpress.Ship.MoveUniverse */ +const struct sbus_arg_meta com_planetexpress_Ship_MoveUniverse__in[] = { + { "smoothly", "b" }, + { "speed_factor", "u" }, + { NULL, } +}; + +/* arguments for com.planetexpress.Ship.MoveUniverse */ +const struct sbus_arg_meta com_planetexpress_Ship_MoveUniverse__out[] = { + { "where_we_crashed", "s" }, + { NULL, } +}; + +/* methods for com.planetexpress.Ship */ +const struct sbus_method_meta com_planetexpress_Ship__methods[] = { + { + "MoveUniverse", /* name */ + com_planetexpress_Ship_MoveUniverse__in, + com_planetexpress_Ship_MoveUniverse__out, + }, + { NULL, } +}; + +/* arguments for com.planetexpress.Ship.BecameSentient */ +const struct sbus_arg_meta com_planetexpress_Ship_BecameSentient__args[] = { + { "gender", "s" }, + { NULL, } +}; + +/* signals for com.planetexpress.Ship */ +const struct sbus_signal_meta com_planetexpress_Ship__signals[] = { + { + "BecameSentient", /* name */ + com_planetexpress_Ship_BecameSentient__args + }, + { NULL, } +}; + +/* property info for com.planetexpress.Ship */ +const struct sbus_property_meta com_planetexpress_Ship__properties[] = { + { + "Color", /* name */ + "s", /* signature */ + SBUS_PROPERTY_READABLE, + }, + { NULL, } +}; + +/* interface info for com.planetexpress.Ship */ +const struct sbus_interface_meta com_planetexpress_Ship_meta = { + "com.planetexpress.Ship", /* name */ + com_planetexpress_Ship__methods, + com_planetexpress_Ship__signals, + com_planetexpress_Ship__properties +}; + +/* property info for com.planetexpress.Pilot */ +const struct sbus_property_meta test_pilot__properties[] = { + { + "FullName", /* name */ + "s", /* signature */ + SBUS_PROPERTY_READABLE | SBUS_PROPERTY_WRITABLE, + }, + { NULL, } +}; + +/* interface info for com.planetexpress.Pilot */ +const struct sbus_interface_meta test_pilot_meta = { + "com.planetexpress.Pilot", /* name */ + NULL, /* no methods */ + NULL, /* no signals */ + test_pilot__properties +}; diff --git a/src/tests/sbus_codegen_tests_generated.h b/src/tests/sbus_codegen_tests_generated.h new file mode 100644 index 000000000..c3a23c870 --- /dev/null +++ b/src/tests/sbus_codegen_tests_generated.h @@ -0,0 +1,24 @@ +/* The following declarations are auto-generated from sbus_codegen_tests.xml */ + +#ifndef __SBUS_CODEGEN_TESTS_XML__ +#define __SBUS_CODEGEN_TESTS_XML__ + +#include "sbus/sssd_dbus.h" + +/* ------------------------------------------------------------------------ + * DBus Interface Metadata + * + * These structure definitions are filled in with the information about + * the interfaces, methods, properties and so on. + * + * The actual definitions are found in the accompanying C file next + * to this header. + */ + +/* interface info for com.planetexpress.Ship */ +extern const struct sbus_interface_meta com_planetexpress_Ship_meta; + +/* interface info for com.planetexpress.Pilot */ +extern const struct sbus_interface_meta test_pilot_meta; + +#endif /* __SBUS_CODEGEN_TESTS_XML__ */ -- cgit