Files
sousa-gecko/testing/web-platform/tests/webnn/validation_tests/destroyGraph.https.any.js
T
Wei Wang 82479fa066 Bug 2045298 [wpt PR 60418] - [WebNN] Add "webnn" permissions policy feature, a=testonly
Automatic update from web-platform-tests
[WebNN] Add "webnn" permissions policy feature

Implement the "webnn" policy-controlled feature as specified in the
WebNN specification [1]. The default allowlist is 'self', which means
the WebNN API is available to top-level documents and same-origin
iframes by default, but blocked in cross-origin iframes unless
explicitly granted via the Permissions-Policy header or iframe allow
attribute.

When the feature is disabled, navigator.ml.createContext() rejects
with a "SecurityError" DOMException per the spec.

This CL also changes the WebIDL to only expose the WebNN interfaces
to DedicatedWorker and updates related WPTs.

[1] https://www.w3.org/TR/webnn/#permissions-policy-integration

Bug: 502083483
Change-Id: I5c723e0ea03864fd0b122aed8b3d31f602545a2e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7885337
Reviewed-by: Takashi Toyoshima <toyoshim@chromium.org>
Reviewed-by: Bo Liu <boliu@chromium.org>
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Reviewed-by: Kent Tamura <tkent@chromium.org>
Reviewed-by: Steven Holte <holte@chromium.org>
Commit-Queue: Wang, Wei4 <wei4.wang@intel.com>
Cr-Commit-Position: refs/heads/main@{#1642237}

--

wpt-commits: 48d66a5560161cc5b7a372c709964963f62a8e58
wpt-pr: 60418
2026-06-09 18:47:15 +00:00

98 lines
3.0 KiB
JavaScript

// META: timeout=long
// META: title=validation tests for WebNN API MLContext::destroy()
// META: global=window
// META: variant=?cpu
// META: variant=?gpu
// META: variant=?npu
'use strict';
let context;
promise_setup(async () => {
assert_implements(navigator.ml, 'WebNN is not supported');
const contextOptions = {deviceType: location.search.substring(1)};
try {
context = await navigator.ml.createContext(contextOptions);
} catch (e) {
throw new AssertionError(
`Unable to create context for ${variant} variant. ${e}`);
}
}, {explicit_timeout: true});
promise_test(async t => {
const builder = new MLGraphBuilder(context);
const operandType = {dataType: 'float32', shape: [1]};
const input_operand = builder.input('input', operandType);
const const_operand = builder.constant(operandType, Float32Array.from([2]));
const output_operand = builder.mul(input_operand, const_operand);
const graph = await builder.build({'output': output_operand});
graph.destroy();
graph.destroy();
}, 'Graph can be destroyed twice.');
promise_test(async t => {
const builder = new MLGraphBuilder(context);
const operandType = {dataType: 'float32', shape: [1]};
const lhsOperand = builder.input('lhs', operandType);
const rhsOperand = builder.input('rhs', operandType);
const graph =
await builder.build({'output': builder.mul(lhsOperand, rhsOperand)});
const lhsTensor = await context.createTensor(operandType);
const rhsTensor = await context.createTensor(operandType);
const dispatchOutputs = {'output': await context.createTensor(operandType)};
graph.destroy();
assert_throws_dom('InvalidStateError', () => {
context.dispatch(
graph, {
'lhs': lhsTensor,
'rhs': rhsTensor,
},
dispatchOutputs);
});
}, 'Destroyed graph can not dispatch.');
promise_test(async t => {
const builder = new MLGraphBuilder(context);
const operandType = {dataType: 'float32', shape: [1]};
const lhsOperand = builder.input('lhs', operandType);
const rhsOperand = builder.input('rhs', operandType);
const graph =
await builder.build({'output': builder.mul(lhsOperand, rhsOperand)});
const lhsTensor = await context.createTensor({
dataType: 'float32',
shape: [1],
writable: true,
});
const rhsTensor = await context.createTensor({
dataType: 'float32',
shape: [1],
writable: true,
});
const outputTensor = await context.createTensor({
dataType: 'float32',
shape: [1],
readable: true,
});
// Initialize inputs
const inputData = new Float32Array(1).fill(2.0);
context.writeTensor(lhsTensor, inputData);
context.writeTensor(rhsTensor, inputData);
context.dispatch(
graph, {
'lhs': lhsTensor,
'rhs': rhsTensor,
},
{'output': outputTensor});
graph.destroy();
const outputData = await context.readTensor(outputTensor);
assert_array_equals(
new Float32Array(outputData), [4],
'Read tensor data equals expected data.');
}, 'Destroying graph after dispatch() and before readTensor() is OK.');