@@ -199,6 +199,14 @@ static test_fnptr test_function(const struct test_suite *t, int subtest)
199199 return t -> test_cases [subtest ].run_case ;
200200}
201201
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+
202210static bool perf_test__matches (const char * desc , int curr , int argc , const char * argv [])
203211{
204212 int i ;
@@ -242,7 +250,7 @@ static int run_test_child(struct child_process *process)
242250 const int signals [] = {
243251 SIGABRT , SIGBUS , SIGFPE , SIGILL , SIGINT , SIGPIPE , SIGQUIT , SIGSEGV , SIGTERM ,
244252 };
245- static struct child_test * child ;
253+ struct child_test * child = container_of ( process , struct child_test , process ) ;
246254 int err ;
247255
248256 err = sigsetjmp (run_test_jmp_buf , 1 );
@@ -252,7 +260,6 @@ static int run_test_child(struct child_process *process)
252260 goto err_out ;
253261 }
254262
255- child = container_of (process , struct child_test , process );
256263 for (size_t i = 0 ; i < ARRAY_SIZE (signals ); i ++ )
257264 signal (signals [i ], child_test_sig_handler );
258265
@@ -305,19 +312,25 @@ static int print_test_result(struct test_suite *t, int i, int subtest, int resul
305312 return 0 ;
306313}
307314
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 )
310317{
311318 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 ;
316321 bool err_done = false;
317322 struct strbuf err_output = STRBUF_INIT ;
318323 int last_running = -1 ;
319324 int ret ;
320325
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 ;
321334 /*
322335 * For test suites with subtests, display the suite name ahead of the
323336 * sub test names.
@@ -347,6 +360,8 @@ static int finish_test(struct child_test **child_tests, int running_test, int ch
347360 int running = 0 ;
348361
349362 for (int y = running_test ; y < child_test_num ; y ++ ) {
363+ if (child_tests [y ] == NULL )
364+ continue ;
350365 if (check_if_command_finished (& child_tests [y ]-> process ) == 0 )
351366 running ++ ;
352367 }
@@ -399,23 +414,32 @@ static int finish_test(struct child_test **child_tests, int running_test, int ch
399414 print_test_result (t , i , subi , ret , width , /*running=*/ 0 );
400415 if (err > 0 )
401416 close (err );
402- return 0 ;
417+ zfree ( & child_tests [ running_test ]) ;
403418}
404419
405420static int start_test (struct test_suite * test , int i , int subi , struct child_test * * child ,
406- int width )
421+ int width , int pass )
407422{
408423 int err ;
409424
410425 * child = NULL ;
411426 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. */
416441 return 0 ;
417442 }
418-
419443 * child = zalloc (sizeof (* * child ));
420444 if (!* child )
421445 return - ENOMEM ;
@@ -434,10 +458,14 @@ static int start_test(struct test_suite *test, int i, int subi, struct child_tes
434458 (* child )-> process .err = -1 ;
435459 }
436460 (* 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 );
441469}
442470
443471#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
447475static int __cmd_test (int argc , const char * argv [], struct intlist * skiplist )
448476{
449477 struct test_suite * t ;
450- unsigned int j , k ;
451- int i = 0 ;
452478 int width = 0 ;
479+ unsigned int j , k ;
453480 size_t num_tests = 0 ;
454481 struct child_test * * child_tests ;
455- int child_test_num = 0 ;
482+ int err = 0 ;
456483
457484 for_each_test (j , k , t ) {
458485 int len = strlen (test_description (t , -1 ));
@@ -475,62 +502,73 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
475502 if (!child_tests )
476503 return - ENOMEM ;
477504
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+ }
483529
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 ;
488532 }
489533
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" );
491537 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+ }
502539
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 ;
507546 }
508- } else {
509547 for (int subi = 0 , subn = num_subtests (t ); subi < subn ; subi ++ ) {
510- int err ;
511-
512548 if (!perf_test__matches (test_description (t , subi ),
513549 curr , argc , argv ))
514550 continue ;
515551
516552 err = start_test (t , curr , subi , & child_tests [child_test_num ++ ],
517- width );
553+ width , pass );
518554 if (err )
519- return err ;
555+ goto err_out ;
520556 }
521557 }
522- }
523- for (i = 0 ; i < child_test_num ; i ++ ) {
524558 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 );
529562 }
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 );
531569 }
532570 free (child_tests );
533- return 0 ;
571+ return err ;
534572}
535573
536574static int perf_test__list (int argc , const char * * argv )
@@ -656,6 +694,7 @@ int cmd_test(int argc, const char **argv)
656694 symbol_conf .priv_size = sizeof (int );
657695 symbol_conf .try_vmlinux_path = true;
658696
697+
659698 if (symbol__init (NULL ) < 0 )
660699 return -1 ;
661700
0 commit comments