finished refactoring
This commit is contained in:
parent
37b8691c8c
commit
c4114c2f66
|
@ -9,8 +9,6 @@
|
|||
import {Inject, Injectable, OpaqueToken} from '@angular/core';
|
||||
|
||||
import {Options} from '../common_options';
|
||||
import {ListWrapper, StringMapWrapper} from '../facade/collection';
|
||||
import {Math, NumberWrapper, StringWrapper, isBlank, isPresent} from '../facade/lang';
|
||||
import {Metric} from '../metric';
|
||||
import {PerfLogEvent, PerfLogFeatures, WebDriverExtension} from '../web_driver_extension';
|
||||
|
||||
|
@ -95,8 +93,9 @@ export class PerflogMetric extends Metric {
|
|||
res['frameTime.smooth'] = 'percentage of frames that hit 60fps';
|
||||
}
|
||||
}
|
||||
StringMapWrapper.forEach(
|
||||
this._microMetrics, (desc, name) => { StringMapWrapper.set(res, name, desc); });
|
||||
for (let name in this._microMetrics) {
|
||||
res[name] = this._microMetrics[name];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -126,8 +125,8 @@ export class PerflogMetric extends Metric {
|
|||
.then((_) => this._endMeasure(restartMeasure))
|
||||
.then((forceGcMeasureValues) => {
|
||||
this._captureFrames = originalFrameCaptureValue;
|
||||
StringMapWrapper.set(measureValues, 'forcedGcTime', forceGcMeasureValues['gcTime']);
|
||||
StringMapWrapper.set(measureValues, 'forcedGcAmount', forceGcMeasureValues['gcAmount']);
|
||||
measureValues['forcedGcTime'] = forceGcMeasureValues['gcTime'];
|
||||
measureValues['forcedGcAmount'] = forceGcMeasureValues['gcAmount'];
|
||||
return measureValues;
|
||||
});
|
||||
});
|
||||
|
@ -152,7 +151,7 @@ export class PerflogMetric extends Metric {
|
|||
return this._driverExtension.readPerfLog().then((events) => {
|
||||
this._addEvents(events);
|
||||
var result = this._aggregateEvents(this._remainingEvents, markName);
|
||||
if (isPresent(result)) {
|
||||
if (result) {
|
||||
this._remainingEvents = events;
|
||||
return result;
|
||||
}
|
||||
|
@ -166,14 +165,14 @@ export class PerflogMetric extends Metric {
|
|||
private _addEvents(events: PerfLogEvent[]) {
|
||||
var needSort = false;
|
||||
events.forEach(event => {
|
||||
if (StringWrapper.equals(event['ph'], 'X')) {
|
||||
if (event['ph'] === 'X') {
|
||||
needSort = true;
|
||||
var startEvent: PerfLogEvent = {};
|
||||
var endEvent: PerfLogEvent = {};
|
||||
StringMapWrapper.forEach(event, (value, prop) => {
|
||||
(<any>startEvent)[prop] = value;
|
||||
(<any>endEvent)[prop] = value;
|
||||
});
|
||||
for (let prop in event) {
|
||||
startEvent[prop] = event[prop];
|
||||
endEvent[prop] = event[prop];
|
||||
}
|
||||
startEvent['ph'] = 'B';
|
||||
endEvent['ph'] = 'E';
|
||||
endEvent['ts'] = startEvent['ts'] + startEvent['dur'];
|
||||
|
@ -185,7 +184,7 @@ export class PerflogMetric extends Metric {
|
|||
});
|
||||
if (needSort) {
|
||||
// Need to sort because of the ph==='X' events
|
||||
ListWrapper.sort(this._remainingEvents, (a, b) => {
|
||||
this._remainingEvents.sort((a, b) => {
|
||||
var diff = a['ts'] - b['ts'];
|
||||
return diff > 0 ? 1 : diff < 0 ? -1 : 0;
|
||||
});
|
||||
|
@ -208,7 +207,9 @@ export class PerflogMetric extends Metric {
|
|||
result['frameTime.worst'] = 0;
|
||||
result['frameTime.smooth'] = 0;
|
||||
}
|
||||
StringMapWrapper.forEach(this._microMetrics, (desc, name) => { result[name] = 0; });
|
||||
for (let name in this._microMetrics) {
|
||||
result[name] = 0;
|
||||
}
|
||||
if (this._receivedData) {
|
||||
result['receivedData'] = 0;
|
||||
}
|
||||
|
@ -233,23 +234,23 @@ export class PerflogMetric extends Metric {
|
|||
var name = event['name'];
|
||||
var microIterations = 1;
|
||||
var microIterationsMatch = name.match(_MICRO_ITERATIONS_REGEX);
|
||||
if (isPresent(microIterationsMatch)) {
|
||||
if (microIterationsMatch) {
|
||||
name = microIterationsMatch[1];
|
||||
microIterations = NumberWrapper.parseInt(microIterationsMatch[2], 10);
|
||||
microIterations = parseInt(microIterationsMatch[2], 10);
|
||||
}
|
||||
|
||||
if (StringWrapper.equals(ph, 'b') && StringWrapper.equals(name, markName)) {
|
||||
if (ph === 'b' && name === markName) {
|
||||
markStartEvent = event;
|
||||
} else if (StringWrapper.equals(ph, 'e') && StringWrapper.equals(name, markName)) {
|
||||
} else if (ph === 'e' && name === markName) {
|
||||
markEndEvent = event;
|
||||
}
|
||||
|
||||
let isInstant = StringWrapper.equals(ph, 'I') || StringWrapper.equals(ph, 'i');
|
||||
if (this._requestCount && StringWrapper.equals(name, 'sendRequest')) {
|
||||
let isInstant = ph === 'I' || ph === 'i';
|
||||
if (this._requestCount && name === 'sendRequest') {
|
||||
result['requestCount'] += 1;
|
||||
} else if (this._receivedData && StringWrapper.equals(name, 'receivedData') && isInstant) {
|
||||
} else if (this._receivedData && name === 'receivedData' && isInstant) {
|
||||
result['receivedData'] += event['args']['encodedDataLength'];
|
||||
} else if (StringWrapper.equals(name, 'navigationStart')) {
|
||||
} else if (name === 'navigationStart') {
|
||||
// We count data + requests since the last navigationStart
|
||||
// (there might be chrome extensions loaded by selenium before our page, so there
|
||||
// will likely be more than one navigationStart).
|
||||
|
@ -260,10 +261,9 @@ export class PerflogMetric extends Metric {
|
|||
result['requestCount'] = 0;
|
||||
}
|
||||
}
|
||||
if (isPresent(markStartEvent) && isBlank(markEndEvent) &&
|
||||
event['pid'] === markStartEvent['pid']) {
|
||||
if (StringWrapper.equals(ph, 'b') && StringWrapper.equals(name, _MARK_NAME_FRAME_CAPUTRE)) {
|
||||
if (isPresent(frameCaptureStartEvent)) {
|
||||
if (markStartEvent && !markEndEvent && event['pid'] === markStartEvent['pid']) {
|
||||
if (ph === 'b' && name === _MARK_NAME_FRAME_CAPUTRE) {
|
||||
if (frameCaptureStartEvent) {
|
||||
throw new Error('can capture frames only once per benchmark run');
|
||||
}
|
||||
if (!this._captureFrames) {
|
||||
|
@ -271,17 +271,15 @@ export class PerflogMetric extends Metric {
|
|||
'found start event for frame capture, but frame capture was not requested in benchpress');
|
||||
}
|
||||
frameCaptureStartEvent = event;
|
||||
} else if (
|
||||
StringWrapper.equals(ph, 'e') && StringWrapper.equals(name, _MARK_NAME_FRAME_CAPUTRE)) {
|
||||
if (isBlank(frameCaptureStartEvent)) {
|
||||
} else if (ph === 'e' && name === _MARK_NAME_FRAME_CAPUTRE) {
|
||||
if (!frameCaptureStartEvent) {
|
||||
throw new Error('missing start event for frame capture');
|
||||
}
|
||||
frameCaptureEndEvent = event;
|
||||
}
|
||||
|
||||
if (isInstant) {
|
||||
if (isPresent(frameCaptureStartEvent) && isBlank(frameCaptureEndEvent) &&
|
||||
StringWrapper.equals(name, 'frame')) {
|
||||
if (frameCaptureStartEvent && !frameCaptureEndEvent && name === 'frame') {
|
||||
frameTimestamps.push(event['ts']);
|
||||
if (frameTimestamps.length >= 2) {
|
||||
frameTimes.push(
|
||||
|
@ -291,57 +289,54 @@ export class PerflogMetric extends Metric {
|
|||
}
|
||||
}
|
||||
|
||||
if (StringWrapper.equals(ph, 'B') || StringWrapper.equals(ph, 'b')) {
|
||||
if (isBlank(intervalStarts[name])) {
|
||||
if (ph === 'B' || ph === 'b') {
|
||||
if (!intervalStarts[name]) {
|
||||
intervalStartCount[name] = 1;
|
||||
intervalStarts[name] = event;
|
||||
} else {
|
||||
intervalStartCount[name]++;
|
||||
}
|
||||
} else if (
|
||||
(StringWrapper.equals(ph, 'E') || StringWrapper.equals(ph, 'e')) &&
|
||||
isPresent(intervalStarts[name])) {
|
||||
} else if ((ph === 'E' || ph === 'e') && intervalStarts[name]) {
|
||||
intervalStartCount[name]--;
|
||||
if (intervalStartCount[name] === 0) {
|
||||
var startEvent = intervalStarts[name];
|
||||
var duration = (event['ts'] - startEvent['ts']);
|
||||
intervalStarts[name] = null;
|
||||
if (StringWrapper.equals(name, 'gc')) {
|
||||
if (name === 'gc') {
|
||||
result['gcTime'] += duration;
|
||||
var amount =
|
||||
(startEvent['args']['usedHeapSize'] - event['args']['usedHeapSize']) / 1000;
|
||||
result['gcAmount'] += amount;
|
||||
var majorGc = event['args']['majorGc'];
|
||||
if (isPresent(majorGc) && majorGc) {
|
||||
if (majorGc && majorGc) {
|
||||
result['majorGcTime'] += duration;
|
||||
}
|
||||
if (isPresent(intervalStarts['script'])) {
|
||||
if (intervalStarts['script']) {
|
||||
gcTimeInScript += duration;
|
||||
}
|
||||
} else if (StringWrapper.equals(name, 'render')) {
|
||||
} else if (name === 'render') {
|
||||
result['renderTime'] += duration;
|
||||
if (isPresent(intervalStarts['script'])) {
|
||||
if (intervalStarts['script']) {
|
||||
renderTimeInScript += duration;
|
||||
}
|
||||
} else if (StringWrapper.equals(name, 'script')) {
|
||||
} else if (name === 'script') {
|
||||
result['scriptTime'] += duration;
|
||||
} else if (isPresent(this._microMetrics[name])) {
|
||||
} else if (this._microMetrics[name]) {
|
||||
(<any>result)[name] += duration / microIterations;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!isPresent(markStartEvent) || !isPresent(markEndEvent)) {
|
||||
if (!markStartEvent || !markEndEvent) {
|
||||
// not all events have been received, no further processing for now
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isPresent(markEndEvent) && isPresent(frameCaptureStartEvent) &&
|
||||
isBlank(frameCaptureEndEvent)) {
|
||||
if (markEndEvent && frameCaptureStartEvent && !frameCaptureEndEvent) {
|
||||
throw new Error('missing end event for frame capture');
|
||||
}
|
||||
if (this._captureFrames && isBlank(frameCaptureStartEvent)) {
|
||||
if (this._captureFrames && !frameCaptureStartEvent) {
|
||||
throw new Error('frame capture requested in benchpress, but no start event was found');
|
||||
}
|
||||
if (frameTimes.length > 0) {
|
||||
|
|
|
@ -12,8 +12,10 @@ import {Options} from './common_options';
|
|||
import {isBlank, isPresent} from './facade/lang';
|
||||
|
||||
export type PerfLogEvent = {
|
||||
[key: string]: any
|
||||
} & {
|
||||
cat?: string,
|
||||
ph?: 'X' | 'B' | 'E' | 'b' | 'e',
|
||||
ph?: 'X' | 'B' | 'E' | 'b' | 'e' | 'i' | 'I',
|
||||
ts?: number,
|
||||
dur?: number,
|
||||
name?: string,
|
||||
|
|
|
@ -14,7 +14,7 @@ import {PerfLogEvent, PerfLogFeatures, WebDriverExtension} from '../web_driver_e
|
|||
|
||||
/**
|
||||
* Set the following 'traceCategories' to collect metrics in Chrome:
|
||||
* 'v8,blink.console,disabled-by-default-devtools.timeline,devtools.timeline'
|
||||
* 'v8,blink.console,disabled-by-default-devtools.timeline,devtools.timeline,blink.user_timing'
|
||||
*
|
||||
* In order to collect the frame rate related metrics, add 'benchmark'
|
||||
* to the list above.
|
||||
|
@ -28,7 +28,6 @@ export class ChromeDriverExtension extends WebDriverExtension {
|
|||
constructor(private _driver: WebDriverAdapter, @Inject(Options.USER_AGENT) userAgent: string) {
|
||||
super();
|
||||
this._majorChromeVersion = this._parseChromeVersion(userAgent);
|
||||
|
||||
}
|
||||
|
||||
private _parseChromeVersion(userAgent: string): number {
|
||||
|
@ -74,7 +73,7 @@ export class ChromeDriverExtension extends WebDriverExtension {
|
|||
if (message['method'] === 'Tracing.dataCollected') {
|
||||
events.push(message['params']);
|
||||
}
|
||||
if (message['method'] === 'Tracing.bufferUsage') {
|
||||
if (message['method'] === 'Tracing.bufferUsage') {
|
||||
throw new Error('The DevTools trace buffer filled during the test!');
|
||||
}
|
||||
});
|
||||
|
@ -87,64 +86,59 @@ export class ChromeDriverExtension extends WebDriverExtension {
|
|||
if (!normalizedEvents) {
|
||||
normalizedEvents = [];
|
||||
}
|
||||
var majorGCPids = {};
|
||||
chromeEvents.forEach((event) => {
|
||||
var categories = this._parseCategories(event['cat']);
|
||||
var name = event['name'];
|
||||
if (this._isEvent(categories, name, ['blink.console'])) {
|
||||
normalizedEvents.push(normalizeEvent(event, {'name': name}));
|
||||
} else if (this._isEvent(
|
||||
categories, name, ['benchmark'],
|
||||
'BenchmarkInstrumentation::ImplThreadRenderingStats')) {
|
||||
// TODO(goderbauer): Instead of BenchmarkInstrumentation::ImplThreadRenderingStats the
|
||||
// following events should be used (if available) for more accurate measurments:
|
||||
// 1st choice: vsync_before - ground truth on Android
|
||||
// 2nd choice: BenchmarkInstrumentation::DisplayRenderingStats - available on systems with
|
||||
// new surfaces framework (not broadly enabled yet)
|
||||
// 3rd choice: BenchmarkInstrumentation::ImplThreadRenderingStats - fallback event that is
|
||||
// always available if something is rendered
|
||||
var frameCount = event['args']['data']['frame_count'];
|
||||
if (frameCount > 1) {
|
||||
throw new Error('multi-frame render stats not supported');
|
||||
}
|
||||
if (frameCount == 1) {
|
||||
normalizedEvents.push(normalizeEvent(event, {'name': 'frame'}));
|
||||
}
|
||||
} else if (
|
||||
this._isEvent(categories, name, ['disabled-by-default-devtools.timeline'], 'Rasterize') ||
|
||||
this._isEvent(
|
||||
categories, name, ['disabled-by-default-devtools.timeline'], 'CompositeLayers')) {
|
||||
normalizedEvents.push(normalizeEvent(event, {'name': 'render'}));
|
||||
} else {
|
||||
var normalizedEvent = this._processAsPostChrome44Event(event, categories);
|
||||
if (normalizedEvent != null) normalizedEvents.push(normalizedEvent);
|
||||
}
|
||||
const categories = this._parseCategories(event['cat']);
|
||||
const normalizedEvent = this._convertEvent(event, categories);
|
||||
if (normalizedEvent != null) normalizedEvents.push(normalizedEvent);
|
||||
});
|
||||
return normalizedEvents;
|
||||
}
|
||||
|
||||
private _processAsPostChrome44Event(event: {[key: string]: any}, categories: string[]) {
|
||||
private _convertEvent(event: {[key: string]: any}, categories: string[]) {
|
||||
var name = event['name'];
|
||||
var args = event['args'];
|
||||
if (this._isEvent(categories, name, ['devtools.timeline', 'v8'], 'MajorGC')) {
|
||||
if (this._isEvent(categories, name, ['blink.console'])) {
|
||||
return normalizeEvent(event, {'name': name});
|
||||
} else if (this._isEvent(
|
||||
categories, name, ['benchmark'],
|
||||
'BenchmarkInstrumentation::ImplThreadRenderingStats')) {
|
||||
// TODO(goderbauer): Instead of BenchmarkInstrumentation::ImplThreadRenderingStats the
|
||||
// following events should be used (if available) for more accurate measurments:
|
||||
// 1st choice: vsync_before - ground truth on Android
|
||||
// 2nd choice: BenchmarkInstrumentation::DisplayRenderingStats - available on systems with
|
||||
// new surfaces framework (not broadly enabled yet)
|
||||
// 3rd choice: BenchmarkInstrumentation::ImplThreadRenderingStats - fallback event that is
|
||||
// always available if something is rendered
|
||||
var frameCount = event['args']['data']['frame_count'];
|
||||
if (frameCount > 1) {
|
||||
throw new Error('multi-frame render stats not supported');
|
||||
}
|
||||
if (frameCount == 1) {
|
||||
return normalizeEvent(event, {'name': 'frame'});
|
||||
}
|
||||
} else if (
|
||||
this._isEvent(categories, name, ['disabled-by-default-devtools.timeline'], 'Rasterize') ||
|
||||
this._isEvent(
|
||||
categories, name, ['disabled-by-default-devtools.timeline'], 'CompositeLayers')) {
|
||||
return normalizeEvent(event, {'name': 'render'});
|
||||
} else if (this._isEvent(categories, name, ['devtools.timeline', 'v8'], 'MajorGC')) {
|
||||
var normArgs = {
|
||||
'majorGc': true,
|
||||
'usedHeapSize': args['usedHeapSizeAfter'] !== undefined ? args['usedHeapSizeAfter'] :
|
||||
args['usedHeapSizeBefore']
|
||||
args['usedHeapSizeBefore']
|
||||
};
|
||||
return normalizeEvent(event, {'name': 'gc', 'args': normArgs});
|
||||
} else if (this._isEvent(categories, name, ['devtools.timeline', 'v8'], 'MinorGC')) {
|
||||
var normArgs = {
|
||||
'majorGc': false,
|
||||
'usedHeapSize': args['usedHeapSizeAfter'] !== undefined ? args['usedHeapSizeAfter'] :
|
||||
args['usedHeapSizeBefore']
|
||||
args['usedHeapSizeBefore']
|
||||
};
|
||||
return normalizeEvent(event, {'name': 'gc', 'args': normArgs});
|
||||
} else if (
|
||||
this._isEvent(categories, name, ['devtools.timeline'], 'FunctionCall') &&
|
||||
(!args || !args['data'] ||
|
||||
(args['data']['scriptName'] !== 'InjectedScript' &&
|
||||
args['data']['scriptName'] !== ''))) {
|
||||
(args['data']['scriptName'] !== 'InjectedScript' && args['data']['scriptName'] !== ''))) {
|
||||
return normalizeEvent(event, {'name': 'script'});
|
||||
} else if (this._isEvent(
|
||||
categories, name, ['devtools.timeline', 'blink'], 'UpdateLayoutTree')) {
|
||||
|
@ -174,8 +168,7 @@ export class ChromeDriverExtension extends WebDriverExtension {
|
|||
expectedName: string = null): boolean {
|
||||
var hasCategories = expectedCategories.reduce(
|
||||
(value, cat) => { return value && eventCategories.indexOf(cat) !== -1; }, true);
|
||||
return !expectedName ? hasCategories :
|
||||
hasCategories && eventName === expectedName;
|
||||
return !expectedName ? hasCategories : hasCategories && eventName === expectedName;
|
||||
}
|
||||
|
||||
perfLogFeatures(): PerfLogFeatures {
|
||||
|
@ -183,17 +176,16 @@ export class ChromeDriverExtension extends WebDriverExtension {
|
|||
}
|
||||
|
||||
supports(capabilities: {[key: string]: any}): boolean {
|
||||
return this._majorChromeVersion >=44 &&
|
||||
capabilities['browserName'].toLowerCase() === 'chrome';
|
||||
return this._majorChromeVersion >= 44 && capabilities['browserName'].toLowerCase() === 'chrome';
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeEvent(
|
||||
chromeEvent: {[key: string]: any}, data: {[key: string]: any}): PerfLogEvent {
|
||||
var ph = chromeEvent['ph'];
|
||||
if (ph === 'S') {
|
||||
if (ph === 'S') {
|
||||
ph = 'b';
|
||||
} else if (ph === 'F') {
|
||||
} else if (ph === 'F') {
|
||||
ph = 'e';
|
||||
}
|
||||
var result: {[key: string]: any} =
|
||||
|
|
|
@ -14,8 +14,6 @@ import {TraceEventFactory} from '../trace_event_factory';
|
|||
|
||||
export function main() {
|
||||
describe('chrome driver extension', () => {
|
||||
var CHROME44_USER_AGENT =
|
||||
'"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.0 Safari/537.36"';
|
||||
var CHROME45_USER_AGENT =
|
||||
'"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2499.0 Safari/537.36"';
|
||||
|
||||
|
@ -41,7 +39,7 @@ export function main() {
|
|||
perfRecords = [];
|
||||
}
|
||||
if (isBlank(userAgent)) {
|
||||
userAgent = CHROME44_USER_AGENT;
|
||||
userAgent = CHROME45_USER_AGENT;
|
||||
}
|
||||
log = [];
|
||||
extension = ReflectiveInjector
|
||||
|
@ -89,228 +87,83 @@ export function main() {
|
|||
});
|
||||
}));
|
||||
|
||||
describe('readPerfLog Chrome44', () => {
|
||||
it('should normalize times to ms and forward ph and pid event properties',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([chromeTimelineEvents.complete('FunctionCall', 1100, 5500, null)])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.complete('script', 1.1, 5.5, null),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
it('should normalize times to ms and forward ph and pid event properties',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([chromeTimelineV8Events.complete('FunctionCall', 1100, 5500, null)])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.complete('script', 1.1, 5.5, null),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should normalize "tdur" to "dur"',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var event: any = chromeTimelineEvents.create('X', 'FunctionCall', 1100, null);
|
||||
event['tdur'] = 5500;
|
||||
createExtension([event]).readPerfLog().then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.complete('script', 1.1, 5.5, null),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
it('should normalize "tdur" to "dur"',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var event: any = chromeTimelineV8Events.create('X', 'FunctionCall', 1100, null);
|
||||
event['tdur'] = 5500;
|
||||
createExtension([event]).readPerfLog().then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.complete('script', 1.1, 5.5, null),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report FunctionCall events as "script"',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([chromeTimelineEvents.start('FunctionCall', 0)])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.start('script', 0),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
it('should report FunctionCall events as "script"',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([chromeTimelineV8Events.start('FunctionCall', 0)])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.start('script', 0),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report gc', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([
|
||||
chromeTimelineEvents.start('GCEvent', 1000, {'usedHeapSizeBefore': 1000}),
|
||||
chromeTimelineEvents.end('GCEvent', 2000, {'usedHeapSizeAfter': 0}),
|
||||
])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.start('gc', 1.0, {'usedHeapSize': 1000}),
|
||||
normEvents.end('gc', 2.0, {'usedHeapSize': 0, 'majorGc': false}),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
it('should report minor gc', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([
|
||||
chromeTimelineV8Events.start('MinorGC', 1000, {'usedHeapSizeBefore': 1000}),
|
||||
chromeTimelineV8Events.end('MinorGC', 2000, {'usedHeapSizeAfter': 0}),
|
||||
])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events.length).toEqual(2);
|
||||
expect(events[0]).toEqual(
|
||||
normEvents.start('gc', 1.0, {'usedHeapSize': 1000, 'majorGc': false}));
|
||||
expect(events[1]).toEqual(
|
||||
normEvents.end('gc', 2.0, {'usedHeapSize': 0, 'majorGc': false}));
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should ignore major gc from different processes',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([
|
||||
chromeTimelineEvents.start('GCEvent', 1000, {'usedHeapSizeBefore': 1000}),
|
||||
v8EventsOtherProcess.start('majorGC', 1100, null),
|
||||
v8EventsOtherProcess.end('majorGC', 1200, null),
|
||||
chromeTimelineEvents.end('GCEvent', 2000, {'usedHeapSizeAfter': 0}),
|
||||
])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.start('gc', 1.0, {'usedHeapSize': 1000}),
|
||||
normEvents.end('gc', 2.0, {'usedHeapSize': 0, 'majorGc': false}),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
it('should report major gc', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension(
|
||||
[
|
||||
chromeTimelineV8Events.start('MajorGC', 1000, {'usedHeapSizeBefore': 1000}),
|
||||
chromeTimelineV8Events.end('MajorGC', 2000, {'usedHeapSizeAfter': 0}),
|
||||
], )
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events.length).toEqual(2);
|
||||
expect(events[0]).toEqual(
|
||||
normEvents.start('gc', 1.0, {'usedHeapSize': 1000, 'majorGc': true}));
|
||||
expect(events[1]).toEqual(
|
||||
normEvents.end('gc', 2.0, {'usedHeapSize': 0, 'majorGc': true}));
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report major gc', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([
|
||||
chromeTimelineEvents.start('GCEvent', 1000, {'usedHeapSizeBefore': 1000}),
|
||||
v8Events.start('majorGC', 1100, null),
|
||||
v8Events.end('majorGC', 1200, null),
|
||||
chromeTimelineEvents.end('GCEvent', 2000, {'usedHeapSizeAfter': 0}),
|
||||
])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.start('gc', 1.0, {'usedHeapSize': 1000}),
|
||||
normEvents.end('gc', 2.0, {'usedHeapSize': 0, 'majorGc': true}),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
['RecalculateStyles', 'Layout', 'UpdateLayerTree', 'Paint'].forEach((recordType) => {
|
||||
it(`should report ${recordType} as "render"`,
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([
|
||||
chromeTimelineEvents.start(recordType, 1234),
|
||||
chromeTimelineEvents.end(recordType, 2345)
|
||||
])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.start('render', 1.234),
|
||||
normEvents.end('render', 2.345),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('should ignore FunctionCalls from webdriver',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([chromeTimelineEvents.start(
|
||||
'FunctionCall', 0, {'data': {'scriptName': 'InjectedScript'}})])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
});
|
||||
|
||||
describe('readPerfLog Chrome45', () => {
|
||||
it('should normalize times to ms and forward ph and pid event properties',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension(
|
||||
[chromeTimelineV8Events.complete('FunctionCall', 1100, 5500, null)],
|
||||
CHROME45_USER_AGENT)
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.complete('script', 1.1, 5.5, null),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should normalize "tdur" to "dur"',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
var event: any = chromeTimelineV8Events.create('X', 'FunctionCall', 1100, null);
|
||||
event['tdur'] = 5500;
|
||||
createExtension([event], CHROME45_USER_AGENT).readPerfLog().then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.complete('script', 1.1, 5.5, null),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report FunctionCall events as "script"',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([chromeTimelineV8Events.start('FunctionCall', 0)], CHROME45_USER_AGENT)
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.start('script', 0),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report minor gc', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension(
|
||||
[
|
||||
chromeTimelineV8Events.start('MinorGC', 1000, {'usedHeapSizeBefore': 1000}),
|
||||
chromeTimelineV8Events.end('MinorGC', 2000, {'usedHeapSizeAfter': 0}),
|
||||
],
|
||||
CHROME45_USER_AGENT)
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events.length).toEqual(2);
|
||||
expect(events[0]).toEqual(
|
||||
normEvents.start('gc', 1.0, {'usedHeapSize': 1000, 'majorGc': false}));
|
||||
expect(events[1]).toEqual(
|
||||
normEvents.end('gc', 2.0, {'usedHeapSize': 0, 'majorGc': false}));
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report major gc', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension(
|
||||
[
|
||||
chromeTimelineV8Events.start('MajorGC', 1000, {'usedHeapSizeBefore': 1000}),
|
||||
chromeTimelineV8Events.end('MajorGC', 2000, {'usedHeapSizeAfter': 0}),
|
||||
],
|
||||
CHROME45_USER_AGENT)
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events.length).toEqual(2);
|
||||
expect(events[0]).toEqual(
|
||||
normEvents.start('gc', 1.0, {'usedHeapSize': 1000, 'majorGc': true}));
|
||||
expect(events[1]).toEqual(
|
||||
normEvents.end('gc', 2.0, {'usedHeapSize': 0, 'majorGc': true}));
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
['Layout', 'UpdateLayerTree', 'Paint'].forEach((recordType) => {
|
||||
it(`should report ${recordType} as "render"`,
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension(
|
||||
[
|
||||
chrome45TimelineEvents.start(recordType, 1234),
|
||||
chrome45TimelineEvents.end(recordType, 2345)
|
||||
],
|
||||
CHROME45_USER_AGENT)
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.start('render', 1.234),
|
||||
normEvents.end('render', 2.345),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it(`should report UpdateLayoutTree as "render"`,
|
||||
['Layout', 'UpdateLayerTree', 'Paint'].forEach((recordType) => {
|
||||
it(`should report ${recordType} as "render"`,
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension(
|
||||
[
|
||||
chromeBlinkTimelineEvents.start('UpdateLayoutTree', 1234),
|
||||
chromeBlinkTimelineEvents.end('UpdateLayoutTree', 2345)
|
||||
],
|
||||
CHROME45_USER_AGENT)
|
||||
chrome45TimelineEvents.start(recordType, 1234),
|
||||
chrome45TimelineEvents.end(recordType, 2345)
|
||||
], )
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
|
@ -320,70 +173,82 @@ export function main() {
|
|||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
|
||||
it('should ignore FunctionCalls from webdriver',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([chromeTimelineV8Events.start(
|
||||
'FunctionCall', 0, {'data': {'scriptName': 'InjectedScript'}})])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should ignore FunctionCalls with empty scriptName',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension(
|
||||
[chromeTimelineV8Events.start('FunctionCall', 0, {'data': {'scriptName': ''}})])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report navigationStart',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension(
|
||||
[chromeBlinkUserTimingEvents.start('navigationStart', 1234)], CHROME45_USER_AGENT)
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([normEvents.start('navigationStart', 1.234)]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report receivedData', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension(
|
||||
[chrome45TimelineEvents.instant(
|
||||
'ResourceReceivedData', 1234, {'data': {'encodedDataLength': 987}})],
|
||||
CHROME45_USER_AGENT)
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual(
|
||||
[normEvents.instant('receivedData', 1.234, {'encodedDataLength': 987})]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report sendRequest', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension(
|
||||
[chrome45TimelineEvents.instant(
|
||||
'ResourceSendRequest', 1234,
|
||||
{'data': {'url': 'http://here', 'requestMethod': 'GET'}})],
|
||||
CHROME45_USER_AGENT)
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([normEvents.instant(
|
||||
'sendRequest', 1.234, {'url': 'http://here', 'method': 'GET'})]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it(`should report UpdateLayoutTree as "render"`,
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension(
|
||||
[
|
||||
chromeBlinkTimelineEvents.start('UpdateLayoutTree', 1234),
|
||||
chromeBlinkTimelineEvents.end('UpdateLayoutTree', 2345)
|
||||
], )
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
normEvents.start('render', 1.234),
|
||||
normEvents.end('render', 2.345),
|
||||
]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
|
||||
it('should ignore FunctionCalls from webdriver',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([chromeTimelineV8Events.start(
|
||||
'FunctionCall', 0, {'data': {'scriptName': 'InjectedScript'}})])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should ignore FunctionCalls with empty scriptName',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension(
|
||||
[chromeTimelineV8Events.start('FunctionCall', 0, {'data': {'scriptName': ''}})])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report navigationStart',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([chromeBlinkUserTimingEvents.start('navigationStart', 1234)])
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([normEvents.start('navigationStart', 1.234)]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report receivedData', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([chrome45TimelineEvents.instant(
|
||||
'ResourceReceivedData', 1234, {'data': {'encodedDataLength': 987}})], )
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual(
|
||||
[normEvents.instant('receivedData', 1.234, {'encodedDataLength': 987})]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should report sendRequest', inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
createExtension([chrome45TimelineEvents.instant(
|
||||
'ResourceSendRequest', 1234,
|
||||
{'data': {'url': 'http://here', 'requestMethod': 'GET'}})], )
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([normEvents.instant(
|
||||
'sendRequest', 1.234, {'url': 'http://here', 'method': 'GET'})]);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
||||
describe('readPerfLog (common)', () => {
|
||||
|
||||
it('should execute a dummy script before reading them',
|
||||
|
@ -404,8 +269,7 @@ export function main() {
|
|||
[
|
||||
chromeTimelineEvents.start(recordType, 1234),
|
||||
chromeTimelineEvents.end(recordType, 2345)
|
||||
],
|
||||
CHROME45_USER_AGENT)
|
||||
], )
|
||||
.readPerfLog()
|
||||
.then((events) => {
|
||||
expect(events).toEqual([
|
||||
|
|
Loading…
Reference in New Issue