commit d9d07ef1ee8863b7598e147ccb8d4952e2f78461 Author: Jiri Pirko jpirko@redhat.com Date: Fri Jul 1 14:09:49 2011 +0200
Tests: allow to interrupt running test and get its result
Signed-off-by: Jiri Pirko jpirko@redhat.com
Common/TestsCommon.py | 28 ++++++++++++++++++++++++++-- NetTest/NetTestCommand.py | 40 +++++++++++++++++++++++++--------------- 2 files changed, 51 insertions(+), 17 deletions(-) --- diff --git a/Common/TestsCommon.py b/Common/TestsCommon.py index 197bb62..1e275ca 100644 --- a/Common/TestsCommon.py +++ b/Common/TestsCommon.py @@ -10,7 +10,11 @@ __author__ = """ jpirko@redhat.com (Jiri Pirko) """
-import re, logging, sys, os +import re +import logging +import sys +import os +import signal from NetTest.NetTestCommand import NetTestCommandGeneric
class testLogger(logging.Logger): @@ -51,8 +55,28 @@ class TestOptionMissing(Exception):
class TestGeneric(NetTestCommandGeneric): def __init__(self, command): - self._command = command self._testLogger = logging.getLogger("root.testLogger") + self._read_pipe, self._write_pipe = os.pipe() + signal.signal(signal.SIGINT, self._signal_intr_handler) + NetTestCommandGeneric.__init__(self, command) + + def __del__(self): + os.close(self._read_pipe) + os.close(self._write_pipe) + + def _signal_intr_handler(self, signum, frame): + os.write(self._write_pipe, "a") + + def wait_on_interrupt(self): + ''' + Should be used by test implementation for waiting on SIGINT + ''' + while True: + try: + os.read(self._read_pipe, 1) + except OSError: + continue + break
def set_fail(self, err_msg, res_data = None): self._testLogger.error("FAILED - %s" % err_msg) diff --git a/NetTest/NetTestCommand.py b/NetTest/NetTestCommand.py index 0c9bc54..24f432c 100644 --- a/NetTest/NetTestCommand.py +++ b/NetTest/NetTestCommand.py @@ -67,6 +67,7 @@ def NetTestCommandTest(command): class NetTestCommandGeneric: def __init__(self, command): self._command = command + self._result = None
def run(self): pass @@ -75,6 +76,12 @@ class NetTestCommandGeneric: self._result = result
def get_result(self): + if not self._result: + ''' + In case result is not set yet, it most likely means that + command was killed. So set pass in this case + ''' + self.set_pass() return self._result
def set_fail(self, err_msg): @@ -95,27 +102,30 @@ class NetTestCommandExec(NetTestCommandGeneric): except ExecCmdFail: self.set_fail("Command failed to execute")
- class BgProcessException(Exception): """Base class for client errors.""" def __init__(self, str): - self.str = str + self._str = str
def __str__(self): - return "BgProcessError: " + self.str + return "BgProcessError: " + self._str + +def get_bg_process_result(bg_id): + pipe = bg_processes.get_pipe(bg_id) + tmp = os.read(pipe, 4096*10) + result = pickle.loads(tmp) + if "Exception" in result: + raise BgProcessException(result["Exception"]) + os.close(pipe) + return result
class NetTestCommandWait(NetTestCommandGeneric): def run(self): bg_id = int(self._command["value"]) pid = bg_processes.get_pid(bg_id) - pipe = bg_processes.get_pipe(bg_id) logging.debug("Waiting for background id "%d", pid "%d"" % (bg_id, pid)) os.waitpid(pid, 0) - tmp = os.read(pipe, 4096*10) - result = pickle.loads(tmp) - if "Exception" in result: - raise BgProcessException(result["Exception"]) - os.close(pipe) + result = get_bg_process_result(bg_id) bg_processes.remove(bg_id) self.set_result(result)
@@ -125,8 +135,10 @@ class NetTestCommandKill(NetTestCommandGeneric): pid = bg_processes.get_pid(bg_id) logging.debug("Killing background id "%d", pid "%d"" % (bg_id, pid)) os.killpg(os.getpgid(pid), signal.SIGINT) + os.waitpid(pid, 0) + result = get_bg_process_result(bg_id) bg_processes.remove(bg_id) - self.set_result({"passed": True}) + self.set_result(result)
def get_command_class(command): cmd_type = command["type"] @@ -164,15 +176,13 @@ class NetTestCommand: try: cmd_cls.run() result = cmd_cls.get_result() - tmp = pickle.dumps(result) - os.write(write_pipe, tmp) except KeyboardInterrupt: - pass + result = cmd_cls.get_result() except: type, value, tb = sys.exc_info() result = {"Exception": ''.join(traceback.format_exception(type, value, tb))} - tmp = pickle.dumps(result) - os.write(write_pipe, tmp) + tmp = pickle.dumps(result) + os.write(write_pipe, tmp) os.close(write_pipe) os._exit(0) else:
lnst-developers@lists.fedorahosted.org