sbus_codegen_tests.c revision 01f852fcb27e0a0a07e2b8b51e7e838a256b485f
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/*
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen SSSD
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen sbus_codegen tests.
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen Authors:
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen Stef Walter <stefw@redhat.com>
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
9511a40d933181045343110c8101b75887062aaeTimo Sirainen Copyright (C) Red Hat, Inc 2014
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen This program is free software; you can redistribute it and/or modify
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen it under the terms of the GNU General Public License as published by
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen the Free Software Foundation; either version 3 of the License, or
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen (at your option) any later version.
f30d2b798191d94f845463637610d6b833162d9bTimo Sirainen
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen This program is distributed in the hope that it will be useful,
f30d2b798191d94f845463637610d6b833162d9bTimo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
f30d2b798191d94f845463637610d6b833162d9bTimo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f30d2b798191d94f845463637610d6b833162d9bTimo Sirainen GNU General Public License for more details.
f30d2b798191d94f845463637610d6b833162d9bTimo Sirainen
56db132c6523e8c28e8bd97e36f0ec7056e4ce7bTimo Sirainen You should have received a copy of the GNU General Public License
f30d2b798191d94f845463637610d6b833162d9bTimo Sirainen along with this program. If not, see <http://www.gnu.org/licenses/>.
56db132c6523e8c28e8bd97e36f0ec7056e4ce7bTimo Sirainen*/
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen#include <stdint.h>
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen#include <stdlib.h>
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen#include <check.h>
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen#include <talloc.h>
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen#include <tevent.h>
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen#include <popt.h>
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen#include "sbus/sssd_dbus_meta.h"
597dba3488c648ffb375ee4a552bd52ac4346979Timo Sirainen#include "tests/common.h"
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen#include "tests/sbus_codegen_tests_generated.h"
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen#include "util/util_errors.h"
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen/* The following 2 macros were taken from check's project source files (0.9.10)
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen * http://check.sourceforge.net/
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen */
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen#ifndef _ck_assert_uint
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen#define _ck_assert_uint(X, OP, Y) do { \
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen uintmax_t _ck_x = (X); \
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen uintmax_t _ck_y = (Y); \
601f5f14c6cde28f0e0c6ca7c5d735315d3d48dfTimo Sirainen ck_assert_msg(_ck_x OP _ck_y, "Assertion '"#X#OP#Y"' failed: "#X"==%ju, "#Y"==%ju", _ck_x, _ck_y); \
859cc94211b759825db5e15b0c88754da902ca14Timo Sirainen} while (0)
859cc94211b759825db5e15b0c88754da902ca14Timo Sirainen#endif /* _ck_assert_uint */
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
859cc94211b759825db5e15b0c88754da902ca14Timo Sirainen#ifndef ck_assert_uint_eq
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen#define ck_assert_uint_eq(X, Y) _ck_assert_uint(X, ==, Y)
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen#endif /* ck_assert_uint_eq */
9511a40d933181045343110c8101b75887062aaeTimo Sirainen
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainenstatic const struct sbus_arg_meta *
9511a40d933181045343110c8101b75887062aaeTimo Sirainenfind_arg(const struct sbus_arg_meta *args,
601f5f14c6cde28f0e0c6ca7c5d735315d3d48dfTimo Sirainen const char *name)
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen{
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen const struct sbus_arg_meta *arg;
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen for (arg = args; arg->name != NULL; arg++) {
42aaebd4b237403aff6bbfafdcdf52cf5f8c1c06Timo Sirainen if (strcmp (arg->name, name) == 0)
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen return arg;
7a4c6cc0aea1fc7999ac9bbebc3a95197ac2585cTimo Sirainen }
7a4c6cc0aea1fc7999ac9bbebc3a95197ac2585cTimo Sirainen
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen return NULL;
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen}
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen
9b1d6da0f2b42b8b6f612a570a83355c2a5088eeTimo SirainenSTART_TEST(test_interfaces)
9b1d6da0f2b42b8b6f612a570a83355c2a5088eeTimo Sirainen{
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen ck_assert_str_eq(com_planetexpress_Ship_meta.name, "com.planetexpress.Ship");
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen ck_assert(com_planetexpress_Ship_meta.methods != NULL);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen ck_assert(com_planetexpress_Ship_meta.signals != NULL);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen ck_assert(com_planetexpress_Ship_meta.properties != NULL);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
1117aa7adc2909c750031fd7551a58a486d100d8Timo Sirainen /* Explicit C Symbol */
1117aa7adc2909c750031fd7551a58a486d100d8Timo Sirainen ck_assert_str_eq(test_pilot_meta.name, "com.planetexpress.Pilot");
e50c7afe297ab10e07a8acc816c76ce9d45ef409Timo Sirainen ck_assert(test_pilot_meta.methods != NULL);
1117aa7adc2909c750031fd7551a58a486d100d8Timo Sirainen ck_assert(test_pilot_meta.signals == NULL); /* no signals */
e50c7afe297ab10e07a8acc816c76ce9d45ef409Timo Sirainen ck_assert(test_pilot_meta.properties != NULL);
e50c7afe297ab10e07a8acc816c76ce9d45ef409Timo Sirainen
1117aa7adc2909c750031fd7551a58a486d100d8Timo Sirainen}
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo SirainenEND_TEST
9b1d6da0f2b42b8b6f612a570a83355c2a5088eeTimo Sirainen
9b1d6da0f2b42b8b6f612a570a83355c2a5088eeTimo SirainenSTART_TEST(test_methods)
601f5f14c6cde28f0e0c6ca7c5d735315d3d48dfTimo Sirainen{
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen const struct sbus_method_meta *method;
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen const struct sbus_arg_meta *arg;
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen method = sbus_meta_find_method(&com_planetexpress_Ship_meta, "MoveUniverse");
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen ck_assert(method != NULL);
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen ck_assert_str_eq(method->name, "MoveUniverse");
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen ck_assert(method->in_args != NULL);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen ck_assert(method->out_args != NULL);
34ce7c45264902e217bfb5fa7f7a0aace9302074Timo Sirainen
34ce7c45264902e217bfb5fa7f7a0aace9302074Timo Sirainen arg = find_arg(method->in_args, "smoothly");
34ce7c45264902e217bfb5fa7f7a0aace9302074Timo Sirainen ck_assert(arg != NULL);
34ce7c45264902e217bfb5fa7f7a0aace9302074Timo Sirainen ck_assert_str_eq(arg->name, "smoothly");
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen ck_assert_str_eq(arg->type, "b");
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen arg = find_arg(method->out_args, "where_we_crashed");
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen ck_assert(arg != NULL);
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen ck_assert_str_eq(arg->name, "where_we_crashed");
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen ck_assert_str_eq(arg->type, "s");
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen}
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo SirainenEND_TEST
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo SirainenSTART_TEST(test_properties)
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen{
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen const struct sbus_property_meta *prop;
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen prop = sbus_meta_find_property(&com_planetexpress_Ship_meta, "Color");
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen ck_assert(prop != NULL);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen ck_assert_str_eq(prop->name, "Color");
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen ck_assert_str_eq(prop->type, "s");
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen ck_assert_int_eq(prop->flags, SBUS_PROPERTY_READABLE);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen}
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo SirainenEND_TEST
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen
4b9f99761df5014c659cd87fddaf6854af428cfcTimo SirainenSTART_TEST(test_signals)
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen{
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen const struct sbus_signal_meta *sig;
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen const struct sbus_arg_meta *arg;
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen sig = sbus_meta_find_signal(&com_planetexpress_Ship_meta, "BecameSentient");
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen ck_assert(sig != NULL);
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen ck_assert_str_eq(sig->name, "BecameSentient");
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen ck_assert(sig->args != NULL);
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen arg = find_arg(sig->args, "gender");
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen ck_assert(arg != NULL);
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen ck_assert_str_eq(arg->name, "gender");
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen ck_assert_str_eq(arg->type, "s");
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen}
4b9f99761df5014c659cd87fddaf6854af428cfcTimo SirainenEND_TEST
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainenstatic int
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainenmock_move_universe(struct sbus_request *dbus_req, void *data,
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen bool arg_smoothly, uint32_t arg_speed_factor)
10c96a244935de4add8213ba0b894178dfb889a5Timo Sirainen{
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen /*
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen * The above arguments should match the handler signature,
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen * and the below finish function should have the right signature.
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen *
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen * Not called, just testing compilation
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainen */
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen ck_assert(FALSE);
597dba3488c648ffb375ee4a552bd52ac4346979Timo Sirainen return com_planetexpress_Ship_MoveUniverse_finish(dbus_req, "here");
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen}
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainenstatic int
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainenmock_crash_now(struct sbus_request *dbus_req, void *data,
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen const char *where)
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen{
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen /*
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen * One argument, no return value, yet a finish function should
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen * have been generated.
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen *
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen * Not called, just testing compilation
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen */
411d6baa37f31d90730e90c4a28c43e1974bbe58Timo Sirainen ck_assert(FALSE);
9511a40d933181045343110c8101b75887062aaeTimo Sirainen return com_planetexpress_Ship_crash_now_finish(dbus_req);
9511a40d933181045343110c8101b75887062aaeTimo Sirainen}
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
static int
mock_land(struct sbus_request *req, void *data)
{
/*
* Raw handler, no finish function, no special arguments.
*
* Not called, just testing compilation
*/
ck_assert(FALSE);
return 0;
}
START_TEST(test_vtable)
{
struct com_planetexpress_Ship vtable = {
{ &com_planetexpress_Ship_meta, 0 },
mock_move_universe,
mock_crash_now,
mock_land,
NULL,
};
/*
* These are not silly tests:
* - Will fail compilation if c-symbol name was not respected
* - Will fail if method order was not respected
*/
ck_assert(vtable.crash_now == mock_crash_now);
ck_assert(vtable.MoveUniverse == mock_move_universe);
ck_assert(vtable.Land == mock_land);
}
END_TEST
START_TEST(test_constants)
{
ck_assert_str_eq(COM_PLANETEXPRESS_SHIP, "com.planetexpress.Ship");
ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_MOVEUNIVERSE, "MoveUniverse");
ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_CRASH_NOW, "Crash");
ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_BECAMESENTIENT, "BecameSentient");
ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_COLOR, "Color");
/* constants for com.planetexpress.Pilot */
ck_assert_str_eq(TEST_PILOT, "com.planetexpress.Pilot");
ck_assert_str_eq(TEST_PILOT_FULLNAME, "FullName");
}
END_TEST
TCase *create_defs_tests(void)
{
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);
tcase_add_test(tc, test_vtable);
tcase_add_test(tc, test_constants);
return tc;
}
/* This is a handler which has all the basic arguments types */
static int eject_handler(struct sbus_request *req, void *instance_data,
uint8_t arg_byte, bool arg_boolean,
int16_t arg_int16, uint16_t arg_uint16, int32_t arg_int32,
uint32_t arg_uint32, int64_t arg_int64, uint64_t arg_uint64,
double arg_double, const char *arg_string, const char *arg_object_path,
uint8_t arg_byte_array[], int len_byte_array,
int16_t arg_int16_array[], int len_int16_array,
uint16_t arg_uint16_array[], int len_uint16_array,
int32_t arg_int32_array[], int len_int32_array,
uint32_t arg_uint32_array[], int len_uint32_array,
int64_t arg_int64_array[], int len_int64_array,
uint64_t arg_uint64_array[], int len_uint64_array,
double arg_double_array[], int len_double_array,
const char *arg_string_array[], int len_string_array,
const char *arg_object_path_array[], int len_object_path_array)
{
int i;
/* Only called for leela, so double check here */
ck_assert_str_eq(instance_data, "Crash into the billboard");
/* Murge the various values for test case */
ck_assert_uint_eq(arg_byte, 11);
arg_byte++;
ck_assert(arg_boolean == TRUE);
arg_boolean = !arg_boolean;
ck_assert_int_eq(arg_int16, -2222);
arg_int16++;
ck_assert_uint_eq(arg_uint16, 3333);
arg_uint16++;
ck_assert_int_eq(arg_int32, -44444444);
arg_int32++;
ck_assert_uint_eq(arg_uint32, 55555555);
arg_uint32++;
ck_assert(arg_int64 == INT64_C(-6666666666666666));
arg_int64++;
ck_assert(arg_uint64 == UINT64_C(7777777777777777));
arg_uint64++;
ck_assert(arg_double == 1.1);
arg_double++;
ck_assert_str_eq(arg_string, "hello");
arg_string = "bears, beets, battlestar galactica";
ck_assert_str_eq(arg_object_path, "/original/object/path");
arg_object_path = "/another/object/path";
arg_byte_array = talloc_memdup(req, arg_byte_array, sizeof(uint8_t) * len_byte_array);
for (i = 0; i < len_byte_array; i++)
arg_byte_array[i]++;
arg_int16_array = talloc_memdup(req, arg_int16_array, sizeof(int16_t) * len_int16_array);
for (i = 0; i < len_int16_array; i++)
arg_int16_array[i]++;
len_int16_array--;
arg_uint16_array = talloc_memdup(req, arg_uint16_array, sizeof(uint16_t) * len_uint16_array);
for (i = 0; i < len_uint16_array; i++)
arg_uint16_array[i]++;
arg_int32_array = talloc_memdup(req, arg_int32_array, sizeof(int32_t) * len_int32_array);
for (i = 0; i < len_int32_array; i++)
arg_int32_array[i]++;
len_int32_array--;
arg_uint32_array = talloc_memdup(req, arg_uint32_array, sizeof(uint32_t) * len_uint32_array);
for (i = 0; i < len_uint32_array; i++)
arg_uint32_array[i]++;
arg_int64_array = talloc_memdup(req, arg_int64_array, sizeof(int64_t) * len_int64_array);
for (i = 0; i < len_int64_array; i++)
arg_int64_array[i]++;
arg_uint64_array = talloc_memdup(req, arg_uint64_array, sizeof(uint64_t) * len_uint64_array);
for (i = 0; i < len_uint64_array; i++)
arg_uint64_array[i]++;
arg_double_array = talloc_memdup(req, arg_double_array, sizeof(double) * len_double_array);
for (i = 0; i < len_double_array; i++)
arg_double_array[i]++;
arg_string_array = talloc_memdup(req, arg_string_array, sizeof(char *) * len_string_array);
for (i = 0; i < len_double_array; i++) {
ck_assert_str_eq(arg_string_array[i], "bears");
arg_string_array[i] = "beets";
}
len_string_array--;
arg_object_path_array = talloc_memdup(req, arg_object_path_array, sizeof(char *) * len_object_path_array);
for (i = 0; i < len_object_path_array; i++) {
ck_assert_str_eq(arg_object_path_array[i], "/original");
arg_object_path_array[i] = "/changed";
}
/* And reply with those values */
return test_pilot_Eject_finish(req, arg_byte, arg_boolean, arg_int16,
arg_uint16, arg_int32, arg_uint32,
arg_int64, arg_uint64, arg_double,
arg_string, arg_object_path,
arg_byte_array, len_byte_array,
arg_int16_array, len_int16_array,
arg_uint16_array, len_uint16_array,
arg_int32_array, len_int32_array,
arg_uint32_array, len_uint32_array,
arg_int64_array, len_int64_array,
arg_uint64_array, len_uint64_array,
arg_double_array, len_double_array,
arg_string_array, len_string_array,
arg_object_path_array, len_object_path_array);
}
#define getter_body(in, out) do { \
ck_assert(dbus_req != NULL); \
ck_assert(out != NULL); \
*out = in; \
} while(0);
static const bool pilot_bool = true;
void pilot_get_boolean_handler(struct sbus_request *dbus_req,
void *instance_data,
bool *val)
{
getter_body(pilot_bool, val);
}
static const char *pilot_full_name = "Turanga Leela";
void pilot_get_full_name_handler(struct sbus_request *dbus_req,
void *instance_data,
const char **name)
{
getter_body(pilot_full_name, name);
}
static const uint8_t pilot_byte = 42;
void pilot_get_byte_handler(struct sbus_request *dbus_req,
void *instance_data,
uint8_t *byte)
{
getter_body(pilot_byte, byte);
}
static const int16_t pilot_int16 = -123;
void pilot_get_int16_handler(struct sbus_request *dbus_req,
void *instance_data,
int16_t *int16)
{
getter_body(pilot_int16, int16);
}
static const uint16_t pilot_uint16 = 123;
void pilot_get_uint16_handler(struct sbus_request *dbus_req,
void *instance_data,
uint16_t *uint16)
{
getter_body(pilot_uint16, uint16);
}
static const int32_t pilot_int32 = -456;
void pilot_get_int32_handler(struct sbus_request *dbus_req,
void *instance_data,
int32_t *int32)
{
getter_body(pilot_int32, int32);
}
static const uint32_t pilot_uint32 = 456;
void pilot_get_uint32_handler(struct sbus_request *dbus_req,
void *instance_data,
uint32_t *uint32)
{
getter_body(pilot_uint32, uint32);
}
static const int64_t pilot_int64 = -456;
void pilot_get_int64_handler(struct sbus_request *dbus_req,
void *instance_data,
int64_t *int64)
{
getter_body(pilot_int64, int64);
}
static const uint64_t pilot_uint64 = 456;
void pilot_get_uint64_handler(struct sbus_request *dbus_req,
void *instance_data,
uint64_t *uint64)
{
getter_body(pilot_uint64, uint64);
}
static const double pilot_double = 3.14;
void pilot_get_double_handler(struct sbus_request *dbus_req,
void *instance_data,
double *double_val)
{
getter_body(pilot_double, double_val);
}
static const char *pilot_string = "leela";
void pilot_get_string_handler(struct sbus_request *dbus_req,
void *instance_data,
const char **string_val)
{
*string_val = pilot_string;
}
static const char *pilot_path = "/path/leela";
void pilot_get_objpath_handler(struct sbus_request *dbus_req,
void *instance_data,
const char **path_val)
{
*path_val = pilot_path;
}
void pilot_get_null_string_handler(struct sbus_request *dbus_req,
void *instance_data,
const char **string_val)
{
*string_val = NULL;
}
void pilot_get_null_path_handler(struct sbus_request *dbus_req,
void *instance_data,
const char **path_val)
{
*path_val = NULL;
}
#define array_getter_body(in, out, outlen) do { \
ck_assert(dbus_req != NULL); \
ck_assert(out != NULL); \
ck_assert(outlen != NULL); \
*out = in; \
*outlen = N_ELEMENTS(in); \
} while(0);
static uint8_t pilot_byte_array[] = { 42, 0 };
void pilot_get_byte_array_handler(struct sbus_request *dbus_req,
void *instance_data,
uint8_t **arr_out, int *arr_len)
{
array_getter_body(pilot_byte_array, arr_out, arr_len);
}
static int16_t pilot_int16_array[] = { -123, 0 };
void pilot_get_int16_array_handler(struct sbus_request *dbus_req,
void *instance_data,
int16_t **arr_out, int *arr_len)
{
array_getter_body(pilot_int16_array, arr_out, arr_len);
}
static uint16_t pilot_uint16_array[] = { 123, 0 };
void pilot_get_uint16_array_handler(struct sbus_request *dbus_req,
void *instance_data,
uint16_t **arr_out, int *arr_len)
{
array_getter_body(pilot_uint16_array, arr_out, arr_len);
}
static int32_t pilot_int32_array[] = { -456, 0 };
void pilot_get_int32_array_handler(struct sbus_request *dbus_req,
void *instance_data,
int32_t **arr_out, int *arr_len)
{
array_getter_body(pilot_int32_array, arr_out, arr_len);
}
static uint32_t pilot_uint32_array[] = { 456, 0 };
void pilot_get_uint32_array_handler(struct sbus_request *dbus_req,
void *instance_data,
uint32_t **arr_out, int *arr_len)
{
array_getter_body(pilot_uint32_array, arr_out, arr_len);
}
static int64_t pilot_int64_array[] = { -789, 0 };
void pilot_get_int64_array_handler(struct sbus_request *dbus_req,
void *instance_data,
int64_t **arr_out, int *arr_len)
{
array_getter_body(pilot_int64_array, arr_out, arr_len);
}
static uint64_t pilot_uint64_array[] = { 789, 0 };
void pilot_get_uint64_array_handler(struct sbus_request *dbus_req,
void *instance_data,
uint64_t **arr_out, int *arr_len)
{
array_getter_body(pilot_uint64_array, arr_out, arr_len);
}
static double pilot_double_array[] = { 3.14, 0 };
void pilot_get_double_array_handler(struct sbus_request *dbus_req,
void *instance_data,
double **arr_out, int *arr_len)
{
array_getter_body(pilot_double_array, arr_out, arr_len);
}
static const char *pilot_string_array[] = { "Turanga", "Leela" };
void pilot_get_string_array_handler(struct sbus_request *dbus_req,
void *data,
const char ***arr_out,
int *arr_len)
{
array_getter_body(pilot_string_array, arr_out, arr_len);
}
static const char *pilot_path_array[] = { "/some/path", "/another/path" };
void pilot_get_path_array_handler(struct sbus_request *dbus_req,
void *data,
const char ***arr_out,
int *arr_len)
{
array_getter_body(pilot_path_array, arr_out, arr_len);
}
void special_get_array_dict_sas(struct sbus_request *sbus_req,
void *data,
hash_table_t **_out)
{
hash_table_t *table;
hash_key_t key;
hash_value_t value;
char **values;
errno_t ret;
int hret;
*_out = NULL;
ret = sss_hash_create(sbus_req, 10, &table);
ck_assert_int_eq(ret, EOK);
values = talloc_zero_array(table, char *, 3);
ck_assert(values != NULL);
values[0] = talloc_strdup(values, "hello1");
values[1] = talloc_strdup(values, "world1");
ck_assert(values[0] != NULL);
ck_assert(values[1] != NULL);
key.type = HASH_KEY_STRING;
key.str = talloc_strdup(table, "key1");
value.type = HASH_VALUE_PTR;
value.ptr = values;
hret = hash_enter(table, &key, &value);
ck_assert_int_eq(hret, HASH_SUCCESS);
values = talloc_zero_array(table, char *, 3);
ck_assert(values != NULL);
values[0] = talloc_strdup(values, "hello2");
values[1] = talloc_strdup(values, "world2");
ck_assert(values[0] != NULL);
ck_assert(values[1] != NULL);
key.type = HASH_KEY_STRING;
key.str = talloc_strdup(table, "key2");
ck_assert(key.str != NULL);
value.type = HASH_VALUE_PTR;
value.ptr = values;
hash_enter(table, &key, &value);
ck_assert_int_eq(hret, HASH_SUCCESS);
*_out = table;
}
struct test_pilot pilot_iface = {
{ &test_pilot_meta, 0 },
.Eject = eject_handler,
.get_FullName = pilot_get_full_name_handler,
.get_byte = pilot_get_byte_handler,
.get_boolean = pilot_get_boolean_handler,
.get_int16 = pilot_get_int16_handler,
.get_uint16 = pilot_get_uint16_handler,
.get_int32 = pilot_get_int32_handler,
.get_uint32 = pilot_get_uint32_handler,
.get_int64 = pilot_get_int64_handler,
.get_uint64 = pilot_get_uint64_handler,
.get_double = pilot_get_double_handler,
.get_string = pilot_get_string_handler,
.get_object_path = pilot_get_objpath_handler,
.get_null_string = pilot_get_null_string_handler,
.get_null_path = pilot_get_null_path_handler,
.get_byte_array = pilot_get_byte_array_handler,
.get_int16_array = pilot_get_int16_array_handler,
.get_uint16_array = pilot_get_uint16_array_handler,
.get_int32_array = pilot_get_int32_array_handler,
.get_uint32_array = pilot_get_uint32_array_handler,
.get_int64_array = pilot_get_int64_array_handler,
.get_uint64_array = pilot_get_uint64_array_handler,
.get_double_array = pilot_get_double_array_handler,
.get_string_array = pilot_get_string_array_handler,
.get_object_path_array = pilot_get_path_array_handler,
};
struct test_special special_iface = {
{ &test_special_meta, 0},
.get_array_dict_sas = special_get_array_dict_sas
};
static int pilot_test_server_init(struct sbus_connection *server, void *unused)
{
int ret;
ret = sbus_conn_register_iface(server, &pilot_iface.vtable, "/test/leela",
discard_const("Crash into the billboard"));
ck_assert_int_eq(ret, EOK);
return EOK;
}
static int special_test_server_init(struct sbus_connection *server, void *unused)
{
int ret;
ret = sbus_conn_register_iface(server, &special_iface.vtable,
"/test/special",
discard_const("Crash into the billboard"));
ck_assert_int_eq(ret, EOK);
return EOK;
}
START_TEST(test_marshal_basic_types)
{
unsigned char arg_byte = 11;
dbus_bool_t arg_boolean = TRUE;
dbus_int16_t arg_int16 = -2222;
dbus_uint16_t arg_uint16 = 3333;
dbus_int32_t arg_int32 = -44444444;
dbus_uint32_t arg_uint32 = 55555555;
dbus_int64_t arg_int64 = INT64_C(-6666666666666666);
dbus_uint64_t arg_uint64 = UINT64_C(7777777777777777);
double arg_double = 1.1;
const char *arg_string = "hello";
const char *arg_object_path = "/original/object/path";
unsigned char v_byte[] = { 11, 12 };
dbus_int16_t v_int16[] = { 1, -22, 333, -4444 };
dbus_uint16_t v_uint16[] = { 1, 2, 3, 4, 5 };
dbus_int32_t v_int32[] = { -1, -23, 34, -56, -90000000, 78 };
dbus_uint32_t v_uint32[] = { 11111111, 22222222, 33333333 };
dbus_int64_t v_int64[] = { INT64_C(-6666666666666666), INT64_C(7777777777777777) };
dbus_uint64_t v_uint64[] = { UINT64_C(7777777777777777), INT64_C(888888888888888888) };
double v_double[] = { 1.1, 2.2, 3.3 };
const char *v_string[] = { "bears", "bears", "bears" };
const char *v_object_path[] = { "/original", "/original" };
unsigned char *arr_byte = v_byte;
dbus_int16_t *arr_int16 = v_int16;
dbus_uint16_t *arr_uint16 = v_uint16;
dbus_int32_t *arr_int32 = v_int32;
dbus_uint32_t *arr_uint32 = v_uint32;
dbus_int64_t *arr_int64 = v_int64;
dbus_uint64_t *arr_uint64 = v_uint64;
double *arr_double = v_double;
char **arr_string = discard_const(v_string);
char **arr_object_path = discard_const(v_object_path);
int len_byte = N_ELEMENTS(v_byte);
int len_int16 = N_ELEMENTS(v_int16);
int len_uint16 = N_ELEMENTS(v_uint16);
int len_int32 = N_ELEMENTS(v_int32);
int len_uint32 = N_ELEMENTS(v_uint32);
int len_int64 = N_ELEMENTS(v_int64);
int len_uint64 = N_ELEMENTS(v_uint64);
int len_double = N_ELEMENTS(v_double);
int len_string = N_ELEMENTS(v_string);
int len_object_path = N_ELEMENTS(v_object_path);
TALLOC_CTX *ctx;
DBusConnection *client;
DBusError error = DBUS_ERROR_INIT;
DBusMessage *reply;
ctx = talloc_new(NULL);
ck_assert(ctx != NULL);
client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL);
ck_assert(client != NULL);
reply = test_dbus_call_sync(client,
"/test/leela",
TEST_PILOT,
TEST_PILOT_EJECT,
&error,
DBUS_TYPE_BYTE, &arg_byte,
DBUS_TYPE_BOOLEAN, &arg_boolean,
DBUS_TYPE_INT16, &arg_int16,
DBUS_TYPE_UINT16, &arg_uint16,
DBUS_TYPE_INT32, &arg_int32,
DBUS_TYPE_UINT32, &arg_uint32,
DBUS_TYPE_INT64, &arg_int64,
DBUS_TYPE_UINT64, &arg_uint64,
DBUS_TYPE_DOUBLE, &arg_double,
DBUS_TYPE_STRING, &arg_string,
DBUS_TYPE_OBJECT_PATH, &arg_object_path,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &arr_byte, len_byte,
DBUS_TYPE_ARRAY, DBUS_TYPE_INT16, &arr_int16, len_int16,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT16, &arr_uint16, len_uint16,
DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &arr_int32, len_int32,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &arr_uint32, len_uint32,
DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &arr_int64, len_int64,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &arr_uint64, len_uint64,
DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &arr_double, len_double,
DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &arr_string, len_string,
DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arr_object_path, len_object_path,
DBUS_TYPE_INVALID);
ck_assert(reply != NULL);
ck_assert(!dbus_error_is_set(&error));
ck_assert(dbus_message_get_args(reply, NULL,
DBUS_TYPE_BYTE, &arg_byte,
DBUS_TYPE_BOOLEAN, &arg_boolean,
DBUS_TYPE_INT16, &arg_int16,
DBUS_TYPE_UINT16, &arg_uint16,
DBUS_TYPE_INT32, &arg_int32,
DBUS_TYPE_UINT32, &arg_uint32,
DBUS_TYPE_INT64, &arg_int64,
DBUS_TYPE_UINT64, &arg_uint64,
DBUS_TYPE_DOUBLE, &arg_double,
DBUS_TYPE_STRING, &arg_string,
DBUS_TYPE_OBJECT_PATH, &arg_object_path,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &arr_byte, &len_byte,
DBUS_TYPE_ARRAY, DBUS_TYPE_INT16, &arr_int16, &len_int16,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT16, &arr_uint16, &len_uint16,
DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &arr_int32, &len_int32,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &arr_uint32, &len_uint32,
DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &arr_int64, &len_int64,
DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &arr_uint64, &len_uint64,
DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &arr_double, &len_double,
DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &arr_string, &len_string,
DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arr_object_path, &len_object_path,
DBUS_TYPE_INVALID));
ck_assert_uint_eq(arg_byte, 12);
ck_assert(arg_boolean == FALSE);
ck_assert_int_eq(arg_int16, -2221);
ck_assert_uint_eq(arg_uint16, 3334);
ck_assert_int_eq(arg_int32, -44444443);
ck_assert_uint_eq(arg_uint32, 55555556);
ck_assert(arg_int64 == INT64_C(-6666666666666665));
ck_assert(arg_uint64 == UINT64_C(7777777777777778));
ck_assert(arg_double == 2.1);
ck_assert_str_eq(arg_string, "bears, beets, battlestar galactica");
ck_assert_str_eq(arg_object_path, "/another/object/path");
ck_assert_int_eq(len_byte, 2);
ck_assert_int_eq(arr_byte[0], 12);
ck_assert_int_eq(arr_byte[1], 13);
ck_assert_int_eq(len_int16, 3);
ck_assert_int_eq(arr_int16[0], 2);
ck_assert_int_eq(arr_int16[1], -21);
ck_assert_int_eq(arr_int16[2], 334);
ck_assert_int_eq(len_uint16, 5);
ck_assert_uint_eq(arr_uint16[0], 2);
ck_assert_uint_eq(arr_uint16[1], 3);
ck_assert_uint_eq(arr_uint16[2], 4);
ck_assert_uint_eq(arr_uint16[3], 5);
ck_assert_uint_eq(arr_uint16[4], 6);
ck_assert_int_eq(len_int32, 5);
ck_assert_int_eq(arr_int32[0], 0);
ck_assert_int_eq(arr_int32[1], -22);
ck_assert_int_eq(arr_int32[2], 35);
ck_assert_int_eq(arr_int32[3], -55);
ck_assert_int_eq(arr_int32[4], -89999999);
ck_assert_int_eq(len_uint32, 3);
ck_assert_uint_eq(arr_uint32[0], 11111112);
ck_assert_uint_eq(arr_uint32[1], 22222223);
ck_assert_uint_eq(arr_uint32[2], 33333334);
ck_assert_int_eq(len_int64, 2);
ck_assert(arr_int64[0] == INT64_C(-6666666666666665));
ck_assert(arr_int64[1] == INT64_C(7777777777777778));
ck_assert_int_eq(len_uint64, 2);
ck_assert(arr_uint64[0] == UINT64_C(7777777777777778));
ck_assert(arr_uint64[1] == UINT64_C(888888888888888889));
ck_assert_int_eq(len_double, 3);
ck_assert(arr_double[0] == 2.1);
ck_assert(arr_double[1] == 3.2);
ck_assert(arr_double[2] == 4.3);
ck_assert_int_eq(len_string, 2);
ck_assert_str_eq(arr_string[0], "beets");
ck_assert_str_eq(arr_string[1], "beets");
dbus_free_string_array(arr_string);
ck_assert_int_eq(len_object_path, 2);
ck_assert_str_eq(arr_object_path[0], "/changed");
ck_assert_str_eq(arr_object_path[1], "/changed");
dbus_free_string_array(arr_object_path);
dbus_message_unref (reply);
talloc_free(ctx);
}
END_TEST
static void parse_get_reply(DBusMessage *reply, const int type, void *val)
{
DBusMessageIter iter;
DBusMessageIter variter;
dbus_bool_t dbret;
dbret = dbus_message_iter_init(reply, &iter);
ck_assert(dbret == TRUE);
ck_assert_int_eq(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_VARIANT);
dbus_message_iter_recurse(&iter, &variter);
ck_assert_int_eq(dbus_message_iter_get_arg_type(&variter), type);
dbus_message_iter_get_basic(&variter, val);
}
static void call_get(DBusConnection *client,
const char *object_path,
const char *iface,
const char *prop,
int type,
void *val)
{
DBusMessage *reply;
DBusError error = DBUS_ERROR_INIT;
reply = test_dbus_call_sync(client,
object_path,
DBUS_PROPERTIES_INTERFACE,
"Get",
&error,
DBUS_TYPE_STRING, &iface,
DBUS_TYPE_STRING, &prop,
DBUS_TYPE_INVALID);
ck_assert(reply != NULL);
parse_get_reply(reply, type, val);
}
START_TEST(test_get_basic_types)
{
TALLOC_CTX *ctx;
DBusConnection *client;
dbus_bool_t bool_val;
const char *string_val;
const char *path_val;
uint8_t byte_val;
int16_t int16_val;
uint16_t uint16_val;
int32_t int32_val;
uint32_t uint32_val;
int64_t int64_val;
uint64_t uint64_val;
double double_val;
ctx = talloc_new(NULL);
ck_assert(ctx != NULL);
client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL);
ck_assert(client != NULL);
call_get(client, "/test/leela", test_pilot_meta.name, "boolean",
DBUS_TYPE_BOOLEAN, &bool_val);
ck_assert(bool_val == pilot_bool);
call_get(client, "/test/leela", test_pilot_meta.name, "FullName",
DBUS_TYPE_STRING, &string_val);
ck_assert_str_eq(string_val, pilot_full_name);
call_get(client, "/test/leela", test_pilot_meta.name, "byte",
DBUS_TYPE_BYTE, &byte_val);
ck_assert_int_eq(byte_val, pilot_byte);
call_get(client, "/test/leela", test_pilot_meta.name, "int16",
DBUS_TYPE_INT16, &int16_val);
ck_assert_int_eq(int16_val, pilot_int16);
call_get(client, "/test/leela", test_pilot_meta.name, "uint16",
DBUS_TYPE_UINT16, &uint16_val);
ck_assert_int_eq(uint16_val, pilot_uint16);
call_get(client, "/test/leela", test_pilot_meta.name, "int32",
DBUS_TYPE_INT32, &int32_val);
ck_assert_int_eq(int32_val, pilot_int32);
call_get(client, "/test/leela", test_pilot_meta.name, "uint32",
DBUS_TYPE_UINT32, &uint32_val);
ck_assert_int_eq(uint32_val, pilot_uint32);
call_get(client, "/test/leela", test_pilot_meta.name, "int64",
DBUS_TYPE_INT64, &int64_val);
ck_assert_int_eq(int64_val, pilot_int64);
call_get(client, "/test/leela", test_pilot_meta.name, "uint64",
DBUS_TYPE_UINT64, &uint64_val);
ck_assert_int_eq(uint64_val, pilot_uint64);
call_get(client, "/test/leela", test_pilot_meta.name, "double",
DBUS_TYPE_DOUBLE, &double_val);
ck_assert_int_eq(double_val, pilot_double);
call_get(client, "/test/leela", test_pilot_meta.name, "string",
DBUS_TYPE_STRING, &string_val);
ck_assert_str_eq(string_val, pilot_string);
call_get(client, "/test/leela", test_pilot_meta.name, "object_path",
DBUS_TYPE_OBJECT_PATH, &path_val);
ck_assert_str_eq(path_val, pilot_path);
/* If a string getter returns NULL, the caller should receive "" */
call_get(client, "/test/leela", test_pilot_meta.name, "null_string",
DBUS_TYPE_STRING, &string_val);
ck_assert_str_eq(string_val, "");
/* If a string getter returns NULL, the caller should receive "/" */
call_get(client, "/test/leela", test_pilot_meta.name, "null_path",
DBUS_TYPE_OBJECT_PATH, &path_val);
ck_assert_str_eq(path_val, "/");
talloc_free(ctx);
}
END_TEST
static void parse_get_array_reply(DBusMessage *reply, const int type,
void **values, int *nels)
{
DBusMessageIter iter;
DBusMessageIter variter;
DBusMessageIter arriter;
dbus_bool_t dbret;
dbret = dbus_message_iter_init(reply, &iter);
ck_assert(dbret == TRUE);
ck_assert_int_eq(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_VARIANT);
dbus_message_iter_recurse(&iter, &variter);
ck_assert_int_eq(dbus_message_iter_get_arg_type(&variter), DBUS_TYPE_ARRAY);
ck_assert_int_eq(dbus_message_iter_get_element_type(&variter), type);
dbus_message_iter_recurse(&variter, &arriter);
if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
int n = 0, i = 0;
const char **strings;
const char *s;
do {
n++;
} while (dbus_message_iter_next(&arriter));
/* Allocating on NULL is bad, but this is unit test */
strings = talloc_array(NULL, const char *, n);
ck_assert(strings != NULL);
dbus_message_iter_recurse(&variter, &arriter);
do {
dbus_message_iter_get_basic(&arriter, &s);
strings[i] = talloc_strdup(strings, s);
ck_assert(strings[i] != NULL);
i++;
} while (dbus_message_iter_next(&arriter));
*nels = n;
*values = strings;
} else {
/* Fixed types are easy */
dbus_message_iter_get_fixed_array(&arriter, values, nels);
}
}
static void call_get_array(DBusConnection *client,
const char *object_path,
const char *iface,
const char *prop,
int type,
void **values,
int *nels)
{
DBusMessage *reply;
DBusError error = DBUS_ERROR_INIT;
reply = test_dbus_call_sync(client,
object_path,
DBUS_PROPERTIES_INTERFACE,
"Get",
&error,
DBUS_TYPE_STRING, &iface,
DBUS_TYPE_STRING, &prop,
DBUS_TYPE_INVALID);
ck_assert(reply != NULL);
parse_get_array_reply(reply, type, values, nels);
}
#define _check_array(reply, len, known, fn) do { \
fn(len, 2); \
fn(reply[0], known[0]); \
fn(reply[1], known[1]); \
} while(0); \
#define check_int_array(reply, len, known) \
_check_array(reply, len, known, ck_assert_int_eq)
#define check_uint_array(reply, len, known) \
_check_array(reply, len, known, ck_assert_uint_eq)
START_TEST(test_get_basic_array_types)
{
TALLOC_CTX *ctx;
DBusConnection *client;
const char **string_arr_val;
int string_arr_len;
const char **path_arr_val;
int path_arr_len;
uint8_t *byte_arr_val;
int byte_arr_len;
int16_t *int16_arr_val;
int int16_arr_len;
uint16_t *uint16_arr_val;
int uint16_arr_len;
int32_t *int32_arr_val;
int int32_arr_len;
uint32_t *uint32_arr_val;
int uint32_arr_len;
int64_t *int64_arr_val;
int int64_arr_len;
uint64_t *uint64_arr_val;
int uint64_arr_len;
double *double_arr_val;
int double_arr_len;
ctx = talloc_new(NULL);
ck_assert(ctx != NULL);
client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL);
ck_assert(client != NULL);
call_get_array(client, "/test/leela", test_pilot_meta.name, "byte_array",
DBUS_TYPE_BYTE, (void **) &byte_arr_val, &byte_arr_len);
check_uint_array(byte_arr_val, byte_arr_len, pilot_byte_array);
call_get_array(client, "/test/leela", test_pilot_meta.name, "int16_array",
DBUS_TYPE_INT16, (void **) &int16_arr_val, &int16_arr_len);
check_int_array(int16_arr_val, int16_arr_len, pilot_int16_array);
call_get_array(client, "/test/leela", test_pilot_meta.name, "uint16_array",
DBUS_TYPE_UINT16, (void **) &uint16_arr_val, &uint16_arr_len);
check_uint_array(uint16_arr_val, uint16_arr_len, pilot_uint16_array);
call_get_array(client, "/test/leela", test_pilot_meta.name, "int32_array",
DBUS_TYPE_INT32, (void **) &int32_arr_val, &int32_arr_len);
check_int_array(int32_arr_val, int32_arr_len, pilot_int32_array);
call_get_array(client, "/test/leela", test_pilot_meta.name, "uint32_array",
DBUS_TYPE_UINT32, (void **) &uint32_arr_val, &uint32_arr_len);
check_uint_array(uint32_arr_val, uint32_arr_len, pilot_uint32_array);
call_get_array(client, "/test/leela", test_pilot_meta.name, "int64_array",
DBUS_TYPE_INT64, (void **) &int64_arr_val, &int64_arr_len);
check_int_array(int64_arr_val, int64_arr_len, pilot_int64_array);
call_get_array(client, "/test/leela", test_pilot_meta.name, "uint64_array",
DBUS_TYPE_UINT64, (void **) &uint64_arr_val, &uint64_arr_len);
check_uint_array(uint64_arr_val, uint64_arr_len, pilot_uint64_array);
call_get_array(client, "/test/leela", test_pilot_meta.name, "double_array",
DBUS_TYPE_DOUBLE, (void **) &double_arr_val, &double_arr_len);
check_int_array(double_arr_val, double_arr_len, pilot_double_array);
call_get_array(client, "/test/leela", test_pilot_meta.name, "string_array",
DBUS_TYPE_STRING, (void **) &string_arr_val, &string_arr_len);
ck_assert_int_eq(string_arr_len, 2);
ck_assert_str_eq(string_arr_val[0], pilot_string_array[0]);
ck_assert_str_eq(string_arr_val[1], pilot_string_array[1]);
call_get_array(client, "/test/leela", test_pilot_meta.name, "string_array",
DBUS_TYPE_STRING, (void **) &string_arr_val, &string_arr_len);
ck_assert_int_eq(string_arr_len, 2);
ck_assert_str_eq(string_arr_val[0], pilot_string_array[0]);
ck_assert_str_eq(string_arr_val[1], pilot_string_array[1]);
call_get_array(client, "/test/leela", test_pilot_meta.name, "object_path_array",
DBUS_TYPE_OBJECT_PATH, (void **) &path_arr_val, &path_arr_len);
ck_assert_int_eq(path_arr_len, 2);
ck_assert_str_eq(path_arr_val[0], pilot_path_array[0]);
ck_assert_str_eq(path_arr_val[1], pilot_path_array[1]);
talloc_free(ctx);
}
END_TEST
START_TEST(test_get_array_dict_sas)
{
TALLOC_CTX *ctx;
DBusConnection *client;
DBusMessage *reply;
DBusMessageIter it_variant;
DBusMessageIter it_array;
DBusMessageIter it_dict;
DBusMessageIter it_dict_entry;
DBusMessageIter it_values;
DBusError error = DBUS_ERROR_INIT;
const char *prop = "array_dict_sas";
dbus_bool_t dbret;
const char *value;
const char *hash_content[2][2] = {{"hello1", "world1"},
{"hello2", "world2"}};
const char **exp_values = NULL;
int i;
ctx = talloc_new(NULL);
ck_assert(ctx != NULL);
client = test_dbus_setup_mock(ctx, NULL, special_test_server_init, NULL);
ck_assert(client != NULL);
reply = test_dbus_call_sync(client,
"/test/special",
DBUS_PROPERTIES_INTERFACE,
"Get",
&error,
DBUS_TYPE_STRING, &test_special_meta.name,
DBUS_TYPE_STRING, &prop,
DBUS_TYPE_INVALID);
ck_assert(reply != NULL);
dbret = dbus_message_iter_init(reply, &it_variant);
ck_assert(dbret == TRUE);
ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_variant), DBUS_TYPE_VARIANT);
dbus_message_iter_recurse(&it_variant, &it_array);
/* array */
ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_array), DBUS_TYPE_ARRAY);
ck_assert_int_eq(dbus_message_iter_get_element_type(&it_array), DBUS_TYPE_DICT_ENTRY);
/* dict entry */
/* first item */
dbus_message_iter_recurse(&it_array, &it_dict);
for (i = 0; i < 2; i++) {
dbus_message_iter_recurse(&it_dict, &it_dict_entry);
ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_dict_entry), DBUS_TYPE_STRING);
dbus_message_iter_get_basic(&it_dict_entry, &value);
ck_assert(value != NULL);
if (strcmp(value, "key1") == 0) {
exp_values = hash_content[0];
} else if (strcmp(value, "key2") == 0) {
exp_values = hash_content[1];
} else {
ck_abort_msg("Invalid key! %s", value);
}
dbret = dbus_message_iter_next(&it_dict_entry);
ck_assert(dbret == TRUE);
ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_dict_entry), DBUS_TYPE_ARRAY);
ck_assert_int_eq(dbus_message_iter_get_element_type(&it_dict_entry), DBUS_TYPE_STRING);
dbus_message_iter_recurse(&it_dict_entry, &it_values);
dbus_message_iter_get_basic(&it_values, &value);
ck_assert(value != NULL);
ck_assert_str_eq(value, exp_values[0]);
dbret = dbus_message_iter_next(&it_values);
dbus_message_iter_get_basic(&it_values, &value);
ck_assert(value != NULL);
ck_assert_str_eq(value, exp_values[1]);
dbus_message_iter_next(&it_dict);
}
talloc_free(ctx);
}
END_TEST
struct prop_test {
const char *name;
bool handled;
int length;
int type;
union prop_value {
bool bool_val;
const char *string_val;
const char *path_val;
uint8_t byte_val;
int16_t int16_val;
uint16_t uint16_val;
int32_t int32_val;
uint32_t uint32_val;
int64_t int64_val;
uint64_t uint64_val;
double double_val;
const char **string_arr_val;
const char **path_arr_val;
uint8_t *byte_arr_val;
int16_t *int16_arr_val;
uint16_t *uint16_arr_val;
int32_t *int32_arr_val;
uint32_t *uint32_arr_val;
int64_t *int64_arr_val;
uint64_t *uint64_arr_val;
double *double_arr_val;
} value;
};
void check_prop(DBusMessageIter *variter, struct prop_test *p)
{
dbus_bool_t bool_val;
const char *string_val;
const char *path_val;
uint8_t byte_val;
int16_t int16_val;
uint16_t uint16_val;
int32_t int32_val;
uint32_t uint32_val;
int64_t int64_val;
uint64_t uint64_val;
double double_val;
int type;
type = dbus_message_iter_get_arg_type(variter);
/* No property should be returned twice */
ck_assert(p->handled == false);
ck_assert(p->type == type);
switch (p->type) {
case DBUS_TYPE_BOOLEAN:
dbus_message_iter_get_basic(variter, &bool_val);
ck_assert(bool_val == p->value.bool_val);
break;
case DBUS_TYPE_STRING:
dbus_message_iter_get_basic(variter, &string_val);
ck_assert_str_eq(string_val, p->value.string_val);
break;
case DBUS_TYPE_BYTE:
dbus_message_iter_get_basic(variter, &byte_val);
ck_assert_int_eq(byte_val, p->value.byte_val);
break;
case DBUS_TYPE_INT16:
dbus_message_iter_get_basic(variter, &int16_val);
ck_assert_int_eq(int16_val, p->value.int16_val);
break;
case DBUS_TYPE_UINT16:
dbus_message_iter_get_basic(variter, &uint16_val);
ck_assert_int_eq(uint16_val, p->value.uint16_val);
break;
case DBUS_TYPE_INT32:
dbus_message_iter_get_basic(variter, &int32_val);
ck_assert_int_eq(int32_val, p->value.int32_val);
break;
case DBUS_TYPE_UINT32:
dbus_message_iter_get_basic(variter, &uint32_val);
ck_assert_int_eq(uint32_val, p->value.uint32_val);
break;
case DBUS_TYPE_INT64:
dbus_message_iter_get_basic(variter, &int64_val);
ck_assert_int_eq(int64_val, p->value.int64_val);
break;
case DBUS_TYPE_UINT64:
dbus_message_iter_get_basic(variter, &uint64_val);
ck_assert_int_eq(uint64_val, p->value.uint64_val);
break;
case DBUS_TYPE_DOUBLE:
dbus_message_iter_get_basic(variter, &double_val);
ck_assert_int_eq(double_val, p->value.double_val);
break;
case DBUS_TYPE_OBJECT_PATH:
dbus_message_iter_get_basic(variter, &path_val);
ck_assert_str_eq(path_val, p->value.path_val);
break;
default:
/* Not handled */
return;
}
/* This attribute was handled, get the next one */
p->handled = true;
}
void check_arr_prop(DBusMessageIter *variter, struct prop_test *p)
{
DBusMessageIter arriter;
const char **strings = NULL;
uint8_t *byte_arr_val;
int16_t *int16_arr_val;
uint16_t *uint16_arr_val;
int32_t *int32_arr_val;
uint32_t *uint32_arr_val;
int64_t *int64_arr_val;
uint64_t *uint64_arr_val;
double *double_arr_val;
int len;
int type;
ck_assert_int_eq(dbus_message_iter_get_arg_type(variter), DBUS_TYPE_ARRAY);
type = dbus_message_iter_get_element_type(variter);
ck_assert_int_eq(type, p->type);
dbus_message_iter_recurse(variter, &arriter);
if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
int n = 0, i = 0;
const char *s;
do {
n++;
} while (dbus_message_iter_next(&arriter));
/* Allocating on NULL is bad, but this is unit test */
strings = talloc_array(NULL, const char *, n);
ck_assert(strings != NULL);
dbus_message_iter_recurse(variter, &arriter);
do {
dbus_message_iter_get_basic(&arriter, &s);
strings[i] = talloc_strdup(strings, s);
ck_assert(strings[i] != NULL);
i++;
} while (dbus_message_iter_next(&arriter));
len = n;
}
switch (p->type) {
case DBUS_TYPE_STRING:
ck_assert_int_eq(len, 2);
ck_assert(strings != NULL);
ck_assert_str_eq(strings[0], pilot_string_array[0]);
ck_assert_str_eq(strings[1], pilot_string_array[1]);
break;
case DBUS_TYPE_BYTE:
dbus_message_iter_get_fixed_array(&arriter, &byte_arr_val, &len);
check_uint_array(byte_arr_val, len, p->value.byte_arr_val);
break;
case DBUS_TYPE_INT16:
dbus_message_iter_get_fixed_array(&arriter, &int16_arr_val, &len);
check_int_array(int16_arr_val, len, p->value.int16_arr_val);
break;
case DBUS_TYPE_UINT16:
dbus_message_iter_get_fixed_array(&arriter, &uint16_arr_val, &len);
check_uint_array(uint16_arr_val, len, p->value.uint16_arr_val);
break;
case DBUS_TYPE_INT32:
dbus_message_iter_get_fixed_array(&arriter, &int32_arr_val, &len);
check_int_array(int32_arr_val, len, p->value.int32_arr_val);
break;
case DBUS_TYPE_UINT32:
dbus_message_iter_get_fixed_array(&arriter, &uint32_arr_val, &len);
check_uint_array(uint32_arr_val, len, p->value.uint32_arr_val);
break;
case DBUS_TYPE_INT64:
dbus_message_iter_get_fixed_array(&arriter, &int64_arr_val, &len);
check_int_array(int64_arr_val, len, p->value.int64_arr_val);
break;
case DBUS_TYPE_UINT64:
dbus_message_iter_get_fixed_array(&arriter, &uint64_arr_val, &len);
check_uint_array(uint64_arr_val, len, p->value.uint64_arr_val);
break;
case DBUS_TYPE_DOUBLE:
dbus_message_iter_get_fixed_array(&arriter, &double_arr_val, &len);
check_int_array(double_arr_val, len, p->value.double_arr_val);
break;
case DBUS_TYPE_OBJECT_PATH:
ck_assert_int_eq(len, 2);
ck_assert(strings != NULL);
ck_assert_str_eq(strings[0], pilot_path_array[0]);
ck_assert_str_eq(strings[1], pilot_path_array[1]);
break;
default:
/* Not handled */
return;
}
p->handled = true;
}
START_TEST(test_getall_basic_types)
{
DBusMessage *reply;
DBusMessageIter iter;
DBusMessageIter arriter;
DBusMessageIter dictiter;
DBusMessageIter variter;
dbus_bool_t dbret;
DBusError error = DBUS_ERROR_INIT;
TALLOC_CTX *ctx;
DBusConnection *client;
char *attr_name;
int i;
int num_prop;
struct prop_test pilot_properties[] = {
{ "boolean", false, 0, DBUS_TYPE_BOOLEAN, { .bool_val = pilot_bool } },
{ "FullName", false, 0, DBUS_TYPE_STRING, { .string_val = pilot_full_name } },
{ "byte", false, 0, DBUS_TYPE_BYTE, { .byte_val = pilot_byte } },
{ "int16", false, 0, DBUS_TYPE_INT16, { .int16_val = pilot_int16 } },
{ "uint16", false, 0, DBUS_TYPE_UINT16, { .uint16_val = pilot_uint16 } },
{ "int32", false, 0, DBUS_TYPE_INT32, { .int32_val = pilot_int32 } },
{ "uint32", false, 0, DBUS_TYPE_UINT32, { .uint32_val = pilot_uint32 } },
{ "int64", false, 0, DBUS_TYPE_INT64, { .int64_val = pilot_int64 } },
{ "uint64", false, 0, DBUS_TYPE_UINT64, { .uint64_val = pilot_uint64 } },
{ "double", false, 0, DBUS_TYPE_DOUBLE, { .double_val = pilot_double } },
{ "string", false, 0, DBUS_TYPE_STRING, { .string_val = pilot_string } },
{ "object_path", false, 0, DBUS_TYPE_OBJECT_PATH, { .path_val = pilot_path } },
{ "null_string", false, 0, DBUS_TYPE_STRING, { .string_val = "" } },
{ "null_path", false, 0, DBUS_TYPE_OBJECT_PATH, { .path_val = "/" } },
{ "byte_array", false, N_ELEMENTS(pilot_byte_array), DBUS_TYPE_BYTE, { .byte_arr_val = pilot_byte_array } },
{ "int16_array", false, N_ELEMENTS(pilot_int16_array), DBUS_TYPE_INT16, { .int16_arr_val = pilot_int16_array } },
{ "uint16_array", false, N_ELEMENTS(pilot_uint16_array), DBUS_TYPE_UINT16, { .uint16_arr_val = pilot_uint16_array } },
{ "int32_array", false, N_ELEMENTS(pilot_int32_array), DBUS_TYPE_INT32, { .int32_arr_val = pilot_int32_array } },
{ "uint32_array", false, N_ELEMENTS(pilot_uint32_array), DBUS_TYPE_UINT32, { .uint32_arr_val = pilot_uint32_array } },
{ "int64_array", false, N_ELEMENTS(pilot_int64_array), DBUS_TYPE_INT64, { .int64_arr_val = pilot_int64_array } },
{ "uint64_array", false, N_ELEMENTS(pilot_uint64_array), DBUS_TYPE_UINT64, { .uint64_arr_val = pilot_uint64_array } },
{ "double_array", false, N_ELEMENTS(pilot_double_array), DBUS_TYPE_DOUBLE, { .double_arr_val = pilot_double_array } },
{ "string_array", false, N_ELEMENTS(pilot_string_array), DBUS_TYPE_STRING, { .string_arr_val = pilot_string_array } },
{ "object_path_array", false, N_ELEMENTS(pilot_path_array), DBUS_TYPE_OBJECT_PATH, { .path_arr_val = pilot_path_array } },
{ NULL, false, 0, 0, { .bool_val = false } }};
ctx = talloc_new(NULL);
ck_assert(ctx != NULL);
client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL);
ck_assert(client != NULL);
reply = test_dbus_call_sync(client,
"/test/leela",
DBUS_PROPERTIES_INTERFACE,
"GetAll",
&error,
DBUS_TYPE_STRING,
&test_pilot_meta.name,
DBUS_TYPE_INVALID);
ck_assert(reply != NULL);
/* GetAll reply is an array of dictionaries */
dbret = dbus_message_iter_init(reply, &iter);
ck_assert(dbret == TRUE);
ck_assert_int_eq(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_ARRAY);
dbus_message_iter_recurse(&iter, &arriter);
num_prop = 0;
do {
ck_assert_int_eq(dbus_message_iter_get_arg_type(&arriter),
DBUS_TYPE_DICT_ENTRY);
dbus_message_iter_recurse(&arriter, &dictiter);
dbus_message_iter_get_basic(&dictiter, &attr_name);
ck_assert(dbus_message_iter_next(&dictiter) == TRUE);
ck_assert_int_eq(dbus_message_iter_get_arg_type(&dictiter),
DBUS_TYPE_VARIANT);
dbus_message_iter_recurse(&dictiter, &variter);
for (i=0; pilot_properties[i].name; i++) {
if (strcmp(attr_name, pilot_properties[i].name) == 0) {
if (dbus_message_iter_get_arg_type(&variter) == DBUS_TYPE_ARRAY) {
check_arr_prop(&variter, &pilot_properties[i]);
} else {
check_prop(&variter, &pilot_properties[i]);
}
break;
}
}
num_prop++;
} while(dbus_message_iter_next(&arriter));
/* All known properties must be handled now */
for (i=0; pilot_properties[i].name; i++) {
ck_assert(pilot_properties[i].handled == true);
}
/* Also all properties returned from the bus must be accounted for */
ck_assert_uint_eq(num_prop, N_ELEMENTS(pilot_properties)-1);
talloc_free(ctx);
}
END_TEST
TCase *create_handler_tests(void)
{
TCase *tc = tcase_create("handler");
tcase_add_test(tc, test_marshal_basic_types);
tcase_add_test(tc, test_get_basic_types);
tcase_add_test(tc, test_getall_basic_types);
tcase_add_test(tc, test_get_basic_array_types);
tcase_add_test(tc, test_get_array_dict_sas);
return tc;
}
Suite *create_suite(void)
{
Suite *s = suite_create("sbus_codegen");
suite_add_tcase(s, create_defs_tests ());
suite_add_tcase(s, create_handler_tests ());
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);
/* 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);
}