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()