tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

selftest.py (48270B)


      1 #!/usr/bin/env python
      2 #
      3 # Any copyright is dedicated to the Public Domain.
      4 # http://creativecommons.org/publicdomain/zero/1.0/
      5 #
      6 # These tests are run before any xpcshell test is ran when the --self-test flag
      7 # is passed. To run these tests, run:
      8 # ./mach xpcshell-test --self-test
      9 # or use "mach test" with any xpcshell test file or directory:
     10 # ./mach test testing/modules/tests/xpcshell/test_assert.js --self-test
     11 
     12 import os
     13 import pprint
     14 import re
     15 import sys
     16 import tempfile
     17 import unittest
     18 
     19 import mozfile
     20 import mozinfo
     21 import six
     22 from mozlog import structured
     23 from runxpcshelltests import XPCShellTests
     24 
     25 TEST_PASS_STRING = "TEST-PASS"
     26 TEST_FAIL_STRING = "TEST-UNEXPECTED-FAIL"
     27 
     28 SIMPLE_PASSING_TEST = "function run_test() { Assert.ok(true); }"
     29 SIMPLE_FAILING_TEST = "function run_test() { Assert.ok(false); }"
     30 SIMPLE_PREFCHECK_TEST = """
     31 function run_test() {
     32  Assert.ok(Services.prefs.getBoolPref("fake.pref.to.test"));
     33 }
     34 """
     35 
     36 SIMPLE_UNCAUGHT_REJECTION_TEST = """
     37 function run_test() {
     38  Promise.reject(new Error("Test rejection."));
     39  Assert.ok(true);
     40 }
     41 """
     42 
     43 ADD_TEST_SIMPLE = """
     44 function run_test() { run_next_test(); }
     45 
     46 add_test(function test_simple() {
     47  Assert.ok(true);
     48  run_next_test();
     49 });
     50 """
     51 
     52 ADD_TEST_FAILING = """
     53 function run_test() { run_next_test(); }
     54 
     55 add_test(function test_failing() {
     56  Assert.ok(false);
     57  run_next_test();
     58 });
     59 """
     60 
     61 ADD_TEST_UNCAUGHT_REJECTION = """
     62 function run_test() { run_next_test(); }
     63 
     64 add_test(function test_uncaught_rejection() {
     65  Promise.reject(new Error("Test rejection."));
     66  run_next_test();
     67 });
     68 """
     69 
     70 CHILD_TEST_PASSING = """
     71 function run_test () { run_next_test(); }
     72 
     73 add_test(function test_child_simple () {
     74  run_test_in_child("test_pass.js");
     75  run_next_test();
     76 });
     77 """
     78 
     79 CHILD_TEST_FAILING = """
     80 function run_test () { run_next_test(); }
     81 
     82 add_test(function test_child_simple () {
     83  run_test_in_child("test_fail.js");
     84  run_next_test();
     85 });
     86 """
     87 
     88 CHILD_HARNESS_SIMPLE = """
     89 function run_test () { run_next_test(); }
     90 
     91 add_test(function test_child_assert () {
     92  do_load_child_test_harness();
     93  do_test_pending("test child assertion");
     94  sendCommand("Assert.ok(true);", do_test_finished);
     95  run_next_test();
     96 });
     97 """
     98 
     99 CHILD_TEST_HANG = """
    100 function run_test () { run_next_test(); }
    101 
    102 add_test(function test_child_simple () {
    103  do_test_pending("hang test");
    104  do_load_child_test_harness();
    105  sendCommand("_testLogger.info('CHILD-TEST-STARTED'); " +
    106              + "const _TEST_FILE=['test_pass.js']; _execute_test(); ",
    107              do_test_finished);
    108  run_next_test();
    109 });
    110 """
    111 
    112 SIMPLE_LOOPING_TEST = """
    113 function run_test () { run_next_test(); }
    114 
    115 add_test(function test_loop () {
    116  do_test_pending()
    117 });
    118 """
    119 
    120 PASSING_TEST_UNICODE = rb"""
    121 function run_test () { run_next_test(); }
    122 
    123 add_test(function test_unicode_print () {
    124  Assert.equal("\u201c\u201d", "\u201c\u201d");
    125  run_next_test();
    126 });
    127 """
    128 
    129 ADD_TASK_SINGLE = """
    130 function run_test() { run_next_test(); }
    131 
    132 add_task(async function test_task() {
    133  await Promise.resolve(true);
    134  await Promise.resolve(false);
    135 });
    136 """
    137 
    138 ADD_TASK_MULTIPLE = """
    139 function run_test() { run_next_test(); }
    140 
    141 add_task(async function test_task() {
    142  await Promise.resolve(true);
    143 });
    144 
    145 add_task(async function test_2() {
    146  await Promise.resolve(true);
    147 });
    148 """
    149 
    150 ADD_TASK_REJECTED = """
    151 function run_test() { run_next_test(); }
    152 
    153 add_task(async function test_failing() {
    154  await Promise.reject(new Error("I fail."));
    155 });
    156 """
    157 
    158 ADD_TASK_REJECTED_UNDEFINED = """
    159 function run_test() { run_next_test(); }
    160 
    161 add_task(async function test_failing() {
    162  await Promise.reject();
    163 });
    164 """
    165 
    166 ADD_TASK_FAILURE_INSIDE = """
    167 function run_test() { run_next_test(); }
    168 
    169 add_task(async function test() {
    170  let result = await Promise.resolve(false);
    171 
    172  Assert.ok(result);
    173 });
    174 """
    175 
    176 ADD_TASK_RUN_NEXT_TEST = """
    177 function run_test() { run_next_test(); }
    178 
    179 add_task(function () {
    180  Assert.ok(true);
    181 
    182  run_next_test();
    183 });
    184 """
    185 
    186 ADD_TASK_STACK_TRACE = """
    187 function run_test() { run_next_test(); }
    188 
    189 add_task(async function this_test_will_fail() {
    190  for (let i = 0; i < 10; ++i) {
    191    await Promise.resolve();
    192  }
    193  Assert.ok(false);
    194 });
    195 """
    196 
    197 ADD_TASK_SKIP = """
    198 add_task(async function skipMeNot1() {
    199  Assert.ok(true, "Well well well.");
    200 });
    201 
    202 add_task(async function skipMe1() {
    203  Assert.ok(false, "Not skipped after all.");
    204 }).skip();
    205 
    206 add_task(async function skipMeNot2() {
    207  Assert.ok(true, "Well well well.");
    208 });
    209 
    210 add_task(async function skipMeNot3() {
    211  Assert.ok(true, "Well well well.");
    212 });
    213 
    214 add_task(async function skipMe2() {
    215  Assert.ok(false, "Not skipped after all.");
    216 }).skip();
    217 """
    218 
    219 ADD_TASK_SKIPALL = """
    220 add_task(async function skipMe1() {
    221  Assert.ok(false, "Not skipped after all.");
    222 });
    223 
    224 add_task(async function skipMe2() {
    225  Assert.ok(false, "Not skipped after all.");
    226 }).skip();
    227 
    228 add_task(async function skipMe3() {
    229  Assert.ok(false, "Not skipped after all.");
    230 }).only();
    231 
    232 add_task(async function skipMeNot() {
    233  Assert.ok(true, "Well well well.");
    234 }).only();
    235 
    236 add_task(async function skipMe4() {
    237  Assert.ok(false, "Not skipped after all.");
    238 });
    239 """
    240 
    241 ADD_TEST_THROW_STRING = """
    242 function run_test() {do_throw("Passing a string to do_throw")};
    243 """
    244 
    245 ADD_TEST_THROW_OBJECT = """
    246 let error = {
    247  message: "Error object",
    248  fileName: "failure.js",
    249  stack: "ERROR STACK",
    250  toString: function() {return this.message;}
    251 };
    252 function run_test() {do_throw(error)};
    253 """
    254 
    255 ADD_TEST_REPORT_OBJECT = """
    256 let error = {
    257  message: "Error object",
    258  fileName: "failure.js",
    259  stack: "ERROR STACK",
    260  toString: function() {return this.message;}
    261 };
    262 function run_test() {do_report_unexpected_exception(error)};
    263 """
    264 
    265 ADD_TEST_VERBOSE = """
    266 function run_test() {info("a message from info")};
    267 """
    268 
    269 # A test for genuine JS-generated Error objects
    270 ADD_TEST_REPORT_REF_ERROR = """
    271 function run_test() {
    272  let obj = {blah: 0};
    273  try {
    274    obj.noSuchFunction();
    275  }
    276  catch (error) {
    277    do_report_unexpected_exception(error);
    278  }
    279 };
    280 """
    281 
    282 # A test for failure to load a test due to a syntax error
    283 LOAD_ERROR_SYNTAX_ERROR = """
    284 function run_test(
    285 """
    286 
    287 # A test for failure to load a test due to an error other than a syntax error
    288 LOAD_ERROR_OTHER_ERROR = """
    289 "use strict";
    290 no_such_var = "foo"; // assignment to undeclared variable
    291 """
    292 
    293 # A test that crashes outright.
    294 TEST_CRASHING = """
    295 function run_test () {
    296  const { ctypes } = ChromeUtils.importESModule(
    297    "resource://gre/modules/ctypes.sys.mjs"
    298  );
    299  let zero = new ctypes.intptr_t(8);
    300  let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
    301  badptr.contents;
    302 }
    303 """
    304 
    305 # A test for asynchronous cleanup functions
    306 ASYNC_CLEANUP = """
    307 function run_test() {
    308  // The list of checkpoints in the order we encounter them.
    309  let checkpoints = [];
    310 
    311  // Cleanup tasks, in reverse order
    312  registerCleanupFunction(function cleanup_checkout() {
    313    Assert.equal(checkpoints.join(""), "123456");
    314    info("At this stage, the test has succeeded");
    315    do_throw("Throwing an error to force displaying the log");
    316  });
    317 
    318  registerCleanupFunction(function sync_cleanup_2() {
    319    checkpoints.push(6);
    320  });
    321 
    322  registerCleanupFunction(async function async_cleanup_4() {
    323    await undefined;
    324    checkpoints.push(5);
    325  });
    326 
    327  registerCleanupFunction(async function async_cleanup_3() {
    328    await undefined;
    329    checkpoints.push(4);
    330  });
    331 
    332  registerCleanupFunction(function async_cleanup_2() {
    333    let deferred = Promise.withResolvers();
    334    executeSoon(deferred.resolve);
    335    return deferred.promise.then(function() {
    336      checkpoints.push(3);
    337    });
    338  });
    339 
    340  registerCleanupFunction(function sync_cleanup() {
    341    checkpoints.push(2);
    342  });
    343 
    344  registerCleanupFunction(function async_cleanup() {
    345    let deferred = Promise.withResolvers();
    346    executeSoon(deferred.resolve);
    347    return deferred.promise.then(function() {
    348      checkpoints.push(1);
    349    });
    350  });
    351 
    352 }
    353 """
    354 
    355 # A test to check that add_test() tests run without run_test()
    356 NO_RUN_TEST_ADD_TEST = """
    357 add_test(function no_run_test_add_test() {
    358  Assert.ok(true);
    359  run_next_test();
    360 });
    361 """
    362 
    363 # A test to check that add_task() tests run without run_test()
    364 NO_RUN_TEST_ADD_TASK = """
    365 add_task(function no_run_test_add_task() {
    366  Assert.ok(true);
    367 });
    368 """
    369 
    370 # A test to check that both add_task() and add_test() work without run_test()
    371 NO_RUN_TEST_ADD_TEST_ADD_TASK = """
    372 add_test(function no_run_test_add_test() {
    373  Assert.ok(true);
    374  run_next_test();
    375 });
    376 
    377 add_task(function no_run_test_add_task() {
    378  Assert.ok(true);
    379 });
    380 """
    381 
    382 # A test to check that an empty test file without run_test(),
    383 # add_test() or add_task() works.
    384 NO_RUN_TEST_EMPTY_TEST = """
    385 // This is an empty test file.
    386 """
    387 
    388 NO_RUN_TEST_ADD_TEST_FAIL = """
    389 add_test(function no_run_test_add_test_fail() {
    390  Assert.ok(false);
    391  run_next_test();
    392 });
    393 """
    394 
    395 NO_RUN_TEST_ADD_TASK_FAIL = """
    396 add_task(function no_run_test_add_task_fail() {
    397  Assert.ok(false);
    398 });
    399 """
    400 
    401 NO_RUN_TEST_ADD_TASK_MULTIPLE = """
    402 add_task(async function test_task() {
    403  await Promise.resolve(true);
    404 });
    405 
    406 add_task(async function test_2() {
    407  await Promise.resolve(true);
    408 });
    409 """
    410 
    411 LOAD_MOZINFO = """
    412 function run_test() {
    413  Assert.notEqual(typeof mozinfo, undefined);
    414  Assert.notEqual(typeof mozinfo.os, undefined);
    415 }
    416 """
    417 
    418 CHILD_MOZINFO = """
    419 function run_test () { run_next_test(); }
    420 
    421 add_test(function test_child_mozinfo () {
    422  run_test_in_child("test_mozinfo.js");
    423  run_next_test();
    424 });
    425 """
    426 
    427 HEADLESS_TRUE = """
    428 add_task(function headless_true() {
    429  Assert.equal(Services.env.get("MOZ_HEADLESS"), "1", "Check MOZ_HEADLESS");
    430  Assert.equal(Services.env.get("DISPLAY"), "77", "Check DISPLAY");
    431 });
    432 """
    433 
    434 HEADLESS_FALSE = """
    435 add_task(function headless_false() {
    436  Assert.notEqual(Services.env.get("MOZ_HEADLESS"), "1", "Check MOZ_HEADLESS");
    437  Assert.notEqual(Services.env.get("DISPLAY"), "77", "Check DISPLAY");
    438 });
    439 """
    440 
    441 
    442 class XPCShellTestsTests(unittest.TestCase):
    443    """
    444    Yes, these are unit tests for a unit test harness.
    445    """
    446 
    447    def __init__(self, name):
    448        super().__init__(name)
    449        from buildconfig import substs
    450        from mozbuild.base import MozbuildObject
    451 
    452        os.environ.pop("MOZ_OBJDIR", None)
    453        self.build_obj = MozbuildObject.from_environment()
    454 
    455        objdir = self.build_obj.topobjdir
    456        self.testing_modules = os.path.join(objdir, "_tests", "modules")
    457 
    458        if mozinfo.isMac:
    459            self.xpcshellBin = os.path.join(
    460                objdir,
    461                "dist",
    462                substs["MOZ_MACBUNDLE_NAME"],
    463                "Contents",
    464                "MacOS",
    465                "xpcshell",
    466            )
    467        else:
    468            self.xpcshellBin = os.path.join(objdir, "dist", "bin", "xpcshell")
    469 
    470        if sys.platform == "win32":
    471            self.xpcshellBin += ".exe"
    472        self.utility_path = os.path.join(objdir, "dist", "bin")
    473        self.symbols_path = None
    474        candidate_path = os.path.join(self.build_obj.distdir, "crashreporter-symbols")
    475        if os.path.isdir(candidate_path):
    476            self.symbols_path = candidate_path
    477 
    478    def setUp(self):
    479        self.log = six.StringIO()
    480        self.tempdir = tempfile.mkdtemp()
    481        logger = structured.commandline.setup_logging(
    482            "selftest%s" % id(self), {}, {"tbpl": self.log}
    483        )
    484        self.x = XPCShellTests(logger)
    485        self.x.harness_timeout = 30 if not mozinfo.info["ccov"] else 60
    486 
    487    def tearDown(self):
    488        mozfile.remove(self.tempdir)
    489        self.x.shutdownNode()
    490 
    491    def writeFile(self, name, contents, mode="w"):
    492        """
    493        Write |contents| to a file named |name| in the temp directory,
    494        and return the full path to the file.
    495        """
    496        fullpath = os.path.join(self.tempdir, name)
    497        with open(fullpath, mode) as f:
    498            f.write(contents)
    499        return fullpath
    500 
    501    def writeManifest(self, tests, prefs=[]):
    502        """
    503        Write an xpcshell.toml in the temp directory and set
    504        self.manifest to its pathname. |tests| is a list containing
    505        either strings (for test names), or tuples with a test name
    506        as the first element and manifest conditions as the following
    507        elements. |prefs| is an optional list of prefs in the form of
    508        "prefname=prefvalue" strings.
    509        """
    510        testlines = []
    511        for t in tests:
    512            testlines.append('["%s"]' % (t if isinstance(t, str) else t[0]))
    513            if isinstance(t, tuple):
    514                testlines.extend(t[1:])
    515        prefslines = []
    516        for p in prefs:
    517            # Append prefs lines as indented inside "prefs=" manifest option.
    518            prefslines.append('  "%s",' % p)
    519 
    520        val = """
    521 [DEFAULT]
    522 head = ""
    523 tail = ""
    524 prefs = [
    525 """
    526        val += "\n".join(prefslines)
    527        val += "]\n"
    528        val += "\n".join(testlines)
    529        self.manifest = self.writeFile("xpcshell.toml", val)
    530 
    531    def assertTestResult(self, expected, shuffle=False, verbose=False, headless=False):
    532        """
    533        Assert that self.x.runTests with manifest=self.manifest
    534        returns |expected|.
    535        """
    536        kwargs = {}
    537        kwargs["app_binary"] = self.app_binary
    538        kwargs["xpcshell"] = self.xpcshellBin
    539        kwargs["symbolsPath"] = self.symbols_path
    540        kwargs["manifest"] = self.manifest
    541        kwargs["mozInfo"] = mozinfo.info
    542        kwargs["shuffle"] = shuffle
    543        kwargs["verbose"] = verbose
    544        kwargs["headless"] = headless
    545        kwargs["selfTest"] = True  # Prevent singleFile from forcing sequential=True
    546        kwargs["testingModulesDir"] = self.testing_modules
    547        kwargs["utility_path"] = self.utility_path
    548        kwargs["repeat"] = 0
    549        # Don't retry tests that are expected to fail
    550        if not expected:
    551            kwargs["retry"] = False
    552 
    553        startup_profiling = os.environ.pop("MOZ_PROFILER_STARTUP", None)
    554        try:
    555            self.assertEqual(
    556                expected,
    557                self.x.runTests(kwargs),
    558                msg="""Tests should have %s, log:
    559 ========
    560 %s
    561 ========
    562 """
    563                % ("passed" if expected else "failed", self.log.getvalue()),
    564            )
    565        finally:
    566            if startup_profiling:
    567                os.environ["MOZ_PROFILER_STARTUP"] = startup_profiling
    568 
    569    def _assertLog(self, s, expected):
    570        l = self.log.getvalue()
    571        self.assertEqual(
    572            expected,
    573            s in l,
    574            msg="""Value %s %s in log:
    575 ========
    576 %s
    577 ========"""
    578            % (s, "expected" if expected else "not expected", l),
    579        )
    580 
    581    def assertInLog(self, s):
    582        """
    583        Assert that the string |s| is contained in self.log.
    584        """
    585        self._assertLog(s, True)
    586 
    587    def assertNotInLog(self, s):
    588        """
    589        Assert that the string |s| is not contained in self.log.
    590        """
    591        self._assertLog(s, False)
    592 
    593    def testPass(self):
    594        """
    595        Check that a simple test without any manifest conditions passes.
    596        """
    597        self.writeFile("test_basic.js", SIMPLE_PASSING_TEST)
    598        self.writeManifest(["test_basic.js"])
    599 
    600        self.assertTestResult(True)
    601        self.assertEqual(1, self.x.testCount)
    602        self.assertEqual(1, self.x.passCount)
    603        self.assertEqual(0, self.x.failCount)
    604        self.assertEqual(0, self.x.todoCount)
    605        self.assertInLog(TEST_PASS_STRING)
    606        self.assertNotInLog(TEST_FAIL_STRING)
    607 
    608    def testFail(self):
    609        """
    610        Check that a simple failing test without any manifest conditions fails.
    611        """
    612        self.writeFile("test_basic.js", SIMPLE_FAILING_TEST)
    613        self.writeManifest(["test_basic.js"])
    614 
    615        self.assertTestResult(False)
    616        self.assertEqual(1, self.x.testCount)
    617        self.assertEqual(0, self.x.passCount)
    618        self.assertEqual(1, self.x.failCount)
    619        self.assertEqual(0, self.x.todoCount)
    620        self.assertInLog(TEST_FAIL_STRING)
    621        self.assertNotInLog(TEST_PASS_STRING)
    622 
    623    def testPrefsInManifestVerbose(self):
    624        """
    625        Check prefs configuration option is supported in xpcshell manifests.
    626        """
    627        self.writeFile("test_prefs.js", SIMPLE_PREFCHECK_TEST)
    628        self.writeManifest(tests=["test_prefs.js"], prefs=["fake.pref.to.test=true"])
    629 
    630        self.assertTestResult(True, verbose=True)
    631        self.assertInLog(TEST_PASS_STRING)
    632        self.assertNotInLog(TEST_FAIL_STRING)
    633        self.assertEqual(1, self.x.testCount)
    634        self.assertEqual(1, self.x.passCount)
    635        self.assertInLog("Per-test extra prefs will be set:")
    636        self.assertInLog("fake.pref.to.test=true")
    637 
    638    def testPrefsInManifestNonVerbose(self):
    639        """
    640        Check prefs configuration are not logged in non verbose mode.
    641        """
    642        self.writeFile("test_prefs.js", SIMPLE_PREFCHECK_TEST)
    643        self.writeManifest(tests=["test_prefs.js"], prefs=["fake.pref.to.test=true"])
    644 
    645        self.assertTestResult(True, verbose=False)
    646        self.assertNotInLog("Per-test extra prefs will be set:")
    647        self.assertNotInLog("fake.pref.to.test=true")
    648 
    649    @unittest.skipIf(
    650        mozinfo.isWin or not mozinfo.info.get("debug"),
    651        "We don't have a stack fixer on hand for windows.",
    652    )
    653    def testAssertStack(self):
    654        """
    655        When an assertion is hit, we should produce a useful stack.
    656        """
    657        self.writeFile(
    658            "test_assert.js",
    659            """
    660          add_test(function test_asserts_immediately() {
    661            Components.classes["@mozilla.org/xpcom/debug;1"]
    662                      .getService(Components.interfaces.nsIDebug2)
    663                      .assertion("foo", "assertion failed", "test.js", 1)
    664            run_next_test();
    665          });
    666        """,
    667        )
    668 
    669        self.writeManifest(["test_assert.js"])
    670        self.assertTestResult(False)
    671 
    672        self.assertInLog("###!!! ASSERTION")
    673        log_lines = self.log.getvalue().splitlines()
    674        line_pat = r"#\d\d:"
    675        unknown_pat = r"#\d\d\: \?\?\?\[.* \+0x[a-f0-9]+\]"
    676        self.assertFalse(
    677            any(re.search(unknown_pat, line) for line in log_lines),
    678            "An stack frame without symbols was found in\n%s"
    679            % pprint.pformat(log_lines),
    680        )
    681        self.assertTrue(
    682            any(re.search(line_pat, line) for line in log_lines),
    683            "No line resembling a stack frame was found in\n%s"
    684            % pprint.pformat(log_lines),
    685        )
    686 
    687    def testChildPass(self):
    688        """
    689        Check that a simple test running in a child process passes.
    690        """
    691        self.writeFile("test_pass.js", SIMPLE_PASSING_TEST)
    692        self.writeFile("test_child_pass.js", CHILD_TEST_PASSING)
    693        self.writeManifest(["test_child_pass.js"])
    694 
    695        self.assertTestResult(True, verbose=True)
    696        self.assertEqual(1, self.x.testCount)
    697        self.assertEqual(1, self.x.passCount)
    698        self.assertEqual(0, self.x.failCount)
    699        self.assertEqual(0, self.x.todoCount)
    700        self.assertInLog(TEST_PASS_STRING)
    701        self.assertInLog("CHILD-TEST-STARTED")
    702        self.assertInLog("CHILD-TEST-COMPLETED")
    703        self.assertNotInLog(TEST_FAIL_STRING)
    704 
    705    def testChildFail(self):
    706        """
    707        Check that a simple failing test running in a child process fails.
    708        """
    709        self.writeFile("test_fail.js", SIMPLE_FAILING_TEST)
    710        self.writeFile("test_child_fail.js", CHILD_TEST_FAILING)
    711        self.writeManifest(["test_child_fail.js"])
    712 
    713        self.assertTestResult(False)
    714        self.assertEqual(1, self.x.testCount)
    715        self.assertEqual(0, self.x.passCount)
    716        self.assertEqual(1, self.x.failCount)
    717        self.assertEqual(0, self.x.todoCount)
    718        self.assertInLog(TEST_FAIL_STRING)
    719        self.assertInLog("CHILD-TEST-STARTED")
    720        self.assertInLog("CHILD-TEST-COMPLETED")
    721        self.assertNotInLog(TEST_PASS_STRING)
    722 
    723    def testChildHang(self):
    724        """
    725        Check that incomplete output from a child process results in a
    726        test failure.
    727        """
    728        self.writeFile("test_pass.js", SIMPLE_PASSING_TEST)
    729        self.writeFile("test_child_hang.js", CHILD_TEST_HANG)
    730        self.writeManifest(["test_child_hang.js"])
    731 
    732        self.assertTestResult(False)
    733        self.assertEqual(1, self.x.testCount)
    734        self.assertEqual(0, self.x.passCount)
    735        self.assertEqual(1, self.x.failCount)
    736        self.assertEqual(0, self.x.todoCount)
    737        self.assertInLog(TEST_FAIL_STRING)
    738        self.assertInLog("CHILD-TEST-STARTED")
    739        self.assertNotInLog("CHILD-TEST-COMPLETED")
    740        self.assertNotInLog(TEST_PASS_STRING)
    741 
    742    def testChild(self):
    743        """
    744        Checks that calling do_load_child_test_harness without run_test_in_child
    745        results in a usable test state. This test has a spurious failure when
    746        run using |mach python-test|. See bug 1103226.
    747        """
    748        self.writeFile("test_child_assertions.js", CHILD_HARNESS_SIMPLE)
    749        self.writeManifest(["test_child_assertions.js"])
    750 
    751        self.assertTestResult(True)
    752        self.assertEqual(1, self.x.testCount)
    753        self.assertEqual(1, self.x.passCount)
    754        self.assertEqual(0, self.x.failCount)
    755        self.assertEqual(0, self.x.todoCount)
    756        self.assertInLog(TEST_PASS_STRING)
    757        self.assertNotInLog(TEST_FAIL_STRING)
    758 
    759    def testSkipForAddTest(self):
    760        """
    761        Check that add_test is skipped if |skip_if| condition is true
    762        """
    763        self.writeFile(
    764            "test_skip.js",
    765            """
    766 add_test({
    767  skip_if: () => true,
    768 }, function test_should_be_skipped() {
    769  Assert.ok(false);
    770  run_next_test();
    771 });
    772 """,
    773        )
    774        self.writeManifest(["test_skip.js"])
    775        self.assertTestResult(True, verbose=True)
    776        self.assertEqual(1, self.x.testCount)
    777        self.assertEqual(1, self.x.passCount)
    778        self.assertEqual(0, self.x.failCount)
    779        self.assertEqual(0, self.x.todoCount)
    780        self.assertInLog(TEST_PASS_STRING)
    781        self.assertInLog("TEST-SKIP")
    782        self.assertNotInLog(TEST_FAIL_STRING)
    783 
    784    def testNotSkipForAddTask(self):
    785        """
    786        Check that add_task is not skipped if |skip_if| condition is false
    787        """
    788        self.writeFile(
    789            "test_not_skip.js",
    790            """
    791 add_task({
    792  skip_if: () => false,
    793 }, function test_should_not_be_skipped() {
    794  Assert.ok(true);
    795 });
    796 """,
    797        )
    798        self.writeManifest(["test_not_skip.js"])
    799        self.assertTestResult(True, verbose=True)
    800        self.assertEqual(1, self.x.testCount)
    801        self.assertEqual(1, self.x.passCount)
    802        self.assertEqual(0, self.x.failCount)
    803        self.assertEqual(0, self.x.todoCount)
    804        self.assertInLog(TEST_PASS_STRING)
    805        self.assertNotInLog("TEST-SKIP")
    806        self.assertNotInLog(TEST_FAIL_STRING)
    807 
    808    def testSkipForAddTask(self):
    809        """
    810        Check that add_task is skipped if |skip_if| condition is true
    811        """
    812        self.writeFile(
    813            "test_skip.js",
    814            """
    815 add_task({
    816  skip_if: () => true,
    817 }, function test_should_be_skipped() {
    818  Assert.ok(false);
    819 });
    820 """,
    821        )
    822        self.writeManifest(["test_skip.js"])
    823        self.assertTestResult(True, verbose=True)
    824        self.assertEqual(1, self.x.testCount)
    825        self.assertEqual(1, self.x.passCount)
    826        self.assertEqual(0, self.x.failCount)
    827        self.assertEqual(0, self.x.todoCount)
    828        self.assertInLog(TEST_PASS_STRING)
    829        self.assertInLog("TEST-SKIP")
    830        self.assertNotInLog(TEST_FAIL_STRING)
    831 
    832    def testNotSkipForAddTest(self):
    833        """
    834        Check that add_test is not skipped if |skip_if| condition is false
    835        """
    836        self.writeFile(
    837            "test_not_skip.js",
    838            """
    839 add_test({
    840  skip_if: () => false,
    841 }, function test_should_not_be_skipped() {
    842  Assert.ok(true);
    843  run_next_test();
    844 });
    845 """,
    846        )
    847        self.writeManifest(["test_not_skip.js"])
    848        self.assertTestResult(True, verbose=True)
    849        self.assertEqual(1, self.x.testCount)
    850        self.assertEqual(1, self.x.passCount)
    851        self.assertEqual(0, self.x.failCount)
    852        self.assertEqual(0, self.x.todoCount)
    853        self.assertInLog(TEST_PASS_STRING)
    854        self.assertNotInLog("TEST-SKIP")
    855        self.assertNotInLog(TEST_FAIL_STRING)
    856 
    857    def testSyntaxError(self):
    858        """
    859        Check that running a test file containing a syntax error produces
    860        a test failure and expected output.
    861        """
    862        self.writeFile("test_syntax_error.js", '"')
    863        self.writeManifest(["test_syntax_error.js"])
    864 
    865        self.assertTestResult(False, verbose=True)
    866        self.assertEqual(1, self.x.testCount)
    867        self.assertEqual(0, self.x.passCount)
    868        self.assertEqual(1, self.x.failCount)
    869        self.assertEqual(0, self.x.todoCount)
    870        self.assertInLog(TEST_FAIL_STRING)
    871        self.assertNotInLog(TEST_PASS_STRING)
    872 
    873    def testUnicodeInAssertMethods(self):
    874        """
    875        Check that passing unicode characters through an assertion method works.
    876        """
    877        self.writeFile("test_unicode_assert.js", PASSING_TEST_UNICODE, mode="wb")
    878        self.writeManifest(["test_unicode_assert.js"])
    879 
    880        self.assertTestResult(True, verbose=True)
    881 
    882    @unittest.skipIf(
    883        "MOZ_AUTOMATION" in os.environ,
    884        "Timeout code path occasionally times out (bug 1098121)",
    885    )
    886    def testHangingTimeout(self):
    887        """
    888        Check that a test that never finishes results in the correct error log.
    889        """
    890        self.writeFile("test_loop.js", SIMPLE_LOOPING_TEST)
    891        self.writeManifest(["test_loop.js"])
    892 
    893        old_timeout = self.x.harness_timeout
    894        self.x.harness_timeout = 1
    895 
    896        self.assertTestResult(False)
    897        self.assertEqual(1, self.x.testCount)
    898        self.assertEqual(1, self.x.failCount)
    899        self.assertEqual(0, self.x.passCount)
    900        self.assertEqual(0, self.x.todoCount)
    901        self.assertInLog("TEST-UNEXPECTED-TIMEOUT")
    902 
    903        self.x.harness_timeout = old_timeout
    904 
    905    def testPassFail(self):
    906        """
    907        Check that running more than one test works.
    908        """
    909        self.writeFile("test_pass.js", SIMPLE_PASSING_TEST)
    910        self.writeFile("test_fail.js", SIMPLE_FAILING_TEST)
    911        self.writeManifest(["test_pass.js", "test_fail.js"])
    912 
    913        self.assertTestResult(False)
    914        self.assertEqual(2, self.x.testCount)
    915        self.assertEqual(1, self.x.passCount)
    916        self.assertEqual(1, self.x.failCount)
    917        self.assertEqual(0, self.x.todoCount)
    918        self.assertInLog(TEST_PASS_STRING)
    919        self.assertInLog(TEST_FAIL_STRING)
    920 
    921    def testSkip(self):
    922        """
    923        Check that a simple failing test skipped in the manifest does
    924        not cause failure.
    925        """
    926        self.writeFile("test_basic.js", SIMPLE_FAILING_TEST)
    927        self.writeManifest([("test_basic.js", "skip-if = true")])
    928        self.assertTestResult(True)
    929        self.assertEqual(1, self.x.testCount)
    930        self.assertEqual(0, self.x.passCount)
    931        self.assertEqual(0, self.x.failCount)
    932        self.assertEqual(0, self.x.todoCount)
    933        self.assertNotInLog(TEST_FAIL_STRING)
    934        self.assertNotInLog(TEST_PASS_STRING)
    935 
    936    def testKnownFail(self):
    937        """
    938        Check that a simple failing test marked as known-fail in the manifest
    939        does not cause failure.
    940        """
    941        self.writeFile("test_basic.js", SIMPLE_FAILING_TEST)
    942        self.writeManifest([("test_basic.js", "fail-if = true")])
    943        self.assertTestResult(True)
    944        self.assertEqual(1, self.x.testCount)
    945        self.assertEqual(0, self.x.passCount)
    946        self.assertEqual(0, self.x.failCount)
    947        self.assertEqual(1, self.x.todoCount)
    948        self.assertInLog("TEST-FAIL")
    949        # This should be suppressed because the harness doesn't include
    950        # the full log from the xpcshell run when things pass.
    951        self.assertNotInLog(TEST_FAIL_STRING)
    952        self.assertNotInLog(TEST_PASS_STRING)
    953 
    954    def testUnexpectedPass(self):
    955        """
    956        Check that a simple failing test marked as known-fail in the manifest
    957        that passes causes an unexpected pass.
    958        """
    959        self.writeFile("test_basic.js", SIMPLE_PASSING_TEST)
    960        self.writeManifest([("test_basic.js", "fail-if = true")])
    961        self.assertTestResult(False)
    962        self.assertEqual(1, self.x.testCount)
    963        self.assertEqual(0, self.x.passCount)
    964        self.assertEqual(1, self.x.failCount)
    965        self.assertEqual(0, self.x.todoCount)
    966        # From the outer (Python) harness
    967        self.assertInLog("TEST-UNEXPECTED-PASS")
    968        self.assertNotInLog("TEST-KNOWN-FAIL")
    969 
    970    def testReturnNonzero(self):
    971        """
    972        Check that a test where xpcshell returns nonzero fails.
    973        """
    974        self.writeFile("test_error.js", "throw 'foo'")
    975        self.writeManifest(["test_error.js"])
    976 
    977        self.assertTestResult(False)
    978        self.assertEqual(1, self.x.testCount)
    979        self.assertEqual(0, self.x.passCount)
    980        self.assertEqual(1, self.x.failCount)
    981        self.assertEqual(0, self.x.todoCount)
    982        self.assertInLog(TEST_FAIL_STRING)
    983        self.assertNotInLog(TEST_PASS_STRING)
    984 
    985    def testUncaughtRejection(self):
    986        """
    987        Ensure a simple test with an uncaught rejection is reported.
    988        """
    989        self.writeFile(
    990            "test_simple_uncaught_rejection.js", SIMPLE_UNCAUGHT_REJECTION_TEST
    991        )
    992        self.writeManifest(["test_simple_uncaught_rejection.js"])
    993 
    994        self.assertTestResult(False)
    995        self.assertInLog(TEST_FAIL_STRING)
    996        self.assertInLog("test_simple_uncaught_rejection.js:3:18")
    997        self.assertInLog("Test rejection.")
    998        self.assertEqual(1, self.x.testCount)
    999        self.assertEqual(0, self.x.passCount)
   1000        self.assertEqual(1, self.x.failCount)
   1001 
   1002    def testAddTestSimple(self):
   1003        """
   1004        Ensure simple add_test() works.
   1005        """
   1006        self.writeFile("test_add_test_simple.js", ADD_TEST_SIMPLE)
   1007        self.writeManifest(["test_add_test_simple.js"])
   1008 
   1009        self.assertTestResult(True)
   1010        self.assertEqual(1, self.x.testCount)
   1011        self.assertEqual(1, self.x.passCount)
   1012        self.assertEqual(0, self.x.failCount)
   1013 
   1014    def testCrashLogging(self):
   1015        """
   1016        Test that a crashing test process logs a failure.
   1017        """
   1018        self.writeFile("test_crashes.js", TEST_CRASHING)
   1019        self.writeManifest(["test_crashes.js"])
   1020 
   1021        self.assertTestResult(False)
   1022        self.assertEqual(1, self.x.testCount)
   1023        self.assertEqual(0, self.x.passCount)
   1024        self.assertEqual(1, self.x.failCount)
   1025        if mozinfo.info.get("crashreporter"):
   1026            self.assertInLog("\nPROCESS-CRASH")
   1027 
   1028    def testLogCorrectFileName(self):
   1029        """
   1030        Make sure a meaningful filename and line number is logged
   1031        by a passing test.
   1032        """
   1033        self.writeFile("test_add_test_simple.js", ADD_TEST_SIMPLE)
   1034        self.writeManifest(["test_add_test_simple.js"])
   1035 
   1036        self.assertTestResult(True, verbose=True)
   1037        self.assertInLog("true == true")
   1038        self.assertNotInLog("[Assert.ok :")
   1039        self.assertInLog("[test_simple : 5]")
   1040 
   1041    def testAddTestFailing(self):
   1042        """
   1043        Ensure add_test() with a failing test is reported.
   1044        """
   1045        self.writeFile("test_add_test_failing.js", ADD_TEST_FAILING)
   1046        self.writeManifest(["test_add_test_failing.js"])
   1047 
   1048        self.assertTestResult(False)
   1049        self.assertEqual(1, self.x.testCount)
   1050        self.assertEqual(0, self.x.passCount)
   1051        self.assertEqual(1, self.x.failCount)
   1052 
   1053    def testAddTestUncaughtRejection(self):
   1054        """
   1055        Ensure add_test() with an uncaught rejection is reported.
   1056        """
   1057        self.writeFile(
   1058            "test_add_test_uncaught_rejection.js", ADD_TEST_UNCAUGHT_REJECTION
   1059        )
   1060        self.writeManifest(["test_add_test_uncaught_rejection.js"])
   1061 
   1062        self.assertTestResult(False)
   1063        self.assertEqual(1, self.x.testCount)
   1064        self.assertEqual(0, self.x.passCount)
   1065        self.assertEqual(1, self.x.failCount)
   1066 
   1067    def testAddTaskTestSingle(self):
   1068        """
   1069        Ensure add_test_task() with a single passing test works.
   1070        """
   1071        self.writeFile("test_add_task_simple.js", ADD_TASK_SINGLE)
   1072        self.writeManifest(["test_add_task_simple.js"])
   1073 
   1074        self.assertTestResult(True)
   1075        self.assertEqual(1, self.x.testCount)
   1076        self.assertEqual(1, self.x.passCount)
   1077        self.assertEqual(0, self.x.failCount)
   1078 
   1079    def testAddTaskTestMultiple(self):
   1080        """
   1081        Ensure multiple calls to add_test_task() work as expected.
   1082        """
   1083        self.writeFile("test_add_task_multiple.js", ADD_TASK_MULTIPLE)
   1084        self.writeManifest(["test_add_task_multiple.js"])
   1085 
   1086        self.assertTestResult(True)
   1087        self.assertEqual(1, self.x.testCount)
   1088        self.assertEqual(1, self.x.passCount)
   1089        self.assertEqual(0, self.x.failCount)
   1090 
   1091    def testAddTaskTestRejected(self):
   1092        """
   1093        Ensure rejected task reports as failure.
   1094        """
   1095        self.writeFile("test_add_task_rejected.js", ADD_TASK_REJECTED)
   1096        self.writeManifest(["test_add_task_rejected.js"])
   1097 
   1098        self.assertTestResult(False)
   1099        self.assertEqual(1, self.x.testCount)
   1100        self.assertEqual(0, self.x.passCount)
   1101        self.assertEqual(1, self.x.failCount)
   1102 
   1103    def testAddTaskTestRejectedUndefined(self):
   1104        """
   1105        Ensure rejected task with undefined reason reports as failure and does not hang.
   1106        """
   1107        self.writeFile(
   1108            "test_add_task_rejected_undefined.js", ADD_TASK_REJECTED_UNDEFINED
   1109        )
   1110        self.writeManifest(["test_add_task_rejected_undefined.js"])
   1111 
   1112        self.assertTestResult(False)
   1113        self.assertEqual(1, self.x.testCount)
   1114        self.assertEqual(0, self.x.passCount)
   1115        self.assertEqual(1, self.x.failCount)
   1116        self.assertNotInLog("TEST-UNEXPECTED-TIMEOUT")
   1117 
   1118    def testAddTaskTestFailureInside(self):
   1119        """
   1120        Ensure tests inside task are reported as failures.
   1121        """
   1122        self.writeFile("test_add_task_failure_inside.js", ADD_TASK_FAILURE_INSIDE)
   1123        self.writeManifest(["test_add_task_failure_inside.js"])
   1124 
   1125        self.assertTestResult(False)
   1126        self.assertEqual(1, self.x.testCount)
   1127        self.assertEqual(0, self.x.passCount)
   1128        self.assertEqual(1, self.x.failCount)
   1129 
   1130    def testAddTaskRunNextTest(self):
   1131        """
   1132        Calling run_next_test() from inside add_task() results in failure.
   1133        """
   1134        self.writeFile("test_add_task_run_next_test.js", ADD_TASK_RUN_NEXT_TEST)
   1135        self.writeManifest(["test_add_task_run_next_test.js"])
   1136 
   1137        self.assertTestResult(False)
   1138        self.assertEqual(1, self.x.testCount)
   1139        self.assertEqual(0, self.x.passCount)
   1140        self.assertEqual(1, self.x.failCount)
   1141 
   1142    def testAddTaskStackTrace(self):
   1143        """
   1144        Ensuring that calling Assert.ok(false) from inside add_task()
   1145        results in a human-readable stack trace.
   1146        """
   1147        self.writeFile("test_add_task_stack_trace.js", ADD_TASK_STACK_TRACE)
   1148        self.writeManifest(["test_add_task_stack_trace.js"])
   1149 
   1150        self.assertTestResult(False)
   1151        self.assertInLog("this_test_will_fail")
   1152        self.assertInLog("run_next_test")
   1153        self.assertInLog("run_test")
   1154 
   1155    def testAddTaskSkip(self):
   1156        self.writeFile("test_tasks_skip.js", ADD_TASK_SKIP)
   1157        self.writeManifest(["test_tasks_skip.js"])
   1158 
   1159        self.assertTestResult(True)
   1160        self.assertEqual(1, self.x.testCount)
   1161        self.assertEqual(1, self.x.passCount)
   1162        self.assertEqual(0, self.x.failCount)
   1163 
   1164    def testAddTaskSkipAll(self):
   1165        self.writeFile("test_tasks_skipall.js", ADD_TASK_SKIPALL)
   1166        self.writeManifest(["test_tasks_skipall.js"])
   1167 
   1168        self.assertTestResult(True)
   1169        self.assertEqual(1, self.x.testCount)
   1170        self.assertEqual(1, self.x.passCount)
   1171        self.assertEqual(0, self.x.failCount)
   1172 
   1173    def testMissingHeadFile(self):
   1174        """
   1175        Ensure that missing head file results in fatal failure.
   1176        """
   1177        self.writeFile("test_basic.js", SIMPLE_PASSING_TEST)
   1178        self.writeManifest([("test_basic.js", 'head = "missing.js"')])
   1179 
   1180        raised = False
   1181 
   1182        try:
   1183            # The actual return value is never checked because we raise.
   1184            self.assertTestResult(True)
   1185        except Exception as ex:
   1186            raised = True
   1187            self.assertEqual(str(ex)[0:9], "head file")
   1188 
   1189        self.assertTrue(raised)
   1190 
   1191    def testRandomExecution(self):
   1192        """
   1193        Check that random execution doesn't break.
   1194        """
   1195        manifest = []
   1196        for i in range(0, 10):
   1197            filename = "test_pass_%d.js" % i
   1198            self.writeFile(filename, SIMPLE_PASSING_TEST)
   1199            manifest.append(filename)
   1200 
   1201        self.writeManifest(manifest)
   1202        self.assertTestResult(True, shuffle=True)
   1203        self.assertEqual(10, self.x.testCount)
   1204        self.assertEqual(10, self.x.passCount)
   1205 
   1206    def testDoThrowString(self):
   1207        """
   1208        Check that do_throw produces reasonable messages when the
   1209        input is a string instead of an object
   1210        """
   1211        self.writeFile("test_error.js", ADD_TEST_THROW_STRING)
   1212        self.writeManifest(["test_error.js"])
   1213 
   1214        self.assertTestResult(False)
   1215        self.assertInLog(TEST_FAIL_STRING)
   1216        self.assertInLog("Passing a string to do_throw")
   1217        self.assertNotInLog(TEST_PASS_STRING)
   1218 
   1219    def testDoThrowForeignObject(self):
   1220        """
   1221        Check that do_throw produces reasonable messages when the
   1222        input is a generic object with 'filename', 'message' and 'stack' attributes
   1223        but 'object instanceof Error' returns false
   1224        """
   1225        self.writeFile("test_error.js", ADD_TEST_THROW_OBJECT)
   1226        self.writeManifest(["test_error.js"])
   1227 
   1228        self.assertTestResult(False)
   1229        self.assertInLog(TEST_FAIL_STRING)
   1230        self.assertInLog("failure.js")
   1231        self.assertInLog("Error object")
   1232        self.assertInLog("ERROR STACK")
   1233        self.assertNotInLog(TEST_PASS_STRING)
   1234 
   1235    def testDoReportForeignObject(self):
   1236        """
   1237        Check that do_report_unexpected_exception produces reasonable messages when the
   1238        input is a generic object with 'filename', 'message' and 'stack' attributes
   1239        but 'object instanceof Error' returns false
   1240        """
   1241        self.writeFile("test_error.js", ADD_TEST_REPORT_OBJECT)
   1242        self.writeManifest(["test_error.js"])
   1243 
   1244        self.assertTestResult(False)
   1245        self.assertInLog(TEST_FAIL_STRING)
   1246        self.assertInLog("failure.js")
   1247        self.assertInLog("Error object")
   1248        self.assertInLog("ERROR STACK")
   1249        self.assertNotInLog(TEST_PASS_STRING)
   1250 
   1251    def testDoReportRefError(self):
   1252        """
   1253        Check that do_report_unexpected_exception produces reasonable messages when the
   1254        input is a JS-generated Error
   1255        """
   1256        self.writeFile("test_error.js", ADD_TEST_REPORT_REF_ERROR)
   1257        self.writeManifest(["test_error.js"])
   1258 
   1259        self.assertTestResult(False)
   1260        self.assertInLog(TEST_FAIL_STRING)
   1261        self.assertInLog("test_error.js")
   1262        self.assertInLog("obj.noSuchFunction is not a function")
   1263        self.assertInLog("run_test@")
   1264        self.assertNotInLog(TEST_PASS_STRING)
   1265 
   1266    def testDoReportSyntaxError(self):
   1267        """
   1268        Check that attempting to load a test file containing a syntax error
   1269        generates details of the error in the log
   1270        """
   1271        self.writeFile("test_error.js", LOAD_ERROR_SYNTAX_ERROR)
   1272        self.writeManifest(["test_error.js"])
   1273 
   1274        self.assertTestResult(False)
   1275        self.assertInLog(TEST_FAIL_STRING)
   1276        self.assertInLog("test_error.js:3")
   1277        self.assertNotInLog(TEST_PASS_STRING)
   1278 
   1279    def testDoReportNonSyntaxError(self):
   1280        """
   1281        Check that attempting to load a test file containing an error other
   1282        than a syntax error generates details of the error in the log
   1283        """
   1284        self.writeFile("test_error.js", LOAD_ERROR_OTHER_ERROR)
   1285        self.writeManifest(["test_error.js"])
   1286 
   1287        self.assertTestResult(False)
   1288        self.assertInLog(TEST_FAIL_STRING)
   1289        self.assertInLog("ReferenceError: assignment to undeclared variable")
   1290        self.assertInLog("test_error.js:3")
   1291        self.assertNotInLog(TEST_PASS_STRING)
   1292 
   1293    def testDoPrintWhenVerboseNotExplicit(self):
   1294        """
   1295        Check that info() and similar calls that generate output do
   1296        not have the output when not run verbosely.
   1297        """
   1298        self.writeFile("test_verbose.js", ADD_TEST_VERBOSE)
   1299        self.writeManifest(["test_verbose.js"])
   1300 
   1301        self.assertTestResult(True)
   1302        self.assertNotInLog("a message from info")
   1303 
   1304    def testDoPrintWhenVerboseExplicit(self):
   1305        """
   1306        Check that info() and similar calls that generate output have the
   1307        output shown when run verbosely.
   1308        """
   1309        self.writeFile("test_verbose.js", ADD_TEST_VERBOSE)
   1310        self.writeManifest(["test_verbose.js"])
   1311        self.assertTestResult(True, verbose=True)
   1312        self.assertInLog("a message from info")
   1313 
   1314    def testDoPrintWhenVerboseInManifest(self):
   1315        """
   1316        Check that info() and similar calls that generate output have the
   1317        output shown when 'verbose = true' is in the manifest, even when
   1318        not run verbosely.
   1319        """
   1320        self.writeFile("test_verbose.js", ADD_TEST_VERBOSE)
   1321        self.writeManifest([("test_verbose.js", "verbose = true")])
   1322 
   1323        self.assertTestResult(True)
   1324        self.assertInLog("a message from info")
   1325 
   1326    def testAsyncCleanup(self):
   1327        """
   1328        Check that registerCleanupFunction handles nicely async cleanup tasks
   1329        """
   1330        self.writeFile("test_asyncCleanup.js", ASYNC_CLEANUP)
   1331        self.writeManifest(["test_asyncCleanup.js"])
   1332        self.assertTestResult(False)
   1333        self.assertInLog('"123456" == "123456"')
   1334        self.assertInLog("At this stage, the test has succeeded")
   1335        self.assertInLog("Throwing an error to force displaying the log")
   1336 
   1337    def testNoRunTestAddTest(self):
   1338        """
   1339        Check that add_test() works fine without run_test() in the test file.
   1340        """
   1341        self.writeFile("test_noRunTestAddTest.js", NO_RUN_TEST_ADD_TEST)
   1342        self.writeManifest(["test_noRunTestAddTest.js"])
   1343 
   1344        self.assertTestResult(True)
   1345        self.assertEqual(1, self.x.testCount)
   1346        self.assertEqual(1, self.x.passCount)
   1347        self.assertEqual(0, self.x.failCount)
   1348        self.assertInLog(TEST_PASS_STRING)
   1349        self.assertNotInLog(TEST_FAIL_STRING)
   1350 
   1351    def testNoRunTestAddTask(self):
   1352        """
   1353        Check that add_task() works fine without run_test() in the test file.
   1354        """
   1355        self.writeFile("test_noRunTestAddTask.js", NO_RUN_TEST_ADD_TASK)
   1356        self.writeManifest(["test_noRunTestAddTask.js"])
   1357 
   1358        self.assertTestResult(True)
   1359        self.assertEqual(1, self.x.testCount)
   1360        self.assertEqual(1, self.x.passCount)
   1361        self.assertEqual(0, self.x.failCount)
   1362        self.assertInLog(TEST_PASS_STRING)
   1363        self.assertNotInLog(TEST_FAIL_STRING)
   1364 
   1365    def testNoRunTestAddTestAddTask(self):
   1366        """
   1367        Check that both add_test() and add_task() work without run_test()
   1368        in the test file.
   1369        """
   1370        self.writeFile("test_noRunTestAddTestAddTask.js", NO_RUN_TEST_ADD_TEST_ADD_TASK)
   1371        self.writeManifest(["test_noRunTestAddTestAddTask.js"])
   1372 
   1373        self.assertTestResult(True)
   1374        self.assertEqual(1, self.x.testCount)
   1375        self.assertEqual(1, self.x.passCount)
   1376        self.assertEqual(0, self.x.failCount)
   1377        self.assertInLog(TEST_PASS_STRING)
   1378        self.assertNotInLog(TEST_FAIL_STRING)
   1379 
   1380    def testNoRunTestEmptyTest(self):
   1381        """
   1382        Check that the test passes on an empty file that contains neither
   1383        run_test() nor add_test(), add_task().
   1384        """
   1385        self.writeFile("test_noRunTestEmptyTest.js", NO_RUN_TEST_EMPTY_TEST)
   1386        self.writeManifest(["test_noRunTestEmptyTest.js"])
   1387 
   1388        self.assertTestResult(True)
   1389        self.assertEqual(1, self.x.testCount)
   1390        self.assertEqual(1, self.x.passCount)
   1391        self.assertEqual(0, self.x.failCount)
   1392        self.assertInLog(TEST_PASS_STRING)
   1393        self.assertNotInLog(TEST_FAIL_STRING)
   1394 
   1395    def testNoRunTestAddTestFail(self):
   1396        """
   1397        Check that test fails on using add_test() without run_test().
   1398        """
   1399        self.writeFile("test_noRunTestAddTestFail.js", NO_RUN_TEST_ADD_TEST_FAIL)
   1400        self.writeManifest(["test_noRunTestAddTestFail.js"])
   1401 
   1402        self.assertTestResult(False)
   1403        self.assertEqual(1, self.x.testCount)
   1404        self.assertEqual(0, self.x.passCount)
   1405        self.assertEqual(1, self.x.failCount)
   1406        self.assertInLog(TEST_FAIL_STRING)
   1407        self.assertNotInLog(TEST_PASS_STRING)
   1408 
   1409    def testNoRunTestAddTaskFail(self):
   1410        """
   1411        Check that test fails on using add_task() without run_test().
   1412        """
   1413        self.writeFile("test_noRunTestAddTaskFail.js", NO_RUN_TEST_ADD_TASK_FAIL)
   1414        self.writeManifest(["test_noRunTestAddTaskFail.js"])
   1415 
   1416        self.assertTestResult(False)
   1417        self.assertEqual(1, self.x.testCount)
   1418        self.assertEqual(0, self.x.passCount)
   1419        self.assertEqual(1, self.x.failCount)
   1420        self.assertInLog(TEST_FAIL_STRING)
   1421        self.assertNotInLog(TEST_PASS_STRING)
   1422 
   1423    def testNoRunTestAddTaskMultiple(self):
   1424        """
   1425        Check that multple add_task() tests work without run_test().
   1426        """
   1427        self.writeFile(
   1428            "test_noRunTestAddTaskMultiple.js", NO_RUN_TEST_ADD_TASK_MULTIPLE
   1429        )
   1430        self.writeManifest(["test_noRunTestAddTaskMultiple.js"])
   1431 
   1432        self.assertTestResult(True)
   1433        self.assertEqual(1, self.x.testCount)
   1434        self.assertEqual(1, self.x.passCount)
   1435        self.assertEqual(0, self.x.failCount)
   1436        self.assertInLog(TEST_PASS_STRING)
   1437        self.assertNotInLog(TEST_FAIL_STRING)
   1438 
   1439    def testMozinfo(self):
   1440        """
   1441        Check that mozinfo.json is loaded
   1442        """
   1443        self.writeFile("test_mozinfo.js", LOAD_MOZINFO)
   1444        self.writeManifest(["test_mozinfo.js"])
   1445        self.assertTestResult(True)
   1446        self.assertEqual(1, self.x.testCount)
   1447        self.assertEqual(1, self.x.passCount)
   1448        self.assertEqual(0, self.x.failCount)
   1449        self.assertEqual(0, self.x.todoCount)
   1450        self.assertInLog(TEST_PASS_STRING)
   1451        self.assertNotInLog(TEST_FAIL_STRING)
   1452 
   1453    def testChildMozinfo(self):
   1454        """
   1455        Check that mozinfo.json is loaded in child process
   1456        """
   1457        self.writeFile("test_mozinfo.js", LOAD_MOZINFO)
   1458        self.writeFile("test_child_mozinfo.js", CHILD_MOZINFO)
   1459        self.writeManifest(["test_child_mozinfo.js"])
   1460        self.assertTestResult(True)
   1461        self.assertEqual(1, self.x.testCount)
   1462        self.assertEqual(1, self.x.passCount)
   1463        self.assertEqual(0, self.x.failCount)
   1464        self.assertEqual(0, self.x.todoCount)
   1465        self.assertInLog(TEST_PASS_STRING)
   1466        self.assertNotInLog(TEST_FAIL_STRING)
   1467 
   1468    def testNotHeadlessByDefault(self):
   1469        """
   1470        Check that the default is not headless.
   1471        """
   1472        self.writeFile("test_notHeadlessByDefault.js", HEADLESS_FALSE)
   1473        self.writeManifest(["test_notHeadlessByDefault.js"])
   1474        self.assertTestResult(True)
   1475 
   1476    def testHeadlessWhenHeadlessExplicit(self):
   1477        """
   1478        Check that explicitly requesting headless works when the manifest doesn't override.
   1479        """
   1480        self.writeFile("test_headlessWhenExplicit.js", HEADLESS_TRUE)
   1481        self.writeManifest(["test_headlessWhenExplicit.js"])
   1482        self.assertTestResult(True, headless=True)
   1483 
   1484    def testHeadlessWhenHeadlessTrueInManifest(self):
   1485        """
   1486        Check that enabling headless in the manifest alone works.
   1487        """
   1488        self.writeFile("test_headlessWhenTrueInManifest.js", HEADLESS_TRUE)
   1489        self.writeManifest([("test_headlessWhenTrueInManifest.js", "headless = true")])
   1490        self.assertTestResult(True)
   1491 
   1492    def testNotHeadlessWhenHeadlessFalseInManifest(self):
   1493        """
   1494        Check that the manifest entry overrides the explicit default.
   1495        """
   1496        self.writeFile("test_notHeadlessWhenFalseInManifest.js", HEADLESS_FALSE)
   1497        self.writeManifest([
   1498            ("test_notHeadlessWhenFalseInManifest.js", "headless = false")
   1499        ])
   1500        self.assertTestResult(True, headless=True)
   1501 
   1502 
   1503 if __name__ == "__main__":
   1504    import mozunit
   1505 
   1506    mozinfo.find_and_update_from_json()
   1507    mozunit.main()