Merge branch 'feature/language-separation' into bleeding

This commit is contained in:
Snaipe 2015-10-02 10:01:46 +02:00
commit c530fd08eb
20 changed files with 358 additions and 38 deletions

View file

@ -40,6 +40,7 @@ add_definitions(-DCRITERION_BUILDING_DLL=1)
if (NOT MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -g -std=gnu99")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -g -std=c++11")
endif ()
if (MSVC)
@ -84,6 +85,8 @@ find_package(PCRE)
# List sources and headers
set(SOURCE_FILES
src/core/wrappers/wrap.c
src/core/wrappers/wrap.cc
src/core/abort.c
src/core/abort.h
src/core/report.c

View file

@ -36,9 +36,11 @@
# ifdef __cplusplus
# define TEST_PROTOTYPE_(Category, Name) \
extern "C" void IDENTIFIER_(Category, Name, impl)(void)
# define CR_LANG CR_LANG_CPP
# else
# define TEST_PROTOTYPE_(Category, Name) \
void IDENTIFIER_(Category, Name, impl)(void)
# define CR_LANG CR_LANG_C
# endif
# define SUITE_IDENTIFIER_(Name, Suffix) \
@ -49,6 +51,7 @@
TEST_PROTOTYPE_(Category, Name); \
struct criterion_test_extra_data IDENTIFIER_(Category, Name, extra) = \
CR_EXPAND(CRITERION_MAKE_STRUCT(struct criterion_test_extra_data, \
.lang_ = CR_LANG, \
.kind_ = CR_TEST_NORMAL, \
.param_ = (struct criterion_test_params(*)(void)) NULL, \
.identifier_ = #Category "/" #Name, \

View file

@ -110,6 +110,7 @@ struct criterion_output_provider {
void (*log_theory_fail )(struct criterion_theory_stats *stats);
void (*log_test_timeout )(struct criterion_test_stats *stats);
void (*log_test_crash )(struct criterion_test_stats *stats);
void (*log_test_abort )(struct criterion_test_stats *stats, const char *msg);
void (*log_other_crash )(struct criterion_test_stats *stats);
void (*log_abnormal_exit)(struct criterion_test_stats *stats);
void (*log_post_test )(struct criterion_test_stats *stats);

View file

@ -35,6 +35,11 @@ using std::size_t;
# endif
# include "common.h"
enum criterion_language {
CR_LANG_C,
CR_LANG_CPP,
};
enum criterion_test_kind {
CR_TEST_NORMAL,
CR_TEST_PARAMETERIZED,
@ -84,6 +89,7 @@ struct criterion_test_params {
struct criterion_test_extra_data {
int sentinel_;
enum criterion_language lang_;
enum criterion_test_kind kind_;
struct criterion_test_params (*param_)(void);
const char *identifier_;

View file

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: criterion 2.0.0\n"
"Report-Msgid-Bugs-To: franklinmathieu+criterion@gmail.com\n"
"POT-Creation-Date: 2015-09-27 12:24+0200\n"
"POT-Creation-Date: 2015-10-01 23:09+0200\n"
"PO-Revision-Date: 2015-04-03 17:58+0200\n"
"Last-Translator: <franklinmathieu@gmail.com>\n"
"Language-Team: French\n"
@ -78,6 +78,11 @@ msgstr "%1$s::%2$s: PLANTAGE!\n"
#: src/log/normal.c:64
#, fuzzy, c-format
msgid "%1$s::%2$s: %3$s\n"
msgstr "%1$s::%2$s: (%3$3.2fs)\n"
#: src/log/normal.c:65
#, fuzzy, c-format
msgid ""
"%1$sWarning! The test `%2$s::%3$s` crashed during its setup or teardown."
"%4$s\n"
@ -85,7 +90,7 @@ msgstr ""
"%1$sAttention! Le test `%2$s::%3$s` a planté pendant son initialisation ou "
"sa finalisation.%4$s\n"
#: src/log/normal.c:65
#: src/log/normal.c:66
#, fuzzy, c-format
msgid ""
"%1$sWarning! The test `%2$s::%3$s` exited during its setup or teardown.%4$s\n"
@ -93,14 +98,14 @@ msgstr ""
"%1$sAttention! Le test `%2$s::%3$s` a quitté pendant son initialisation ou "
"sa finalisation.%4$s\n"
#: src/log/normal.c:66
#: src/log/normal.c:67
#, c-format
msgid "Running %1$s%2$lu%3$s test from %4$s%5$s%6$s:\n"
msgid_plural "Running %1$s%2$lu%3$s tests from %4$s%5$s%6$s:\n"
msgstr[0] "Lancement de %1$s%2$lu%3$s test dans %4$s%5$s%6$s:\n"
msgstr[1] "Lancement de %1$s%2$lu%3$s tests dans %4$s%5$s%6$s:\n"
#: src/log/normal.c:68
#: src/log/normal.c:69
#, c-format
msgid ""
"%1$sSynthesis: Tested: %2$s%3$lu%4$s | Passing: %5$s%6$lu%7$s | Failing: %8$s"
@ -109,6 +114,11 @@ msgstr ""
"%1$sSynthèse: Testés: %2$s%3$lu%4$s | Validés: %5$s%6$lu%7$s | Échoués: %8$s"
"%9$lu%10$s | Plantages: %11$s%12$lu%13$s %14$s\n"
#: src/log/normal.c:85
#, fuzzy, c-format
msgid "%s::%s: %s\n"
msgstr "%1$s::%2$s: (%3$3.2fs)\n"
#: src/string/i18n.c:13
msgid "The conditions for this assertion were not met."
msgstr "Les conditions de cette assertion n'ont pas été remplies."
@ -175,7 +185,7 @@ msgstr "L'instruction `%1$s` a levé une instance de l'exception `%2$s`."
msgid "The statement `%1$s` did not throw an instance of the `%2$s` exception."
msgstr "L'instruction `%1$s` n'a pas levé d'instance de l'exception `%2$s`."
#: src/core/runner.c:54
#: src/core/runner.c:56
#, c-format
msgid ""
"%1$sWarning! Criterion has detected that it is running under valgrind, but "
@ -186,7 +196,7 @@ msgstr ""
"l'option no_early_exit est explicitement désactivée. Les rapports d'erreur "
"ne seront pas précis!%2$s\n"
#: src/core/runner.c:58
#: src/core/runner.c:60
#, c-format
msgid ""
"%1$sWarning! Criterion has detected that it is running under valgrind, but "

View file

@ -10,6 +10,8 @@ set(SAMPLES
long-messages.cc
other-crashes.cc
theories_regression.cc
exception.cc
)
add_samples("${CMAKE_CURRENT_LIST_DIR}" "${SAMPLES}")

View file

@ -0,0 +1,18 @@
#include <criterion/criterion.h>
#include <stdexcept>
void raise_std(void) {
throw std::invalid_argument("Some exception message");
}
void raise_any(void) {
throw 1;
}
Test(exception, raise_std) { raise_std(); }
Test(exception, raise_any) { raise_any(); }
Test(exception, raise_std_init, .init = raise_std) {}
Test(exception, raise_any_init, .init = raise_any) {}
Test(exception, raise_std_fini, .fini = raise_std) {}
Test(exception, raise_any_fini, .fini = raise_any) {}

View file

@ -30,7 +30,15 @@
# undef _WIN32_WINNT
# define _WIN32_WINNT 0x0502
# include <windows.h>
# if defined(__MINGW32__) || defined(__MINGW64__)
# define off_t _off_t
# define off64_t _off64_t
# endif
# include <io.h>
# if defined(__MINGW32__) || defined(__MINGW64__)
# undef off_t
# undef off64_t
# endif
# include <fcntl.h>
# include <winnt.h>
# include <stdint.h>

View file

@ -40,7 +40,15 @@
# define _POSIX_SOURCE 1
# define TMP_POSIX
# endif
# if defined(__MINGW32__) || defined(__MINGW64__)
# define off_t _off_t
# define off64_t _off64_t
# endif
# include <stdio.h>
# if defined(__MINGW32__) || defined(__MINGW64__)
# undef off_t
# undef off64_t
# endif
# ifdef TMP_POSIX
# undef _POSIX_SOURCE
# undef TMP_POSIX

View file

@ -21,10 +21,34 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <string.h>
#include "abort.h"
#include "criterion/asprintf-compat.h"
#include "io/event.h"
jmp_buf g_pre_test;
void criterion_abort_test(void) {
longjmp(g_pre_test, 1);
}
void criterion_test_die(const char *msg, ...) {
va_list vl;
va_start(vl, msg);
char *formatted_msg = NULL;
int res = cr_vasprintf(&formatted_msg, msg, vl);
va_end(vl);
if (res < 0)
abort();
size_t *buf = malloc(sizeof (size_t) + res + 1);
*buf = res + 1;
memcpy(buf + 1, formatted_msg, res + 1);
send_event(TEST_ABORT, buf, sizeof (size_t) + res + 1);
free(buf);
free(formatted_msg);
exit(0);
}

View file

@ -29,4 +29,6 @@
extern jmp_buf g_pre_test;
void criterion_test_die(const char *msg, ...);
#endif /* !ABORT_H_ */

View file

@ -45,9 +45,9 @@ DECL_CALL_REPORT_HOOKS(POST_FINI);
DECL_CALL_REPORT_HOOKS(POST_SUITE);
DECL_CALL_REPORT_HOOKS(POST_ALL);
#define log(Type, Arg) \
log_(criterion_options.output_provider->log_ ## Type, Arg);
#define log_(Log, Arg) \
(Log ? Log(Arg) : nothing());
#define log(Type, ...) \
log_(criterion_options.output_provider->log_ ## Type, __VA_ARGS__);
#define log_(Log, ...) \
(Log ? Log(__VA_ARGS__) : nothing());
#endif /* !REPORT_H_ */

View file

@ -34,6 +34,7 @@
#include "compat/time.h"
#include "compat/posix.h"
#include "compat/processor.h"
#include "wrappers/wrap.h"
#include "string/i18n.h"
#include "io/event.h"
#include "runner_coroutine.h"
@ -156,6 +157,11 @@ struct criterion_test_set *criterion_init(void) {
return set;
}
f_wrapper *g_wrappers[] = {
[CR_LANG_C] = c_wrap,
[CR_LANG_CPP] = cpp_wrap,
};
void run_test_child(struct criterion_test *test,
struct criterion_suite *suite) {
@ -168,34 +174,7 @@ void run_test_child(struct criterion_test *test,
else if (test->data->timeout != 0)
setup_timeout((uint64_t) (test->data->timeout * 1e9));
send_event(PRE_INIT, NULL, 0);
if (suite->data)
(suite->data->init ? suite->data->init : nothing)();
(test->data->init ? test->data->init : nothing)();
send_event(PRE_TEST, NULL, 0);
struct timespec_compat ts;
if (!setjmp(g_pre_test)) {
timer_start(&ts);
if (test->test) {
if (!test->data->param_) {
test->test();
} else {
void(*param_test_func)(void *) = (void(*)(void*)) test->test;
param_test_func(g_worker_context.param->ptr);
}
}
}
double elapsed_time;
if (!timer_end(&elapsed_time, &ts))
elapsed_time = -1;
send_event(POST_TEST, &elapsed_time, sizeof (double));
(test->data->fini ? test->data->fini : nothing)();
if (suite->data)
(suite->data->fini ? suite->data->fini : nothing)();
send_event(POST_FINI, NULL, 0);
g_wrappers[test->data->lang_](test, suite);
}
#define push_event(Kind, ...) \
@ -249,6 +228,18 @@ static void handle_worker_terminated(struct event *ev,
log(post_fini, ctx->test_stats);
}
} else {
if (ctx->aborted) {
if (!ctx->normal_finish) {
double elapsed_time = 0;
push_event(POST_TEST, .data = &elapsed_time);
log(post_test, ctx->test_stats);
}
if (!ctx->cleaned_up) {
push_event(POST_FINI);
log(post_fini, ctx->test_stats);
}
return;
}
if ((ctx->normal_finish && !ctx->cleaned_up) || !ctx->test_started) {
log(abnormal_exit, ctx->test_stats);
if (!ctx->test_started) {
@ -301,6 +292,11 @@ static void handle_event(struct event *ev) {
report(ASSERT, ev->data);
log(assert, ev->data);
break;
case TEST_ABORT:
log(test_abort, ctx->test_stats, ev->data);
ctx->test_stats->failed = 1;
ctx->aborted = true;
break;
case POST_TEST:
report(POST_TEST, ctx->test_stats);
log(post_test, ctx->test_stats);

View file

@ -38,6 +38,7 @@ struct execution_context {
bool test_started;
bool normal_finish;
bool cleaned_up;
bool aborted;
struct criterion_global_stats *stats;
struct criterion_test *test;
struct criterion_test_stats *test_stats;

65
src/core/wrappers/wrap.c Normal file
View file

@ -0,0 +1,65 @@
/*
* The MIT License (MIT)
*
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
*
* 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 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 "core/abort.h"
#include "core/stats.h"
#include "core/worker.h"
#include "core/report.h"
#include "compat/time.h"
#include "io/event.h"
#include "wrap.h"
static INLINE void nothing(void) {}
void c_wrap(struct criterion_test *test, struct criterion_suite *suite) {
send_event(PRE_INIT, NULL, 0);
if (suite->data)
(suite->data->init ? suite->data->init : nothing)();
(test->data->init ? test->data->init : nothing)();
send_event(PRE_TEST, NULL, 0);
struct timespec_compat ts;
if (!setjmp(g_pre_test)) {
timer_start(&ts);
if (test->test) {
if (!test->data->param_) {
test->test();
} else {
void(*param_test_func)(void *) = (void(*)(void*)) test->test;
param_test_func(g_worker_context.param->ptr);
}
}
}
double elapsed_time;
if (!timer_end(&elapsed_time, &ts))
elapsed_time = -1;
send_event(POST_TEST, &elapsed_time, sizeof (double));
(test->data->fini ? test->data->fini : nothing)();
if (suite->data)
(suite->data->fini ? suite->data->fini : nothing)();
send_event(POST_FINI, NULL, 0);
}

90
src/core/wrappers/wrap.cc Normal file
View file

@ -0,0 +1,90 @@
/*
* The MIT License (MIT)
*
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
*
* 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 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 <exception>
#include "criterion/assert.h"
#include "criterion/event.h"
extern "C" {
#include "core/abort.h"
#include "core/report.h"
#include "core/worker.h"
#include "compat/time.h"
#include "wrap.h"
#include "common.h"
static INLINE void nothing(void) {}
void cpp_wrap(struct criterion_test *test, struct criterion_suite *suite) {
send_event(PRE_INIT, NULL, 0);
try {
if (suite->data)
(suite->data->init ? suite->data->init : nothing)();
(test->data->init ? test->data->init : nothing)();
} catch (const std::exception &e) {
criterion_test_die("Caught an unexpected exception during the test initialization: %s.", e.what());
} catch (...) {
criterion_test_die("Caught some unexpected exception during the test initialization.");
}
send_event(PRE_TEST, NULL, 0);
struct timespec_compat ts;
if (!setjmp(g_pre_test)) {
timer_start(&ts);
if (test->test) {
try {
if (!test->data->param_) {
test->test();
} else {
void(*param_test_func)(void *) = (void(*)(void*)) test->test;
param_test_func(g_worker_context.param->ptr);
}
} catch (const std::exception &e) {
criterion_test_die("Caught an unexpected exception during the test execution: %s.", e.what());
} catch (...) {
criterion_test_die("Caught some unexpected exception during the test execution.");
}
}
}
double elapsed_time;
if (!timer_end(&elapsed_time, &ts))
elapsed_time = -1;
send_event(POST_TEST, &elapsed_time, sizeof (double));
try {
(test->data->fini ? test->data->fini : nothing)();
if (suite->data)
(suite->data->fini ? suite->data->fini : nothing)();
} catch (const std::exception &e) {
criterion_test_die("Caught an unexpected exception during the test finalization: %s.", e.what());
} catch (...) {
criterion_test_die("Caught some unexpected exception during the test finalization.");
}
send_event(POST_FINI, NULL, 0);
}
}

36
src/core/wrappers/wrap.h Normal file
View file

@ -0,0 +1,36 @@
/*
* The MIT License (MIT)
*
* Copyright © 2015 Franklin "Snaipe" Mathieu <http://snai.pe/>
*
* 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 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 WRAP_H_
# define WRAP_H_
# include "criterion/types.h"
typedef void (f_wrapper)(struct criterion_test *, struct criterion_suite *);
void c_wrap(struct criterion_test *test, struct criterion_suite *suite);
void cpp_wrap(struct criterion_test *test, struct criterion_suite *suite);
extern f_wrapper *g_wrappers[];
#endif /* !WRAP_H_ */

View file

@ -90,6 +90,22 @@ struct event *read_event(s_pipe_file_handle *f) {
*ev = (struct event) { .pid = pid, .kind = kind, .data = buf };
return ev;
}
case TEST_ABORT: {
char *msg = NULL;
size_t len = 0;
ASSERT(pipe_read(&len, sizeof (size_t), f) == 1);
msg = malloc(len);
ASSERT(pipe_read(msg, len, f) == 1);
struct event *ev = smalloc(
.size = sizeof (struct event),
.dtor = destroy_event
);
*ev = (struct event) { .pid = pid, .kind = kind, .data = msg };
return ev;
}
case THEORY_FAIL: {
size_t len = 0;
ASSERT(pipe_read(&len, sizeof (size_t), f) == 1);

View file

@ -41,6 +41,7 @@ struct event {
enum other_event_kinds {
WORKER_TERMINATED = 1 << 30,
TEST_ABORT,
};
struct event *read_event(s_pipe_file_handle *f);

View file

@ -61,6 +61,7 @@ static msg_t msg_theory_fail = N_(" Theory %1$s::%2$s failed with the following
static msg_t msg_test_timeout = N_("%1$s::%2$s: Timed out. (%3$3.2fs)\n");
static msg_t msg_test_crash_line = N_("%1$s%2$s%3$s:%4$s%5$u%6$s: Unexpected signal caught below this line!\n");
static msg_t msg_test_crash = N_("%1$s::%2$s: CRASH!\n");
static msg_t msg_test_abort = N_("%1$s::%2$s: %3$s\n");
static msg_t msg_test_other_crash = N_("%1$sWarning! The test `%2$s::%3$s` crashed during its setup or teardown.%4$s\n");
static msg_t msg_test_abnormal_exit = N_("%1$sWarning! The test `%2$s::%3$s` exited during its setup or teardown.%4$s\n");
static msg_t msg_pre_suite[] = N_s("Running %1$s%2$lu%3$s test from %4$s%5$s%6$s:\n",
@ -81,6 +82,7 @@ static msg_t msg_theory_fail = " Theory %s::%s failed with the following parame
static msg_t msg_test_timeout = "%s::%s: Timed out. (%3.2fs)\n";
static msg_t msg_test_crash_line = "%s%s%s:%s%u%s: Unexpected signal caught below this line!\n";
static msg_t msg_test_crash = "%s::%s: CRASH!\n";
static msg_t msg_test_abort = N_("%s::%s: %s\n");
static msg_t msg_test_other_crash = "%sWarning! The test `%s::%s` crashed during its setup or teardown.%s\n";
static msg_t msg_test_abnormal_exit = "%sWarning! The test `%s::%s` exited during its setup or teardown.%s\n";
static msg_t msg_pre_suite[] = { "Running %s%lu%s test from %s%s%s:\n",
@ -230,6 +232,33 @@ void normal_log_test_timeout(UNUSED struct criterion_test_stats *stats) {
stats->elapsed_time);
}
void normal_log_test_abort(UNUSED struct criterion_test_stats *stats, const char *msg) {
char *dup = strdup(msg);
#ifdef VANILLA_WIN32
char *line = strtok(dup, "\n");
#else
char *saveptr = NULL;
char *line = strtok_r(dup, "\n", &saveptr);
#endif
criterion_pimportant(CRITERION_PREFIX_DASHES,
_(msg_test_abort),
stats->test->category,
stats->test->name,
line);
#ifdef VANILLA_WIN32
while ((line = strtok(NULL, "\n")))
#else
while ((line = strtok_r(NULL, "\n", &saveptr)))
#endif
criterion_pimportant(CRITERION_PREFIX_DASHES, _(msg_desc), line);
free(dup);
}
struct criterion_output_provider normal_logging = {
.log_pre_all = normal_log_pre_all,
.log_pre_init = normal_log_pre_init,
@ -238,6 +267,7 @@ struct criterion_output_provider normal_logging = {
.log_theory_fail = normal_log_theory_fail,
.log_test_timeout = normal_log_test_timeout,
.log_test_crash = normal_log_test_crash,
.log_test_abort = normal_log_test_abort,
.log_other_crash = normal_log_other_crash,
.log_abnormal_exit = normal_log_abnormal_exit,
.log_post_test = normal_log_post_test,