1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 var EXPORTED_SYMBOLS = ["StructuredLogger", "StructuredFormatter"];
10 * TestLogger: Logger class generating messages compliant with the
11 * structured logging protocol for tests exposed by mozlog
14 * The name of the logger to instantiate.
16 * An underlying function to be used to log raw messages. This function
17 * will receive the complete serialized json string to log.
19 * An array of functions used to add global context to log messages.
20 * These will each be called with the complete object to log as an
23 var StructuredLogger = function(name, dumpFun = dump, mutators = []) {
25 this._dumpFun = dumpFun;
26 this._mutatorFuns = mutators;
30 * Log functions producing messages in the format specified by mozlog
32 StructuredLogger.prototype = {
34 var data = { test: this._testId(test) };
35 this._logData("test_start", data);
47 if (subtest === null || subtest === undefined) {
48 // Fix for assertions that don't pass in a name
49 subtest = "undefined assertion name";
53 test: this._testId(test),
58 if (expected != status && status != "SKIP") {
59 data.expected = expected;
61 if (message !== null) {
62 data.message = String(message);
71 this._logData("test_status", data);
82 var data = { test: this._testId(test), status };
84 if (expected != status && status != "SKIP") {
85 data.expected = expected;
87 if (message !== null) {
88 data.message = String(message);
97 this._logData("test_end", data);
100 assertionCount(test, count, minExpected = 0, maxExpected = 0) {
102 test: this._testId(test),
103 min_expected: minExpected,
104 max_expected: maxExpected,
108 this._logData("assertion_count", data);
119 Object.keys(ids).map(function(manifest) {
120 ids[manifest] = ids[manifest].map(x => this._testId(x));
122 var data = { tests: ids };
128 if (runinfo !== null) {
129 data.runinfo = runinfo;
132 if (versioninfo !== null) {
133 data.versioninfo = versioninfo;
136 if (deviceinfo !== null) {
137 data.deviceinfo = deviceinfo;
140 if (extra !== null) {
144 this._logData("suite_start", data);
147 suiteEnd(extra = null) {
150 if (extra !== null) {
154 this._logData("suite_end", data);
158 * Unstructured logging functions. The "extra" parameter can always by used to
159 * log suite specific data. If a "stack" field is provided it is logged at the
160 * top level of the data object for the benefit of mozlog's formatters.
162 log(level, message, extra = null) {
165 message: String(message),
168 if (extra !== null) {
170 if ("stack" in extra) {
171 data.stack = extra.stack;
175 this._logData("log", data);
178 debug(message, extra = null) {
179 this.log("DEBUG", message, extra);
182 info(message, extra = null) {
183 this.log("INFO", message, extra);
186 warning(message, extra = null) {
187 this.log("WARNING", message, extra);
190 error(message, extra = null) {
191 this.log("ERROR", message, extra);
194 critical(message, extra = null) {
195 this.log("CRITICAL", message, extra);
198 processOutput(thread, message) {
199 this._logData("process_output", {
205 _logData(action, data = {}) {
214 for (var field in data) {
215 allData[field] = data[field];
218 for (var fun of this._mutatorFuns) {
222 this._dumpFun(allData);
226 if (Array.isArray(test)) {
227 return test.join(" ");
234 * StructuredFormatter: Formatter class turning structured messages
235 * into human-readable messages.
237 var StructuredFormatter = function() {
238 this.testStartTimes = {};
241 StructuredFormatter.prototype = {
243 return message.message;
246 suite_start(message) {
247 this.suiteStartTime = message.time;
248 return "SUITE-START | Running " + message.tests.length + " tests";
251 test_start(message) {
252 this.testStartTimes[message.test] = new Date().getTime();
253 return "TEST-START | " + message.test;
256 test_status(message) {
261 (message.message ? " | " + message.message : "");
262 if (message.expected) {
272 return "TEST-" + message.status + " | " + statusInfo;
276 var startTime = this.testStartTimes[message.test];
277 delete this.testStartTimes[message.test];
279 message.test + (message.message ? " | " + String(message.message) : "");
281 if (message.expected) {
290 return "TEST-" + message.status + " | " + statusInfo;
292 result = result + " | took " + message.time - startTime + "ms";
297 return "SUITE-END | took " + message.time - this.suiteStartTime + "ms";