chore(trace-viewer): more clear classification of trace contexts (#30737)
This commit is contained in:
parent
a50cd30519
commit
00bf7ea815
|
|
@ -19,7 +19,7 @@ import type { ResourceSnapshot } from '@trace/snapshot';
|
||||||
import type * as trace from '@trace/trace';
|
import type * as trace from '@trace/trace';
|
||||||
|
|
||||||
export type ContextEntry = {
|
export type ContextEntry = {
|
||||||
isPrimary: boolean;
|
origin: 'testRunner'|'library';
|
||||||
traceUrl: string;
|
traceUrl: string;
|
||||||
startTime: number;
|
startTime: number;
|
||||||
endTime: number;
|
endTime: number;
|
||||||
|
|
@ -55,7 +55,7 @@ export type ActionEntry = trace.ActionTraceEvent & {
|
||||||
|
|
||||||
export function createEmptyContext(): ContextEntry {
|
export function createEmptyContext(): ContextEntry {
|
||||||
return {
|
return {
|
||||||
isPrimary: false,
|
origin: 'testRunner',
|
||||||
traceUrl: '',
|
traceUrl: '',
|
||||||
startTime: Number.MAX_SAFE_INTEGER,
|
startTime: Number.MAX_SAFE_INTEGER,
|
||||||
endTime: 0,
|
endTime: 0,
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ export class TraceModernizer {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case 'context-options': {
|
case 'context-options': {
|
||||||
this._version = event.version;
|
this._version = event.version;
|
||||||
contextEntry.isPrimary = true;
|
contextEntry.origin = 'library';
|
||||||
contextEntry.browserName = event.browserName;
|
contextEntry.browserName = event.browserName;
|
||||||
contextEntry.channel = event.channel;
|
contextEntry.channel = event.channel;
|
||||||
contextEntry.title = event.title;
|
contextEntry.title = event.title;
|
||||||
|
|
|
||||||
|
|
@ -80,16 +80,16 @@ export class MultiTraceModel {
|
||||||
|
|
||||||
constructor(contexts: ContextEntry[]) {
|
constructor(contexts: ContextEntry[]) {
|
||||||
contexts.forEach(contextEntry => indexModel(contextEntry));
|
contexts.forEach(contextEntry => indexModel(contextEntry));
|
||||||
const primaryContext = contexts.find(context => context.isPrimary);
|
const libraryContext = contexts.find(context => context.origin === 'library');
|
||||||
|
|
||||||
this.browserName = primaryContext?.browserName || '';
|
this.browserName = libraryContext?.browserName || '';
|
||||||
this.sdkLanguage = primaryContext?.sdkLanguage;
|
this.sdkLanguage = libraryContext?.sdkLanguage;
|
||||||
this.channel = primaryContext?.channel;
|
this.channel = libraryContext?.channel;
|
||||||
this.testIdAttributeName = primaryContext?.testIdAttributeName;
|
this.testIdAttributeName = libraryContext?.testIdAttributeName;
|
||||||
this.platform = primaryContext?.platform || '';
|
this.platform = libraryContext?.platform || '';
|
||||||
this.title = primaryContext?.title || '';
|
this.title = libraryContext?.title || '';
|
||||||
this.options = primaryContext?.options || {};
|
this.options = libraryContext?.options || {};
|
||||||
// Next call updates all timestamps for all events in non-primary contexts, so it must be done first.
|
// Next call updates all timestamps for all events in library contexts, so it must be done first.
|
||||||
this.actions = mergeActionsAndUpdateTiming(contexts);
|
this.actions = mergeActionsAndUpdateTiming(contexts);
|
||||||
this.pages = ([] as PageEntry[]).concat(...contexts.map(c => c.pages));
|
this.pages = ([] as PageEntry[]).concat(...contexts.map(c => c.pages));
|
||||||
this.wallTime = contexts.map(c => c.wallTime).reduce((prev, cur) => Math.min(prev || Number.MAX_VALUE, cur!), Number.MAX_VALUE);
|
this.wallTime = contexts.map(c => c.wallTime).reduce((prev, cur) => Math.min(prev || Number.MAX_VALUE, cur!), Number.MAX_VALUE);
|
||||||
|
|
@ -99,7 +99,7 @@ export class MultiTraceModel {
|
||||||
this.stdio = ([] as trace.StdioTraceEvent[]).concat(...contexts.map(c => c.stdio));
|
this.stdio = ([] as trace.StdioTraceEvent[]).concat(...contexts.map(c => c.stdio));
|
||||||
this.errors = ([] as trace.ErrorTraceEvent[]).concat(...contexts.map(c => c.errors));
|
this.errors = ([] as trace.ErrorTraceEvent[]).concat(...contexts.map(c => c.errors));
|
||||||
this.hasSource = contexts.some(c => c.hasSource);
|
this.hasSource = contexts.some(c => c.hasSource);
|
||||||
this.hasStepData = contexts.some(context => !context.isPrimary);
|
this.hasStepData = contexts.some(context => context.origin === 'testRunner');
|
||||||
this.resources = [...contexts.map(c => c.resources)].flat();
|
this.resources = [...contexts.map(c => c.resources)].flat();
|
||||||
|
|
||||||
this.events.sort((a1, a2) => a1.time - a2.time);
|
this.events.sort((a1, a2) => a1.time - a2.time);
|
||||||
|
|
@ -212,24 +212,24 @@ function makeCallIdsUniqueAcrossTraceFiles(contexts: ContextEntry[], traceFileId
|
||||||
function mergeActionsAndUpdateTimingSameTrace(contexts: ContextEntry[]) {
|
function mergeActionsAndUpdateTimingSameTrace(contexts: ContextEntry[]) {
|
||||||
const map = new Map<string, ActionTraceEventInContext>();
|
const map = new Map<string, ActionTraceEventInContext>();
|
||||||
|
|
||||||
const primaryContexts = contexts.filter(context => context.isPrimary);
|
const libraryContexts = contexts.filter(context => context.origin === 'library');
|
||||||
const nonPrimaryContexts = contexts.filter(context => !context.isPrimary);
|
const testRunnerContexts = contexts.filter(context => context.origin === 'testRunner');
|
||||||
|
|
||||||
for (const context of primaryContexts) {
|
for (const context of libraryContexts) {
|
||||||
for (const action of context.actions)
|
for (const action of context.actions)
|
||||||
map.set(`${action.apiName}@${action.wallTime}`, { ...action, context });
|
map.set(`${action.apiName}@${action.wallTime}`, { ...action, context });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protocol call aka isPrimary contexts have startTime/endTime as server-side times.
|
// Protocol call aka library contexts have startTime/endTime as server-side times.
|
||||||
// Step aka non-isPrimary contexts have startTime/endTime are client-side times.
|
// Step aka test runner contexts have startTime/endTime as client-side times.
|
||||||
// Adjust startTime/endTime on the primary contexts to align them with the test
|
// Adjust startTime/endTime on the library contexts to align them with the test
|
||||||
// runner steps.
|
// runner steps.
|
||||||
const delta = monotonicTimeDeltaBetweenLibraryAndRunner(nonPrimaryContexts, map);
|
const delta = monotonicTimeDeltaBetweenLibraryAndRunner(testRunnerContexts, map);
|
||||||
if (delta)
|
if (delta)
|
||||||
adjustMonotonicTime(primaryContexts, delta);
|
adjustMonotonicTime(libraryContexts, delta);
|
||||||
|
|
||||||
const nonPrimaryIdToPrimaryId = new Map<string, string>();
|
const nonPrimaryIdToPrimaryId = new Map<string, string>();
|
||||||
for (const context of nonPrimaryContexts) {
|
for (const context of testRunnerContexts) {
|
||||||
for (const action of context.actions) {
|
for (const action of context.actions) {
|
||||||
const key = `${action.apiName}@${action.wallTime}`;
|
const key = `${action.apiName}@${action.wallTime}`;
|
||||||
const existing = map.get(key);
|
const existing = map.get(key);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue