[PATCH weston v5 3/6] Enables output in the Test Anything Protocol (TAP) format.
Jon A. Cruz
jonc at osg.samsung.com
Sat Jun 20 15:47:45 PDT 2015
Adds basic support for optionally outputting in the Test Anything
Protocol (TAP) format.
This format is a bit older and simplistic, but certain tools
handle it well.
https://testanything.org/
Signed-off-by: Jon A. Cruz <jonc at osg.samsung.com>
---
Makefile.am | 2 +
tools/zunitc/inc/zunitc/zunitc.h | 9 ++
tools/zunitc/src/zuc_tap_logger.c | 265 ++++++++++++++++++++++++++++++++++++++
tools/zunitc/src/zuc_tap_logger.h | 39 ++++++
tools/zunitc/src/zunitc_impl.c | 13 ++
5 files changed, 328 insertions(+)
create mode 100644 tools/zunitc/src/zuc_tap_logger.c
create mode 100644 tools/zunitc/src/zuc_tap_logger.h
diff --git a/Makefile.am b/Makefile.am
index efb24b0..4b6bb97 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1018,6 +1018,8 @@ libzunitc_la_SOURCES = \
tools/zunitc/src/zuc_context.h \
tools/zunitc/src/zuc_event.h \
tools/zunitc/src/zuc_event_listener.h \
+ tools/zunitc/src/zuc_tap_logger.c \
+ tools/zunitc/src/zuc_tap_logger.h \
tools/zunitc/src/zuc_types.h \
tools/zunitc/src/zunitc_impl.c \
shared/helpers.h
diff --git a/tools/zunitc/inc/zunitc/zunitc.h b/tools/zunitc/inc/zunitc/zunitc.h
index f97ad6a..559cdd0 100644
--- a/tools/zunitc/inc/zunitc/zunitc.h
+++ b/tools/zunitc/inc/zunitc/zunitc.h
@@ -235,6 +235,15 @@ void
zuc_set_spawn(bool spawn);
/**
+ * Enables output in the Test Anything Protocol (TAP) format.
+ * https://testanything.org/
+ *
+ * @param enable true to generate TAP output, false to disable.
+ */
+void
+zuc_set_output_tap(bool enable);
+
+/**
* Defines a test case that can be registered to run.
*/
#define ZUC_TEST(tcase, test) \
diff --git a/tools/zunitc/src/zuc_tap_logger.c b/tools/zunitc/src/zuc_tap_logger.c
new file mode 100644
index 0000000..4142e30
--- /dev/null
+++ b/tools/zunitc/src/zuc_tap_logger.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright © 2015 Samsung Electronics Co., Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "config.h"
+
+#include "zuc_tap_logger.h"
+
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "shared/zalloc.h"
+#include "zuc_event_listener.h"
+#include "zuc_types.h"
+#include "zunitc/zunitc_impl.h"
+
+#define LOG_FNAME "test_detail.tap"
+
+/**
+ * Internal data for tracking and proper output.
+ */
+struct tap_data {
+ int fd; /**< file descriptor to output to. */
+ int id; /**< counter id of the current test. */
+};
+
+/**
+ * Helper that outputs the detail of a specific failure event.
+ *
+ * @param fd the file descriptor to write to.
+ * @param event the event to write the details of.
+ */
+static void
+emit_event(int fd, struct zuc_event *event);
+
+static void
+destroy(void *data);
+
+static void
+run_started(void *data, int live_case_count, int live_test_count,
+ int disabled_count);
+
+static void
+run_ended(void *data, int case_count, struct zuc_case **cases,
+ int live_case_count, int live_test_count, int total_passed,
+ int total_failed, int total_disabled, long total_elapsed);
+
+static void
+test_ended(void *data, struct zuc_test *test);
+
+static void
+test_disabled(void *data, struct zuc_test *test);
+
+struct zuc_event_listener *
+zuc_tap_logger_create(void)
+{
+ struct zuc_event_listener *listener =
+ zalloc(sizeof(struct zuc_event_listener));
+
+ listener->data = zalloc(sizeof(struct tap_data));
+ ((struct tap_data *)listener->data)->fd = -1;
+ listener->destroy = destroy;
+ listener->run_started = run_started;
+ listener->run_ended = run_ended;
+ listener->test_ended = test_ended;
+ listener->test_disabled = test_disabled;
+
+ return listener;
+}
+
+void
+destroy(void *data)
+{
+ free(data);
+}
+
+void
+run_started(void *data, int live_case_count, int live_test_count,
+ int disabled_count)
+{
+ struct tap_data *tdata = data;
+ tdata->fd = open(LOG_FNAME, O_WRONLY | O_CLOEXEC | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
+ tdata->id = 0;
+ dprintf(tdata->fd, "TAP version 13\n");
+ dprintf(tdata->fd, "1..%d\n", live_test_count + disabled_count);
+}
+
+void
+run_ended(void *data, int case_count, struct zuc_case **cases,
+ int live_case_count, int live_test_count, int total_passed,
+ int total_failed, int total_disabled,long total_elapsed)
+{
+ struct tap_data *tdata = data;
+ if ((tdata->fd != fileno(stdout))
+ && (tdata->fd != fileno(stderr))
+ && (tdata->fd != -1)) {
+ close(tdata->fd);
+ tdata->fd = -1;
+ }
+}
+
+void
+test_ended(void *data, struct zuc_test *test)
+{
+ struct tap_data *tdata = data;
+ bool bad = test->failed || test->fatal;
+ tdata->id++;
+ if (bad)
+ dprintf(tdata->fd, "not ok %d - %s.%s\n",
+ tdata->id,
+ test->test_case->name,
+ test->name);
+ else if (test->skipped)
+ dprintf(tdata->fd, "ok %d - # SKIP at runtime %s.%s\n",
+ tdata->id,
+ test->test_case->name,
+ test->name);
+ else
+ dprintf(tdata->fd, "ok %d - %s.%s\n",
+ tdata->id,
+ test->test_case->name,
+ test->name);
+
+ if ((bad || test->skipped) && test->events) {
+ struct zuc_event *evt;
+ dprintf(tdata->fd, " ---\n");
+ for (evt = test->events; evt; evt = evt->next)
+ emit_event(tdata->fd, evt);
+ dprintf(tdata->fd, " ...\n");
+ }
+}
+
+void
+test_disabled(void *data, struct zuc_test *test)
+{
+ struct tap_data *tdata = data;
+ tdata->id++;
+ dprintf(tdata->fd, "ok %d - # SKIP disabled %s.%s\n",
+ tdata->id,
+ test->test_case->name,
+ test->name);
+}
+
+void
+emit_event(int fd, struct zuc_event *event)
+{
+ dprintf(fd, " - message: '");
+
+ switch (event->op) {
+ case ZUC_OP_TRUE:
+ dprintf(fd, "%s:%d: error: Value of: %s",
+ event->file, event->line, event->expr1);
+ break;
+ case ZUC_OP_FALSE:
+ dprintf(fd, "%s:%d: error: Value of: %s",
+ event->file, event->line, event->expr1);
+ break;
+ case ZUC_OP_EQ:
+ dprintf(fd, "%s:%d: error: Value of: %s",
+ event->file, event->line, event->expr2);
+ break;
+ case ZUC_OP_TERMINATE:
+ dprintf(fd, "%s:%d: error: %s",
+ event->file, event->line, event->expr1);
+ break;
+ case ZUC_OP_TRACEPOINT:
+ dprintf(fd, "%s:%d: note: %s",
+ event->file, event->line, event->expr1);
+ break;
+ default:
+ dprintf(fd, "%s:%d: error", event->file, event->line);
+ }
+ dprintf(fd, "'\n");
+
+ if ((event->op != ZUC_OP_TRACEPOINT)
+ && ((event->op != ZUC_OP_TERMINATE) || (event->val1 < 2)))
+ dprintf(fd, " severity: fail\n");
+
+ if ((event->op != ZUC_OP_TRACEPOINT) && (event->op != ZUC_OP_TERMINATE))
+ dprintf(fd, " data:\n");
+
+ switch (event->op) {
+ case ZUC_OP_TRUE:
+ dprintf(fd, " got : false\n");
+ dprintf(fd, " expected: true\n");
+ break;
+ case ZUC_OP_FALSE:
+ dprintf(fd, " got : true\n");
+ dprintf(fd, " expected: false\n");
+ break;
+ case ZUC_OP_NULL:
+ dprintf(fd, " got : %s\n", event->expr1);
+ dprintf(fd, " which_is: %p\n", (void *)event->val1);
+ dprintf(fd, " expected: %p\n", NULL);
+ break;
+ case ZUC_OP_NOT_NULL:
+ dprintf(fd, " got : %s\n", event->expr1);
+ dprintf(fd, " which_is: %p\n", (void *)event->val1);
+ dprintf(fd, " expected: not %p\n", NULL);
+ break;
+ case ZUC_OP_EQ:
+ if (event->valtype == ZUC_VAL_CSTR) {
+ dprintf(fd, " got : %s\n",
+ (char *)event->val2);
+ dprintf(fd, " expected: %s\n", event->expr1);
+ dprintf(fd, " which_is: %s\n",
+ (char *)event->val1);
+ } else {
+ dprintf(fd, " got : %ld\n", event->val2);
+ dprintf(fd, " expected: %s\n", event->expr1);
+ dprintf(fd, " which_is: %ld\n", event->val1);
+ }
+ break;
+ case ZUC_OP_NE:
+ if (event->valtype == ZUC_VAL_CSTR) {
+ dprintf(fd, " got : %s == %s\n",
+ (char *)event->val1, (char *)event->val2);
+ dprintf(fd, " expected: (%s) %s (%s)\n",
+ event->expr1, zuc_get_opstr(event->op),
+ event->expr2);
+ } else {
+ dprintf(fd, " got : %ld vs %ld\n",
+ event->val1, event->val2);
+ dprintf(fd, " expected: (%s) %s (%s)\n",
+ event->expr1, zuc_get_opstr(event->op),
+ event->expr2);
+ }
+ break;
+ case ZUC_OP_TERMINATE: /* fallthrough */
+ case ZUC_OP_TRACEPOINT:
+ break;
+ default:
+ dprintf(fd, " got : %ld vs %ld\n",
+ event->val1, event->val2);
+ dprintf(fd, " expected: (%s) %s (%s)\n",
+ event->expr1, zuc_get_opstr(event->op), event->expr2);
+ }
+}
diff --git a/tools/zunitc/src/zuc_tap_logger.h b/tools/zunitc/src/zuc_tap_logger.h
new file mode 100644
index 0000000..c370cdd
--- /dev/null
+++ b/tools/zunitc/src/zuc_tap_logger.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2015 Samsung Electronics Co., Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ZUC_TAP_LOGGER_H
+#define ZUC_TAP_LOGGER_H
+
+struct zuc_event_listener;
+
+/**
+ * Creates a new logger that outputs data in the Test Anything Protocol
+ * (TAP) format.
+ * https://testanything.org/
+ */
+struct zuc_event_listener *
+zuc_tap_logger_create(void);
+
+#endif /* ZUC_TAP_LOGGER_H */
diff --git a/tools/zunitc/src/zunitc_impl.c b/tools/zunitc/src/zunitc_impl.c
index d904749..7e34aca 100644
--- a/tools/zunitc/src/zunitc_impl.c
+++ b/tools/zunitc/src/zunitc_impl.c
@@ -46,6 +46,7 @@
#include "zuc_collector.h"
#include "zuc_context.h"
#include "zuc_event_listener.h"
+#include "zuc_tap_logger.h"
#include "shared/config-parser.h"
#include "shared/helpers.h"
@@ -290,6 +291,12 @@ zuc_set_break_on_failure(bool break_on_failure)
g_ctx.break_on_failure = break_on_failure;
}
+void
+zuc_set_output_tap(bool enable)
+{
+ g_ctx.output_tap = enable;
+}
+
const char *
zuc_get_program_name(void)
{
@@ -312,6 +319,7 @@ zuc_initialize(int *argc, char *argv[], bool *help_flagged)
int opt_repeat = 0;
int opt_random = 0;
int opt_break_on_failure = 0;
+ int opt_tap = 0;
char *opt_filter = NULL;
char *help_param = NULL;
@@ -324,6 +332,7 @@ zuc_initialize(int *argc, char *argv[], bool *help_flagged)
{ WESTON_OPTION_INTEGER, "zuc-random", 0, &opt_random },
{ WESTON_OPTION_BOOLEAN, "zuc-break-on-failure", 0,
&opt_break_on_failure },
+ { WESTON_OPTION_BOOLEAN, "zuc-output-tap", 0, &opt_tap },
{ WESTON_OPTION_STRING, "zuc-filter", 0, &opt_filter },
};
@@ -412,6 +421,7 @@ zuc_initialize(int *argc, char *argv[], bool *help_flagged)
" --zuc-filter=FILTER\n"
" --zuc-list-tests\n"
" --zuc-nofork\n"
+ " --zuc-output-tap\n"
" --zuc-random=N [0|1|<seed number>]\n"
" --zuc-repeat=N\n"
" --help\n",
@@ -427,6 +437,7 @@ zuc_initialize(int *argc, char *argv[], bool *help_flagged)
zuc_set_random(opt_random);
zuc_set_spawn(!opt_nofork);
zuc_set_break_on_failure(opt_break_on_failure);
+ zuc_set_output_tap(opt_tap);
rc = EXIT_SUCCESS;
}
@@ -959,6 +970,8 @@ zucimpl_run_tests(void)
if (g_ctx.listeners == NULL) {
zuc_add_event_listener(zuc_collector_create(&(g_ctx.fds[1])));
zuc_add_event_listener(zuc_base_logger_create());
+ if (g_ctx.output_tap)
+ zuc_add_event_listener(zuc_tap_logger_create());
}
if (g_ctx.case_count < 1) {
--
2.1.0
More information about the wayland-devel
mailing list