@@ -66,6 +66,11 @@ static int parse_arg(const char* key, const char* value, struct TestFramework* t
66
66
if (strcmp (key , "t" ) == 0 || strcmp (key , "target" ) == 0 ) {
67
67
return parse_target (value , tf );
68
68
}
69
+ /* Logging */
70
+ if (strcmp (key , "log" ) == 0 ) {
71
+ tf -> args .logging = value && strcmp (value , "1" ) == 0 ;
72
+ return 0 ;
73
+ }
69
74
70
75
/* Unknown key: report just so typos don’t silently pass. */
71
76
printf ("Unknown argument '-%s=%s'\n" , key , value );
@@ -83,6 +88,7 @@ static void help(void) {
83
88
printf (" -seed=<hex> Set a specific RNG seed (default: random)\n" );
84
89
printf (" -target=<test name>, -t=<name> Run a specific test (can be provided multiple times)\n" );
85
90
printf (" -target=<module name>, -t=<module> Run all tests within a specific module (can be provided multiple times)\n" );
91
+ printf (" -log=<0|1> Enable or disable test execution logging (default: 0 = disabled)\n" );
86
92
printf ("\n" );
87
93
printf ("Notes:\n" );
88
94
printf (" - All arguments must be provided in the form '-key=value'.\n" );
@@ -192,18 +198,21 @@ static int read_args(int argc, char** argv, int start, struct TestFramework* tf)
192
198
return 0 ;
193
199
}
194
200
195
- static void run_test (const struct TestEntry * t ) {
201
+ static void run_test_log (const struct TestEntry * t ) {
202
+ int64_t start_time = gettime_i64 ();
196
203
printf ("Running %s..\n" , t -> name );
197
204
t -> func ();
198
- printf ("%s PASSED\n" , t -> name );
205
+ printf ("Test %s PASSED (%.3f sec) \n" , t -> name , ( double )( gettime_i64 () - start_time ) / 1000000 );
199
206
}
200
207
208
+ static void run_test (const struct TestEntry * t ) { t -> func (); }
209
+
201
210
/* Process tests in sequential order */
202
211
static int run_sequential (struct TestFramework * tf ) {
203
212
int it ;
204
213
for (it = 0 ; it < tf -> args .targets .size ; it ++ ) {
205
214
TestRef * index = & tf -> args .targets .slots [it ];
206
- run_test (& tf -> registry_modules [index -> group ].data [index -> idx ]);
215
+ tf -> fn_run_test (& tf -> registry_modules [index -> group ].data [index -> idx ]);
207
216
}
208
217
return EXIT_SUCCESS ;
209
218
}
@@ -241,7 +250,7 @@ static int run_concurrent(struct TestFramework* tf) {
241
250
TestRef tref ;
242
251
close (pipes [it ][1 ]); /* Close write end */
243
252
while (read (pipes [it ][0 ], & tref , sizeof (tref )) == sizeof (tref )) {
244
- run_test (& tf -> registry_modules [tref .group ].data [tref .idx ]);
253
+ tf -> fn_run_test (& tf -> registry_modules [tref .group ].data [tref .idx ]);
245
254
}
246
255
_exit (EXIT_SUCCESS ); /* finish child process */
247
256
} else {
@@ -283,6 +292,7 @@ static int tf_init(struct TestFramework* tf, int argc, char** argv)
283
292
tf -> args .num_processes = 0 ;
284
293
tf -> args .custom_seed = NULL ;
285
294
tf -> args .targets .size = 0 ;
295
+ tf -> args .logging = 0 ;
286
296
287
297
/* Disable buffering for stdout to improve reliability of getting
288
298
* diagnostic information. Happens right at the start of main because
@@ -325,6 +335,7 @@ static int tf_init(struct TestFramework* tf, int argc, char** argv)
325
335
}
326
336
}
327
337
338
+ tf -> fn_run_test = tf -> args .logging ? run_test_log : run_test ;
328
339
return EXIT_SUCCESS ;
329
340
}
330
341
@@ -335,6 +346,12 @@ static int tf_run(struct TestFramework* tf) {
335
346
struct TestEntry * t ;
336
347
/* Initial test time */
337
348
int64_t start_time = gettime_i64 (); /* maybe move this after the slots set */
349
+ /* Verify 'tf_init' has been called */
350
+ if (!tf -> fn_run_test ) {
351
+ fprintf (stderr , "Error: No test runner set. You must call 'tf_init' first to initialize the framework "
352
+ "or manually assign 'fn_run_test' before calling 'tf_run'.\n" );
353
+ return EXIT_FAILURE ;
354
+ }
338
355
339
356
/* Populate targets with all tests if none were explicitly specified */
340
357
if (tf -> args .targets .size == 0 ) {
@@ -354,12 +371,14 @@ static int tf_run(struct TestFramework* tf) {
354
371
tf -> args .targets .size = slot ;
355
372
}
356
373
374
+ if (!tf -> args .logging ) printf ("Tests running silently. Use '-log=1' to enable detailed logging\n" );
375
+
357
376
/* Run test RNG tests (must run before we really initialize the test RNG) */
358
377
/* Note: currently, these tests are executed sequentially because there */
359
378
/* is really only one test. */
360
379
for (t = tf -> registry_no_ctx ; t -> name ; t ++ ) {
361
380
if (tf -> args .targets .size == 0 ) { /* future: support filtering */
362
- run_test (t );
381
+ tf -> fn_run_test (t );
363
382
}
364
383
}
365
384
0 commit comments