Skip to content

Commit

Permalink
[FSA API] Enable all-sync surface for SyncAccessHandle.
Browse files Browse the repository at this point in the history
I2S: https://groups.google.com/a/chromium.org/g/blink-dev/c/UzGXhVEFpwU

Bug: 1338340
Change-Id: I066d304a1ae6ecf98c90553bc93f75e45952cdb1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3868249
Reviewed-by: Hayato Ito <[email protected]>
Commit-Queue: Daseul Lee <[email protected]>
Reviewed-by: Austin Sullivan <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1062802}
  • Loading branch information
dslee414 authored and chromium-wpt-export-bot committed Oct 24, 2022
1 parent aa5e7a3 commit 2fcf086
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 146 deletions.
2 changes: 1 addition & 1 deletion file-system-access/resources/message-target.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ function add_message_event_handlers(receiver, target, target_origin) {
let success = true;
try {
const access_handle = await message_data.file_handle.createSyncAccessHandle();
await access_handle.close();
access_handle.close();
} catch (error) {
success = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ directory_test(async (t, root_dir) => {
await promise_rejects_dom(
t, 'NoModificationAllowedError', fileHandle.createSyncAccessHandle());

await syncHandle1.close();
syncHandle1.close();
const syncHandle2 = await fileHandle.createSyncAccessHandle();
await syncHandle2.close();
syncHandle2.close();
}, 'There can only be one open access handle at any given time');

directory_test(async (t, root_dir) => {
Expand All @@ -26,9 +26,9 @@ directory_test(async (t, root_dir) => {
await promise_rejects_dom(
t, 'NoModificationAllowedError', barFileHandle.createSyncAccessHandle());

await barSyncHandle1.close();
barSyncHandle1.close();
const barSyncHandle2 = await barFileHandle.createSyncAccessHandle();
await barSyncHandle2.close();
barSyncHandle2.close();
}, 'An access handle from one file does not interfere with the creation of an' +
' access handle on another file');

Expand Down Expand Up @@ -62,8 +62,7 @@ directory_test(async (t, root_dir) => {
const syncHandle = await fileHandle.createSyncAccessHandle();
await promise_rejects_dom(
t, 'NoModificationAllowedError', fileHandle.createWritable());

await syncHandle.close();
syncHandle.close();
const writable = await fileHandle.createWritable();
await writable.close();
}, 'Writable streams cannot be created if there is an open access handle');
Expand All @@ -82,7 +81,7 @@ directory_test(async (t, root_dir) => {

await writable2.close();
const syncHandle = await fileHandle.createSyncAccessHandle();
await syncHandle.close();
syncHandle.close();
}, 'Access handles cannot be created if there are open Writable streams');

done();
110 changes: 30 additions & 80 deletions fs/FileSystemSyncAccessHandle-close.https.tentative.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,89 +2,39 @@ importScripts("/resources/testharness.js");
importScripts('resources/sync-access-handle-test.js');

'use strict';

sync_access_handle_test(async (testCase, handle) => {
assert_equals(await handle.close(), undefined);

assert_equals(await handle.close(), undefined);
sync_access_handle_test((t, handle) => {
assert_equals(handle.close(), undefined);
assert_equals(handle.close(), undefined);
}, 'SyncAccessHandle.close is idempotent');

sync_access_handle_test(async (testCase, handle) => {
const closePromise = handle.close();

assert_equals(await handle.close(), undefined);
assert_equals(await closePromise, undefined);
}, 'SyncAccessHandle.close is idempotent when called immediately');

sync_access_handle_test(async (testCase, handle) => {
assert_equals(await handle.close(), undefined);

sync_access_handle_test((t, handle) => {
assert_equals(handle.close(), undefined);
const readBuffer = new Uint8Array(4);
assert_throws_dom('InvalidStateError', () => handle.read(readBuffer, {at: 0}));
}, 'SyncAccessHandle.read fails after SyncAccessHandle.close settles');

sync_access_handle_test(async (testCase, handle) => {
const closePromise = handle.close();

const readBuffer = new Uint8Array(4);
assert_throws_dom('InvalidStateError', () => handle.read(readBuffer, {at: 0}));
assert_equals(await closePromise, undefined);
}, 'SyncAccessHandle.read fails immediately after calling SyncAccessHandle.close');

sync_access_handle_test(async (testCase, handle) => {
assert_equals(await handle.close(), undefined);

const writeBuffer = new Uint8Array(4);
writeBuffer.set([96, 97, 98, 99]);
assert_throws_dom('InvalidStateError', () => handle.write(writeBuffer, {at: 0}));
}, 'SyncAccessHandle.write fails after SyncAccessHandle.close settles');

sync_access_handle_test(async (testCase, handle) => {
const closePromise = handle.close();
assert_throws_dom(
'InvalidStateError', () => handle.read(readBuffer, {at: 0}));
}, 'SyncAccessHandle.read fails after SyncAccessHandle.close');

sync_access_handle_test((t, handle) => {
assert_equals(handle.close(), undefined);
const writeBuffer = new Uint8Array(4);
writeBuffer.set([96, 97, 98, 99]);
assert_throws_dom('InvalidStateError', () => handle.write(writeBuffer, {at: 0}));
assert_equals(await closePromise, undefined);
}, 'SyncAccessHandle.write fails immediately after calling SyncAccessHandle.close');

sync_access_handle_test(async (testCase, handle) => {
assert_equals(await handle.close(), undefined);

await promise_rejects_dom(testCase, 'InvalidStateError', handle.flush());
}, 'SyncAccessHandle.flush fails after SyncAccessHandle.close settles');

sync_access_handle_test(async (testCase, handle) => {
const closePromise = handle.close();

await promise_rejects_dom(testCase, 'InvalidStateError', handle.flush());
assert_equals(await closePromise, undefined);
}, 'SyncAccessHandle.flush fails immediately after calling SyncAccessHandle.close');

sync_access_handle_test(async (testCase, handle) => {
assert_equals(await handle.close(), undefined);

await promise_rejects_dom(testCase, 'InvalidStateError', handle.getSize());
}, 'SyncAccessHandle.getSize fails after SyncAccessHandle.close settles');

sync_access_handle_test(async (testCase, handle) => {
const closePromise = handle.close();

await promise_rejects_dom(testCase, 'InvalidStateError', handle.getSize());
assert_equals(await closePromise, undefined);
}, 'SyncAccessHandle.getSize fails immediately after calling SyncAccessHandle.close');

sync_access_handle_test(async (testCase, handle) => {
assert_equals(await handle.close(), undefined);

await promise_rejects_dom(testCase, 'InvalidStateError', handle.truncate(4));
}, 'SyncAccessHandle.truncate fails after SyncAccessHandle.close settles');

sync_access_handle_test(async (testCase, handle) => {
const closePromise = handle.close();

await promise_rejects_dom(testCase, 'InvalidStateError', handle.truncate(4));
assert_equals(await closePromise, undefined);
}, 'SyncAccessHandle.truncate fails immediately after calling SyncAccessHandle.close');

done();
assert_throws_dom(
'InvalidStateError', () => handle.write(writeBuffer, {at: 0}));
}, 'SyncAccessHandle.write fails after SyncAccessHandle.close');

sync_access_handle_test((t, handle) => {
assert_equals(handle.close(), undefined);
assert_throws_dom('InvalidStateError', () => handle.flush());
}, 'SyncAccessHandle.flush fails after SyncAccessHandle.close');

sync_access_handle_test((t, handle) => {
assert_equals(handle.close(), undefined);
assert_throws_dom('InvalidStateError', () => handle.getSize());
}, 'SyncAccessHandle.getSize fails after SyncAccessHandle.close');

sync_access_handle_test((t, handle) => {
assert_equals(handle.close(), undefined);
assert_throws_dom('InvalidStateError', () => handle.truncate(4));
}, 'SyncAccessHandle.truncate fails after SyncAccessHandle.handle.close');

done();
30 changes: 5 additions & 25 deletions fs/FileSystemSyncAccessHandle-flush.https.tentative.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ importScripts('resources/sync-access-handle-test.js');

'use strict';

sync_access_handle_test(async (t, handle) => {
await handle.flush();
sync_access_handle_test((t, handle) => {
handle.flush();
}, 'Test flush on an empty file.');

sync_access_handle_test(async (t, handle) => {
sync_access_handle_test((t, handle) => {
if (!('TextEncoder' in self)) {
return;
}
Expand All @@ -17,33 +17,13 @@ sync_access_handle_test(async (t, handle) => {
const text = 'Hello Storage Foundation';
const writeBuffer = new TextEncoder().encode(text);
handle.write(writeBuffer, {at: 0});
await handle.flush();
handle.flush();
let readBuffer = new Uint8Array(text.length);
handle.read(readBuffer, {at: 0});
assert_equals(
text, new TextDecoder().decode(readBuffer),
'Check that the written bytes and the read bytes match');
},
'SyncAccessHandle.read returns bytes written by SyncAccessHandle.write' +
}, 'SyncAccessHandle.read returns bytes written by SyncAccessHandle.write' +
' after SyncAccessHandle.flush');

sync_access_handle_test(async (testCase, handle) => {
const flushPromise = handle.flush();
const readBuffer = new Uint8Array(4);
assert_throws_dom(
'InvalidStateError', () => handle.read(readBuffer, {at: 0}));
assert_equals(await flushPromise, undefined);
},
'SyncAccessHandle.read fails when there is a pending SyncAccessHandle.flush');

sync_access_handle_test(async (testCase, handle) => {
const flushPromise = handle.flush();
const writeBuffer = new Uint8Array(4);
writeBuffer.set([96, 97, 98, 99]);
assert_throws_dom(
'InvalidStateError', () => handle.write(writeBuffer, {at: 0}));
assert_equals(await flushPromise, undefined);
},
'SyncAccessHandle.write fails when there is a pending SyncAccessHandle.flush');

done();
15 changes: 5 additions & 10 deletions fs/FileSystemSyncAccessHandle-getSize.https.tentative.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,19 @@ importScripts('resources/sync-access-handle-test.js');

'use strict';

sync_access_handle_test(async (testCase, handle) => {
assert_equals(await handle.getSize(), 0);
sync_access_handle_test((t, handle) => {
assert_equals(handle.getSize(), 0);
const bufferSize = 4;
const writeBuffer = new Uint8Array(bufferSize);
writeBuffer.set([96, 97, 98, 99]);
handle.write(writeBuffer, {at: 0});
assert_equals(await handle.getSize(), bufferSize);
assert_equals(handle.getSize(), bufferSize);
let offset = 3;
handle.write(writeBuffer, {at: offset});
assert_equals(await handle.getSize(), bufferSize + offset);
assert_equals(handle.getSize(), bufferSize + offset);
offset = 10;
handle.write(writeBuffer, {at: offset});
assert_equals(await handle.getSize(), bufferSize + offset);
assert_equals(handle.getSize(), bufferSize + offset);
}, 'test SyncAccessHandle.getSize after SyncAccessHandle.write');

sync_access_handle_test(async (testCase, handle) => {
const getSizePromise = handle.getSize();
await promise_rejects_dom(testCase, 'InvalidStateError', handle.getSize());
assert_equals(await getSizePromise, 0);
}, 'test createSyncAccessHandle.getSize with pending operation');
done();
38 changes: 18 additions & 20 deletions fs/FileSystemSyncAccessHandle-truncate.https.tentative.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,38 @@ importScripts('resources/sync-access-handle-test.js');

'use strict';

sync_access_handle_test(async (testCase, handle) => {
const getSizePromise = handle.getSize();
await promise_rejects_dom(testCase, 'InvalidStateError', handle.truncate(4));
assert_equals(await getSizePromise, 0);
}, 'test createSyncAccessHandle.truncate with pending operation');

sync_access_handle_test(async (testCase, handle) => {
await handle.truncate(4);
assert_equals(await handle.getSize(), 4);

await handle.truncate(2);
assert_equals(await handle.getSize(), 2);

await handle.truncate(7);
assert_equals(await handle.getSize(), 7);

await promise_rejects_js(testCase, TypeError, handle.truncate(-4));
sync_access_handle_test((t, handle) => {
// Without this assertion, the test passes even if truncate is not defined.
assert_implements(handle.truncate,
"SyncAccessHandle.truncate is not implemented.");

handle.truncate(4);
assert_equals(handle.getSize(), 4);
handle.truncate(2);
assert_equals(handle.getSize(), 2);
handle.truncate(7);
assert_equals(handle.getSize(), 7);
handle.truncate(0);
assert_equals(handle.getSize(), 0);
assert_throws_js(TypeError, () => handle.truncate(-4));
}, 'test SyncAccessHandle.truncate with different sizes');

sync_access_handle_test(async (testCase, handle) => {
sync_access_handle_test((t, handle) => {
const writeBuffer = new Uint8Array(4);
writeBuffer.set([96, 97, 98, 99]);
handle.write(writeBuffer, {at: 0});

await handle.truncate(2);
handle.truncate(2);
let readBuffer = new Uint8Array(6);
assert_equals(2, handle.read(readBuffer, {at: 0}));
let expected = new Uint8Array(6);
expected.set([96, 97, 0, 0, 0, 0]);
assert_array_equals(expected, readBuffer);

// Resize the file to 6, expect that everything beyond the old size is '0'.
await handle.truncate(6);
handle.truncate(6);
assert_equals(6, handle.read(readBuffer, {at: 0}));
assert_array_equals(expected, readBuffer);
}, 'test SyncAccessHandle.truncate after SyncAccessHandle.write');

done();
2 changes: 1 addition & 1 deletion fs/resources/message-target.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function add_message_event_handlers(receiver, target, target_origin) {
try {
const access_handle = await message_data.file_handle
.createSyncAccessHandle({mode: "in-place"});
await access_handle.close();
access_handle.close();
} catch (error) {
success = false;
}
Expand Down
4 changes: 2 additions & 2 deletions fs/resources/sync-access-handle-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function sync_access_handle_test(test, description) {
const dir = await navigator.storage.getDirectory();
const fileHandle = await dir.getFileHandle('OPFS.test', {create: true});
const syncHandle = await fileHandle.createSyncAccessHandle();
await test(t, syncHandle);
await syncHandle.close();
test(t, syncHandle);
syncHandle.close();
}, description);
}

0 comments on commit 2fcf086

Please sign in to comment.