X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-marshal-recursive-util.c;h=6d62983f03c8218759dfa186940d36e26933d535;hb=0b2b6cba926a739ac56666f86ad4f88cbf5a8d48;hp=08d030abaf122bcb7be433396202320df6a8180d;hpb=fddbc09c4a9125fcb168fb31ff300d4132919ea6;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-marshal-recursive-util.c b/dbus/dbus-marshal-recursive-util.c index 08d030a..6d62983 100644 --- a/dbus/dbus-marshal-recursive-util.c +++ b/dbus/dbus-marshal-recursive-util.c @@ -1,4 +1,4 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* dbus-marshal-recursive-util.c Would be in dbus-marshal-recursive.c, but only used in bus/tests * * Copyright (C) 2004, 2005 Red Hat, Inc. @@ -17,16 +17,17 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #include -#ifdef DBUS_BUILD_TESTS +#ifdef DBUS_ENABLE_EMBEDDED_TESTS #include "dbus-marshal-recursive.h" #include "dbus-marshal-basic.h" +#include "dbus-signature.h" #include "dbus-internals.h" #include @@ -37,8 +38,8 @@ basic_value_zero (DBusBasicValue *value) #ifdef DBUS_HAVE_INT64 value->u64 = 0; #else - value->u64.first32 = 0; - value->u64.second32 = 0; + value->eight.first32 = 0; + value->eight.second32 = 0; #endif } @@ -58,8 +59,8 @@ basic_value_equal (int type, #ifdef DBUS_HAVE_INT64 return lhs->u64 == rhs->u64; #else - return lhs->u64.first32 == rhs->u64.first32 && - lhs->u64.second32 == rhs->u64.second32; + return lhs->eight.first32 == rhs->eight.first32 && + lhs->eight.second32 == rhs->eight.second32; #endif } } @@ -80,7 +81,7 @@ equal_values_helper (DBusTypeReader *lhs, if (lhs_type == DBUS_TYPE_INVALID) return TRUE; - if (_dbus_type_is_basic (lhs_type)) + if (dbus_type_is_basic (lhs_type)) { DBusBasicValue lhs_value; DBusBasicValue rhs_value; @@ -123,6 +124,9 @@ _dbus_type_reader_equal_values (const DBusTypeReader *lhs, } /* TESTS */ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + #include "dbus-test.h" #include "dbus-list.h" #include @@ -396,6 +400,26 @@ struct TestTypeNodeContainerClass * and by merging read_value and set_value into one function * taking a flag argument. */ +static dbus_bool_t int16_write_value (TestTypeNode *node, + DataBlock *block, + DBusTypeWriter *writer, + int seed); +static dbus_bool_t int16_read_value (TestTypeNode *node, + DBusTypeReader *reader, + int seed); +static dbus_bool_t int16_set_value (TestTypeNode *node, + DBusTypeReader *reader, + DBusTypeReader *realign_root, + int seed); +static dbus_bool_t int16_write_multi (TestTypeNode *node, + DataBlock *block, + DBusTypeWriter *writer, + int seed, + int count); +static dbus_bool_t int16_read_multi (TestTypeNode *node, + DBusTypeReader *reader, + int seed, + int count); static dbus_bool_t int32_write_value (TestTypeNode *node, DataBlock *block, DBusTypeWriter *writer, @@ -506,6 +530,19 @@ static dbus_bool_t struct_set_value (TestTypeNode *node, int seed); static dbus_bool_t struct_build_signature (TestTypeNode *node, DBusString *str); +static dbus_bool_t dict_write_value (TestTypeNode *node, + DataBlock *block, + DBusTypeWriter *writer, + int seed); +static dbus_bool_t dict_read_value (TestTypeNode *node, + DBusTypeReader *reader, + int seed); +static dbus_bool_t dict_set_value (TestTypeNode *node, + DBusTypeReader *reader, + DBusTypeReader *realign_root, + int seed); +static dbus_bool_t dict_build_signature (TestTypeNode *node, + DBusString *str); static dbus_bool_t array_write_value (TestTypeNode *node, DataBlock *block, DBusTypeWriter *writer, @@ -533,6 +570,35 @@ static dbus_bool_t variant_set_value (TestTypeNode *node, static void container_destroy (TestTypeNode *node); + +static const TestTypeNodeClass int16_class = { + DBUS_TYPE_INT16, + sizeof (TestTypeNode), + 0, + NULL, + NULL, + int16_write_value, + int16_read_value, + int16_set_value, + NULL, + int16_write_multi, + int16_read_multi +}; + +static const TestTypeNodeClass uint16_class = { + DBUS_TYPE_UINT16, + sizeof (TestTypeNode), + 0, + NULL, + NULL, + int16_write_value, /* recycle from int16 */ + int16_read_value, /* recycle from int16 */ + int16_set_value, /* recycle from int16 */ + NULL, + int16_write_multi, /* recycle from int16 */ + int16_read_multi /* recycle from int16 */ +}; + static const TestTypeNodeClass int32_class = { DBUS_TYPE_INT32, sizeof (TestTypeNode), @@ -745,6 +811,20 @@ static const TestTypeNodeClass struct_2_class = { NULL }; +static const TestTypeNodeClass dict_1_class = { + DBUS_TYPE_ARRAY, /* this is correct, a dict is an array of dict entry */ + sizeof (TestTypeNodeContainer), + 1, /* number of entries */ + NULL, + container_destroy, + dict_write_value, + dict_read_value, + dict_set_value, + dict_build_signature, + NULL, + NULL +}; + static dbus_bool_t arrays_write_fixed_in_blocks = FALSE; static const TestTypeNodeClass array_0_class = { @@ -819,6 +899,8 @@ static const TestTypeNodeClass variant_class = { static const TestTypeNodeClass* const basic_nodes[] = { + &int16_class, + &uint16_class, &int32_class, &uint32_class, &int64_class, @@ -842,7 +924,8 @@ container_nodes[] = { &struct_2_class, &array_0_class, &array_2_class, - &variant_class + &variant_class, + &dict_1_class /* last since we want struct and array before it */ /* array_9_class is omitted on purpose, it's too slow; * we only use it in one hardcoded test below */ @@ -865,7 +948,7 @@ node_new (const TestTypeNodeClass *klass) if (!(* klass->construct) (node)) { dbus_free (node); - return FALSE; + return NULL; } } @@ -903,23 +986,11 @@ node_read_value (TestTypeNode *node, DBusTypeReader *reader, int seed) { - DBusTypeMark mark; - DBusTypeReader restored; - - _dbus_type_reader_save_mark (reader, &mark); + /* DBusTypeReader restored; */ if (!(* node->klass->read_value) (node, reader, seed)) return FALSE; - _dbus_type_reader_init_from_mark (&restored, - reader->byte_order, - reader->type_str, - reader->value_str, - &mark); - - if (!(* node->klass->read_value) (node, &restored, seed)) - return FALSE; - return TRUE; } @@ -1019,7 +1090,7 @@ run_test_copy (NodeIterationData *nid) DBusTypeReader reader; DBusTypeWriter writer; - _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME); + _dbus_verbose ("\n"); src = nid->block; @@ -1082,7 +1153,7 @@ run_test_values_only_write (NodeIterationData *nid) dbus_bool_t retval; int sig_len; - _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME); + _dbus_verbose ("\n"); retval = FALSE; @@ -1150,7 +1221,7 @@ run_test_set_values (NodeIterationData *nid) dbus_bool_t retval; int i; - _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME); + _dbus_verbose ("\n"); retval = FALSE; @@ -1207,7 +1278,7 @@ run_test_delete_values (NodeIterationData *nid) dbus_bool_t retval; int t; - _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME); + _dbus_verbose ("\n"); retval = FALSE; @@ -1853,6 +1924,14 @@ make_and_run_test_nodes (void) node_destroy (node); } + if (_dbus_getenv ("DBUS_TEST_SLOW") == NULL || + atoi (_dbus_getenv ("DBUS_TEST_SLOW")) < 1) + { + fprintf (stderr, "skipping remaining marshal-recursive tests, " + "run with DBUS_TEST_SLOW=1 (or more) to enable\n"); + goto out; + } + start_next_test ("Each container of each container of each value %d iterations\n", N_CONTAINERS * N_CONTAINERS * N_VALUES); for (i = 0; i < N_CONTAINERS; i++) @@ -1925,8 +2004,15 @@ make_and_run_test_nodes (void) node_destroy (outer_container); } -#if 0 - /* This one takes a really long time, so comment it out for now */ + /* This one takes a really long time (10 minutes on a Core2), so only enable + * it if you're really sure */ + if (atoi (_dbus_getenv ("DBUS_TEST_SLOW")) < 2) + { + fprintf (stderr, "skipping really slow marshal-recursive test, " + "run with DBUS_TEST_SLOW=2 (or more) to enable\n"); + goto out; + } + start_next_test ("Each value,value,value triplet combination as toplevel, in all orders %d iterations\n", N_VALUES * N_VALUES * N_VALUES); { @@ -1950,8 +2036,8 @@ make_and_run_test_nodes (void) node_destroy (nodes[0]); } } -#endif /* #if 0 expensive test */ +out: fprintf (stderr, "%d total iterations of recursive marshaling tests\n", n_iterations_completed_total); fprintf (stderr, "each iteration ran at initial offsets 0 through %d in both big and little endian\n", @@ -1978,6 +2064,142 @@ _dbus_marshal_recursive_test (void) */ #define MAX_MULTI_COUNT 5 +#define SAMPLE_INT16 1234 +#define SAMPLE_INT16_ALTERNATE 6785 +static dbus_int16_t +int16_from_seed (int seed) +{ + /* Generate an integer value that's predictable from seed. We could + * just use seed itself, but that would only ever touch one byte of + * the int so would miss some kinds of bug. + */ + dbus_int16_t v; + + v = 42; /* just to quiet compiler afaik */ + switch (seed % 5) + { + case 0: + v = SAMPLE_INT16; + break; + case 1: + v = SAMPLE_INT16_ALTERNATE; + break; + case 2: + v = -1; + break; + case 3: + v = _DBUS_INT16_MAX; + break; + case 4: + v = 1; + break; + } + + if (seed > 1) + v *= seed; /* wraps around eventually, which is fine */ + + return v; +} + +static dbus_bool_t +int16_write_value (TestTypeNode *node, + DataBlock *block, + DBusTypeWriter *writer, + int seed) +{ + /* also used for uint16 */ + dbus_int16_t v; + + v = int16_from_seed (seed); + + return _dbus_type_writer_write_basic (writer, + node->klass->typecode, + &v); +} + +static dbus_bool_t +int16_read_value (TestTypeNode *node, + DBusTypeReader *reader, + int seed) +{ + /* also used for uint16 */ + dbus_int16_t v; + + check_expected_type (reader, node->klass->typecode); + + _dbus_type_reader_read_basic (reader, + (dbus_int16_t*) &v); + + _dbus_assert (v == int16_from_seed (seed)); + + return TRUE; +} + +static dbus_bool_t +int16_set_value (TestTypeNode *node, + DBusTypeReader *reader, + DBusTypeReader *realign_root, + int seed) +{ + /* also used for uint16 */ + dbus_int16_t v; + + v = int16_from_seed (seed); + + return _dbus_type_reader_set_basic (reader, + &v, + realign_root); +} + +static dbus_bool_t +int16_write_multi (TestTypeNode *node, + DataBlock *block, + DBusTypeWriter *writer, + int seed, + int count) +{ + /* also used for uint16 */ + dbus_int16_t values[MAX_MULTI_COUNT]; + dbus_int16_t *v_ARRAY_INT16 = values; + int i; + + for (i = 0; i < count; ++i) + values[i] = int16_from_seed (seed + i); + + return _dbus_type_writer_write_fixed_multi (writer, + node->klass->typecode, + &v_ARRAY_INT16, count); +} + +static dbus_bool_t +int16_read_multi (TestTypeNode *node, + DBusTypeReader *reader, + int seed, + int count) +{ + /* also used for uint16 */ + dbus_int16_t *values; + int n_elements; + int i; + + check_expected_type (reader, node->klass->typecode); + + _dbus_type_reader_read_fixed_multi (reader, + &values, + &n_elements); + + if (n_elements != count) + _dbus_warn ("got %d elements expected %d\n", n_elements, count); + _dbus_assert (n_elements == count); + + for (i = 0; i < count; i++) + _dbus_assert (((dbus_int16_t)_dbus_unpack_uint16 (reader->byte_order, + (const unsigned char*)values + (i * 2))) == + int16_from_seed (seed + i)); + + return TRUE; +} + #define SAMPLE_INT32 12345678 #define SAMPLE_INT32_ALTERNATE 53781429 @@ -2242,9 +2464,10 @@ string_write_value (TestTypeNode *node, DBusTypeWriter *writer, int seed) { - char buf[MAX_SAMPLE_STRING_LEN]; + char buf[MAX_SAMPLE_STRING_LEN + 1]=""; const char *v_string = buf; + string_from_seed (buf, node->klass->subclass_detail, seed); @@ -2259,7 +2482,8 @@ string_read_value (TestTypeNode *node, int seed) { const char *v; - char buf[MAX_SAMPLE_STRING_LEN]; + char buf[MAX_SAMPLE_STRING_LEN + 1]; + v = buf; check_expected_type (reader, node->klass->typecode); @@ -2285,7 +2509,7 @@ string_set_value (TestTypeNode *node, DBusTypeReader *realign_root, int seed) { - char buf[MAX_SAMPLE_STRING_LEN]; + char buf[MAX_SAMPLE_STRING_LEN + 1]; const char *v_string = buf; string_from_seed (buf, node->klass->subclass_detail, @@ -2442,8 +2666,8 @@ double_read_value (TestTypeNode *node, if (!_DBUS_DOUBLES_BITWISE_EQUAL (v, expected)) { -#ifdef DBUS_HAVE_INT64 - _dbus_warn ("Expected double %g got %g\n bits = 0x%llx vs.\n bits = 0x%llx)\n", +#ifdef DBUS_INT64_PRINTF_MODIFIER + _dbus_warn ("Expected double %g got %g\n bits = 0x%" DBUS_INT64_PRINTF_MODIFIER "x vs.\n bits = 0x%" DBUS_INT64_PRINTF_MODIFIER "x)\n", expected, v, *(dbus_uint64_t*)(char*)&expected, *(dbus_uint64_t*)(char*)&v); @@ -2514,7 +2738,7 @@ object_path_write_value (TestTypeNode *node, DBusTypeWriter *writer, int seed) { - char buf[MAX_SAMPLE_OBJECT_PATH_LEN]; + char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1]; const char *v_string = buf; object_path_from_seed (buf, seed); @@ -2530,7 +2754,7 @@ object_path_read_value (TestTypeNode *node, int seed) { const char *v; - char buf[MAX_SAMPLE_OBJECT_PATH_LEN]; + char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1]; check_expected_type (reader, node->klass->typecode); @@ -2555,7 +2779,7 @@ object_path_set_value (TestTypeNode *node, DBusTypeReader *realign_root, int seed) { - char buf[MAX_SAMPLE_OBJECT_PATH_LEN]; + char buf[MAX_SAMPLE_OBJECT_PATH_LEN + 1]; const char *v_string = buf; object_path_from_seed (buf, seed); @@ -2570,8 +2794,6 @@ static void signature_from_seed (char *buf, int seed) { - int i; - const char *s; /* try to avoid ascending, descending, or alternating length to help find bugs */ const char *sample_signatures[] = { "asax" @@ -2582,13 +2804,7 @@ signature_from_seed (char *buf, "a(ii)" }; - s = sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)]; - - for (i = 0; s[i]; i++) - { - buf[i] = s[i]; - } - buf[i] = '\0'; + strcpy (buf, sample_signatures[seed % _DBUS_N_ELEMENTS(sample_signatures)]); } static dbus_bool_t @@ -2597,7 +2813,7 @@ signature_write_value (TestTypeNode *node, DBusTypeWriter *writer, int seed) { - char buf[MAX_SAMPLE_SIGNATURE_LEN]; + char buf[MAX_SAMPLE_SIGNATURE_LEN + 1]; const char *v_string = buf; signature_from_seed (buf, seed); @@ -2613,7 +2829,7 @@ signature_read_value (TestTypeNode *node, int seed) { const char *v; - char buf[MAX_SAMPLE_SIGNATURE_LEN]; + char buf[MAX_SAMPLE_SIGNATURE_LEN + 1]; check_expected_type (reader, node->klass->typecode); @@ -2639,7 +2855,7 @@ signature_set_value (TestTypeNode *node, DBusTypeReader *realign_root, int seed) { - char buf[MAX_SAMPLE_SIGNATURE_LEN]; + char buf[MAX_SAMPLE_SIGNATURE_LEN + 1]; const char *v_string = buf; signature_from_seed (buf, seed); @@ -2858,7 +3074,7 @@ array_write_value (TestTypeNode *node, goto oom; if (arrays_write_fixed_in_blocks && - _dbus_type_is_fixed (element_type) && + dbus_type_is_fixed (element_type) && child->klass->write_multi) { if (!node_write_multi (child, block, &sub, seed, n_copies)) @@ -2922,7 +3138,7 @@ array_read_or_set_value (TestTypeNode *node, _dbus_type_reader_recurse (reader, &sub); if (realign_root == NULL && arrays_write_fixed_in_blocks && - _dbus_type_is_fixed (_dbus_type_reader_get_element_type (reader)) && + dbus_type_is_fixed (_dbus_type_reader_get_element_type (reader)) && child->klass->read_multi) { if (!node_read_multi (child, &sub, seed, n_copies)) @@ -3112,6 +3328,230 @@ variant_set_value (TestTypeNode *node, return variant_read_or_set_value (node, reader, realign_root, seed); } +static dbus_bool_t +dict_write_value (TestTypeNode *node, + DataBlock *block, + DBusTypeWriter *writer, + int seed) +{ + TestTypeNodeContainer *container = (TestTypeNodeContainer*) node; + DataBlockState saved; + DBusTypeWriter sub; + DBusString entry_value_signature; + DBusString dict_entry_signature; + int i; + int n_entries; + TestTypeNode *child; + + n_entries = node->klass->subclass_detail; + + _dbus_assert (container->children != NULL); + + data_block_save (block, &saved); + + if (!_dbus_string_init (&entry_value_signature)) + return FALSE; + + if (!_dbus_string_init (&dict_entry_signature)) + { + _dbus_string_free (&entry_value_signature); + return FALSE; + } + + child = _dbus_list_get_first (&container->children); + + if (!node_build_signature (child, + &entry_value_signature)) + goto oom; + + if (!_dbus_string_append (&dict_entry_signature, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_INT32_AS_STRING)) + goto oom; + + if (!_dbus_string_copy (&entry_value_signature, 0, + &dict_entry_signature, + _dbus_string_get_length (&dict_entry_signature))) + goto oom; + + if (!_dbus_string_append_byte (&dict_entry_signature, + DBUS_DICT_ENTRY_END_CHAR)) + goto oom; + + if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_ARRAY, + &dict_entry_signature, 0, + &sub)) + goto oom; + + i = 0; + while (i < n_entries) + { + DBusTypeWriter entry_sub; + dbus_int32_t key; + + if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_DICT_ENTRY, + NULL, 0, + &entry_sub)) + goto oom; + + key = int32_from_seed (seed + i); + + if (!_dbus_type_writer_write_basic (&entry_sub, + DBUS_TYPE_INT32, + &key)) + goto oom; + + if (!node_write_value (child, block, &entry_sub, seed + i)) + goto oom; + + if (!_dbus_type_writer_unrecurse (&sub, &entry_sub)) + goto oom; + + ++i; + } + + if (!_dbus_type_writer_unrecurse (writer, &sub)) + goto oom; + + _dbus_string_free (&entry_value_signature); + _dbus_string_free (&dict_entry_signature); + return TRUE; + + oom: + data_block_restore (block, &saved); + _dbus_string_free (&entry_value_signature); + _dbus_string_free (&dict_entry_signature); + return FALSE; +} + +static dbus_bool_t +dict_read_or_set_value (TestTypeNode *node, + DBusTypeReader *reader, + DBusTypeReader *realign_root, + int seed) +{ + TestTypeNodeContainer *container = (TestTypeNodeContainer*) node; + DBusTypeReader sub; + int i; + int n_entries; + TestTypeNode *child; + + n_entries = node->klass->subclass_detail; + + check_expected_type (reader, DBUS_TYPE_ARRAY); + + child = _dbus_list_get_first (&container->children); + + if (n_entries > 0) + { + _dbus_type_reader_recurse (reader, &sub); + + check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY); + + i = 0; + while (i < n_entries) + { + DBusTypeReader entry_sub; + + check_expected_type (&sub, DBUS_TYPE_DICT_ENTRY); + + _dbus_type_reader_recurse (&sub, &entry_sub); + + if (realign_root == NULL) + { + dbus_int32_t v; + + check_expected_type (&entry_sub, DBUS_TYPE_INT32); + + _dbus_type_reader_read_basic (&entry_sub, + (dbus_int32_t*) &v); + + _dbus_assert (v == int32_from_seed (seed + i)); + + NEXT_EXPECTING_TRUE (&entry_sub); + + if (!node_read_value (child, &entry_sub, seed + i)) + return FALSE; + + NEXT_EXPECTING_FALSE (&entry_sub); + } + else + { + dbus_int32_t v; + + v = int32_from_seed (seed + i); + + if (!_dbus_type_reader_set_basic (&entry_sub, + &v, + realign_root)) + return FALSE; + + NEXT_EXPECTING_TRUE (&entry_sub); + + if (!node_set_value (child, &entry_sub, realign_root, seed + i)) + return FALSE; + + NEXT_EXPECTING_FALSE (&entry_sub); + } + + if (i == (n_entries - 1)) + NEXT_EXPECTING_FALSE (&sub); + else + NEXT_EXPECTING_TRUE (&sub); + + ++i; + } + } + + return TRUE; +} + +static dbus_bool_t +dict_read_value (TestTypeNode *node, + DBusTypeReader *reader, + int seed) +{ + return dict_read_or_set_value (node, reader, NULL, seed); +} + +static dbus_bool_t +dict_set_value (TestTypeNode *node, + DBusTypeReader *reader, + DBusTypeReader *realign_root, + int seed) +{ + return dict_read_or_set_value (node, reader, realign_root, seed); +} + +static dbus_bool_t +dict_build_signature (TestTypeNode *node, + DBusString *str) +{ + TestTypeNodeContainer *container = (TestTypeNodeContainer*) node; + int orig_len; + + orig_len = _dbus_string_get_length (str); + + if (!_dbus_string_append_byte (str, DBUS_TYPE_ARRAY)) + goto oom; + + if (!_dbus_string_append (str, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_INT32_AS_STRING)) + goto oom; + + if (!node_build_signature (_dbus_list_get_first (&container->children), + str)) + goto oom; + + if (!_dbus_string_append_byte (str, DBUS_DICT_ENTRY_END_CHAR)) + goto oom; + + return TRUE; + + oom: + _dbus_string_set_length (str, orig_len); + return FALSE; +} + static void container_destroy (TestTypeNode *node) { @@ -3132,4 +3572,6 @@ container_destroy (TestTypeNode *node) } } -#endif /* DBUS_BUILD_TESTS */ +#endif /* !DOXYGEN_SHOULD_SKIP_THIS */ + +#endif /* DBUS_ENABLE_EMBEDDED_TESTS */