Skip to content

Commit

Permalink
Address kainino0x feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
beaufortfrancois committed Mar 6, 2024
1 parent 23f0a47 commit 675f6ad
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 239 deletions.
2 changes: 1 addition & 1 deletion src/common/internal/query/compare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function compareOneLevel(ordering: Ordering, aIsBig: boolean, bIsBig: boolean):
return Ordering.Unordered;
}

function comparePaths(a: readonly string[], b: readonly string[]): Ordering {
export function comparePaths(a: readonly string[], b: readonly string[]): Ordering {
const shorter = Math.min(a.length, b.length);

for (let i = 0; i < shorter; ++i) {
Expand Down
85 changes: 32 additions & 53 deletions src/common/runtime/helper/test_worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,39 @@ import { TestQueryWithExpectation } from '../../internal/query/query.js';

import { CTSOptions, kDefaultCTSOptions } from './options.js';

export class TestDedicatedWorker {
private readonly ctsOptions: CTSOptions;
class TestBaseWorker {
protected readonly ctsOptions: CTSOptions;
protected readonly resolvers = new Map<string, (result: LiveTestCaseResult) => void>();

constructor(worker: CTSOptions['worker'], ctsOptions?: CTSOptions) {
this.ctsOptions = { ...(ctsOptions || kDefaultCTSOptions), ...{ worker } };
}

onmessage(ev: MessageEvent) {
const query: string = ev.data.query;
const result: TransferredTestCaseResult = ev.data.result;
if (result.logs) {
for (const l of result.logs) {
Object.setPrototypeOf(l, LogMessageWithStack.prototype);
}
}
this.resolvers.get(query)!(result as LiveTestCaseResult);

// MAINTENANCE_TODO(kainino0x): update the Logger with this result (or don't have a logger and
// update the entire results JSON somehow at some point).
}
}

export class TestDedicatedWorker extends TestBaseWorker {
private readonly worker: Worker;
private readonly resolvers = new Map<string, (result: LiveTestCaseResult) => void>();

constructor(ctsOptions?: CTSOptions) {
this.ctsOptions = { ...(ctsOptions || kDefaultCTSOptions), ...{ worker: 'dedicated' } };
super('dedicated', ctsOptions);
const selfPath = import.meta.url;
const selfPathDir = selfPath.substring(0, selfPath.lastIndexOf('/'));
const workerPath = selfPathDir + '/test_worker-worker.js';
this.worker = new Worker(workerPath, { type: 'module' });
this.worker.onmessage = ev => {
const query: string = ev.data.query;
const result: TransferredTestCaseResult = ev.data.result;
if (result.logs) {
for (const l of result.logs) {
Object.setPrototypeOf(l, LogMessageWithStack.prototype);
}
}
this.resolvers.get(query)!(result as LiveTestCaseResult);

// MAINTENANCE_TODO(kainino0x): update the Logger with this result (or don't have a logger and
// update the entire results JSON somehow at some point).
};
this.worker.onmessage = ev => this.onmessage(ev);
}

async run(
Expand All @@ -50,32 +59,18 @@ export class TestDedicatedWorker {

export class TestWorker extends TestDedicatedWorker {}

export class TestSharedWorker {
private readonly ctsOptions: CTSOptions;
export class TestSharedWorker extends TestBaseWorker {
private readonly port: MessagePort;
private readonly resolvers = new Map<string, (result: LiveTestCaseResult) => void>();

constructor(ctsOptions?: CTSOptions) {
this.ctsOptions = { ...(ctsOptions || kDefaultCTSOptions), ...{ worker: 'shared' } };
super('shared', ctsOptions);
const selfPath = import.meta.url;
const selfPathDir = selfPath.substring(0, selfPath.lastIndexOf('/'));
const workerPath = selfPathDir + '/test_worker-worker.js';
const worker = new SharedWorker(workerPath, { type: 'module' });
this.port = worker.port;
this.port.start();
this.port.onmessage = ev => {
const query: string = ev.data.query;
const result: TransferredTestCaseResult = ev.data.result;
if (result.logs) {
for (const l of result.logs) {
Object.setPrototypeOf(l, LogMessageWithStack.prototype);
}
}
this.resolvers.get(query)!(result as LiveTestCaseResult);

// MAINTENANCE_TODO(kainino0x): update the Logger with this result (or don't have a logger and
// update the entire results JSON somehow at some point).
};
this.port.onmessage = ev => this.onmessage(ev);
}

async run(
Expand All @@ -95,12 +90,9 @@ export class TestSharedWorker {
}
}

export class TestServiceWorker {
private readonly ctsOptions: CTSOptions;
private readonly resolvers = new Map<string, (result: LiveTestCaseResult) => void>();

export class TestServiceWorker extends TestBaseWorker {
constructor(ctsOptions?: CTSOptions) {
this.ctsOptions = { ...(ctsOptions || kDefaultCTSOptions), ...{ worker: 'service' } };
super('service', ctsOptions);
}

async run(
Expand All @@ -117,20 +109,7 @@ export class TestServiceWorker {
scope: '/',
});
await registration.update();

navigator.serviceWorker.onmessage = ev => {
const query: string = ev.data.query;
const result: TransferredTestCaseResult = ev.data.result;
if (result.logs) {
for (const l of result.logs) {
Object.setPrototypeOf(l, LogMessageWithStack.prototype);
}
}
this.resolvers.get(query)!(result as LiveTestCaseResult);

// MAINTENANCE_TODO(kainino0x): update the Logger with this result (or don't have a logger and
// update the entire results JSON somehow at some point).
};
navigator.serviceWorker.onmessage = ev => this.onmessage(ev);

registration.active?.postMessage({
query,
Expand Down
52 changes: 52 additions & 0 deletions src/common/runtime/helper/wrap_for_worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Fixture } from '../../framework/fixture';
import { globalTestConfig } from '../../framework/test_config.js';
import { Logger } from '../../internal/logging/logger.js';
import { comparePaths, comparePublicParamsPaths, Ordering } from '../../internal/query/compare.js';
import { parseQuery } from '../../internal/query/parseQuery.js';
import { TestQuerySingleCase, TestQueryWithExpectation } from '../../internal/query/query.js';
import { TestGroup } from '../../internal/test_group.js';
import { setDefaultRequestAdapterOptions } from '../../util/navigator_gpu.js';
import { assert } from '../../util/util.js';

import { CTSOptions } from './options.js';

export function wrapTestGroupForWorker(g: TestGroup<Fixture>) {
self.onmessage = async (ev: MessageEvent) => {
const query: string = ev.data.query;
const expectations: TestQueryWithExpectation[] = ev.data.expectations;
const ctsOptions: CTSOptions = ev.data.ctsOptions;

const { debug, unrollConstEvalLoops, powerPreference, compatibility } = ctsOptions;
globalTestConfig.unrollConstEvalLoops = unrollConstEvalLoops;
globalTestConfig.compatibility = compatibility;

Logger.globalDebugMode = debug;
const log = new Logger();

if (powerPreference || compatibility) {
setDefaultRequestAdapterOptions({
...(powerPreference && { powerPreference }),
// MAINTENANCE_TODO: Change this to whatever the option ends up being
...(compatibility && { compatibilityMode: true }),
});
}

const testQuery = parseQuery(query);
assert(testQuery instanceof TestQuerySingleCase);
let testcase = null;
for (const t of g.iterate()) {
if (comparePaths(t.testPath, testQuery.testPathParts) !== Ordering.Equal) {
continue;
}
for (const c of t.iterate(testQuery.params)) {
if (comparePublicParamsPaths(c.id.params, testQuery.params) === Ordering.Equal) {
testcase = c;
}
}
}
assert(!!testcase);
const [rec, result] = log.record(query);
await testcase.run(rec, testQuery, expectations);
ev.source?.postMessage({ query, result });
};
}
55 changes: 2 additions & 53 deletions src/common/tools/gen_listings_and_webworkers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,60 +80,9 @@ export const listing = ${JSON.stringify(listing, undefined, 2)};
// g is a TestGroup<Fixture> object (defined in common/internal/test_group.ts).
import { g } from '${relPathToSuiteRoot}/${entry.file.join('/')}.spec.js';
import { wrapTestGroupForWorker } from '${relPathToSuiteRoot}/../common/runtime/helper/wrap_for_worker.js';
import { globalTestConfig } from '/out/common/framework/test_config.js';
import { Logger } from '/out/common/internal/logging/logger.js';
import { setDefaultRequestAdapterOptions } from '/out/common/util/navigator_gpu.js';
import { parseQuery } from '/out/common/internal/query/parseQuery.js';
import { comparePublicParamsPaths, Ordering } from '/out/common/internal/query/compare.js';
import { assert } from '/out/common/util/util.js';
async function reportTestResults(ev) {
const query = ev.data.query;
const expectations = ev.data.expectations;
const ctsOptions = ev.data.ctsOptions;
const { debug, unrollConstEvalLoops, powerPreference, compatibility } = ctsOptions;
globalTestConfig.unrollConstEvalLoops = unrollConstEvalLoops;
globalTestConfig.compatibility = compatibility;
Logger.globalDebugMode = debug;
const log = new Logger();
if (powerPreference || compatibility) {
setDefaultRequestAdapterOptions({
...(powerPreference && { powerPreference }),
// MAINTENANCE_TODO: Change this to whatever the option ends up being
...(compatibility && { compatibilityMode: true }),
});
}
const testQuerySingleCase = parseQuery(query);
let testcase = null;
for (const t of g.iterate()) {
for (const c of t.iterate(testQuerySingleCase.params)) {
if (comparePublicParamsPaths(c.id.params, testQuerySingleCase.params) === Ordering.Equal) {
testcase = c;
}
}
}
assert(testcase);
const [rec, result] = log.record(query);
await testcase.run(rec, testQuerySingleCase, expectations);
this.postMessage({ query, result });
}
self.onmessage = (ev) => {
void reportTestResults.call(ev.source || self, ev);
};
self.onconnect = (event) => {
const port = event.ports[0];
port.onmessage = (ev) => {
void reportTestResults.call(port, ev);
};
};
wrapTestGroupForWorker(g);
`
);
}
Expand Down
Loading

0 comments on commit 675f6ad

Please sign in to comment.