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>dev
parent
6c8ae362bb
commit
759712ba05
@ -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 */ |
|
Loading…
Reference in new issue