woocommerce/tools/compare-perf/process-reports.ts

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,
};