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 
25 static int _runModule(GWEN_GUI *gui, GWEN_TEST_MODULE *mod, int depth);
26 static int _runTest(GWEN_GUI *gui, GWEN_TEST_MODULE *mod, int depth);
27 static GWEN_GUI *_setupGui(GWEN_TEST_FRAMEWORK *tf, int argc, char **argv);
28 static void _finishGui(GWEN_GUI *gui);
29 static GWEN_DB_NODE *_readCommandLine(int argc, char **argv);
30 
31 
32 
33 
34 
35 int 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 
55 GWEN_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 
88 void _finishGui(GWEN_GUI *gui)
89 {
90  Test_Gui_FlushLogs(gui);
91  TestGui_Unextend(gui);
92 }
93 
94 
95 
96 int _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 
146 int _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);
169  if (rv!=GWEN_ERROR_NOT_IMPLEMENTED) {
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 
223  GWEN_FREE_OBJECT(tf);
224  }
225 }
226 
227 
228 
230 {
231  assert(tf);
232  return tf->modulesRoot;
233 }
234 
235 
236 
237 
238 GWEN_DB_NODE *_readCommandLine(int argc, char **argv)
239 {
240  GWEN_DB_NODE *db;
241  int rv;
242  const GWEN_ARGS args[]= {
243  {
244  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
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  {
255  GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
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");
285  GWEN_DB_Group_free(db);
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");
294  GWEN_DB_Group_free(db);
295  return NULL;
296  }
297  fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(ubuf));
298  GWEN_Buffer_free(ubuf);
299  GWEN_DB_Group_free(db);
300  return NULL;
301  }
302 
303  return db;
304 }
305 
306 
307 
308 
void GWEN_Test_Module_free(GWEN_TEST_MODULE *p_struct)
Definition: testmodule.c:43
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
GWEN_TEST_MODULE * GWEN_Test_Module_new(void)
Definition: testmodule.c:24
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition: db.c:421
#define GWEN_ERROR_INVALID
Definition: error.h:67
static int _runModule(GWEN_GUI *gui, GWEN_TEST_MODULE *mod, int depth)
Definition: testframework.c:96
GWEN_TEST_FRAMEWORK * TestFramework_new()
const char * GWEN_Test_Module_GetName(const GWEN_TEST_MODULE *p_struct)
Definition: testmodule.c:166
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
void TestGui_Extend(GWEN_GUI *gui)
Definition: testgui.c:41
void TestGui_Unextend(GWEN_GUI *gui)
Definition: testgui.c:55
static GWEN_DB_NODE * _readCommandLine(int argc, char **argv)
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void TestGui_SetLogFile(GWEN_GUI *gui, const char *fname)
Definition: testgui.c:149
#define GWEN_ARGS_FLAGS_HELP
Definition: src/base/args.h:52
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
void GWEN_Buffer_Reset(GWEN_BUFFER *bf)
Definition: buffer.c:650
#define GWEN_ARGS_RESULT_HELP
Definition: src/base/args.h:58
void TestFramework_AddModule(GWEN_TEST_FRAMEWORK *tf, GWEN_TEST_MODULE *mod)
#define GWEN_ARGS_RESULT_ERROR
Definition: src/base/args.h:57
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
static int _runTest(GWEN_GUI *gui, GWEN_TEST_MODULE *mod, int depth)
struct GWEN_TEST_MODULE GWEN_TEST_MODULE
Definition: testmodule.h:65
int GWEN_Args_Usage(const GWEN_ARGS *args, GWEN_BUFFER *ubuf, GWEN_ARGS_OUTTYPE ot)
GWEN_GUI * GWEN_Gui_GetGui(void)
Definition: gui.c:160
void Test_Gui_FlushLogs(GWEN_GUI *gui)
Definition: testgui.c:88
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:971
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
#define GWEN_ARGS_FLAGS_LAST
Definition: src/base/args.h:51
void TestFramework_free(GWEN_TEST_FRAMEWORK *tf)
void GWEN_Test_Module_SetResult(GWEN_TEST_MODULE *p_struct, int p_src)
Definition: testmodule.c:226
void TestGui_AddLogLine(GWEN_GUI *gui, const char *s)
Definition: testgui.c:133
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
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 TestFramework_Run(GWEN_TEST_FRAMEWORK *tf, int argc, char **argv)
Definition: testframework.c:35
void TestGui_SetLogLastX(GWEN_GUI *gui, int i)
Definition: testgui.c:167
struct GWEN_TEST_FRAMEWORK GWEN_TEST_FRAMEWORK
Definition: testframework.h:23
static GWEN_GUI * _setupGui(GWEN_TEST_FRAMEWORK *tf, int argc, char **argv)
Definition: testframework.c:55
struct GWEN_GUI GWEN_GUI
Definition: gui.h:176
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, const char *path, int idx, int defVal)
Definition: db.c:1163
int GWEN_Buffer_FillWithBytes(GWEN_BUFFER *bf, unsigned char c, uint32_t size)
Definition: buffer.c:1009
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition: db.c:173
GWEN_TEST_MODULE * TestFramework_GetModulesRoot(const GWEN_TEST_FRAMEWORK *tf)
static void _finishGui(GWEN_GUI *gui)
Definition: testframework.c:88
#define GWEN_ARGS_FLAGS_HAS_ARGUMENT
Definition: src/base/args.h:50
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
int GWEN_Test_Module_Test(GWEN_TEST_MODULE *p_struct)
Definition: testmodule.c:248
void GWEN_Test_Module_SetName(GWEN_TEST_MODULE *p_struct, const char *p_src)
Definition: testmodule.c:196
#define GWEN_ERROR_NOT_IMPLEMENTED
Definition: error.h:108