X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest%2Fautotest_runner.py;h=21d3be2cb2cd2072a729f5adbc9dd5a04338307a;hb=b4d63fb622400449d78bc1ea3e18a6ef14e8d7da;hp=15935edd39bc5aa8dd33b6d2778776a199da4b8f;hpb=8184f087dd5755fe584ea3d98f86104ba78ffea3;p=dpdk.git diff --git a/app/test/autotest_runner.py b/app/test/autotest_runner.py index 15935edd39..21d3be2cb2 100644 --- a/app/test/autotest_runner.py +++ b/app/test/autotest_runner.py @@ -1,40 +1,39 @@ #!/usr/bin/python # BSD LICENSE -# -# Copyright(c) 2010-2013 Intel Corporation. All rights reserved. +# +# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. # All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions # are met: -# -# * Redistributions of source code must retain the above copyright +# +# * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the # distribution. -# * Neither the name of Intel Corporation nor the names of its -# contributors may be used to endorse or promote products derived +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived # from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# # The main logic behind running autotests in parallel -import multiprocessing, sys, pexpect, time, os, StringIO, csv +import multiprocessing, subprocess, sys, pexpect, re, time, os, StringIO, csv # wait for prompt def wait_prompt(child): @@ -73,6 +72,7 @@ def run_test_group(cmdline, test_group): startuplog = StringIO.StringIO() print >>startuplog, "\n%s %s\n" % ("="*20, test_group["Prefix"]) + print >>startuplog, "\ncmdline=%s" % cmdline child = pexpect.spawn(cmdline, logfile=startuplog) @@ -105,6 +105,13 @@ def run_test_group(cmdline, test_group): results.append((0, "Success", "Start %s" % test_group["Prefix"], time.time() - start_time, startuplog.getvalue(), None)) + # parse the binary for available test commands + binary = cmdline.split()[0] + stripped = 'not stripped' not in subprocess.check_output(['file', binary]) + if not stripped: + symbols = subprocess.check_output(['nm', binary]).decode('utf-8') + avail_cmds = re.findall('test_register_(\w+)', symbols) + # run all tests in test group for test in test_group["Tests"]: @@ -124,7 +131,10 @@ def run_test_group(cmdline, test_group): print >>logfile, "\n%s %s\n" % ("-"*20, test["Name"]) # run test function associated with the test - result = test["Func"](child, test["Command"]) + if stripped or test["Command"] in avail_cmds: + result = test["Func"](child, test["Command"]) + else: + result = (0, "Skipped [Not Available]") # make a note when the test was finished end_time = time.time() @@ -155,7 +165,7 @@ def run_test_group(cmdline, test_group): results.append(result) # regardless of whether test has crashed, try quitting it - try: + try: child.sendline("quit") child.close() # if the test crashed, just do nothing instead @@ -199,7 +209,7 @@ class AutotestRunner: self.logfile = open(logfile, "w") csvfile = open(csvfile, "w") self.csvwriter = csv.writer(csvfile) - + # prepare results table self.csvwriter.writerow(["test_name","test_result","result_str"]) @@ -209,23 +219,19 @@ class AutotestRunner: def __get_cmdline(self, test): cmdline = self.cmdline - # perform additional linuxapp adjustments - if not "baremetal" in self.target: - - # append memory limitations for each test - # otherwise tests won't run in parallel - if not "i686" in self.target: - cmdline += " --socket-mem=%s"% test["Memory"] - else: - # affinitize startup so that tests don't fail on i686 - cmdline = "taskset 1 " + cmdline - cmdline += " -m " + str(sum(map(int,test["Memory"].split(",")))) + # append memory limitations for each test + # otherwise tests won't run in parallel + if not "i686" in self.target: + cmdline += " --socket-mem=%s"% test["Memory"] + else: + # affinitize startup so that tests don't fail on i686 + cmdline = "taskset 1 " + cmdline + cmdline += " -m " + str(sum(map(int,test["Memory"].split(",")))) - # set group prefix for autotest group - # otherwise they won't run in parallel - cmdline += " --file-prefix=%s"% test["Prefix"] + # set group prefix for autotest group + # otherwise they won't run in parallel + cmdline += " --file-prefix=%s"% test["Prefix"] - return cmdline return cmdline @@ -235,12 +241,12 @@ class AutotestRunner: def add_non_parallel_test_group(self,test_group): self.non_parallel_test_groups.append(test_group) - - + + def __process_results(self, results): # this iterates over individual test results for i, result in enumerate(results): - + # increase total number of tests that were run # do not include "start" test if i > 0: @@ -268,10 +274,10 @@ class AutotestRunner: # if test failed and it wasn't a "start" test if test_result < 0 and not i == 0: self.fails += 1 - + # collect logs self.log_buffers.append(log) - + # create report if it exists if report: try: @@ -281,7 +287,7 @@ class AutotestRunner: else: with f: f.write(report) - + # write test result to CSV file if i != 0: self.csvwriter.writerow([test_name, test_result, result_str]) @@ -304,7 +310,7 @@ class AutotestRunner: # dump tests are specified in full e.g. "Dump_mempool" if "_autotest" in test_id: test_id = test_id[:-len("_autotest")] - + # filter out blacklisted/whitelisted tests if self.blacklist and test_id in self.blacklist: test_group["Tests"].remove(test) @@ -321,13 +327,13 @@ class AutotestRunner: # put the numbers backwards so that we start # deleting from the end, not from the beginning groups_to_remove.insert(0, i) - + # remove test groups that need to be removed for i in groups_to_remove: del test_groups[i] - + return test_groups - + # iterate over test groups and run tests associated with them @@ -337,17 +343,12 @@ class AutotestRunner: self.__filter_groups(self.parallel_test_groups) self.non_parallel_test_groups = \ self.__filter_groups(self.non_parallel_test_groups) - + # create a pool of worker threads - if not "baremetal" in self.target: - pool = multiprocessing.Pool(processes=1) - else: - # we can't be sure running baremetal tests in parallel - # will work, so let's stay on the safe side - pool = multiprocessing.Pool(processes=1) - + pool = multiprocessing.Pool(processes=1) + results = [] - + # whatever happens, try to save as much logs as possible try: @@ -380,7 +381,7 @@ class AutotestRunner: continue res = group_result.get() - + self.__process_results(res) # remove result from results list once we're done with it @@ -389,11 +390,11 @@ class AutotestRunner: # run non_parallel tests. they are run one by one, synchronously for test_group in self.non_parallel_test_groups: group_result = run_test_group(self.__get_cmdline(test_group), test_group) - + self.__process_results(group_result) - + # get total run time - cur_time = time.time() + cur_time = time.time() total_time = int(cur_time - self.start) # print out summary @@ -410,10 +411,12 @@ class AutotestRunner: except: print "Exception occured" print sys.exc_info() + self.fails = 1 # drop logs from all executions to a logfile for buf in self.log_buffers: self.logfile.write(buf.replace("\r","")) - + log_buffers = [] + return self.fails