summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2005-01-02 02:17:05 +0000
committerHavoc Pennington <hp@redhat.com>2005-01-02 02:17:05 +0000
commit50103620b3d3a76ebecac0c9f6873ece8fa0d1f1 (patch)
tree0da74469c38d7704709bfe77252351314efc4de4
parent441907e73affff202c75564f4c4b968ff37f094b (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.c298
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)
{