1 # Copyright 2012 the V8 project authors. All rights reserved.
2 # Redistribution and use in source and binary forms, with or without
3 # modification, are permitted provided that the following conditions are
6 # * Redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer.
8 # * Redistributions in binary form must reproduce the above
9 # copyright notice, this list of conditions and the following
10 # disclaimer in the documentation and/or other materials provided
11 # with the distribution.
12 # * Neither the name of Google Inc. nor the names of its
13 # contributors may be used to endorse or promote products derived
14 # from this software without specific prior written permission.
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 from testrunner.local import testsuite
37 from testrunner.local import utils
38 from testrunner.objects import testcase
40 TEST_262_ARCHIVE_REVISION = "61113db" # This is the 2014-10-23 revision.
41 TEST_262_ARCHIVE_MD5 = "261e69b4a97a4bfc18225cf3938daf50"
42 TEST_262_URL = "https://github.com/tc39/test262/tarball/%s"
43 TEST_262_HARNESS_FILES = ["sta.js"]
45 TEST_262_SUITE_PATH = ["data", "test", "suite"]
46 TEST_262_HARNESS_PATH = ["data", "test", "harness"]
47 TEST_262_TOOLS_PATH = ["data", "tools", "packaging"]
49 class Test262TestSuite(testsuite.TestSuite):
51 def __init__(self, name, root):
52 super(Test262TestSuite, self).__init__(name, root)
53 self.testroot = os.path.join(self.root, *TEST_262_SUITE_PATH)
54 self.harnesspath = os.path.join(self.root, *TEST_262_HARNESS_PATH)
55 self.harness = [os.path.join(self.harnesspath, f)
56 for f in TEST_262_HARNESS_FILES]
57 self.harness += [os.path.join(self.root, "harness-adapt.js")]
58 self.ParseTestRecord = None
60 def ListTests(self, context):
62 for dirname, dirs, files in os.walk(self.testroot):
63 for dotted in [x for x in dirs if x.startswith(".")]:
65 if context.noi18n and "intl402" in dirs:
66 dirs.remove("intl402")
69 for filename in files:
70 if filename.endswith(".js"):
71 testname = os.path.join(dirname[len(self.testroot) + 1:],
73 case = testcase.TestCase(self, testname)
77 def GetFlagsForTestCase(self, testcase, context):
78 return (testcase.flags + context.mode_flags + self.harness +
79 self.GetIncludesForTest(testcase) + ["--harmony"] +
80 [os.path.join(self.testroot, testcase.path + ".js")])
82 def LoadParseTestRecord(self):
83 if not self.ParseTestRecord:
84 root = os.path.join(self.root, *TEST_262_TOOLS_PATH)
87 (f, pathname, description) = imp.find_module("parseTestRecord", [root])
88 module = imp.load_module("parseTestRecord", f, pathname, description)
89 self.ParseTestRecord = module.parseTestRecord
91 raise ImportError("Cannot load parseTestRecord; you may need to "
92 "--download-data for test262")
96 return self.ParseTestRecord
98 def GetTestRecord(self, testcase):
99 if not hasattr(testcase, "test_record"):
100 ParseTestRecord = self.LoadParseTestRecord()
101 testcase.test_record = ParseTestRecord(self.GetSourceForTest(testcase),
103 return testcase.test_record
105 def GetIncludesForTest(self, testcase):
106 test_record = self.GetTestRecord(testcase)
107 if "includes" in test_record:
108 includes = [os.path.join(self.harnesspath, f)
109 for f in test_record["includes"]]
114 def GetSourceForTest(self, testcase):
115 filename = os.path.join(self.testroot, testcase.path + ".js")
116 with open(filename) as f:
119 def IsNegativeTest(self, testcase):
120 test_record = self.GetTestRecord(testcase)
121 return "negative" in test_record
123 def IsFailureOutput(self, output, testpath):
124 if output.exit_code != 0:
126 return "FAILED!" in output.stdout
128 def DownloadData(self):
129 revision = TEST_262_ARCHIVE_REVISION
130 archive_url = TEST_262_URL % revision
131 archive_name = os.path.join(self.root, "tc39-test262-%s.tar.gz" % revision)
132 directory_name = os.path.join(self.root, "data")
133 directory_old_name = os.path.join(self.root, "data.old")
134 if not os.path.exists(archive_name):
135 print "Downloading test data from %s ..." % archive_url
136 utils.URLRetrieve(archive_url, archive_name)
137 if os.path.exists(directory_name):
138 if os.path.exists(directory_old_name):
139 shutil.rmtree(directory_old_name)
140 os.rename(directory_name, directory_old_name)
141 if not os.path.exists(directory_name):
142 print "Extracting test262-%s.tar.gz ..." % revision
144 with open(archive_name, "rb") as f:
145 for chunk in iter(lambda: f.read(8192), ""):
147 print "MD5 hash is %s" % md5.hexdigest()
148 if md5.hexdigest() != TEST_262_ARCHIVE_MD5:
149 os.remove(archive_name)
150 print "MD5 expected %s" % TEST_262_ARCHIVE_MD5
151 raise Exception("MD5 hash mismatch of test data file")
152 archive = tarfile.open(archive_name, "r:gz")
153 if sys.platform in ("win32", "cygwin"):
154 # Magic incantation to allow longer path names on Windows.
155 archive.extractall(u"\\\\?\\%s" % self.root)
157 archive.extractall(self.root)
158 os.rename(os.path.join(self.root, "tc39-test262-%s" % revision),
162 def GetSuite(name, root):
163 return Test262TestSuite(name, root)