scripts/benchmarks.js (126 lines of code) (raw):

/** * MIT License * * Copyright (c) 2017-present, Elasticsearch BV * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ const { spawn, execSync } = require('@lerna/child-process') const glob = require('glob') const { join } = require('path') const { readFile, writeFile } = require('fs') const { promisify } = require('util') const pReadFile = promisify(readFile) const pWriteFile = promisify(writeFile) const PKG_DIR = join(__dirname, '../') async function getAllBenchmarkResults() { const results = [] const files = glob.sync(`${PKG_DIR}/packages/**/reports/*-benchmarks.json`) for (let file of files) { try { const benchmarksFile = await pReadFile(file, 'utf-8') const parsedResults = JSON.parse(benchmarksFile) const { type, summary } = parsedResults const formattedResult = extractFields(summary, type) results.push(...formattedResult) } catch (err) { console.error('Failed to read benchmark from', file, err) } } return results } function extractFields(benchResults, type) { let keysToFilter = [] switch (type) { case 'benchmarkjs': keysToFilter = ['browser', 'suite', 'name', 'hz', 'unit'] break case 'eum': keysToFilter = '*' } const filteredResult = [] for (let result of benchResults) { filteredResult.push( Object.keys(result) .filter(key => { if (keysToFilter === '*') { return !!key } return keysToFilter.includes(key) }) .reduce( (obj, key) => ({ ...obj, [key]: result[key] }), {} ) ) } return filteredResult } function runBenchmarks() { const outputFile = process.argv[2] const lernaProcess = spawn('lerna', ['run', 'bench', '--stream']) lernaProcess.on('exit', code => { if (code !== 0) { process.exit(code) } }) lernaProcess.on('close', async () => { try { const results = await getAllBenchmarkResults() if (results.length === 0) { console.warn('No benchmarks results found', 'Skipping this run') process.exit(1) } const gitlog = execSync('git', [ 'log', '-1', '--pretty=%h,%s', '--no-merges' ]) const [commit, commitMessage] = gitlog.split(',') const branch = execSync('git', ['rev-parse', '--abbrev-ref', 'HEAD']) const baseOutput = { process: { version: process.version, arch: process.arch, platform: process.platform }, meta: { commit, commitMessage, branch, agentName: 'rum-js' } } let resultObj = {} for (let result of results) { const metricKey = result.name || result.scenario const browser = result.browser if (!resultObj[metricKey]) { resultObj[metricKey] = {} } resultObj[metricKey][browser] = result } const output = Object.assign({}, baseOutput, { metrics: resultObj, '@timestamp': Date.now() }) /** * DEV - show the results in the terminal * CI - store the results in file and upload to ES */ if (!outputFile) { console.log( 'Benchmark Results:', '\n', JSON.stringify(output, undefined, 2) ) return } /** * NDJSON format for uploading to ES */ let ndJSONOutput = '{"index": { "_index": "benchmarks-rum-js" }}' + '\n' ndJSONOutput += JSON.stringify(output) ndJSONOutput += '\n' const outputPath = join(PKG_DIR, outputFile) await pWriteFile(outputPath, ndJSONOutput) console.log('Benchmark results is stored in', outputPath) } catch (err) { console.error('Error running benchmark script', err) process.exit(2) } }) } if (require.main === module) { runBenchmarks() }