summaryrefslogtreecommitdiffstats
path: root/modules/libmar/tests/unit/head_libmar.js
blob: 49ce2e8ba6e241e0f869276e711d311dba620aaa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

const BIN_SUFFIX = mozinfo.bin_suffix;
const tempDir = do_get_tempdir();

/**
 * Compares binary data of 2 arrays and throws if they aren't the same.
 * Throws on mismatch, does nothing on match.
 *
 * @param arr1 The first array to compare
 * @param arr2 The second array to compare
 */
function compareBinaryData(arr1, arr2) {
  Assert.equal(arr1.length, arr2.length);
  for (let i = 0; i < arr1.length; i++) {
    if (arr1[i] != arr2[i]) {
      throw new Error(
        `Data differs at index ${i}, arr1: ${arr1[i]}, arr2: ${arr2[i]}`
      );
    }
  }
}

/**
 * Reads a file's data and returns it
 *
 * @param file The file to read the data from
 * @return a byte array for the data in the file.
 */
function getBinaryFileData(file) {
  let fileStream = Cc[
    "@mozilla.org/network/file-input-stream;1"
  ].createInstance(Ci.nsIFileInputStream);
  // Open as RD_ONLY with default permissions.
  fileStream.init(file, -1, -1, null);

  // Check the returned size versus the expected size.
  let stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
    Ci.nsIBinaryInputStream
  );
  stream.setInputStream(fileStream);
  let bytes = stream.readByteArray(stream.available());
  fileStream.close();
  return bytes;
}

/**
 * Runs each method in the passed in object
 * Every method of the passed in object that starts with test_ will be ran
 * The cleanup_per_test method of the object will be run right away, it will be
 * registered to be the cleanup function, and it will be run between each test.
 *
 * @return The number of tests ran
 */
function run_tests(obj) {
  let cleanup_per_test = obj.cleanup_per_test;
  if (cleanup_per_test === undefined) {
    cleanup_per_test = function __cleanup_per_test() {};
  }

  registerCleanupFunction(cleanup_per_test);

  // Make sure there's nothing left over from a preious failed test
  cleanup_per_test();

  let ranCount = 0;
  // hasOwnProperty ensures we only see direct properties and not all
  for (let f in obj) {
    if (
      typeof obj[f] === "function" &&
      obj.hasOwnProperty(f) &&
      f.toString().indexOf("test_") === 0
    ) {
      obj[f]();
      cleanup_per_test();
      ranCount++;
    }
  }
  return ranCount;
}

/**
 * Creates a MAR file with the content of files.
 *
 * @param outMAR  The file where the MAR should be created to
 * @param dataDir The directory where the relative file paths exist
 * @param files   The relative file paths of the files to include in the MAR
 */
function createMAR(outMAR, dataDir, files) {
  // You cannot create an empy MAR.
  Assert.ok(!!files.length);

  // Get an nsIProcess to the signmar binary.
  let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
  let signmarBin = do_get_file("signmar" + BIN_SUFFIX);

  // Make sure the signmar binary exists and is an executable.
  Assert.ok(signmarBin.exists());
  Assert.ok(signmarBin.isExecutable());

  // Ensure on non Windows platforms we encode the same permissions
  // as the refernence MARs contain.  On Windows this is also safe.
  // The reference MAR files have permissions of 0o664, so in case
  // someone is running these tests locally with another permission
  // (perhaps 0o777), make sure that we encode them as 0o664.
  for (let filePath of files) {
    let f = dataDir.clone();
    f.append(filePath);
    f.permissions = 0o664;
  }

  // Setup the command line arguments to create the MAR.
  let args = [
    "-C",
    dataDir.path,
    "-H",
    "@MAR_CHANNEL_ID@",
    "-V",
    "13.0a1",
    "-c",
    outMAR.path,
  ];
  args = args.concat(files);

  info("Running: " + signmarBin.path + " " + args.join(" "));
  process.init(signmarBin);
  process.run(true, args, args.length);

  // Verify signmar returned 0 for success.
  Assert.equal(process.exitValue, 0);

  // Verify the out MAR file actually exists.
  Assert.ok(outMAR.exists());
}

/**
 * Extracts a MAR file to the specified output directory.
 *
 * @param mar     The MAR file that should be matched
 * @param dataDir The directory to extract to
 */
function extractMAR(mar, dataDir) {
  // Get an nsIProcess to the signmar binary.
  let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
  let signmarBin = do_get_file("signmar" + BIN_SUFFIX);

  // Make sure the signmar binary exists and is an executable.
  Assert.ok(signmarBin.exists());
  Assert.ok(signmarBin.isExecutable());

  // Setup the command line arguments to extract the MAR.
  let args = ["-C", dataDir.path, "-x", mar.path];

  info("Running: " + signmarBin.path + " " + args.join(" "));
  process.init(signmarBin);
  process.run(true, args, args.length);

  return process.exitValue;
}