2 # Copyright 2014 the V8 project authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 from collections import namedtuple
9 from mock import DEFAULT
10 from mock import MagicMock
12 from os import path, sys
17 # Requires python-coverage and python-mock. Native python coverage
18 # version >= 3.7.1 should be installed to get the best speed.
20 TEST_WORKSPACE = path.join(tempfile.gettempdir(), "test-v8-run-perf")
28 "results_regexp": "^%s: (.+)$",
31 {"name": "DeltaBlue"},
35 V8_NESTED_SUITES_JSON = {
45 "resources": ["file1.js", "file2.js"],
47 "results_regexp": "^Richards: (.+)$"},
56 "results_regexp": "^Simple: (.+) ms.$"},
60 "path": ["delta_blue"],
63 "results_regexp": "^DeltaBlue: (.+)$"},
64 {"name": "ShouldntRun",
80 Output = namedtuple("Output", "stdout, stderr, timed_out")
82 class PerfTest(unittest.TestCase):
85 cls.base = path.dirname(path.dirname(path.abspath(__file__)))
86 sys.path.append(cls.base)
87 cls._cov = coverage.coverage(
88 include=([os.path.join(cls.base, "run_perf.py")]))
91 from testrunner.local import commands
96 def tearDownClass(cls):
99 print cls._cov.report()
103 if path.exists(TEST_WORKSPACE):
104 shutil.rmtree(TEST_WORKSPACE)
105 os.makedirs(TEST_WORKSPACE)
108 if path.exists(TEST_WORKSPACE):
109 shutil.rmtree(TEST_WORKSPACE)
111 def _WriteTestInput(self, json_content):
112 self._test_input = path.join(TEST_WORKSPACE, "test.json")
113 with open(self._test_input, "w") as f:
114 f.write(json.dumps(json_content))
116 def _MockCommand(self, *args, **kwargs):
117 # Fake output for each test run.
118 test_outputs = [Output(stdout=arg,
120 timed_out=kwargs.get("timed_out", False))
122 def execute(*args, **kwargs):
123 return test_outputs.pop()
124 commands.Execute = MagicMock(side_effect=execute)
126 # Check that d8 is called from the correct cwd for each test run.
127 dirs = [path.join(TEST_WORKSPACE, arg) for arg in args[0]]
128 def chdir(*args, **kwargs):
129 self.assertEquals(dirs.pop(), args[0])
130 os.chdir = MagicMock(side_effect=chdir)
132 def _CallMain(self, *args):
133 self._test_output = path.join(TEST_WORKSPACE, "results.json")
135 "--json-test-results",
140 return run_perf.Main(all_args)
142 def _LoadResults(self):
143 with open(self._test_output) as f:
146 def _VerifyResults(self, suite, units, traces):
149 "graphs": [suite, trace["name"]],
150 "results": trace["results"],
151 "stddev": trace["stddev"]} for trace in traces],
152 self._LoadResults()["traces"])
154 def _VerifyErrors(self, errors):
155 self.assertEquals(errors, self._LoadResults()["errors"])
157 def _VerifyMock(self, binary, *args, **kwargs):
158 arg = [path.join(path.dirname(self.base), binary)]
160 commands.Execute.assert_called_with(
161 arg, timeout=kwargs.get("timeout", 60))
163 def _VerifyMockMultiple(self, *args, **kwargs):
166 a = [path.join(path.dirname(self.base), arg[0])]
168 expected.append(((a,), {"timeout": kwargs.get("timeout", 60)}))
169 self.assertEquals(expected, commands.Execute.call_args_list)
171 def testOneRun(self):
172 self._WriteTestInput(V8_JSON)
173 self._MockCommand(["."], ["x\nRichards: 1.234\nDeltaBlue: 10657567\ny\n"])
174 self.assertEquals(0, self._CallMain())
175 self._VerifyResults("test", "score", [
176 {"name": "Richards", "results": ["1.234"], "stddev": ""},
177 {"name": "DeltaBlue", "results": ["10657567"], "stddev": ""},
179 self._VerifyErrors([])
180 self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js")
182 def testTwoRuns_Units_SuiteName(self):
183 test_input = dict(V8_JSON)
184 test_input["run_count"] = 2
185 test_input["name"] = "v8"
186 test_input["units"] = "ms"
187 self._WriteTestInput(test_input)
188 self._MockCommand([".", "."],
189 ["Richards: 100\nDeltaBlue: 200\n",
190 "Richards: 50\nDeltaBlue: 300\n"])
191 self.assertEquals(0, self._CallMain())
192 self._VerifyResults("v8", "ms", [
193 {"name": "Richards", "results": ["50", "100"], "stddev": ""},
194 {"name": "DeltaBlue", "results": ["300", "200"], "stddev": ""},
196 self._VerifyErrors([])
197 self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js")
199 def testTwoRuns_SubRegexp(self):
200 test_input = dict(V8_JSON)
201 test_input["run_count"] = 2
202 del test_input["results_regexp"]
203 test_input["tests"][0]["results_regexp"] = "^Richards: (.+)$"
204 test_input["tests"][1]["results_regexp"] = "^DeltaBlue: (.+)$"
205 self._WriteTestInput(test_input)
206 self._MockCommand([".", "."],
207 ["Richards: 100\nDeltaBlue: 200\n",
208 "Richards: 50\nDeltaBlue: 300\n"])
209 self.assertEquals(0, self._CallMain())
210 self._VerifyResults("test", "score", [
211 {"name": "Richards", "results": ["50", "100"], "stddev": ""},
212 {"name": "DeltaBlue", "results": ["300", "200"], "stddev": ""},
214 self._VerifyErrors([])
215 self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js")
217 def testNestedSuite(self):
218 self._WriteTestInput(V8_NESTED_SUITES_JSON)
219 self._MockCommand(["delta_blue", "sub/leaf", "richards"],
226 self.assertEquals(0, self._CallMain())
229 "graphs": ["test", "Richards"],
230 "results": ["50", "100"],
233 "graphs": ["test", "Sub", "Leaf"],
234 "results": ["3", "2", "1"],
237 "graphs": ["test", "DeltaBlue"],
240 ], self._LoadResults()["traces"])
241 self._VerifyErrors([])
242 self._VerifyMockMultiple(
243 (path.join("out", "x64.release", "d7"), "--flag", "file1.js",
244 "file2.js", "run.js"),
245 (path.join("out", "x64.release", "d7"), "--flag", "file1.js",
246 "file2.js", "run.js"),
247 (path.join("out", "x64.release", "d8"), "--flag", "run.js"),
248 (path.join("out", "x64.release", "d8"), "--flag", "run.js"),
249 (path.join("out", "x64.release", "d8"), "--flag", "run.js"),
250 (path.join("out", "x64.release", "d8"), "--flag", "--flag2", "run.js"))
252 def testOneRunStdDevRegExp(self):
253 test_input = dict(V8_JSON)
254 test_input["stddev_regexp"] = "^%s\-stddev: (.+)$"
255 self._WriteTestInput(test_input)
256 self._MockCommand(["."], ["Richards: 1.234\nRichards-stddev: 0.23\n"
257 "DeltaBlue: 10657567\nDeltaBlue-stddev: 106\n"])
258 self.assertEquals(0, self._CallMain())
259 self._VerifyResults("test", "score", [
260 {"name": "Richards", "results": ["1.234"], "stddev": "0.23"},
261 {"name": "DeltaBlue", "results": ["10657567"], "stddev": "106"},
263 self._VerifyErrors([])
264 self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js")
266 def testTwoRunsStdDevRegExp(self):
267 test_input = dict(V8_JSON)
268 test_input["stddev_regexp"] = "^%s\-stddev: (.+)$"
269 test_input["run_count"] = 2
270 self._WriteTestInput(test_input)
271 self._MockCommand(["."], ["Richards: 3\nRichards-stddev: 0.7\n"
272 "DeltaBlue: 6\nDeltaBlue-boom: 0.9\n",
273 "Richards: 2\nRichards-stddev: 0.5\n"
274 "DeltaBlue: 5\nDeltaBlue-stddev: 0.8\n"])
275 self.assertEquals(1, self._CallMain())
276 self._VerifyResults("test", "score", [
277 {"name": "Richards", "results": ["2", "3"], "stddev": "0.7"},
278 {"name": "DeltaBlue", "results": ["5", "6"], "stddev": "0.8"},
281 ["Test Richards should only run once since a stddev is provided "
283 "Test DeltaBlue should only run once since a stddev is provided "
285 "Regexp \"^DeltaBlue\-stddev: (.+)$\" didn't match for test "
287 self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js")
289 def testBuildbot(self):
290 self._WriteTestInput(V8_JSON)
291 self._MockCommand(["."], ["Richards: 1.234\nDeltaBlue: 10657567\n"])
292 self.assertEquals(0, self._CallMain("--buildbot"))
293 self._VerifyResults("test", "score", [
294 {"name": "Richards", "results": ["1.234"], "stddev": ""},
295 {"name": "DeltaBlue", "results": ["10657567"], "stddev": ""},
297 self._VerifyErrors([])
298 self._VerifyMock(path.join("out", "Release", "d7"), "--flag", "run.js")
300 def testBuildbotWithTotal(self):
301 test_input = dict(V8_JSON)
302 test_input["total"] = True
303 self._WriteTestInput(test_input)
304 self._MockCommand(["."], ["Richards: 1.234\nDeltaBlue: 10657567\n"])
305 self.assertEquals(0, self._CallMain("--buildbot"))
306 self._VerifyResults("test", "score", [
307 {"name": "Richards", "results": ["1.234"], "stddev": ""},
308 {"name": "DeltaBlue", "results": ["10657567"], "stddev": ""},
309 {"name": "Total", "results": ["3626.49109719"], "stddev": ""},
311 self._VerifyErrors([])
312 self._VerifyMock(path.join("out", "Release", "d7"), "--flag", "run.js")
314 def testBuildbotWithTotalAndErrors(self):
315 test_input = dict(V8_JSON)
316 test_input["total"] = True
317 self._WriteTestInput(test_input)
318 self._MockCommand(["."], ["x\nRichaards: 1.234\nDeltaBlue: 10657567\ny\n"])
319 self.assertEquals(1, self._CallMain("--buildbot"))
320 self._VerifyResults("test", "score", [
321 {"name": "Richards", "results": [], "stddev": ""},
322 {"name": "DeltaBlue", "results": ["10657567"], "stddev": ""},
325 ["Regexp \"^Richards: (.+)$\" didn't match for test Richards.",
326 "Not all traces have the same number of results."])
327 self._VerifyMock(path.join("out", "Release", "d7"), "--flag", "run.js")
329 def testRegexpNoMatch(self):
330 self._WriteTestInput(V8_JSON)
331 self._MockCommand(["."], ["x\nRichaards: 1.234\nDeltaBlue: 10657567\ny\n"])
332 self.assertEquals(1, self._CallMain())
333 self._VerifyResults("test", "score", [
334 {"name": "Richards", "results": [], "stddev": ""},
335 {"name": "DeltaBlue", "results": ["10657567"], "stddev": ""},
338 ["Regexp \"^Richards: (.+)$\" didn't match for test Richards."])
339 self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js")
341 def testOneRunGeneric(self):
342 test_input = dict(V8_GENERIC_JSON)
343 self._WriteTestInput(test_input)
344 self._MockCommand(["."], [
345 "RESULT Infra: Constant1= 11 count\n"
346 "RESULT Infra: Constant2= [10,5,10,15] count\n"
347 "RESULT Infra: Constant3= {12,1.2} count\n"])
348 self.assertEquals(0, self._CallMain())
351 "graphs": ["test", "Infra", "Constant1"],
355 "graphs": ["test", "Infra", "Constant2"],
356 "results": ["10", "5", "10", "15"],
359 "graphs": ["test", "Infra", "Constant3"],
362 ], self._LoadResults()["traces"])
363 self._VerifyErrors([])
364 self._VerifyMock(path.join("out", "x64.release", "cc"), "--flag", "")
366 def testOneRunTimingOut(self):
367 test_input = dict(V8_JSON)
368 test_input["timeout"] = 70
369 self._WriteTestInput(test_input)
370 self._MockCommand(["."], [""], timed_out=True)
371 self.assertEquals(1, self._CallMain())
372 self._VerifyResults("test", "score", [
373 {"name": "Richards", "results": [], "stddev": ""},
374 {"name": "DeltaBlue", "results": [], "stddev": ""},
377 "Regexp \"^Richards: (.+)$\" didn't match for test Richards.",
378 "Regexp \"^DeltaBlue: (.+)$\" didn't match for test DeltaBlue.",
381 path.join("out", "x64.release", "d7"), "--flag", "run.js", timeout=70)