@@ -454,8 +454,99 @@ export class BenchmarkRunner {
454454 }
455455
456456 async runSuite ( suite ) {
457- await this . _prepareSuite ( suite ) ;
458- await this . _runSuite ( suite ) ;
457+ // FIXME: Encapsulate more state in the SuiteRunner.
458+ // FIXME: Return and use measured values from SuiteRunner.
459+ const suiteRunner = new SuiteRunner ( this . _measuredValues , this . _frame , this . _page , this . _client , suite ) ;
460+ await suiteRunner . run ( ) ;
461+ }
462+
463+ async _finalize ( ) {
464+ this . _appendIterationMetrics ( ) ;
465+ if ( this . _client ?. didRunSuites ) {
466+ let product = 1 ;
467+ const values = [ ] ;
468+ for ( const suiteName in this . _measuredValues . tests ) {
469+ const suiteTotal = this . _measuredValues . tests [ suiteName ] . total ;
470+ product *= suiteTotal ;
471+ values . push ( suiteTotal ) ;
472+ }
473+
474+ values . sort ( ( a , b ) => a - b ) ; // Avoid the loss of significance for the sum.
475+ const total = values . reduce ( ( a , b ) => a + b ) ;
476+ const geomean = Math . pow ( product , 1 / values . length ) ;
477+
478+ this . _measuredValues . total = total ;
479+ this . _measuredValues . mean = total / values . length ;
480+ this . _measuredValues . geomean = geomean ;
481+ this . _measuredValues . score = geomeanToScore ( geomean ) ;
482+ await this . _client . didRunSuites ( this . _measuredValues ) ;
483+ }
484+ }
485+
486+ _appendIterationMetrics ( ) {
487+ const getMetric = ( name , unit = "ms" ) => this . _metrics [ name ] || ( this . _metrics [ name ] = new Metric ( name , unit ) ) ;
488+ const iterationTotalMetric = ( i ) => {
489+ if ( i >= params . iterationCount )
490+ throw new Error ( `Requested iteration=${ i } does not exist.` ) ;
491+ return getMetric ( `Iteration-${ i } -Total` ) ;
492+ } ;
493+
494+ const collectSubMetrics = ( prefix , items , parent ) => {
495+ for ( let name in items ) {
496+ const results = items [ name ] ;
497+ const metric = getMetric ( prefix + name ) ;
498+ metric . add ( results . total ?? results ) ;
499+ if ( metric . parent !== parent )
500+ parent . addChild ( metric ) ;
501+ if ( results . tests )
502+ collectSubMetrics ( `${ metric . name } ${ Metric . separator } ` , results . tests , metric ) ;
503+ }
504+ } ;
505+ const initializeMetrics = this . _metrics === null ;
506+ if ( initializeMetrics )
507+ this . _metrics = { __proto__ : null } ;
508+
509+ const iterationResults = this . _measuredValues . tests ;
510+ collectSubMetrics ( "" , iterationResults ) ;
511+
512+ if ( initializeMetrics ) {
513+ // Prepare all iteration metrics so they are listed at the end of
514+ // of the _metrics object, before "Total" and "Score".
515+ for ( let i = 0 ; i < this . _iterationCount ; i ++ )
516+ iterationTotalMetric ( i ) . description = `Test totals for iteration ${ i } ` ;
517+ getMetric ( "Geomean" , "ms" ) . description = "Geomean of test totals" ;
518+ getMetric ( "Score" , "score" ) . description = "Scaled inverse of the Geomean" ;
519+ }
520+
521+ const geomean = getMetric ( "Geomean" ) ;
522+ const iterationTotal = iterationTotalMetric ( geomean . length ) ;
523+ for ( const results of Object . values ( iterationResults ) )
524+ iterationTotal . add ( results . total ) ;
525+ iterationTotal . computeAggregatedMetrics ( ) ;
526+ geomean . add ( iterationTotal . geomean ) ;
527+ getMetric ( "Score" ) . add ( geomeanToScore ( iterationTotal . geomean ) ) ;
528+
529+ for ( const metric of Object . values ( this . _metrics ) )
530+ metric . computeAggregatedMetrics ( ) ;
531+ }
532+ }
533+
534+ // FIXME: Create AsyncSuiteRunner subclass.
535+ // FIXME: Create RemoteSuiteRunner subclass.
536+ export class SuiteRunner {
537+ constructor ( measuredValues , frame , page , client , suite ) {
538+ // FIXME: Create SuiteRunner-local measuredValues.
539+ this . _measuredValues = measuredValues ;
540+ this . _frame = frame ;
541+ this . _page = page ;
542+ this . _client = client ;
543+ this . _suite = suite ;
544+ }
545+
546+ async run ( ) {
547+ // FIXME: use this._suite in all SuiteRunner methods directly.
548+ await this . _prepareSuite ( this . _suite ) ;
549+ await this . _runSuite ( this . _suite ) ;
459550 }
460551
461552 async _prepareSuite ( suite ) {
@@ -570,74 +661,4 @@ export class BenchmarkRunner {
570661 if ( this . _client ?. didRunTest )
571662 await this . _client . didRunTest ( suite , test ) ;
572663 }
573-
574- async _finalize ( ) {
575- this . _appendIterationMetrics ( ) ;
576- if ( this . _client ?. didRunSuites ) {
577- let product = 1 ;
578- const values = [ ] ;
579- for ( const suiteName in this . _measuredValues . tests ) {
580- const suiteTotal = this . _measuredValues . tests [ suiteName ] . total ;
581- product *= suiteTotal ;
582- values . push ( suiteTotal ) ;
583- }
584-
585- values . sort ( ( a , b ) => a - b ) ; // Avoid the loss of significance for the sum.
586- const total = values . reduce ( ( a , b ) => a + b ) ;
587- const geomean = Math . pow ( product , 1 / values . length ) ;
588-
589- this . _measuredValues . total = total ;
590- this . _measuredValues . mean = total / values . length ;
591- this . _measuredValues . geomean = geomean ;
592- this . _measuredValues . score = geomeanToScore ( geomean ) ;
593- await this . _client . didRunSuites ( this . _measuredValues ) ;
594- }
595- }
596-
597- _appendIterationMetrics ( ) {
598- const getMetric = ( name , unit = "ms" ) => this . _metrics [ name ] || ( this . _metrics [ name ] = new Metric ( name , unit ) ) ;
599- const iterationTotalMetric = ( i ) => {
600- if ( i >= params . iterationCount )
601- throw new Error ( `Requested iteration=${ i } does not exist.` ) ;
602- return getMetric ( `Iteration-${ i } -Total` ) ;
603- } ;
604-
605- const collectSubMetrics = ( prefix , items , parent ) => {
606- for ( let name in items ) {
607- const results = items [ name ] ;
608- const metric = getMetric ( prefix + name ) ;
609- metric . add ( results . total ?? results ) ;
610- if ( metric . parent !== parent )
611- parent . addChild ( metric ) ;
612- if ( results . tests )
613- collectSubMetrics ( `${ metric . name } ${ Metric . separator } ` , results . tests , metric ) ;
614- }
615- } ;
616- const initializeMetrics = this . _metrics === null ;
617- if ( initializeMetrics )
618- this . _metrics = { __proto__ : null } ;
619-
620- const iterationResults = this . _measuredValues . tests ;
621- collectSubMetrics ( "" , iterationResults ) ;
622-
623- if ( initializeMetrics ) {
624- // Prepare all iteration metrics so they are listed at the end of
625- // of the _metrics object, before "Total" and "Score".
626- for ( let i = 0 ; i < this . _iterationCount ; i ++ )
627- iterationTotalMetric ( i ) . description = `Test totals for iteration ${ i } ` ;
628- getMetric ( "Geomean" , "ms" ) . description = "Geomean of test totals" ;
629- getMetric ( "Score" , "score" ) . description = "Scaled inverse of the Geomean" ;
630- }
631-
632- const geomean = getMetric ( "Geomean" ) ;
633- const iterationTotal = iterationTotalMetric ( geomean . length ) ;
634- for ( const results of Object . values ( iterationResults ) )
635- iterationTotal . add ( results . total ) ;
636- iterationTotal . computeAggregatedMetrics ( ) ;
637- geomean . add ( iterationTotal . geomean ) ;
638- getMetric ( "Score" ) . add ( geomeanToScore ( iterationTotal . geomean ) ) ;
639-
640- for ( const metric of Object . values ( this . _metrics ) )
641- metric . computeAggregatedMetrics ( ) ;
642- }
643664}
0 commit comments