Bug 1063635 Part 3 - Fix tests for native writeAtomic. r=Yoric
authorMilindL <i.milind.luthra@gmail.com>
Tue, 29 Aug 2017 20:20:26 +0530
changeset 386285 09157e44e113b4fdb403623a8b9c78c75f188f26
parent 386284 71f8ad3208d996e35ce44bc0718b859d77dde4fe
child 386286 194b77d4004f1634e1cc6a426e37ee49dc93a615
child 386309 0bd9b61304e208cdd5cc489aef45fdff04a006f2
push id53324
push userdteller@mozilla.com
push dateSat, 14 Oct 2017 20:46:48 +0000
treeherderautoland@09157e44e113 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersYoric
bugs1063635
milestone58.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 1063635 Part 3 - Fix tests for native writeAtomic. r=Yoric MozReview-Commit-ID: 94lNCMUEg7c
toolkit/components/osfile/tests/xpcshell/test_duration.js
toolkit/components/osfile/tests/xpcshell/test_osfile_writeAtomic_unicode_filename.js
toolkit/components/osfile/tests/xpcshell/xpcshell.ini
--- a/toolkit/components/osfile/tests/xpcshell/test_duration.js
+++ b/toolkit/components/osfile/tests/xpcshell/test_duration.js
@@ -52,22 +52,22 @@ add_task(async function duration() {
     outExecutionDuration: null
   };
   let contents = await OS.File.read(pathSource, undefined, readOptions);
   testOptions(readOptions, "OS.File.read", ["outExecutionDuration"]);
   // Options structure passed to a OS.File writeAtomic method.
   let writeAtomicOptions = {
     // This field should be first initialized with the actual
     // duration measurement then progressively incremented.
-    outSerializationDuration: null,
     outExecutionDuration: null,
     tmpPath
   };
+  // Note that |contents| cannot be reused after this call since it is detached.
   await OS.File.writeAtomic(pathDest, contents, writeAtomicOptions);
-  testOptions(writeAtomicOptions, "OS.File.writeAtomic");
+  testOptions(writeAtomicOptions, "OS.File.writeAtomic", ["outExecutionDuration"]);
   await OS.File.remove(pathDest);
 
   do_print(`Ensuring that we can use ${availableDurations.join(", ")} to accumulate durations`);
 
   let ARBITRARY_BASE_DURATION = 5;
   copyOptions = {
     // This field should now be incremented with the actual duration
     // measurement.
@@ -83,20 +83,25 @@ add_task(async function duration() {
   testOptionIncrements(copyOptions, "copy", backupDuration);
 
   backupDuration = Object.assign({}, copyOptions);
   await OS.File.remove(copyFile, copyOptions);
   testOptionIncrements(copyOptions, "remove", backupDuration);
 
   // Trying an operation where options are cloned.
   // Options structure passed to a OS.File writeAtomic method.
-  writeAtomicOptions = copyOptions;
+  writeAtomicOptions = {
+    // We do not check for |outSerializationDuration| since |Scheduler.post|
+    // may not be called whenever |writeAtomic| is called.
+    outExecutionDuration: ARBITRARY_BASE_DURATION
+  };
   writeAtomicOptions.tmpPath = tmpPath;
-  backupDuration = Object.assign({}, copyOptions);
+  backupDuration = Object.assign({}, writeAtomicOptions);
+  contents = await OS.File.read(pathSource, undefined, readOptions);
   await OS.File.writeAtomic(pathDest, contents, writeAtomicOptions);
-  testOptionIncrements(writeAtomicOptions, "writeAtomicOptions", backupDuration);
+  testOptionIncrements(writeAtomicOptions, "writeAtomicOptions", backupDuration, ["outExecutionDuration"]);
   OS.File.remove(pathDest);
 
   // Testing an operation that doesn't take arguments at all
   let file = await OS.File.open(pathSource);
   await file.stat();
   await file.close();
 });
new file mode 100644
--- /dev/null
+++ b/toolkit/components/osfile/tests/xpcshell/test_osfile_writeAtomic_unicode_filename.js
@@ -0,0 +1,40 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * This test checks against failures that may occur while creating and/or
+ * renaming files with Unicode paths on Windows.
+ * See bug 1063635#c89 for a failure due to a Unicode filename being renamed.
+ */
+
+"use strict";
+var profileDir;
+
+async function writeAndCheck(path, tmpPath) {
+  const encoder = new TextEncoder();
+  const content = "tmpContent";
+  const outBin = encoder.encode(content);
+  await OS.File.writeAtomic(path, outBin, { tmpPath });
+
+  const decoder = new TextDecoder();
+  const writtenBin = await OS.File.read(path);
+  const written = decoder.decode(writtenBin);
+
+  // Clean up
+  await OS.File.remove(path);
+  Assert.equal(written, content, `Expected correct write/read for ${path} with tmpPath ${tmpPath}`);
+}
+
+add_task(async function init() {
+  do_get_profile();
+  profileDir = OS.Constants.Path.profileDir;
+});
+
+add_test_pair(async function test_osfile_writeAtomic_unicode_filename() {
+  await writeAndCheck(OS.Path.join(profileDir, "☕") + ".tmp", undefined);
+  await writeAndCheck(OS.Path.join(profileDir, "☕"), undefined);
+  await writeAndCheck(OS.Path.join(profileDir, "☕") + ".tmp",
+                      OS.Path.join(profileDir, "☕"));
+  await writeAndCheck(OS.Path.join(profileDir, "☕"),
+                      OS.Path.join(profileDir, "☕") + ".tmp");
+});
--- a/toolkit/components/osfile/tests/xpcshell/xpcshell.ini
+++ b/toolkit/components/osfile/tests/xpcshell/xpcshell.ini
@@ -25,16 +25,17 @@ skip-if = os == "win" || os == "android"
 [test_osfile_closed.js]
 [test_osfile_error.js]
 [test_osfile_kill.js]
 # Windows test
 [test_osfile_win_async_setPermissions.js]
 skip-if = os != "win"
 [test_osfile_writeAtomic_backupTo_option.js]
 [test_osfile_writeAtomic_zerobytes.js]
+[test_osfile_writeAtomic_unicode_filename.js]
 [test_path.js]
 [test_path_constants.js]
 [test_queue.js]
 [test_read_write.js]
 requesttimeoutfactor = 4
 [test_remove.js]
 [test_removeDir.js]
 requesttimeoutfactor = 4