forked from Imagelibrary/rtems
@@ -66,6 +66,13 @@ typedef struct T_fixture {
|
||||
void *initial_context;
|
||||
} T_fixture;
|
||||
|
||||
typedef struct T_fixture_node {
|
||||
struct T_fixture_node *next;
|
||||
struct T_fixture_node *previous;
|
||||
const T_fixture *fixture;
|
||||
void *context;
|
||||
} T_fixture_node;
|
||||
|
||||
#define T_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
|
||||
|
||||
/*
|
||||
@@ -2232,6 +2239,10 @@ void *T_fixture_context(void);
|
||||
|
||||
void T_set_fixture_context(void *);
|
||||
|
||||
void *T_push_fixture(T_fixture_node *, const T_fixture *);
|
||||
|
||||
void T_pop_fixture(void);
|
||||
|
||||
#ifdef __rtems__
|
||||
#define T_TEST_CASE_FIXTURE(name, fixture) \
|
||||
void T_case_body_##name(void); \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (C) 2018, 2019 embedded brains GmbH
|
||||
* Copyright (C) 2018, 2020 embedded brains GmbH
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -62,7 +62,8 @@ typedef struct {
|
||||
T_verbosity verbosity;
|
||||
const T_case_context *registered_cases;
|
||||
const T_case_context *current_case;
|
||||
void *fixture_context;
|
||||
T_fixture_node *fixtures;
|
||||
T_fixture_node case_fixture;
|
||||
LIST_HEAD(, T_destructor) destructors;
|
||||
T_time case_begin_time;
|
||||
atomic_uint planned_steps;
|
||||
@@ -288,7 +289,7 @@ static const char *
|
||||
T_scope(T_context *ctx, char *buf)
|
||||
{
|
||||
const char *r;
|
||||
const T_case_context *tc;
|
||||
T_fixture_node *node;
|
||||
|
||||
#if defined(__rtems__)
|
||||
ISR_Level level;
|
||||
@@ -327,19 +328,23 @@ T_scope(T_context *ctx, char *buf)
|
||||
r = buf;
|
||||
#endif
|
||||
|
||||
tc = ctx->current_case;
|
||||
if (tc != NULL) {
|
||||
node = &ctx->case_fixture;
|
||||
|
||||
do {
|
||||
const T_fixture *fixture;
|
||||
|
||||
fixture = tc->fixture;
|
||||
fixture = node->fixture;
|
||||
|
||||
if (fixture != NULL && fixture->scope != NULL) {
|
||||
size_t n;
|
||||
|
||||
n = strlen(r);
|
||||
(*fixture->scope)(ctx->fixture_context, buf + n,
|
||||
(*fixture->scope)(node->context, buf + n,
|
||||
T_SCOPE_SIZE - n);
|
||||
}
|
||||
}
|
||||
|
||||
node = node->previous;
|
||||
} while (node != NULL);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -421,18 +426,20 @@ T_add_failure(T_context *ctx)
|
||||
static void
|
||||
T_stop(T_context *ctx)
|
||||
{
|
||||
const T_case_context *tc;
|
||||
T_fixture_node *node;
|
||||
|
||||
tc = ctx->current_case;
|
||||
node = ctx->fixtures;
|
||||
|
||||
if (tc != NULL) {
|
||||
while (node != NULL) {
|
||||
const T_fixture *fixture;
|
||||
|
||||
fixture = tc->fixture;
|
||||
fixture = node->fixture;
|
||||
|
||||
if (fixture != NULL && fixture->stop != NULL) {
|
||||
(*fixture->stop)(ctx->fixture_context);
|
||||
(*fixture->stop)(node->context);
|
||||
}
|
||||
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
longjmp(ctx->case_begin_context, 1);
|
||||
@@ -478,13 +485,13 @@ T_set_verbosity(T_verbosity verbosity)
|
||||
void *
|
||||
T_fixture_context(void)
|
||||
{
|
||||
return T_instance.fixture_context;
|
||||
return T_instance.fixtures->context;
|
||||
}
|
||||
|
||||
void
|
||||
T_set_fixture_context(void *context)
|
||||
{
|
||||
T_instance.fixture_context = context;
|
||||
T_instance.fixtures->context = context;
|
||||
}
|
||||
|
||||
const char *
|
||||
@@ -730,6 +737,7 @@ T_do_run_initialize(const T_config *config)
|
||||
ctx->buf_mask = 0;
|
||||
}
|
||||
|
||||
ctx->fixtures = &ctx->case_fixture;
|
||||
atomic_store_explicit(&ctx->buf_head, 0, memory_order_relaxed);
|
||||
ctx->buf_tail = 0;
|
||||
ctx->putchar = config->putchar;
|
||||
@@ -761,6 +769,7 @@ T_do_case_begin(T_context *ctx, const T_case_context *tc)
|
||||
fixture = tc->fixture;
|
||||
ctx->verbosity = config->verbosity;
|
||||
ctx->current_case = tc;
|
||||
ctx->fixtures = &ctx->case_fixture;
|
||||
LIST_INIT(&ctx->destructors);
|
||||
atomic_store_explicit(&ctx->planned_steps, UINT_MAX,
|
||||
memory_order_relaxed);
|
||||
@@ -773,10 +782,11 @@ T_do_case_begin(T_context *ctx, const T_case_context *tc)
|
||||
T_actions_forward(config, T_EVENT_CASE_BEGIN, tc->name);
|
||||
|
||||
if (fixture != NULL) {
|
||||
ctx->fixture_context = fixture->initial_context;
|
||||
ctx->case_fixture.fixture = fixture;
|
||||
ctx->case_fixture.context = fixture->initial_context;
|
||||
|
||||
if (fixture->setup != NULL) {
|
||||
(*fixture->setup)(ctx->fixture_context);
|
||||
(*fixture->setup)(ctx->case_fixture.context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -785,7 +795,7 @@ static void
|
||||
T_do_case_end(T_context *ctx, const T_case_context *tc)
|
||||
{
|
||||
const T_config *config;
|
||||
const T_fixture *fixture;
|
||||
T_fixture_node *node;
|
||||
unsigned int planned_steps;
|
||||
unsigned int steps;
|
||||
unsigned int failures;
|
||||
@@ -793,10 +803,22 @@ T_do_case_end(T_context *ctx, const T_case_context *tc)
|
||||
T_time_string ts;
|
||||
|
||||
config = ctx->config;
|
||||
fixture = tc->fixture;
|
||||
node = ctx->fixtures;
|
||||
ctx->fixtures = NULL;
|
||||
|
||||
if (fixture != NULL && fixture->teardown != NULL) {
|
||||
(*fixture->teardown)(ctx->fixture_context);
|
||||
while (node != NULL) {
|
||||
const T_fixture *fixture;
|
||||
T_fixture_node *dead;
|
||||
|
||||
fixture = node->fixture;
|
||||
|
||||
if (fixture != NULL && fixture->teardown != NULL) {
|
||||
(*fixture->teardown)(node->context);
|
||||
}
|
||||
|
||||
dead = node;
|
||||
node = node->next;
|
||||
memset(dead, 0, sizeof(*dead));
|
||||
}
|
||||
|
||||
T_call_destructors(ctx);
|
||||
@@ -1027,3 +1049,49 @@ T_now(void)
|
||||
config = ctx->config;
|
||||
return (*config->now)();
|
||||
}
|
||||
|
||||
void *
|
||||
T_push_fixture(T_fixture_node *node, const T_fixture *fixture)
|
||||
{
|
||||
T_context *ctx;
|
||||
T_fixture_node *old;
|
||||
void *context;
|
||||
|
||||
ctx = &T_instance;
|
||||
old = ctx->fixtures;
|
||||
old->previous = node;
|
||||
node->next = old;
|
||||
node->previous = NULL;
|
||||
node->fixture = fixture;
|
||||
context = fixture->initial_context;
|
||||
node->context = context;
|
||||
ctx->fixtures = node;
|
||||
|
||||
if (fixture != NULL && fixture->setup != NULL) {
|
||||
(*fixture->setup)(context);
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void
|
||||
T_pop_fixture(void)
|
||||
{
|
||||
T_context *ctx;
|
||||
T_fixture_node *node;
|
||||
const T_fixture *fixture;
|
||||
T_fixture_node *next;
|
||||
|
||||
ctx = &T_instance;
|
||||
node = ctx->fixtures;
|
||||
next = node->next;
|
||||
next->previous = NULL;
|
||||
ctx->fixtures = next;
|
||||
fixture = node->fixture;
|
||||
|
||||
if (fixture != NULL && fixture->teardown != NULL) {
|
||||
(*fixture->teardown)(node->context);
|
||||
}
|
||||
|
||||
memset(node, 0, sizeof(*node));
|
||||
}
|
||||
|
||||
@@ -182,8 +182,8 @@ run_initialize(void)
|
||||
T_set_putchar(censor_putchar, ctx, &ctx->putchar, &ctx->putchar_arg);
|
||||
}
|
||||
|
||||
static const char expected_final[] = "Z:ttest01:C:342:N:1316:F:791:D:0.687999\n"
|
||||
"Y:ReportHash:SHA256:efd7b69ac3ec0cac31fa147008bba87a077e6d53c0cfb8a836a4de2ae90ecc27\n";
|
||||
static const char expected_final[] = "Z:ttest01:C:342:N:1329:F:791:D:0.687999\n"
|
||||
"Y:ReportHash:SHA256:e5c3847558c805663117be13ef27fd89579f595148b8515c42a38bd1b9dd79c2\n";
|
||||
|
||||
static void
|
||||
run_finalize(void)
|
||||
|
||||
@@ -58,9 +58,77 @@ static const T_fixture fixture = {
|
||||
.initial_context = &initial_value
|
||||
};
|
||||
|
||||
static int initial_value_2 = 7;
|
||||
|
||||
static int counter_2;
|
||||
|
||||
static void
|
||||
setup_2(void *ctx)
|
||||
{
|
||||
int *c;
|
||||
|
||||
T_log(T_QUIET, "setup 2 begin");
|
||||
T_eq_ptr(ctx, &initial_value_2);
|
||||
T_eq_ptr(ctx, T_fixture_context());
|
||||
c = ctx;
|
||||
counter_2 = *c;
|
||||
T_set_fixture_context(&counter_2);
|
||||
T_eq_ptr(&counter_2, T_fixture_context());
|
||||
T_log(T_QUIET, "setup 2 end");
|
||||
}
|
||||
|
||||
static void
|
||||
stop_2(void *ctx)
|
||||
{
|
||||
int *c;
|
||||
|
||||
T_log(T_QUIET, "stop 2 begin");
|
||||
T_eq_ptr(ctx, &counter_2);
|
||||
c = ctx;
|
||||
++(*c);
|
||||
T_log(T_QUIET, "stop 2 end");
|
||||
}
|
||||
|
||||
static void
|
||||
teardown_2(void *ctx)
|
||||
{
|
||||
int *c;
|
||||
|
||||
T_log(T_QUIET, "teardown 2 begin");
|
||||
T_eq_ptr(ctx, &counter_2);
|
||||
c = ctx;
|
||||
T_eq_int(*c, 8);
|
||||
T_log(T_QUIET, "teardown 2 end");
|
||||
}
|
||||
|
||||
static void
|
||||
scope_2(void *ctx, char *buf, size_t n)
|
||||
{
|
||||
|
||||
strlcpy(buf, "/AndMore", n);
|
||||
}
|
||||
|
||||
static const T_fixture fixture_2 = {
|
||||
.setup = setup_2,
|
||||
.stop = stop_2,
|
||||
.teardown = teardown_2,
|
||||
.scope = scope_2,
|
||||
.initial_context = &initial_value_2
|
||||
};
|
||||
|
||||
static T_fixture_node node;
|
||||
|
||||
T_TEST_CASE_FIXTURE(fixture, &fixture)
|
||||
{
|
||||
void *ctx;
|
||||
|
||||
T_assert_true(true, "all right");
|
||||
ctx = T_push_fixture(&node, &fixture_2);
|
||||
T_eq_ptr(ctx, &initial_value_2);
|
||||
++counter_2;
|
||||
T_pop_fixture();
|
||||
ctx = T_push_fixture(&node, &fixture_2);
|
||||
T_eq_ptr(ctx, &initial_value_2);
|
||||
T_assert_true(false, "test fails and we stop the test case");
|
||||
T_log(T_QUIET, "not reached");
|
||||
}
|
||||
@@ -74,16 +142,39 @@ T_TEST_OUTPUT(fixture,
|
||||
"P:1:0:UI1/More:test-fixture.c:14\n"
|
||||
"P:2:0:UI1/More:test-fixture.c:18\n"
|
||||
"L:setup end\n"
|
||||
"P:3:0:UI1/More:test-fixture.c:63\n"
|
||||
"F:4:0:UI1/More:test-fixture.c:64:test fails and we stop the test case\n"
|
||||
"P:3:0:UI1/More:test-fixture.c:125\n"
|
||||
"L:setup 2 begin\n"
|
||||
"P:4:0:UI1/More/AndMore:test-fixture.c:71\n"
|
||||
"P:5:0:UI1/More/AndMore:test-fixture.c:72\n"
|
||||
"P:6:0:UI1/More/AndMore:test-fixture.c:76\n"
|
||||
"L:setup 2 end\n"
|
||||
"P:7:0:UI1/More/AndMore:test-fixture.c:127\n"
|
||||
"L:teardown 2 begin\n"
|
||||
"P:8:0:UI1/More:test-fixture.c:98\n"
|
||||
"P:9:0:UI1/More:test-fixture.c:100\n"
|
||||
"L:teardown 2 end\n"
|
||||
"L:setup 2 begin\n"
|
||||
"P:10:0:UI1/More/AndMore:test-fixture.c:71\n"
|
||||
"P:11:0:UI1/More/AndMore:test-fixture.c:72\n"
|
||||
"P:12:0:UI1/More/AndMore:test-fixture.c:76\n"
|
||||
"L:setup 2 end\n"
|
||||
"P:13:0:UI1/More/AndMore:test-fixture.c:131\n"
|
||||
"F:14:0:UI1/More/AndMore:test-fixture.c:132:test fails and we stop the test case\n"
|
||||
"L:stop 2 begin\n"
|
||||
"P:15:0:UI1/More/AndMore:test-fixture.c:86\n"
|
||||
"L:stop 2 end\n"
|
||||
"L:stop begin\n"
|
||||
"P:5:0:UI1/More:test-fixture.c:28\n"
|
||||
"P:16:0:UI1/More/AndMore:test-fixture.c:28\n"
|
||||
"L:stop end\n"
|
||||
"L:teardown 2 begin\n"
|
||||
"P:17:0:UI1/More/AndMore:test-fixture.c:98\n"
|
||||
"P:18:0:UI1/More/AndMore:test-fixture.c:100\n"
|
||||
"L:teardown 2 end\n"
|
||||
"L:teardown begin\n"
|
||||
"P:6:0:UI1/More:test-fixture.c:40\n"
|
||||
"P:7:0:UI1/More:test-fixture.c:42\n"
|
||||
"P:19:0:UI1/More:test-fixture.c:40\n"
|
||||
"P:20:0:UI1/More:test-fixture.c:42\n"
|
||||
"L:teardown end\n"
|
||||
"E:fixture:N:8:F:1:D:0.001000\n");
|
||||
"E:fixture:N:21:F:1:D:0.001000\n");
|
||||
|
||||
/*
|
||||
* The license is at the end of the file to be able to use the test code and
|
||||
@@ -94,7 +185,7 @@ T_TEST_OUTPUT(fixture,
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-2-Clause OR CC-BY-SA-4.0
|
||||
*
|
||||
* Copyright (C) 2018, 2019 embedded brains GmbH
|
||||
* Copyright (C) 2018, 2020 embedded brains GmbH
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
||||
Reference in New Issue
Block a user