diff --git a/lib/core/engine/command/simpleperf.js b/lib/core/engine/command/simpleperf.js index ad0960613..ce8f34613 100644 --- a/lib/core/engine/command/simpleperf.js +++ b/lib/core/engine/command/simpleperf.js @@ -14,7 +14,7 @@ import { isAndroidConfigured } from '../../../android/index.js'; const log = getLogger('browsertime.command.simpleperf'); -const defaultOptions = +const defaultRecordOptions = '--call-graph fp --duration 240 -f 1000 --trace-offcpu -e cpu-clock'; /** @@ -72,7 +72,11 @@ export class SimplePerfProfiler { * @throws {Error} Throws an error if app_profiler.py fails to execute. */ - async start(profilerOptions = defaultOptions, dirName = 'simpleperf') { + async start( + profilerOptions = [], + recordOptions = defaultRecordOptions, + dirName = 'simpleperf' + ) { if (!isAndroidConfigured(this.options)) { throw new Error('Simpleperf profiling is only available on Android.'); } @@ -83,6 +87,8 @@ export class SimplePerfProfiler { let dirname = `${dirName}-${this.index}`; let counter = 0; + this.profilerOptions = profilerOptions; + while (true) { log.info(`Checking if ${dirname} exists...`); @@ -102,13 +108,14 @@ export class SimplePerfProfiler { this.options.browser === 'firefox' ? this.options.firefox?.android?.package : this.options.chrome?.android?.package; - let ndkPath = this.options.androidNDK; - let cmd = `${ndkPath}/simpleperf/app_profiler.py`; + let simpleperfPath = this.options.androidSimpleperf; + let cmd = join(simpleperfPath, 'app_profiler.py'); let args = [ + ...profilerOptions, '-p', packageName, '-r', - profilerOptions, + recordOptions, '--log', 'debug', '-o', @@ -167,11 +174,24 @@ export class SimplePerfProfiler { stderrStream.on('data', data => { const dataStr = data.toString(); log.info(dataStr); + // Resolve immediately if -nb or --skip_collect_binaries is passed + // into the app_profiler options as a binary cache will not be produced. + if ( + this.profilerOptions.includes('-nb') || + this.profilerOptions.includes('--skip_collect_binaries') + ) { + stderrStream.removeAllListeners('data'); + return resolve(); + } if (/profiling is finished./.test(dataStr)) { stderrStream.removeAllListeners('data'); - // There is no way to specify the output of binary_cache, so manually move - // it into the data directory. - renameSync('binary_cache', join(this.dataDir, 'binary_cache')); + // There is no way to specify the output of binary_cache, + // so manually move it (if it exists) into the data directory. + if (existsSync('binary_cache')) { + renameSync('binary_cache', join(this.dataDir, 'binary_cache')); + } else { + log.info('binary_cache does not exist.'); + } return resolve(); } }); diff --git a/lib/support/cli.js b/lib/support/cli.js index 075fc7918..e03387bb0 100644 --- a/lib/support/cli.js +++ b/lib/support/cli.js @@ -837,10 +837,10 @@ export function parseCommandLine() { 'Before a test start, verify that the device has a Internet connection by pinging 8.8.8.8 (or a configurable domain with --androidPingAddress)', group: 'android' }) - .option('android.ndk', { - alias: 'androidNDK', + .option('android.simpleperf', { + alias: 'androidSimpleperf', type: 'string', - describe: 'Path to the Android NDK (required for simpleperf profiling).', + describe: 'Path to the Simpleperf profiler from the Android NDK.', group: 'android' }) .option('android.perfettoTrace', { diff --git a/types/core/engine/command/simpleperf.d.ts b/types/core/engine/command/simpleperf.d.ts index acc8d08e7..0756b6bb7 100644 --- a/types/core/engine/command/simpleperf.d.ts +++ b/types/core/engine/command/simpleperf.d.ts @@ -27,7 +27,8 @@ export class SimplePerfProfiler { * @returns {Promise} A promise that resolves when simpleperf has started profiling. * @throws {Error} Throws an error if app_profiler.py fails to execute. */ - start(profilerOptions?: string, dirName?: string): Promise; + start(profilerOptions?: any[], recordOptions?: string, dirName?: string): Promise; + profilerOptions: any[]; dataDir: any; simpleperfProcess: import("execa").ResultPromise<{}>; /** diff --git a/types/core/engine/command/simpleperf.d.ts.map b/types/core/engine/command/simpleperf.d.ts.map index bd23118e5..6cce4ee49 100644 --- a/types/core/engine/command/simpleperf.d.ts.map +++ b/types/core/engine/command/simpleperf.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"simpleperf.d.ts","sourceRoot":"","sources":["../../../../lib/core/engine/command/simpleperf.js"],"names":[],"mappings":"AA0CA;IACE,yEAqBC;IApBC;;OAEG;IACH,gBAAsB;IACtB;;OAEG;IACH,uBAAoC;IACpC;;OAEG;IACH,gBAAsB;IACtB;;OAEG;IACH,cAAkB;IAClB;;OAEG;IACH,gBAAoB;IAGtB;;;;;;OAMG;IAEH,mDAJa,OAAO,CAAC,IAAI,CAAC,CAsEzB;IA/CK,aAAkE;IAuBtE,qDAAyC;IA0B3C;;;;;;;OAOG;IACH,QAJa,OAAO,CAAC,IAAI,CAAC,CAiCzB;CACF"} \ No newline at end of file +{"version":3,"file":"simpleperf.d.ts","sourceRoot":"","sources":["../../../../lib/core/engine/command/simpleperf.js"],"names":[],"mappings":"AA0CA;IACE,yEAqBC;IApBC;;OAEG;IACH,gBAAsB;IACtB;;OAEG;IACH,uBAAoC;IACpC;;OAEG;IACH,gBAAsB;IACtB;;OAEG;IACH,cAAkB;IAClB;;OAEG;IACH,gBAAoB;IAGtB;;;;;;OAMG;IAEH,0EAJa,OAAO,CAAC,IAAI,CAAC,CA6EzB;IA1DC,uBAAsC;IAUlC,aAAkE;IAwBtE,qDAAyC;IA0B3C;;;;;;;OAOG;IACH,QAJa,OAAO,CAAC,IAAI,CAAC,CA8CzB;CACF"} \ No newline at end of file