[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [XTF PATCH v3] xtf-runner: support two modes for getting output
We need two modes for getting output: 1. Use console directly with newer (>=4.8) Xen 2. Use log files for older Xen This patch implements both. The default behaviour is to use the console mode. Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- v3: 1. use os module for opening log file 2. poll up to 1 second for final output in logfile mode v2: delete auto selection mode, squash all patches into one. --- xtf-runner | 119 +++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 97 insertions(+), 22 deletions(-) diff --git a/xtf-runner b/xtf-runner index c063699..96a5ba0 100755 --- a/xtf-runner +++ b/xtf-runner @@ -7,7 +7,7 @@ Currently assumes the presence and availability of the `xl` toolstack. """ -import sys, os, os.path as path +import sys, os, os.path as path, signal from optparse import OptionParser from subprocess import Popen, PIPE, call as subproc_call, check_output @@ -425,30 +425,19 @@ def list_tests(opts): for sel in opts.selection: print sel +def run_test_console(opts, test): + """ Run a specific test via xenconsole""" -def run_test(test): - """ Run a specific test """ - - cmd = ['xl', 'create', '-p', test.cfg_path()] - print "Executing '%s'" % (" ".join(cmd), ) - rc = subproc_call(cmd) - if rc: - raise RunnerError("Failed to create VM") - - cmd = ['xl', 'console', test.vm_name()] + cmd = ['xl', 'create', '-Fc', test.cfg_path()] print "Executing '%s'" % (" ".join(cmd), ) - console = Popen(cmd, stdout = PIPE) + guest = Popen(cmd, stdout = PIPE, stderr = PIPE) - cmd = ['xl', 'unpause', test.vm_name()] - print "Executing '%s'" % (" ".join(cmd), ) - rc = subproc_call(cmd) - if rc: - raise RunnerError("Failed to unpause VM") + # stdout is console output, stderr is xl output + stdout, stderr = guest.communicate() - stdout, _ = console.communicate() - - if console.returncode: - raise RunnerError("Failed to obtain VM console") + if guest.returncode: + print stderr + raise RunnerError("Failed to communicate with guest") lines = stdout.splitlines() @@ -470,6 +459,59 @@ def run_test(test): return "ERROR" +should_exit = False +def sigalrm_handler(signum, frame): + """Signal handler for SIGALRM""" + + global should_exit + should_exit = True + +def run_test_logfile(opts, test): + """ Run a specific test via grepping log file""" + + global should_exit + fn = opts.logfile_dir + (opts.logfile_pattern % test) + + print "Using %s" % fn + + fd = os.open(fn, os.O_CREAT|os.O_RDONLY, 0644) + logfile = os.fdopen(fd) + logfile.seek(0, os.SEEK_END) + + cmd = ['xl', 'create', '-F', test.cfg_path()] + print "Executing '%s'" % (" ".join(cmd), ) + rc = subproc_call(cmd) + if rc: + raise RunnerError("Failed to run test") + + signal.signal(signal.SIGALRM, sigalrm_handler) + + lines = [] + should_exit = False + signal.alarm(1) + while not should_exit: + line = logfile.readline() + lines.append(line) + if "Test result:" in line: + should_exit = True + signal.alarm(0) + + logfile.close() + + print "".join(lines) + + test_result = lines[-1] + if not "Test result:" in test_result: + return "ERROR" + + for res in all_results: + + if res in test_result: + return res + + return "ERROR" + + def run_tests(opts): """ Run tests """ @@ -477,12 +519,21 @@ def run_tests(opts): if not len(tests): raise RunnerError("No tests to run") + if opts.mode == "console": + run_test = run_test_console + elif opts.mode == "logfile": + print "Using logfile mode, please make sure the log \ +files are not rotated!" + run_test = run_test_logfile + else: + raise RunnerError("Unrecognised mode") + rc = all_results.index('SUCCESS') results = [] for test in tests: - res = run_test(test) + res = run_test(opts, test) res_idx = all_results.index(res) if res_idx > rc: rc = res_idx @@ -519,6 +570,17 @@ def main(): " all tests in the selection, printing a summary of their\n" " results at the end.\n" "\n" + " To determine how runner should get output from Xen, use\n" + " --mode option. The default value is \"console\", which\n" + " means using xenconsole program to extract output.\n" + " The other supported value is \"logfile\", which\n" + " means to get output from log file.\n" + "\n" + " The \"logfile\" mode requires users to configure\n" + " xenconsoled to log guest console output. This mode\n" + " is useful for Xen version < 4.8. Also see --logfile-dir\n" + " and --logfile-pattern options.\n" + "\n" "Selections:\n" " A selection is zero or more of any of the following\n" " parameters: Categories, Environments and Tests.\n" @@ -596,6 +658,19 @@ def main(): dest = "host", help = "Restrict selection to applicable" " tests for the current host", ) + parser.add_option("-m", "--mode", action = "store", + dest = "mode", default = "console", type = "string", + help = "Instruct how runner gets its output (see below)") + parser.add_option("--logfile-dir", action = "store", + dest = "logfile_dir", default = "/var/log/xen/console/", + type = "string", + help = 'Specify the directory to look for console logs, \ +defaults to "/var/log/xen/console/"') + parser.add_option("--logfile-pattern", action = "store", + dest = "logfile_pattern", default = "guest-%s.log", + type = "string", + help = 'Specify the log file name pattern, \ +defaults to "guest-%s.log"') opts, args = parser.parse_args() opts.args = args -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |