/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; var {utils: Cu} = Components; var SHARED_PATH; var EXISTING_FILE = do_get_file("xpcshell.ini").path; add_task(function* init() { do_get_profile(); SHARED_PATH = OS.Path.join(OS.Constants.Path.profileDir, "test_osfile_read.tmp"); }); // Check that OS.File.read() is executed after the previous operation add_test_pair(function* ordering() { let string1 = "Initial state " + Math.random(); let string2 = "After writing " + Math.random(); yield OS.File.writeAtomic(SHARED_PATH, string1); OS.File.writeAtomic(SHARED_PATH, string2); let string3 = yield OS.File.read(SHARED_PATH, { encoding: "utf-8" }); do_check_eq(string3, string2); }); add_test_pair(function* read_write_all() { let DEST_PATH = SHARED_PATH + Math.random(); let TMP_PATH = DEST_PATH + ".tmp"; let test_with_options = function(options, suffix) { return Task.spawn(function*() { do_print("Running test read_write_all with options " + JSON.stringify(options)); let TEST = "read_write_all " + suffix; let optionsBackup = JSON.parse(JSON.stringify(options)); // Check that read + writeAtomic performs a correct copy let currentDir = yield OS.File.getCurrentDirectory(); let pathSource = OS.Path.join(currentDir, EXISTING_FILE); let contents = yield OS.File.read(pathSource); do_check_true(!!contents); // Content is not empty let bytesRead = contents.byteLength; let bytesWritten = yield OS.File.writeAtomic(DEST_PATH, contents, options); do_check_eq(bytesRead, bytesWritten); // Correct number of bytes written // Check that options are not altered do_check_eq(JSON.stringify(options), JSON.stringify(optionsBackup)); yield reference_compare_files(pathSource, DEST_PATH, TEST); // Check that temporary file was removed or never created exist do_check_false(new FileUtils.File(TMP_PATH).exists()); // Check that writeAtomic fails if noOverwrite is true and the destination // file already exists! contents = new Uint8Array(300); let view = new Uint8Array(contents.buffer, 10, 200); try { let opt = JSON.parse(JSON.stringify(options)); opt.noOverwrite = true; yield OS.File.writeAtomic(DEST_PATH, view, opt); do_throw("With noOverwrite, writeAtomic should have refused to overwrite file (" + suffix + ")"); } catch (err if err instanceof OS.File.Error && err.becauseExists) { do_print("With noOverwrite, writeAtomic correctly failed (" + suffix + ")"); } yield reference_compare_files(pathSource, DEST_PATH, TEST); // Check that temporary file was removed or never created do_check_false(new FileUtils.File(TMP_PATH).exists()); // Now write a subset let START = 10; let LENGTH = 100; contents = new Uint8Array(300); for (var i = 0; i < contents.byteLength; i++) contents[i] = i % 256; view = new Uint8Array(contents.buffer, START, LENGTH); bytesWritten = yield OS.File.writeAtomic(DEST_PATH, view, options); do_check_eq(bytesWritten, LENGTH); let array2 = yield OS.File.read(DEST_PATH); do_check_eq(LENGTH, array2.length); for (var i = 0; i < LENGTH; i++) do_check_eq(array2[i], (i + START) % 256); // Cleanup. yield OS.File.remove(DEST_PATH); yield OS.File.remove(TMP_PATH); }); }; yield test_with_options({tmpPath: TMP_PATH}, "Renaming, not flushing"); yield test_with_options({tmpPath: TMP_PATH, flush: true}, "Renaming, flushing"); yield test_with_options({}, "Not renaming, not flushing"); yield test_with_options({flush: true}, "Not renaming, flushing"); }); function run_test() { run_next_test(); }