-class SubTest:
- "Defines a subtest"
- def __init__(self, title, function, command=None, timeout=10, genreport=None):
- self.title = title
- self.function = function
- self.command = command
- self.timeout = timeout
- self.genreport = genreport
-
-class AutoTest:
- """This class contains all methods needed to launch several
- automatic tests, archive test results, log, and generate a nice
- test report in restructured text"""
-
- title = "new"
- mainlog = None
- logbuf = None
- literal = 0
- test_list = []
- report_list = []
- child = None
-
- def __init__(self, pexpectchild, filename, mode):
- "Init the Autotest class"
- self.mainlog = file(filename, mode)
- self.child = pexpectchild
- pexpectchild.logfile = self
- def register(self, filename, title, subtest_list):
- "Register a test with a list of subtests"
- test = {}
- test["filename"] = filename
- test["title"] = title
- test["subtest_list"] = subtest_list
- self.test_list.append(test)
-
- def start(self):
- "start the tests, and fill the internal report_list field"
- for t in self.test_list:
- report = {}
- report["date"] = time.asctime()
- report["title"] = t["title"]
- report["filename"] = t["filename"]
- report["subreport_list"] = []
- report["fails"] = 0
- report["success"] = 0
- report["subreport_list"] = []
- for st in t["subtest_list"]:
- if test_whitelist is not None and st.title not in test_whitelist:
- continue
- if test_blacklist is not None and st.title in test_blacklist:
- continue
- subreport = {}
- self.reportbuf = ""
- subreport["title"] = st.title
- subreport["func"] = st.function
- subreport["command"] = st.command
- subreport["timeout"] = st.timeout
- subreport["genreport"] = st.genreport
-
- # launch subtest
- print "%s (%s): "%(subreport["title"], subreport["command"]),
- sys.stdout.flush()
- start = time.time()
- res = subreport["func"](self.child,
- command = subreport["command"],
- timeout = subreport["timeout"])
- t = int(time.time() - start)
-
- subreport["time"] = "%dmn%d"%(t/60, t%60)
- subreport["result"] = res[0] # 0 or -1
- subreport["result_str"] = res[1] # cause of fail
- subreport["logs"] = self.reportbuf
- print "%s [%s]"%(subreport["result_str"], subreport["time"])
- if subreport["result"] == 0:
- report["success"] += 1
- else:
- report["fails"] += 1
- report["subreport_list"].append(subreport)
- self.report_list.append(report)
-
- def gen_report(self):
- for report in self.report_list:
- # main report header and stats
- self.literal = 0
- reportlog = file(report["filename"], "w")
- reportlog.write(report_hdr)
- reportlog.write(report["title"] + "\n")
- reportlog.write(re.sub(".", "=", report["title"]) + "\n\n")
- reportlog.write("Autogenerated test report:\n\n" )
- reportlog.write("- date: **%s**\n"%(report["date"]))
- reportlog.write("- target: **%s**\n"%(target))
- reportlog.write("- success: **%d**\n"%(report["success"]))
- reportlog.write("- fails: **%d**\n"%(report["fails"]))
- reportlog.write("- platform: **%s**\n\n"%(platform))
-
- # summary
- reportlog.write(".. csv-table:: Test results summary\n")
- reportlog.write(' :header: "Name", "Result"\n\n')
- for subreport in report["subreport_list"]:
- if subreport["result"] == 0:
- res_str = "Success"
- else:
- res_str = "Failure"
- reportlog.write(' "%s", "%s"\n'%(subreport["title"], res_str))
- reportlog.write('\n')
-
- # subreports
- for subreport in report["subreport_list"]:
- # print subtitle
- reportlog.write(subreport["title"] + "\n")
- reportlog.write(re.sub(".", "-", subreport["title"]) + "\n\n")
- # print logs
- reportlog.write("::\n \n ")
- s = subreport["logs"].replace("\n", "\n ")
- reportlog.write(s)
- # print result
- reportlog.write("\n\n")
- reportlog.write("**" + subreport["result_str"] + "**\n\n")
- # custom genreport
- if subreport["genreport"] != None:
- s = subreport["genreport"]()
- reportlog.write(s)
-
- reportlog.close()
-
- # displayed on console
- print
- print "-------------------------"
- print
- if report["fails"] == 0:
- print "All test OK"
- else:
- print "%s test(s) failed"%(report["fails"])
-
- # file API, to store logs from pexpect
- def write(self, buf):
- s = buf[:]
- s = s.replace("\r", "")
- self.mainlog.write(s)
- self.reportbuf += s
- def flush(self):
- self.mainlog.flush()
- def close(self):
- self.mainlog.close()
-
-
-# Try to match prompt: return 0 on success, else return -1
-def wait_prompt(child):
- for i in range(3):
- index = child.expect(["RTE>>", pexpect.TIMEOUT], timeout = 1)
- child.sendline("")
- if index == 0:
- return 0
- print "Cannot find prompt"
- return -1
-
-# Try to match prompt after boot: return 0 on success, else return -1
-def wait_boot(child):
- index = child.expect(["RTE>>", pexpect.TIMEOUT],
- timeout = 120)
- if index == 0:
- return 0
- if (wait_prompt(child) == -1):
- print "Target did not boot, failed"
- return -1
- return 0
-
-# quit RTE
-def quit(child):
- if wait_boot(child) != 0:
- return -1, "Cannot find prompt"
- child.sendline("quit")
- return 0, "Success"
-
-# Default function to launch an autotest that does not need to
-# interact with the user. Basically, this function calls the autotest
-# function through command line interface, then check that it displays
-# "Test OK" or "Test Failed".
-def default_autotest(child, command, timeout=10):
- if wait_prompt(child) != 0:
- return -1, "Failed: cannot find prompt"
- child.sendline(command)
- index = child.expect(["Test OK", "Test Failed",
- pexpect.TIMEOUT], timeout = timeout)
- if index == 1:
- return -1, "Failed"
- elif index == 2:
- return -1, "Failed [Timeout]"
- return 0, "Success"
-
-# wait boot
-def boot_autotest(child, **kargs):
- if wait_boot(child) != 0:
- return -1, "Cannot find prompt"
- return 0, "Success"
-
-# Test memory dump. We need to check that at least one memory zone is
-# displayed.
-def memory_autotest(child, command, **kargs):
- if wait_prompt(child) != 0:
- return -1, "Failed: cannot find prompt"
- child.sendline(command)
- regexp = "phys:0x[0-9a-f]*, len:0x([0-9a-f]*), virt:0x[0-9a-f]*, socket_id:[0-9]*"
- index = child.expect([regexp, pexpect.TIMEOUT], timeout = 180)
- if index != 0:
- return -1, "Failed: timeout"
- size = int(child.match.groups()[0], 16)
- if size <= 0:
- return -1, "Failed: bad size"
- index = child.expect(["Test OK", "Test Failed",
- pexpect.TIMEOUT], timeout = 10)
- if index == 1:
- return -1, "Failed: C code returned an error"
- elif index == 2:
- return -1, "Failed: timeout"
- return 0, "Success"
-
-# Test some libc functions including scanf. This requires a
-# interaction with the user (simulated in expect), so we cannot use
-# default_autotest() here.
-def string_autotest(child, command, **kargs):
- if wait_prompt(child) != 0:
- return -1, "Failed: cannot find prompt"
- child.sendline(command)
- index = child.expect(["Now, test scanf, enter this number",
- pexpect.TIMEOUT], timeout = 10)
- if index != 0:
- return -1, "Failed: timeout"
- child.sendline("123456")
- index = child.expect(["number=123456", pexpect.TIMEOUT], timeout = 10)
- if index != 0:
- return -1, "Failed: timeout (2)"
- index = child.expect(["Test OK", "Test Failed",
- pexpect.TIMEOUT], timeout = 10)
- if index != 0:
- return -1, "Failed: C code returned an error"
- return 0, "Success"
-
-# Test spinlock. This requires to check the order of displayed lines:
-# we cannot use default_autotest() here.
-def spinlock_autotest(child, command, **kargs):
- i = 0
- ir = 0
- if wait_prompt(child) != 0:
- return -1, "Failed: cannot find prompt"
- child.sendline(command)
- while True:
- index = child.expect(["Test OK",
- "Test Failed",
- "Hello from core ([0-9]*) !",
- "Hello from within recursive locks from ([0-9]*) !",
- pexpect.TIMEOUT], timeout = 20)
- # ok
- if index == 0:
- break
-
- # message, check ordering
- elif index == 2:
- if int(child.match.groups()[0]) < i:
- return -1, "Failed: bad order"
- i = int(child.match.groups()[0])
- elif index == 3:
- if int(child.match.groups()[0]) < ir:
- return -1, "Failed: bad order"
- ir = int(child.match.groups()[0])
-
- # fail
- else:
- return -1, "Failed: timeout or error"
-
- return 0, "Success"
-
-
-# Test rwlock. This requires to check the order of displayed lines:
-# we cannot use default_autotest() here.
-def rwlock_autotest(child, command, **kargs):
- i = 0
- if wait_prompt(child) != 0:
- return -1, "Failed: cannot find prompt"
- child.sendline(command)
- while True:
- index = child.expect(["Test OK",
- "Test Failed",
- "Hello from core ([0-9]*) !",
- "Global write lock taken on master core ([0-9]*)",
- pexpect.TIMEOUT], timeout = 10)
- # ok
- if index == 0:
- if i != 0xffff:
- return -1, "Failed: a message is missing"
- break
-
- # message, check ordering
- elif index == 2:
- if int(child.match.groups()[0]) < i:
- return -1, "Failed: bad order"
- i = int(child.match.groups()[0])
-
- # must be the last message, check ordering
- elif index == 3:
- i = 0xffff
-
- # fail
- else:
- return -1, "Failed: timeout or error"
-
- return 0, "Success"
-
-# Test logs. This requires to check the order of displayed lines:
-# we cannot use default_autotest() here.
-def logs_autotest(child, command, **kargs):
- i = 0
- if wait_prompt(child) != 0:
- return -1, "Failed: cannot find prompt"
- child.sendline(command)