-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for deferring cleanup operations
This patch adds two main features: - ability to offer resources to the test system - ability to queue cleanup operations Signed-off-by: Zygmunt Krynicki <me@zygoon.pl>
- Loading branch information
Showing
17 changed files
with
709 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,4 +25,6 @@ VERS_0_2 { | |
VERS_0_3 { | ||
global: | ||
zt_cmp_ptr; | ||
zt_visit_resource; | ||
zt_defer; | ||
} VERS_0_2; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
.Dd January 14, 2020 | ||
.Os libzt @VERSION@ | ||
.Dt zt_closure 3 PRM | ||
.Sh NAME | ||
.Nm zt_closure | ||
.Nd structure representing a function closure | ||
.Sh SYNOPSIS | ||
.In zt.h | ||
.Bd -literal | ||
typedef struct zt_closure { | ||
union { | ||
zt_closure_func0 args0; | ||
zt_closure_func1 args1; | ||
} func; | ||
zt_location location; | ||
int nargs; | ||
zt_value args[1]; | ||
} zt_closure; | ||
.Be | ||
.Sh DESCRIPTION | ||
The structure | ||
.Nm | ||
contains a function pointer and at most one argument represented as a | ||
.Nm zt_value . | ||
.Pp | ||
Closures are used by | ||
.Fn zt_defer | ||
to facilitate reliable management of memory and other resources inside test | ||
code. It can be also used to setup and restore mocking of application | ||
behaviors. Function arguments are represented by | ||
.Nm zt_value | ||
for convenience, to avoid casting integers and pointers. Test code is | ||
expected to provide wrapper functions that take a | ||
.Nm zt_value | ||
argument and pass the call to another function such as | ||
.Fn free | ||
or | ||
.Fn close . | ||
.Sh IMPLEMENTATION NOTES | ||
The | ||
.Nm location | ||
field describes location in the source code where the closure was packed. It | ||
is used in some diagnostic error messages. | ||
.Sh SEE ALSO | ||
.Xr zt_closure_func0 3 , | ||
.Xr zt_closure_func1 3 , | ||
.Xr zt_defer 3 , | ||
.Xr zt_location 3 , | ||
.Xr zt_pack_closure0 3 , | ||
.Xr zt_pack_closure1 3 , | ||
.Xr zt_value 3 | ||
.Sh HISTORY | ||
The structure | ||
.Nm | ||
first appeared in libzt 0.4 | ||
.Sh AUTHORS | ||
.An "Zygmunt Krynicki" Aq Mt me@zygoon.pl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
.Dd January 14, 2020 | ||
.Os libzt @VERSION@ | ||
.Dt zt_closure_func0 3 PRM | ||
.Sh NAME | ||
.Nm zt_closure_func0 | ||
.Nd function type for closures without arguments | ||
.Sh SYNOPSIS | ||
.In zt.h | ||
.Ft typedef void | ||
.Fo (*zt_closure_func0) | ||
.Fa "void" | ||
.Fc | ||
.Sh DESCRIPTION | ||
.Nm | ||
is a function type that takes no arguments. It is used by | ||
.Nm zt_closure . | ||
.Sh SEE ALSO | ||
.Xr zt_closure 3 | ||
.Sh HISTORY | ||
The type | ||
.Nm | ||
first appeared in libzt 0.4 | ||
.Sh AUTHORS | ||
.An "Zygmunt Krynicki" Aq Mt me@zygoon.pl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
.Dd January 14, 2020 | ||
.Os libzt @VERSION@ | ||
.Dt zt_closure_func1 3 PRM | ||
.Sh NAME | ||
.Nm zt_closure_func1 | ||
.Nd function type for closures with one argument | ||
.Sh SYNOPSIS | ||
.In zt.h | ||
.Ft typedef void | ||
.Fo (*zt_closure_func1) | ||
.Fa "zt_value arg1" | ||
.Fc | ||
.Sh DESCRIPTION | ||
.Nm | ||
is a function type that takes one argument. It is used by | ||
.Nm zt_closure . | ||
.Sh SEE ALSO | ||
.Xr zt_closure 3 , | ||
.Xr zt_value 3 | ||
.Sh HISTORY | ||
The type | ||
.Nm | ||
first appeared in libzt 0.4 | ||
.Sh AUTHORS | ||
.An "Zygmunt Krynicki" Aq Mt me@zygoon.pl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
.Dd January 14, 2020 | ||
.Os libzt @VERSION@ | ||
.Dt zt_defer 3 PRM | ||
.Sh NAME | ||
.Nm zt_defer, | ||
.Nd call a function after the current test terminates | ||
.Sh SYNOPSIS | ||
.In zt.h | ||
.Ft void | ||
.Fo zt_defer | ||
.Fa "zt_t t" | ||
.Fa "zt_closure closure" | ||
.Fc | ||
.Sh DESCRIPTION | ||
The function | ||
.Fn | ||
arranges for the function encapsulated by | ||
.Em closure | ||
to be called at after the current test function returns. | ||
This mechanism works even in the case of non-local exit | ||
used by | ||
.Fn zt_assert . | ||
It is designed to allow test authors to reclaim allocated memory, close | ||
files, restore the state of mocked state or other tasks that are required | ||
to ensure program consistency. | ||
.Pp | ||
In the spirit of robustness, the burden of providing memory for deferred | ||
function calls is shifted to the test author. Test authors must provide a | ||
.Em test resource | ||
of the kind | ||
.Em ZT_RESOURCE_DEFER_CLOSURES | ||
with enough capacity to remember all of the deferred calls in all the tests. | ||
This can be done by calling | ||
.Fn zt_visit_resource | ||
anywhere in a test suite function, before visiting the first test that relies | ||
on defer. | ||
.Pp | ||
If insufficient amount of defer resources are available, the defer function | ||
is called immediately, the current test is marked as failed and the test | ||
terminates through a non-local exit. Note that succesfully deferred calls | ||
are also executed regardless of the means of exiting from a test function. | ||
.Sh IMPLEMENTATION NOTES | ||
Defer is implemented using a stack of | ||
.Nm zt_closure | ||
structures. Before visiting a test function, the stack is emptied. | ||
At the end of the test subsequent closures are popped and executed. | ||
.Sh RETURN VALUES | ||
.Nm | ||
does not return any value. | ||
.Sh EXAMPLES | ||
The following example shows a minimal test program using resources and defer | ||
to ensure that allocated memory is not leaked. | ||
.Bd -literal -offset indent | ||
#include <stdlib.h> | ||
#include <zt.h> | ||
|
||
static void free_value(zt_value val) { | ||
free(val.as.pointer); | ||
} | ||
|
||
#define FREE(ptr) ZT_CLOSURE1(free_value, zt_pack_pointer((ptr), #ptr)) | ||
|
||
static void test_allocated_memory(zt_t t) { | ||
void *m = malloc(100); | ||
zt_assert(t, ZT_NOT_NULL(m)); | ||
zt_defer(t, FREE(m)); | ||
/* Do something with the allocated memory. */ | ||
} | ||
|
||
static void test_suite(zt_visitor v) { | ||
zt_closure closures[1]; | ||
zt_visit_resource(v, ZT_RESOURCE_DEFER_CLOSURES, | ||
sizeof closures / sizeof *closures, closures); | ||
ZT_VISIT_TEST_CASE(v, test_allocated_memory); | ||
} | ||
|
||
int main(int argc, char** argv, char** envp) { | ||
return zt_main(argc, argv, envp, test_suite); | ||
} | ||
.Ed | ||
.Sh SEE ALSO | ||
.Xr ZT_CLOSURE0 3 , | ||
.Xr ZT_CLOSURE1 3 , | ||
.Xr zt_closure 3 , | ||
.Xr zt_visit_resource 3 | ||
.Sh HISTORY | ||
The function | ||
.Nm | ||
first appeared in libzt 0.4 | ||
.Sh AUTHORS | ||
.An "Zygmunt Krynicki" Aq Mt me@zygoon.pl |
Oops, something went wrong.