* [AUTOTEST][PATCH] Add ability to call autotest client tests from kvm tests like a subtest.
@ 2011-05-04 14:42 Jiří Župka
2011-05-11 3:13 ` Amos Kong
0 siblings, 1 reply; 5+ messages in thread
From: Jiří Župka @ 2011-05-04 14:42 UTC (permalink / raw)
To: kvm-autotest, kvm, autotest, lmr, ldoktor, akong; +Cc: jzupka
Example run client/tests/sleeptest.
test.runsubtest("sleeptest", **args)
args is dictionary with parameters for subtest.
For sleeptest looks like { "seconds":5 }.
This args says sleeptest sleep 5 seconds.
This patch are necessary to avoid of creation double version of test.
netperf, multicast, etc..
Make patch of tests_base.cfs.sample in correct way.
Signed-off-by: Jiří Župka <jzupka@redhat.com>
---
client/bin/client_logging_config.py | 5 +-
client/bin/net/net_utils.py | 16 ++++-
client/common_lib/base_job.py | 2 +
client/common_lib/logging_config.py | 3 +-
client/common_lib/test.py | 21 ++++++-
client/tests/kvm/tests/subtest.py | 19 +++++
client/tests/kvm/tests_base.cfg.sample | 6 ++
client/tests/netperf2/netperf2.py | 3 +-
client/tools/html_report.py | 115 ++++++++++++++++++--------------
client/virt/virt_test_utils.py | 19 ++++--
10 files changed, 148 insertions(+), 61 deletions(-)
create mode 100644 client/tests/kvm/tests/subtest.py
diff --git a/client/bin/client_logging_config.py b/client/bin/client_logging_config.py
index a59b078..28c007d 100644
--- a/client/bin/client_logging_config.py
+++ b/client/bin/client_logging_config.py
@@ -12,8 +12,9 @@ class ClientLoggingConfig(logging_config.LoggingConfig):
def configure_logging(self, results_dir=None, verbose=False):
- super(ClientLoggingConfig, self).configure_logging(use_console=True,
- verbose=verbose)
+ super(ClientLoggingConfig, self).configure_logging(
+ use_console=self.use_console,
+ verbose=verbose)
if results_dir:
log_dir = os.path.join(results_dir, 'debug')
diff --git a/client/bin/net/net_utils.py b/client/bin/net/net_utils.py
index 868958c..ac9b494 100644
--- a/client/bin/net/net_utils.py
+++ b/client/bin/net/net_utils.py
@@ -5,7 +5,7 @@ This library is to release in the public repository.
import commands, os, re, socket, sys, time, struct
from autotest_lib.client.common_lib import error
-import utils
+from autotest_lib.client.common_lib import utils
TIMEOUT = 10 # Used for socket timeout and barrier timeout
@@ -27,6 +27,20 @@ class network_utils(object):
utils.system('/sbin/ifconfig -a')
+ def get_corespond_local_ip(self, query_ip, netmask="24"):
+ """
+ Get ip address in local system which can communicate with quert_ip.
+
+ @param query_ip: IP of client which want communicate with autotest machine.
+ @return: IP address which can communicate with query_ip
+ """
+ ip = utils.system_output("ip addr show to %s/%s" % (query_ip, netmask))
+ ip = re.search(r"inet ([0-9.]*)/",ip)
+ if ip is None:
+ return ip
+ return ip.group(1)
+
+
def disable_ip_local_loopback(self, ignore_status=False):
utils.system("echo '1' > /proc/sys/net/ipv4/route/no_local_loopback",
ignore_status=ignore_status)
diff --git a/client/common_lib/base_job.py b/client/common_lib/base_job.py
index 843c0e8..eef9efc 100644
--- a/client/common_lib/base_job.py
+++ b/client/common_lib/base_job.py
@@ -1117,6 +1117,7 @@ class base_job(object):
tag_parts = []
# build up the parts of the tag used for the test name
+ master_testpath = dargs.get('master_testpath', "")
base_tag = dargs.pop('tag', None)
if base_tag:
tag_parts.append(str(base_tag))
@@ -1132,6 +1133,7 @@ class base_job(object):
if subdir_tag:
tag_parts.append(subdir_tag)
subdir = '.'.join([testname] + tag_parts)
+ subdir = os.path.join(master_testpath, subdir)
tag = '.'.join(tag_parts)
return full_testname, subdir, tag
diff --git a/client/common_lib/logging_config.py b/client/common_lib/logging_config.py
index afe754a..9114d7a 100644
--- a/client/common_lib/logging_config.py
+++ b/client/common_lib/logging_config.py
@@ -32,9 +32,10 @@ class LoggingConfig(object):
fmt='%(asctime)s %(levelname)-5.5s| %(message)s',
datefmt='%H:%M:%S')
- def __init__(self):
+ def __init__(self, use_console=True):
self.logger = logging.getLogger()
self.global_level = logging.DEBUG
+ self.use_console = use_console
@classmethod
diff --git a/client/common_lib/test.py b/client/common_lib/test.py
index c55d23b..b1a0904 100644
--- a/client/common_lib/test.py
+++ b/client/common_lib/test.py
@@ -465,6 +465,24 @@ class base_test(object):
self.job.enable_warnings("NETWORK")
+ def runsubtest(self, url, *args, **dargs):
+ """
+ This call subtest in running test.
+
+ @param test: Parent test.
+ @param url: Url of new test.
+ @param tag: Tag added to test name.
+ @param args: Args for subtest.
+ @param dargs: Distionary args for subtest.
+ @iterations: Number of iteration of subtest.
+ @profile_inly: If true not profile.
+ """
+ dargs["profile_only"] = dargs.get("profile_only", True)
+ test_basepath = self.outputdir[len(self.job.resultdir + "/"):]
+ self.job.run_test(url, master_testpath=test_basepath,
+ *args, **dargs)
+
+
def _get_nonstar_args(func):
"""Extract all the (normal) function parameter names.
@@ -658,7 +676,8 @@ def runtest(job, url, tag, args, dargs,
if not bindir:
raise error.TestError(testname + ': test does not exist')
- outputdir = os.path.join(job.resultdir, testname)
+ subdir = os.path.join(dargs.pop('master_testpath', ""), testname)
+ outputdir = os.path.join(job.resultdir, subdir)
if tag:
outputdir += '.' + tag
diff --git a/client/tests/kvm/tests/subtest.py b/client/tests/kvm/tests/subtest.py
new file mode 100644
index 0000000..c2baadc
--- /dev/null
+++ b/client/tests/kvm/tests/subtest.py
@@ -0,0 +1,19 @@
+import os, logging
+
+
+def run_subtest(test, params, env):
+ """
+ Run an autotest test inside a guest and subtest on host side.
+ This test should be substitution netperf test in kvm.
+
+ @param test: kvm test object.
+ @param params: Dictionary with test parameters.
+ @param env: Dictionary with the test environment.
+ """
+
+ # Collect test parameters
+ test_control_file = params.get("test_control_file")
+ args = eval(params.get("test_control_args"))
+
+ # Run subtest with args.
+ test.runsubtest(test_control_file, **args)
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 810a4bd..c7c05a5 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -261,6 +261,12 @@ variants:
- systemtap:
test_control_file = systemtap.control
+ - subtest: install setup unattended_install.cdrom
+ type = subtest
+ test_timeout = 1800
+ test_control_file = sleeptest
+ test_control_args = {"seconds": 5}
+
- linux_s3: install setup unattended_install.cdrom
only Linux
type = linux_s3
diff --git a/client/tests/netperf2/netperf2.py b/client/tests/netperf2/netperf2.py
index 1b659dd..23d25c5 100644
--- a/client/tests/netperf2/netperf2.py
+++ b/client/tests/netperf2/netperf2.py
@@ -2,6 +2,7 @@ import os, time, re, logging
from autotest_lib.client.bin import test, utils
from autotest_lib.client.bin.net import net_utils
from autotest_lib.client.common_lib import error
+from autotest_lib.client.common_lib import barrier
MPSTAT_IX = 0
NETPERF_IX = 1
@@ -36,7 +37,7 @@ class netperf2(test.test):
def run_once(self, server_ip, client_ip, role, test = 'TCP_STREAM',
test_time = 15, stream_list = [1], test_specific_args = '',
- cpu_affinity = '', dev = '', bidi = False, wait_time = 5):
+ cpu_affinity = '', dev = '', bidi = False, wait_time = 2):
"""
server_ip: IP address of host running netserver
client_ip: IP address of host running netperf client(s)
diff --git a/client/tools/html_report.py b/client/tools/html_report.py
index 7b17a75..563a7a9 100755
--- a/client/tools/html_report.py
+++ b/client/tools/html_report.py
@@ -1372,7 +1372,7 @@ function processList(ul) {
}
"""
-stimelist = []
+
def make_html_file(metadata, results, tag, host, output_file_name, dirname):
@@ -1430,11 +1430,12 @@ return true;
total_failed = 0
total_passed = 0
for res in results:
- total_executed += 1
- if res['status'] == 'GOOD':
- total_passed += 1
- else:
- total_failed += 1
+ if results[res][2] != None:
+ total_executed += 1
+ if results[res][2]['status'] == 'GOOD':
+ total_passed += 1
+ else:
+ total_failed += 1
stat_str = 'No test cases executed'
if total_executed > 0:
failed_perct = int(float(total_failed)/float(total_executed)*100)
@@ -1471,39 +1472,46 @@ id="t1" class="stats table-autosort:4 table-autofilter table-stripeclass:alterna
<tbody>
"""
print >> output, result_table_prefix
- for res in results:
- print >> output, '<tr>'
- print >> output, '<td align="left">%s</td>' % res['time']
- print >> output, '<td align="left">%s</td>' % res['testcase']
- if res['status'] == 'GOOD':
- print >> output, '<td align=\"left\"><b><font color="#00CC00">PASS</font></b></td>'
- elif res['status'] == 'FAIL':
- print >> output, '<td align=\"left\"><b><font color="red">FAIL</font></b></td>'
- elif res['status'] == 'ERROR':
- print >> output, '<td align=\"left\"><b><font color="red">ERROR!</font></b></td>'
- else:
- print >> output, '<td align=\"left\">%s</td>' % res['status']
- # print exec time (seconds)
- print >> output, '<td align="left">%s</td>' % res['exec_time_sec']
- # print log only if test failed..
- if res['log']:
- #chop all '\n' from log text (to prevent html errors)
- rx1 = re.compile('(\s+)')
- log_text = rx1.sub(' ', res['log'])
-
- # allow only a-zA-Z0-9_ in html title name
- # (due to bug in MS-explorer)
- rx2 = re.compile('([^a-zA-Z_0-9])')
- updated_tag = rx2.sub('_', res['title'])
-
- html_body_text = '<html><head><title>%s</title></head><body>%s</body></html>' % (str(updated_tag), log_text)
- print >> output, '<td align=\"left\"><A HREF=\"#\" onClick=\"popup(\'%s\',\'%s\')\">Info</A></td>' % (str(updated_tag), str(html_body_text))
- else:
- print >> output, '<td align=\"left\"></td>'
- # print execution time
- print >> output, '<td align="left"><A HREF=\"%s\">Debug</A></td>' % os.path.join(dirname, res['title'], "debug")
+ def print_result(result, indent):
+ while result != []:
+ r = result.pop(0)
+ print r
+ res = results[r][2]
+ print >> output, '<tr>'
+ print >> output, '<td align="left">%s</td>' % res['time']
+ print >> output, '<td align="left" style="padding-left:%dpx">%s</td>' % (indent * 20, res['title'])
+ if res['status'] == 'GOOD':
+ print >> output, '<td align=\"left\"><b><font color="#00CC00">PASS</font></b></td>'
+ elif res['status'] == 'FAIL':
+ print >> output, '<td align=\"left\"><b><font color="red">FAIL</font></b></td>'
+ elif res['status'] == 'ERROR':
+ print >> output, '<td align=\"left\"><b><font color="red">ERROR!</font></b></td>'
+ else:
+ print >> output, '<td align=\"left\">%s</td>' % res['status']
+ # print exec time (seconds)
+ print >> output, '<td align="left">%s</td>' % res['exec_time_sec']
+ # print log only if test failed..
+ if res['log']:
+ #chop all '\n' from log text (to prevent html errors)
+ rx1 = re.compile('(\s+)')
+ log_text = rx1.sub(' ', res['log'])
+
+ # allow only a-zA-Z0-9_ in html title name
+ # (due to bug in MS-explorer)
+ rx2 = re.compile('([^a-zA-Z_0-9])')
+ updated_tag = rx2.sub('_', res['title'])
+
+ html_body_text = '<html><head><title>%s</title></head><body>%s</body></html>' % (str(updated_tag), log_text)
+ print >> output, '<td align=\"left\"><A HREF=\"#\" onClick=\"popup(\'%s\',\'%s\')\">Info</A></td>' % (str(updated_tag), str(html_body_text))
+ else:
+ print >> output, '<td align=\"left\"></td>'
+ # print execution time
+ print >> output, '<td align="left"><A HREF=\"%s\">Debug</A></td>' % os.path.join(dirname, res['subdir'], "debug")
- print >> output, '</tr>'
+ print >> output, '</tr>'
+ print_result(results[r][1], indent + 1)
+
+ print_result(results[""][1], 0)
print >> output, "</tbody></table>"
@@ -1531,21 +1539,27 @@ id="t1" class="stats table-autosort:4 table-autofilter table-stripeclass:alterna
output.close()
-def parse_result(dirname, line):
+def parse_result(dirname, line, results_data):
"""
Parse job status log line.
@param dirname: Job results dir
@param line: Status log line.
+ @param results_data: Dictionary with for results.
"""
parts = line.split()
if len(parts) < 4:
return None
- global stimelist
+ global tests
if parts[0] == 'START':
pair = parts[3].split('=')
stime = int(pair[1])
- stimelist.append(stime)
+ results_data[parts[1]] = [stime, [], None]
+ try:
+ parent_test = re.findall(r".*/", parts[1])[0][:-1]
+ results_data[parent_test][1].append(parts[1])
+ except IndexError:
+ results_data[""][1].append(parts[1])
elif (parts[0] == 'END'):
result = {}
@@ -1562,21 +1576,25 @@ def parse_result(dirname, line):
result['exec_time_sec'] = 'na'
tag = parts[3]
+ result['subdir'] = parts[2]
# assign actual values
rx = re.compile('^(\w+)\.(.*)$')
m1 = rx.findall(parts[3])
- result['testcase'] = str(tag)
+ if len(m1):
+ result['testcase'] = m1[0][1]
+ else:
+ result['testcase'] = parts[3]
result['title'] = str(tag)
result['status'] = parts[1]
if result['status'] != 'GOOD':
result['log'] = get_exec_log(dirname, tag)
- if len(stimelist)>0:
+ if len(results_data)>0:
pair = parts[4].split('=')
etime = int(pair[1])
- stime = stimelist.pop()
+ stime = results_data[parts[2]][0]
total_exec_time_sec = etime - stime
result['exec_time_sec'] = total_exec_time_sec
- return result
+ results_data[parts[2]][2] = result
return None
@@ -1699,16 +1717,15 @@ def create_report(dirname, html_path='', output_file_name=None):
host = get_info_file(os.path.join(sysinfo_dir, 'hostname'))
rx = re.compile('^\s+[END|START].*$')
# create the results set dict
- results_data = []
+ results_data = {}
+ results_data[""] = [0, [], None]
if os.path.exists(status_file_name):
f = open(status_file_name, "r")
lines = f.readlines()
f.close()
for line in lines:
if rx.match(line):
- result_dict = parse_result(dirname, line)
- if result_dict:
- results_data.append(result_dict)
+ parse_result(dirname, line, results_data)
# create the meta info dict
metalist = {
'uname': get_info_file(os.path.join(sysinfo_dir, 'uname')),
diff --git a/client/virt/virt_test_utils.py b/client/virt/virt_test_utils.py
index e3a18d2..556d3e5 100644
--- a/client/virt/virt_test_utils.py
+++ b/client/virt/virt_test_utils.py
@@ -430,13 +430,15 @@ def get_memory_info(lvms):
return meminfo
-def run_autotest(vm, session, control_path, timeout, outputdir, params):
+def run_autotest(vm, session, control_path, control_args, timeout, outputdir,
+ params):
"""
Run an autotest control file inside a guest (linux only utility).
@param vm: VM object.
@param session: A shell session on the VM provided.
@param control_path: A path to an autotest control file.
+ @param control_args: An argumets for control file.
@param timeout: Timeout under which the autotest control file must complete.
@param outputdir: Path on host where we should copy the guest autotest
results to.
@@ -561,6 +563,10 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
pass
try:
bg = None
+ if control_args != None:
+ control_args = ' -a "' + control_args + '"'
+ else:
+ control_args = ""
try:
logging.info("---------------- Test output ----------------")
if migrate_background:
@@ -568,7 +574,8 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
mig_protocol = params.get("migration_protocol", "tcp")
bg = virt_utils.Thread(session.cmd_output,
- kwargs={'cmd': "bin/autotest control",
+ kwargs={'cmd': "bin/autotest control" +
+ control_args,
'timeout': timeout,
'print_func': logging.info})
@@ -579,8 +586,8 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
"migration ...")
vm.migrate(timeout=mig_timeout, protocol=mig_protocol)
else:
- session.cmd_output("bin/autotest control", timeout=timeout,
- print_func=logging.info)
+ session.cmd_output("bin/autotest control" + control_args,
+ timeout=timeout, print_func=logging.info)
finally:
logging.info("------------- End of test output ------------")
if migrate_background and bg:
@@ -624,8 +631,8 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
def get_loss_ratio(output):
"""
- Get the packet loss ratio from the output of ping
-.
+ Get the packet loss ratio from the output of ping.
+
@param output: Ping output.
"""
try:
--
1.7.4.4
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [AUTOTEST][PATCH] Add ability to call autotest client tests from kvm tests like a subtest.
2011-05-04 14:42 [AUTOTEST][PATCH] Add ability to call autotest client tests from kvm tests like a subtest Jiří Župka
@ 2011-05-11 3:13 ` Amos Kong
0 siblings, 0 replies; 5+ messages in thread
From: Amos Kong @ 2011-05-11 3:13 UTC (permalink / raw)
To: Jiří Župka; +Cc: kvm-autotest, kvm, autotest, lmr, ldoktor
On Wed, May 04, 2011 at 04:42:39PM +0200, Jiří Župka wrote:
> Example run client/tests/sleeptest.
>
> test.runsubtest("sleeptest", **args)
>
> args is dictionary with parameters for subtest.
> For sleeptest looks like { "seconds":5 }.
> This args says sleeptest sleep 5 seconds.
>
> This patch are necessary to avoid of creation double version of test.
> netperf, multicast, etc..
>
> Make patch of tests_base.cfs.sample in correct way.
>
> Signed-off-by: Jiří Župka <jzupka@redhat.com>
Patch works for me, it would be better if you can split different
kind of fixes(adding new feature, adding helper function, fixing bug,
fixing coding style, ..) to single patches
> ---
> client/bin/client_logging_config.py | 5 +-
> client/bin/net/net_utils.py | 16 ++++-
> client/common_lib/base_job.py | 2 +
> client/common_lib/logging_config.py | 3 +-
> client/common_lib/test.py | 21 ++++++-
> client/tests/kvm/tests/subtest.py | 19 +++++
> client/tests/kvm/tests_base.cfg.sample | 6 ++
> client/tests/netperf2/netperf2.py | 3 +-
> client/tools/html_report.py | 115 ++++++++++++++++++--------------
> client/virt/virt_test_utils.py | 19 ++++--
> 10 files changed, 148 insertions(+), 61 deletions(-)
> create mode 100644 client/tests/kvm/tests/subtest.py
>
> diff --git a/client/bin/client_logging_config.py b/client/bin/client_logging_config.py
> index a59b078..28c007d 100644
> --- a/client/bin/client_logging_config.py
> +++ b/client/bin/client_logging_config.py
> @@ -12,8 +12,9 @@ class ClientLoggingConfig(logging_config.LoggingConfig):
>
>
> def configure_logging(self, results_dir=None, verbose=False):
> - super(ClientLoggingConfig, self).configure_logging(use_console=True,
> - verbose=verbose)
> + super(ClientLoggingConfig, self).configure_logging(
> + use_console=self.use_console,
> + verbose=verbose)
>
> if results_dir:
> log_dir = os.path.join(results_dir, 'debug')
> diff --git a/client/bin/net/net_utils.py b/client/bin/net/net_utils.py
> index 868958c..ac9b494 100644
> --- a/client/bin/net/net_utils.py
> +++ b/client/bin/net/net_utils.py
> @@ -5,7 +5,7 @@ This library is to release in the public repository.
>
> import commands, os, re, socket, sys, time, struct
> from autotest_lib.client.common_lib import error
> -import utils
> +from autotest_lib.client.common_lib import utils
>
> TIMEOUT = 10 # Used for socket timeout and barrier timeout
>
> @@ -27,6 +27,20 @@ class network_utils(object):
> utils.system('/sbin/ifconfig -a')
>
>
> + def get_corespond_local_ip(self, query_ip, netmask="24"):
This function is not used in your patch, you can split it to a single patch.
> + """
> + Get ip address in local system which can communicate with quert_ip.
> +
> + @param query_ip: IP of client which want communicate with autotest machine.
> + @return: IP address which can communicate with query_ip
> + """
> + ip = utils.system_output("ip addr show to %s/%s" % (query_ip, netmask))
> + ip = re.search(r"inet ([0-9.]*)/",ip)
> + if ip is None:
> + return ip
> + return ip.group(1)
> +
> +
> def disable_ip_local_loopback(self, ignore_status=False):
> utils.system("echo '1' > /proc/sys/net/ipv4/route/no_local_loopback",
> ignore_status=ignore_status)
> diff --git a/client/common_lib/base_job.py b/client/common_lib/base_job.py
> index 843c0e8..eef9efc 100644
> --- a/client/common_lib/base_job.py
> +++ b/client/common_lib/base_job.py
> @@ -1117,6 +1117,7 @@ class base_job(object):
> tag_parts = []
>
> # build up the parts of the tag used for the test name
> + master_testpath = dargs.get('master_testpath', "")
> base_tag = dargs.pop('tag', None)
> if base_tag:
> tag_parts.append(str(base_tag))
> @@ -1132,6 +1133,7 @@ class base_job(object):
> if subdir_tag:
> tag_parts.append(subdir_tag)
> subdir = '.'.join([testname] + tag_parts)
> + subdir = os.path.join(master_testpath, subdir)
> tag = '.'.join(tag_parts)
>
> return full_testname, subdir, tag
> diff --git a/client/common_lib/logging_config.py b/client/common_lib/logging_config.py
> index afe754a..9114d7a 100644
> --- a/client/common_lib/logging_config.py
> +++ b/client/common_lib/logging_config.py
> @@ -32,9 +32,10 @@ class LoggingConfig(object):
> fmt='%(asctime)s %(levelname)-5.5s| %(message)s',
> datefmt='%H:%M:%S')
>
> - def __init__(self):
> + def __init__(self, use_console=True):
> self.logger = logging.getLogger()
> self.global_level = logging.DEBUG
> + self.use_console = use_console
>
>
> @classmethod
> diff --git a/client/common_lib/test.py b/client/common_lib/test.py
> index c55d23b..b1a0904 100644
> --- a/client/common_lib/test.py
> +++ b/client/common_lib/test.py
> @@ -465,6 +465,24 @@ class base_test(object):
> self.job.enable_warnings("NETWORK")
>
>
> + def runsubtest(self, url, *args, **dargs):
> + """
> + This call subtest in running test.
> +
> + @param test: Parent test.
> + @param url: Url of new test.
> + @param tag: Tag added to test name.
> + @param args: Args for subtest.
> + @param dargs: Distionary args for subtest.
> + @iterations: Number of iteration of subtest.
> + @profile_inly: If true not profile.
> + """
> + dargs["profile_only"] = dargs.get("profile_only", True)
> + test_basepath = self.outputdir[len(self.job.resultdir + "/"):]
> + self.job.run_test(url, master_testpath=test_basepath,
> + *args, **dargs)
> +
> +
> def _get_nonstar_args(func):
> """Extract all the (normal) function parameter names.
>
> @@ -658,7 +676,8 @@ def runtest(job, url, tag, args, dargs,
> if not bindir:
> raise error.TestError(testname + ': test does not exist')
>
> - outputdir = os.path.join(job.resultdir, testname)
> + subdir = os.path.join(dargs.pop('master_testpath', ""), testname)
> + outputdir = os.path.join(job.resultdir, subdir)
> if tag:
> outputdir += '.' + tag
>
> diff --git a/client/tests/kvm/tests/subtest.py b/client/tests/kvm/tests/subtest.py
> new file mode 100644
> index 0000000..c2baadc
> --- /dev/null
> +++ b/client/tests/kvm/tests/subtest.py
> @@ -0,0 +1,19 @@
> +import os, logging
> +
> +
> +def run_subtest(test, params, env):
> + """
> + Run an autotest test inside a guest and subtest on host side.
> + This test should be substitution netperf test in kvm.
> +
> + @param test: kvm test object.
> + @param params: Dictionary with test parameters.
> + @param env: Dictionary with the test environment.
> + """
> +
> + # Collect test parameters
> + test_control_file = params.get("test_control_file")
> + args = eval(params.get("test_control_args"))
> +
> + # Run subtest with args.
> + test.runsubtest(test_control_file, **args)
> diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
> index 810a4bd..c7c05a5 100644
> --- a/client/tests/kvm/tests_base.cfg.sample
> +++ b/client/tests/kvm/tests_base.cfg.sample
> @@ -261,6 +261,12 @@ variants:
> - systemtap:
> test_control_file = systemtap.control
>
> + - subtest: install setup unattended_install.cdrom
> + type = subtest
> + test_timeout = 1800
> + test_control_file = sleeptest
> + test_control_args = {"seconds": 5}
> +
> - linux_s3: install setup unattended_install.cdrom
> only Linux
> type = linux_s3
> diff --git a/client/tests/netperf2/netperf2.py b/client/tests/netperf2/netperf2.py
> index 1b659dd..23d25c5 100644
> --- a/client/tests/netperf2/netperf2.py
> +++ b/client/tests/netperf2/netperf2.py
> @@ -2,6 +2,7 @@ import os, time, re, logging
> from autotest_lib.client.bin import test, utils
> from autotest_lib.client.bin.net import net_utils
> from autotest_lib.client.common_lib import error
> +from autotest_lib.client.common_lib import barrier
>
> MPSTAT_IX = 0
> NETPERF_IX = 1
> @@ -36,7 +37,7 @@ class netperf2(test.test):
>
> def run_once(self, server_ip, client_ip, role, test = 'TCP_STREAM',
> test_time = 15, stream_list = [1], test_specific_args = '',
> - cpu_affinity = '', dev = '', bidi = False, wait_time = 5):
> + cpu_affinity = '', dev = '', bidi = False, wait_time = 2):
why reduce the wait time ?
> """
> server_ip: IP address of host running netserver
> client_ip: IP address of host running netperf client(s)
> diff --git a/client/tools/html_report.py b/client/tools/html_report.py
> index 7b17a75..563a7a9 100755
> --- a/client/tools/html_report.py
> +++ b/client/tools/html_report.py
need split fix of html_report to a single patch.
> @@ -1372,7 +1372,7 @@ function processList(ul) {
> }
> """
>
> -stimelist = []
> +
>
>
> def make_html_file(metadata, results, tag, host, output_file_name, dirname):
> @@ -1430,11 +1430,12 @@ return true;
> total_failed = 0
> total_passed = 0
> for res in results:
> - total_executed += 1
> - if res['status'] == 'GOOD':
> - total_passed += 1
> - else:
> - total_failed += 1
> + if results[res][2] != None:
> + total_executed += 1
> + if results[res][2]['status'] == 'GOOD':
> + total_passed += 1
> + else:
> + total_failed += 1
> stat_str = 'No test cases executed'
> if total_executed > 0:
> failed_perct = int(float(total_failed)/float(total_executed)*100)
> @@ -1471,39 +1472,46 @@ id="t1" class="stats table-autosort:4 table-autofilter table-stripeclass:alterna
> <tbody>
> """
> print >> output, result_table_prefix
> - for res in results:
> - print >> output, '<tr>'
> - print >> output, '<td align="left">%s</td>' % res['time']
> - print >> output, '<td align="left">%s</td>' % res['testcase']
> - if res['status'] == 'GOOD':
> - print >> output, '<td align=\"left\"><b><font color="#00CC00">PASS</font></b></td>'
> - elif res['status'] == 'FAIL':
> - print >> output, '<td align=\"left\"><b><font color="red">FAIL</font></b></td>'
> - elif res['status'] == 'ERROR':
> - print >> output, '<td align=\"left\"><b><font color="red">ERROR!</font></b></td>'
> - else:
> - print >> output, '<td align=\"left\">%s</td>' % res['status']
> - # print exec time (seconds)
> - print >> output, '<td align="left">%s</td>' % res['exec_time_sec']
> - # print log only if test failed..
> - if res['log']:
> - #chop all '\n' from log text (to prevent html errors)
> - rx1 = re.compile('(\s+)')
> - log_text = rx1.sub(' ', res['log'])
> -
> - # allow only a-zA-Z0-9_ in html title name
> - # (due to bug in MS-explorer)
> - rx2 = re.compile('([^a-zA-Z_0-9])')
> - updated_tag = rx2.sub('_', res['title'])
> -
> - html_body_text = '<html><head><title>%s</title></head><body>%s</body></html>' % (str(updated_tag), log_text)
> - print >> output, '<td align=\"left\"><A HREF=\"#\" onClick=\"popup(\'%s\',\'%s\')\">Info</A></td>' % (str(updated_tag), str(html_body_text))
> - else:
> - print >> output, '<td align=\"left\"></td>'
> - # print execution time
> - print >> output, '<td align="left"><A HREF=\"%s\">Debug</A></td>' % os.path.join(dirname, res['title'], "debug")
> + def print_result(result, indent):
> + while result != []:
> + r = result.pop(0)
> + print r
> + res = results[r][2]
> + print >> output, '<tr>'
> + print >> output, '<td align="left">%s</td>' % res['time']
> + print >> output, '<td align="left" style="padding-left:%dpx">%s</td>' % (indent * 20, res['title'])
> + if res['status'] == 'GOOD':
> + print >> output, '<td align=\"left\"><b><font color="#00CC00">PASS</font></b></td>'
> + elif res['status'] == 'FAIL':
> + print >> output, '<td align=\"left\"><b><font color="red">FAIL</font></b></td>'
> + elif res['status'] == 'ERROR':
> + print >> output, '<td align=\"left\"><b><font color="red">ERROR!</font></b></td>'
> + else:
> + print >> output, '<td align=\"left\">%s</td>' % res['status']
> + # print exec time (seconds)
> + print >> output, '<td align="left">%s</td>' % res['exec_time_sec']
> + # print log only if test failed..
> + if res['log']:
> + #chop all '\n' from log text (to prevent html errors)
> + rx1 = re.compile('(\s+)')
> + log_text = rx1.sub(' ', res['log'])
> +
> + # allow only a-zA-Z0-9_ in html title name
> + # (due to bug in MS-explorer)
> + rx2 = re.compile('([^a-zA-Z_0-9])')
> + updated_tag = rx2.sub('_', res['title'])
> +
> + html_body_text = '<html><head><title>%s</title></head><body>%s</body></html>' % (str(updated_tag), log_text)
> + print >> output, '<td align=\"left\"><A HREF=\"#\" onClick=\"popup(\'%s\',\'%s\')\">Info</A></td>' % (str(updated_tag), str(html_body_text))
> + else:
> + print >> output, '<td align=\"left\"></td>'
> + # print execution time
> + print >> output, '<td align="left"><A HREF=\"%s\">Debug</A></td>' % os.path.join(dirname, res['subdir'], "debug")
>
> - print >> output, '</tr>'
> + print >> output, '</tr>'
> + print_result(results[r][1], indent + 1)
> +
> + print_result(results[""][1], 0)
> print >> output, "</tbody></table>"
>
>
> @@ -1531,21 +1539,27 @@ id="t1" class="stats table-autosort:4 table-autofilter table-stripeclass:alterna
> output.close()
>
>
> -def parse_result(dirname, line):
> +def parse_result(dirname, line, results_data):
> """
> Parse job status log line.
>
> @param dirname: Job results dir
> @param line: Status log line.
> + @param results_data: Dictionary with for results.
> """
> parts = line.split()
> if len(parts) < 4:
> return None
> - global stimelist
> + global tests
> if parts[0] == 'START':
> pair = parts[3].split('=')
> stime = int(pair[1])
> - stimelist.append(stime)
> + results_data[parts[1]] = [stime, [], None]
> + try:
> + parent_test = re.findall(r".*/", parts[1])[0][:-1]
> + results_data[parent_test][1].append(parts[1])
> + except IndexError:
> + results_data[""][1].append(parts[1])
>
> elif (parts[0] == 'END'):
> result = {}
> @@ -1562,21 +1576,25 @@ def parse_result(dirname, line):
> result['exec_time_sec'] = 'na'
> tag = parts[3]
>
> + result['subdir'] = parts[2]
> # assign actual values
> rx = re.compile('^(\w+)\.(.*)$')
> m1 = rx.findall(parts[3])
> - result['testcase'] = str(tag)
> + if len(m1):
> + result['testcase'] = m1[0][1]
> + else:
> + result['testcase'] = parts[3]
> result['title'] = str(tag)
> result['status'] = parts[1]
> if result['status'] != 'GOOD':
> result['log'] = get_exec_log(dirname, tag)
> - if len(stimelist)>0:
> + if len(results_data)>0:
> pair = parts[4].split('=')
> etime = int(pair[1])
> - stime = stimelist.pop()
> + stime = results_data[parts[2]][0]
> total_exec_time_sec = etime - stime
> result['exec_time_sec'] = total_exec_time_sec
> - return result
> + results_data[parts[2]][2] = result
> return None
>
>
> @@ -1699,16 +1717,15 @@ def create_report(dirname, html_path='', output_file_name=None):
> host = get_info_file(os.path.join(sysinfo_dir, 'hostname'))
> rx = re.compile('^\s+[END|START].*$')
> # create the results set dict
> - results_data = []
> + results_data = {}
> + results_data[""] = [0, [], None]
> if os.path.exists(status_file_name):
> f = open(status_file_name, "r")
> lines = f.readlines()
> f.close()
> for line in lines:
> if rx.match(line):
> - result_dict = parse_result(dirname, line)
> - if result_dict:
> - results_data.append(result_dict)
> + parse_result(dirname, line, results_data)
> # create the meta info dict
> metalist = {
> 'uname': get_info_file(os.path.join(sysinfo_dir, 'uname')),
> diff --git a/client/virt/virt_test_utils.py b/client/virt/virt_test_utils.py
> index e3a18d2..556d3e5 100644
> --- a/client/virt/virt_test_utils.py
> +++ b/client/virt/virt_test_utils.py
> @@ -430,13 +430,15 @@ def get_memory_info(lvms):
> return meminfo
>
>
> -def run_autotest(vm, session, control_path, timeout, outputdir, params):
> +def run_autotest(vm, session, control_path, control_args, timeout, outputdir,
> + params):
> """
> Run an autotest control file inside a guest (linux only utility).
>
> @param vm: VM object.
> @param session: A shell session on the VM provided.
> @param control_path: A path to an autotest control file.
> + @param control_args: An argumets for control file.
> @param timeout: Timeout under which the autotest control file must complete.
> @param outputdir: Path on host where we should copy the guest autotest
> results to.
> @@ -561,6 +563,10 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
> pass
> try:
> bg = None
> + if control_args != None:
> + control_args = ' -a "' + control_args + '"'
> + else:
> + control_args = ""
> try:
> logging.info("---------------- Test output ----------------")
> if migrate_background:
> @@ -568,7 +574,8 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
> mig_protocol = params.get("migration_protocol", "tcp")
>
> bg = virt_utils.Thread(session.cmd_output,
> - kwargs={'cmd': "bin/autotest control",
> + kwargs={'cmd': "bin/autotest control" +
> + control_args,
> 'timeout': timeout,
> 'print_func': logging.info})
>
> @@ -579,8 +586,8 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
> "migration ...")
> vm.migrate(timeout=mig_timeout, protocol=mig_protocol)
> else:
> - session.cmd_output("bin/autotest control", timeout=timeout,
> - print_func=logging.info)
> + session.cmd_output("bin/autotest control" + control_args,
> + timeout=timeout, print_func=logging.info)
> finally:
> logging.info("------------- End of test output ------------")
> if migrate_background and bg:
> @@ -624,8 +631,8 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
>
> def get_loss_ratio(output):
> """
> - Get the packet loss ratio from the output of ping
> -.
> + Get the packet loss ratio from the output of ping.
> +
> @param output: Ping output.
> """
> try:
> --
> 1.7.4.4
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [AUTOTEST][PATCH] Add ability to call autotest client tests from kvm tests like a subtest.
@ 2011-04-26 10:22 Jiří Župka
2011-04-26 15:08 ` Amos Kong
0 siblings, 1 reply; 5+ messages in thread
From: Jiří Župka @ 2011-04-26 10:22 UTC (permalink / raw)
To: kvm-autotest, kvm, autotest, lmr, ldoktor, akong; +Cc: jzupka
Example run autotest/client/netperf2 like a server.
test.runsubtest("netperf2", tag="server", server_ip=host_ip,
client_ip=guest_ip, role='server')
Client part is called in paralel thread on virtual machine.
guest = kvm_utils.Thread(kvm_test_utils.run_autotest,
(vm, session, control_path, control_args,
timeout, outputdir, params))
guest.start()
On the guest is required to have installed the program mpstat for netpert2 test.
Netperf2 test will be changed or will be created in new version.
This patch are necessary to avoid of creation double version of test.
netperf, multicast, etc..
Signed-off-by: Jiří Župka <jzupka@redhat.com>
---
client/bin/client_logging_config.py | 5 +-
client/bin/net/net_utils.py | 16 ++++-
client/common_lib/base_job.py | 2 +
client/common_lib/logging_config.py | 3 +-
client/common_lib/test.py | 21 ++++++-
client/tests/kvm/html_report.py | 115 ++++++++++++++++++--------------
client/tests/kvm/kvm_test_utils.py | 19 ++++--
client/tests/kvm/tests/subtest.py | 43 ++++++++++++
client/tests/kvm/tests_base.cfg.sample | 10 +++-
client/tests/netperf2/netperf2.py | 3 +-
10 files changed, 173 insertions(+), 64 deletions(-)
create mode 100644 client/tests/kvm/tests/subtest.py
diff --git a/client/bin/client_logging_config.py b/client/bin/client_logging_config.py
index a59b078..28c007d 100644
--- a/client/bin/client_logging_config.py
+++ b/client/bin/client_logging_config.py
@@ -12,8 +12,9 @@ class ClientLoggingConfig(logging_config.LoggingConfig):
def configure_logging(self, results_dir=None, verbose=False):
- super(ClientLoggingConfig, self).configure_logging(use_console=True,
- verbose=verbose)
+ super(ClientLoggingConfig, self).configure_logging(
+ use_console=self.use_console,
+ verbose=verbose)
if results_dir:
log_dir = os.path.join(results_dir, 'debug')
diff --git a/client/bin/net/net_utils.py b/client/bin/net/net_utils.py
index 868958c..ac9b494 100644
--- a/client/bin/net/net_utils.py
+++ b/client/bin/net/net_utils.py
@@ -5,7 +5,7 @@ This library is to release in the public repository.
import commands, os, re, socket, sys, time, struct
from autotest_lib.client.common_lib import error
-import utils
+from autotest_lib.client.common_lib import utils
TIMEOUT = 10 # Used for socket timeout and barrier timeout
@@ -27,6 +27,20 @@ class network_utils(object):
utils.system('/sbin/ifconfig -a')
+ def get_corespond_local_ip(self, query_ip, netmask="24"):
+ """
+ Get ip address in local system which can communicate with quert_ip.
+
+ @param query_ip: IP of client which want communicate with autotest machine.
+ @return: IP address which can communicate with query_ip
+ """
+ ip = utils.system_output("ip addr show to %s/%s" % (query_ip, netmask))
+ ip = re.search(r"inet ([0-9.]*)/",ip)
+ if ip is None:
+ return ip
+ return ip.group(1)
+
+
def disable_ip_local_loopback(self, ignore_status=False):
utils.system("echo '1' > /proc/sys/net/ipv4/route/no_local_loopback",
ignore_status=ignore_status)
diff --git a/client/common_lib/base_job.py b/client/common_lib/base_job.py
index 843c0e8..eef9efc 100644
--- a/client/common_lib/base_job.py
+++ b/client/common_lib/base_job.py
@@ -1117,6 +1117,7 @@ class base_job(object):
tag_parts = []
# build up the parts of the tag used for the test name
+ master_testpath = dargs.get('master_testpath', "")
base_tag = dargs.pop('tag', None)
if base_tag:
tag_parts.append(str(base_tag))
@@ -1132,6 +1133,7 @@ class base_job(object):
if subdir_tag:
tag_parts.append(subdir_tag)
subdir = '.'.join([testname] + tag_parts)
+ subdir = os.path.join(master_testpath, subdir)
tag = '.'.join(tag_parts)
return full_testname, subdir, tag
diff --git a/client/common_lib/logging_config.py b/client/common_lib/logging_config.py
index afe754a..9114d7a 100644
--- a/client/common_lib/logging_config.py
+++ b/client/common_lib/logging_config.py
@@ -32,9 +32,10 @@ class LoggingConfig(object):
fmt='%(asctime)s %(levelname)-5.5s| %(message)s',
datefmt='%H:%M:%S')
- def __init__(self):
+ def __init__(self, use_console=True):
self.logger = logging.getLogger()
self.global_level = logging.DEBUG
+ self.use_console = use_console
@classmethod
diff --git a/client/common_lib/test.py b/client/common_lib/test.py
index c55d23b..b1a0904 100644
--- a/client/common_lib/test.py
+++ b/client/common_lib/test.py
@@ -465,6 +465,24 @@ class base_test(object):
self.job.enable_warnings("NETWORK")
+ def runsubtest(self, url, *args, **dargs):
+ """
+ This call subtest in running test.
+
+ @param test: Parent test.
+ @param url: Url of new test.
+ @param tag: Tag added to test name.
+ @param args: Args for subtest.
+ @param dargs: Distionary args for subtest.
+ @iterations: Number of iteration of subtest.
+ @profile_inly: If true not profile.
+ """
+ dargs["profile_only"] = dargs.get("profile_only", True)
+ test_basepath = self.outputdir[len(self.job.resultdir + "/"):]
+ self.job.run_test(url, master_testpath=test_basepath,
+ *args, **dargs)
+
+
def _get_nonstar_args(func):
"""Extract all the (normal) function parameter names.
@@ -658,7 +676,8 @@ def runtest(job, url, tag, args, dargs,
if not bindir:
raise error.TestError(testname + ': test does not exist')
- outputdir = os.path.join(job.resultdir, testname)
+ subdir = os.path.join(dargs.pop('master_testpath', ""), testname)
+ outputdir = os.path.join(job.resultdir, subdir)
if tag:
outputdir += '.' + tag
diff --git a/client/tests/kvm/html_report.py b/client/tests/kvm/html_report.py
index 8b4b109..bac48bd 100755
--- a/client/tests/kvm/html_report.py
+++ b/client/tests/kvm/html_report.py
@@ -1380,8 +1380,6 @@ function processList(ul) {
## input and create a single html formatted result page. ##
#################################################################
-stimelist = []
-
def make_html_file(metadata, results, tag, host, output_file_name, dirname):
html_prefix = """
@@ -1427,11 +1425,12 @@ return true;
total_failed = 0
total_passed = 0
for res in results:
- total_executed += 1
- if res['status'] == 'GOOD':
- total_passed += 1
- else:
- total_failed += 1
+ if results[res][2] != None:
+ total_executed += 1
+ if results[res][2]['status'] == 'GOOD':
+ total_passed += 1
+ else:
+ total_failed += 1
stat_str = 'No test cases executed'
if total_executed > 0:
failed_perct = int(float(total_failed)/float(total_executed)*100)
@@ -1468,39 +1467,46 @@ id="t1" class="stats table-autosort:4 table-autofilter table-stripeclass:alterna
<tbody>
"""
print >> output, result_table_prefix
- for res in results:
- print >> output, '<tr>'
- print >> output, '<td align="left">%s</td>' % res['time']
- print >> output, '<td align="left">%s</td>' % res['testcase']
- if res['status'] == 'GOOD':
- print >> output, '<td align=\"left\"><b><font color="#00CC00">PASS</font></b></td>'
- elif res['status'] == 'FAIL':
- print >> output, '<td align=\"left\"><b><font color="red">FAIL</font></b></td>'
- elif res['status'] == 'ERROR':
- print >> output, '<td align=\"left\"><b><font color="red">ERROR!</font></b></td>'
- else:
- print >> output, '<td align=\"left\">%s</td>' % res['status']
- # print exec time (seconds)
- print >> output, '<td align="left">%s</td>' % res['exec_time_sec']
- # print log only if test failed..
- if res['log']:
- #chop all '\n' from log text (to prevent html errors)
- rx1 = re.compile('(\s+)')
- log_text = rx1.sub(' ', res['log'])
-
- # allow only a-zA-Z0-9_ in html title name
- # (due to bug in MS-explorer)
- rx2 = re.compile('([^a-zA-Z_0-9])')
- updated_tag = rx2.sub('_', res['title'])
-
- html_body_text = '<html><head><title>%s</title></head><body>%s</body></html>' % (str(updated_tag), log_text)
- print >> output, '<td align=\"left\"><A HREF=\"#\" onClick=\"popup(\'%s\',\'%s\')\">Info</A></td>' % (str(updated_tag), str(html_body_text))
- else:
- print >> output, '<td align=\"left\"></td>'
- # print execution time
- print >> output, '<td align="left"><A HREF=\"%s\">Debug</A></td>' % os.path.join(dirname, res['title'], "debug")
+ def print_result(result, indent):
+ while result != []:
+ r = result.pop(0)
+ print r
+ res = results[r][2]
+ print >> output, '<tr>'
+ print >> output, '<td align="left">%s</td>' % res['time']
+ print >> output, '<td align="left" style="padding-left:%dpx">%s</td>' % (indent * 20, res['title'])
+ if res['status'] == 'GOOD':
+ print >> output, '<td align=\"left\"><b><font color="#00CC00">PASS</font></b></td>'
+ elif res['status'] == 'FAIL':
+ print >> output, '<td align=\"left\"><b><font color="red">FAIL</font></b></td>'
+ elif res['status'] == 'ERROR':
+ print >> output, '<td align=\"left\"><b><font color="red">ERROR!</font></b></td>'
+ else:
+ print >> output, '<td align=\"left\">%s</td>' % res['status']
+ # print exec time (seconds)
+ print >> output, '<td align="left">%s</td>' % res['exec_time_sec']
+ # print log only if test failed..
+ if res['log']:
+ #chop all '\n' from log text (to prevent html errors)
+ rx1 = re.compile('(\s+)')
+ log_text = rx1.sub(' ', res['log'])
+
+ # allow only a-zA-Z0-9_ in html title name
+ # (due to bug in MS-explorer)
+ rx2 = re.compile('([^a-zA-Z_0-9])')
+ updated_tag = rx2.sub('_', res['title'])
+
+ html_body_text = '<html><head><title>%s</title></head><body>%s</body></html>' % (str(updated_tag), log_text)
+ print >> output, '<td align=\"left\"><A HREF=\"#\" onClick=\"popup(\'%s\',\'%s\')\">Info</A></td>' % (str(updated_tag), str(html_body_text))
+ else:
+ print >> output, '<td align=\"left\"></td>'
+ # print execution time
+ print >> output, '<td align="left"><A HREF=\"%s\">Debug</A></td>' % os.path.join(dirname, res['subdir'], "debug")
+
+ print >> output, '</tr>'
+ print_result(results[r][1], indent + 1)
- print >> output, '</tr>'
+ print_result(results[""][1], 0)
print >> output, "</tbody></table>"
@@ -1528,15 +1534,20 @@ id="t1" class="stats table-autosort:4 table-autofilter table-stripeclass:alterna
output.close()
-def parse_result(dirname, line):
+def parse_result(dirname, line, results_data):
parts = line.split()
if len(parts) < 4:
return None
- global stimelist
+ global tests
if parts[0] == 'START':
pair = parts[3].split('=')
stime = int(pair[1])
- stimelist.append(stime)
+ results_data[parts[1]] = [stime, [], None]
+ try:
+ parent_test = re.findall(r".*/", parts[1])[0][:-1]
+ results_data[parent_test][1].append(parts[1])
+ except IndexError:
+ results_data[""][1].append(parts[1])
elif (parts[0] == 'END'):
result = {}
@@ -1553,21 +1564,25 @@ def parse_result(dirname, line):
result['exec_time_sec'] = 'na'
tag = parts[3]
+ result['subdir'] = parts[2]
# assign actual values
rx = re.compile('^(\w+)\.(.*)$')
m1 = rx.findall(parts[3])
- result['testcase'] = m1[0][1]
+ if len(m1):
+ result['testcase'] = m1[0][1]
+ else:
+ result['testcase'] = parts[3]
result['title'] = str(tag)
result['status'] = parts[1]
if result['status'] != 'GOOD':
result['log'] = get_exec_log(dirname, tag)
- if len(stimelist)>0:
+ if len(results_data)>0:
pair = parts[4].split('=')
etime = int(pair[1])
- stime = stimelist.pop()
+ stime = results_data[parts[2]][0]
total_exec_time_sec = etime - stime
result['exec_time_sec'] = total_exec_time_sec
- return result
+ results_data[parts[2]][2] = result
return None
@@ -1689,16 +1704,15 @@ def main(argv):
host = get_info_file('%s/hostname' % sysinfo_dir)
rx = re.compile('^\s+[END|START].*$')
# create the results set dict
- results_data = []
+ results_data = {}
+ results_data[""] = [0, [], None]
if os.path.exists(status_file_name):
f = open(status_file_name, "r")
lines = f.readlines()
f.close()
for line in lines:
if rx.match(line):
- result_dict = parse_result(dirname, line)
- if result_dict:
- results_data.append(result_dict)
+ parse_result(dirname, line, results_data)
# create the meta info dict
metalist = {
'uname': get_info_file('%s/uname' % sysinfo_dir),
@@ -1711,7 +1725,6 @@ def main(argv):
'dmesg':get_info_file('%s/dmesg' % sysinfo_dir),
'kvmver':get_kvm_version(dirname)
}
-
make_html_file(metalist, results_data, tag, host, output_file_name,
html_path)
sys.exit(0)
diff --git a/client/tests/kvm/kvm_test_utils.py b/client/tests/kvm/kvm_test_utils.py
index b5c4a24..c2c9615 100644
--- a/client/tests/kvm/kvm_test_utils.py
+++ b/client/tests/kvm/kvm_test_utils.py
@@ -429,13 +429,15 @@ def get_memory_info(lvms):
return meminfo
-def run_autotest(vm, session, control_path, timeout, outputdir, params):
+def run_autotest(vm, session, control_path, control_args,
+ timeout, outputdir, params):
"""
Run an autotest control file inside a guest (linux only utility).
@param vm: VM object.
@param session: A shell session on the VM provided.
@param control_path: A path to an autotest control file.
+ @param control_args: An argumets for control file..
@param timeout: Timeout under which the autotest control file must complete.
@param outputdir: Path on host where we should copy the guest autotest
results to.
@@ -560,6 +562,10 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
pass
try:
bg = None
+ if control_args != None:
+ control_args = ' -a "' + control_args + '"'
+ else:
+ control_args = ""
try:
logging.info("---------------- Test output ----------------")
if migrate_background:
@@ -567,7 +573,8 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
mig_protocol = params.get("migration_protocol", "tcp")
bg = kvm_utils.Thread(session.cmd_output,
- kwargs={'cmd': "bin/autotest control",
+ kwargs={'cmd': "bin/autotest control" +
+ control_args,
'timeout': timeout,
'print_func': logging.info})
@@ -578,8 +585,8 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
"migration ...")
vm.migrate(timeout=mig_timeout, protocol=mig_protocol)
else:
- session.cmd_output("bin/autotest control", timeout=timeout,
- print_func=logging.info)
+ session.cmd_output("bin/autotest control" + control_args,
+ timeout=timeout, print_func=logging.info)
finally:
logging.info("------------- End of test output ------------")
if migrate_background and bg:
@@ -623,8 +630,8 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
def get_loss_ratio(output):
"""
- Get the packet loss ratio from the output of ping
-.
+ Get the packet loss ratio from the output of ping.
+
@param output: Ping output.
"""
try:
diff --git a/client/tests/kvm/tests/subtest.py b/client/tests/kvm/tests/subtest.py
new file mode 100644
index 0000000..380390e
--- /dev/null
+++ b/client/tests/kvm/tests/subtest.py
@@ -0,0 +1,43 @@
+import os, logging
+import kvm_test_utils, kvm_utils
+from autotest_lib.client.bin import job
+from autotest_lib.client.bin.net import net_utils
+
+
+def run_subtest(test, params, env):
+ """
+ Run an autotest test inside a guest and subtest on host side.
+ This test should be substitution netperf test in kvm.
+
+ @param test: kvm test object.
+ @param params: Dictionary with test parameters.
+ @param env: Dictionary with the test environment.
+ """
+ vm = env.get_vm(params["main_vm"])
+ vm.verify_alive()
+ timeout = int(params.get("login_timeout", 360))
+ session = vm.wait_for_login(timeout=timeout)
+
+ # Collect test parameters
+ timeout = int(params.get("test_timeout", 300))
+ control_path = os.path.join(test.bindir, "autotest_control",
+ params.get("test_control_file"))
+ control_args = params.get("test_control_args")
+ outputdir = test.outputdir
+
+ guest_ip = vm.get_address()
+ host_ip = net_utils.network().get_corespond_local_ip(guest_ip)
+ if not host_ip is None:
+ control_args = host_ip + " " + guest_ip
+
+ guest = kvm_utils.Thread(kvm_test_utils.run_autotest,
+ (vm, session, control_path, control_args,
+ timeout, outputdir, params))
+ guest.start()
+
+ test.runsubtest("netperf2", tag="server", server_ip=host_ip,
+ client_ip=guest_ip, role='server')
+
+ else:
+ logging.error("Host cannot communicate with client by"
+ " normal network connection.")
\ No newline at end of file
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 5d274f8..f9efb4b 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -255,11 +255,19 @@ variants:
test_control_file = rtc.control
- iozone:
test_control_file = iozone.control
- - flail:
+ - flail:
test_control_file = flail.control
- systemtap:
test_control_file = systemtap.control
+- subtest: install setup unattended_install.cdrom
+ type = subtest
+ test_timeout = 1800
+ variants:
+ - netperf2:
+ test_control_file = netperf2.control
+ nic_mode = tap
+
- linux_s3: install setup unattended_install.cdrom
only Linux
type = linux_s3
diff --git a/client/tests/netperf2/netperf2.py b/client/tests/netperf2/netperf2.py
index 1b659dd..23d25c5 100644
--- a/client/tests/netperf2/netperf2.py
+++ b/client/tests/netperf2/netperf2.py
@@ -2,6 +2,7 @@ import os, time, re, logging
from autotest_lib.client.bin import test, utils
from autotest_lib.client.bin.net import net_utils
from autotest_lib.client.common_lib import error
+from autotest_lib.client.common_lib import barrier
MPSTAT_IX = 0
NETPERF_IX = 1
@@ -36,7 +37,7 @@ class netperf2(test.test):
def run_once(self, server_ip, client_ip, role, test = 'TCP_STREAM',
test_time = 15, stream_list = [1], test_specific_args = '',
- cpu_affinity = '', dev = '', bidi = False, wait_time = 5):
+ cpu_affinity = '', dev = '', bidi = False, wait_time = 2):
"""
server_ip: IP address of host running netserver
client_ip: IP address of host running netperf client(s)
--
1.7.4.4
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [AUTOTEST][PATCH] Add ability to call autotest client tests from kvm tests like a subtest.
2011-04-26 10:22 Jiří Župka
@ 2011-04-26 15:08 ` Amos Kong
2011-04-26 15:52 ` Lucas Meneghel Rodrigues
0 siblings, 1 reply; 5+ messages in thread
From: Amos Kong @ 2011-04-26 15:08 UTC (permalink / raw)
To: Jiří Župka; +Cc: autotest, kvm, kvm-autotest
On Tue, Apr 26, 2011 at 12:22:31PM +0200, Jiří Župka wrote:
> Example run autotest/client/netperf2 like a server.
>
> test.runsubtest("netperf2", tag="server", server_ip=host_ip,
> client_ip=guest_ip, role='server')
>
> Client part is called in paralel thread on virtual machine.
>
> guest = kvm_utils.Thread(kvm_test_utils.run_autotest,
> (vm, session, control_path, control_args,
> timeout, outputdir, params))
> guest.start()
>
> On the guest is required to have installed the program mpstat for netpert2 test.
> Netperf2 test will be changed or will be created in new version.
>
> This patch are necessary to avoid of creation double version of test.
> netperf, multicast, etc..
It's cool!
> Signed-off-by: Jiří Župka <jzupka@redhat.com>
> ---
> client/bin/client_logging_config.py | 5 +-
> client/bin/net/net_utils.py | 16 ++++-
> client/common_lib/base_job.py | 2 +
> client/common_lib/logging_config.py | 3 +-
> client/common_lib/test.py | 21 ++++++-
> client/tests/kvm/html_report.py | 115 ++++++++++++++++++--------------
> client/tests/kvm/kvm_test_utils.py | 19 ++++--
> client/tests/kvm/tests/subtest.py | 43 ++++++++++++
> client/tests/kvm/tests_base.cfg.sample | 10 +++-
> client/tests/netperf2/netperf2.py | 3 +-
> 10 files changed, 173 insertions(+), 64 deletions(-)
> create mode 100644 client/tests/kvm/tests/subtest.py
>
> diff --git a/client/bin/client_logging_config.py b/client/bin/client_logging_config.py
> index a59b078..28c007d 100644
> --- a/client/bin/client_logging_config.py
> +++ b/client/bin/client_logging_config.py
> @@ -12,8 +12,9 @@ class ClientLoggingConfig(logging_config.LoggingConfig):
>
>
> def configure_logging(self, results_dir=None, verbose=False):
> - super(ClientLoggingConfig, self).configure_logging(use_console=True,
> - verbose=verbose)
> + super(ClientLoggingConfig, self).configure_logging(
> + use_console=self.use_console,
> + verbose=verbose)
>
> if results_dir:
> log_dir = os.path.join(results_dir, 'debug')
> diff --git a/client/bin/net/net_utils.py b/client/bin/net/net_utils.py
> index 868958c..ac9b494 100644
> --- a/client/bin/net/net_utils.py
> +++ b/client/bin/net/net_utils.py
> @@ -5,7 +5,7 @@ This library is to release in the public repository.
>
> import commands, os, re, socket, sys, time, struct
> from autotest_lib.client.common_lib import error
> -import utils
> +from autotest_lib.client.common_lib import utils
>
> TIMEOUT = 10 # Used for socket timeout and barrier timeout
>
> @@ -27,6 +27,20 @@ class network_utils(object):
> utils.system('/sbin/ifconfig -a')
>
>
> + def get_corespond_local_ip(self, query_ip, netmask="24"):
> + """
> + Get ip address in local system which can communicate with quert_ip.
> +
> + @param query_ip: IP of client which want communicate with autotest machine.
> + @return: IP address which can communicate with query_ip
> + """
> + ip = utils.system_output("ip addr show to %s/%s" % (query_ip, netmask))
> + ip = re.search(r"inet ([0-9.]*)/",ip)
> + if ip is None:
> + return ip
> + return ip.group(1)
> +
> +
> def disable_ip_local_loopback(self, ignore_status=False):
> utils.system("echo '1' > /proc/sys/net/ipv4/route/no_local_loopback",
> ignore_status=ignore_status)
> diff --git a/client/common_lib/base_job.py b/client/common_lib/base_job.py
> index 843c0e8..eef9efc 100644
> --- a/client/common_lib/base_job.py
> +++ b/client/common_lib/base_job.py
> @@ -1117,6 +1117,7 @@ class base_job(object):
> tag_parts = []
>
> # build up the parts of the tag used for the test name
> + master_testpath = dargs.get('master_testpath', "")
> base_tag = dargs.pop('tag', None)
> if base_tag:
> tag_parts.append(str(base_tag))
> @@ -1132,6 +1133,7 @@ class base_job(object):
> if subdir_tag:
> tag_parts.append(subdir_tag)
> subdir = '.'.join([testname] + tag_parts)
> + subdir = os.path.join(master_testpath, subdir)
> tag = '.'.join(tag_parts)
>
> return full_testname, subdir, tag
> diff --git a/client/common_lib/logging_config.py b/client/common_lib/logging_config.py
> index afe754a..9114d7a 100644
> --- a/client/common_lib/logging_config.py
> +++ b/client/common_lib/logging_config.py
> @@ -32,9 +32,10 @@ class LoggingConfig(object):
> fmt='%(asctime)s %(levelname)-5.5s| %(message)s',
> datefmt='%H:%M:%S')
>
> - def __init__(self):
> + def __init__(self, use_console=True):
> self.logger = logging.getLogger()
> self.global_level = logging.DEBUG
> + self.use_console = use_console
>
>
> @classmethod
> diff --git a/client/common_lib/test.py b/client/common_lib/test.py
> index c55d23b..b1a0904 100644
> --- a/client/common_lib/test.py
> +++ b/client/common_lib/test.py
> @@ -465,6 +465,24 @@ class base_test(object):
> self.job.enable_warnings("NETWORK")
>
>
> + def runsubtest(self, url, *args, **dargs):
> + """
> + This call subtest in running test.
> +
> + @param test: Parent test.
> + @param url: Url of new test.
> + @param tag: Tag added to test name.
> + @param args: Args for subtest.
> + @param dargs: Distionary args for subtest.
> + @iterations: Number of iteration of subtest.
> + @profile_inly: If true not profile.
> + """
> + dargs["profile_only"] = dargs.get("profile_only", True)
> + test_basepath = self.outputdir[len(self.job.resultdir + "/"):]
> + self.job.run_test(url, master_testpath=test_basepath,
> + *args, **dargs)
> +
> +
> def _get_nonstar_args(func):
> """Extract all the (normal) function parameter names.
>
> @@ -658,7 +676,8 @@ def runtest(job, url, tag, args, dargs,
> if not bindir:
> raise error.TestError(testname + ': test does not exist')
>
> - outputdir = os.path.join(job.resultdir, testname)
> + subdir = os.path.join(dargs.pop('master_testpath', ""), testname)
> + outputdir = os.path.join(job.resultdir, subdir)
> if tag:
> outputdir += '.' + tag
>
> diff --git a/client/tests/kvm/html_report.py b/client/tests/kvm/html_report.py
> index 8b4b109..bac48bd 100755
> --- a/client/tests/kvm/html_report.py
> +++ b/client/tests/kvm/html_report.py
> @@ -1380,8 +1380,6 @@ function processList(ul) {
> ## input and create a single html formatted result page. ##
> #################################################################
>
> -stimelist = []
> -
>
> def make_html_file(metadata, results, tag, host, output_file_name, dirname):
> html_prefix = """
> @@ -1427,11 +1425,12 @@ return true;
> total_failed = 0
> total_passed = 0
> for res in results:
> - total_executed += 1
> - if res['status'] == 'GOOD':
> - total_passed += 1
> - else:
> - total_failed += 1
> + if results[res][2] != None:
> + total_executed += 1
> + if results[res][2]['status'] == 'GOOD':
> + total_passed += 1
> + else:
> + total_failed += 1
> stat_str = 'No test cases executed'
> if total_executed > 0:
> failed_perct = int(float(total_failed)/float(total_executed)*100)
> @@ -1468,39 +1467,46 @@ id="t1" class="stats table-autosort:4 table-autofilter table-stripeclass:alterna
> <tbody>
> """
> print >> output, result_table_prefix
> - for res in results:
> - print >> output, '<tr>'
> - print >> output, '<td align="left">%s</td>' % res['time']
> - print >> output, '<td align="left">%s</td>' % res['testcase']
> - if res['status'] == 'GOOD':
> - print >> output, '<td align=\"left\"><b><font color="#00CC00">PASS</font></b></td>'
> - elif res['status'] == 'FAIL':
> - print >> output, '<td align=\"left\"><b><font color="red">FAIL</font></b></td>'
> - elif res['status'] == 'ERROR':
> - print >> output, '<td align=\"left\"><b><font color="red">ERROR!</font></b></td>'
> - else:
> - print >> output, '<td align=\"left\">%s</td>' % res['status']
> - # print exec time (seconds)
> - print >> output, '<td align="left">%s</td>' % res['exec_time_sec']
> - # print log only if test failed..
> - if res['log']:
> - #chop all '\n' from log text (to prevent html errors)
> - rx1 = re.compile('(\s+)')
> - log_text = rx1.sub(' ', res['log'])
> -
> - # allow only a-zA-Z0-9_ in html title name
> - # (due to bug in MS-explorer)
> - rx2 = re.compile('([^a-zA-Z_0-9])')
> - updated_tag = rx2.sub('_', res['title'])
> -
> - html_body_text = '<html><head><title>%s</title></head><body>%s</body></html>' % (str(updated_tag), log_text)
> - print >> output, '<td align=\"left\"><A HREF=\"#\" onClick=\"popup(\'%s\',\'%s\')\">Info</A></td>' % (str(updated_tag), str(html_body_text))
> - else:
> - print >> output, '<td align=\"left\"></td>'
> - # print execution time
> - print >> output, '<td align="left"><A HREF=\"%s\">Debug</A></td>' % os.path.join(dirname, res['title'], "debug")
> + def print_result(result, indent):
> + while result != []:
> + r = result.pop(0)
> + print r
> + res = results[r][2]
> + print >> output, '<tr>'
> + print >> output, '<td align="left">%s</td>' % res['time']
> + print >> output, '<td align="left" style="padding-left:%dpx">%s</td>' % (indent * 20, res['title'])
> + if res['status'] == 'GOOD':
> + print >> output, '<td align=\"left\"><b><font color="#00CC00">PASS</font></b></td>'
> + elif res['status'] == 'FAIL':
> + print >> output, '<td align=\"left\"><b><font color="red">FAIL</font></b></td>'
> + elif res['status'] == 'ERROR':
> + print >> output, '<td align=\"left\"><b><font color="red">ERROR!</font></b></td>'
> + else:
> + print >> output, '<td align=\"left\">%s</td>' % res['status']
> + # print exec time (seconds)
> + print >> output, '<td align="left">%s</td>' % res['exec_time_sec']
> + # print log only if test failed..
> + if res['log']:
> + #chop all '\n' from log text (to prevent html errors)
> + rx1 = re.compile('(\s+)')
> + log_text = rx1.sub(' ', res['log'])
> +
> + # allow only a-zA-Z0-9_ in html title name
> + # (due to bug in MS-explorer)
> + rx2 = re.compile('([^a-zA-Z_0-9])')
> + updated_tag = rx2.sub('_', res['title'])
> +
> + html_body_text = '<html><head><title>%s</title></head><body>%s</body></html>' % (str(updated_tag), log_text)
> + print >> output, '<td align=\"left\"><A HREF=\"#\" onClick=\"popup(\'%s\',\'%s\')\">Info</A></td>' % (str(updated_tag), str(html_body_text))
> + else:
> + print >> output, '<td align=\"left\"></td>'
> + # print execution time
> + print >> output, '<td align="left"><A HREF=\"%s\">Debug</A></td>' % os.path.join(dirname, res['subdir'], "debug")
> +
> + print >> output, '</tr>'
> + print_result(results[r][1], indent + 1)
>
> - print >> output, '</tr>'
> + print_result(results[""][1], 0)
> print >> output, "</tbody></table>"
>
>
> @@ -1528,15 +1534,20 @@ id="t1" class="stats table-autosort:4 table-autofilter table-stripeclass:alterna
> output.close()
>
>
> -def parse_result(dirname, line):
> +def parse_result(dirname, line, results_data):
> parts = line.split()
> if len(parts) < 4:
> return None
> - global stimelist
> + global tests
> if parts[0] == 'START':
> pair = parts[3].split('=')
> stime = int(pair[1])
> - stimelist.append(stime)
> + results_data[parts[1]] = [stime, [], None]
> + try:
> + parent_test = re.findall(r".*/", parts[1])[0][:-1]
> + results_data[parent_test][1].append(parts[1])
> + except IndexError:
> + results_data[""][1].append(parts[1])
>
> elif (parts[0] == 'END'):
> result = {}
> @@ -1553,21 +1564,25 @@ def parse_result(dirname, line):
> result['exec_time_sec'] = 'na'
> tag = parts[3]
>
> + result['subdir'] = parts[2]
> # assign actual values
> rx = re.compile('^(\w+)\.(.*)$')
> m1 = rx.findall(parts[3])
> - result['testcase'] = m1[0][1]
> + if len(m1):
> + result['testcase'] = m1[0][1]
> + else:
> + result['testcase'] = parts[3]
> result['title'] = str(tag)
> result['status'] = parts[1]
> if result['status'] != 'GOOD':
> result['log'] = get_exec_log(dirname, tag)
> - if len(stimelist)>0:
> + if len(results_data)>0:
> pair = parts[4].split('=')
> etime = int(pair[1])
> - stime = stimelist.pop()
> + stime = results_data[parts[2]][0]
> total_exec_time_sec = etime - stime
> result['exec_time_sec'] = total_exec_time_sec
> - return result
> + results_data[parts[2]][2] = result
> return None
>
>
> @@ -1689,16 +1704,15 @@ def main(argv):
> host = get_info_file('%s/hostname' % sysinfo_dir)
> rx = re.compile('^\s+[END|START].*$')
> # create the results set dict
> - results_data = []
> + results_data = {}
> + results_data[""] = [0, [], None]
> if os.path.exists(status_file_name):
> f = open(status_file_name, "r")
> lines = f.readlines()
> f.close()
> for line in lines:
> if rx.match(line):
> - result_dict = parse_result(dirname, line)
> - if result_dict:
> - results_data.append(result_dict)
> + parse_result(dirname, line, results_data)
> # create the meta info dict
> metalist = {
> 'uname': get_info_file('%s/uname' % sysinfo_dir),
> @@ -1711,7 +1725,6 @@ def main(argv):
> 'dmesg':get_info_file('%s/dmesg' % sysinfo_dir),
> 'kvmver':get_kvm_version(dirname)
> }
> -
> make_html_file(metalist, results_data, tag, host, output_file_name,
> html_path)
> sys.exit(0)
> diff --git a/client/tests/kvm/kvm_test_utils.py b/client/tests/kvm/kvm_test_utils.py
> index b5c4a24..c2c9615 100644
> --- a/client/tests/kvm/kvm_test_utils.py
> +++ b/client/tests/kvm/kvm_test_utils.py
> @@ -429,13 +429,15 @@ def get_memory_info(lvms):
> return meminfo
>
>
> -def run_autotest(vm, session, control_path, timeout, outputdir, params):
> +def run_autotest(vm, session, control_path, control_args,
> + timeout, outputdir, params):
> """
> Run an autotest control file inside a guest (linux only utility).
>
> @param vm: VM object.
> @param session: A shell session on the VM provided.
> @param control_path: A path to an autotest control file.
> + @param control_args: An argumets for control file..
> @param timeout: Timeout under which the autotest control file must complete.
> @param outputdir: Path on host where we should copy the guest autotest
> results to.
> @@ -560,6 +562,10 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
> pass
> try:
> bg = None
> + if control_args != None:
> + control_args = ' -a "' + control_args + '"'
> + else:
> + control_args = ""
> try:
> logging.info("---------------- Test output ----------------")
> if migrate_background:
> @@ -567,7 +573,8 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
> mig_protocol = params.get("migration_protocol", "tcp")
>
> bg = kvm_utils.Thread(session.cmd_output,
> - kwargs={'cmd': "bin/autotest control",
> + kwargs={'cmd': "bin/autotest control" +
> + control_args,
> 'timeout': timeout,
> 'print_func': logging.info})
>
> @@ -578,8 +585,8 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
> "migration ...")
> vm.migrate(timeout=mig_timeout, protocol=mig_protocol)
> else:
> - session.cmd_output("bin/autotest control", timeout=timeout,
> - print_func=logging.info)
> + session.cmd_output("bin/autotest control" + control_args,
> + timeout=timeout, print_func=logging.info)
> finally:
> logging.info("------------- End of test output ------------")
> if migrate_background and bg:
> @@ -623,8 +630,8 @@ def run_autotest(vm, session, control_path, timeout, outputdir, params):
>
> def get_loss_ratio(output):
> """
> - Get the packet loss ratio from the output of ping
> -.
> + Get the packet loss ratio from the output of ping.
> +
> @param output: Ping output.
> """
> try:
> diff --git a/client/tests/kvm/tests/subtest.py b/client/tests/kvm/tests/subtest.py
> new file mode 100644
> index 0000000..380390e
> --- /dev/null
> +++ b/client/tests/kvm/tests/subtest.py
> @@ -0,0 +1,43 @@
> +import os, logging
> +import kvm_test_utils, kvm_utils
> +from autotest_lib.client.bin import job
> +from autotest_lib.client.bin.net import net_utils
> +
> +
> +def run_subtest(test, params, env):
> + """
> + Run an autotest test inside a guest and subtest on host side.
> + This test should be substitution netperf test in kvm.
> +
> + @param test: kvm test object.
> + @param params: Dictionary with test parameters.
> + @param env: Dictionary with the test environment.
> + """
> + vm = env.get_vm(params["main_vm"])
> + vm.verify_alive()
> + timeout = int(params.get("login_timeout", 360))
> + session = vm.wait_for_login(timeout=timeout)
> +
> + # Collect test parameters
> + timeout = int(params.get("test_timeout", 300))
> + control_path = os.path.join(test.bindir, "autotest_control",
> + params.get("test_control_file"))
> + control_args = params.get("test_control_args")
> + outputdir = test.outputdir
> +
> + guest_ip = vm.get_address()
> + host_ip = net_utils.network().get_corespond_local_ip(guest_ip)
> + if not host_ip is None:
> + control_args = host_ip + " " + guest_ip
> +
try:
> + guest = kvm_utils.Thread(kvm_test_utils.run_autotest,
> + (vm, session, control_path, control_args,
> + timeout, outputdir, params))
> + guest.start()
> +
> + test.runsubtest("netperf2", tag="server", server_ip=host_ip,
> + client_ip=guest_ip, role='server')
finally:
guest.join()
We also need make the test in host can be configured.
> + else:
> + logging.error("Host cannot communicate with client by"
> + " normal network connection.")
> \ No newline at end of file
> diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
> index 5d274f8..f9efb4b 100644
> --- a/client/tests/kvm/tests_base.cfg.sample
> +++ b/client/tests/kvm/tests_base.cfg.sample
> @@ -255,11 +255,19 @@ variants:
> test_control_file = rtc.control
> - iozone:
> test_control_file = iozone.control
> - - flail:
> + - flail:
A typo? please don't use \t for indentation.
> test_control_file = flail.control
> - systemtap:
> test_control_file = systemtap.control
>
> +- subtest: install setup unattended_install.cdrom
> + type = subtest
> + test_timeout = 1800
> + variants:
> + - netperf2:
autotest.subtest.netperf2
> + test_control_file = netperf2.control
no netperf2.control in client/tests/kvm/autotest_control/
how can we assign host/guest ip to this control file?
> + nic_mode = tap
> +
> - linux_s3: install setup unattended_install.cdrom
> only Linux
> type = linux_s3
> diff --git a/client/tests/netperf2/netperf2.py b/client/tests/netperf2/netperf2.py
> index 1b659dd..23d25c5 100644
> --- a/client/tests/netperf2/netperf2.py
> +++ b/client/tests/netperf2/netperf2.py
> @@ -2,6 +2,7 @@ import os, time, re, logging
> from autotest_lib.client.bin import test, utils
> from autotest_lib.client.bin.net import net_utils
> from autotest_lib.client.common_lib import error
> +from autotest_lib.client.common_lib import barrier
>
> MPSTAT_IX = 0
> NETPERF_IX = 1
> @@ -36,7 +37,7 @@ class netperf2(test.test):
>
> def run_once(self, server_ip, client_ip, role, test = 'TCP_STREAM',
> test_time = 15, stream_list = [1], test_specific_args = '',
> - cpu_affinity = '', dev = '', bidi = False, wait_time = 5):
> + cpu_affinity = '', dev = '', bidi = False, wait_time = 2):
> """
> server_ip: IP address of host running netserver
> client_ip: IP address of host running netperf client(s)
> --
> 1.7.4.4
>
When I test this patch, autotest could not finish.
....
21:25:53 DEBUG| Running '/usr/bin/qemu-img check /root/RHEL-Server-6.0-64-virtio.qcow2'
21:25:54 DEBUG| Postprocessing VM 'vm1'...
21:25:54 DEBUG| Terminating screendump thread...
21:25:54 DEBUG| 'keep_ppm_files' not specified; removing all PPM files from debug dir...
21:25:54 DEBUG| 'keep_screendumps' not specified; removing screendump dirs...
21:25:54 DEBUG| 'kill_unresponsive_vms' specified; killing all VMs that fail to respond to a remote login request...
21:25:54 DEBUG| Trying to login with command 'ssh -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=password -p 22 root@192.168.33.95'
21:25:57 DEBUG| Got 'Are you sure...'; sending 'yes'
21:25:57 DEBUG| Got password prompt; sending 'redhat'
21:25:58 DEBUG| Got shell prompt -- logged in
21:25:58 INFO | ['iteration.1']
21:25:58 INFO | Test finished after 1 iterations.
[hang....]
_______________________________________________
Autotest mailing list
Autotest@test.kernel.org
http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [AUTOTEST][PATCH] Add ability to call autotest client tests from kvm tests like a subtest.
2011-04-26 15:08 ` Amos Kong
@ 2011-04-26 15:52 ` Lucas Meneghel Rodrigues
0 siblings, 0 replies; 5+ messages in thread
From: Lucas Meneghel Rodrigues @ 2011-04-26 15:52 UTC (permalink / raw)
To: Amos Kong; +Cc: Jiří Župka, kvm-autotest, kvm, autotest, ldoktor
On Tue, 2011-04-26 at 23:08 +0800, Amos Kong wrote:
> On Tue, Apr 26, 2011 at 12:22:31PM +0200, Jiří Župka wrote:
> > + else:
> > + logging.error("Host cannot communicate with client by"
> > + " normal network connection.")
> > \ No newline at end of file
> > diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
> > index 5d274f8..f9efb4b 100644
> > --- a/client/tests/kvm/tests_base.cfg.sample
> > +++ b/client/tests/kvm/tests_base.cfg.sample
> > @@ -255,11 +255,19 @@ variants:
> > test_control_file = rtc.control
> > - iozone:
> > test_control_file = iozone.control
> > - - flail:
> > + - flail:
>
> A typo? please don't use \t for indentation.
^ No, flail is the actual name of this test, a syscall fuzzer, not a
typo.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-05-11 3:13 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-04 14:42 [AUTOTEST][PATCH] Add ability to call autotest client tests from kvm tests like a subtest Jiří Župka
2011-05-11 3:13 ` Amos Kong
-- strict thread matches above, loose matches on Subject: below --
2011-04-26 10:22 Jiří Župka
2011-04-26 15:08 ` Amos Kong
2011-04-26 15:52 ` Lucas Meneghel Rodrigues
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox