LCOV - code coverage report
Current view: top level - tests - sbus_codegen_tests.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 482 666 72.4 %
Date: 2015-10-19 Functions: 22 53 41.5 %

          Line data    Source code
       1             : /*
       2             :    SSSD
       3             : 
       4             :    sbus_codegen tests.
       5             : 
       6             :    Authors:
       7             :         Stef Walter <stefw@redhat.com>
       8             : 
       9             :    Copyright (C) Red Hat, Inc 2014
      10             : 
      11             :    This program is free software; you can redistribute it and/or modify
      12             :    it under the terms of the GNU General Public License as published by
      13             :    the Free Software Foundation; either version 3 of the License, or
      14             :    (at your option) any later version.
      15             : 
      16             :    This program is distributed in the hope that it will be useful,
      17             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :    GNU General Public License for more details.
      20             : 
      21             :    You should have received a copy of the GNU General Public License
      22             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include <stdlib.h>
      26             : #include <check.h>
      27             : #include <talloc.h>
      28             : #include <tevent.h>
      29             : #include <popt.h>
      30             : 
      31             : #include "sbus/sssd_dbus_meta.h"
      32             : #include "tests/common.h"
      33             : #include "tests/sbus_codegen_tests_generated.h"
      34             : #include "util/util_errors.h"
      35             : 
      36             : /* The following 2 macros were taken from check's project source files (0.9.10)
      37             :  * http://check.sourceforge.net/
      38             :  */
      39             : #ifndef _ck_assert_uint
      40             : #define _ck_assert_uint(X, OP, Y) do { \
      41             :     uintmax_t _ck_x = (X); \
      42             :     uintmax_t _ck_y = (Y); \
      43             :     ck_assert_msg(_ck_x OP _ck_y, "Assertion '"#X#OP#Y"' failed: "#X"==%ju, "#Y"==%ju", _ck_x, _ck_y); \
      44             : } while (0)
      45             : #endif /* _ck_assert_uint */
      46             : 
      47             : #ifndef ck_assert_uint_eq
      48             : #define ck_assert_uint_eq(X, Y) _ck_assert_uint(X, ==, Y)
      49             : #endif /* ck_assert_uint_eq */
      50             : 
      51             : static const struct sbus_arg_meta *
      52           3 : find_arg(const struct sbus_arg_meta *args,
      53             :          const char *name)
      54             : {
      55             :     const struct sbus_arg_meta *arg;
      56           3 :     for (arg = args; arg->name != NULL; arg++) {
      57           3 :         if (strcmp (arg->name, name) == 0)
      58           3 :             return arg;
      59             :     }
      60             : 
      61           0 :     return NULL;
      62             : }
      63             : 
      64           1 : START_TEST(test_interfaces)
      65             : {
      66           1 :     ck_assert_str_eq(com_planetexpress_Ship_meta.name, "com.planetexpress.Ship");
      67           1 :     ck_assert(com_planetexpress_Ship_meta.methods != NULL);
      68           1 :     ck_assert(com_planetexpress_Ship_meta.signals != NULL);
      69           1 :     ck_assert(com_planetexpress_Ship_meta.properties != NULL);
      70             : 
      71             :     /* Explicit C Symbol */
      72           1 :     ck_assert_str_eq(test_pilot_meta.name, "com.planetexpress.Pilot");
      73           1 :     ck_assert(test_pilot_meta.methods != NULL);
      74           1 :     ck_assert(test_pilot_meta.signals == NULL); /* no signals */
      75           1 :     ck_assert(test_pilot_meta.properties != NULL);
      76             : 
      77             : }
      78           1 : END_TEST
      79             : 
      80           1 : START_TEST(test_methods)
      81             : {
      82             :     const struct sbus_method_meta *method;
      83             :     const struct sbus_arg_meta *arg;
      84             : 
      85           1 :     method = sbus_meta_find_method(&com_planetexpress_Ship_meta, "MoveUniverse");
      86           1 :     ck_assert(method != NULL);
      87           1 :     ck_assert_str_eq(method->name, "MoveUniverse");
      88           1 :     ck_assert(method->in_args != NULL);
      89           1 :     ck_assert(method->out_args != NULL);
      90             : 
      91           1 :     arg = find_arg(method->in_args, "smoothly");
      92           1 :     ck_assert(arg != NULL);
      93           1 :     ck_assert_str_eq(arg->name, "smoothly");
      94           1 :     ck_assert_str_eq(arg->type, "b");
      95             : 
      96           1 :     arg = find_arg(method->out_args, "where_we_crashed");
      97           1 :     ck_assert(arg != NULL);
      98           1 :     ck_assert_str_eq(arg->name, "where_we_crashed");
      99           1 :     ck_assert_str_eq(arg->type, "s");
     100             : }
     101           1 : END_TEST
     102             : 
     103           1 : START_TEST(test_properties)
     104             : {
     105             :     const struct sbus_property_meta *prop;
     106             : 
     107           1 :     prop = sbus_meta_find_property(&com_planetexpress_Ship_meta, "Color");
     108           1 :     ck_assert(prop != NULL);
     109           1 :     ck_assert_str_eq(prop->name, "Color");
     110           1 :     ck_assert_str_eq(prop->type, "s");
     111           1 :     ck_assert_int_eq(prop->flags, SBUS_PROPERTY_READABLE);
     112             : }
     113           1 : END_TEST
     114             : 
     115           1 : START_TEST(test_signals)
     116             : {
     117             :     const struct sbus_signal_meta *signal;
     118             :     const struct sbus_arg_meta *arg;
     119             : 
     120           1 :     signal = sbus_meta_find_signal(&com_planetexpress_Ship_meta, "BecameSentient");
     121           1 :     ck_assert(signal != NULL);
     122           1 :     ck_assert_str_eq(signal->name, "BecameSentient");
     123           1 :     ck_assert(signal->args != NULL);
     124             : 
     125           1 :     arg = find_arg(signal->args, "gender");
     126           1 :     ck_assert(arg != NULL);
     127           1 :     ck_assert_str_eq(arg->name, "gender");
     128           1 :     ck_assert_str_eq(arg->type, "s");
     129             : }
     130           1 : END_TEST
     131             : 
     132             : static int
     133           0 : mock_move_universe(struct sbus_request *dbus_req, void *data,
     134             :                    bool arg_smoothly, uint32_t arg_speed_factor)
     135             : {
     136             :     /*
     137             :      * The above arguments should match the handler signature,
     138             :      * and the below finish function should have the right signature.
     139             :      *
     140             :      * Not called, just testing compilation
     141             :      */
     142           0 :     ck_assert(FALSE);
     143             :     return com_planetexpress_Ship_MoveUniverse_finish(dbus_req, "here");
     144             : }
     145             : 
     146             : static int
     147           0 : mock_crash_now(struct sbus_request *dbus_req, void *data,
     148             :                const char *where)
     149             : {
     150             :     /*
     151             :      * One argument, no return value, yet a finish function should
     152             :      * have been generated.
     153             :      *
     154             :      * Not called, just testing compilation
     155             :      */
     156           0 :     ck_assert(FALSE);
     157             :     return com_planetexpress_Ship_crash_now_finish(dbus_req);
     158             : }
     159             : 
     160             : static int
     161           0 : mock_land(struct sbus_request *req, void *data)
     162             : {
     163             :     /*
     164             :      * Raw handler, no finish function, no special arguments.
     165             :      *
     166             :      * Not called, just testing compilation
     167             :      */
     168           0 :     ck_assert(FALSE);
     169             :     return 0;
     170             : }
     171             : 
     172           1 : START_TEST(test_vtable)
     173             : {
     174           1 :     struct com_planetexpress_Ship vtable = {
     175             :         { &com_planetexpress_Ship_meta, 0 },
     176             :         mock_move_universe,
     177             :         mock_crash_now,
     178             :         mock_land,
     179             :         NULL,
     180             :     };
     181             : 
     182             :     /*
     183             :      * These are not silly tests:
     184             :      * - Will fail compilation if c-symbol name was not respected
     185             :      * - Will fail if method order was not respected
     186             :      */
     187           1 :     ck_assert(vtable.crash_now == mock_crash_now);
     188           1 :     ck_assert(vtable.MoveUniverse == mock_move_universe);
     189           1 :     ck_assert(vtable.Land == mock_land);
     190             : }
     191           1 : END_TEST
     192             : 
     193           1 : START_TEST(test_constants)
     194             : {
     195           1 :     ck_assert_str_eq(COM_PLANETEXPRESS_SHIP, "com.planetexpress.Ship");
     196           1 :     ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_MOVEUNIVERSE, "MoveUniverse");
     197           1 :     ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_CRASH_NOW, "Crash");
     198           1 :     ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_BECAMESENTIENT, "BecameSentient");
     199           1 :     ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_COLOR, "Color");
     200             : 
     201             :     /* constants for com.planetexpress.Pilot */
     202           1 :     ck_assert_str_eq(TEST_PILOT, "com.planetexpress.Pilot");
     203           1 :     ck_assert_str_eq(TEST_PILOT_FULLNAME, "FullName");
     204             : }
     205           1 : END_TEST
     206             : 
     207           1 : TCase *create_defs_tests(void)
     208             : {
     209           1 :     TCase *tc = tcase_create("defs");
     210             : 
     211             :     /* Do some testing */
     212           1 :     tcase_add_test(tc, test_interfaces);
     213           1 :     tcase_add_test(tc, test_methods);
     214           1 :     tcase_add_test(tc, test_properties);
     215           1 :     tcase_add_test(tc, test_signals);
     216           1 :     tcase_add_test(tc, test_vtable);
     217           1 :     tcase_add_test(tc, test_constants);
     218             : 
     219           1 :     return tc;
     220             : }
     221             : 
     222             : /* This is a handler which has all the basic arguments types */
     223           0 : static int eject_handler(struct sbus_request *req, void *instance_data,
     224             :                          uint8_t arg_byte, bool arg_boolean,
     225             :                          int16_t arg_int16, uint16_t arg_uint16, int32_t arg_int32,
     226             :                          uint32_t arg_uint32, int64_t arg_int64, uint64_t arg_uint64,
     227             :                          double arg_double, const char *arg_string, const char *arg_object_path,
     228             :                          uint8_t arg_byte_array[], int len_byte_array,
     229             :                          int16_t arg_int16_array[], int len_int16_array,
     230             :                          uint16_t arg_uint16_array[], int len_uint16_array,
     231             :                          int32_t arg_int32_array[], int len_int32_array,
     232             :                          uint32_t arg_uint32_array[], int len_uint32_array,
     233             :                          int64_t arg_int64_array[], int len_int64_array,
     234             :                          uint64_t arg_uint64_array[], int len_uint64_array,
     235             :                          double arg_double_array[], int len_double_array,
     236             :                          const char *arg_string_array[], int len_string_array,
     237             :                          const char *arg_object_path_array[], int len_object_path_array)
     238             : {
     239             :     int i;
     240             : 
     241             :     /* Only called for leela, so double check here */
     242           0 :     ck_assert_str_eq(instance_data, "Crash into the billboard");
     243             : 
     244             :     /* Murge the various values for test case */
     245           0 :     ck_assert_uint_eq(arg_byte, 11);
     246           0 :     arg_byte++;
     247           0 :     ck_assert(arg_boolean == TRUE);
     248           0 :     arg_boolean = !arg_boolean;
     249           0 :     ck_assert_int_eq(arg_int16, -2222);
     250           0 :     arg_int16++;
     251           0 :     ck_assert_uint_eq(arg_uint16, 3333);
     252           0 :     arg_uint16++;
     253           0 :     ck_assert_int_eq(arg_int32, -44444444);
     254           0 :     arg_int32++;
     255           0 :     ck_assert_uint_eq(arg_uint32, 55555555);
     256           0 :     arg_uint32++;
     257           0 :     ck_assert(arg_int64 == -6666666666666666);
     258           0 :     arg_int64++;
     259           0 :     ck_assert(arg_uint64 == 7777777777777777);
     260           0 :     arg_uint64++;
     261           0 :     ck_assert(arg_double == 1.1);
     262           0 :     arg_double++;
     263             : 
     264           0 :     ck_assert_str_eq(arg_string, "hello");
     265           0 :     arg_string = "bears, beets, battlestar galactica";
     266           0 :     ck_assert_str_eq(arg_object_path, "/original/object/path");
     267           0 :     arg_object_path = "/another/object/path";
     268             : 
     269           0 :     arg_byte_array = talloc_memdup(req, arg_byte_array, sizeof(uint8_t) * len_byte_array);
     270           0 :     for (i = 0; i < len_byte_array; i++)
     271           0 :         arg_byte_array[i]++;
     272             : 
     273           0 :     arg_int16_array = talloc_memdup(req, arg_int16_array, sizeof(int16_t) * len_int16_array);
     274           0 :     for (i = 0; i < len_int16_array; i++)
     275           0 :         arg_int16_array[i]++;
     276           0 :     len_int16_array--;
     277             : 
     278           0 :     arg_uint16_array = talloc_memdup(req, arg_uint16_array, sizeof(uint16_t) * len_uint16_array);
     279           0 :     for (i = 0; i < len_uint16_array; i++)
     280           0 :         arg_uint16_array[i]++;
     281             : 
     282           0 :     arg_int32_array = talloc_memdup(req, arg_int32_array, sizeof(int32_t) * len_int32_array);
     283           0 :     for (i = 0; i < len_int32_array; i++)
     284           0 :         arg_int32_array[i]++;
     285           0 :     len_int32_array--;
     286             : 
     287           0 :     arg_uint32_array = talloc_memdup(req, arg_uint32_array, sizeof(uint32_t) * len_uint32_array);
     288           0 :     for (i = 0; i < len_uint32_array; i++)
     289           0 :         arg_uint32_array[i]++;
     290             : 
     291           0 :     arg_int64_array = talloc_memdup(req, arg_int64_array, sizeof(int64_t) * len_int64_array);
     292           0 :     for (i = 0; i < len_int64_array; i++)
     293           0 :         arg_int64_array[i]++;
     294             : 
     295           0 :     arg_uint64_array = talloc_memdup(req, arg_uint64_array, sizeof(uint64_t) * len_uint64_array);
     296           0 :     for (i = 0; i < len_uint64_array; i++)
     297           0 :         arg_uint64_array[i]++;
     298             : 
     299           0 :     arg_double_array = talloc_memdup(req, arg_double_array, sizeof(double) * len_double_array);
     300           0 :     for (i = 0; i < len_double_array; i++)
     301           0 :         arg_double_array[i]++;
     302             : 
     303           0 :     arg_string_array = talloc_memdup(req, arg_string_array, sizeof(char *) * len_string_array);
     304           0 :     for (i = 0; i < len_double_array; i++) {
     305           0 :         ck_assert_str_eq(arg_string_array[i], "bears");
     306           0 :         arg_string_array[i] = "beets";
     307             :     }
     308           0 :     len_string_array--;
     309             : 
     310           0 :     arg_object_path_array = talloc_memdup(req, arg_object_path_array, sizeof(char *) * len_object_path_array);
     311           0 :     for (i = 0; i < len_object_path_array; i++) {
     312           0 :         ck_assert_str_eq(arg_object_path_array[i], "/original");
     313           0 :         arg_object_path_array[i] = "/changed";
     314             :     }
     315             : 
     316             :     /* And reply with those values */
     317           0 :     return test_pilot_Eject_finish(req, arg_byte, arg_boolean, arg_int16,
     318             :                                    arg_uint16, arg_int32, arg_uint32,
     319             :                                    arg_int64, arg_uint64, arg_double,
     320             :                                    arg_string, arg_object_path,
     321             :                                    arg_byte_array, len_byte_array,
     322             :                                    arg_int16_array, len_int16_array,
     323             :                                    arg_uint16_array, len_uint16_array,
     324             :                                    arg_int32_array, len_int32_array,
     325             :                                    arg_uint32_array, len_uint32_array,
     326             :                                    arg_int64_array, len_int64_array,
     327             :                                    arg_uint64_array, len_uint64_array,
     328             :                                    arg_double_array, len_double_array,
     329             :                                    arg_string_array, len_string_array,
     330             :                                    arg_object_path_array, len_object_path_array);
     331             : }
     332             : 
     333             : #define getter_body(in, out) do {           \
     334             :     ck_assert(dbus_req != NULL);            \
     335             :     ck_assert(out != NULL);                 \
     336             :     *out = in;                              \
     337             : } while(0);
     338             : 
     339             : static const bool pilot_bool = true;
     340           0 : void pilot_get_boolean_handler(struct sbus_request *dbus_req,
     341             :                                void *instance_data,
     342             :                                bool *val)
     343             : {
     344           0 :     getter_body(pilot_bool, val);
     345           0 : }
     346             : 
     347             : static const char *pilot_full_name = "Turanga Leela";
     348           0 : void pilot_get_full_name_handler(struct sbus_request *dbus_req,
     349             :                                  void *instance_data,
     350             :                                  const char **name)
     351             : {
     352           0 :     getter_body(pilot_full_name, name);
     353           0 : }
     354             : 
     355             : static const uint8_t pilot_byte = 42;
     356           0 : void pilot_get_byte_handler(struct sbus_request *dbus_req,
     357             :                             void *instance_data,
     358             :                             uint8_t *byte)
     359             : {
     360           0 :     getter_body(pilot_byte, byte);
     361           0 : }
     362             : 
     363             : static const int16_t pilot_int16 = -123;
     364           0 : void pilot_get_int16_handler(struct sbus_request *dbus_req,
     365             :                              void *instance_data,
     366             :                              int16_t *int16)
     367             : {
     368           0 :     getter_body(pilot_int16, int16);
     369           0 : }
     370             : 
     371             : static const uint16_t pilot_uint16 = 123;
     372           0 : void pilot_get_uint16_handler(struct sbus_request *dbus_req,
     373             :                               void *instance_data,
     374             :                               uint16_t *uint16)
     375             : {
     376           0 :     getter_body(pilot_uint16, uint16);
     377           0 : }
     378             : 
     379             : static const int32_t pilot_int32 = -456;
     380           0 : void pilot_get_int32_handler(struct sbus_request *dbus_req,
     381             :                              void *instance_data,
     382             :                              int32_t *int32)
     383             : {
     384           0 :     getter_body(pilot_int32, int32);
     385           0 : }
     386             : 
     387             : static const uint32_t pilot_uint32 = 456;
     388           0 : void pilot_get_uint32_handler(struct sbus_request *dbus_req,
     389             :                               void *instance_data,
     390             :                               uint32_t *uint32)
     391             : {
     392           0 :     getter_body(pilot_uint32, uint32);
     393           0 : }
     394             : 
     395             : static const int64_t pilot_int64 = -456;
     396           0 : void pilot_get_int64_handler(struct sbus_request *dbus_req,
     397             :                              void *instance_data,
     398             :                              int64_t *int64)
     399             : {
     400           0 :     getter_body(pilot_int64, int64);
     401           0 : }
     402             : 
     403             : static const uint64_t pilot_uint64 = 456;
     404           0 : void pilot_get_uint64_handler(struct sbus_request *dbus_req,
     405             :                               void *instance_data,
     406             :                               uint64_t *uint64)
     407             : {
     408           0 :     getter_body(pilot_uint64, uint64);
     409           0 : }
     410             : 
     411             : static const double pilot_double = 3.14;
     412           0 : void pilot_get_double_handler(struct sbus_request *dbus_req,
     413             :                               void *instance_data,
     414             :                               double *double_val)
     415             : {
     416           0 :     getter_body(pilot_double, double_val);
     417           0 : }
     418             : 
     419             : static const char *pilot_string = "leela";
     420           0 : void pilot_get_string_handler(struct sbus_request *dbus_req,
     421             :                               void *instance_data,
     422             :                               const char **string_val)
     423             : {
     424           0 :     *string_val = pilot_string;
     425           0 : }
     426             : 
     427             : static const char *pilot_path = "/path/leela";
     428           0 : void pilot_get_objpath_handler(struct sbus_request *dbus_req,
     429             :                               void *instance_data,
     430             :                               const char **path_val)
     431             : {
     432           0 :     *path_val = pilot_path;
     433           0 : }
     434             : 
     435           0 : void pilot_get_null_string_handler(struct sbus_request *dbus_req,
     436             :                                    void *instance_data,
     437             :                                    const char **string_val)
     438             : {
     439           0 :     *string_val = NULL;
     440           0 : }
     441             : 
     442           0 : void pilot_get_null_path_handler(struct sbus_request *dbus_req,
     443             :                                  void *instance_data,
     444             :                                  const char **path_val)
     445             : {
     446           0 :     *path_val = NULL;
     447           0 : }
     448             : 
     449             : #define array_getter_body(in, out, outlen) do {     \
     450             :     ck_assert(dbus_req != NULL);                    \
     451             :     ck_assert(out != NULL);                         \
     452             :     ck_assert(outlen != NULL);                      \
     453             :     *out = in;                                      \
     454             :     *outlen = N_ELEMENTS(in);                       \
     455             : } while(0);
     456             : 
     457             : static uint8_t pilot_byte_array[] = { 42, 0 };
     458           0 : void pilot_get_byte_array_handler(struct sbus_request *dbus_req,
     459             :                                   void *instance_data,
     460             :                                   uint8_t **arr_out, int *arr_len)
     461             : {
     462           0 :     array_getter_body(pilot_byte_array, arr_out, arr_len);
     463           0 : }
     464             : 
     465             : static int16_t pilot_int16_array[] = { -123, 0 };
     466           0 : void pilot_get_int16_array_handler(struct sbus_request *dbus_req,
     467             :                                   void *instance_data,
     468             :                                   int16_t **arr_out, int *arr_len)
     469             : {
     470           0 :     array_getter_body(pilot_int16_array, arr_out, arr_len);
     471           0 : }
     472             : 
     473             : static uint16_t pilot_uint16_array[] = { 123, 0 };
     474           0 : void pilot_get_uint16_array_handler(struct sbus_request *dbus_req,
     475             :                                   void *instance_data,
     476             :                                   uint16_t **arr_out, int *arr_len)
     477             : {
     478           0 :     array_getter_body(pilot_uint16_array, arr_out, arr_len);
     479           0 : }
     480             : 
     481             : static int32_t pilot_int32_array[] = { -456, 0 };
     482           0 : void pilot_get_int32_array_handler(struct sbus_request *dbus_req,
     483             :                                   void *instance_data,
     484             :                                   int32_t **arr_out, int *arr_len)
     485             : {
     486           0 :     array_getter_body(pilot_int32_array, arr_out, arr_len);
     487           0 : }
     488             : 
     489             : static uint32_t pilot_uint32_array[] = { 456, 0 };
     490           0 : void pilot_get_uint32_array_handler(struct sbus_request *dbus_req,
     491             :                                   void *instance_data,
     492             :                                   uint32_t **arr_out, int *arr_len)
     493             : {
     494           0 :     array_getter_body(pilot_uint32_array, arr_out, arr_len);
     495           0 : }
     496             : 
     497             : static int64_t pilot_int64_array[] = { -789, 0 };
     498           0 : void pilot_get_int64_array_handler(struct sbus_request *dbus_req,
     499             :                                   void *instance_data,
     500             :                                   int64_t **arr_out, int *arr_len)
     501             : {
     502           0 :     array_getter_body(pilot_int64_array, arr_out, arr_len);
     503           0 : }
     504             : 
     505             : static uint64_t pilot_uint64_array[] = { 789, 0 };
     506           0 : void pilot_get_uint64_array_handler(struct sbus_request *dbus_req,
     507             :                                   void *instance_data,
     508             :                                   uint64_t **arr_out, int *arr_len)
     509             : {
     510           0 :     array_getter_body(pilot_uint64_array, arr_out, arr_len);
     511           0 : }
     512             : 
     513             : static double pilot_double_array[] = { 3.14, 0 };
     514           0 : void pilot_get_double_array_handler(struct sbus_request *dbus_req,
     515             :                                     void *instance_data,
     516             :                                     double **arr_out, int *arr_len)
     517             : {
     518           0 :     array_getter_body(pilot_double_array, arr_out, arr_len);
     519           0 : }
     520             : 
     521             : static const char *pilot_string_array[] = { "Turanga", "Leela" };
     522           0 : void pilot_get_string_array_handler(struct sbus_request *dbus_req,
     523             :                                     void *data,
     524             :                                     const char ***arr_out,
     525             :                                     int *arr_len)
     526             : {
     527           0 :     array_getter_body(pilot_string_array, arr_out, arr_len);
     528           0 : }
     529             : 
     530             : static const char *pilot_path_array[] = { "/some/path", "/another/path" };
     531           0 : void pilot_get_path_array_handler(struct sbus_request *dbus_req,
     532             :                                     void *data,
     533             :                                     const char ***arr_out,
     534             :                                     int *arr_len)
     535             : {
     536           0 :     array_getter_body(pilot_path_array, arr_out, arr_len);
     537           0 : }
     538             : 
     539           0 : void special_get_array_dict_sas(struct sbus_request *sbus_req,
     540             :                                 void *data,
     541             :                                 hash_table_t **_out)
     542             : {
     543             :     hash_table_t *table;
     544             :     hash_key_t key;
     545             :     hash_value_t value;
     546             :     char **values;
     547             :     errno_t ret;
     548             :     int hret;
     549             : 
     550           0 :     *_out = NULL;
     551             : 
     552           0 :     ret = sss_hash_create(sbus_req, 10, &table);
     553           0 :     ck_assert_int_eq(ret, EOK);
     554             : 
     555           0 :     values = talloc_zero_array(table, char *, 3);
     556           0 :     ck_assert(values != NULL);
     557             : 
     558           0 :     values[0] = talloc_strdup(values, "hello1");
     559           0 :     values[1] = talloc_strdup(values, "world1");
     560             : 
     561           0 :     ck_assert(values[0] != NULL);
     562           0 :     ck_assert(values[1] != NULL);
     563             : 
     564           0 :     key.type = HASH_KEY_STRING;
     565           0 :     key.str = talloc_strdup(table, "key1");
     566             : 
     567           0 :     value.type = HASH_VALUE_PTR;
     568           0 :     value.ptr = values;
     569             : 
     570           0 :     hret = hash_enter(table, &key, &value);
     571           0 :     ck_assert_int_eq(hret, HASH_SUCCESS);
     572             : 
     573           0 :     values = talloc_zero_array(table, char *, 3);
     574           0 :     ck_assert(values != NULL);
     575             : 
     576           0 :     values[0] = talloc_strdup(values, "hello2");
     577           0 :     values[1] = talloc_strdup(values, "world2");
     578             : 
     579           0 :     ck_assert(values[0] != NULL);
     580           0 :     ck_assert(values[1] != NULL);
     581             : 
     582           0 :     key.type = HASH_KEY_STRING;
     583           0 :     key.str = talloc_strdup(table, "key2");
     584           0 :     ck_assert(key.str != NULL);
     585             : 
     586           0 :     value.type = HASH_VALUE_PTR;
     587           0 :     value.ptr = values;
     588             : 
     589           0 :     hash_enter(table, &key, &value);
     590           0 :     ck_assert_int_eq(hret, HASH_SUCCESS);
     591             : 
     592           0 :     *_out = table;
     593           0 : }
     594             : 
     595             : struct test_pilot pilot_iface = {
     596             :     { &test_pilot_meta, 0 },
     597             :     .Eject = eject_handler,
     598             : 
     599             :     .get_FullName = pilot_get_full_name_handler,
     600             :     .get_byte = pilot_get_byte_handler,
     601             :     .get_boolean = pilot_get_boolean_handler,
     602             :     .get_int16 = pilot_get_int16_handler,
     603             :     .get_uint16 = pilot_get_uint16_handler,
     604             :     .get_int32 = pilot_get_int32_handler,
     605             :     .get_uint32 = pilot_get_uint32_handler,
     606             :     .get_int64 = pilot_get_int64_handler,
     607             :     .get_uint64 = pilot_get_uint64_handler,
     608             :     .get_double = pilot_get_double_handler,
     609             :     .get_string = pilot_get_string_handler,
     610             :     .get_object_path = pilot_get_objpath_handler,
     611             :     .get_null_string = pilot_get_null_string_handler,
     612             :     .get_null_path = pilot_get_null_path_handler,
     613             : 
     614             :     .get_byte_array = pilot_get_byte_array_handler,
     615             :     .get_int16_array = pilot_get_int16_array_handler,
     616             :     .get_uint16_array = pilot_get_uint16_array_handler,
     617             :     .get_int32_array = pilot_get_int32_array_handler,
     618             :     .get_uint32_array = pilot_get_uint32_array_handler,
     619             :     .get_int64_array = pilot_get_int64_array_handler,
     620             :     .get_uint64_array = pilot_get_uint64_array_handler,
     621             :     .get_double_array = pilot_get_double_array_handler,
     622             :     .get_string_array = pilot_get_string_array_handler,
     623             :     .get_object_path_array = pilot_get_path_array_handler,
     624             : };
     625             : 
     626             : struct test_special special_iface = {
     627             :     { &test_special_meta, 0},
     628             :     .get_array_dict_sas = special_get_array_dict_sas
     629             : };
     630             : 
     631           0 : static int pilot_test_server_init(struct sbus_connection *server, void *unused)
     632             : {
     633             :     int ret;
     634             : 
     635           0 :     ret = sbus_conn_register_iface(server, &pilot_iface.vtable, "/test/leela",
     636             :                                    "Crash into the billboard");
     637           0 :     ck_assert_int_eq(ret, EOK);
     638             : 
     639           0 :     return EOK;
     640             : }
     641             : 
     642           0 : static int special_test_server_init(struct sbus_connection *server, void *unused)
     643             : {
     644             :     int ret;
     645             : 
     646           0 :     ret = sbus_conn_register_iface(server, &special_iface.vtable,
     647             :                                    "/test/special", "Crash into the billboard");
     648           0 :     ck_assert_int_eq(ret, EOK);
     649             : 
     650           0 :     return EOK;
     651             : }
     652             : 
     653           1 : START_TEST(test_marshal_basic_types)
     654             : {
     655           1 :     unsigned char arg_byte = 11;
     656           1 :     dbus_bool_t arg_boolean = TRUE;
     657           1 :     dbus_int16_t arg_int16 = -2222;
     658           1 :     dbus_uint16_t arg_uint16 = 3333;
     659           1 :     dbus_int32_t arg_int32 = -44444444;
     660           1 :     dbus_uint32_t arg_uint32 = 55555555;
     661           1 :     dbus_int64_t arg_int64 = -6666666666666666;
     662           1 :     dbus_uint64_t arg_uint64 = 7777777777777777;
     663           1 :     double arg_double = 1.1;
     664           1 :     const char *arg_string = "hello";
     665           1 :     const char *arg_object_path = "/original/object/path";
     666             : 
     667           1 :     unsigned char v_byte[] = { 11, 12 };
     668           1 :     dbus_int16_t v_int16[] = { 1, -22, 333, -4444 };
     669           1 :     dbus_uint16_t v_uint16[] = { 1, 2, 3, 4, 5 };
     670           1 :     dbus_int32_t v_int32[] = { -1, -23, 34, -56, -90000000, 78 };
     671           1 :     dbus_uint32_t v_uint32[] = { 11111111, 22222222, 33333333 };
     672           1 :     dbus_int64_t v_int64[] = { -6666666666666666, 7777777777777777 };
     673           1 :     dbus_uint64_t v_uint64[] = { 7777777777777777, 888888888888888888 };
     674           1 :     double v_double[] = { 1.1, 2.2, 3.3 };
     675           1 :     char *v_string[] = { "bears", "bears", "bears" };
     676           1 :     char *v_object_path[] = { "/original", "/original" };
     677             : 
     678           1 :     unsigned char *arr_byte = v_byte;
     679           1 :     dbus_int16_t *arr_int16 = v_int16;
     680           1 :     dbus_uint16_t *arr_uint16 = v_uint16;
     681           1 :     dbus_int32_t *arr_int32 = v_int32;
     682           1 :     dbus_uint32_t *arr_uint32 = v_uint32;
     683           1 :     dbus_int64_t *arr_int64 = v_int64;
     684           1 :     dbus_uint64_t *arr_uint64 = v_uint64;
     685           1 :     double *arr_double = v_double;
     686           1 :     char **arr_string = v_string;
     687           1 :     char **arr_object_path = v_object_path;
     688             : 
     689           1 :     int len_byte = N_ELEMENTS(v_byte);
     690           1 :     int len_int16 = N_ELEMENTS(v_int16);
     691           1 :     int len_uint16 = N_ELEMENTS(v_uint16);
     692           1 :     int len_int32 = N_ELEMENTS(v_int32);
     693           1 :     int len_uint32 = N_ELEMENTS(v_uint32);
     694           1 :     int len_int64 = N_ELEMENTS(v_int64);
     695           1 :     int len_uint64 = N_ELEMENTS(v_uint64);
     696           1 :     int len_double = N_ELEMENTS(v_double);
     697           1 :     int len_string = N_ELEMENTS(v_string);
     698           1 :     int len_object_path = N_ELEMENTS(v_object_path);
     699             : 
     700             :     TALLOC_CTX *ctx;
     701             :     DBusConnection *client;
     702           1 :     DBusError error = DBUS_ERROR_INIT;
     703             :     DBusMessage *reply;
     704             : 
     705           1 :     ctx = talloc_new(NULL);
     706           1 :     ck_assert(ctx != NULL);
     707             : 
     708           1 :     client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL);
     709           1 :     ck_assert(client != NULL);
     710             : 
     711           1 :     reply = test_dbus_call_sync(client,
     712             :                                 "/test/leela",
     713             :                                 TEST_PILOT,
     714             :                                 TEST_PILOT_EJECT,
     715             :                                 &error,
     716             :                                 DBUS_TYPE_BYTE, &arg_byte,
     717             :                                 DBUS_TYPE_BOOLEAN, &arg_boolean,
     718             :                                 DBUS_TYPE_INT16, &arg_int16,
     719             :                                 DBUS_TYPE_UINT16, &arg_uint16,
     720             :                                 DBUS_TYPE_INT32, &arg_int32,
     721             :                                 DBUS_TYPE_UINT32, &arg_uint32,
     722             :                                 DBUS_TYPE_INT64, &arg_int64,
     723             :                                 DBUS_TYPE_UINT64, &arg_uint64,
     724             :                                 DBUS_TYPE_DOUBLE, &arg_double,
     725             :                                 DBUS_TYPE_STRING, &arg_string,
     726             :                                 DBUS_TYPE_OBJECT_PATH, &arg_object_path,
     727             :                                 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &arr_byte, len_byte,
     728             :                                 DBUS_TYPE_ARRAY, DBUS_TYPE_INT16, &arr_int16, len_int16,
     729             :                                 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT16, &arr_uint16, len_uint16,
     730             :                                 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &arr_int32, len_int32,
     731             :                                 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &arr_uint32, len_uint32,
     732             :                                 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &arr_int64, len_int64,
     733             :                                 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &arr_uint64, len_uint64,
     734             :                                 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &arr_double, len_double,
     735             :                                 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &arr_string, len_string,
     736             :                                 DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arr_object_path, len_object_path,
     737             :                                 DBUS_TYPE_INVALID);
     738           1 :     ck_assert(reply != NULL);
     739           1 :     ck_assert(!dbus_error_is_set(&error));
     740           1 :     ck_assert(dbus_message_get_args(reply, NULL,
     741             :                                     DBUS_TYPE_BYTE, &arg_byte,
     742             :                                     DBUS_TYPE_BOOLEAN, &arg_boolean,
     743             :                                     DBUS_TYPE_INT16, &arg_int16,
     744             :                                     DBUS_TYPE_UINT16, &arg_uint16,
     745             :                                     DBUS_TYPE_INT32, &arg_int32,
     746             :                                     DBUS_TYPE_UINT32, &arg_uint32,
     747             :                                     DBUS_TYPE_INT64, &arg_int64,
     748             :                                     DBUS_TYPE_UINT64, &arg_uint64,
     749             :                                     DBUS_TYPE_DOUBLE, &arg_double,
     750             :                                     DBUS_TYPE_STRING, &arg_string,
     751             :                                     DBUS_TYPE_OBJECT_PATH, &arg_object_path,
     752             :                                     DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &arr_byte, &len_byte,
     753             :                                     DBUS_TYPE_ARRAY, DBUS_TYPE_INT16, &arr_int16, &len_int16,
     754             :                                     DBUS_TYPE_ARRAY, DBUS_TYPE_UINT16, &arr_uint16, &len_uint16,
     755             :                                     DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &arr_int32, &len_int32,
     756             :                                     DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &arr_uint32, &len_uint32,
     757             :                                     DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &arr_int64, &len_int64,
     758             :                                     DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &arr_uint64, &len_uint64,
     759             :                                     DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &arr_double, &len_double,
     760             :                                     DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &arr_string, &len_string,
     761             :                                     DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arr_object_path, &len_object_path,
     762             :                                     DBUS_TYPE_INVALID));
     763             : 
     764           1 :     ck_assert_uint_eq(arg_byte, 12);
     765           1 :     ck_assert(arg_boolean == FALSE);
     766           1 :     ck_assert_int_eq(arg_int16, -2221);
     767           1 :     ck_assert_uint_eq(arg_uint16, 3334);
     768           1 :     ck_assert_int_eq(arg_int32, -44444443);
     769           1 :     ck_assert_uint_eq(arg_uint32, 55555556);
     770           1 :     ck_assert(arg_int64 ==-6666666666666665);
     771           1 :     ck_assert(arg_uint64 == 7777777777777778);
     772           1 :     ck_assert(arg_double == 2.1);
     773           1 :     ck_assert_str_eq(arg_string, "bears, beets, battlestar galactica");
     774           1 :     ck_assert_str_eq(arg_object_path, "/another/object/path");
     775             : 
     776           1 :     ck_assert_int_eq(len_byte, 2);
     777           1 :     ck_assert_int_eq(arr_byte[0], 12);
     778           1 :     ck_assert_int_eq(arr_byte[1], 13);
     779             : 
     780           1 :     ck_assert_int_eq(len_int16, 3);
     781           1 :     ck_assert_int_eq(arr_int16[0], 2);
     782           1 :     ck_assert_int_eq(arr_int16[1], -21);
     783           1 :     ck_assert_int_eq(arr_int16[2], 334);
     784             : 
     785           1 :     ck_assert_int_eq(len_uint16, 5);
     786           1 :     ck_assert_uint_eq(arr_uint16[0], 2);
     787           1 :     ck_assert_uint_eq(arr_uint16[1], 3);
     788           1 :     ck_assert_uint_eq(arr_uint16[2], 4);
     789           1 :     ck_assert_uint_eq(arr_uint16[3], 5);
     790           1 :     ck_assert_uint_eq(arr_uint16[4], 6);
     791             : 
     792           1 :     ck_assert_int_eq(len_int32, 5);
     793           1 :     ck_assert_int_eq(arr_int32[0], 0);
     794           1 :     ck_assert_int_eq(arr_int32[1], -22);
     795           1 :     ck_assert_int_eq(arr_int32[2], 35);
     796           1 :     ck_assert_int_eq(arr_int32[3], -55);
     797           1 :     ck_assert_int_eq(arr_int32[4], -89999999);
     798             : 
     799           1 :     ck_assert_int_eq(len_uint32, 3);
     800           1 :     ck_assert_uint_eq(arr_uint32[0], 11111112);
     801           1 :     ck_assert_uint_eq(arr_uint32[1], 22222223);
     802           1 :     ck_assert_uint_eq(arr_uint32[2], 33333334);
     803             : 
     804           1 :     ck_assert_int_eq(len_int64, 2);
     805           1 :     ck_assert(arr_int64[0] == -6666666666666665);
     806           1 :     ck_assert(arr_int64[1] == 7777777777777778);
     807             : 
     808           1 :     ck_assert_int_eq(len_uint64, 2);
     809           1 :     ck_assert(arr_uint64[0] == 7777777777777778);
     810           1 :     ck_assert(arr_uint64[1] == 888888888888888889);
     811             : 
     812           1 :     ck_assert_int_eq(len_double, 3);
     813           1 :     ck_assert(arr_double[0] == 2.1);
     814           1 :     ck_assert(arr_double[1] == 3.2);
     815           1 :     ck_assert(arr_double[2] == 4.3);
     816             : 
     817           1 :     ck_assert_int_eq(len_string, 2);
     818           1 :     ck_assert_str_eq(arr_string[0], "beets");
     819           1 :     ck_assert_str_eq(arr_string[1], "beets");
     820           1 :     dbus_free_string_array(arr_string);
     821             : 
     822           1 :     ck_assert_int_eq(len_object_path, 2);
     823           1 :     ck_assert_str_eq(arr_object_path[0], "/changed");
     824           1 :     ck_assert_str_eq(arr_object_path[1], "/changed");
     825           1 :     dbus_free_string_array(arr_object_path);
     826             : 
     827           1 :     dbus_message_unref (reply);
     828           1 :     talloc_free(ctx);
     829             : }
     830           1 : END_TEST
     831             : 
     832          14 : static void parse_get_reply(DBusMessage *reply, const int type, void *val)
     833             : {
     834             :     DBusMessageIter iter;
     835             :     DBusMessageIter variter;
     836             :     dbus_bool_t dbret;
     837             : 
     838          14 :     dbret = dbus_message_iter_init(reply, &iter);
     839          14 :     ck_assert(dbret == TRUE);
     840          14 :     ck_assert_int_eq(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_VARIANT);
     841          14 :     dbus_message_iter_recurse(&iter, &variter);
     842          14 :     ck_assert_int_eq(dbus_message_iter_get_arg_type(&variter), type);
     843          14 :     dbus_message_iter_get_basic(&variter, val);
     844          14 : }
     845             : 
     846          14 : static void call_get(DBusConnection *client,
     847             :                      const char *object_path,
     848             :                      const char *iface,
     849             :                      const char *prop,
     850             :                      int type,
     851             :                      void *val)
     852             : {
     853             :     DBusMessage *reply;
     854          14 :     DBusError error = DBUS_ERROR_INIT;
     855             : 
     856          14 :     reply = test_dbus_call_sync(client,
     857             :                                 object_path,
     858             :                                 DBUS_PROPERTIES_INTERFACE,
     859             :                                 "Get",
     860             :                                 &error,
     861             :                                 DBUS_TYPE_STRING, &iface,
     862             :                                 DBUS_TYPE_STRING, &prop,
     863             :                                 DBUS_TYPE_INVALID);
     864          14 :     ck_assert(reply != NULL);
     865          14 :     parse_get_reply(reply, type, val);
     866          14 : }
     867             : 
     868           1 : START_TEST(test_get_basic_types)
     869             : {
     870             :     TALLOC_CTX *ctx;
     871             :     DBusConnection *client;
     872             :     dbus_bool_t bool_val;
     873             :     const char *string_val;
     874             :     const char *path_val;
     875             :     uint8_t byte_val;
     876             :     int16_t int16_val;
     877             :     uint16_t uint16_val;
     878             :     int32_t int32_val;
     879             :     uint32_t uint32_val;
     880             :     int64_t int64_val;
     881             :     uint64_t uint64_val;
     882             :     double double_val;
     883             : 
     884           1 :     ctx = talloc_new(NULL);
     885           1 :     ck_assert(ctx != NULL);
     886             : 
     887           1 :     client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL);
     888           1 :     ck_assert(client != NULL);
     889             : 
     890           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "boolean",
     891             :              DBUS_TYPE_BOOLEAN, &bool_val);
     892           1 :     ck_assert(bool_val == pilot_bool);
     893             : 
     894           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "FullName",
     895             :              DBUS_TYPE_STRING, &string_val);
     896           1 :     ck_assert_str_eq(string_val, pilot_full_name);
     897             : 
     898           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "byte",
     899             :              DBUS_TYPE_BYTE, &byte_val);
     900           1 :     ck_assert_int_eq(byte_val, pilot_byte);
     901             : 
     902           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "int16",
     903             :              DBUS_TYPE_INT16, &int16_val);
     904           1 :     ck_assert_int_eq(int16_val, pilot_int16);
     905             : 
     906           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "uint16",
     907             :              DBUS_TYPE_UINT16, &uint16_val);
     908           1 :     ck_assert_int_eq(uint16_val, pilot_uint16);
     909             : 
     910           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "int32",
     911             :              DBUS_TYPE_INT32, &int32_val);
     912           1 :     ck_assert_int_eq(int32_val, pilot_int32);
     913             : 
     914           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "uint32",
     915             :              DBUS_TYPE_UINT32, &uint32_val);
     916           1 :     ck_assert_int_eq(uint32_val, pilot_uint32);
     917             : 
     918           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "int64",
     919             :              DBUS_TYPE_INT64, &int64_val);
     920           1 :     ck_assert_int_eq(int64_val, pilot_int64);
     921             : 
     922           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "uint64",
     923             :              DBUS_TYPE_UINT64, &uint64_val);
     924           1 :     ck_assert_int_eq(uint64_val, pilot_uint64);
     925             : 
     926           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "double",
     927             :              DBUS_TYPE_DOUBLE, &double_val);
     928           1 :     ck_assert_int_eq(double_val, pilot_double);
     929             : 
     930           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "string",
     931             :              DBUS_TYPE_STRING, &string_val);
     932           1 :     ck_assert_str_eq(string_val, pilot_string);
     933             : 
     934           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "object_path",
     935             :              DBUS_TYPE_OBJECT_PATH, &path_val);
     936           1 :     ck_assert_str_eq(path_val, pilot_path);
     937             : 
     938             :     /* If a string getter returns NULL, the caller should receive "" */
     939           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "null_string",
     940             :              DBUS_TYPE_STRING, &string_val);
     941           1 :     ck_assert_str_eq(string_val, "");
     942             : 
     943             :     /* If a string getter returns NULL, the caller should receive "/" */
     944           1 :     call_get(client, "/test/leela", test_pilot_meta.name, "null_path",
     945             :              DBUS_TYPE_OBJECT_PATH, &path_val);
     946           1 :     ck_assert_str_eq(path_val, "/");
     947             : 
     948           1 :     talloc_free(ctx);
     949             : }
     950           1 : END_TEST
     951             : 
     952          11 : static void parse_get_array_reply(DBusMessage *reply, const int type,
     953             :                                   void **values, int *nels)
     954             : {
     955             :     DBusMessageIter iter;
     956             :     DBusMessageIter variter;
     957             :     DBusMessageIter arriter;
     958             :     dbus_bool_t dbret;
     959             : 
     960          11 :     dbret = dbus_message_iter_init(reply, &iter);
     961          11 :     ck_assert(dbret == TRUE);
     962          11 :     ck_assert_int_eq(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_VARIANT);
     963          11 :     dbus_message_iter_recurse(&iter, &variter);
     964          11 :     ck_assert_int_eq(dbus_message_iter_get_arg_type(&variter), DBUS_TYPE_ARRAY);
     965          11 :     ck_assert_int_eq(dbus_message_iter_get_element_type(&variter), type);
     966          11 :     dbus_message_iter_recurse(&variter, &arriter);
     967          14 :     if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
     968           3 :         int n = 0, i = 0;;
     969             :         const char **strings;
     970             :         const char *s;
     971             : 
     972             :         do {
     973           6 :             n++;
     974           6 :         } while (dbus_message_iter_next(&arriter));
     975             : 
     976             :         /* Allocating on NULL is bad, but this is unit test */
     977           3 :         strings = talloc_array(NULL, const char *, n);
     978           3 :         ck_assert(strings != NULL);
     979             : 
     980           3 :         dbus_message_iter_recurse(&variter, &arriter);
     981             :         do {
     982           6 :             dbus_message_iter_get_basic(&arriter, &s);
     983           6 :             strings[i] = talloc_strdup(strings, s);
     984           6 :             ck_assert(strings[i] != NULL);
     985           6 :             i++;
     986           6 :         } while (dbus_message_iter_next(&arriter));
     987             : 
     988           3 :         *nels = n;
     989           3 :         *values = strings;
     990             :     } else {
     991             :         /* Fixed types are easy */
     992           8 :         dbus_message_iter_get_fixed_array(&arriter, values, nels);
     993             :     }
     994          11 : }
     995             : 
     996          11 : static void call_get_array(DBusConnection *client,
     997             :                            const char *object_path,
     998             :                            const char *iface,
     999             :                            const char *prop,
    1000             :                            int type,
    1001             :                            void **values,
    1002             :                            int *nels)
    1003             : {
    1004             :     DBusMessage *reply;
    1005          11 :     DBusError error = DBUS_ERROR_INIT;
    1006             : 
    1007          11 :     reply = test_dbus_call_sync(client,
    1008             :                                 object_path,
    1009             :                                 DBUS_PROPERTIES_INTERFACE,
    1010             :                                 "Get",
    1011             :                                 &error,
    1012             :                                 DBUS_TYPE_STRING, &iface,
    1013             :                                 DBUS_TYPE_STRING, &prop,
    1014             :                                 DBUS_TYPE_INVALID);
    1015          11 :     ck_assert(reply != NULL);
    1016          11 :     parse_get_array_reply(reply, type, values, nels);
    1017          11 : }
    1018             : 
    1019             : #define _check_array(reply, len, known, fn) do {    \
    1020             :     fn(len, 2);                                     \
    1021             :     fn(reply[0], known[0]);                         \
    1022             :     fn(reply[1], known[1]);                         \
    1023             : } while(0);                                         \
    1024             : 
    1025             : #define check_int_array(reply, len, known) \
    1026             :     _check_array(reply, len, known, ck_assert_int_eq)
    1027             : #define check_uint_array(reply, len, known) \
    1028             :     _check_array(reply, len, known, ck_assert_uint_eq)
    1029             : 
    1030           1 : START_TEST(test_get_basic_array_types)
    1031             : {
    1032             :     TALLOC_CTX *ctx;
    1033             :     DBusConnection *client;
    1034             :     const char **string_arr_val;
    1035             :     int string_arr_len;
    1036             :     const char **path_arr_val;
    1037             :     int path_arr_len;
    1038             :     uint8_t *byte_arr_val;
    1039             :     int byte_arr_len;
    1040             :     int16_t *int16_arr_val;
    1041             :     int int16_arr_len;
    1042             :     uint16_t *uint16_arr_val;
    1043             :     int uint16_arr_len;
    1044             :     int32_t *int32_arr_val;
    1045             :     int int32_arr_len;
    1046             :     uint32_t *uint32_arr_val;
    1047             :     int uint32_arr_len;
    1048             :     int64_t *int64_arr_val;
    1049             :     int int64_arr_len;
    1050             :     uint64_t *uint64_arr_val;
    1051             :     int uint64_arr_len;
    1052             :     double *double_arr_val;
    1053             :     int double_arr_len;
    1054             : 
    1055           1 :     ctx = talloc_new(NULL);
    1056           1 :     ck_assert(ctx != NULL);
    1057             : 
    1058           1 :     client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL);
    1059           1 :     ck_assert(client != NULL);
    1060             : 
    1061           1 :     call_get_array(client, "/test/leela", test_pilot_meta.name, "byte_array",
    1062             :                    DBUS_TYPE_BYTE, (void **) &byte_arr_val, &byte_arr_len);
    1063           1 :     check_uint_array(byte_arr_val, byte_arr_len, pilot_byte_array);
    1064             : 
    1065           1 :     call_get_array(client, "/test/leela", test_pilot_meta.name, "int16_array",
    1066             :                    DBUS_TYPE_INT16, (void **) &int16_arr_val, &int16_arr_len);
    1067           1 :     check_int_array(int16_arr_val, int16_arr_len, pilot_int16_array);
    1068             : 
    1069           1 :     call_get_array(client, "/test/leela", test_pilot_meta.name, "uint16_array",
    1070             :                    DBUS_TYPE_UINT16, (void **) &uint16_arr_val, &uint16_arr_len);
    1071           1 :     check_uint_array(uint16_arr_val, uint16_arr_len, pilot_uint16_array);
    1072             : 
    1073           1 :     call_get_array(client, "/test/leela", test_pilot_meta.name, "int32_array",
    1074             :                    DBUS_TYPE_INT32, (void **) &int32_arr_val, &int32_arr_len);
    1075           1 :     check_int_array(int32_arr_val, int32_arr_len, pilot_int32_array);
    1076             : 
    1077           1 :     call_get_array(client, "/test/leela", test_pilot_meta.name, "uint32_array",
    1078             :                    DBUS_TYPE_UINT32, (void **) &uint32_arr_val, &uint32_arr_len);
    1079           1 :     check_uint_array(uint32_arr_val, uint32_arr_len, pilot_uint32_array);
    1080             : 
    1081           1 :     call_get_array(client, "/test/leela", test_pilot_meta.name, "int64_array",
    1082             :                    DBUS_TYPE_INT64, (void **) &int64_arr_val, &int64_arr_len);
    1083           1 :     check_int_array(int64_arr_val, int64_arr_len, pilot_int64_array);
    1084             : 
    1085           1 :     call_get_array(client, "/test/leela", test_pilot_meta.name, "uint64_array",
    1086             :                    DBUS_TYPE_UINT64, (void **) &uint64_arr_val, &uint64_arr_len);
    1087           1 :     check_uint_array(uint64_arr_val, uint64_arr_len, pilot_uint64_array);
    1088             : 
    1089           1 :     call_get_array(client, "/test/leela", test_pilot_meta.name, "double_array",
    1090             :                    DBUS_TYPE_DOUBLE, (void **) &double_arr_val, &double_arr_len);
    1091           1 :     check_int_array(double_arr_val, double_arr_len, pilot_double_array);
    1092             : 
    1093           1 :     call_get_array(client, "/test/leela", test_pilot_meta.name, "string_array",
    1094             :                    DBUS_TYPE_STRING, (void **) &string_arr_val, &string_arr_len);
    1095           1 :     ck_assert_int_eq(string_arr_len, 2);
    1096           1 :     ck_assert_str_eq(string_arr_val[0], pilot_string_array[0]);
    1097           1 :     ck_assert_str_eq(string_arr_val[1], pilot_string_array[1]);
    1098             : 
    1099           1 :     call_get_array(client, "/test/leela", test_pilot_meta.name, "string_array",
    1100             :                    DBUS_TYPE_STRING, (void **) &string_arr_val, &string_arr_len);
    1101           1 :     ck_assert_int_eq(string_arr_len, 2);
    1102           1 :     ck_assert_str_eq(string_arr_val[0], pilot_string_array[0]);
    1103           1 :     ck_assert_str_eq(string_arr_val[1], pilot_string_array[1]);
    1104             : 
    1105           1 :     call_get_array(client, "/test/leela", test_pilot_meta.name, "object_path_array",
    1106             :                    DBUS_TYPE_OBJECT_PATH, (void **) &path_arr_val, &path_arr_len);
    1107           1 :     ck_assert_int_eq(path_arr_len, 2);
    1108           1 :     ck_assert_str_eq(path_arr_val[0], pilot_path_array[0]);
    1109           1 :     ck_assert_str_eq(path_arr_val[1], pilot_path_array[1]);
    1110             : 
    1111           1 :     talloc_free(ctx);
    1112             : }
    1113           1 : END_TEST
    1114             : 
    1115           1 : START_TEST(test_get_array_dict_sas)
    1116             : {
    1117             :     TALLOC_CTX *ctx;
    1118             :     DBusConnection *client;
    1119             :     DBusMessage *reply;
    1120             :     DBusMessageIter it_variant;
    1121             :     DBusMessageIter it_array;
    1122             :     DBusMessageIter it_dict;
    1123             :     DBusMessageIter it_dict_entry;
    1124             :     DBusMessageIter it_values;
    1125           1 :     DBusError error = DBUS_ERROR_INIT;
    1126           1 :     const char *prop = "array_dict_sas";
    1127             :     dbus_bool_t dbret;
    1128             :     const char *value;
    1129           1 :     const char *hash_content[2][2] = {{"hello1", "world1"},
    1130             :                                       {"hello2", "world2"}};
    1131             :     const char **exp_values;
    1132             :     int i;
    1133             : 
    1134           1 :     ctx = talloc_new(NULL);
    1135           1 :     ck_assert(ctx != NULL);
    1136             : 
    1137           1 :     client = test_dbus_setup_mock(ctx, NULL, special_test_server_init, NULL);
    1138           1 :     ck_assert(client != NULL);
    1139             : 
    1140           1 :     reply = test_dbus_call_sync(client,
    1141             :                                 "/test/special",
    1142             :                                 DBUS_PROPERTIES_INTERFACE,
    1143             :                                 "Get",
    1144             :                                 &error,
    1145             :                                 DBUS_TYPE_STRING, &test_special_meta.name,
    1146             :                                 DBUS_TYPE_STRING, &prop,
    1147             :                                 DBUS_TYPE_INVALID);
    1148           1 :     ck_assert(reply != NULL);
    1149             : 
    1150           1 :     dbret = dbus_message_iter_init(reply, &it_variant);
    1151           1 :     ck_assert(dbret == TRUE);
    1152             : 
    1153           1 :     ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_variant), DBUS_TYPE_VARIANT);
    1154           1 :     dbus_message_iter_recurse(&it_variant, &it_array);
    1155             : 
    1156             :     /* array */
    1157           1 :     ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_array), DBUS_TYPE_ARRAY);
    1158           1 :     ck_assert_int_eq(dbus_message_iter_get_element_type(&it_array), DBUS_TYPE_DICT_ENTRY);
    1159             : 
    1160             :     /* dict entry */
    1161             : 
    1162             :     /* first item */
    1163           1 :     dbus_message_iter_recurse(&it_array, &it_dict);
    1164           3 :     for (i = 0; i < 2; i++) {
    1165           2 :         dbus_message_iter_recurse(&it_dict, &it_dict_entry);
    1166           2 :         ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_dict_entry), DBUS_TYPE_STRING);
    1167             : 
    1168           2 :         dbus_message_iter_get_basic(&it_dict_entry, &value);
    1169           2 :         ck_assert(value != NULL);
    1170           2 :         if (strcmp(value, "key1") == 0) {
    1171           1 :             exp_values = hash_content[0];
    1172           1 :         } else if (strcmp(value, "key2") == 0) {
    1173           1 :             exp_values = hash_content[1];
    1174             :         } else {
    1175           0 :             ck_abort_msg("Invalid key! %s", value);
    1176             :         }
    1177             : 
    1178           2 :         dbret = dbus_message_iter_next(&it_dict_entry);
    1179           2 :         ck_assert(dbret == TRUE);
    1180             : 
    1181           2 :         ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_dict_entry), DBUS_TYPE_ARRAY);
    1182           2 :         ck_assert_int_eq(dbus_message_iter_get_element_type(&it_dict_entry), DBUS_TYPE_STRING);
    1183             : 
    1184           2 :         dbus_message_iter_recurse(&it_dict_entry, &it_values);
    1185             : 
    1186           2 :         dbus_message_iter_get_basic(&it_values, &value);
    1187           2 :         ck_assert(value != NULL);
    1188           2 :         ck_assert_str_eq(value, exp_values[0]);
    1189             : 
    1190           2 :         dbret = dbus_message_iter_next(&it_values);
    1191           2 :         dbus_message_iter_get_basic(&it_values, &value);
    1192           2 :         ck_assert(value != NULL);
    1193           2 :         ck_assert_str_eq(value, exp_values[1]);
    1194           2 :         dbus_message_iter_next(&it_dict);
    1195             :     }
    1196             : 
    1197           1 :     talloc_free(ctx);
    1198             : }
    1199           1 : END_TEST
    1200             : 
    1201             : struct prop_test {
    1202             :     const char *name;
    1203             :     bool handled;
    1204             :     int length;
    1205             :     int type;
    1206             :     union prop_value {
    1207             :         bool bool_val;
    1208             :         const char *string_val;
    1209             :         const char *path_val;
    1210             :         uint8_t byte_val;
    1211             :         int16_t int16_val;
    1212             :         uint16_t uint16_val;
    1213             :         int32_t int32_val;
    1214             :         uint32_t uint32_val;
    1215             :         int64_t int64_val;
    1216             :         uint64_t uint64_val;
    1217             :         double double_val;
    1218             : 
    1219             :         const char **string_arr_val;
    1220             :         const char **path_arr_val;
    1221             :         uint8_t *byte_arr_val;
    1222             :         int16_t *int16_arr_val;
    1223             :         uint16_t *uint16_arr_val;
    1224             :         int32_t *int32_arr_val;
    1225             :         uint32_t *uint32_arr_val;
    1226             :         int64_t *int64_arr_val;
    1227             :         uint64_t *uint64_arr_val;
    1228             :         double *double_arr_val;
    1229             :     } value;
    1230             : };
    1231             : 
    1232          14 : void check_prop(DBusMessageIter *variter, struct prop_test *p)
    1233             : {
    1234             :     dbus_bool_t bool_val;
    1235             :     const char *string_val;
    1236             :     const char *path_val;
    1237             :     uint8_t byte_val;
    1238             :     int16_t int16_val;
    1239             :     uint16_t uint16_val;
    1240             :     int32_t int32_val;
    1241             :     uint32_t uint32_val;
    1242             :     int64_t int64_val;
    1243             :     uint64_t uint64_val;
    1244             :     double double_val;
    1245             :     int type;
    1246             : 
    1247          14 :     type = dbus_message_iter_get_arg_type(variter);
    1248             : 
    1249             :     /* No property should be returned twice */
    1250          14 :     ck_assert(p->handled == false);
    1251          14 :     ck_assert(p->type == type);
    1252          14 :     switch (p->type) {
    1253             :         case DBUS_TYPE_BOOLEAN:
    1254           1 :             dbus_message_iter_get_basic(variter, &bool_val);
    1255           1 :             ck_assert(bool_val == p->value.bool_val);
    1256           1 :             break;
    1257             :         case DBUS_TYPE_STRING:
    1258           3 :             dbus_message_iter_get_basic(variter, &string_val);
    1259           3 :             ck_assert_str_eq(string_val, p->value.string_val);
    1260           3 :             break;
    1261             :         case DBUS_TYPE_BYTE:
    1262           1 :             dbus_message_iter_get_basic(variter, &byte_val);
    1263           1 :             ck_assert_int_eq(byte_val, p->value.byte_val);
    1264           1 :             break;
    1265             :         case DBUS_TYPE_INT16:
    1266           1 :             dbus_message_iter_get_basic(variter, &int16_val);
    1267           1 :             ck_assert_int_eq(int16_val, p->value.int16_val);
    1268           1 :             break;
    1269             :         case DBUS_TYPE_UINT16:
    1270           1 :             dbus_message_iter_get_basic(variter, &uint16_val);
    1271           1 :             ck_assert_int_eq(uint16_val, p->value.uint16_val);
    1272           1 :             break;
    1273             :         case DBUS_TYPE_INT32:
    1274           1 :             dbus_message_iter_get_basic(variter, &int32_val);
    1275           1 :             ck_assert_int_eq(int32_val, p->value.int32_val);
    1276           1 :             break;
    1277             :         case DBUS_TYPE_UINT32:
    1278           1 :             dbus_message_iter_get_basic(variter, &uint32_val);
    1279           1 :             ck_assert_int_eq(uint32_val, p->value.uint32_val);
    1280           1 :             break;
    1281             :         case DBUS_TYPE_INT64:
    1282           1 :             dbus_message_iter_get_basic(variter, &int64_val);
    1283           1 :             ck_assert_int_eq(int64_val, p->value.int64_val);
    1284           1 :             break;
    1285             :         case DBUS_TYPE_UINT64:
    1286           1 :             dbus_message_iter_get_basic(variter, &uint64_val);
    1287           1 :             ck_assert_int_eq(uint64_val, p->value.uint64_val);
    1288           1 :             break;
    1289             :         case DBUS_TYPE_DOUBLE:
    1290           1 :             dbus_message_iter_get_basic(variter, &double_val);
    1291           1 :             ck_assert_int_eq(double_val, p->value.double_val);
    1292           1 :             break;
    1293             :         case DBUS_TYPE_OBJECT_PATH:
    1294           2 :             dbus_message_iter_get_basic(variter, &path_val);
    1295           2 :             ck_assert_str_eq(path_val, p->value.path_val);
    1296           2 :             break;
    1297             :         default:
    1298             :             /* Not handled */
    1299           0 :             return;
    1300             :     }
    1301             : 
    1302             :     /* This attribute was handled, get the next one */
    1303          14 :     p->handled = true;
    1304             : }
    1305             : 
    1306          10 : void check_arr_prop(DBusMessageIter *variter, struct prop_test *p)
    1307             : {
    1308             :     DBusMessageIter arriter;
    1309          10 :     const char **strings = NULL;
    1310             :     uint8_t *byte_arr_val;
    1311             :     int16_t *int16_arr_val;
    1312             :     uint16_t *uint16_arr_val;
    1313             :     int32_t *int32_arr_val;
    1314             :     uint32_t *uint32_arr_val;
    1315             :     int64_t *int64_arr_val;
    1316             :     uint64_t *uint64_arr_val;
    1317             :     double *double_arr_val;
    1318             :     int len;
    1319             :     int type;
    1320             : 
    1321          10 :     ck_assert_int_eq(dbus_message_iter_get_arg_type(variter), DBUS_TYPE_ARRAY);
    1322          10 :     type = dbus_message_iter_get_element_type(variter);
    1323          10 :     ck_assert_int_eq(type, p->type);
    1324             : 
    1325          10 :     dbus_message_iter_recurse(variter, &arriter);
    1326          10 :     if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
    1327           2 :         int n = 0, i = 0;;
    1328             :         const char *s;
    1329             : 
    1330             :         do {
    1331           4 :             n++;
    1332           4 :         } while (dbus_message_iter_next(&arriter));
    1333             : 
    1334             :         /* Allocating on NULL is bad, but this is unit test */
    1335           2 :         strings = talloc_array(NULL, const char *, n);
    1336           2 :         ck_assert(strings != NULL);
    1337             : 
    1338           2 :         dbus_message_iter_recurse(variter, &arriter);
    1339             :         do {
    1340           4 :             dbus_message_iter_get_basic(&arriter, &s);
    1341           4 :             strings[i] = talloc_strdup(strings, s);
    1342           4 :             ck_assert(strings[i] != NULL);
    1343           4 :             i++;
    1344           4 :         } while (dbus_message_iter_next(&arriter));
    1345             : 
    1346           2 :         len = n;
    1347             :     }
    1348             : 
    1349          10 :     switch (p->type) {
    1350             :         case DBUS_TYPE_STRING:
    1351           1 :             ck_assert_int_eq(len, 2);
    1352           1 :             ck_assert(strings != NULL);
    1353           1 :             ck_assert_str_eq(strings[0], pilot_string_array[0]);
    1354           1 :             ck_assert_str_eq(strings[1], pilot_string_array[1]);
    1355           1 :             break;
    1356             :         case DBUS_TYPE_BYTE:
    1357           1 :             dbus_message_iter_get_fixed_array(&arriter, &byte_arr_val, &len);
    1358           1 :             check_uint_array(byte_arr_val, len, p->value.byte_arr_val);
    1359           1 :             break;
    1360             :         case DBUS_TYPE_INT16:
    1361           1 :             dbus_message_iter_get_fixed_array(&arriter, &int16_arr_val, &len);
    1362           1 :             check_int_array(int16_arr_val, len, p->value.int16_arr_val);
    1363           1 :             break;
    1364             :         case DBUS_TYPE_UINT16:
    1365           1 :             dbus_message_iter_get_fixed_array(&arriter, &uint16_arr_val, &len);
    1366           1 :             check_uint_array(uint16_arr_val, len, p->value.uint16_arr_val);
    1367           1 :             break;
    1368             :         case DBUS_TYPE_INT32:
    1369           1 :             dbus_message_iter_get_fixed_array(&arriter, &int32_arr_val, &len);
    1370           1 :             check_int_array(int32_arr_val, len, p->value.int32_arr_val);
    1371           1 :             break;
    1372             :         case DBUS_TYPE_UINT32:
    1373           1 :             dbus_message_iter_get_fixed_array(&arriter, &uint32_arr_val, &len);
    1374           1 :             check_uint_array(uint32_arr_val, len, p->value.uint32_arr_val);
    1375           1 :             break;
    1376             :         case DBUS_TYPE_INT64:
    1377           1 :             dbus_message_iter_get_fixed_array(&arriter, &int64_arr_val, &len);
    1378           1 :             check_int_array(int64_arr_val, len, p->value.int64_arr_val);
    1379           1 :             break;
    1380             :         case DBUS_TYPE_UINT64:
    1381           1 :             dbus_message_iter_get_fixed_array(&arriter, &uint64_arr_val, &len);
    1382           1 :             check_uint_array(uint64_arr_val, len, p->value.uint64_arr_val);
    1383           1 :             break;
    1384             :         case DBUS_TYPE_DOUBLE:
    1385           1 :             dbus_message_iter_get_fixed_array(&arriter, &double_arr_val, &len);
    1386           1 :             check_int_array(double_arr_val, len, p->value.double_arr_val);
    1387           1 :             break;
    1388             :         case DBUS_TYPE_OBJECT_PATH:
    1389           1 :             ck_assert_int_eq(len, 2);
    1390           1 :             ck_assert(strings != NULL);
    1391           1 :             ck_assert_str_eq(strings[0], pilot_path_array[0]);
    1392           1 :             ck_assert_str_eq(strings[1], pilot_path_array[1]);
    1393           1 :             break;
    1394             :         default:
    1395             :             /* Not handled */
    1396           0 :             return;
    1397             :     }
    1398             : 
    1399             : 
    1400          10 :     p->handled = true;
    1401             : }
    1402             : 
    1403           1 : START_TEST(test_getall_basic_types)
    1404             : {
    1405             :     DBusMessage *reply;
    1406             :     DBusMessageIter iter;
    1407             :     DBusMessageIter arriter;
    1408             :     DBusMessageIter dictiter;
    1409             :     DBusMessageIter variter;
    1410             :     dbus_bool_t dbret;
    1411           1 :     DBusError error = DBUS_ERROR_INIT;
    1412             :     TALLOC_CTX *ctx;
    1413             :     DBusConnection *client;
    1414             :     char *attr_name;
    1415             :     int i;
    1416             :     int num_prop;
    1417             : 
    1418           1 :     struct prop_test pilot_properties[] = {
    1419             :       { "boolean", false, 0, DBUS_TYPE_BOOLEAN, { .bool_val = pilot_bool } },
    1420             :       { "FullName", false, 0, DBUS_TYPE_STRING, { .string_val = pilot_full_name } },
    1421             :       { "byte", false, 0, DBUS_TYPE_BYTE, { .byte_val = pilot_byte } },
    1422             :       { "int16", false, 0, DBUS_TYPE_INT16, { .int16_val = pilot_int16 } },
    1423             :       { "uint16", false, 0, DBUS_TYPE_UINT16, { .uint16_val = pilot_uint16 } },
    1424             :       { "int32", false, 0, DBUS_TYPE_INT32, { .int32_val = pilot_int32 } },
    1425             :       { "uint32", false, 0, DBUS_TYPE_UINT32, { .uint32_val = pilot_uint32 } },
    1426             :       { "int64", false, 0, DBUS_TYPE_INT64, { .int64_val = pilot_int64 } },
    1427             :       { "uint64", false, 0, DBUS_TYPE_UINT64, { .uint64_val = pilot_uint64 } },
    1428             :       { "double", false, 0, DBUS_TYPE_DOUBLE, { .double_val = pilot_double } },
    1429             :       { "string", false, 0, DBUS_TYPE_STRING, { .string_val = pilot_string } },
    1430             :       { "object_path", false, 0, DBUS_TYPE_OBJECT_PATH, { .path_val = pilot_path } },
    1431             :       { "null_string", false, 0, DBUS_TYPE_STRING, { .string_val = "" } },
    1432             :       { "null_path", false, 0, DBUS_TYPE_OBJECT_PATH, { .path_val = "/" } },
    1433             : 
    1434             :       { "byte_array", false, N_ELEMENTS(pilot_byte_array), DBUS_TYPE_BYTE, { .byte_arr_val = pilot_byte_array } },
    1435             :       { "int16_array", false, N_ELEMENTS(pilot_int16_array), DBUS_TYPE_INT16, { .int16_arr_val = pilot_int16_array } },
    1436             :       { "uint16_array", false, N_ELEMENTS(pilot_uint16_array), DBUS_TYPE_UINT16, { .uint16_arr_val = pilot_uint16_array } },
    1437             :       { "int32_array", false, N_ELEMENTS(pilot_int32_array), DBUS_TYPE_INT32, { .int32_arr_val = pilot_int32_array } },
    1438             :       { "uint32_array", false, N_ELEMENTS(pilot_uint32_array), DBUS_TYPE_UINT32, { .uint32_arr_val = pilot_uint32_array } },
    1439             :       { "int64_array", false, N_ELEMENTS(pilot_int64_array), DBUS_TYPE_INT64, { .int64_arr_val = pilot_int64_array } },
    1440             :       { "uint64_array", false, N_ELEMENTS(pilot_uint64_array), DBUS_TYPE_UINT64, { .uint64_arr_val = pilot_uint64_array } },
    1441             :       { "double_array", false, N_ELEMENTS(pilot_double_array), DBUS_TYPE_DOUBLE, { .double_arr_val = pilot_double_array } },
    1442             :       { "string_array", false, N_ELEMENTS(pilot_string_array), DBUS_TYPE_STRING, { .string_arr_val = pilot_string_array } },
    1443             :       { "object_path_array", false, N_ELEMENTS(pilot_path_array), DBUS_TYPE_OBJECT_PATH, { .path_arr_val = pilot_path_array } },
    1444             : 
    1445             :       { NULL, false, 0, 0, { .bool_val = false } }};
    1446             : 
    1447           1 :     ctx = talloc_new(NULL);
    1448           1 :     ck_assert(ctx != NULL);
    1449             : 
    1450           1 :     client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL);
    1451           1 :     ck_assert(client != NULL);
    1452             : 
    1453           1 :     reply = test_dbus_call_sync(client,
    1454             :                                 "/test/leela",
    1455             :                                 DBUS_PROPERTIES_INTERFACE,
    1456             :                                 "GetAll",
    1457             :                                 &error,
    1458             :                                 DBUS_TYPE_STRING,
    1459             :                                 &test_pilot_meta.name,
    1460             :                                 DBUS_TYPE_INVALID);
    1461           1 :     ck_assert(reply != NULL);
    1462             : 
    1463             :     /* GetAll reply is an array of dictionaries */
    1464           1 :     dbret = dbus_message_iter_init(reply, &iter);
    1465           1 :     ck_assert(dbret == TRUE);
    1466           1 :     ck_assert_int_eq(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_ARRAY);
    1467             : 
    1468           1 :     dbus_message_iter_recurse(&iter, &arriter);
    1469           1 :     num_prop = 0;
    1470             :     do {
    1471          24 :         ck_assert_int_eq(dbus_message_iter_get_arg_type(&arriter),
    1472             :                          DBUS_TYPE_DICT_ENTRY);
    1473          24 :         dbus_message_iter_recurse(&arriter, &dictiter);
    1474          24 :         dbus_message_iter_get_basic(&dictiter, &attr_name);
    1475          24 :         ck_assert(dbus_message_iter_next(&dictiter) == TRUE);
    1476          24 :         ck_assert_int_eq(dbus_message_iter_get_arg_type(&dictiter),
    1477             :                          DBUS_TYPE_VARIANT);
    1478             : 
    1479          24 :         dbus_message_iter_recurse(&dictiter, &variter);
    1480             : 
    1481         300 :         for (i=0; pilot_properties[i].name; i++) {
    1482         300 :             if (strcmp(attr_name, pilot_properties[i].name) == 0) {
    1483          24 :                 if (dbus_message_iter_get_arg_type(&variter) == DBUS_TYPE_ARRAY) {
    1484          10 :                     check_arr_prop(&variter, &pilot_properties[i]);
    1485             :                 } else {
    1486          14 :                     check_prop(&variter, &pilot_properties[i]);
    1487             :                 }
    1488          24 :                 break;
    1489             :             }
    1490             :         }
    1491             : 
    1492          24 :         num_prop++;
    1493          24 :     } while(dbus_message_iter_next(&arriter));
    1494             : 
    1495             :     /* All known properties must be handled now */
    1496          25 :     for (i=0; pilot_properties[i].name; i++) {
    1497          24 :         ck_assert(pilot_properties[i].handled == true);
    1498             :     }
    1499             :     /* Also all properties returned from the bus must be accounted for */
    1500           1 :     ck_assert_uint_eq(num_prop, N_ELEMENTS(pilot_properties)-1);
    1501             : 
    1502           1 :     talloc_free(ctx);
    1503             : }
    1504           1 : END_TEST
    1505             : 
    1506           1 : TCase *create_handler_tests(void)
    1507             : {
    1508           1 :     TCase *tc = tcase_create("handler");
    1509             : 
    1510           1 :     tcase_add_test(tc, test_marshal_basic_types);
    1511           1 :     tcase_add_test(tc, test_get_basic_types);
    1512           1 :     tcase_add_test(tc, test_getall_basic_types);
    1513           1 :     tcase_add_test(tc, test_get_basic_array_types);
    1514           1 :     tcase_add_test(tc, test_get_array_dict_sas);
    1515             : 
    1516           1 :     return tc;
    1517             : }
    1518             : 
    1519           1 : Suite *create_suite(void)
    1520             : {
    1521           1 :     Suite *s = suite_create("sbus_codegen");
    1522             : 
    1523           1 :     suite_add_tcase(s, create_defs_tests ());
    1524           1 :     suite_add_tcase(s, create_handler_tests ());
    1525             : 
    1526           1 :     return s;
    1527             : }
    1528             : 
    1529           1 : int main(int argc, const char *argv[])
    1530             : {
    1531             :     int opt;
    1532             :     poptContext pc;
    1533             :     int failure_count;
    1534             :     Suite *suite;
    1535             :     SRunner *sr;
    1536             : 
    1537           1 :     struct poptOption long_options[] = {
    1538             :         POPT_AUTOHELP
    1539             :         POPT_TABLEEND
    1540             :     };
    1541             : 
    1542           1 :     pc = poptGetContext(argv[0], argc, argv, long_options, 0);
    1543           1 :     while ((opt = poptGetNextOpt(pc)) != -1) {
    1544             :         switch (opt) {
    1545             :         default:
    1546           0 :             fprintf(stderr, "\nInvalid option %s: %s\n\n",
    1547             :                     poptBadOption(pc, 0), poptStrerror(opt));
    1548           0 :             poptPrintUsage(pc, stderr, 0);
    1549           0 :             return 1;
    1550             :         }
    1551             :     }
    1552           1 :     poptFreeContext(pc);
    1553             : 
    1554           1 :     suite = create_suite();
    1555           1 :     sr = srunner_create(suite);
    1556             :     /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
    1557           1 :     srunner_run_all(sr, CK_ENV);
    1558           1 :     failure_count = srunner_ntests_failed(sr);
    1559           1 :     srunner_free(sr);
    1560           1 :     return (failure_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
    1561             : }

Generated by: LCOV version 1.10