@@ -199,6 +199,14 @@ static test_fnptr test_function(const struct test_suite *t, int subtest)
199
199
return t -> test_cases [subtest ].run_case ;
200
200
}
201
201
202
+ static bool test_exclusive (const struct test_suite * t , int subtest )
203
+ {
204
+ if (subtest <= 0 )
205
+ return t -> test_cases [0 ].exclusive ;
206
+
207
+ return t -> test_cases [subtest ].exclusive ;
208
+ }
209
+
202
210
static bool perf_test__matches (const char * desc , int curr , int argc , const char * argv [])
203
211
{
204
212
int i ;
@@ -242,7 +250,7 @@ static int run_test_child(struct child_process *process)
242
250
const int signals [] = {
243
251
SIGABRT , SIGBUS , SIGFPE , SIGILL , SIGINT , SIGPIPE , SIGQUIT , SIGSEGV , SIGTERM ,
244
252
};
245
- static struct child_test * child ;
253
+ struct child_test * child = container_of ( process , struct child_test , process ) ;
246
254
int err ;
247
255
248
256
err = sigsetjmp (run_test_jmp_buf , 1 );
@@ -252,7 +260,6 @@ static int run_test_child(struct child_process *process)
252
260
goto err_out ;
253
261
}
254
262
255
- child = container_of (process , struct child_test , process );
256
263
for (size_t i = 0 ; i < ARRAY_SIZE (signals ); i ++ )
257
264
signal (signals [i ], child_test_sig_handler );
258
265
@@ -305,19 +312,25 @@ static int print_test_result(struct test_suite *t, int i, int subtest, int resul
305
312
return 0 ;
306
313
}
307
314
308
- static int finish_test (struct child_test * * child_tests , int running_test , int child_test_num ,
309
- int width )
315
+ static void finish_test (struct child_test * * child_tests , int running_test , int child_test_num ,
316
+ int width )
310
317
{
311
318
struct child_test * child_test = child_tests [running_test ];
312
- struct test_suite * t = child_test -> test ;
313
- int i = child_test -> test_num ;
314
- int subi = child_test -> subtest ;
315
- int err = child_test -> process .err ;
319
+ struct test_suite * t ;
320
+ int i , subi , err ;
316
321
bool err_done = false;
317
322
struct strbuf err_output = STRBUF_INIT ;
318
323
int last_running = -1 ;
319
324
int ret ;
320
325
326
+ if (child_test == NULL ) {
327
+ /* Test wasn't started. */
328
+ return ;
329
+ }
330
+ t = child_test -> test ;
331
+ i = child_test -> test_num ;
332
+ subi = child_test -> subtest ;
333
+ err = child_test -> process .err ;
321
334
/*
322
335
* For test suites with subtests, display the suite name ahead of the
323
336
* sub test names.
@@ -347,6 +360,8 @@ static int finish_test(struct child_test **child_tests, int running_test, int ch
347
360
int running = 0 ;
348
361
349
362
for (int y = running_test ; y < child_test_num ; y ++ ) {
363
+ if (child_tests [y ] == NULL )
364
+ continue ;
350
365
if (check_if_command_finished (& child_tests [y ]-> process ) == 0 )
351
366
running ++ ;
352
367
}
@@ -399,23 +414,32 @@ static int finish_test(struct child_test **child_tests, int running_test, int ch
399
414
print_test_result (t , i , subi , ret , width , /*running=*/ 0 );
400
415
if (err > 0 )
401
416
close (err );
402
- return 0 ;
417
+ zfree ( & child_tests [ running_test ]) ;
403
418
}
404
419
405
420
static int start_test (struct test_suite * test , int i , int subi , struct child_test * * child ,
406
- int width )
421
+ int width , int pass )
407
422
{
408
423
int err ;
409
424
410
425
* child = NULL ;
411
426
if (dont_fork ) {
412
- pr_debug ("--- start ---\n" );
413
- err = test_function (test , subi )(test , subi );
414
- pr_debug ("---- end ----\n" );
415
- print_test_result (test , i , subi , err , width , /*running=*/ 0 );
427
+ if (pass == 1 ) {
428
+ pr_debug ("--- start ---\n" );
429
+ err = test_function (test , subi )(test , subi );
430
+ pr_debug ("---- end ----\n" );
431
+ print_test_result (test , i , subi , err , width , /*running=*/ 0 );
432
+ }
433
+ return 0 ;
434
+ }
435
+ if (pass == 1 && !sequential && test_exclusive (test , subi )) {
436
+ /* When parallel, skip exclusive tests on the first pass. */
437
+ return 0 ;
438
+ }
439
+ if (pass != 1 && (sequential || !test_exclusive (test , subi ))) {
440
+ /* Sequential and non-exclusive tests were run on the first pass. */
416
441
return 0 ;
417
442
}
418
-
419
443
* child = zalloc (sizeof (* * child ));
420
444
if (!* child )
421
445
return - ENOMEM ;
@@ -434,10 +458,14 @@ static int start_test(struct test_suite *test, int i, int subi, struct child_tes
434
458
(* child )-> process .err = -1 ;
435
459
}
436
460
(* child )-> process .no_exec_cmd = run_test_child ;
437
- err = start_command (& (* child )-> process );
438
- if (err || !sequential )
439
- return err ;
440
- return finish_test (child , /*running_test=*/ 0 , /*child_test_num=*/ 1 , width );
461
+ if (sequential || pass == 2 ) {
462
+ err = start_command (& (* child )-> process );
463
+ if (err )
464
+ return err ;
465
+ finish_test (child , /*running_test=*/ 0 , /*child_test_num=*/ 1 , width );
466
+ return 0 ;
467
+ }
468
+ return start_command (& (* child )-> process );
441
469
}
442
470
443
471
#define for_each_test (j , k , t ) \
@@ -447,12 +475,11 @@ static int start_test(struct test_suite *test, int i, int subi, struct child_tes
447
475
static int __cmd_test (int argc , const char * argv [], struct intlist * skiplist )
448
476
{
449
477
struct test_suite * t ;
450
- unsigned int j , k ;
451
- int i = 0 ;
452
478
int width = 0 ;
479
+ unsigned int j , k ;
453
480
size_t num_tests = 0 ;
454
481
struct child_test * * child_tests ;
455
- int child_test_num = 0 ;
482
+ int err = 0 ;
456
483
457
484
for_each_test (j , k , t ) {
458
485
int len = strlen (test_description (t , -1 ));
@@ -475,62 +502,73 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
475
502
if (!child_tests )
476
503
return - ENOMEM ;
477
504
478
- for_each_test (j , k , t ) {
479
- int curr = i ++ ;
480
-
481
- if (!perf_test__matches (test_description (t , -1 ), curr , argc , argv )) {
482
- bool skip = true;
505
+ /*
506
+ * In parallel mode pass 1 runs non-exclusive tests in parallel, pass 2
507
+ * runs the exclusive tests sequentially. In other modes all tests are
508
+ * run in pass 1.
509
+ */
510
+ for (int pass = 1 ; pass <= 2 ; pass ++ ) {
511
+ int child_test_num = 0 ;
512
+ int i = 0 ;
513
+
514
+ for_each_test (j , k , t ) {
515
+ int curr = i ++ ;
516
+
517
+ if (!perf_test__matches (test_description (t , -1 ), curr , argc , argv )) {
518
+ /*
519
+ * Test suite shouldn't be run based on
520
+ * description. See if subtest should.
521
+ */
522
+ bool skip = true;
523
+
524
+ for (int subi = 0 , subn = num_subtests (t ); subi < subn ; subi ++ ) {
525
+ if (perf_test__matches (test_description (t , subi ),
526
+ curr , argc , argv ))
527
+ skip = false;
528
+ }
483
529
484
- for (int subi = 0 , subn = num_subtests (t ); subi < subn ; subi ++ ) {
485
- if (perf_test__matches (test_description (t , subi ),
486
- curr , argc , argv ))
487
- skip = false;
530
+ if (skip )
531
+ continue ;
488
532
}
489
533
490
- if (skip )
534
+ if (intlist__find (skiplist , i )) {
535
+ pr_info ("%3d: %-*s:" , curr + 1 , width , test_description (t , -1 ));
536
+ color_fprintf (stderr , PERF_COLOR_YELLOW , " Skip (user override)\n" );
491
537
continue ;
492
- }
493
-
494
- if (intlist__find (skiplist , i )) {
495
- pr_info ("%3d: %-*s:" , curr + 1 , width , test_description (t , -1 ));
496
- color_fprintf (stderr , PERF_COLOR_YELLOW , " Skip (user override)\n" );
497
- continue ;
498
- }
499
-
500
- if (!has_subtests (t )) {
501
- int err = start_test (t , curr , -1 , & child_tests [child_test_num ++ ], width );
538
+ }
502
539
503
- if (err ) {
504
- /* TODO: if !sequential waitpid the already forked children. */
505
- free (child_tests );
506
- return err ;
540
+ if (!has_subtests (t )) {
541
+ err = start_test (t , curr , -1 , & child_tests [child_test_num ++ ],
542
+ width , pass );
543
+ if (err )
544
+ goto err_out ;
545
+ continue ;
507
546
}
508
- } else {
509
547
for (int subi = 0 , subn = num_subtests (t ); subi < subn ; subi ++ ) {
510
- int err ;
511
-
512
548
if (!perf_test__matches (test_description (t , subi ),
513
549
curr , argc , argv ))
514
550
continue ;
515
551
516
552
err = start_test (t , curr , subi , & child_tests [child_test_num ++ ],
517
- width );
553
+ width , pass );
518
554
if (err )
519
- return err ;
555
+ goto err_out ;
520
556
}
521
557
}
522
- }
523
- for (i = 0 ; i < child_test_num ; i ++ ) {
524
558
if (!sequential ) {
525
- int ret = finish_test (child_tests , i , child_test_num , width );
526
-
527
- if (ret )
528
- return ret ;
559
+ /* Parallel mode starts tests but doesn't finish them. Do that now. */
560
+ for (size_t x = 0 ; x < num_tests ; x ++ )
561
+ finish_test (child_tests , x , num_tests , width );
529
562
}
530
- free (child_tests [i ]);
563
+ }
564
+ err_out :
565
+ if (err ) {
566
+ pr_err ("Internal test harness failure. Completing any started tests:\n:" );
567
+ for (size_t x = 0 ; x < num_tests ; x ++ )
568
+ finish_test (child_tests , x , num_tests , width );
531
569
}
532
570
free (child_tests );
533
- return 0 ;
571
+ return err ;
534
572
}
535
573
536
574
static int perf_test__list (int argc , const char * * argv )
@@ -656,6 +694,7 @@ int cmd_test(int argc, const char **argv)
656
694
symbol_conf .priv_size = sizeof (int );
657
695
symbol_conf .try_vmlinux_path = true;
658
696
697
+
659
698
if (symbol__init (NULL ) < 0 )
660
699
return -1 ;
661
700
0 commit comments