From f10f4fc49cf3b346b86114720089e1379887c7af Mon Sep 17 00:00:00 2001 From: "jkummerow@chromium.org" Date: Tue, 2 Oct 2012 08:50:02 +0000 Subject: [PATCH] Test runner: More fixes. - handle Ctrl+C better - actually show error messages sent by network peers - gracefully handle missing test cases - pull test.py and utils.py during server setup (temporary fix for testcfg import issue) Review URL: https://codereview.chromium.org/11036005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12648 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- tools/test-server.py | 9 ++++++++ tools/testrunner/local/execution.py | 32 ++++++++++++++++++++++++--- tools/testrunner/network/endpoint.py | 8 ++++--- tools/testrunner/network/network_execution.py | 12 ++++++---- tools/testrunner/server/work_handler.py | 2 +- 5 files changed, 52 insertions(+), 11 deletions(-) diff --git a/tools/test-server.py b/tools/test-server.py index ab927de..df547ed 100755 --- a/tools/test-server.py +++ b/tools/test-server.py @@ -124,6 +124,15 @@ def Update(): scriptname = os.path.abspath(sys.argv[0]) _Cmd("svn cat %s > %s" % (path, scriptname)) + # The testcfg.py files currently need to be able to import the old test.py + # script, so we temporarily need to make that available. + # TODO(jkummerow): Remove this when removing test.py. + for filename in ("test.py", "utils.py"): + url = ("http://v8.googlecode.com/svn/branches/bleeding_edge/" + "tools/%s" % filename) + filepath = os.path.join(os.path.dirname(scriptname), filename) + _Cmd("svn cat %s > %s" % (url, filepath)) + # Check out or update V8. v8_dir = os.path.join(ROOT, "v8") if os.path.exists(v8_dir): diff --git a/tools/testrunner/local/execution.py b/tools/testrunner/local/execution.py index fd331e2..25df043 100644 --- a/tools/testrunner/local/execution.py +++ b/tools/testrunner/local/execution.py @@ -35,6 +35,10 @@ from . import commands from . import utils +BREAK_NOW = -1 +EXCEPTION = -2 + + class Job(object): def __init__(self, command, dep_command, test_id, timeout, verbose): self.command = command @@ -57,9 +61,11 @@ def RunTest(job): return (job.id, dep_output, time.time() - start_time) output = commands.Execute(job.command, job.verbose, job.timeout) return (job.id, output, time.time() - start_time) + except KeyboardInterrupt: + return (-1, BREAK_NOW, 0) except Exception, e: print(">>> EXCEPTION: %s" % e) - return (-1, -1, 0) + return (-1, EXCEPTION, 0) class Runner(object): @@ -90,10 +96,17 @@ class Runner(object): pool = multiprocessing.Pool(processes=jobs) test_map = {} queue = [] + queued_exception = None for test in self.tests: assert test.id >= 0 test_map[test.id] = test - command = self.GetCommand(test) + try: + command = self.GetCommand(test) + except Exception, e: + # If this failed, save the exception and re-raise it later (after + # all other tests have had a chance to run). + queued_exception = e + continue timeout = self.context.timeout if ("--stress-opt" in test.flags or "--stress-opt" in self.context.mode_flags or @@ -111,6 +124,13 @@ class Runner(object): for result in it: test_id = result[0] if test_id < 0: + if result[1] == BREAK_NOW: + self.terminate = True + else: + continue + if self.terminate: + pool.terminate() + pool.join() raise BreakNowException("User pressed Ctrl+C or IO went wrong") test = test_map[test_id] self.indicator.AboutToRun(test) @@ -124,10 +144,16 @@ class Runner(object): self.succeeded += 1 self.remaining -= 1 self.indicator.HasRun(test) - except: + except KeyboardInterrupt: + pool.terminate() + pool.join() + except Exception, e: + print("Exception: %s" % e) pool.terminate() pool.join() raise + if queued_exception: + raise queued_exception return diff --git a/tools/testrunner/network/endpoint.py b/tools/testrunner/network/endpoint.py index 8350fee..5dc2b9f 100644 --- a/tools/testrunner/network/endpoint.py +++ b/tools/testrunner/network/endpoint.py @@ -60,7 +60,6 @@ class EndpointProgress(progress.ProgressIndicator): self.sender_lock.acquire() while keep_running: time.sleep(0.1) - t1 = time.time() # This should be "atomic enough" without locking :-) # (We don't care which list any new elements get appended to, as long # as we don't lose any and the last one comes last.) @@ -77,7 +76,10 @@ class EndpointProgress(progress.ProgressIndicator): result = [] for t in tests: result.append(t.PackResult()) - compression.Send(result, self.sock) + try: + compression.Send(result, self.sock) + except: + self.runner.terminate = True for t in tests: self.server.CompareOwnPerf(t, self.context.arch, self.context.mode) tests = [] @@ -116,7 +118,7 @@ def Execute(workspace, ctx, tests, sock, server): e.filename) else: message = "%s" % e - compression.Send([-1, message], sock) + compression.Send([[-1, message]], sock) progress_indicator.HasRun(None) # Sentinel to signal the end. progress_indicator.sender_lock.acquire() # Released when sending is done. progress_indicator.sender_lock.release() diff --git a/tools/testrunner/network/network_execution.py b/tools/testrunner/network/network_execution.py index b17249d..ddb59e6 100644 --- a/tools/testrunner/network/network_execution.py +++ b/tools/testrunner/network/network_execution.py @@ -187,8 +187,8 @@ class NetworkedRunner(execution.Runner): test_id = data[0] if test_id < 0: # The peer is reporting an error. - print("Peer %s reports error: %s" % (peer.address, data[1])) - rec.Advance() + with self.lock: + print("\nPeer %s reports error: %s" % (peer.address, data[1])) continue test = test_map.pop(test_id) test.MergeResult(data) @@ -214,7 +214,11 @@ class NetworkedRunner(execution.Runner): self.indicator.HasRun(test) rec.Advance() peer.runtime = time.time() - start_time - except Exception: + except KeyboardInterrupt: + sock.close() + raise + except Exception, e: + print("Got exception: %s" % e) pass # Fall back to local execution. else: compression.Send([constants.UNRESPONSIVE_PEER, peer.address], @@ -222,7 +226,7 @@ class NetworkedRunner(execution.Runner): sock.close() if len(test_map) > 0: # Some tests have not received any results. Run them locally. - print("No results for %d tests, running them locally." % len(test_map)) + print("\nNo results for %d tests, running them locally." % len(test_map)) self._EnqueueLocally(test_map) def _EnqueueLocally(self, test_map): diff --git a/tools/testrunner/server/work_handler.py b/tools/testrunner/server/work_handler.py index 80f0178..6bf7d43 100644 --- a/tools/testrunner/server/work_handler.py +++ b/tools/testrunner/server/work_handler.py @@ -76,7 +76,7 @@ class WorkHandler(SocketServer.BaseRequestHandler): def _SendResponse(self, error_message=None): try: if error_message: - compression.Send([-1, error_message], self.request) + compression.Send([[-1, error_message]], self.request) compression.Send(constants.END_OF_STREAM, self.request) return except Exception, e: -- 2.7.4