Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* Any copyright is dedicated to the Public Domain. |
michael@0 | 2 | * http://creativecommons.org/publicdomain/zero/1.0/ */ |
michael@0 | 3 | |
michael@0 | 4 | "use strict"; |
michael@0 | 5 | |
michael@0 | 6 | let {utils: Cu} = Components; |
michael@0 | 7 | |
michael@0 | 8 | let SHARED_PATH; |
michael@0 | 9 | |
michael@0 | 10 | let EXISTING_FILE = do_get_file("xpcshell.ini").path; |
michael@0 | 11 | |
michael@0 | 12 | add_task(function* init() { |
michael@0 | 13 | do_get_profile(); |
michael@0 | 14 | SHARED_PATH = OS.Path.join(OS.Constants.Path.profileDir, "test_osfile_read.tmp"); |
michael@0 | 15 | }); |
michael@0 | 16 | |
michael@0 | 17 | |
michael@0 | 18 | // Check that OS.File.read() is executed after the previous operation |
michael@0 | 19 | add_test_pair(function* ordering() { |
michael@0 | 20 | let string1 = "Initial state " + Math.random(); |
michael@0 | 21 | let string2 = "After writing " + Math.random(); |
michael@0 | 22 | yield OS.File.writeAtomic(SHARED_PATH, string1); |
michael@0 | 23 | OS.File.writeAtomic(SHARED_PATH, string2); |
michael@0 | 24 | let string3 = yield OS.File.read(SHARED_PATH, { encoding: "utf-8" }); |
michael@0 | 25 | do_check_eq(string3, string2); |
michael@0 | 26 | }); |
michael@0 | 27 | |
michael@0 | 28 | add_test_pair(function* read_write_all() { |
michael@0 | 29 | let DEST_PATH = SHARED_PATH + Math.random(); |
michael@0 | 30 | let TMP_PATH = DEST_PATH + ".tmp"; |
michael@0 | 31 | |
michael@0 | 32 | let test_with_options = function(options, suffix) { |
michael@0 | 33 | return Task.spawn(function*() { |
michael@0 | 34 | do_print("Running test read_write_all with options " + JSON.stringify(options)); |
michael@0 | 35 | let TEST = "read_write_all " + suffix; |
michael@0 | 36 | |
michael@0 | 37 | let optionsBackup = JSON.parse(JSON.stringify(options)); |
michael@0 | 38 | |
michael@0 | 39 | // Check that read + writeAtomic performs a correct copy |
michael@0 | 40 | let currentDir = yield OS.File.getCurrentDirectory(); |
michael@0 | 41 | let pathSource = OS.Path.join(currentDir, EXISTING_FILE); |
michael@0 | 42 | let contents = yield OS.File.read(pathSource); |
michael@0 | 43 | do_check_true(!!contents); // Content is not empty |
michael@0 | 44 | |
michael@0 | 45 | let bytesWritten = yield OS.File.writeAtomic(DEST_PATH, contents, options); |
michael@0 | 46 | do_check_eq(contents.byteLength, bytesWritten); // Correct number of bytes written |
michael@0 | 47 | |
michael@0 | 48 | // Check that options are not altered |
michael@0 | 49 | do_check_eq(JSON.stringify(options), JSON.stringify(optionsBackup)); |
michael@0 | 50 | yield reference_compare_files(pathSource, DEST_PATH, TEST); |
michael@0 | 51 | |
michael@0 | 52 | // Check that temporary file was removed or never created exist |
michael@0 | 53 | do_check_false(new FileUtils.File(TMP_PATH).exists()); |
michael@0 | 54 | |
michael@0 | 55 | // Check that writeAtomic fails if noOverwrite is true and the destination |
michael@0 | 56 | // file already exists! |
michael@0 | 57 | let view = new Uint8Array(contents.buffer, 10, 200); |
michael@0 | 58 | try { |
michael@0 | 59 | let opt = JSON.parse(JSON.stringify(options)); |
michael@0 | 60 | opt.noOverwrite = true; |
michael@0 | 61 | yield OS.File.writeAtomic(DEST_PATH, view, opt); |
michael@0 | 62 | do_throw("With noOverwrite, writeAtomic should have refused to overwrite file (" + suffix + ")"); |
michael@0 | 63 | } catch (err if err instanceof OS.File.Error && err.becauseExists) { |
michael@0 | 64 | do_print("With noOverwrite, writeAtomic correctly failed (" + suffix + ")"); |
michael@0 | 65 | } |
michael@0 | 66 | yield reference_compare_files(pathSource, DEST_PATH, TEST); |
michael@0 | 67 | |
michael@0 | 68 | // Check that temporary file was removed or never created |
michael@0 | 69 | do_check_false(new FileUtils.File(TMP_PATH).exists()); |
michael@0 | 70 | |
michael@0 | 71 | // Now write a subset |
michael@0 | 72 | let START = 10; |
michael@0 | 73 | let LENGTH = 100; |
michael@0 | 74 | view = new Uint8Array(contents.buffer, START, LENGTH); |
michael@0 | 75 | bytesWritten = yield OS.File.writeAtomic(DEST_PATH, view, options); |
michael@0 | 76 | do_check_eq(bytesWritten, LENGTH); |
michael@0 | 77 | |
michael@0 | 78 | let array2 = yield OS.File.read(DEST_PATH); |
michael@0 | 79 | let view1 = new Uint8Array(contents.buffer, START, LENGTH); |
michael@0 | 80 | do_check_eq(view1.length, array2.length); |
michael@0 | 81 | let decoder = new TextDecoder(); |
michael@0 | 82 | do_check_eq(decoder.decode(view1), decoder.decode(array2)); |
michael@0 | 83 | |
michael@0 | 84 | |
michael@0 | 85 | // Cleanup. |
michael@0 | 86 | yield OS.File.remove(DEST_PATH); |
michael@0 | 87 | yield OS.File.remove(TMP_PATH); |
michael@0 | 88 | }); |
michael@0 | 89 | }; |
michael@0 | 90 | |
michael@0 | 91 | yield test_with_options({tmpPath: TMP_PATH}, "Renaming, not flushing"); |
michael@0 | 92 | yield test_with_options({tmpPath: TMP_PATH, flush: true}, "Renaming, flushing"); |
michael@0 | 93 | yield test_with_options({}, "Not renaming, not flushing"); |
michael@0 | 94 | yield test_with_options({flush: true}, "Not renaming, flushing"); |
michael@0 | 95 | }); |
michael@0 | 96 | |
michael@0 | 97 | |
michael@0 | 98 | function run_test() { |
michael@0 | 99 | run_next_test(); |
michael@0 | 100 | } |