Bug 1642961 [wpt PR 23941] - [nativeio] NativeIO: Add Rename., a=testonly
authorRichard Stotz <rstz@chromium.org>
Mon, 22 Jun 2020 10:45:01 +0000
changeset 600939 d66ae07454fffe60e879b1b66fd7afdf03f27eca
parent 600938 88fa5bd17cde18067f9ef26b10636a333e119e51
child 600940 ffe6dcb7c6460f0e573a38ec758321493c79d8e4
push id13310
push userffxbld-merge
push dateMon, 29 Jun 2020 14:50:06 +0000
treeherdermozilla-beta@15a59a0afa5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1642961, 23941, 914488, 2228152, 780220
milestone79.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1642961 [wpt PR 23941] - [nativeio] NativeIO: Add Rename., a=testonly Automatic update from web-platform-tests [nativeio] NativeIO: Add Rename. Bug: 914488 Change-Id: I81a96bc4f395d82d7a0c1d804eef25a861eb1fe5 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2228152 Commit-Queue: Richard Stotz <rstz@chromium.org> Reviewed-by: Victor Costan <pwnall@chromium.org> Reviewed-by: Mike West <mkwst@chromium.org> Cr-Commit-Position: refs/heads/master@{#780220} -- wpt-commits: 81785c7e2e7c6ba72fc3996066d4d11761ff0eda wpt-pr: 23941
testing/web-platform/tests/native-io/rename_async_basic.tentative.https.any.js
testing/web-platform/tests/native-io/rename_async_failure_handling.tentative.https.any.js
testing/web-platform/tests/native-io/rename_sync_basic.tentative.https.any.js
testing/web-platform/tests/native-io/rename_sync_failure_handling.tentative.https.any.js
testing/web-platform/tests/native-io/resources/support.js
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/native-io/rename_async_basic.tentative.https.any.js
@@ -0,0 +1,23 @@
+// META: title=NativeIO API: File renaming is reflected in listing.
+// META: global=window,worker
+
+'use strict';
+
+promise_test(async testCase => {
+  const file = await nativeIO.open('test_file');
+  await file.close();
+
+  const fileNamesBeforeRename = await nativeIO.getAll();
+  assert_in_array('test_file', fileNamesBeforeRename);
+
+  await nativeIO.rename('test_file', 'renamed_test_file');
+  testCase.add_cleanup(async () => {
+    await nativeIO.delete('test_file');
+    await nativeIO.delete('renamed_test_file');
+  });
+
+  const fileNamesAfterRename = await nativeIO.getAll();
+  assert_false(fileNamesAfterRename.includes('test_file'));
+  assert_in_array('renamed_test_file', fileNamesAfterRename);
+}, 'nativeIO.getAll returns a file renamed by nativeIO.rename' +
+     ' with its new name.');
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/native-io/rename_async_failure_handling.tentative.https.any.js
@@ -0,0 +1,127 @@
+// META: title=NativeIO API: Failures of rename are properly handled.
+// META: global=window,worker
+// META: script=resources/support.js
+
+'use strict';
+
+promise_test(async testCase => {
+  const file1 = await nativeIO.open('test_file_1');
+  const file2 = await nativeIO.open('test_file_2');
+  testCase.add_cleanup(async () => {
+    await file1.close();
+    await file2.close();
+  });
+
+  const writeSharedArrayBuffer1 = new SharedArrayBuffer(4);
+  const writtenBytes1 = new Uint8Array(writeSharedArrayBuffer1);
+  writtenBytes1.set([64, 65, 66, 67]);
+  const writeSharedArrayBuffer2 = new SharedArrayBuffer(4);
+  const writtenBytes2 = new Uint8Array(writeSharedArrayBuffer2);
+  writtenBytes2.set([96, 97, 98, 99]);
+
+  await file1.write(writtenBytes1, 0);
+  await file2.write(writtenBytes2, 0);
+  await file1.close();
+  await file2.close();
+
+  await promise_rejects_dom(testCase, "UnknownError",
+                            nativeIO.rename('test_file_1', 'test_file_2'));
+
+  const fileNamesAfterRename = await nativeIO.getAll();
+  assert_in_array('test_file_1', fileNamesAfterRename);
+  assert_in_array('test_file_2', fileNamesAfterRename);
+
+  // Make sure that a failed rename does not modify file contents.
+  const file1_after = await nativeIO.open('test_file_1');
+  const file2_after = await nativeIO.open('test_file_2');
+
+  testCase.add_cleanup(async () => {
+    await file1_after.close();
+    await file2_after.close();
+    await nativeIO.delete('test_file_1');
+    await nativeIO.delete('test_file_2');
+  });
+
+  const readSharedArrayBuffer1 = new SharedArrayBuffer(writtenBytes1.length);
+  const readBytes1 = new Uint8Array(readSharedArrayBuffer1);
+  await file1_after.read(readBytes1, 0);
+  const readSharedArrayBuffer2 = new SharedArrayBuffer(writtenBytes2.length);
+  const readBytes2 = new Uint8Array(readSharedArrayBuffer2);
+  await file2_after.read(readBytes2, 0);
+  assert_array_equals(readBytes1, writtenBytes1,
+                      'the bytes read should match the bytes written');
+  assert_array_equals(readBytes2, writtenBytes2,
+                     'the bytes read should match the bytes written');
+}, 'nativeIO.rename does not overwrite an existing file.');
+
+promise_test(async testCase => {
+  const file = await nativeIO.open('test_file');
+  testCase.add_cleanup(async () => {
+    await file.close();
+    await nativeIO.delete('test_file');
+  });
+  await promise_rejects_dom(testCase, "UnknownError",
+                            nativeIO.rename('test_file', 'renamed_test_file'));
+  await file.close();
+
+  const fileNamesAfterRename = await nativeIO.getAll();
+  assert_false(fileNamesAfterRename.includes('renamed_test_file'));
+  assert_in_array('test_file', fileNamesAfterRename);
+}, 'nativeIO.rename does not allow renaming an open file.');
+
+promise_test(async testCase => {
+  testCase.add_cleanup(async () => {
+    await file.close();
+    await nativeIO.delete('test_file');
+    for (let name of await nativeIO.getAll()) {
+      await nativeIO.delete(name);
+    }
+  });
+
+  const file = await nativeIO.open('test_file');
+  await file.close();
+  for (let name of kBadNativeIoNames) {
+    await promise_rejects_js(testCase, TypeError,
+                             nativeIO.rename('test_file', name));
+    await promise_rejects_js(testCase, TypeError,
+                             nativeIO.rename(name, 'test_file_2'));
+  }
+}, 'nativeIO.rename does not allow renaming from or to invalid names.');
+
+promise_test(async testCase => {
+  const closed_file = await nativeIO.open('closed_file');
+  closed_file.close();
+  const opened_file = await nativeIO.open('opened_file');
+  testCase.add_cleanup(async () => {
+    closed_file.close();
+    opened_file.close();
+    await nativeIO.delete('closed_file');
+    await nativeIO.delete('opened_file');
+  });
+
+  // First rename fails, as source is still open.
+  await promise_rejects_dom(testCase, "UnknownError",
+                            nativeIO.rename('opened_file', 'closed_file'));
+  // First rename fails again, as source has not been unlocked.
+  await promise_rejects_dom(testCase, "UnknownError",
+                            nativeIO.rename('opened_file', 'closed_file'));
+}, 'Failed nativeIO.rename does not unlock the source.');
+
+promise_test(async testCase => {
+  const closed_file = await nativeIO.open('closed_file');
+  await closed_file.close();
+  const opened_file = await nativeIO.open('opened_file');
+  testCase.add_cleanup(async () => {
+    await closed_file.close();
+    await opened_file.close();
+    await nativeIO.delete('closed_file');
+    await nativeIO.delete('opened_file');
+  });
+
+  // First rename fails, as destination is still open.
+  await promise_rejects_dom(testCase, "UnknownError",
+                            nativeIO.rename('closed_file', 'opened_file'));
+  // First rename fails again, as destination has not been unlocked.
+  await promise_rejects_dom(testCase, "UnknownError",
+                            nativeIO.rename('closed_file', 'opened_file'));
+}, 'Failed nativeIO.rename does not unlock the destination.');
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/native-io/rename_sync_basic.tentative.https.any.js
@@ -0,0 +1,24 @@
+// META: title=Synchronous NativeIO API: File renaming is reflected in listing.
+// META: global=dedicatedworker
+
+'use strict';
+
+test(testCase => {
+  const file = nativeIO.openSync('test_file');
+  file.close();
+
+  const fileNamesBeforeRename = nativeIO.getAllSync();
+  assert_in_array('test_file', fileNamesBeforeRename);
+
+  nativeIO.renameSync('test_file', 'renamed_test_file');
+  testCase.add_cleanup(() => {
+    file.close();
+    nativeIO.deleteSync('test_file');
+    nativeIO.deleteSync('renamed_test_file');
+  });
+
+  const fileNamesAfterRename = nativeIO.getAllSync();
+  assert_equals(fileNamesAfterRename.indexOf('test_file'), -1);
+  assert_in_array('renamed_test_file', fileNamesAfterRename);
+}, 'nativeIO.getAllSync returns a file renamed' +
+   ' by nativeIOFile.renameSync with its new name.');
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/native-io/rename_sync_failure_handling.tentative.https.any.js
@@ -0,0 +1,118 @@
+// META: title=Synchronous NativeIO API: Failures of rename are properly handled.
+// META: global=dedicatedworker
+// META: script=resources/support.js
+
+'use strict';
+
+test(testCase => {
+  const file1 = nativeIO.openSync('test_file_1');
+  const file2 = nativeIO.openSync('test_file_2');
+  testCase.add_cleanup(() => {
+    file1.close();
+    file2.close();
+  });
+
+  const writtenBytes1 = Uint8Array.from([64, 65, 66, 67]);
+  file1.write(writtenBytes1, 0);
+  const writtenBytes2 = Uint8Array.from([96, 97, 98, 99]);
+  file2.write(writtenBytes2, 0);
+
+  file1.close();
+  file2.close();
+
+  assert_throws_dom("UnknownError",
+                    () => nativeIO.renameSync('test_file_1', 'test_file_2'));
+
+  const fileNamesAfterRename = nativeIO.getAllSync();
+  assert_in_array('test_file_1', fileNamesAfterRename);
+  assert_in_array('test_file_2', fileNamesAfterRename);
+
+  // Make sure that a failed rename does not modify file contents.
+  const file1_after = nativeIO.openSync('test_file_1');
+  const file2_after = nativeIO.openSync('test_file_2');
+
+  testCase.add_cleanup(() => {
+    file1_after.close();
+    file2_after.close();
+    nativeIO.deleteSync('test_file_1');
+    nativeIO.deleteSync('test_file_2');
+  });
+  const readBytes1 = new Uint8Array(writtenBytes1.length);
+  file1_after.read(readBytes1, 0);
+  assert_array_equals(readBytes1, writtenBytes1,
+                      'the bytes read should match the bytes written');
+  const readBytes2 = new Uint8Array(writtenBytes2.length);
+  file2_after.read(readBytes2, 0);
+  assert_array_equals(readBytes2, writtenBytes2,
+                      'the bytes read should match the bytes written');
+}, 'nativeIO.renameSync does not overwrite an existing file.');
+
+test(testCase => {
+  const file = nativeIO.openSync('test_file');
+  testCase.add_cleanup(() => {
+    file.close();
+    nativeIO.deleteSync('test_file');
+  });
+  assert_throws_dom("UnknownError", () =>
+                    nativeIO.renameSync('test_file', 'renamed_test_file'));
+  file.close();
+
+  const fileNamesAfterRename = nativeIO.getAllSync();
+  assert_equals(fileNamesAfterRename.indexOf('renamed_test_file'), -1);
+  assert_in_array('test_file', fileNamesAfterRename);
+}, 'nativeIO.renameSync allows renaming an open file.');
+
+test(testCase => {
+  testCase.add_cleanup(() => {
+    file.close();
+    nativeIO.deleteSync('test_file');
+    for (let name of nativeIO.getAllSync()) {
+      nativeIO.deleteSync(name);
+    }
+  });
+
+  const file = nativeIO.openSync('test_file');
+  file.close();
+  for (let name of kBadNativeIoNames) {
+    assert_throws_js(TypeError, () => nativeIO.renameSync('test_file', name));
+    assert_throws_js(TypeError, () => nativeIO.renameSync(name, 'test_file_2'));
+  }
+}, 'nativeIO.renameSync does not allow renaming from or to invalid names.');
+
+test(testCase => {
+  const closed_file = nativeIO.openSync('closed_file');
+  closed_file.close();
+  const opened_file = nativeIO.openSync('opened_file');
+  testCase.add_cleanup(() => {
+    closed_file.close();
+    opened_file.close();
+    nativeIO.deleteSync('closed_file');
+    nativeIO.deleteSync('opened_file');
+  });
+
+  // First rename fails, as source is still open.
+  assert_throws_dom("UnknownError",
+                    () => nativeIO.renameSync('opened_file', 'closed_file'));
+  // First rename fails again, as source has not been unlocked.
+  assert_throws_dom("UnknownError",
+                    () => nativeIO.renameSync('opened_file', 'closed_file'));
+}, 'Failed nativeIO.renameSync does not unlock the source.');
+
+test(testCase => {
+  const closed_file = nativeIO.openSync('closed_file');
+  closed_file.close();
+  const opened_file = nativeIO.openSync('opened_file');
+  testCase.add_cleanup(() => {
+    closed_file.close();
+    opened_file.close();
+    nativeIO.deleteSync('closed_file');
+    nativeIO.deleteSync('opened_file');
+  });
+
+  // First rename fails, as destination is still open.
+  assert_throws_dom("UnknownError",
+                    () => nativeIO.renameSync('closed_file', 'opened_file'));
+  // First rename fails again, as destination has not been unlocked.
+  assert_throws_dom("UnknownError",
+                    () => nativeIO.renameSync('closed_file', 'opened_file'));
+}, 'Failed nativeIO.renameSync does not unlock the destination.');
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/native-io/resources/support.js
@@ -0,0 +1,7 @@
+// Names disallowed by NativeIO
+const kBadNativeIoNames = [
+  "Uppercase",
+  "has-dash",
+  "has.dot",
+  "has/slash",
+];