summaryrefslogtreecommitdiff
path: root/cesar/lib/test/trace
diff options
context:
space:
mode:
authorsave2008-04-07 14:17:42 +0000
committersave2008-04-07 14:17:42 +0000
commit3d58a62727346b7ac1a6cb36fed1a06ed72228dd (patch)
treed7788c3cf9f76426aef0286d0202e2097f0fa0eb /cesar/lib/test/trace
parent095dca4b0a8d4924093bab424f71f588fdd84613 (diff)
Moved the complete svn base into the cesar directory.
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@1769 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/lib/test/trace')
-rw-r--r--cesar/lib/test/trace/Config2
-rw-r--r--cesar/lib/test/trace/Makefile7
-rw-r--r--cesar/lib/test/trace/src/test_trace.c302
3 files changed, 311 insertions, 0 deletions
diff --git a/cesar/lib/test/trace/Config b/cesar/lib/test/trace/Config
new file mode 100644
index 0000000000..79839151a9
--- /dev/null
+++ b/cesar/lib/test/trace/Config
@@ -0,0 +1,2 @@
+CONFIG_DEBUG_MORE = y
+CONFIG_TRACE = y
diff --git a/cesar/lib/test/trace/Makefile b/cesar/lib/test/trace/Makefile
new file mode 100644
index 0000000000..475dfc75b9
--- /dev/null
+++ b/cesar/lib/test/trace/Makefile
@@ -0,0 +1,7 @@
+BASE = ../../..
+
+HOST_PROGRAMS = test_trace
+test_trace_SOURCES = test_trace.c
+test_trace_MODULES = lib
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/lib/test/trace/src/test_trace.c b/cesar/lib/test/trace/src/test_trace.c
new file mode 100644
index 0000000000..c2d1f0e8ff
--- /dev/null
+++ b/cesar/lib/test/trace/src/test_trace.c
@@ -0,0 +1,302 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_trace.c
+ * \brief Trace test.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/rnd.h"
+#include "lib/trace.h"
+#include "lib/test.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define NB_ITER 100000
+#define MAX_ARGS 8
+
+#define NB_PRINT 1000
+
+struct growing_buffer_t
+{
+ char *buf;
+ uint buf_pos;
+ uint buf_size;
+};
+typedef struct growing_buffer_t growing_buffer_t;
+
+int
+dump_callback (void *user, char *text, uint text_size)
+{
+ dbg_assert (user);
+ dbg_assert (text && text_size != 0);
+ growing_buffer_t *g = user;
+ /* Grow buffer if necessary. */
+ if (g->buf_pos + text_size >= g->buf_size)
+ {
+ g->buf_size = (g->buf_size + text_size) * 2;
+ g->buf = realloc (g->buf, g->buf_size);
+ dbg_assert (g->buf);
+ }
+ /* Copy data. */
+ memcpy (g->buf + g->buf_pos, text, text_size);
+ g->buf_pos += text_size;
+ return text_size;
+}
+
+void
+growing_sprintf (growing_buffer_t *g, const char *fmt, ...)
+{
+ dbg_assert (g);
+ dbg_assert (fmt);
+ va_list ap;
+ va_start (ap, fmt);
+ do
+ {
+ int ret = vsnprintf (g->buf + g->buf_pos, g->buf_size - g->buf_pos,
+ fmt, ap);
+ // Hum, ecos does not use the same meaning for the return value.
+ if (ret != -1 && ret < (int) (g->buf_size - g->buf_pos - 1))
+ {
+ g->buf_pos += ret;
+ break;
+ }
+ else
+ {
+ g->buf_size *= 2;
+ g->buf = realloc (g->buf, g->buf_size);
+ dbg_assert (g->buf);
+ }
+ } while (1);
+}
+
+void
+trace_basic_test_case (test_t t)
+{
+ uint i, j;
+ lib_rnd_t rnd[1];
+ trace_buffer_t trace_buf[3];
+ uint sum[COUNT (trace_buf)] = { };
+ /* Initialise. */
+ test_case_begin (t, "basic");
+ lib_rnd_init (rnd, 1234);
+ trace_init ();
+ /* Test. */
+ test_begin (t, "massive print and drop")
+ {
+ trace_buffer_add (&trace_buf[0], "one", 2, 4, true, NULL);
+ trace_buffer_add (&trace_buf[1], "two", 2, 1, false, NULL);
+ trace_buffer_add (&trace_buf[2], "three", 0, 1, false, NULL);
+ for (i = 0; i < NB_ITER; i++)
+ {
+ if (lib_rnd_flip_coin (rnd, LIB_RND_RATIO (0.995)))
+ {
+ /* Trace. */
+ uint buf_i = lib_rnd_uniform (rnd, COUNT (trace_buf));
+ uint arg_nb = lib_rnd_uniform (rnd, MAX_ARGS + 1);
+ uint args[MAX_ARGS];
+ for (j = 0; j < arg_nb; j++)
+ args[j] = lib_rnd32 (rnd);
+ /* trace_(fast_)?print\d (...) {{{ */
+ if (trace_buf[buf_i].locked)
+ {
+ switch (arg_nb)
+ {
+ case 8:
+ trace_fast_print8 (&trace_buf[buf_i], i, args[0],
+ args[1], args[2], args[3], args[4],
+ args[5], args[6], args[7]);
+ break;
+ case 7:
+ trace_fast_print7 (&trace_buf[buf_i], i, args[0],
+ args[1], args[2], args[3], args[4],
+ args[5], args[6]);
+ break;
+ case 6:
+ trace_fast_print6 (&trace_buf[buf_i], i, args[0],
+ args[1], args[2], args[3], args[4],
+ args[5]);
+ break;
+ case 5:
+ trace_fast_print5 (&trace_buf[buf_i], i, args[0],
+ args[1], args[2], args[3],
+ args[4]);
+ break;
+ case 4:
+ trace_fast_print4 (&trace_buf[buf_i], i, args[0],
+ args[1], args[2], args[3]);
+ break;
+ case 3:
+ trace_fast_print3 (&trace_buf[buf_i], i, args[0],
+ args[1], args[2]);
+ break;
+ case 2:
+ trace_fast_print2 (&trace_buf[buf_i], i, args[0],
+ args[1]);
+ break;
+ case 1:
+ trace_fast_print1 (&trace_buf[buf_i], i, args[0]);
+ break;
+ case 0:
+ trace_fast_print0 (&trace_buf[buf_i], i);
+ break;
+ }
+ }
+ else
+ {
+ switch (arg_nb)
+ {
+ case 8:
+ trace_print8 (&trace_buf[buf_i], i, args[0], args[1],
+ args[2], args[3], args[4], args[5],
+ args[6], args[7]);
+ break;
+ case 7:
+ trace_print7 (&trace_buf[buf_i], i, args[0], args[1],
+ args[2], args[3], args[4], args[5],
+ args[6]);
+ break;
+ case 6:
+ trace_print6 (&trace_buf[buf_i], i, args[0], args[1],
+ args[2], args[3], args[4], args[5]);
+ break;
+ case 5:
+ trace_print5 (&trace_buf[buf_i], i, args[0], args[1],
+ args[2], args[3], args[4]);
+ break;
+ case 4:
+ trace_print4 (&trace_buf[buf_i], i, args[0], args[1],
+ args[2], args[3]);
+ break;
+ case 3:
+ trace_print3 (&trace_buf[buf_i], i, args[0], args[1],
+ args[2]);
+ break;
+ case 2:
+ trace_print2 (&trace_buf[buf_i], i, args[0], args[1]);
+ break;
+ case 1:
+ trace_print1 (&trace_buf[buf_i], i, args[0]);
+ break;
+ case 0:
+ trace_print0 (&trace_buf[buf_i], i);
+ break;
+ }
+ }
+ /* }}} */
+ }
+ else
+ {
+ /* Drop chunks. */
+ uint chunks_nb = 0;
+ for (j = 0; j < COUNT (trace_buf); j++)
+ {
+ dbg_assert (trace_buf[j].chunks_nb
+ >= trace_buf[j].preload);
+ chunks_nb += trace_buf[j].chunks_nb
+ - trace_buf[j].preload;
+ }
+ trace_drop_chunks (1 + (chunks_nb > 30
+ ? lib_rnd_uniform (rnd, chunks_nb - 30)
+ : 0));
+ }
+ for (j = 0; j < COUNT (trace_buf); j++)
+ sum[j] += trace_buf[j].chunks_nb;
+ }
+ test_verbose_print ("avg chunks_nb: %d %d %d",
+ sum[0] / NB_ITER,
+ sum[1] / NB_ITER,
+ sum[2] / NB_ITER);
+ trace_buffer_remove (&trace_buf[0]);
+ trace_buffer_remove (&trace_buf[1]);
+ trace_buffer_remove (&trace_buf[2]);
+ } test_end;
+ test_begin (t, "dump")
+ {
+#define TEST_TRACE_TRACE(id, args...) \
+ TRACE_SHORT (TEST_TRACE_TRACE_, &trace_buf[0], id, ## args)
+ enum
+ {
+ TEST_TRACE_TRACE_ONE,
+ TEST_TRACE_TRACE_TWO,
+ TEST_TRACE_TRACE_THREE,
+ TEST_TRACE_TRACE_FOUR,
+ };
+ static const trace_event_id_t ei[] = {
+ TRACE_EVENT (TEST_TRACE_TRACE_ONE, "one"),
+ TRACE_EVENT (TEST_TRACE_TRACE_TWO, "two %d", TIMESTAMP),
+ TRACE_EVENT (TEST_TRACE_TRACE_THREE, "three %u, %x, %d, %b, %b"),
+ TRACE_EVENT (TEST_TRACE_TRACE_FOUR, "four %m, %d"),
+ };
+ trace_namespace_t ns;
+ trace_namespace_init (&ns, ei, COUNT (ei));
+ trace_buffer_add (&trace_buf[0], "trace", 2, 1, false, &ns);
+ /* Trace and record expected trace. */
+ growing_buffer_t expected_dump;
+ expected_dump.buf_pos = 0;
+ expected_dump.buf_size = 100;
+ expected_dump.buf = malloc (expected_dump.buf_size);
+ dbg_assert (expected_dump.buf);
+ for (i = 0; i < NB_PRINT; i++)
+ {
+ trace_print0 (&trace_buf[0], TEST_TRACE_TRACE_ONE);
+ growing_sprintf (&expected_dump, "[.] one\n");
+ TEST_TRACE_TRACE (TWO, 0x123abc ^ i, -123456789 + i);
+ growing_sprintf (&expected_dump, "[0x%08x] two %d\n",
+ 0x123abc ^ i, -123456789 + i);
+ TEST_TRACE_TRACE (THREE, 123456789 - i, 0xabcdef ^ i, 1, true,
+ false);
+ growing_sprintf (&expected_dump,
+ "[.] three %u, 0x%08x, %d, %s, %s\n",
+ 123456789 - i, 0xabcdef ^ i, 1, "true", "false");
+ TEST_TRACE_TRACE (FOUR, TRACE_U64 (0xbc9a78563412LL), i);
+ growing_sprintf (&expected_dump,
+ "[.] four 12:34:56:78:9a:bc, %d\n", i);
+ }
+ test_verbose_print ("%s", expected_dump.buf);
+ /* Dump to memory. */
+ growing_buffer_t dump;
+ dump.buf_pos = 0;
+ dump.buf_size = 100;
+ dump.buf = malloc (dump.buf_size);
+ dbg_assert (dump.buf);
+ int ret = trace_buffer_dump (&trace_buf[0], dump_callback, &dump);
+ /* Check dump. */
+ test_fail_unless (expected_dump.buf_pos == dump.buf_pos);
+ test_fail_unless ((int) dump.buf_pos == ret);
+ test_fail_unless (memcmp (expected_dump.buf, dump.buf, dump.buf_pos)
+ == 0);
+ /* Cleanup. */
+ free (expected_dump.buf);
+ free (dump.buf);
+ trace_buffer_remove (&trace_buf[0]);
+ } test_end;
+ /* Uninit. */
+ trace_uninit ();
+}
+
+void
+trace_test_suite (test_t t)
+{
+ test_suite_begin (t, "trace");
+ trace_basic_test_case (t);
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ test_init (t, argc, argv);
+ trace_test_suite (t);
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}