--- a/js/src/tests/e4x/Expressions/jstests.list
+++ b/js/src/tests/e4x/Expressions/jstests.list
@@ -1,16 +1,16 @@
url-prefix ../../jsreftest.html?test=e4x/Expressions/
script 11.1.1.js
script 11.1.2.js
script 11.1.3.js
script 11.1.4-01.js
script 11.1.4-02.js
script 11.1.4-03.js
-fails script 11.1.4-04.js
+fails-if(!xulRuntime.shell) script 11.1.4-04.js # bug - Expected value 'NL there ', Actual value 'there'
script 11.1.4-05.js
script 11.1.4-06.js
script 11.1.4-07.js
fails script 11.1.4-08.js
script 11.1.4.js
script 11.1.5.js
script 11.2.1.js
script 11.2.2.js
--- a/js/src/tests/e4x/GC/jstests.list
+++ b/js/src/tests/e4x/GC/jstests.list
@@ -1,11 +1,11 @@
url-prefix ../../jsreftest.html?test=e4x/GC/
script regress-280844-1.js
script regress-280844-2.js
-skip script regress-292455.js # does not always dismiss alert
+skip-if(!xulRuntime.shell) script regress-292455.js # does not always dismiss alert
script regress-313952-01.js
script regress-313952-02.js
script regress-324117.js
skip script regress-324278.js # slow
script regress-339785.js
script regress-357063-01.js
script regress-357063-02.js
--- a/js/src/tests/e4x/Regress/jstests.list
+++ b/js/src/tests/e4x/Regress/jstests.list
@@ -13,17 +13,17 @@ script regress-277935.js
skip script regress-278112.js # obsolete test
script regress-283349.js
script regress-290056.js
script regress-290499.js
script regress-301553.js
script regress-301573.js
script regress-301596.js
script regress-301692.js
-skip-if(isDebugBuild) script regress-308111.js # slow
+skip-if(!xulRuntime.shell&&isDebugBuild) script regress-308111.js # slow
script regress-309897.js
script regress-311580.js
script regress-313799.js
script regress-318922.js
skip script regress-319872.js # slow, Bug 514139
script regress-321547.js
script regress-322499.js
script regress-323338-1.js
@@ -36,17 +36,17 @@ script regress-327697.js
script regress-328249.js
script regress-329257.js
script regress-331558.js
script regress-331664.js
script regress-344455.js
script regress-347155.js
script regress-350206-1.js
script regress-350206.js
-skip script regress-350238.js # slow
+skip-if(!xulRuntime.shell) script regress-350238.js # slow
script regress-350629.js
script regress-352097.js
script regress-352103.js
script regress-352223.js
script regress-354145-01.js
script regress-354145-02.js
script regress-354145-03.js
script regress-354145-04.js
--- a/js/src/tests/ecma/Date/jstests.list
+++ b/js/src/tests/ecma/Date/jstests.list
@@ -28,17 +28,17 @@ script 15.9.4.2-1.js
script 15.9.4.2.js
script 15.9.4.3.js
script 15.9.5.1.js
script 15.9.5.10-1.js
script 15.9.5.10-10.js
script 15.9.5.10-11.js
script 15.9.5.10-12.js
script 15.9.5.10-13.js
-skip script 15.9.5.10-2.js # bug xxx
+script 15.9.5.10-2.js
script 15.9.5.10-3.js
script 15.9.5.10-4.js
script 15.9.5.10-5.js
script 15.9.5.10-6.js
script 15.9.5.10-7.js
script 15.9.5.10-8.js
script 15.9.5.10-9.js
script 15.9.5.11-1.js
@@ -141,11 +141,11 @@ script 15.9.5.37-2.js
script 15.9.5.37-3.js
script 15.9.5.37-4.js
script 15.9.5.37-5.js
script 15.9.5.4-1.js
script 15.9.5.4-2-n.js
script 15.9.5.5.js
script 15.9.5.6.js
script 15.9.5.7.js
-skip-if(isDebugBuild) script 15.9.5.8.js # slow
+script 15.9.5.8.js
script 15.9.5.9.js
script 15.9.5.js
--- a/js/src/tests/ecma/ExecutionContexts/jstests.list
+++ b/js/src/tests/ecma/ExecutionContexts/jstests.list
@@ -13,12 +13,12 @@ script 10.1.4-7.js
script 10.1.4-8.js
script 10.1.5-1.js
script 10.1.5-2.js
script 10.1.5-3.js
script 10.1.5-4.js
script 10.1.8-2.js
script 10.1.8-3.js
script 10.2.1.js
-fails script 10.2.2-1.js
-fails script 10.2.2-2.js
+skip-if(!xulRuntime.shell) script 10.2.2-1.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR Line 91
+skip-if(!xulRuntime.shell) script 10.2.2-2.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR Line 177
script 10.2.3-1.js
script 10.2.3-2.js
--- a/js/src/tests/ecma/TypeConversion/9.3-1.js
+++ b/js/src/tests/ecma/TypeConversion/9.3-1.js
@@ -93,8 +93,9 @@ new TestCase( SECTION, "typeof Number(ne
new TestCase( SECTION, "Number(new Boolean(false))", 0, Number(new Boolean(false)) );
new TestCase( SECTION, "typeof Number(new Boolean(false))", "number", typeof Number(new Boolean(false)) );
// object is array
new TestCase( SECTION, "Number(new Array(2,4,8,16,32))", Number.NaN, Number(new Array(2,4,8,16,32)) );
new TestCase( SECTION, "typeof Number(new Array(2,4,8,16,32))", "number", typeof Number(new Array(2,4,8,16,32)) );
+test();
--- a/js/src/tests/ecma_2/Statements/jstests.list
+++ b/js/src/tests/ecma_2/Statements/jstests.list
@@ -2,17 +2,17 @@ url-prefix ../../jsreftest.html?test=ecm
script dowhile-001.js
script dowhile-002.js
script dowhile-003.js
script dowhile-004.js
script dowhile-005.js
script dowhile-006.js
script dowhile-007.js
script forin-001.js
-fails script forin-002.js
+fails-if(!xulRuntime.shell) script forin-002.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 112
script if-001.js
script label-001.js
script label-002.js
script switch-001.js
script switch-002.js
script switch-003.js
script switch-004.js
script try-001.js
--- a/js/src/tests/js1_3/Script/jstests.list
+++ b/js/src/tests/js1_3/Script/jstests.list
@@ -1,7 +1,7 @@
url-prefix ../../jsreftest.html?test=js1_3/Script/
-skip script delete-001.js # obsolete test
+script delete-001.js
skip script function-001-n.js # obsolete test
script function-002.js
script in-001.js
script new-001.js
script switch-001.js
--- a/js/src/tests/js1_3/regress/jstests.list
+++ b/js/src/tests/js1_3/regress/jstests.list
@@ -1,7 +1,7 @@
url-prefix ../../jsreftest.html?test=js1_3/regress/
-skip script delete-001.js # obsolete test
+script delete-001.js
skip script function-001-n.js # obsolete test
script function-002.js
script in-001.js
script new-001.js
script switch-001.js
--- a/js/src/tests/js1_5/Array/jstests.list
+++ b/js/src/tests/js1_5/Array/jstests.list
@@ -1,14 +1,14 @@
url-prefix ../../jsreftest.html?test=js1_5/Array/
script 11.1.4.js
script array-001.js
script regress-101964.js
script regress-107138.js
-fails script regress-108440.js
+fails-if(!xulRuntime.shell) script regress-108440.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 74
script regress-154338.js
skip-if(xulRuntime.OS=="Linux"&&xulRuntime.XPCOMABI.match(/x86_64/)) script regress-157652.js # No test results
script regress-178722.js
script regress-255555.js
script regress-299644.js
script regress-300858.js
script regress-310351.js
script regress-311515.js
--- a/js/src/tests/js1_5/GC/jstests.list
+++ b/js/src/tests/js1_5/GC/jstests.list
@@ -1,22 +1,22 @@
url-prefix ../../jsreftest.html?test=js1_5/GC/
script regress-104584.js
-skip-if(xulRuntime.OS=="Darwin") script regress-203278-2.js # slow
+skip-if(!xulRuntime.shell&&xulRuntime.OS=="Darwin") script regress-203278-2.js # slow
script regress-203278-3.js
script regress-278725.js
script regress-306788.js
script regress-311497.js
script regress-313276.js
script regress-313479.js
script regress-316885-01.js
script regress-316885-02.js
script regress-316885-03.js
-skip script regress-319980-01.js # slow, sometimes out of memory fatal exception.
-script regress-324278.js
+skip-if(!xulRuntime.shell&&xulRuntime.OS=="Linux") script regress-319980-01.js # slow
+skip-if(!xulRuntime.shell&&!isDebugBuild) script regress-324278.js # slow
script regress-331719.js
skip script regress-338653.js # slow, killed on x86_64
script regress-341877-01.js
script regress-341877-02.js
skip script regress-346794.js # slow, killed
script regress-348532.js
script regress-352606.js
script regress-383269-01.js
--- a/js/src/tests/js1_5/Regress/jstests.list
+++ b/js/src/tests/js1_5/Regress/jstests.list
@@ -36,17 +36,17 @@ skip script regress-173067.js # obsolete
script regress-174709.js
script regress-176125.js
script regress-179524.js
script regress-185165.js
script regress-191633.js
script regress-191668.js
script regress-192414.js
script regress-193418.js
-skip-if(xulRuntime.OS=="Darwin") script regress-203278-1.js # slow
+skip-if(!xulRuntime.shell&&xulRuntime.OS=="Darwin"||xulRuntime.shell&&xulRuntime.OS=="Linux"&&xulRuntime.XPCOMABI.match(/x86_64/)) script regress-203278-1.js # slow
script regress-203402.js
script regress-203841.js
script regress-204210.js
script regress-210682.js
script regress-211590.js
script regress-213482.js
script regress-214761.js
script regress-216320.js
@@ -76,17 +76,17 @@ script regress-248444.js
skip script regress-249211.js # obsolete test
script regress-252892.js
script regress-253150.js
script regress-254296.js
script regress-254974.js
script regress-256501.js
script regress-256617.js
script regress-256798.js
-script regress-259935.js
+skip-if(xulRuntime.shell) script regress-259935.js # browser only
script regress-260541.js
script regress-261886.js
script regress-261887.js
skip script regress-271716-n.js # never terminates
script regress-274035.js
script regress-274888.js
script regress-275378.js
script regress-276103.js
@@ -200,17 +200,17 @@ script regress-355829-02.js
script regress-355829-03.js
script regress-356250.js
script regress-356693.js
script regress-360969-01.js
script regress-360969-02.js
script regress-360969-03.js
script regress-360969-04.js
script regress-360969-05.js
-skip-if(isDebugBuild) script regress-360969-06.js # slow
+script regress-360969-06.js
script regress-361467.js
script regress-361617.js
skip script regress-362583.js # obsolete test
fails-if(xulRuntime.OS=="WINNT") random-if(xulRuntime.OS=="Linux"&&!xulRuntime.XPCOMABI.match(/x86_64/)) skip-if(xulRuntime.OS=="Linux"&&xulRuntime.XPCOMABI.match(/x86_64/)) script regress-3649-n.js # No test results on windows, sometimes no test results on 32 bit linux, hangs os/consumes ram/swap on 64bit linux.
script regress-366122.js
script regress-366468.js
script regress-366601.js
script regress-367561-01.js
@@ -320,17 +320,17 @@ script regress-465347.js
script regress-465366.js
script regress-466262.js
script regress-466747.js
script regress-469044.js
script regress-470061.js
script regress-470187-01.js
script regress-470187-02.js
script regress-470758-01.js
-skip script regress-470758-02.js
+script regress-470758-02.js
script regress-475645-01.js
script regress-475645-02.js
script regress-476049.js
script regress-476192.js
script regress-477733.js
script regress-477758.js
script regress-478314.js
script regress-479353.js
--- a/js/src/tests/js1_5/Regress/regress-3649-n.js
+++ b/js/src/tests/js1_5/Regress/regress-3649-n.js
@@ -46,16 +46,17 @@ var expect = 'error';
DESCRIPTION = summary;
EXPECTED = expect;
printBugNumber(BUGNUMBER);
printStatus (summary);
expectExitCode(0);
+expectExitCode(3);
expectExitCode(5);
var s = "";
s = "abcd";
for (i = 0; i < 100000; i++) {
s += s;
}
--- a/js/src/tests/js1_5/extensions/jstests.list
+++ b/js/src/tests/js1_5/extensions/jstests.list
@@ -41,22 +41,22 @@ script regress-313938.js
script regress-314874.js
script regress-315509-02.js
script regress-319683.js
fails script regress-322957.js
script regress-325269.js
script regress-327608.js
script regress-328443.js
script regress-328556.js
-skip script regress-330569.js # slow
+script regress-330569.js
script regress-333541.js
skip script regress-335700.js # bug xxx - reftest hang, BigO
-skip script regress-336409-1.js # no results reported.
+skip-if(!xulRuntime.shell) script regress-336409-1.js # no results reported.
script regress-336409-2.js
-skip script regress-336410-1.js # slow
+skip-if(!xulRuntime.shell) script regress-336410-1.js # slow
script regress-336410-2.js
script regress-338804-01.js
script regress-338804-02.js
script regress-338804-03.js
script regress-339685.js
script regress-340199.js
script regress-341956-01.js
script regress-341956-02.js
@@ -111,20 +111,20 @@ script regress-358594-05.js
script regress-358594-06.js
script regress-359024.js
script regress-361346.js
script regress-361360.js
script regress-361552.js
script regress-361558.js
script regress-361571.js
script regress-361856.js
-skip script regress-361964.js # slow
+skip-if(!xulRuntime.shell) script regress-361964.js # alert is not dismissed.
random-if(xulRuntime.OS=="WINNT") script regress-363258.js # bug 524788
script regress-363988.js
-skip-if(isDebugBuild) script regress-365527.js # slow
+script regress-365527.js
script regress-365692.js
script regress-365869.js
script regress-366288.js
script regress-366292.js
script regress-366396.js
script regress-367118-01.js
script regress-367118-02.js
script regress-367119-01.js
@@ -165,17 +165,17 @@ script regress-385134.js
script regress-385393-02.js
script regress-385393-09.js
script regress-390597.js
script regress-394967.js
script regress-396326.js
script regress-406572.js
script regress-407019.js
script regress-407501.js
-skip script regress-407720.js # slow
+skip-if(!xulRuntime.shell) script regress-407720.js # slow
script regress-412926.js
script regress-414755.js
script regress-416354.js
script regress-416460.js
script regress-416834.js
skip script regress-418730.js # obsolete test
script regress-420612.js
script regress-420869-01.js
@@ -197,17 +197,17 @@ script regress-435497-01.js
script regress-435497-02.js
script regress-435497-03.js
script regress-436741.js
skip script regress-437288-01.js # obsolete test
script regress-44009.js
script regress-443569.js
script regress-446386.js
script regress-449657.js
-skip-if(isDebugBuild) script regress-452168.js
+script regress-452168.js
script regress-452178.js
script regress-452329.js
script regress-452338.js
script regress-452372.js
script regress-452565.js
script regress-453249.js
script regress-454040.js
script regress-454142.js
--- a/js/src/tests/js1_6/decompilation/jstests.list
+++ b/js/src/tests/js1_6/decompilation/jstests.list
@@ -1,4 +1,4 @@
url-prefix ../../jsreftest.html?test=js1_6/decompilation/
script regress-352084.js
script regress-352613-01.js
-skip-if(isDebugBuild) script regress-352613-02.js # bug xxx - hang reftests.
+script regress-352613-02.js
--- a/js/src/tests/js1_6/extensions/jstests.list
+++ b/js/src/tests/js1_6/extensions/jstests.list
@@ -1,15 +1,15 @@
url-prefix ../../jsreftest.html?test=js1_6/extensions/
script regress-312385-01.js
script regress-352392.js
script regress-385393-08.js
script regress-414098.js
-fails script regress-455464-01.js
-fails script regress-455464-02.js
-fails script regress-455464-03.js
+fails-if(!xulRuntime.shell) script regress-455464-01.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 1
+fails-if(!xulRuntime.shell) script regress-455464-02.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 49
+fails-if(!xulRuntime.shell) script regress-455464-03.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 1
fails-if(!xulRuntime.shell&&!isDebugBuild) skip-if(!xulRuntime.shell&&isDebugBuild) script regress-455464-04.js # bug xxx - hangs reftests in debug, ### bug xxx - NS_ERROR_DOM_NOT_SUPPORTED_ERR in opt
-skip script regress-456826.js # slow
+fails-if(xulRuntime.shell) skip-if(!xulRuntime.shell) script regress-456826.js # bug 504632
script regress-457521.js
script regress-465443.js
script regress-470310.js
script regress-472508.js
fails-if(!xulRuntime.shell) script regress-475144.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
--- a/js/src/tests/js1_7/extensions/jstests.list
+++ b/js/src/tests/js1_7/extensions/jstests.list
@@ -50,16 +50,16 @@ script regress-381303.js
script regress-387955-01.js
script regress-387955-02.js
script regress-392308.js
script regress-396326.js
script regress-429266.js
script regress-453955.js
fails-if(!xulRuntime.shell) script regress-455982-01.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
fails-if(!xulRuntime.shell) script regress-455982-02.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
-skip script regress-458679.js # slow
+skip-if(!xulRuntime.shell||xulRuntime.shell&&xulRuntime.XPCOMABI.match(/x86_64/)) script regress-458679.js # slow
script regress-469234.js
script regress-470176.js
script regress-470300-01.js
script regress-470300-02.js
script regress-474771-01.js
script regress-474771-02.js
script regress-477048.js
--- a/js/src/tests/js1_7/iterable/jstests.list
+++ b/js/src/tests/js1_7/iterable/jstests.list
@@ -1,15 +1,15 @@
url-prefix ../../jsreftest.html?test=js1_7/iterable/
script regress-340526-01.js
skip script regress-340526-02.js # obsolete test
script regress-341496.js
script regress-341499.js
script regress-341510.js
-skip script regress-341815.js # bug xxx - fails to dismiss alert
-skip script regress-341821.js # bug xxx - fails to dismiss alert
+skip-if(!xulRuntime.shell) script regress-341815.js # bug xxx - fails to dismiss alert
+skip-if(!xulRuntime.shell) script regress-341821.js # bug xxx - fails to dismiss alert
script regress-354750-01.js
script regress-355025.js
script regress-355075-01.js
script regress-355075-02.js
script regress-355090.js
script regress-412467.js
script regress-415922.js
--- a/js/src/tests/js1_8/extensions/jstests.list
+++ b/js/src/tests/js1_8/extensions/jstests.list
@@ -25,17 +25,17 @@ script regress-455973.js
script regress-465337.js
script regress-465453.js
script regress-469625.js
script regress-471197.js
script regress-472450-03.js
script regress-472450-04.js
script regress-473040.js
script regress-475971.js
-skip script regress-476414-01.js # slow
-skip script regress-476414-02.js # slow
+skip-if(!xulRuntime.shell) script regress-476414-01.js # slow
+skip-if(!xulRuntime.shell) script regress-476414-02.js # slow
fails-if(!xulRuntime.shell) script regress-476427.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
script regress-476869.js
script regress-479252.js
script regress-479381.js
script regress-481989.js
script regress-482263.js
script simple-tree.js
--- a/js/src/tests/js1_8/genexps/jstests.list
+++ b/js/src/tests/js1_8/genexps/jstests.list
@@ -1,10 +1,10 @@
url-prefix ../../jsreftest.html?test=js1_8/genexps/
script regress-347739.js
script regress-349012-01.js
script regress-349326.js
script regress-349331.js
script regress-380237-01.js
script regress-380237-02.js
-skip script regress-380237-03.js # obsolete test
-skip script regress-380237-04.js # obsolete test
+script regress-380237-03.js
+skip script regress-380237-04.js # obsolete test, need to remove minor failures to reenable.
script regress-384991.js
--- a/js/src/tests/js1_8/regress/jstests.list
+++ b/js/src/tests/js1_8/regress/jstests.list
@@ -21,17 +21,17 @@ script regress-459389.js
script regress-461930.js
script regress-461932.js
script regress-463334-01.js
script regress-463334-02.js
script regress-463783.js
script regress-464092-01.js
script regress-464092-02.js
script regress-464096.js
-skip-if(isDebugBuild) script regress-464418.js # slow
+script regress-464418.js
script regress-464978.js
script regress-465220.js
script regress-465234.js
script regress-465239.js
script regress-465241.js
script regress-465249.js
script regress-465261.js
script regress-465308.js
@@ -69,15 +69,15 @@ script regress-472450-01.js
script regress-472450-02.js
script regress-472528-01.js
script regress-472528-02.js
script regress-472703.js
script regress-474769.js
script regress-474771.js
script regress-474935.js
script regress-476655.js
-skip-if(isDebugBuild) script regress-477234.js # slow
+script regress-477234.js
script regress-477581.js
script regress-478205.js
script regress-479353.js
script regress-479740.js
script regress-481800.js
script regress-483749.js
--- a/js/src/tests/js1_8_1/regress/jstests.list
+++ b/js/src/tests/js1_8_1/regress/jstests.list
@@ -76,9 +76,10 @@ script regress-479430-05.js
script regress-495773.js
script regress-495907.js
script regress-496922.js
script regress-507053.js
script regress-507295.js
script regress-507424.js
script regress-515885.js
skip-if(isDebugBuild&&!xulRuntime.shell) script regress-524743.js # hang
+script regress-522123.js
script regress-524264.js
new file mode 100644
--- /dev/null
+++ b/js/src/tests/jstests.py
@@ -0,0 +1,316 @@
+# Test harness for JSTests, controlled by manifest files.
+
+import datetime, os, sys
+from subprocess import *
+
+from tests import TestResult, NullTestOutput
+from workers import Source
+from progressbar import ProgressBar
+
+def exclude_tests(test_list, exclude_files):
+ exclude_paths = []
+ for filename in exclude_files:
+ for line in open(filename):
+ if line.startswith('#'): continue
+ line = line.strip('\n')
+ if not line: continue
+ exclude_paths.append(line)
+ return [ _ for _ in test_list if _.path not in exclude_paths ]
+
+def check_manifest(test_list):
+ test_set = set([ _.path for _ in test_list ])
+
+ missing = []
+
+ for dirpath, dirnames, filenames in os.walk('.'):
+ for filename in filenames:
+ if dirpath == '.': continue
+ if not filename.endswith('.js'): continue
+ if filename in ('browser.js', 'shell.js', 'jsref.js', 'template.js'): continue
+
+ path = os.path.join(dirpath, filename)
+ if path.startswith('./'):
+ path = path[2:]
+ if path not in test_set:
+ missing.append(path)
+
+ if missing:
+ print "Test files not contained in any manifest:"
+ for path in missing:
+ print path
+ else:
+ print 'All test files are listed in manifests'
+
+class TestTask:
+ js_cmd_prefix = None
+
+ def __init__(self, test):
+ self.test = test
+
+ def __call__(self):
+ if self.test.enable or OPTIONS.run_skipped:
+ return self.test.run(self.js_cmd_prefix, OPTIONS.timeout)
+ else:
+ return NullTestOutput(self.test)
+
+ def __str__(self):
+ return str(self.test)
+
+ @classmethod
+ def set_js_cmd_prefix(self, js_path, js_args, debugger_prefix):
+ parts = []
+ if debugger_prefix:
+ parts += debugger_prefix
+ parts.append(js_path)
+ if js_args:
+ parts.append(js_args)
+ self.js_cmd_prefix = parts
+
+class ResultsSink:
+ output_file = None
+
+ def __init__(self):
+ self.groups = {}
+ self.counts = [ 0, 0, 0 ]
+ self.n = 0
+
+ self.finished = False
+ self.pb = None
+
+ def push(self, output):
+ if isinstance(output, NullTestOutput):
+ if OPTIONS.tinderbox:
+ print '%s | %s (SKIP)' % ('TEST-KNOWN-FAIL', output.test.path)
+ self.counts[2] += 1
+ self.n += 1
+ else:
+ if OPTIONS.show_cmd:
+ print >> self.output_file, output.cmd
+
+ if OPTIONS.show_output:
+ print >> self.output_file, ' rc = %d, run time = %f' % (output.rc, output.dt)
+ self.output_file.write(output.out)
+ self.output_file.write(output.err)
+
+ result = TestResult.from_output(output)
+ tup = (result.result, result.test.expect, result.test.random)
+ dev_label = self.LABELS[tup][1]
+ self.groups.setdefault(dev_label, []).append(result.test.path)
+
+ self.n += 1
+
+ if result.result == TestResult.PASS and not result.test.random:
+ self.counts[0] += 1
+ elif result.test.expect and not result.test.random:
+ self.counts[1] += 1
+ else:
+ self.counts[2] += 1
+
+ if OPTIONS.tinderbox:
+ if len(result.results) > 1:
+ for sub_ok, msg in result.results:
+ label = self.LABELS[(sub_ok, result.test.expect, result.test.random)][0]
+ if label == 'TEST-UNEXPECTED-PASS':
+ label = 'TEST-PASS (EXPECTED RANDOM)'
+ print '%s | %s | %s' % (label, result.test.path, msg)
+ print '%s | %s' % (self.LABELS[(result.result,
+ result.test.expect, result.test.random)][0],
+ result.test.path)
+
+ if self.pb:
+ self.pb.label = '[%4d|%4d|%4d]'%tuple(self.counts)
+ self.pb.update(self.n)
+
+ # Conceptually, this maps (test result x test expection) to text labels.
+ # key is (result, expect, random)
+ # value is (tinderbox label, dev test category)
+ LABELS = {
+ (TestResult.CRASH, False, False): ('TEST-KNOWN-FAIL', ''),
+ (TestResult.CRASH, False, True): ('TEST-KNOWN-FAIL (EXPECTED RANDOM)', ''),
+ (TestResult.CRASH, True, False): ('TEST-UNEXPECTED-FAIL', 'REGRESSIONS'),
+ (TestResult.CRASH, True, True): ('TEST-KNOWN-FAIL (EXPECTED RANDOM)', ''),
+
+ (TestResult.FAIL, False, False): ('TEST-KNOWN-FAIL', ''),
+ (TestResult.FAIL, False, True): ('TEST-KNOWN-FAIL (EXPECTED RANDOM)', ''),
+ (TestResult.FAIL, True, False): ('TEST-UNEXPECTED-FAIL', 'REGRESSIONS'),
+ (TestResult.FAIL, True, True): ('TEST-KNOWN-FAIL (EXPECTED RANDOM)', ''),
+
+ (TestResult.PASS, False, False): ('TEST-UNEXPECTED-PASS', 'FIXES'),
+ (TestResult.PASS, False, True): ('TEST-PASS (EXPECTED RANDOM)', ''),
+ (TestResult.PASS, True, False): ('TEST-PASS', ''),
+ (TestResult.PASS, True, True): ('TEST-PASS (EXPECTED RANDOM)', ''),
+ }
+
+ def list(self):
+ for label, paths in sorted(self.groups.items()):
+ if label == '': continue
+
+ print label
+ for path in paths:
+ print ' %s'%path
+
+ suffix = '' if self.finished else ' (partial run -- interrupted by user)'
+ if self.all_passed():
+ print 'PASS' + suffix
+ else:
+ print 'FAIL' + suffix
+
+ def all_passed(self):
+ return not self.groups.get((False, True, False))
+
+def run_tests(tests, results):
+ """Run the given tests, sending raw results to the given results accumulator."""
+ pb = None
+ if not OPTIONS.hide_progress:
+ try:
+ from progressbar import ProgressBar
+ pb = ProgressBar('', len(tests), 16)
+ except ImportError:
+ pass
+ results.pb = pb
+
+ test_list = [ TestTask(test) for test in tests ]
+ pipeline = Source(test_list, results, False)
+ results.finished = pipeline.start(OPTIONS.worker_count)
+
+ if pb:
+ pb.finish()
+
+ if not OPTIONS.tinderbox:
+ results.list()
+
+if __name__ == '__main__':
+ from optparse import OptionParser
+ op = OptionParser(usage='%prog JS_SHELL [TEST-SPECS]')
+ op.add_option('-s', '--show-cmd', dest='show_cmd', action='store_true',
+ help='show js shell command run')
+ op.add_option('-o', '--show-output', dest='show_output', action='store_true',
+ help='show output from js shell')
+ op.add_option('-O', '--output-file', dest='output_file',
+ help='write command output to the given file')
+ op.add_option('-f', '--file', dest='test_file', action='append',
+ help='get tests from the given file')
+ op.add_option('-x', '--exclude-file', dest='exclude_file', action='append',
+ help='exclude tests from the given file')
+ op.add_option('--no-progress', dest='hide_progress', action='store_true',
+ help='hide progress bar')
+ op.add_option('-j', '--worker-count', dest='worker_count', type=int, default=2,
+ help='number of worker threads to run tests on (default 2)')
+ op.add_option('-m', '--manifest', dest='manifest', default='jstests.list',
+ help='select manifest file')
+ op.add_option('-t', '--timeout', dest='timeout', type=float, default=60.0,
+ help='set test timeout in seconds')
+ op.add_option('-d', '--exclude-random', dest='random', action='store_false',
+ help='exclude tests marked random')
+ op.add_option('--run-skipped', dest='run_skipped', action='store_true',
+ help='run skipped tests')
+ op.add_option('--run-only-skipped', dest='run_only_skipped', action='store_true',
+ help='run only skipped tests')
+ op.add_option('--tinderbox', dest='tinderbox', action='store_true',
+ help='Tinderbox-parseable output format')
+ op.add_option('--args', dest='shell_args',
+ help='extra args to pass to the JS shell')
+ op.add_option('-g', '--debug', dest='debug', action='store_true',
+ help='run test in debugger')
+ op.add_option('--valgrind', dest='valgrind', action='store_true',
+ help='run tests in valgrind')
+ op.add_option('--valgrind-args', dest='valgrind_args',
+ help='extra args to pass to valgrind')
+ op.add_option('-c', '--check-manifest', dest='check_manifest', action='store_true',
+ help='check for test files not listed in the manifest')
+ (OPTIONS, args) = op.parse_args()
+ if len(args) < 1:
+ if not OPTIONS.check_manifest:
+ op.error('missing JS_SHELL argument')
+ JS, args = None, []
+ else:
+ JS, args = args[0], args[1:]
+
+ if OPTIONS.debug:
+ if OPTIONS.valgrind:
+ print >> sys.stderr, "--debug and --valgrind options are mutually exclusive"
+ sys.exit(2)
+ debugger_prefix = [ 'gdb', '-q', '--args' ]
+ elif OPTIONS.valgrind:
+ debugger_prefix = [ 'valgrind' ]
+ if os.uname()[0] == 'Darwin':
+ debugger_prefix += ['--dsymutil=yes']
+ if OPTIONS.valgrind_args:
+ debugger_prefix += [ valgrind_args ]
+ # Running under valgrind is not very useful if we don't show results.
+ OPTIONS.show_output = True
+ else:
+ debugger_prefix = []
+
+ TestTask.set_js_cmd_prefix(JS, OPTIONS.shell_args, debugger_prefix)
+
+ output_file = sys.stdout
+ if OPTIONS.output_file and (OPTIONS.show_cmd or OPTIONS.show_output):
+ output_file = open(OPTIONS.output_file, 'w')
+ ResultsSink.output_file = output_file
+
+ if ((OPTIONS.show_cmd or OPTIONS.show_output) and
+ output_file == sys.stdout or OPTIONS.tinderbox):
+ OPTIONS.hide_progress = True
+
+ import manifest
+ if JS is None:
+ xul_tester = manifest.NullXULInfoTester()
+ else:
+ xul_info = manifest.XULInfo.create(JS)
+ xul_tester = manifest.XULInfoTester(xul_info, JS)
+ test_list = manifest.parse(OPTIONS.manifest, xul_tester)
+
+ if OPTIONS.check_manifest:
+ check_manifest(test_list)
+ if JS is None:
+ sys.exit()
+
+ if OPTIONS.test_file:
+ paths = set()
+ for test_file in OPTIONS.test_file:
+ paths |= set([ line.strip() for line in open(test_file).readlines()])
+ test_list = [ _ for _ in test_list if _.path in paths ]
+
+ if args:
+ def p(path):
+ for arg in args:
+ if path.find(arg) != -1:
+ return True
+ return False
+ test_list = [ _ for _ in test_list if p(_.path) ]
+
+ if OPTIONS.exclude_file:
+ test_list = exclude_tests(test_list, OPTIONS.exclude_file)
+
+ if not OPTIONS.random:
+ test_list = [ _ for _ in test_list if not _.random ]
+
+ if OPTIONS.run_only_skipped:
+ OPTIONS.run_skipped = True
+ test_list = [ _ for _ in test_list if not _.enable ]
+
+ if OPTIONS.debug and test_list:
+ if len(test_list) > 1:
+ print('Multiple tests match command line arguments, debugger can only run one')
+ for tc in test_list:
+ print(' %s'%tc.path)
+ sys.exit(2)
+
+ cmd = test_list[0].get_command(TestTask.js_cmd_prefix)
+ if OPTIONS.show_cmd:
+ print ' '.join(cmd)
+ call(cmd)
+ sys.exit()
+
+ if not test_list:
+ print 'no tests selected'
+ else:
+ results = ResultsSink()
+ run_tests(test_list, results)
+
+ if output_file != sys.stdout:
+ output_file.close()
+
+ if not results.all_passed():
+ sys.exit(1)
new file mode 100644
--- /dev/null
+++ b/js/src/tests/manifest.py
@@ -0,0 +1,148 @@
+# Library for JSTest manifests.
+#
+# This includes classes for representing and parsing JS manifests.
+
+import os, re, sys
+from subprocess import *
+
+from tests import TestCase
+
+class XULInfo:
+ def __init__(self, abi, os, isdebug):
+ self.abi = abi
+ self.os = os
+ self.isdebug = isdebug
+
+ def as_js(self):
+ """Return JS that when executed sets up variables so that JS expression
+ predicates on XUL build info evaluate properly."""
+
+ return 'var xulRuntime = { OS: "%s", XPCOMABI: "%s", shell: true }; var isDebugBuild=%s;' % (
+ self.os,
+ self.abi,
+ str(self.isdebug).lower())
+
+ @classmethod
+ def create(cls, jsdir):
+ """Create a XULInfo based on the current platform's characteristics."""
+
+ # Our strategy is to find the autoconf.mk generated for the build and
+ # read the values from there.
+
+ # Find config/autoconf.mk.
+ dir = jsdir
+ while True:
+ if os.path.basename(dir) == 'src':
+ path = None
+ break
+ path = os.path.join(dir, 'config/autoconf.mk')
+ if os.path.isfile(path):
+ break
+ dir = os.path.dirname(dir)
+
+ # Read the values.
+ val_re = re.compile(r'(TARGET_XPCOM_ABI|OS_TARGET|MOZ_DEBUG)\s*=\s*(.*)')
+ kw = {}
+ for line in open(path):
+ m = val_re.match(line)
+ if m:
+ key, val = m.groups()
+ val = val.rstrip()
+ if key == 'TARGET_XPCOM_ABI':
+ kw['abi'] = val
+ if key == 'OS_TARGET':
+ kw['os'] = val
+ if key == 'MOZ_DEBUG':
+ kw['isdebug'] = (val == '1')
+ return cls(**kw)
+
+class XULInfoTester:
+ def __init__(self, xulinfo, js_bin):
+ self.js_prolog = xulinfo.as_js()
+ self.js_bin = js_bin
+ # Maps JS expr to evaluation result.
+ self.cache = {}
+
+ def test(self, cond):
+ """Test a XUL predicate condition against this local info."""
+ ans = self.cache.get(cond, None)
+ if ans is None:
+ cmd = [ self.js_bin, '-e', self.js_prolog, '-e', 'print(%s)'%cond ]
+ p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+ out, err = p.communicate()
+ if out == 'true\n':
+ ans = True
+ elif out in ('false\n', 'null\n'):
+ ans = False
+ else:
+ raise Exception("Failed to test XUL condition '%s'"%cond)
+ self.cache[cond] = ans
+ return ans
+
+class NullXULInfoTester:
+ """Can be used to parse manifests without a JS shell."""
+ def test(self, cond):
+ return False
+
+def parse(filename, xul_tester):
+ ans = []
+ comment_re = re.compile(r'#.*')
+ dir = os.path.dirname(filename)
+
+ try:
+ f = open(filename)
+ except IOError:
+ print "warning: include file not found: '%s'"%filename
+ return ans
+
+ for line in f:
+ sline = comment_re.sub('', line)
+ parts = sline.split()
+ if parts[0] == 'include':
+ ans += parse(os.path.join(dir, parts[1]), xul_tester)
+ elif parts[0] == 'url-prefix':
+ # Doesn't apply to shell tests
+ pass
+ else:
+ script = None
+ enable = True
+ expect = True
+ random = False
+
+ pos = 0
+ while pos < len(parts):
+ if parts[pos] == 'fails':
+ expect = False
+ pos += 1
+ elif parts[pos] == 'skip':
+ expect = enable = False
+ pos += 1
+ elif parts[pos] == 'random':
+ random = True
+ pos += 1
+ elif parts[pos].startswith('fails-if'):
+ cond = parts[pos][len('fails-if('):-1]
+ if xul_tester.test(cond):
+ expect = False
+ pos += 1
+ elif parts[pos].startswith('skip-if'):
+ cond = parts[pos][len('skip-if('):-1]
+ if xul_tester.test(cond):
+ expect = enable = False
+ pos += 1
+ elif parts[pos].startswith('random-if'):
+ cond = parts[pos][len('random-if('):-1]
+ if xul_tester.test(cond):
+ random = True
+ pos += 1
+ elif parts[pos] == 'script':
+ script = parts[pos+1]
+ pos += 2
+ else:
+ print 'warning: invalid manifest line element "%s"'%parts[pos]
+ pos += 1
+
+ assert script is not None
+ ans.append(TestCase(os.path.join(dir, script),
+ enable, expect, random))
+ return ans
new file mode 100644
--- /dev/null
+++ b/js/src/tests/progressbar.py
@@ -0,0 +1,35 @@
+# Text progress bar library, like curl or scp.
+
+import sys, datetime
+
+class ProgressBar:
+ def __init__(self, label, limit, label_width=12):
+ self.label = label
+ self.limit = limit
+ self.label_width = label_width
+ self.cur = 0
+ self.t0 = datetime.datetime.now()
+
+ self.barlen = 64 - self.label_width
+ self.fmt = '\r%-' + str(label_width) + 's %3d%% %-' + str(self.barlen) + 's| %6.1fs'
+
+ def update(self, value):
+ self.cur = value
+ pct = int(100.0 * self.cur / self.limit)
+ barlen = int(1.0 * self.barlen * self.cur / self.limit) - 1
+ bar = '='*barlen + '>'
+ dt = datetime.datetime.now() - self.t0
+ dt = dt.seconds + dt.microseconds * 1e-6
+ sys.stdout.write(self.fmt % (self.label[:self.label_width], pct, bar, dt))
+ sys.stdout.flush()
+
+ def finish(self):
+ self.update(self.limit)
+ sys.stdout.write('\n')
+
+if __name__ == '__main__':
+ pb = ProgressBar('test', 12)
+ for i in range(12):
+ pb.update(i)
+ time.sleep(0.5)
+ pb.finish()
--- a/js/src/tests/spidermonkey-n-1.9.3.tests
+++ b/js/src/tests/spidermonkey-n-1.9.3.tests
@@ -120,17 +120,16 @@ js1_5/decompilation/regress-351626.js
js1_5/decompilation/regress-354878.js
js1_5/decompilation/regress-373678.js
js1_5/extensions/regress-352281.js
js1_7/decompilation/regress-346642-01.js
js1_7/decompilation/regress-349605.js
# decompilation change in spidermonkey 1.8.1
js1_7/decompilation/regress-351070-01.js
js1_8/decompilation/regress-443074.js
-js1_8/genexps/regress-380237-03.js
js1_8/genexps/regress-380237-04.js
# decompilation change in spidermonkey 1.8.1 (bug 460501)
js1_7/decompilation/regress-352026.js
# https://bugzilla.mozilla.org/show_bug.cgi?id=458851#c7
js1_5/extensions/regress-437288-01.js
js1_5/decompilation/regress-437288-02.js
# more decompilation changes, bug 461233
js1_7/block/regress-352609.js
new file mode 100644
--- /dev/null
+++ b/js/src/tests/tests.py
@@ -0,0 +1,158 @@
+# Library for JSTest tests.
+#
+# This contains classes that represent an individual test, including
+# metadata, and know how to run the tests and determine failures.
+
+import datetime, os, re, sys, time
+from subprocess import *
+from threading import *
+
+def do_run_cmd(cmd):
+ l = [ None, None ]
+ th_run_cmd(cmd, l)
+ return l[1]
+
+def th_run_cmd(cmd, l):
+ t0 = datetime.datetime.now()
+ p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
+ l[0] = p
+ out, err = p.communicate()
+ t1 = datetime.datetime.now()
+ dd = t1-t0
+ dt = dd.seconds + 1e-6 * dd.microseconds
+ l[1] = (out, err, p.returncode, dt)
+
+def run_cmd(cmd, timeout=60.0):
+ if timeout is None:
+ return do_run_cmd(cmd)
+
+ l = [ None, None ]
+ th = Thread(target=th_run_cmd, args=(cmd, l))
+ th.start()
+ th.join(timeout)
+ while th.isAlive():
+ if l[0] is not None:
+ try:
+ # In Python 3, we could just do l[0].kill().
+ import signal
+ if sys.platform != 'win32':
+ os.kill(l[0].pid, signal.SIGKILL)
+ time.sleep(.1)
+ except OSError:
+ # Expecting a "No such process" error
+ pass
+ th.join()
+ return l[1]
+
+class Test(object):
+ """A runnable test."""
+ def __init__(self, path):
+ self.path = path # str: path of JS file relative to tests root dir
+
+ @staticmethod
+ def prefix_command(path):
+ """Return the '-f shell.js' options needed to run a test with the given path."""
+ if path == '':
+ return [ '-f', 'shell.js' ]
+ head, base = os.path.split(path)
+ return Test.prefix_command(head) + [ '-f', os.path.join(path, 'shell.js') ]
+
+ def get_command(self, js_cmd_prefix):
+ dir, filename = os.path.split(self.path)
+ # There is a test that requires the path to start with './'.
+ return js_cmd_prefix + Test.prefix_command(dir) + [ '-f', './' + self.path ]
+
+ def run(self, js_cmd_prefix, timeout=30.0):
+ cmd = self.get_command(js_cmd_prefix)
+ out, err, rc, dt = run_cmd(cmd, timeout)
+ return TestOutput(self, cmd, out, err, rc, dt);
+
+class TestCase(Test):
+ """A test case consisting of a test and an expected result."""
+
+ def __init__(self, path, enable, expect, random):
+ Test.__init__(self, path)
+ self.enable = enable # bool: True => run test, False => don't run
+ self.expect = expect # bool: expected result, True => pass
+ self.random = random # bool: True => ignore output as 'random'
+
+ def __str__(self):
+ ans = self.path
+ if not self.enable:
+ ans += ', skip'
+ if not self.expect:
+ ans += ', fails'
+ if self.random:
+ ans += ', random'
+ return ans
+
+class TestOutput:
+ """Output from a test run."""
+ def __init__(self, test, cmd, out, err, rc, dt):
+ self.test = test # Test
+ self.cmd = cmd # str: command line of test
+ self.out = out # str: stdout
+ self.err = err # str: stderr
+ self.rc = rc # int: return code
+ self.dt = dt # float: run time
+
+class NullTestOutput:
+ """Variant of TestOutput that indicates a test was not run."""
+ def __init__(self, test):
+ self.test = test
+ self.cmd = ''
+ self.out = ''
+ self.err = ''
+ self.rc = 0
+ self.dt = 0.0
+
+class TestResult:
+ PASS = 'PASS'
+ FAIL = 'FAIL'
+ CRASH = 'CRASH'
+
+ """Classified result from a test run."""
+ def __init__(self, test, result, results):
+ self.test = test
+ self.result = result
+ self.results = results
+
+ @classmethod
+ def from_output(cls, output):
+ test = output.test
+ result = None # str: overall result, see class-level variables
+ results = [] # (str,str) list: subtest results (pass/fail, message)
+
+ out, rc = output.out, output.rc
+
+ failures = 0
+ passes = 0
+
+ expected_rcs = []
+
+ for line in out.split('\n'):
+ if line.startswith(' FAILED!'):
+ failures += 1
+ msg = line[len(' FAILED! '):]
+ results.append((cls.FAIL, msg))
+ elif line.startswith(' PASSED!'):
+ passes += 1
+ msg = line[len(' PASSED! '):]
+ results.append((cls.PASS, msg))
+ else:
+ m = re.match('--- NOTE: IN THIS TESTCASE, WE EXPECT EXIT CODE ((?:-|\\d)+) ---', line)
+ if m:
+ expected_rcs.append(int(m.group(1)))
+
+ if rc:
+ if (test.path.endswith('-n.js') and rc == 3) or rc in expected_rcs:
+ result = cls.PASS
+ else:
+ result = cls.CRASH
+ else:
+ if passes > 0 and failures == 0:
+ result = cls.PASS
+ else:
+ result = cls.FAIL
+
+ return cls(test, result, results)
new file mode 100644
--- /dev/null
+++ b/js/src/tests/workers.py
@@ -0,0 +1,91 @@
+# Multiprocess activities with a push-driven divide-process-collect model.
+
+import os, sys, time
+from threading import Thread, Lock
+from Queue import Queue, Empty
+from datetime import datetime
+
+class Source:
+ def __init__(self, task_list, results, verbose = False):
+ self.tasks = Queue()
+ for task in task_list:
+ self.tasks.put_nowait(task)
+
+ self.results = results
+ self.verbose = verbose
+
+ def start(self, worker_count):
+ t0 = datetime.now()
+
+ sink = Sink(self.results)
+ self.workers = [ Worker(_+1, self.tasks, sink, self.verbose) for _ in range(worker_count) ]
+ if self.verbose: print '[P] Starting workers.'
+ for w in self.workers:
+ w.t0 = t0
+ w.start()
+ ans = self.join_workers()
+ if self.verbose: print '[P] Finished.'
+
+ t1 = datetime.now()
+ dt = t1-t0
+
+ return ans
+
+ def join_workers(self):
+ try:
+ for w in self.workers:
+ w.thread.join(20000)
+ return True
+ except KeyboardInterrupt:
+ for w in self.workers:
+ w.stop = True
+ return False
+
+class Sink:
+ def __init__(self, results):
+ self.results = results
+ self.lock = Lock()
+
+ def push(self, result):
+ self.lock.acquire()
+ try:
+ self.results.push(result)
+ finally:
+ self.lock.release()
+
+class Worker(object):
+ def __init__(self, id, tasks, sink, verbose):
+ self.id = id
+ self.tasks = tasks
+ self.sink = sink
+ self.verbose = verbose
+
+ self.thread = None
+ self.stop = False
+
+ def log(self, msg):
+ dd = datetime.now() - self.t0
+ dt = dd.seconds + 1e-6 * dd.microseconds
+
+ if self.verbose:
+ print '[W%d %.3f] %s' % (self.id, dt, msg)
+
+ def start(self):
+ self.thread = Thread(target=self.run)
+ self.thread.setDaemon(True)
+ self.thread.start()
+
+ def run(self):
+ try:
+ while True:
+ if self.stop:
+ break
+ self.log('Get next task.')
+ task = self.tasks.get(False)
+ self.log('Start task %s.'%str(task))
+ result = task()
+ self.log('Finished task.')
+ self.sink.push(result)
+ self.log('Pushed result.')
+ except Empty:
+ pass
--- a/js/src/trace-test/trace-test.py
+++ b/js/src/trace-test/trace-test.py
@@ -1,15 +1,25 @@
# trace-test.py -- Python harness for JavaScript trace tests.
import datetime, os, re, sys, traceback
import subprocess
from subprocess import *
-JS = None
+DEBUGGER_INFO = {
+ "gdb": {
+ "interactive": True,
+ "args": "-q --args"
+ },
+
+ "valgrind": {
+ "interactive": False,
+ "args": "--leak-check=full"
+ }
+}
# Backported from Python 3.1 posixpath.py
def _relpath(path, start=None):
"""Return a relative version of a path"""
if not path:
raise ValueError("no path specified")