commit d9d07ef1ee8863b7598e147ccb8d4952e2f78461
Author: Jiri Pirko <jpirko(a)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(a)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(a)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: