gwenhywfar 5.10.1
testframework.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Thu Jan 09 2020
3 copyright : (C) 2020 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * Please see toplevel file COPYING for license details *
8 ***************************************************************************/
9
10#ifdef HAVE_CONFIG_H
11# include <config.h>
12#endif
13
14#include "testframework_p.h"
15#include "testgui_l.h"
16
17#include <gwenhywfar/args.h>
18#include <gwenhywfar/error.h>
19#include <gwenhywfar/gui.h>
20#include <gwenhywfar/debug.h>
21
22
23
24
25static int _runModule(GWEN_GUI *gui, GWEN_TEST_MODULE *mod, int depth);
26static int _runTest(GWEN_GUI *gui, GWEN_TEST_MODULE *mod, int depth);
27static GWEN_GUI *_setupGui(GWEN_TEST_FRAMEWORK *tf, int argc, char **argv);
28static void _finishGui(GWEN_GUI *gui);
29static GWEN_DB_NODE *_readCommandLine(int argc, char **argv);
30
31
32
33
34
35int TestFramework_Run(GWEN_TEST_FRAMEWORK *tf, int argc, char **argv)
36{
37 int rv;
38 GWEN_GUI *gui;
39
40 assert(tf);
41
42 gui=_setupGui(tf, argc, argv);
43 if (gui==NULL) {
44 fprintf(stderr, "ERROR: Could not setup GUI\n");
45 return GWEN_ERROR_INVALID;
46 }
47 rv=_runModule(gui, tf->modulesRoot, 0);
48 _finishGui(gui);
49
50 return rv;
51}
52
53
54
55GWEN_GUI *_setupGui(GWEN_TEST_FRAMEWORK *tf, int argc, char **argv)
56{
57 GWEN_DB_NODE *dbArgs;
58 GWEN_GUI *gui;
59 const char *s;
60 int i;
61
62 dbArgs=_readCommandLine(argc, argv);
63 if (dbArgs==NULL) {
64 fprintf(stderr, "ERROR: Could not parse arguments\n");
66 return NULL;
67 }
68
69 gui=GWEN_Gui_GetGui();
70 if (gui==NULL) {
71 DBG_ERROR(GWEN_LOGDOMAIN, "Need to create and set a GUI first!");
72 return NULL;
73 }
74
75 TestGui_Extend(gui);
76
77 s=GWEN_DB_GetCharValue(dbArgs, "logFile", 0, NULL);
78 if (s && *s)
79 TestGui_SetLogFile(gui, s);
80 i=GWEN_DB_GetIntValue(dbArgs, "logLastLines", 0, 0);
81 TestGui_SetLogLastX(gui, i);
82
83 return gui;
84}
85
86
87
89{
92}
93
94
95
96int _runModule(GWEN_GUI *gui, GWEN_TEST_MODULE *mod, int depth)
97{
98 int rv;
99 GWEN_TEST_MODULE *subMod;
100 int subModsFailed=0;
101
102 subMod=GWEN_Test_Module_Tree2_GetFirstChild(mod);
103 if (subMod) {
104 const char *sName;
105 GWEN_BUFFER *fbuf;
106 int i;
107
108 /* has sub modules, so is no test */
109 sName=GWEN_Test_Module_GetName(mod);
110 fbuf=GWEN_Buffer_new(0, 256, 0, 1);
111 GWEN_Buffer_AppendString(fbuf, "==== Module: ");
112 if (sName && *sName)
113 GWEN_Buffer_AppendString(fbuf, sName);
114 GWEN_Buffer_AppendString(fbuf, "==== \n");
116 GWEN_Buffer_free(fbuf);
117
118 for (i=0; i<depth; i++)
119 fprintf(stdout, " ");
120 fprintf(stdout, "Module %s\n", (sName && *sName)?sName:"");
121
122 subMod=GWEN_Test_Module_Tree2_GetFirstChild(mod);
123 while (subMod) {
124 rv=_runModule(gui, subMod, depth+1);
125 if (rv<0 && rv!=GWEN_ERROR_NOT_IMPLEMENTED) {
126 subModsFailed++;
127 }
128 subMod=GWEN_Test_Module_Tree2_GetNext(subMod);
129 }
130
131 GWEN_Test_Module_SetResult(mod, subModsFailed);
132 return 0;
133 }
134 else {
135 /* is a test with no sub modules, run directly */
136 rv=_runTest(gui, mod, depth);
137 if (rv<0)
138 return rv;
139
140 return 0;
141 }
142}
143
144
145
146int _runTest(GWEN_GUI *gui, GWEN_TEST_MODULE *mod, int depth)
147{
148 const char *sName;
149 GWEN_BUFFER *fbuf;
150 int rv;
151
152 sName=GWEN_Test_Module_GetName(mod);
153 fbuf=GWEN_Buffer_new(0, 256, 0, 1);
154 GWEN_Buffer_AppendString(fbuf, "---- Starting Test: ");
155 if (sName && *sName)
156 GWEN_Buffer_AppendString(fbuf, sName);
157 GWEN_Buffer_AppendString(fbuf, "---- \n");
159 GWEN_Buffer_Reset(fbuf);
160
161 GWEN_Buffer_FillWithBytes(fbuf, ' ', depth);
162 if (sName && *sName)
163 GWEN_Buffer_AppendString(fbuf, sName);
164 else
165 GWEN_Buffer_AppendString(fbuf, "Test");
166 GWEN_Buffer_AppendString(fbuf, ": ");
167
168 rv=GWEN_Test_Module_Test(mod);
170 if (rv<0) {
172 TestGui_AddLogLine(gui, "->FAILED!\n");
173 GWEN_Buffer_AppendString(fbuf, "FAILED!");
174 fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(fbuf));
175 GWEN_Buffer_free(fbuf);
176 return rv;
177 }
178 TestGui_AddLogLine(gui, "->passed\n");
179 GWEN_Buffer_AppendString(fbuf, "passed.");
180 fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(fbuf));
181 }
182 GWEN_Buffer_Reset(fbuf);
183
184 GWEN_Buffer_AppendString(fbuf, "---- Ended Test : ");
185 if (sName && *sName)
186 GWEN_Buffer_AppendString(fbuf, sName);
187 GWEN_Buffer_AppendString(fbuf, "---- \n");
189 GWEN_Buffer_free(fbuf);
190 return 0;
191}
192
193
194
196{
197 assert(tf);
198 assert(tf->modulesRoot);
199 GWEN_Test_Module_Tree2_AddChild(tf->modulesRoot, mod);
200}
201
202
203
205{
207
209 assert(tf);
210 tf->modulesRoot=GWEN_Test_Module_new();
211 GWEN_Test_Module_SetName(tf->modulesRoot, "Root");
212
213 return tf;
214}
215
216
217
219{
220 if (tf) {
221 GWEN_Test_Module_free(tf->modulesRoot);
222
224 }
225}
226
227
228
230{
231 assert(tf);
232 return tf->modulesRoot;
233}
234
235
236
237
238GWEN_DB_NODE *_readCommandLine(int argc, char **argv)
239{
240 GWEN_DB_NODE *db;
241 int rv;
242 const GWEN_ARGS args[]= {
243 {
245 GWEN_ArgsType_Char, /* type */
246 "logFile", /* name */
247 0, /* minnum */
248 1, /* maxnum */
249 "L", /* short option */
250 "logFile", /* long option */
251 "Specify the log file (default: stdout)", /* short description */
252 "Specify the log file (default: stdout))" /* long description */
253 },
254 {
256 GWEN_ArgsType_Int, /* type */
257 "logLastLines", /* name */
258 0, /* minnum */
259 1, /* maxnum */
260 0, /* short option */
261 "logLastLines", /* long option */
262 "Set size of log line buffer (default: unlimited number of lines)", /* short description */
263 "Set size of log line buffer (default: unlimited number of lines)" /* long description */
264 },
265 {
267 GWEN_ArgsType_Int, /* type */
268 "help", /* name */
269 0, /* minnum */
270 0, /* maxnum */
271 "h", /* short option */
272 "help", /* long option */
273 "Show this help screen", /* short description */
274 "Show this help screen" /* long description */
275 }
276 };
277
278 db=GWEN_DB_Group_new("args");
279 rv=GWEN_Args_Check(argc, argv, 1,
280 0 /*GWEN_ARGS_MODE_ALLOW_FREEPARAM*/,
281 args,
282 db);
283 if (rv==GWEN_ARGS_RESULT_ERROR) {
284 fprintf(stderr, "ERROR: Could not parse arguments\n");
286 return NULL;
287 }
288 else if (rv==GWEN_ARGS_RESULT_HELP) {
289 GWEN_BUFFER *ubuf;
290
291 ubuf=GWEN_Buffer_new(0, 1024, 0, 1);
292 if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
293 fprintf(stderr, "ERROR: Could not create help string\n");
295 return NULL;
296 }
297 fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(ubuf));
298 GWEN_Buffer_free(ubuf);
300 return NULL;
301 }
302
303 return db;
304}
305
306
307
308
#define NULL
Definition: binreloc.c:300
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
int GWEN_Buffer_FillWithBytes(GWEN_BUFFER *bf, unsigned char c, uint32_t size)
Definition: buffer.c:1009
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:650
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:971
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition: db.c:173
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, const char *path, int idx, int defVal)
Definition: db.c:1163
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition: db.c:421
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
#define GWEN_ERROR_NOT_IMPLEMENTED
Definition: error.h:108
#define GWEN_ERROR_INVALID
Definition: error.h:67
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
GWEN_GUI * GWEN_Gui_GetGui(void)
Definition: gui.c:160
struct GWEN_GUI GWEN_GUI
Definition: gui.h:176
#define GWEN_LOGDOMAIN
Definition: logger.h:35
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
int GWEN_Args_Check(int argc, char **argv, int startAt, uint32_t mode, const GWEN_ARGS *args, GWEN_DB_NODE *db)
Definition: src/base/args.c:45
int GWEN_Args_Usage(const GWEN_ARGS *args, GWEN_BUFFER *ubuf, GWEN_ARGS_OUTTYPE ot)
#define GWEN_ARGS_FLAGS_HAS_ARGUMENT
Definition: src/base/args.h:50
#define GWEN_ARGS_RESULT_ERROR
Definition: src/base/args.h:57
#define GWEN_ARGS_FLAGS_HELP
Definition: src/base/args.h:52
#define GWEN_ARGS_FLAGS_LAST
Definition: src/base/args.h:51
@ GWEN_ArgsOutType_Txt
Definition: src/base/args.h:68
@ GWEN_ArgsType_Int
Definition: src/base/args.h:63
@ GWEN_ArgsType_Char
Definition: src/base/args.h:62
#define GWEN_ARGS_RESULT_HELP
Definition: src/base/args.h:58
static int _runModule(GWEN_GUI *gui, GWEN_TEST_MODULE *mod, int depth)
Definition: testframework.c:96
void TestFramework_AddModule(GWEN_TEST_FRAMEWORK *tf, GWEN_TEST_MODULE *mod)
int TestFramework_Run(GWEN_TEST_FRAMEWORK *tf, int argc, char **argv)
Definition: testframework.c:35
static int _runTest(GWEN_GUI *gui, GWEN_TEST_MODULE *mod, int depth)
void TestFramework_free(GWEN_TEST_FRAMEWORK *tf)
GWEN_TEST_MODULE * TestFramework_GetModulesRoot(const GWEN_TEST_FRAMEWORK *tf)
GWEN_TEST_FRAMEWORK * TestFramework_new()
static void _finishGui(GWEN_GUI *gui)
Definition: testframework.c:88
static GWEN_DB_NODE * _readCommandLine(int argc, char **argv)
static GWEN_GUI * _setupGui(GWEN_TEST_FRAMEWORK *tf, int argc, char **argv)
Definition: testframework.c:55
struct GWEN_TEST_FRAMEWORK GWEN_TEST_FRAMEWORK
Definition: testframework.h:23
void TestGui_Extend(GWEN_GUI *gui)
Definition: testgui.c:41
void TestGui_AddLogLine(GWEN_GUI *gui, const char *s)
Definition: testgui.c:133
void TestGui_SetLogFile(GWEN_GUI *gui, const char *fname)
Definition: testgui.c:149
void Test_Gui_FlushLogs(GWEN_GUI *gui)
Definition: testgui.c:88
void TestGui_SetLogLastX(GWEN_GUI *gui, int i)
Definition: testgui.c:167
void TestGui_Unextend(GWEN_GUI *gui)
Definition: testgui.c:55
const char * GWEN_Test_Module_GetName(const GWEN_TEST_MODULE *p_struct)
Definition: testmodule.c:166
void GWEN_Test_Module_SetName(GWEN_TEST_MODULE *p_struct, const char *p_src)
Definition: testmodule.c:196
void GWEN_Test_Module_free(GWEN_TEST_MODULE *p_struct)
Definition: testmodule.c:43
GWEN_TEST_MODULE * GWEN_Test_Module_new(void)
Definition: testmodule.c:24
void GWEN_Test_Module_SetResult(GWEN_TEST_MODULE *p_struct, int p_src)
Definition: testmodule.c:226
int GWEN_Test_Module_Test(GWEN_TEST_MODULE *p_struct)
Definition: testmodule.c:248
struct GWEN_TEST_MODULE GWEN_TEST_MODULE
Definition: testmodule.h:65