diff options
Diffstat (limited to 'dom/webgpu/tests/cts/checkout/src/common/internal/logging')
4 files changed, 69 insertions, 17 deletions
diff --git a/dom/webgpu/tests/cts/checkout/src/common/internal/logging/log_message.ts b/dom/webgpu/tests/cts/checkout/src/common/internal/logging/log_message.ts index ee006cdeb3..b01c08b56e 100644 --- a/dom/webgpu/tests/cts/checkout/src/common/internal/logging/log_message.ts +++ b/dom/webgpu/tests/cts/checkout/src/common/internal/logging/log_message.ts @@ -1,19 +1,36 @@ import { ErrorWithExtra } from '../../util/util.js'; import { extractImportantStackTrace } from '../stack.js'; +import { LogMessageRawData } from './result.js'; + export class LogMessageWithStack extends Error { readonly extra: unknown; private stackHiddenMessage: string | undefined = undefined; - constructor(name: string, ex: Error | ErrorWithExtra) { - super(ex.message); + /** + * Wrap an Error (which was created to capture the stack at that point) into a + * LogMessageWithStack (which has extra stuff for good log messages). + * + * The original `ex.name` is ignored. Inclued it in the `name` parameter if it + * needs to be preserved. + */ + static wrapError(name: string, ex: Error | ErrorWithExtra) { + return new LogMessageWithStack({ + name, + message: ex.message, + stackHiddenMessage: undefined, + stack: ex.stack, + extra: 'extra' in ex ? ex.extra : undefined, + }); + } - this.name = name; - this.stack = ex.stack; - if ('extra' in ex) { - this.extra = ex.extra; - } + constructor(o: LogMessageRawData) { + super(o.message); + this.name = o.name; + this.stackHiddenMessage = o.stackHiddenMessage; + this.stack = o.stack; + this.extra = o.extra; } /** Set a flag so the stack is not printed in toJSON(). */ @@ -21,6 +38,11 @@ export class LogMessageWithStack extends Error { this.stackHiddenMessage ??= stackHiddenMessage; } + /** + * Print the message for display. + * + * Note: This is toJSON instead of toString to make it easy to save logs using JSON.stringify. + */ toJSON(): string { let m = this.name; if (this.message) m += ': ' + this.message; @@ -33,6 +55,21 @@ export class LogMessageWithStack extends Error { } return m; } + + /** + * Flatten the message for sending over a message channel. + * + * Note `extra` may get mangled by postMessage. + */ + toRawData(): LogMessageRawData { + return { + name: this.name, + message: this.message, + stackHiddenMessage: this.stackHiddenMessage, + stack: this.stack, + extra: this.extra, + }; + } } /** diff --git a/dom/webgpu/tests/cts/checkout/src/common/internal/logging/logger.ts b/dom/webgpu/tests/cts/checkout/src/common/internal/logging/logger.ts index e4526cff54..6b95f48b74 100644 --- a/dom/webgpu/tests/cts/checkout/src/common/internal/logging/logger.ts +++ b/dom/webgpu/tests/cts/checkout/src/common/internal/logging/logger.ts @@ -1,3 +1,4 @@ +import { globalTestConfig } from '../../framework/test_config.js'; import { version } from '../version.js'; import { LiveTestCaseResult } from './result.js'; @@ -6,8 +7,6 @@ import { TestCaseRecorder } from './test_case_recorder.js'; export type LogResults = Map<string, LiveTestCaseResult>; export class Logger { - static globalDebugMode: boolean = false; - readonly overriddenDebugMode: boolean | undefined; readonly results: LogResults = new Map(); @@ -19,7 +18,7 @@ export class Logger { const result: LiveTestCaseResult = { status: 'running', timems: -1 }; this.results.set(name, result); return [ - new TestCaseRecorder(result, this.overriddenDebugMode ?? Logger.globalDebugMode), + new TestCaseRecorder(result, this.overriddenDebugMode ?? globalTestConfig.enableDebugLogs), result, ]; } diff --git a/dom/webgpu/tests/cts/checkout/src/common/internal/logging/result.ts b/dom/webgpu/tests/cts/checkout/src/common/internal/logging/result.ts index 3318e8c937..9968f3d359 100644 --- a/dom/webgpu/tests/cts/checkout/src/common/internal/logging/result.ts +++ b/dom/webgpu/tests/cts/checkout/src/common/internal/logging/result.ts @@ -14,8 +14,24 @@ export interface LiveTestCaseResult extends TestCaseResult { logs?: LogMessageWithStack[]; } +/** + * Raw data for a test log message. + * + * This form is sendable over a message channel, except `extra` may get mangled. + */ +export interface LogMessageRawData { + name: string; + message: string; + stackHiddenMessage: string | undefined; + stack: string | undefined; + extra: unknown; +} + +/** + * Test case results in a form sendable over a message channel. + * + * Note `extra` may get mangled by postMessage. + */ export interface TransferredTestCaseResult extends TestCaseResult { - // When transferred from a worker, a LogMessageWithStack turns into a generic Error - // (its prototype gets lost and replaced with Error). - logs?: Error[]; + logs?: LogMessageRawData[]; } diff --git a/dom/webgpu/tests/cts/checkout/src/common/internal/logging/test_case_recorder.ts b/dom/webgpu/tests/cts/checkout/src/common/internal/logging/test_case_recorder.ts index f5c3252b5c..78f625269e 100644 --- a/dom/webgpu/tests/cts/checkout/src/common/internal/logging/test_case_recorder.ts +++ b/dom/webgpu/tests/cts/checkout/src/common/internal/logging/test_case_recorder.ts @@ -45,8 +45,6 @@ export class TestCaseRecorder { private logs: LogMessageWithStack[] = []; private logLinesAtCurrentSeverity = 0; private debugging = false; - /** Used to dedup log messages which have identical stacks. */ - private messagesForPreviouslySeenStacks = new Map<string, LogMessageWithStack>(); constructor(result: LiveTestCaseResult, debugging: boolean) { this.result = result; @@ -143,13 +141,15 @@ export class TestCaseRecorder { this.skipped(ex); return; } - this.logImpl(LogSeverity.ThrewException, 'EXCEPTION', ex); + // logImpl will discard the original error's ex.name. Preserve it here. + const name = ex instanceof Error ? `EXCEPTION: ${ex.name}` : 'EXCEPTION'; + this.logImpl(LogSeverity.ThrewException, name, ex); } private logImpl(level: LogSeverity, name: string, baseException: unknown): void { assert(baseException instanceof Error, 'test threw a non-Error object'); globalTestConfig.testHeartbeatCallback(); - const logMessage = new LogMessageWithStack(name, baseException); + const logMessage = LogMessageWithStack.wrapError(name, baseException); // Final case status should be the "worst" of all log entries. if (this.inSubCase) { |