diff options
| author | Havoc Pennington <hp@redhat.com> | 2005-01-02 02:17:05 +0000 | 
|---|---|---|
| committer | Havoc Pennington <hp@redhat.com> | 2005-01-02 02:17:05 +0000 | 
| commit | 50103620b3d3a76ebecac0c9f6873ece8fa0d1f1 (patch) | |
| tree | 0da74469c38d7704709bfe77252351314efc4de4 | |
| parent | 441907e73affff202c75564f4c4b968ff37f094b (diff) | |
extend unit test to display progress and to verify that we are inserting not appending in all cases
| -rw-r--r-- | dbus/dbus-marshal-recursive.c | 298 | 
1 files changed, 225 insertions, 73 deletions
diff --git a/dbus/dbus-marshal-recursive.c b/dbus/dbus-marshal-recursive.c index a01b254b..6848e83b 100644 --- a/dbus/dbus-marshal-recursive.c +++ b/dbus/dbus-marshal-recursive.c @@ -840,6 +840,27 @@ _dbus_type_reader_next (DBusTypeReader *reader)   *   */ +/** + * Initialize a write iterator, which is used to write out values in + * serialized D-BUS format. #DBusTypeWriter is a value iterator; it + * writes out values. You can't use it to write out only types. + * + * The type_pos passed in is expected to be inside an already-valid, + * though potentially empty, type signature. This means that the byte + * after type_pos must be either #DBUS_TYPE_INVALID (aka nul) or some + * other valid type. #DBusTypeWriter won't enforce that the signature + * is already valid (you can append the nul byte at the end if you + * like), but just be aware that you need the nul byte eventually and + * #DBusTypeWriter isn't going to write it for you. + * + * @param writer the writer to init + * @param byte_order the byte order to marshal into + * @param type_str the string to write typecodes into + * @param type_pos where to insert typecodes + * @param value_str the string to write values into + * @param value_pos where to insert values + *  + */  void  _dbus_type_writer_init (DBusTypeWriter *writer,                          int             byte_order, @@ -1374,6 +1395,8 @@ _dbus_type_writer_write_array (DBusTypeWriter *writer,  typedef struct  { +  int byte_order; +  int initial_offset;    DBusString signature;    DBusString body;  } DataBlock; @@ -1384,8 +1407,14 @@ typedef struct    int saved_body_len;  } DataBlockState; +#define N_FENCE_BYTES 5 +#define FENCE_BYTES_STR "abcde" +#define INITIAL_PADDING_BYTE '\0' +  static dbus_bool_t -data_block_init (DataBlock *block) +data_block_init (DataBlock *block, +                 int        byte_order, +                 int        initial_offset)  {    if (!_dbus_string_init (&block->signature))      return FALSE; @@ -1396,58 +1425,124 @@ data_block_init (DataBlock *block)        return FALSE;      } -  return TRUE; -} +  if (!_dbus_string_insert_bytes (&block->signature, 0, initial_offset, +                                  INITIAL_PADDING_BYTE) || +      !_dbus_string_insert_bytes (&block->body, 0, initial_offset, +                                  INITIAL_PADDING_BYTE) || +      !_dbus_string_append (&block->signature, FENCE_BYTES_STR) || +      !_dbus_string_append (&block->body, FENCE_BYTES_STR)) +    { +      _dbus_string_free (&block->signature); +      _dbus_string_free (&block->body); +      return FALSE; +    } -static void -data_block_free (DataBlock *block) -{ -  _dbus_string_free (&block->signature); -  _dbus_string_free (&block->body); +  block->byte_order = byte_order; +  block->initial_offset = initial_offset; +   +  return TRUE;  }  static void  data_block_save (DataBlock      *block,                   DataBlockState *state)  { -  state->saved_sig_len = _dbus_string_get_length (&block->signature); -  state->saved_body_len = _dbus_string_get_length (&block->body); +  state->saved_sig_len = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES; +  state->saved_body_len = _dbus_string_get_length (&block->body) - N_FENCE_BYTES;  }  static void  data_block_restore (DataBlock      *block,                      DataBlockState *state)  { -  /* These set_length should be shortening things so should always work */ +  _dbus_string_delete (&block->signature, +                       state->saved_sig_len, +                       _dbus_string_get_length (&block->signature) - state->saved_sig_len - N_FENCE_BYTES); +  _dbus_string_delete (&block->body, +                       state->saved_body_len, +                       _dbus_string_get_length (&block->body) - state->saved_body_len - N_FENCE_BYTES); +} + +static void +data_block_verify (DataBlock *block) +{ +  if (!_dbus_string_ends_with_c_str (&block->signature, +                                     FENCE_BYTES_STR)) +    { +      int offset; + +      offset = _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - 8; +      if (offset < 0) +        offset = 0; +       +      _dbus_verbose_bytes_of_string (&block->signature, +                                     offset, +                                     _dbus_string_get_length (&block->signature) - offset); +      _dbus_assert_not_reached ("block did not verify: bad bytes at end of signature"); +    } +  if (!_dbus_string_ends_with_c_str (&block->body, +                                     FENCE_BYTES_STR)) +    { +      int offset; -  if (!_dbus_string_set_length (&block->signature, -                                state->saved_sig_len)) -    _dbus_assert_not_reached ("could not restore signature length"); +      offset = _dbus_string_get_length (&block->body) - N_FENCE_BYTES - 8; +      if (offset < 0) +        offset = 0; -  if (!_dbus_string_set_length (&block->body, -                                state->saved_body_len)) -    _dbus_assert_not_reached ("could not restore body length"); +      _dbus_verbose_bytes_of_string (&block->body, +                                     offset, +                                     _dbus_string_get_length (&block->body) - offset); +      _dbus_assert_not_reached ("block did not verify: bad bytes at end of body"); +    } +   +  _dbus_assert (_dbus_string_validate_nul (&block->signature, +                                           0, block->initial_offset)); +  _dbus_assert (_dbus_string_validate_nul (&block->body, +                                           0, block->initial_offset)); +} + +static void +data_block_free (DataBlock *block) +{ +  data_block_verify (block); +   +  _dbus_string_free (&block->signature); +  _dbus_string_free (&block->body); +} + +static void +data_block_reset (DataBlock *block) +{ +  data_block_verify (block); +   +  _dbus_string_delete (&block->signature, +                       block->initial_offset, +                       _dbus_string_get_length (&block->signature) - N_FENCE_BYTES - block->initial_offset); +  _dbus_string_delete (&block->body, +                       block->initial_offset, +                       _dbus_string_get_length (&block->body) - N_FENCE_BYTES - block->initial_offset); + +  data_block_verify (block);  }  static void  data_block_init_reader_writer (DataBlock      *block, -                               int             byte_order,                                 DBusTypeReader *reader,                                 DBusTypeWriter *writer)  {    _dbus_type_reader_init (reader, -                          byte_order, +                          block->byte_order,                            &block->signature, -                          _dbus_string_get_length (&block->signature), +                          _dbus_string_get_length (&block->signature) - N_FENCE_BYTES,                            &block->body, -                          _dbus_string_get_length (&block->body)); +                          _dbus_string_get_length (&block->body) - N_FENCE_BYTES);    _dbus_type_writer_init (writer, -                          byte_order, +                          block->byte_order,                            &block->signature, -                          _dbus_string_get_length (&block->signature), +                          _dbus_string_get_length (&block->signature) - N_FENCE_BYTES,                            &block->body, -                          _dbus_string_get_length (&block->body)); +                          _dbus_string_get_length (&block->body) - N_FENCE_BYTES);  }  static void @@ -1490,9 +1585,6 @@ real_check_expected_type (DBusTypeReader *reader,   check_expected_type (reader, DBUS_TYPE_INVALID);                                       \  } while (0) -#define SAMPLE_INT32           12345678 -#define SAMPLE_INT32_ALTERNATE 53781429 -  typedef struct TestTypeNode               TestTypeNode;  typedef struct TestTypeNodeClass          TestTypeNodeClass;  typedef struct TestTypeNodeContainer      TestTypeNodeContainer; @@ -1923,7 +2015,16 @@ node_write_value (TestTypeNode   *node,                    DBusTypeWriter *writer,                    int             seed)  { -  return (* node->klass->write_value) (node, block, writer, seed); +  dbus_bool_t retval; +   +  retval = (* node->klass->write_value) (node, block, writer, seed); + +#if 0 +  /* Handy to see where things break, but too expensive to do all the time */ +  data_block_verify (block); +#endif +   +  return retval;  }  static dbus_bool_t @@ -1979,12 +2080,15 @@ node_append_child (TestTypeNode *node,    return TRUE;  } +static int n_iterations_completed_total = 0; +static int n_iterations_completed_this_test = 0; +static int n_iterations_expected_this_test = 0; +  typedef struct  {    const DBusString   *signature;    DataBlock          *block;    int                 type_offset; -  int                 byte_order;    TestTypeNode      **nodes;    int                 n_nodes;  } NodeIterationData; @@ -1996,6 +2100,7 @@ run_test_nodes_iteration (void *data)    DBusTypeReader reader;    DBusTypeWriter writer;    int i; +  dbus_bool_t retval;    /* Stuff to do:     * 1. write the value @@ -2003,15 +2108,23 @@ run_test_nodes_iteration (void *data)     * 3. read the value     * 4. type-iterate the signature and the value and see if they are the same type-wise     */ +  retval = FALSE; +      data_block_init_reader_writer (nid->block, -                                 nid->byte_order,                                   &reader, &writer); +  /* DBusTypeWriter assumes it's writing into an existing signature, +   * so doesn't add nul on its own. We have to do that. +   */ +  if (!_dbus_string_insert_byte (&nid->block->signature, +                                 nid->type_offset, '\0')) +    goto out; +      i = 0;    while (i < nid->n_nodes)      {        if (!node_write_value (nid->nodes[i], nid->block, &writer, i)) -        return FALSE; +        goto out;        ++i;      } @@ -2030,7 +2143,7 @@ run_test_nodes_iteration (void *data)    while (i < nid->n_nodes)      {        if (!node_read_value (nid->nodes[i], nid->block, &reader, i)) -        return FALSE; +        goto out;        if (i + 1 == nid->n_nodes)          NEXT_EXPECTING_FALSE (&reader); @@ -2044,9 +2157,21 @@ run_test_nodes_iteration (void *data)     * tree to the node tree     */ -  return TRUE; +  retval = TRUE; +   + out: +   +  data_block_reset (nid->block); +   +  return retval;  } +#define TEST_OOM_HANDLING 0 +/* We do start offset 0 through 9, to get various alignment cases. Still this + * obviously makes the test suite run 10x as slow. + */ +#define MAX_INITIAL_OFFSET 9 +  static void  run_test_nodes_in_one_configuration (TestTypeNode    **nodes,                                       int               n_nodes, @@ -2057,13 +2182,7 @@ run_test_nodes_in_one_configuration (TestTypeNode    **nodes,    DataBlock block;    NodeIterationData nid; -  if (!data_block_init (&block)) -    _dbus_assert_not_reached ("no memory"); - -  if (!_dbus_string_lengthen (&block.signature, initial_offset)) -    _dbus_assert_not_reached ("no memory"); - -  if (!_dbus_string_lengthen (&block.body, initial_offset)) +  if (!data_block_init (&block, byte_order, initial_offset))      _dbus_assert_not_reached ("no memory");    nid.signature = signature; @@ -2071,12 +2190,8 @@ run_test_nodes_in_one_configuration (TestTypeNode    **nodes,    nid.type_offset = initial_offset;    nid.nodes = nodes;    nid.n_nodes = n_nodes; -  nid.byte_order = byte_order; -  /* FIXME put the OOM testing back once we debug everything and are willing to -   * wait for it to run ;-) -   */ -#if 0 +#if TEST_OOM_HANDLING    _dbus_test_oom_handling ("running test node",                             run_test_nodes_iteration,                             &nid); @@ -2110,11 +2225,8 @@ run_test_nodes (TestTypeNode **nodes,    _dbus_verbose (">>> test nodes with signature '%s'\n",                   _dbus_string_get_const_data (&signature)); -  /* We do start offset 0 through 9, to get various alignment cases. Still this -   * obviously makes the test suite run 10x as slow. -   */    i = 0; -  while (i < 10) +  while (i <= MAX_INITIAL_OFFSET)      {        run_test_nodes_in_one_configuration (nodes, n_nodes, &signature,                                             DBUS_LITTLE_ENDIAN, i); @@ -2124,6 +2236,22 @@ run_test_nodes (TestTypeNode **nodes,        ++i;      } +  n_iterations_completed_this_test += 1; +  n_iterations_completed_total += 1; + +  if (n_iterations_completed_this_test == n_iterations_expected_this_test) +    { +      fprintf (stderr, " 100%% %d this test (%d cumulative)\n", +               n_iterations_completed_this_test, +               n_iterations_completed_total); +    } +  /* this happens to turn out well with mod == 1 */ +  else if ((n_iterations_completed_this_test % +            (int)(n_iterations_expected_this_test / 10.0)) == 1) +    { +      fprintf (stderr, " %d%% ", (int) (n_iterations_completed_this_test / (double) n_iterations_expected_this_test * 100)); +    } +      _dbus_string_free (&signature);  } @@ -2209,6 +2337,18 @@ make_and_run_values_inside_container (const TestTypeNodeClass *container_klass,  }  static void +start_next_test (const char *format, +                 int         expected) +{ +  n_iterations_completed_this_test = 0; +  n_iterations_expected_this_test = expected; + +  fprintf (stderr, ">>> >>> "); +  fprintf (stderr, format,  +           n_iterations_expected_this_test); +} + +static void  make_and_run_test_nodes (void)  {    int i, j, k, m; @@ -2245,8 +2385,7 @@ make_and_run_test_nodes (void)    /* FIXME test just an empty body, no types at all */ -  _dbus_verbose (">>> >>> Each value by itself %d iterations\n", -                 N_VALUES); +  start_next_test ("Each value by itself %d iterations\n", N_VALUES);    {      TestTypeNode *node;      i = 0; @@ -2258,7 +2397,7 @@ make_and_run_test_nodes (void)        }    } -  _dbus_verbose (">>> >>> All values in one big toplevel 1 iteration\n"); +  start_next_test ("All values in one big toplevel %d iteration\n", 1);    {      TestTypeNode *nodes[N_VALUES]; @@ -2272,8 +2411,8 @@ make_and_run_test_nodes (void)        node_destroy (nodes[i]);    } -  _dbus_verbose (">>> >>> Each value,value pair combination as toplevel, in both orders %d iterations\n", -                 N_VALUES * N_VALUES * 2); +  start_next_test ("Each value,value pair combination as toplevel, in both orders %d iterations\n", +                   N_VALUES * N_VALUES);    {      TestTypeNode *nodes[2]; @@ -2292,8 +2431,8 @@ make_and_run_test_nodes (void)        }    } -  _dbus_verbose (">>> >>> Each container containing each value %d iterations\n", -                 N_CONTAINERS * N_VALUES); +  start_next_test ("Each container containing each value %d iterations\n", +                   N_CONTAINERS * N_VALUES);    for (i = 0; i < N_CONTAINERS; i++)      {        const TestTypeNodeClass *container_klass = container_nodes[i]; @@ -2301,8 +2440,10 @@ make_and_run_test_nodes (void)        make_and_run_values_inside_container (container_klass, 1);      } +  n_iterations_completed_this_test = 0; +  n_iterations_expected_this_test = N_CONTAINERS * N_VALUES;    _dbus_verbose (">>> >>> Each container of same container of each value %d iterations\n", -                 N_CONTAINERS * N_VALUES); +                 n_iterations_completed_this_test);    for (i = 0; i < N_CONTAINERS; i++)      {        const TestTypeNodeClass *container_klass = container_nodes[i]; @@ -2310,8 +2451,8 @@ make_and_run_test_nodes (void)        make_and_run_values_inside_container (container_klass, 2);      } -  _dbus_verbose (">>> >>> Each container of same container of same container of each value %d iterations\n", -                 N_CONTAINERS * N_VALUES); +  start_next_test ("Each container of same container of same container of each value %d iterations\n", +                   N_CONTAINERS * N_VALUES);    for (i = 0; i < N_CONTAINERS; i++)      {        const TestTypeNodeClass *container_klass = container_nodes[i]; @@ -2319,8 +2460,8 @@ make_and_run_test_nodes (void)        make_and_run_values_inside_container (container_klass, 3);      } -  _dbus_verbose (">>> >>> Each value,value pair inside a struct %d iterations\n", -                 N_VALUES * N_VALUES); +  start_next_test ("Each value,value pair inside a struct %d iterations\n", +                   N_VALUES * N_VALUES);    {      TestTypeNode *val1, *val2;      TestTypeNode *node; @@ -2348,7 +2489,8 @@ make_and_run_test_nodes (void)      node_destroy (node);    } -  _dbus_verbose (">>> >>> all values in one big struct 1 iteration\n"); +  start_next_test ("All values in one big struct %d iteration\n", +                   1);    {      TestTypeNode *node;      TestTypeNode *child; @@ -2364,8 +2506,8 @@ make_and_run_test_nodes (void)      node_destroy (node);    } -  _dbus_verbose (">>> >>> Each value in a large array %d iterations\n", -                 N_VALUES); +  start_next_test ("Each value in a large array %d iterations\n", +                   N_VALUES);    {      TestTypeNode *val;      TestTypeNode *node; @@ -2388,8 +2530,8 @@ make_and_run_test_nodes (void)      node_destroy (node);    } -  _dbus_verbose (">>> >>> Each container of each container of each value %d iterations\n", -                 N_CONTAINERS * N_CONTAINERS * N_VALUES); +  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++)      {        const TestTypeNodeClass *outer_container_klass = container_nodes[i]; @@ -2419,10 +2561,8 @@ 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 */ -  _dbus_verbose (">>> >>> Each container of each container of each container of each value %d iterations\n", -                 N_CONTAINERS * N_CONTAINERS * N_CONTAINERS * N_VALUES); +  start_next_test ("Each container of each container of each container of each value %d iterations\n", +                   N_CONTAINERS * N_CONTAINERS * N_CONTAINERS * N_VALUES);    for (i = 0; i < N_CONTAINERS; i++)      {        const TestTypeNodeClass *outer_container_klass = container_nodes[i]; @@ -2461,10 +2601,11 @@ make_and_run_test_nodes (void)          }        node_destroy (outer_container);      } -#endif /* #if 0 expensive test */ -  _dbus_verbose (">>> >>> Each value,value,value triplet combination as toplevel, in all orders %d iterations\n", -                 N_VALUES * N_VALUES * N_VALUES); +#if 0 +  /* This one takes a really long time, so comment it out for now */ +  start_next_test ("Each value,value,value triplet combination as toplevel, in all orders %d iterations\n", +                   N_VALUES * N_VALUES * N_VALUES);    {      TestTypeNode *nodes[3]; @@ -2486,6 +2627,14 @@ make_and_run_test_nodes (void)          node_destroy (nodes[0]);        }    } +#endif /* #if 0 expensive test */ + +  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", +           MAX_INITIAL_OFFSET); +  fprintf (stderr, "out of memory handling %s tested\n", +           TEST_OOM_HANDLING ? "was" : "was not");  }  dbus_bool_t _dbus_marshal_recursive_test (void); @@ -2521,6 +2670,9 @@ main (int argc, char **argv)   *   */ + +#define SAMPLE_INT32           12345678 +#define SAMPLE_INT32_ALTERNATE 53781429  static dbus_int32_t  int32_from_seed (int seed)  {  | 
