dom/imptests/testharnessreport.js

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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/. */
     5 var W3CTest = {
     6   /**
     7    * Dictionary mapping a test URL to either the string "all", which means that
     8    * all tests in this file are expected to fail, or a dictionary mapping test
     9    * names to either the boolean |true|, or the string "debug". The former
    10    * means that this test is expected to fail in all builds, and the latter
    11    * that it is only expected to fail in debug builds.
    12    */
    13   "expectedFailures": {},
    15   /**
    16    * If set to true, we will dump the test failures to the console.
    17    */
    18   "dumpFailures": false,
    20   /**
    21    * If dumpFailures is true, this holds a structure like necessary for
    22    * expectedFailures, for ease of updating the expectations.
    23    */
    24   "failures": {},
    26   /**
    27    * List of test results, needed by TestRunner to update the UI.
    28    */
    29   "tests": [],
    31   /**
    32    * Number of unlogged passes, to stop buildbot from truncating the log.
    33    * We will print a message every MAX_COLLAPSED_MESSAGES passes.
    34    */
    35   "collapsedMessages": 0,
    36   "MAX_COLLAPSED_MESSAGES": 100,
    38   /**
    39    * Reference to the TestRunner object in the parent frame.
    40    */
    41   "runner": parent === this ? null : parent.TestRunner || parent.wrappedJSObject.TestRunner,
    43   /**
    44    * Prefixes for the error logging. Indexed first by int(todo) and second by
    45    * int(result).
    46    */
    47   "prefixes": [
    48     ["TEST-UNEXPECTED-FAIL", "TEST-PASS"],
    49     ["TEST-KNOWN-FAIL", "TEST-UNEXPECTED-PASS"]
    50   ],
    52   /**
    53    * Prefix of the path to parent of the the failures directory.
    54    */
    55   "pathprefix": "/tests/dom/imptests/",
    57   /**
    58    * Returns the URL of the current test, relative to the root W3C tests
    59    * directory. Used as a key into the expectedFailures dictionary.
    60    */
    61   "getPath": function() {
    62     var url = this.getURL();
    63     if (!url.startsWith(this.pathprefix)) {
    64       return "";
    65     }
    66     return url.substring(this.pathprefix.length);
    67   },
    69   /**
    70    * Returns the root-relative URL of the current test.
    71    */
    72   "getURL": function() {
    73     return this.runner ? this.runner.currentTestURL : location.pathname;
    74   },
    76   /**
    77    * Report the results in the tests array.
    78    */
    79   "reportResults": function() {
    80     var element = function element(aLocalName) {
    81       var xhtmlNS = "http://www.w3.org/1999/xhtml";
    82       return document.createElementNS(xhtmlNS, aLocalName);
    83     };
    85     var stylesheet = element("link");
    86     stylesheet.setAttribute("rel", "stylesheet");
    87     stylesheet.setAttribute("href", "/resources/testharness.css");
    88     var heads = document.getElementsByTagName("head");
    89     if (heads.length) {
    90       heads[0].appendChild(stylesheet);
    91     }
    93     var log = document.getElementById("log");
    94     if (!log) {
    95       return;
    96     }
    97     var section = log.appendChild(element("section"));
    98     section.id = "summary";
    99     section.appendChild(element("h2")).textContent = "Details";
   101     var table = section.appendChild(element("table"));
   102     table.id = "results";
   104     var tr = table.appendChild(element("thead")).appendChild(element("tr"));
   105     for (var header of ["Result", "Test Name", "Message"]) {
   106       tr.appendChild(element("th")).textContent = header;
   107     }
   108     var statuses = [
   109       ["Unexpected Fail", "Pass"],
   110       ["Known Fail", "Unexpected Pass"]
   111     ];
   112     var tbody = table.appendChild(element("tbody"));
   113     for (var test of this.tests) {
   114       tr = tbody.appendChild(element("tr"));
   115       tr.className = (test.result === !test.todo ? "pass" : "fail");
   116       tr.appendChild(element("td")).textContent =
   117         statuses[+test.todo][+test.result];
   118       tr.appendChild(element("td")).textContent = test.name;
   119       tr.appendChild(element("td")).textContent = test.message;
   120     }
   121   },
   123   /**
   124    * Returns a printable message based on aTest's 'name' and 'message'
   125    * properties.
   126    */
   127   "formatTestMessage": function(aTest) {
   128     return aTest.name + (aTest.message ? ": " + aTest.message : "");
   129   },
   131   /**
   132    * Lets the test runner know about a test result.
   133    */
   134   "_log": function(test) {
   135     var url = this.getURL();
   136     var msg = this.prefixes[+test.todo][+test.result] + " | ";
   137     if (url) {
   138       msg += url;
   139     }
   140     msg += " | " + this.formatTestMessage(test);
   141     if (this.runner) {
   142       this.runner[(test.result === !test.todo) ? "log" : "error"](msg);
   143     } else {
   144       dump(msg + "\n");
   145     }
   146   },
   148   /**
   149    * Logs a message about collapsed messages (if any), and resets the counter.
   150    */
   151   "_logCollapsedMessages": function() {
   152     if (this.collapsedMessages) {
   153       this._log({
   154         "name": document.title,
   155         "result": true,
   156         "todo": false,
   157         "message": "Elided " + this.collapsedMessages + " passes or known failures."
   158       });
   159     }
   160     this.collapsedMessages = 0;
   161   },
   163   /**
   164    * Maybe logs a result, eliding up to MAX_COLLAPSED_MESSAGES consecutive
   165    * passes.
   166    */
   167   "_maybeLog": function(test) {
   168     var success = (test.result === !test.todo);
   169     if (success && ++this.collapsedMessages < this.MAX_COLLAPSED_MESSAGES) {
   170       return;
   171     }
   172     this._logCollapsedMessages();
   173     this._log(test);
   174   },
   176   /**
   177    * Reports a test result. The argument is an object with the following
   178    * properties:
   179    *
   180    * o message (string): message to be reported
   181    * o result (boolean): whether this test failed
   182    * o todo (boolean): whether this test is expected to fail
   183    */
   184   "report": function(test) {
   185     this.tests.push(test);
   186     this._maybeLog(test);
   187   },
   189   /**
   190    * Returns true if this test is expected to fail, and false otherwise.
   191    */
   192   "_todo": function(test) {
   193     if (this.expectedFailures === "all") {
   194       return true;
   195     }
   196     var value = this.expectedFailures[test.name];
   197     return value === true || (value === "debug" && !!SpecialPowers.isDebugBuild);
   198   },
   200   /**
   201    * Callback function for testharness.js. Called when one test in a file
   202    * finishes.
   203    */
   204   "result": function(test) {
   205     var url = this.getPath();
   206     this.report({
   207       "name": test.name,
   208       "message": test.message || "",
   209       "result": test.status === test.PASS,
   210       "todo": this._todo(test)
   211     });
   212     if (this.dumpFailures && test.status !== test.PASS) {
   213       this.failures[test.name] = true;
   214     }
   215   },
   217   /**
   218    * Callback function for testharness.js. Called when the entire test file
   219    * finishes.
   220    */
   221   "finish": function(tests, status) {
   222     var url = this.getPath();
   223     this.report({
   224       "name": "Finished test",
   225       "message": "Status: " + status.status,
   226       "result": status.status === status.OK,
   227       "todo":
   228         url in this.expectedFailures &&
   229         this.expectedFailures[url] === "error"
   230     });
   232     this._logCollapsedMessages();
   234     if (this.dumpFailures) {
   235       dump("@@@ @@@ Failures\n");
   236       dump(url + "@@@" + JSON.stringify(this.failures) + "\n");
   237     }
   238     if (this.runner) {
   239       this.runner.testFinished(this.tests.map(function(aTest) {
   240         return {
   241           "message": this.formatTestMessage(aTest),
   242           "result": aTest.result,
   243           "todo": aTest.todo
   244         };
   245       }, this));
   246     } else {
   247       this.reportResults();
   248     }
   249   },
   251   /**
   252    * Log an unexpected failure. Intended to be used from harness code, not
   253    * from tests.
   254    */
   255   "logFailure": function(aTestName, aMessage) {
   256     this.report({
   257       "name": aTestName,
   258       "message": aMessage,
   259       "result": false,
   260       "todo": false
   261     });
   262   },
   264   /**
   265    * Timeout the current test. Intended to be used from harness code, not
   266    * from tests.
   267    */
   268   "timeout": function() {
   269     this.logFailure("Timeout", "Test runner timed us out.");
   270     timeout();
   271   }
   272 };
   273 (function() {
   274   try {
   275     var path = W3CTest.getPath();
   276     if (path) {
   277       // Get expected fails.  If there aren't any, there will be a 404, which is
   278       // fine.  Anything else is unexpected.
   279       var url = W3CTest.pathprefix + "failures/" + path + ".json";
   280       var request = new XMLHttpRequest();
   281       request.open("GET", url, false);
   282       request.send();
   283       if (request.status === 200) {
   284         W3CTest.expectedFailures = JSON.parse(request.responseText);
   285       } else if (request.status !== 404) {
   286         W3CTest.logFailure("Fetching failures file", "Request status was " + request.status);
   287       }
   288     }
   290     add_result_callback(W3CTest.result.bind(W3CTest));
   291     add_completion_callback(W3CTest.finish.bind(W3CTest));
   292     setup({
   293       "output": false,
   294       "explicit_timeout": true
   295     });
   296   } catch (e) {
   297     W3CTest.logFailure("Harness setup", "Unexpected exception: " + e);
   298   }
   299 })();

mercurial