Support SIGUSR1 to stop boot test early and count as failure
There is a user need to be able to stop a boot test before it is done and
to mark the boot test as a failure but to allow the obmc_boot_test program
to continue running other tests.
Change-Id: I910f7269f8fc1f3dde50830e07495b1039b007c0
Signed-off-by: Michael Walsh <micwalsh@us.ibm.com>
diff --git a/lib/obmc_boot_test.py b/lib/obmc_boot_test.py
index f0b6ad3..d7c5e36 100755
--- a/lib/obmc_boot_test.py
+++ b/lib/obmc_boot_test.py
@@ -10,6 +10,7 @@
import glob
import random
import re
+import signal
try:
import cPickle as pickle
except ImportError:
@@ -340,6 +341,35 @@
ffdc_prefix = openbmc_nickname + "." + time_string
+def default_sigusr1(signal_number=0,
+ frame=None):
+ r"""
+ Handle SIGUSR1 by doing nothing.
+
+ This function assists in debugging SIGUSR1 processing by printing messages
+ to stdout and to the log.html file.
+
+ Description of argument(s):
+ signal_number The signal number (should always be 10 for SIGUSR1).
+ frame The frame data.
+ """
+
+ gp.printn()
+ gp.print_executing()
+ gp.lprint_executing()
+
+
+def set_default_siguser1():
+ r"""
+ Set the default_sigusr1 function to be the SIGUSR1 handler.
+ """
+
+ gp.printn()
+ gp.print_executing()
+ gp.lprint_executing()
+ signal.signal(signal.SIGUSR1, default_sigusr1)
+
+
def setup():
r"""
Do general program setup tasks.
@@ -350,6 +380,7 @@
gp.qprintn()
+ set_default_siguser1()
transitional_boot_selected = False
robot_pgm_dir_path = os.path.dirname(__file__) + os.sep
@@ -752,6 +783,33 @@
del last_ten[:max(0, len(last_ten) - max_boot_history)]
+def stop_boot_test(signal_number=0,
+ frame=None):
+ r"""
+ Handle SIGUSR1 by aborting the boot test that is running.
+
+ Description of argument(s):
+ signal_number The signal number (should always be 10 for SIGUSR1).
+ frame The frame data.
+ """
+
+ gp.printn()
+ gp.print_executing()
+ gp.lprint_executing()
+
+ # Restore original sigusr1 handler.
+ set_default_siguser1()
+
+ message = "The caller has asked that the boot test be stopped and marked"
+ message += " as a failure."
+
+ function_stack = gm.get_function_stack()
+ if "wait_state" in function_stack:
+ st.set_wait_early_exit_message(message)
+ else:
+ BuiltIn().fail(gp.sprint_error(message))
+
+
def run_boot(boot):
r"""
Run the specified boot.
@@ -762,6 +820,9 @@
global state
+ signal.signal(signal.SIGUSR1, stop_boot_test)
+ gp.qprint_timen("stop_boot_test is armed.")
+
print_test_start_message(boot)
plug_in_setup()
@@ -770,6 +831,7 @@
if rc != 0:
error_message = "Plug-in failed with non-zero return code.\n" +\
gp.sprint_var(rc, 1)
+ set_default_siguser1()
BuiltIn().fail(gp.sprint_error(error_message))
if test_mode:
@@ -795,6 +857,7 @@
if rc != 0:
error_message = "Plug-in failed with non-zero return code.\n"
error_message += gp.sprint_var(rc, 1)
+ set_default_siguser1()
BuiltIn().fail(gp.sprint_error(error_message))
else:
match_state = st.anchor_state(state)
@@ -817,8 +880,12 @@
if rc != 0:
error_message = "Plug-in failed with non-zero return code.\n" +\
gp.sprint_var(rc, 1)
+ set_default_siguser1()
BuiltIn().fail(gp.sprint_error(error_message))
+ # Restore original sigusr1 handler.
+ set_default_siguser1()
+
def test_loop_body():
r"""