Merge changes Ieddaf47c,Ia96c58d5,I89e03fff into udc-dev
* changes: Add 'npm run test:presubmit' script Change displayed trace descriptors Optimize bugreport loading
This commit is contained in:
committed by
Android (Google) Code Review
commit
09a1c31019
@@ -19,6 +19,7 @@
|
|||||||
"test:unit": "webpack --config webpack.config.unit_test.js && jasmine dist/unit_test/bundle.js",
|
"test:unit": "webpack --config webpack.config.unit_test.js && jasmine dist/unit_test/bundle.js",
|
||||||
"test:component": "npx karma start",
|
"test:component": "npx karma start",
|
||||||
"test:e2e": "rm -rf dist/e2e_test && npx tsc -p ./src/test/e2e && npx protractor protractor.config.js",
|
"test:e2e": "rm -rf dist/e2e_test && npx tsc -p ./src/test/e2e && npx protractor protractor.config.js",
|
||||||
|
"test:presubmit": "npm run test:unit && npm run test:component && npm run format:check && npm run tslint:check && npm run eslint:check && npm run deps_graph:check_cycles",
|
||||||
"test:all": "npm run test:unit && npm run test:component && npm run test:e2e && npm run format:check && npm run tslint:check && npm run eslint:check && npm run deps_graph:check_cycles"
|
"test:all": "npm run test:unit && npm run test:component && npm run test:e2e && npm run format:check && npm run tslint:check && npm run eslint:check && npm run deps_graph:check_cycles"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|||||||
@@ -26,14 +26,15 @@ export class AbtChromeExtensionProtocol implements BuganizerAttachmentsDownloadE
|
|||||||
static readonly ABT_EXTENSION_ID = 'mbbaofdfoekifkfpgehgffcpagbbjkmj';
|
static readonly ABT_EXTENSION_ID = 'mbbaofdfoekifkfpgehgffcpagbbjkmj';
|
||||||
private onAttachmentsDownloadStart: OnBuganizerAttachmentsDownloadStart =
|
private onAttachmentsDownloadStart: OnBuganizerAttachmentsDownloadStart =
|
||||||
FunctionUtils.DO_NOTHING;
|
FunctionUtils.DO_NOTHING;
|
||||||
private onttachmentsDownloaded: OnBuganizerAttachmentsDownloaded = FunctionUtils.DO_NOTHING_ASYNC;
|
private onAttachmentsDownloaded: OnBuganizerAttachmentsDownloaded =
|
||||||
|
FunctionUtils.DO_NOTHING_ASYNC;
|
||||||
|
|
||||||
setOnBuganizerAttachmentsDownloadStart(callback: OnBuganizerAttachmentsDownloadStart) {
|
setOnBuganizerAttachmentsDownloadStart(callback: OnBuganizerAttachmentsDownloadStart) {
|
||||||
this.onAttachmentsDownloadStart = callback;
|
this.onAttachmentsDownloadStart = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
setOnBuganizerAttachmentsDownloaded(callback: OnBuganizerAttachmentsDownloaded) {
|
setOnBuganizerAttachmentsDownloaded(callback: OnBuganizerAttachmentsDownloaded) {
|
||||||
this.onttachmentsDownloaded = callback;
|
this.onAttachmentsDownloaded = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
run() {
|
run() {
|
||||||
@@ -83,7 +84,7 @@ export class AbtChromeExtensionProtocol implements BuganizerAttachmentsDownloadE
|
|||||||
});
|
});
|
||||||
|
|
||||||
const files = await Promise.all(filesBlobPromises);
|
const files = await Promise.all(filesBlobPromises);
|
||||||
await this.onttachmentsDownloaded(files);
|
await this.onAttachmentsDownloaded(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
private isOpenBuganizerResponseMessage(
|
private isOpenBuganizerResponseMessage(
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ export class AppComponent implements TraceDataListener {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${TRACE_INFO[trace.type].name} (${trace.descriptors.join(', ')})`;
|
return `${trace.descriptors.join(', ')}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getActiveTrace(view: View): LoadedTrace | undefined {
|
private getActiveTrace(view: View): LoadedTrace | undefined {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export class Mediator {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
this.crossToolProtocol.setOnTimestampReceived(async (timestamp: Timestamp) => {
|
this.crossToolProtocol.setOnTimestampReceived((timestamp: Timestamp) => {
|
||||||
this.onRemoteTimestampReceived(timestamp);
|
this.onRemoteTimestampReceived(timestamp);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -203,7 +203,7 @@ export class Mediator {
|
|||||||
|
|
||||||
private async processRemoteFilesReceived(files: File[]) {
|
private async processRemoteFilesReceived(files: File[]) {
|
||||||
this.resetAppToInitialState();
|
this.resetAppToInitialState();
|
||||||
this.processFiles(files);
|
await this.processFiles(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async processFiles(files: File[]) {
|
private async processFiles(files: File[]) {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class TracePipeline {
|
|||||||
traceFiles: TraceFile[],
|
traceFiles: TraceFile[],
|
||||||
onLoadProgressUpdate: OnProgressUpdateType = FunctionUtils.DO_NOTHING
|
onLoadProgressUpdate: OnProgressUpdateType = FunctionUtils.DO_NOTHING
|
||||||
): Promise<ParserError[]> {
|
): Promise<ParserError[]> {
|
||||||
|
traceFiles = await this.filterBugreportFilesIfNeeded(traceFiles);
|
||||||
const [parsers, parserErrors] = await this.parserFactory.createParsers(
|
const [parsers, parserErrors] = await this.parserFactory.createParsers(
|
||||||
traceFiles,
|
traceFiles,
|
||||||
onLoadProgressUpdate
|
onLoadProgressUpdate
|
||||||
@@ -117,6 +118,36 @@ class TracePipeline {
|
|||||||
this.files = new Map<TraceType, TraceFile>();
|
this.files = new Map<TraceType, TraceFile>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async filterBugreportFilesIfNeeded(files: TraceFile[]): Promise<TraceFile[]> {
|
||||||
|
const bugreportMainEntry = files.find((file) => file.file.name === 'main_entry.txt');
|
||||||
|
if (!bugreportMainEntry) {
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bugreportName = (await bugreportMainEntry.file.text()).trim();
|
||||||
|
const isBugreport = files.find((file) => file.file.name === bugreportName) !== undefined;
|
||||||
|
if (!isBugreport) {
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BUGREPORT_TRACE_DIRS = ['FS/data/misc/wmtrace/', 'FS/data/misc/perfetto-traces/'];
|
||||||
|
const isFileWithinBugreportTraceDir = (file: TraceFile) => {
|
||||||
|
for (const traceDir of BUGREPORT_TRACE_DIRS) {
|
||||||
|
if (file.file.name.startsWith(traceDir)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const fileBelongsToBugreport = (file: TraceFile) =>
|
||||||
|
file.parentArchive === bugreportMainEntry.parentArchive;
|
||||||
|
|
||||||
|
return files.filter((file) => {
|
||||||
|
return isFileWithinBugreportTraceDir(file) || !fileBelongsToBugreport(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private getCommonTimestampType(): TimestampType {
|
private getCommonTimestampType(): TimestampType {
|
||||||
if (this.commonTimestampType !== undefined) {
|
if (this.commonTimestampType !== undefined) {
|
||||||
return this.commonTimestampType;
|
return this.commonTimestampType;
|
||||||
|
|||||||
@@ -39,6 +39,74 @@ describe('TracePipeline', () => {
|
|||||||
expect(traceEntries.get(TraceType.SURFACE_FLINGER)?.length).toBeGreaterThan(0);
|
expect(traceEntries.get(TraceType.SURFACE_FLINGER)?.length).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can load bugreport and ignores non-trace dirs', async () => {
|
||||||
|
expect(tracePipeline.getLoadedTraces().length).toEqual(0);
|
||||||
|
|
||||||
|
// Could be any file, we just need an instance of File to be used as a fake bugreport archive
|
||||||
|
const bugreportArchive = await UnitTestUtils.getFixtureFile(
|
||||||
|
'bugreports/bugreport_stripped.zip'
|
||||||
|
);
|
||||||
|
|
||||||
|
const bugreportFiles = [
|
||||||
|
new TraceFile(
|
||||||
|
await UnitTestUtils.getFixtureFile('bugreports/main_entry.txt', 'main_entry.txt'),
|
||||||
|
bugreportArchive
|
||||||
|
),
|
||||||
|
new TraceFile(
|
||||||
|
await UnitTestUtils.getFixtureFile(
|
||||||
|
'bugreports/bugreport-codename_beta-UPB2.230407.019-2023-05-30-14-33-48.txt',
|
||||||
|
'bugreport-codename_beta-UPB2.230407.019-2023-05-30-14-33-48.txt'
|
||||||
|
),
|
||||||
|
bugreportArchive
|
||||||
|
),
|
||||||
|
new TraceFile(
|
||||||
|
await UnitTestUtils.getFixtureFile(
|
||||||
|
'traces/elapsed_and_real_timestamp/SurfaceFlinger.pb',
|
||||||
|
'FS/data/misc/wmtrace/surface_flinger.bp'
|
||||||
|
),
|
||||||
|
bugreportArchive
|
||||||
|
),
|
||||||
|
new TraceFile(
|
||||||
|
await UnitTestUtils.getFixtureFile(
|
||||||
|
'traces/elapsed_and_real_timestamp/Transactions.pb',
|
||||||
|
'FS/data/misc/wmtrace/transactions.bp'
|
||||||
|
),
|
||||||
|
bugreportArchive
|
||||||
|
),
|
||||||
|
new TraceFile(
|
||||||
|
await UnitTestUtils.getFixtureFile(
|
||||||
|
'traces/elapsed_and_real_timestamp/WindowManager.pb',
|
||||||
|
'FS/data/misc/ignored-dir/window_manager.bp'
|
||||||
|
),
|
||||||
|
bugreportArchive
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
// Corner case:
|
||||||
|
// A plain trace file is loaded along the bugreport -> trace file must not be ignored
|
||||||
|
//
|
||||||
|
// Note:
|
||||||
|
// The even weirder corner case where two bugreports are loaded at the same time is
|
||||||
|
// currently not properly handled.
|
||||||
|
const plainTraceFile = new TraceFile(
|
||||||
|
await UnitTestUtils.getFixtureFile(
|
||||||
|
'traces/elapsed_and_real_timestamp/InputMethodClients.pb',
|
||||||
|
'would-be-ignored-if-was-part-of-bugreport/input_method_clients.pb'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const mergedFiles = bugreportFiles.concat([plainTraceFile]);
|
||||||
|
const errors = await tracePipeline.loadTraceFiles(mergedFiles);
|
||||||
|
expect(errors.length).toEqual(0);
|
||||||
|
tracePipeline.buildTraces();
|
||||||
|
const traces = tracePipeline.getTraces();
|
||||||
|
|
||||||
|
expect(traces.getTrace(TraceType.SURFACE_FLINGER)).toBeDefined();
|
||||||
|
expect(traces.getTrace(TraceType.TRANSACTIONS)).toBeDefined();
|
||||||
|
expect(traces.getTrace(TraceType.WINDOW_MANAGER)).toBeUndefined(); // ignored
|
||||||
|
expect(traces.getTrace(TraceType.INPUT_METHOD_CLIENTS)).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
it('is robust to invalid trace files', async () => {
|
it('is robust to invalid trace files', async () => {
|
||||||
const invalidTraceFiles = [
|
const invalidTraceFiles = [
|
||||||
new TraceFile(await UnitTestUtils.getFixtureFile('winscope_homepage.png')),
|
new TraceFile(await UnitTestUtils.getFixtureFile('winscope_homepage.png')),
|
||||||
|
|||||||
@@ -61,9 +61,8 @@ class FileUtils {
|
|||||||
// Ignore directories
|
// Ignore directories
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
const name = FileUtils.removeDirFromFileName(filename);
|
|
||||||
const fileBlob = await file.async('blob');
|
const fileBlob = await file.async('blob');
|
||||||
const unzippedFile = new File([fileBlob], name);
|
const unzippedFile = new File([fileBlob], filename);
|
||||||
unzippedFiles.push(unzippedFile);
|
unzippedFiles.push(unzippedFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -128,7 +128,6 @@ export class TimeUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static formattedKotlinTimestamp(time: any, timestampType: TimestampType): string {
|
static formattedKotlinTimestamp(time: any, timestampType: TimestampType): string {
|
||||||
console.log('time', time);
|
|
||||||
if (timestampType === TimestampType.ELAPSED) {
|
if (timestampType === TimestampType.ELAPSED) {
|
||||||
return TimeUtils.format(new ElapsedTimestamp(BigInt(time.elapsedNanos.toString())));
|
return TimeUtils.format(new ElapsedTimestamp(BigInt(time.elapsedNanos.toString())));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,11 @@ class FileImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
text(): Promise<string> {
|
text(): Promise<string> {
|
||||||
throw new Error('Not implemented!');
|
const utf8Decoder = new TextDecoder();
|
||||||
|
const text = utf8Decoder.decode(this.buffer);
|
||||||
|
return new Promise<string>((resolve) => {
|
||||||
|
resolve(text);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,12 @@ import * as path from 'path';
|
|||||||
import {FileImpl} from './file_impl';
|
import {FileImpl} from './file_impl';
|
||||||
|
|
||||||
class CommonTestUtils {
|
class CommonTestUtils {
|
||||||
static async getFixtureFile(filename: string): Promise<File> {
|
static async getFixtureFile(
|
||||||
const buffer = CommonTestUtils.loadFixture(filename);
|
srcFilename: string,
|
||||||
return new FileImpl(buffer, filename) as unknown as File;
|
dstFilename: string = srcFilename
|
||||||
|
): Promise<File> {
|
||||||
|
const buffer = CommonTestUtils.loadFixture(srcFilename);
|
||||||
|
return new FileImpl(buffer, dstFilename) as unknown as File;
|
||||||
}
|
}
|
||||||
|
|
||||||
static loadFixture(filename: string): ArrayBuffer {
|
static loadFixture(filename: string): ArrayBuffer {
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
========================================================
|
||||||
|
== dumpstate: 2023-05-30 14:33:48
|
||||||
|
========================================================
|
||||||
|
|
||||||
|
# ORIGINAL CONTENTS REMOVED TO AVOID INFORMATION LEAKS
|
||||||
|
|
||||||
Binary file not shown.
1
tools/winscope/src/test/fixtures/bugreports/main_entry.txt
vendored
Normal file
1
tools/winscope/src/test/fixtures/bugreports/main_entry.txt
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
bugreport-codename_beta-UPB2.230407.019-2023-05-30-14-33-48.txt
|
||||||
@@ -14,11 +14,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {FileUtils} from 'common/file_utils';
|
||||||
|
|
||||||
export class TraceFile {
|
export class TraceFile {
|
||||||
constructor(public file: File, public parentArchive?: File) {}
|
constructor(public file: File, public parentArchive?: File) {}
|
||||||
|
|
||||||
getDescriptor(): string {
|
getDescriptor(): string {
|
||||||
let descriptor = this.file.name;
|
let descriptor = FileUtils.removeDirFromFileName(this.file.name);
|
||||||
if (this.parentArchive?.name !== undefined) {
|
if (this.parentArchive?.name !== undefined) {
|
||||||
descriptor += ` (${this.parentArchive?.name})`;
|
descriptor += ` (${this.parentArchive?.name})`;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user