120 lines
3.0 KiB
TypeScript
120 lines
3.0 KiB
TypeScript
|
/**
|
||
|
* External dependencies
|
||
|
*/
|
||
|
const bold = require( 'chalk' );
|
||
|
const fs = require( 'fs' );
|
||
|
const path = require( 'path' );
|
||
|
|
||
|
/**
|
||
|
* Internal dependencies
|
||
|
*/
|
||
|
const {
|
||
|
getFilesFromDir,
|
||
|
readJSONFile,
|
||
|
logAtIndent,
|
||
|
sanitizeBranchName,
|
||
|
median
|
||
|
} = require( './utils' ) ;
|
||
|
|
||
|
const formats = {
|
||
|
success: bold.green,
|
||
|
};
|
||
|
|
||
|
const ARTIFACTS_PATH =
|
||
|
process.env.WP_ARTIFACTS_PATH || path.join( process.cwd(), 'artifacts' );
|
||
|
const RESULTS_FILE_SUFFIX = '.performance-results.json';
|
||
|
|
||
|
/**
|
||
|
* Calculates and prints results from the generated reports.
|
||
|
*
|
||
|
* @param {string[]} testSuites Test suites we are aiming.
|
||
|
* @param {string[]} branches Branches we are aiming.
|
||
|
*/
|
||
|
async function processPerformanceReports(
|
||
|
testSuites: string[],
|
||
|
branches: string[]
|
||
|
): Promise< void > {
|
||
|
logAtIndent( 0, 'Calculating results' );
|
||
|
|
||
|
const resultFiles = getFilesFromDir( ARTIFACTS_PATH ).filter(
|
||
|
( file: string ) => file.endsWith( RESULTS_FILE_SUFFIX )
|
||
|
);
|
||
|
const results: Record<
|
||
|
string,
|
||
|
Record< string, Record< string, number > >
|
||
|
> = {};
|
||
|
|
||
|
// Calculate medians from all rounds.
|
||
|
for ( const testSuite of testSuites ) {
|
||
|
logAtIndent( 1, 'Test suite:', formats.success( testSuite ) );
|
||
|
|
||
|
results[ testSuite ] = {};
|
||
|
for ( const branch of branches ) {
|
||
|
const sanitizedBranchName = sanitizeBranchName( branch );
|
||
|
const resultsRounds: any[] = resultFiles
|
||
|
.filter( ( file: string ) =>
|
||
|
file.includes(
|
||
|
`/${ testSuite }_${ sanitizedBranchName }_round-`
|
||
|
)
|
||
|
)
|
||
|
.map( ( file: string ) => {
|
||
|
logAtIndent( 2, 'Reading from:', formats.success( file ) );
|
||
|
return readJSONFile( file );
|
||
|
} );
|
||
|
|
||
|
const metrics = Object.keys( resultsRounds[ 0 ] );
|
||
|
results[ testSuite ][ branch ] = {};
|
||
|
|
||
|
for ( const metric of metrics ) {
|
||
|
const values = resultsRounds
|
||
|
.map( ( round ) => round[ metric ] )
|
||
|
.filter( ( value ) => typeof value === 'number' );
|
||
|
|
||
|
const value = median( values );
|
||
|
if ( value !== undefined ) {
|
||
|
results[ testSuite ][ branch ][ metric ] = value;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
const calculatedResultsPath = path.join(
|
||
|
ARTIFACTS_PATH,
|
||
|
testSuite + RESULTS_FILE_SUFFIX
|
||
|
);
|
||
|
|
||
|
logAtIndent(
|
||
|
2,
|
||
|
'Saving curated results to:',
|
||
|
formats.success( calculatedResultsPath )
|
||
|
);
|
||
|
fs.writeFileSync(
|
||
|
calculatedResultsPath,
|
||
|
JSON.stringify( results[ testSuite ], null, 2 )
|
||
|
);
|
||
|
}
|
||
|
|
||
|
logAtIndent( 0, 'Printing results' );
|
||
|
|
||
|
for ( const testSuite of testSuites ) {
|
||
|
logAtIndent( 0, formats.success( testSuite ) );
|
||
|
|
||
|
// Invert the results, so we can display them in a table.
|
||
|
const invertedResult: Record< string, Record< string, string > > = {};
|
||
|
for ( const [ branch, metrics ] of Object.entries(
|
||
|
results[ testSuite ]
|
||
|
) ) {
|
||
|
for ( const [ metric, value ] of Object.entries( metrics ) ) {
|
||
|
invertedResult[ metric ] = invertedResult[ metric ] || {};
|
||
|
invertedResult[ metric ][ branch ] = `${ value } ms`;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Print the results.
|
||
|
// eslint-disable-next-line no-console
|
||
|
console.table( invertedResult );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = {
|
||
|
processPerformanceReports,
|
||
|
};
|