Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: extending tracing startRecording API to take a full tracing config
This allows memory-infra to be traced correctly. Fixes #12506.
- Loading branch information
1 parent
607b53c
commit 8cc9609
Showing
5 changed files
with
194 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# TraceCategoriesAndOptions Object | ||
|
||
* `categoryFilter` String – is a filter to control what category groups | ||
should be traced. A filter can have an optional `-` prefix to exclude | ||
category groups that contain a matching category. Having both included | ||
and excluded category patterns in the same list is not supported. Examples: | ||
- `test_MyTest*`, | ||
- `test_MyTest*,test_OtherStuff`, | ||
- `-excluded_category1,-excluded_category2` | ||
* `traceOptions` String - Controls what kind of tracing is enabled, | ||
it is a comma-delimited list. Possible options are: | ||
- `record-until-full` | ||
- `record-continuously` | ||
- `trace-to-console` | ||
- `enable-sampling` | ||
- `enable-systrace` | ||
The first 3 options are trace recording modes and hence mutually exclusive. | ||
If more than one trace recording modes appear in the `traceOptions` string, | ||
the last one takes precedence. If none of the trace recording modes are | ||
specified, recording mode is `record-until-full`. | ||
The trace option will first be reset to the default option (`record_mode` set | ||
to `record-until-full`, `enable_sampling` and `enable_systrace` | ||
set to `false`) before options parsed from `traceOptions` are applied on it. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# TraceConfig Object | ||
|
||
* `included_categories` String[] (optional) | ||
* `excluded_categories` String[] (optional) | ||
* `memory_dump_config` Object (optional) | ||
|
||
See an example in the [Chromium docs][1]. | ||
|
||
[1]: https://chromium.googlesource.com/chromium/src/+/master/docs/memory-infra/memory_infra_startup_tracing.md#the-advanced-way |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
const { remote } = require('electron') | ||
const chai = require('chai') | ||
const dirtyChai = require('dirty-chai') | ||
const fs = require('fs') | ||
const path = require('path') | ||
|
||
const { expect } = chai | ||
const { app, contentTracing } = remote | ||
|
||
chai.use(dirtyChai) | ||
|
||
const timeout = async (milliseconds) => { | ||
return new Promise((resolve) => { | ||
setTimeout(resolve, milliseconds) | ||
}) | ||
} | ||
|
||
const getPathInATempFolder = (filename) => { | ||
return path.join(app.getPath('temp'), filename) | ||
} | ||
|
||
describe('contentTracing', () => { | ||
beforeEach(function () { | ||
// FIXME: The tests are skipped on arm/arm64. | ||
if (process.platform === 'linux' && | ||
['arm', 'arm64'].includes(process.arch)) { | ||
this.skip() | ||
} | ||
}) | ||
|
||
const startRecording = async (options) => { | ||
return new Promise((resolve) => { | ||
contentTracing.startRecording(options, () => { | ||
resolve() | ||
}) | ||
}) | ||
} | ||
|
||
const stopRecording = async (filePath) => { | ||
return new Promise((resolve) => { | ||
contentTracing.stopRecording(filePath, (resultFilePath) => { | ||
resolve(resultFilePath) | ||
}) | ||
}) | ||
} | ||
|
||
const record = async (options, outputFilePath) => { | ||
await app.whenReady() | ||
const recordTimeInMilliseconds = 1e3 | ||
|
||
await startRecording(options) | ||
await timeout(recordTimeInMilliseconds) | ||
const resultFilePath = await stopRecording(outputFilePath) | ||
|
||
return resultFilePath | ||
} | ||
|
||
const outputFilePath = getPathInATempFolder('trace.json') | ||
beforeEach(() => { | ||
if (fs.existsSync(outputFilePath)) { | ||
fs.unlinkSync(outputFilePath) | ||
} | ||
}) | ||
|
||
describe('startRecording', function () { | ||
this.timeout(5e3) | ||
|
||
const getFileSizeInKiloBytes = (filePath) => { | ||
const stats = fs.statSync(filePath) | ||
const fileSizeInBytes = stats.size | ||
const fileSizeInKiloBytes = fileSizeInBytes / 1024 | ||
return fileSizeInKiloBytes | ||
} | ||
|
||
it('accepts an empty config', async () => { | ||
const config = {} | ||
await record(config, outputFilePath) | ||
|
||
expect(fs.existsSync(outputFilePath)).to.be.true() | ||
|
||
const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath) | ||
expect(fileSizeInKiloBytes).to.be.above(0, | ||
`the trace output file is empty, check "${outputFilePath}"`) | ||
}) | ||
|
||
it('accepts a trace config', async () => { | ||
// XXX(alexeykuzmin): All categories are excluded on purpose, | ||
// so only metadata gets into the output file. | ||
const config = { | ||
excluded_categories: ['*'] | ||
} | ||
await record(config, outputFilePath) | ||
|
||
expect(fs.existsSync(outputFilePath)).to.be.true() | ||
|
||
// If the `excluded_categories` param above is not respected | ||
// the file size will be above 50KB. | ||
const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath) | ||
const expectedMaximumFileSize = 10 // Depends on a platform. | ||
|
||
expect(fileSizeInKiloBytes).to.be.above(0, | ||
`the trace output file is empty, check "${outputFilePath}"`) | ||
expect(fileSizeInKiloBytes).to.be.below(expectedMaximumFileSize, | ||
`the trace output file is suspiciously large (${fileSizeInKiloBytes}KB), | ||
check "${outputFilePath}"`) | ||
}) | ||
|
||
it('accepts "categoryFilter" and "traceOptions" as a config', async () => { | ||
// XXX(alexeykuzmin): All categories are excluded on purpose, | ||
// so only metadata gets into the output file. | ||
const config = { | ||
categoryFilter: '__ThisIsANonexistentCategory__', | ||
traceOptions: '' | ||
} | ||
await record(config, outputFilePath) | ||
|
||
expect(fs.existsSync(outputFilePath)).to.be.true() | ||
|
||
// If the `categoryFilter` param above is not respected | ||
// the file size will be above 50KB. | ||
const fileSizeInKiloBytes = getFileSizeInKiloBytes(outputFilePath) | ||
const expectedMaximumFileSize = 10 // Depends on a platform. | ||
|
||
expect(fileSizeInKiloBytes).to.be.above(0, | ||
`the trace output file is empty, check "${outputFilePath}"`) | ||
expect(fileSizeInKiloBytes).to.be.below(expectedMaximumFileSize, | ||
`the trace output file is suspiciously large (${fileSizeInKiloBytes}KB), | ||
check "${outputFilePath}"`) | ||
}) | ||
}) | ||
|
||
describe('stopRecording', function () { | ||
this.timeout(5e3) | ||
|
||
it('calls its callback with a result file path', async () => { | ||
const resultFilePath = await record({}, outputFilePath) | ||
expect(resultFilePath).to.be.a('string').and.be.equal(outputFilePath) | ||
}) | ||
}) | ||
}) |