summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2020-06-09 15:55:22 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2020-07-23 09:27:47 +0200
commitcb3c6bdc0f6a89609b88f2c4d647e18d8bcdd843 (patch)
tree461dff981d361a5a861ed5302fe876d630b4170a
parentlibtest: Support custom scope messages via fixture (diff)
downloadrtems-cb3c6bdc0f6a89609b88f2c4d647e18d8bcdd843.tar.bz2
libtest: Add push/pop fixture support
Update #3199.
-rw-r--r--cpukit/include/rtems/test.h11
-rw-r--r--cpukit/libtest/t-test.c110
-rw-r--r--testsuites/libtests/ttest01/init.c4
-rw-r--r--testsuites/libtests/ttest01/test-fixture.c105
4 files changed, 200 insertions, 30 deletions
diff --git a/cpukit/include/rtems/test.h b/cpukit/include/rtems/test.h
index 2362e5b804..04f92dd1f4 100644
--- a/cpukit/include/rtems/test.h
+++ b/cpukit/include/rtems/test.h
@@ -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); \
diff --git a/cpukit/libtest/t-test.c b/cpukit/libtest/t-test.c
index aa04f09139..bf9b68cdf2 100644
--- a/cpukit/libtest/t-test.c
+++ b/cpukit/libtest/t-test.c
@@ -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));
+}
diff --git a/testsuites/libtests/ttest01/init.c b/testsuites/libtests/ttest01/init.c
index 1763a21616..a5df3932f7 100644
--- a/testsuites/libtests/ttest01/init.c
+++ b/testsuites/libtests/ttest01/init.c
@@ -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)
diff --git a/testsuites/libtests/ttest01/test-fixture.c b/testsuites/libtests/ttest01/test-fixture.c
index c3515c320a..545fbf19dc 100644
--- a/testsuites/libtests/ttest01/test-fixture.c
+++ b/testsuites/libtests/ttest01/test-fixture.c
@@ -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