michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: const BIN_SUFFIX = "@BIN_SUFFIX@"; michael@0: const Cc = Components.classes; michael@0: const Ci = Components.interfaces; michael@0: michael@0: #ifdef XP_WIN michael@0: let refMARPrefix = "win_"; michael@0: #else michael@0: let refMARPrefix = ""; michael@0: #endif michael@0: michael@0: let tempDir = do_get_tempdir(); michael@0: michael@0: /** michael@0: * Compares binary data of 2 arrays and throws if they aren't the same. michael@0: * Throws on mismatch, does nothing on match. michael@0: * michael@0: * @param arr1 The first array to compare michael@0: * @param arr2 The second array to compare michael@0: */ michael@0: function compareBinaryData(arr1, arr2) { michael@0: do_check_eq(arr1.length, arr2.length); michael@0: for (let i = 0; i < arr1.length; i++) { michael@0: if (arr1[i] != arr2[i]) { michael@0: throw "Data differs at index " + i + michael@0: ", arr1: " + arr1[i] + ", arr2: " + arr2[i]; michael@0: } michael@0: } michael@0: } michael@0: michael@0: /** michael@0: * Reads a file's data and returns it michael@0: * michael@0: * @param file The file to read the data from michael@0: * @return a byte array for the data in the file. michael@0: */ michael@0: function getBinaryFileData(file) { michael@0: let fileStream = Cc["@mozilla.org/network/file-input-stream;1"]. michael@0: createInstance(Ci.nsIFileInputStream); michael@0: // Open as RD_ONLY with default permissions. michael@0: fileStream.init(file, -1, -1, null); michael@0: michael@0: // Check the returned size versus the expected size. michael@0: let stream = Cc["@mozilla.org/binaryinputstream;1"]. michael@0: createInstance(Ci.nsIBinaryInputStream); michael@0: stream.setInputStream(fileStream); michael@0: let bytes = stream.readByteArray(stream.available()); michael@0: fileStream.close(); michael@0: return bytes; michael@0: } michael@0: michael@0: /** michael@0: * Runs each method in the passed in object michael@0: * Every method of the passed in object that starts with test_ will be ran michael@0: * The cleanup_per_test method of the object will be run right away, it will be michael@0: * registered to be the cleanup function, and it will be run between each test. michael@0: * michael@0: * @return The number of tests ran michael@0: */ michael@0: function run_tests(obj) { michael@0: let cleanup_per_test = obj.cleanup_per_test; michael@0: if (cleanup_per_test === undefined) { michael@0: cleanup_per_test = function() {}; michael@0: } michael@0: michael@0: do_register_cleanup(cleanup_per_test); michael@0: michael@0: // Make sure there's nothing left over from a preious failed test michael@0: cleanup_per_test(); michael@0: michael@0: let ranCount = 0; michael@0: // hasOwnProperty ensures we only see direct properties and not all michael@0: for (let f in obj) { michael@0: if (typeof obj[f] === "function" && michael@0: obj.hasOwnProperty(f) && michael@0: f.toString().indexOf("test_") === 0) { michael@0: obj[f](); michael@0: cleanup_per_test(); michael@0: ranCount++; michael@0: } michael@0: } michael@0: return ranCount; michael@0: } michael@0: michael@0: /** michael@0: * Creates a MAR file with the content of files. michael@0: * michael@0: * @param outMAR The file where the MAR should be created to michael@0: * @param dataDir The directory where the relative file paths exist michael@0: * @param files The relative file paths of the files to include in the MAR michael@0: */ michael@0: function createMAR(outMAR, dataDir, files) { michael@0: // You cannot create an empy MAR. michael@0: do_check_true(files.length > 0); michael@0: michael@0: // Get an nsIProcess to the signmar binary. michael@0: let process = Cc["@mozilla.org/process/util;1"]. michael@0: createInstance(Ci.nsIProcess); michael@0: let signmarBin = do_get_file("signmar" + BIN_SUFFIX); michael@0: michael@0: // Make sure the signmar binary exists and is an executable. michael@0: do_check_true(signmarBin.exists()); michael@0: do_check_true(signmarBin.isExecutable()); michael@0: michael@0: // Ensure on non Windows platforms we encode the same permissions michael@0: // as the refernence MARs contain. On Windows this is also safe. michael@0: // The reference MAR files have permissions of 0664, so in case michael@0: // someone is running these tests locally with another permission michael@0: // (perhaps 0777), make sure that we encode them as 0664. michael@0: for (filePath of files) { michael@0: let f = dataDir.clone(); michael@0: f.append(filePath); michael@0: f.permissions = 0664; michael@0: } michael@0: michael@0: // Setup the command line arguments to create the MAR. michael@0: let args = ["-C", dataDir.path, "-H", "\@MAR_CHANNEL_ID\@", michael@0: "-V", "13.0a1", "-c", outMAR.path]; michael@0: args = args.concat(files); michael@0: michael@0: do_print('Running: ' + signmarBin.path); michael@0: process.init(signmarBin); michael@0: process.run(true, args, args.length); michael@0: michael@0: // Verify signmar returned 0 for success. michael@0: do_check_eq(process.exitValue, 0); michael@0: michael@0: // Verify the out MAR file actually exists. michael@0: do_check_true(outMAR.exists()); michael@0: } michael@0: michael@0: /** michael@0: * Extracts a MAR file to the specified output directory. michael@0: * michael@0: * @param mar The MAR file that should be matched michael@0: * @param dataDir The directory to extract to michael@0: */ michael@0: function extractMAR(mar, dataDir) { michael@0: // Get an nsIProcess to the signmar binary. michael@0: let process = Cc["@mozilla.org/process/util;1"]. michael@0: createInstance(Ci.nsIProcess); michael@0: let signmarBin = do_get_file("signmar" + BIN_SUFFIX); michael@0: michael@0: // Make sure the signmar binary exists and is an executable. michael@0: do_check_true(signmarBin.exists()); michael@0: do_check_true(signmarBin.isExecutable()); michael@0: michael@0: // Setup the command line arguments to create the MAR. michael@0: let args = ["-C", dataDir.path, "-x", mar.path]; michael@0: michael@0: do_print('Running: ' + signmarBin.path); michael@0: process.init(signmarBin); michael@0: process.run(true, args, args.length); michael@0: michael@0: // Verify signmar returned 0 for success. michael@0: do_check_eq(process.exitValue, 0); michael@0: } michael@0: michael@0: