[PATCH weston v3 3/5] Enables output in the Test Anything Protocol (TAP) format.

Bryce Harrington bryce at osg.samsung.com
Fri May 29 11:44:38 PDT 2015


On Tue, May 26, 2015 at 04:06:39PM -0700, Jon A. Cruz wrote:
> Adds basic support for optionally outputting in the Test Anything
> Protocol (TAP) format.
> 
> https://testanything.org/
> 
> Signed-off-by: Jon A. Cruz <jonc at osg.samsung.com>
> ---
>  Makefile.am                       |   2 +
>  tools/zunitc/inc/zunitc/zunitc.h  |   8 ++
>  tools/zunitc/src/zuc_tap_logger.c | 230 ++++++++++++++++++++++++++++++++++++++
>  tools/zunitc/src/zuc_tap_logger.h |  35 ++++++
>  tools/zunitc/src/zunitc_impl.c    |  22 +++-
>  5 files changed, 292 insertions(+), 5 deletions(-)
>  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 d92498a..7686a6d 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -960,6 +960,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
>  
> diff --git a/tools/zunitc/inc/zunitc/zunitc.h b/tools/zunitc/inc/zunitc/zunitc.h
> index 869b46a..53724d2 100644
> --- a/tools/zunitc/inc/zunitc/zunitc.h
> +++ b/tools/zunitc/inc/zunitc/zunitc.h
> @@ -190,6 +190,14 @@ void zuc_set_random(int random);
>  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..90ef90d
> --- /dev/null
> +++ b/tools/zunitc/src/zuc_tap_logger.c
> @@ -0,0 +1,230 @@
> +/*
> + * Copyright © 2015 Samsung Electronics Co., Ltd
> + *
> + * Permission to use, copy, modify, distribute, and sell this software and
> + * its documentation for any purpose is hereby granted without fee, provided
> + * that the above copyright notice appear in all copies and that both that
> + * copyright notice and this permission notice appear in supporting
> + * documentation, and that the name of the copyright holders not be used in
> + * advertising or publicity pertaining to distribution of the software
> + * without specific, written prior permission.  The copyright holders make
> + * no representations about the suitability of this software for any
> + * purpose.  It is provided "as is" without express or implied warranty.
> + *
> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS 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)

Wayland style is to put the types on their own line, with the name of
the function first thing on the following line.

> +{
> +	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_EQ:
> +		dprintf(fd, "        got     : %d\n", event->val2);
> +		dprintf(fd, "        expected: %s\n", event->expr1);
> +		dprintf(fd, "        which_is: %d\n", event->val1);
> +		break;
> +	case ZUC_OP_TERMINATE: /* fallthrough */
> +	case ZUC_OP_TRACEPOINT:
> +		break;
> +	default:
> +		dprintf(fd, "        got     : %d vs %d\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..b1a504f
> --- /dev/null
> +++ b/tools/zunitc/src/zuc_tap_logger.h
> @@ -0,0 +1,35 @@
> +/*
> + * Copyright © 2015 Samsung Electronics Co., Ltd
> + *
> + * Permission to use, copy, modify, distribute, and sell this software and
> + * its documentation for any purpose is hereby granted without fee, provided
> + * that the above copyright notice appear in all copies and that both that
> + * copyright notice and this permission notice appear in supporting
> + * documentation, and that the name of the copyright holders not be used in
> + * advertising or publicity pertaining to distribution of the software
> + * without specific, written prior permission.  The copyright holders make
> + * no representations about the suitability of this software for any
> + * purpose.  It is provided "as is" without express or implied warranty.
> + *
> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS 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 fecd7a6..758987f 100644
> --- a/tools/zunitc/src/zunitc_impl.c
> +++ b/tools/zunitc/src/zunitc_impl.c
> @@ -43,6 +43,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/zalloc.h"
> @@ -242,6 +243,11 @@ void 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;
> +}
> +
>  int zuc_initialize(int *argc, char *argv[], bool *help_flagged)
>  {
>  	int rc = EXIT_FAILURE;
> @@ -251,6 +257,7 @@ int 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;
> @@ -263,6 +270,7 @@ int 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 },
>  	};
>  
> @@ -321,6 +329,7 @@ int 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",
> @@ -336,6 +345,7 @@ int 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;
>  	}
>  
> @@ -496,11 +506,6 @@ void initialize(void)
>  		g_ctx.seed = get_seed_from_time();
>  	}
>  
> -	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.case_count) {
>  		order_cases(g_ctx.case_count, g_ctx.cases);
>  		if (g_ctx.filter && g_ctx.filter[0])
> @@ -840,6 +845,13 @@ int zucimpl_run_tests(void)
>  	if (g_ctx.fatal)
>  		return EXIT_FAILURE;
>  
> +	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) {
>  		printf("%s:%d: error: Setup error: test tree is empty\n",
>  		       __FILE__, __LINE__);
> -- 
> 2.1.0
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Code style suggestions are just cosmetics, and I don't think need to
block this going in, so:

Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>


More information about the wayland-devel mailing list