zuc: Delete support for forking tests
ZUC's default mode is to fork for every test case. Unfortunately on AArch64, fork in an ASan-traced program usually takes around 3.6 entire seconds. This was leading to the config-parser test timing out. As none of our remaining ZUC tests even need to fork, just remove all support for it. Signed-off-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
@@ -107,8 +107,6 @@ lib_zuc = static_library(
|
|||||||
'../tools/zunitc/inc/zunitc/zunitc_impl.h',
|
'../tools/zunitc/inc/zunitc/zunitc_impl.h',
|
||||||
'../tools/zunitc/src/zuc_base_logger.c',
|
'../tools/zunitc/src/zuc_base_logger.c',
|
||||||
'../tools/zunitc/src/zuc_base_logger.h',
|
'../tools/zunitc/src/zuc_base_logger.h',
|
||||||
'../tools/zunitc/src/zuc_collector.c',
|
|
||||||
'../tools/zunitc/src/zuc_collector.h',
|
|
||||||
'../tools/zunitc/src/zuc_context.h',
|
'../tools/zunitc/src/zuc_context.h',
|
||||||
'../tools/zunitc/src/zuc_event.h',
|
'../tools/zunitc/src/zuc_event.h',
|
||||||
'../tools/zunitc/src/zuc_event_listener.h',
|
'../tools/zunitc/src/zuc_event_listener.h',
|
||||||
|
|||||||
@@ -239,16 +239,6 @@ zuc_set_repeat(int repeat);
|
|||||||
void
|
void
|
||||||
zuc_set_random(int random);
|
zuc_set_random(int random);
|
||||||
|
|
||||||
/**
|
|
||||||
* Controls whether or not to run the tests as forked child processes.
|
|
||||||
* Defaults to true.
|
|
||||||
*
|
|
||||||
* @param spawn true to spawn each test in a forked child process,
|
|
||||||
* false to run tests directly.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
zuc_set_spawn(bool spawn);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables output in the JUnit XML format.
|
* Enables output in the JUnit XML format.
|
||||||
* Defaults to false.
|
* Defaults to false.
|
||||||
|
|||||||
@@ -1,427 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_collector.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <libweston/zalloc.h>
|
|
||||||
#include "zuc_event_listener.h"
|
|
||||||
#include "zunitc/zunitc_impl.h"
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* General handling of collecting events during testing to pass back to
|
|
||||||
* main tracking of fork()'d tests.
|
|
||||||
*
|
|
||||||
* @note implementation of zuc_process_message() is included here so that
|
|
||||||
* all child->parent IPC is in a single source file for easier maintenance
|
|
||||||
* and updating.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal data struct for processing.
|
|
||||||
*/
|
|
||||||
struct collector_data
|
|
||||||
{
|
|
||||||
int *fd; /**< file descriptor to output to. */
|
|
||||||
struct zuc_test *test; /**< current test, or NULL. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores an int32_t into the given buffer.
|
|
||||||
*
|
|
||||||
* @param ptr the buffer to store to.
|
|
||||||
* @param val the value to store.
|
|
||||||
* @return a pointer to the position in the buffer after the stored value.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
pack_int32(char *ptr, int32_t val);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores an intptr_t into the given buffer.
|
|
||||||
*
|
|
||||||
* @param ptr the buffer to store to.
|
|
||||||
* @param val the value to store.
|
|
||||||
* @return a pointer to the position in the buffer after the stored value.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
pack_intptr_t(char *ptr, intptr_t val);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts a int32_t from the given buffer.
|
|
||||||
*
|
|
||||||
* @param ptr the buffer to extract from.
|
|
||||||
* @param val the value to set.
|
|
||||||
* @return a pointer to the position in the buffer after the extracted
|
|
||||||
* value.
|
|
||||||
*/
|
|
||||||
static char const *
|
|
||||||
unpack_int32(char const *ptr, int32_t *val);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts a intptr_t from the given buffer.
|
|
||||||
*
|
|
||||||
* @param ptr the buffer to extract from.
|
|
||||||
* @param val the value to set.
|
|
||||||
* @return a pointer to the position in the buffer after the extracted
|
|
||||||
* value.
|
|
||||||
*/
|
|
||||||
static char const *
|
|
||||||
unpack_intptr_t(char const *ptr, intptr_t *val);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts a length-prefixed string from the given buffer.
|
|
||||||
*
|
|
||||||
* @param ptr the buffer to extract from.
|
|
||||||
* @param str the value to set.
|
|
||||||
* @return a pointer to the position in the buffer after the extracted
|
|
||||||
* value.
|
|
||||||
*/
|
|
||||||
static char const *
|
|
||||||
unpack_string(char const *ptr, char **str);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extracts an event from the given buffer.
|
|
||||||
*
|
|
||||||
* @param ptr the buffer to extract from.
|
|
||||||
* @param len the length of the given buffer.
|
|
||||||
* @return an event that was packed in the buffer
|
|
||||||
*/
|
|
||||||
static struct zuc_event *
|
|
||||||
unpack_event(char const *ptr, int32_t len);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles an event by either attaching it directly or sending it over IPC
|
|
||||||
* as needed.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
store_event(struct collector_data *cdata,
|
|
||||||
enum zuc_event_type event_type, char const *file, int line,
|
|
||||||
enum zuc_fail_state state, enum zuc_check_op op,
|
|
||||||
enum zuc_check_valtype valtype,
|
|
||||||
intptr_t val1, intptr_t val2, const char *expr1, const char *expr2);
|
|
||||||
|
|
||||||
static void
|
|
||||||
destroy(void *data);
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_started(void *data, struct zuc_test *test);
|
|
||||||
|
|
||||||
static void
|
|
||||||
test_ended(void *data, struct zuc_test *test);
|
|
||||||
|
|
||||||
static void
|
|
||||||
check_triggered(void *data, char const *file, int line,
|
|
||||||
enum zuc_fail_state state, enum zuc_check_op op,
|
|
||||||
enum zuc_check_valtype valtype,
|
|
||||||
intptr_t val1, intptr_t val2,
|
|
||||||
const char *expr1, const char *expr2);
|
|
||||||
|
|
||||||
static void
|
|
||||||
collect_event(void *data, char const *file, int line, const char *expr1);
|
|
||||||
|
|
||||||
struct zuc_event_listener *
|
|
||||||
zuc_collector_create(int *pipe_fd)
|
|
||||||
{
|
|
||||||
struct zuc_event_listener *listener =
|
|
||||||
zalloc(sizeof(struct zuc_event_listener));
|
|
||||||
|
|
||||||
listener->data = zalloc(sizeof(struct collector_data));
|
|
||||||
((struct collector_data *)listener->data)->fd = pipe_fd;
|
|
||||||
listener->destroy = destroy;
|
|
||||||
listener->test_started = test_started;
|
|
||||||
listener->test_ended = test_ended;
|
|
||||||
listener->check_triggered = check_triggered;
|
|
||||||
listener->collect_event = collect_event;
|
|
||||||
|
|
||||||
return listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
pack_int32(char *ptr, int32_t val)
|
|
||||||
{
|
|
||||||
memcpy(ptr, &val, sizeof(val));
|
|
||||||
return ptr + sizeof(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
pack_intptr_t(char *ptr, intptr_t val)
|
|
||||||
{
|
|
||||||
memcpy(ptr, &val, sizeof(val));
|
|
||||||
return ptr + sizeof(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
|
||||||
pack_cstr(char *ptr, intptr_t val, int len)
|
|
||||||
{
|
|
||||||
if (val == 0) { /* a null pointer */
|
|
||||||
ptr = pack_int32(ptr, -1);
|
|
||||||
} else {
|
|
||||||
ptr = pack_int32(ptr, len);
|
|
||||||
memcpy(ptr, (const char *)val, len);
|
|
||||||
ptr += len;
|
|
||||||
}
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
destroy(void *data)
|
|
||||||
{
|
|
||||||
free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
test_started(void *data, struct zuc_test *test)
|
|
||||||
{
|
|
||||||
struct collector_data *cdata = data;
|
|
||||||
cdata->test = test;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
test_ended(void *data, struct zuc_test *test)
|
|
||||||
{
|
|
||||||
struct collector_data *cdata = data;
|
|
||||||
cdata->test = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
check_triggered(void *data, char const *file, int line,
|
|
||||||
enum zuc_fail_state state, enum zuc_check_op op,
|
|
||||||
enum zuc_check_valtype valtype,
|
|
||||||
intptr_t val1, intptr_t val2,
|
|
||||||
const char *expr1, const char *expr2)
|
|
||||||
{
|
|
||||||
struct collector_data *cdata = data;
|
|
||||||
if (op != ZUC_OP_TRACEPOINT)
|
|
||||||
store_event(cdata, ZUC_EVENT_IMMEDIATE, file, line, state, op,
|
|
||||||
valtype,
|
|
||||||
val1, val2, expr1, expr2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
collect_event(void *data, char const *file, int line, const char *expr1)
|
|
||||||
{
|
|
||||||
struct collector_data *cdata = data;
|
|
||||||
store_event(cdata, ZUC_EVENT_DEFERRED, file, line, ZUC_CHECK_OK,
|
|
||||||
ZUC_OP_TRACEPOINT, ZUC_VAL_INT,
|
|
||||||
0, 0, expr1, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
store_event(struct collector_data *cdata,
|
|
||||||
enum zuc_event_type event_type, char const *file, int line,
|
|
||||||
enum zuc_fail_state state, enum zuc_check_op op,
|
|
||||||
enum zuc_check_valtype valtype,
|
|
||||||
intptr_t val1, intptr_t val2, const char *expr1, const char *expr2)
|
|
||||||
{
|
|
||||||
struct zuc_event *event = zalloc(sizeof(*event));
|
|
||||||
event->file = strdup(file);
|
|
||||||
event->line = line;
|
|
||||||
event->state = state;
|
|
||||||
event->op = op;
|
|
||||||
event->valtype = valtype;
|
|
||||||
event->val1 = val1;
|
|
||||||
event->val2 = val2;
|
|
||||||
if (valtype == ZUC_VAL_CSTR) {
|
|
||||||
if (val1)
|
|
||||||
event->val1 = (intptr_t)strdup((const char *)val1);
|
|
||||||
if (val2)
|
|
||||||
event->val2 = (intptr_t)strdup((const char *)val2);
|
|
||||||
}
|
|
||||||
event->expr1 = strdup(expr1);
|
|
||||||
event->expr2 = strdup(expr2);
|
|
||||||
|
|
||||||
zuc_attach_event(cdata->test, event, event_type, false);
|
|
||||||
|
|
||||||
if (*cdata->fd == -1) {
|
|
||||||
} else {
|
|
||||||
/* Need to pass it back */
|
|
||||||
int sent;
|
|
||||||
int count;
|
|
||||||
int expr1_len = strlen(expr1);
|
|
||||||
int expr2_len = strlen(expr2);
|
|
||||||
int val1_len =
|
|
||||||
((valtype == ZUC_VAL_CSTR) && val1) ?
|
|
||||||
strlen((char *)val1) : 0;
|
|
||||||
int val2_len =
|
|
||||||
((valtype == ZUC_VAL_CSTR) && val2) ?
|
|
||||||
strlen((char *)val2) : 0;
|
|
||||||
int file_len = strlen(file);
|
|
||||||
int len = (sizeof(int32_t) * 9) + file_len
|
|
||||||
+ (sizeof(intptr_t) * 2)
|
|
||||||
+ ((valtype == ZUC_VAL_CSTR) ?
|
|
||||||
(sizeof(int32_t) * 2) + val1_len + val2_len : 0)
|
|
||||||
+ expr1_len + expr2_len;
|
|
||||||
char *buf = zalloc(len);
|
|
||||||
|
|
||||||
char *ptr = pack_int32(buf, len - 4);
|
|
||||||
ptr = pack_int32(ptr, event_type);
|
|
||||||
ptr = pack_int32(ptr, file_len);
|
|
||||||
memcpy(ptr, file, file_len);
|
|
||||||
ptr += file_len;
|
|
||||||
ptr = pack_int32(ptr, line);
|
|
||||||
ptr = pack_int32(ptr, state);
|
|
||||||
ptr = pack_int32(ptr, op);
|
|
||||||
ptr = pack_int32(ptr, valtype);
|
|
||||||
if (valtype == ZUC_VAL_CSTR) {
|
|
||||||
ptr = pack_cstr(ptr, val1, val1_len);
|
|
||||||
ptr = pack_cstr(ptr, val2, val2_len);
|
|
||||||
} else {
|
|
||||||
ptr = pack_intptr_t(ptr, val1);
|
|
||||||
ptr = pack_intptr_t(ptr, val2);
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr = pack_int32(ptr, expr1_len);
|
|
||||||
if (expr1_len) {
|
|
||||||
memcpy(ptr, expr1, expr1_len);
|
|
||||||
ptr += expr1_len;
|
|
||||||
}
|
|
||||||
ptr = pack_int32(ptr, expr2_len);
|
|
||||||
if (expr2_len) {
|
|
||||||
memcpy(ptr, expr2, expr2_len);
|
|
||||||
ptr += expr2_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sent = 0;
|
|
||||||
while (sent < len) {
|
|
||||||
count = write(*cdata->fd, buf, len);
|
|
||||||
if (count == -1)
|
|
||||||
break;
|
|
||||||
sent += count;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char const *
|
|
||||||
unpack_int32(char const *ptr, int32_t *val)
|
|
||||||
{
|
|
||||||
memcpy(val, ptr, sizeof(*val));
|
|
||||||
return ptr + sizeof(*val);
|
|
||||||
}
|
|
||||||
|
|
||||||
char const *
|
|
||||||
unpack_intptr_t(char const *ptr, intptr_t *val)
|
|
||||||
{
|
|
||||||
memcpy(val, ptr, sizeof(*val));
|
|
||||||
return ptr + sizeof(*val);
|
|
||||||
}
|
|
||||||
|
|
||||||
char const *
|
|
||||||
unpack_string(char const *ptr, char **str)
|
|
||||||
{
|
|
||||||
int32_t len = 0;
|
|
||||||
ptr = unpack_int32(ptr, &len);
|
|
||||||
*str = zalloc(len + 1);
|
|
||||||
if (len)
|
|
||||||
memcpy(*str, ptr, len);
|
|
||||||
ptr += len;
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char const *
|
|
||||||
unpack_cstr(char const *ptr, char **str)
|
|
||||||
{
|
|
||||||
int32_t len = 0;
|
|
||||||
ptr = unpack_int32(ptr, &len);
|
|
||||||
if (len < 0) {
|
|
||||||
*str = NULL;
|
|
||||||
} else {
|
|
||||||
*str = zalloc(len + 1);
|
|
||||||
if (len)
|
|
||||||
memcpy(*str, ptr, len);
|
|
||||||
ptr += len;
|
|
||||||
}
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct zuc_event *
|
|
||||||
unpack_event(char const *ptr, int32_t len)
|
|
||||||
{
|
|
||||||
int32_t val = 0;
|
|
||||||
struct zuc_event *evt = zalloc(sizeof(*evt));
|
|
||||||
char const *tmp = unpack_string(ptr, &evt->file);
|
|
||||||
tmp = unpack_int32(tmp, &evt->line);
|
|
||||||
|
|
||||||
tmp = unpack_int32(tmp, &val);
|
|
||||||
evt->state = val;
|
|
||||||
tmp = unpack_int32(tmp, &val);
|
|
||||||
evt->op = val;
|
|
||||||
tmp = unpack_int32(tmp, &val);
|
|
||||||
evt->valtype = val;
|
|
||||||
|
|
||||||
if (evt->valtype == ZUC_VAL_CSTR) {
|
|
||||||
char *ptr = NULL;
|
|
||||||
tmp = unpack_cstr(tmp, &ptr);
|
|
||||||
evt->val1 = (intptr_t)ptr;
|
|
||||||
tmp = unpack_cstr(tmp, &ptr);
|
|
||||||
evt->val2 = (intptr_t)ptr;
|
|
||||||
} else {
|
|
||||||
tmp = unpack_intptr_t(tmp, &evt->val1);
|
|
||||||
tmp = unpack_intptr_t(tmp, &evt->val2);
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = unpack_string(tmp, &evt->expr1);
|
|
||||||
tmp = unpack_string(tmp, &evt->expr2);
|
|
||||||
|
|
||||||
return evt;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
zuc_process_message(struct zuc_test *test, int fd)
|
|
||||||
{
|
|
||||||
char buf[4] = {};
|
|
||||||
int got = read(fd, buf, 4);
|
|
||||||
if (got == 4) {
|
|
||||||
enum zuc_event_type event_type = ZUC_EVENT_IMMEDIATE;
|
|
||||||
int32_t val = 0;
|
|
||||||
int32_t len = 0;
|
|
||||||
const char *tmp = NULL;
|
|
||||||
char *raw = NULL;
|
|
||||||
unpack_int32(buf, &len);
|
|
||||||
raw = zalloc(len);
|
|
||||||
got = read(fd, raw, len);
|
|
||||||
|
|
||||||
tmp = unpack_int32(raw, &val);
|
|
||||||
event_type = val;
|
|
||||||
|
|
||||||
struct zuc_event *evt = unpack_event(tmp, len - (tmp - raw));
|
|
||||||
zuc_attach_event(test, evt, event_type, true);
|
|
||||||
free(raw);
|
|
||||||
}
|
|
||||||
return got;
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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_COLLECTOR_H
|
|
||||||
#define ZUC_COLLECTOR_H
|
|
||||||
|
|
||||||
struct zuc_event_listener;
|
|
||||||
struct zuc_test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance of an event collector that will attach events
|
|
||||||
* to the current test directly or via connection from child to parent.
|
|
||||||
*
|
|
||||||
* @param pipe_fd pointer to the file descriptor to use for communication if
|
|
||||||
* needed. If the value is -1 the events will be attached directly to the
|
|
||||||
* current test. Otherwise events will be passed back via IPC over this
|
|
||||||
* pipe with the expectation that the payload will be handled in the parent
|
|
||||||
* process via zuc_process_message().
|
|
||||||
* @return a new collector instance.
|
|
||||||
* @see zuc_process_message()
|
|
||||||
*/
|
|
||||||
struct zuc_event_listener *
|
|
||||||
zuc_collector_create(int *pipe_fd);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads events from the given pipe and processes them.
|
|
||||||
*
|
|
||||||
* @param test the currently active test to attach events for.
|
|
||||||
* @param pipe_fd the file descriptor of the pipe to read from.
|
|
||||||
* @return a positive value if a message was received, 0 if the end has
|
|
||||||
* been reached and -1 if an error has occurred.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
zuc_process_message(struct zuc_test *test, int pipe_fd);
|
|
||||||
|
|
||||||
#endif /* ZUC_COLLECTOR_H */
|
|
||||||
@@ -42,11 +42,9 @@ struct zuc_context {
|
|||||||
int repeat;
|
int repeat;
|
||||||
int random;
|
int random;
|
||||||
unsigned int seed;
|
unsigned int seed;
|
||||||
bool spawn;
|
|
||||||
bool break_on_failure;
|
bool break_on_failure;
|
||||||
bool output_tap;
|
bool output_tap;
|
||||||
bool output_junit;
|
bool output_junit;
|
||||||
int fds[2];
|
|
||||||
char *filter;
|
char *filter;
|
||||||
|
|
||||||
struct zuc_slinked *listeners;
|
struct zuc_slinked *listeners;
|
||||||
|
|||||||
@@ -41,7 +41,6 @@
|
|||||||
#include "zunitc/zunitc.h"
|
#include "zunitc/zunitc.h"
|
||||||
|
|
||||||
#include "zuc_base_logger.h"
|
#include "zuc_base_logger.h"
|
||||||
#include "zuc_collector.h"
|
|
||||||
#include "zuc_context.h"
|
#include "zuc_context.h"
|
||||||
#include "zuc_event_listener.h"
|
#include "zuc_event_listener.h"
|
||||||
#include "zuc_junit_reporter.h"
|
#include "zuc_junit_reporter.h"
|
||||||
@@ -82,9 +81,7 @@ static struct zuc_context g_ctx = {
|
|||||||
.fatal = false,
|
.fatal = false,
|
||||||
.repeat = 0,
|
.repeat = 0,
|
||||||
.random = 0,
|
.random = 0,
|
||||||
.spawn = true,
|
|
||||||
.break_on_failure = false,
|
.break_on_failure = false,
|
||||||
.fds = {-1, -1},
|
|
||||||
|
|
||||||
.listeners = NULL,
|
.listeners = NULL,
|
||||||
|
|
||||||
@@ -141,12 +138,6 @@ zuc_set_random(int random)
|
|||||||
g_ctx.random = random;
|
g_ctx.random = random;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
zuc_set_spawn(bool spawn)
|
|
||||||
{
|
|
||||||
g_ctx.spawn = spawn;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
zuc_set_break_on_failure(bool break_on_failure)
|
zuc_set_break_on_failure(bool break_on_failure)
|
||||||
{
|
{
|
||||||
@@ -525,7 +516,6 @@ zuc_initialize(int *argc, char *argv[], bool *help_flagged)
|
|||||||
{
|
{
|
||||||
int rc = EXIT_FAILURE;
|
int rc = EXIT_FAILURE;
|
||||||
bool opt_help = false;
|
bool opt_help = false;
|
||||||
bool opt_nofork = false;
|
|
||||||
bool opt_list = false;
|
bool opt_list = false;
|
||||||
int opt_repeat = 0;
|
int opt_repeat = 0;
|
||||||
int opt_random = 0;
|
int opt_random = 0;
|
||||||
@@ -537,7 +527,6 @@ zuc_initialize(int *argc, char *argv[], bool *help_flagged)
|
|||||||
int argc_in = *argc;
|
int argc_in = *argc;
|
||||||
|
|
||||||
const struct weston_option options[] = {
|
const struct weston_option options[] = {
|
||||||
{ WESTON_OPTION_BOOLEAN, "zuc-nofork", 0, &opt_nofork },
|
|
||||||
{ WESTON_OPTION_BOOLEAN, "zuc-list-tests", 0, &opt_list },
|
{ WESTON_OPTION_BOOLEAN, "zuc-list-tests", 0, &opt_list },
|
||||||
{ WESTON_OPTION_INTEGER, "zuc-repeat", 0, &opt_repeat },
|
{ WESTON_OPTION_INTEGER, "zuc-repeat", 0, &opt_repeat },
|
||||||
{ WESTON_OPTION_INTEGER, "zuc-random", 0, &opt_random },
|
{ WESTON_OPTION_INTEGER, "zuc-random", 0, &opt_random },
|
||||||
@@ -633,7 +622,6 @@ zuc_initialize(int *argc, char *argv[], bool *help_flagged)
|
|||||||
" --zuc-break-on-failure\n"
|
" --zuc-break-on-failure\n"
|
||||||
" --zuc-filter=FILTER\n"
|
" --zuc-filter=FILTER\n"
|
||||||
" --zuc-list-tests\n"
|
" --zuc-list-tests\n"
|
||||||
" --zuc-nofork\n"
|
|
||||||
#if ENABLE_JUNIT_XML
|
#if ENABLE_JUNIT_XML
|
||||||
" --zuc-output-xml\n"
|
" --zuc-output-xml\n"
|
||||||
#endif
|
#endif
|
||||||
@@ -650,7 +638,6 @@ zuc_initialize(int *argc, char *argv[], bool *help_flagged)
|
|||||||
} else {
|
} else {
|
||||||
zuc_set_repeat(opt_repeat);
|
zuc_set_repeat(opt_repeat);
|
||||||
zuc_set_random(opt_random);
|
zuc_set_random(opt_random);
|
||||||
zuc_set_spawn(!opt_nofork);
|
|
||||||
zuc_set_break_on_failure(opt_break_on_failure);
|
zuc_set_break_on_failure(opt_break_on_failure);
|
||||||
zuc_set_output_junit(opt_junit);
|
zuc_set_output_junit(opt_junit);
|
||||||
rc = EXIT_SUCCESS;
|
rc = EXIT_SUCCESS;
|
||||||
@@ -937,11 +924,6 @@ zuc_cleanup(void)
|
|||||||
|
|
||||||
free(g_ctx.filter);
|
free(g_ctx.filter);
|
||||||
g_ctx.filter = 0;
|
g_ctx.filter = 0;
|
||||||
for (i = 0; i < 2; ++i)
|
|
||||||
if (g_ctx.fds[i] != -1) {
|
|
||||||
close(g_ctx.fds[i]);
|
|
||||||
g_ctx.fds[i] = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_ctx.listeners) {
|
if (g_ctx.listeners) {
|
||||||
struct zuc_slinked *curr = g_ctx.listeners;
|
struct zuc_slinked *curr = g_ctx.listeners;
|
||||||
@@ -1017,108 +999,9 @@ zuc_list_tests(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
spawn_test(struct zuc_test *test, void *test_data,
|
|
||||||
void (*cleanup_fn)(void *data), void *cleanup_data)
|
|
||||||
{
|
|
||||||
pid_t pid = -1;
|
|
||||||
|
|
||||||
if (!test || (!test->fn && !test->fn_f))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (pipe2(g_ctx.fds, O_CLOEXEC)) {
|
|
||||||
printf("%s:%d: error: Unable to create pipe: %d\n",
|
|
||||||
__FILE__, __LINE__, errno);
|
|
||||||
mark_failed(test, ZUC_CHECK_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fflush(NULL); /* important. avoid duplication of output */
|
|
||||||
pid = fork();
|
|
||||||
switch (pid) {
|
|
||||||
case -1: /* Error forking */
|
|
||||||
printf("%s:%d: error: Problem with fork: %d\n",
|
|
||||||
__FILE__, __LINE__, errno);
|
|
||||||
mark_failed(test, ZUC_CHECK_ERROR);
|
|
||||||
close(g_ctx.fds[0]);
|
|
||||||
g_ctx.fds[0] = -1;
|
|
||||||
close(g_ctx.fds[1]);
|
|
||||||
g_ctx.fds[1] = -1;
|
|
||||||
break;
|
|
||||||
case 0: { /* child */
|
|
||||||
int rc = EXIT_SUCCESS;
|
|
||||||
close(g_ctx.fds[0]);
|
|
||||||
g_ctx.fds[0] = -1;
|
|
||||||
|
|
||||||
if (test->fn_f)
|
|
||||||
test->fn_f(test_data);
|
|
||||||
else
|
|
||||||
test->fn();
|
|
||||||
|
|
||||||
if (test_has_failure(test))
|
|
||||||
rc = EXIT_FAILURE;
|
|
||||||
else if (test_has_skip(test))
|
|
||||||
rc = ZUC_EXIT_SKIP;
|
|
||||||
|
|
||||||
/* Avoid confusing memory tools like valgrind */
|
|
||||||
if (cleanup_fn)
|
|
||||||
cleanup_fn(cleanup_data);
|
|
||||||
|
|
||||||
zuc_cleanup();
|
|
||||||
exit(rc);
|
|
||||||
}
|
|
||||||
default: { /* parent */
|
|
||||||
ssize_t rc = 0;
|
|
||||||
siginfo_t info = {};
|
|
||||||
|
|
||||||
close(g_ctx.fds[1]);
|
|
||||||
g_ctx.fds[1] = -1;
|
|
||||||
|
|
||||||
do {
|
|
||||||
rc = zuc_process_message(g_ctx.curr_test,
|
|
||||||
g_ctx.fds[0]);
|
|
||||||
} while (rc > 0);
|
|
||||||
close(g_ctx.fds[0]);
|
|
||||||
g_ctx.fds[0] = -1;
|
|
||||||
|
|
||||||
if (waitid(P_ALL, 0, &info, WEXITED)) {
|
|
||||||
printf("%s:%d: error: waitid failed. (%d)\n",
|
|
||||||
__FILE__, __LINE__, errno);
|
|
||||||
mark_failed(test, ZUC_CHECK_ERROR);
|
|
||||||
} else {
|
|
||||||
switch (info.si_code) {
|
|
||||||
case CLD_EXITED: {
|
|
||||||
int exit_code = info.si_status;
|
|
||||||
switch(exit_code) {
|
|
||||||
case EXIT_SUCCESS:
|
|
||||||
break;
|
|
||||||
case ZUC_EXIT_SKIP:
|
|
||||||
if (!test_has_skip(g_ctx.curr_test) &&
|
|
||||||
!test_has_failure(g_ctx.curr_test))
|
|
||||||
ZUC_SKIP("Child exited SKIP");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* unexpected failure */
|
|
||||||
if (!test_has_failure(g_ctx.curr_test))
|
|
||||||
ZUC_ASSERT_EQ(0, exit_code);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CLD_KILLED:
|
|
||||||
case CLD_DUMPED:
|
|
||||||
printf("%s:%d: error: signaled: %d\n",
|
|
||||||
__FILE__, __LINE__, info.si_status);
|
|
||||||
mark_failed(test, ZUC_CHECK_ERROR);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
run_single_test(struct zuc_test *test,const struct zuc_fixture *fxt,
|
run_single_test(struct zuc_test *test,const struct zuc_fixture *fxt,
|
||||||
void *case_data, bool spawn)
|
void *case_data)
|
||||||
{
|
{
|
||||||
long elapsed = 0;
|
long elapsed = 0;
|
||||||
struct timespec begin;
|
struct timespec begin;
|
||||||
@@ -1146,15 +1029,10 @@ run_single_test(struct zuc_test *test,const struct zuc_fixture *fxt,
|
|||||||
|
|
||||||
/* Need to re-check these, as fixtures might have changed test state. */
|
/* Need to re-check these, as fixtures might have changed test state. */
|
||||||
if (!test->fatal && !test->skipped) {
|
if (!test->fatal && !test->skipped) {
|
||||||
if (spawn) {
|
if (test->fn_f)
|
||||||
spawn_test(test, test_data,
|
test->fn_f(test_data);
|
||||||
cleanup_fn, cleanup_data);
|
else
|
||||||
} else {
|
test->fn();
|
||||||
if (test->fn_f)
|
|
||||||
test->fn_f(test_data);
|
|
||||||
else
|
|
||||||
test->fn();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clock_gettime(TARGET_TIMER, &end);
|
clock_gettime(TARGET_TIMER, &end);
|
||||||
@@ -1204,8 +1082,7 @@ run_single_case(struct zuc_case *test_case)
|
|||||||
if (curr->disabled) {
|
if (curr->disabled) {
|
||||||
dispatch_test_disabled(&g_ctx, curr);
|
dispatch_test_disabled(&g_ctx, curr);
|
||||||
} else {
|
} else {
|
||||||
run_single_test(curr, fxt, case_data,
|
run_single_test(curr, fxt, case_data);
|
||||||
g_ctx.spawn);
|
|
||||||
if (curr->skipped)
|
if (curr->skipped)
|
||||||
test_case->skipped++;
|
test_case->skipped++;
|
||||||
if (curr->failed)
|
if (curr->failed)
|
||||||
@@ -1313,7 +1190,6 @@ zucimpl_run_tests(void)
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
if (g_ctx.listeners == NULL) {
|
if (g_ctx.listeners == NULL) {
|
||||||
zuc_add_event_listener(zuc_collector_create(&(g_ctx.fds[1])));
|
|
||||||
zuc_add_event_listener(zuc_base_logger_create());
|
zuc_add_event_listener(zuc_base_logger_create());
|
||||||
if (g_ctx.output_junit)
|
if (g_ctx.output_junit)
|
||||||
zuc_add_event_listener(zuc_junit_reporter_create());
|
zuc_add_event_listener(zuc_junit_reporter_create());
|
||||||
|
|||||||
Reference in New Issue
Block a user