1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-25 06:23:53 +01:00

Merge pull request #4965 from kaspar030/add_testrunner

tests: add shared pexpect test code
This commit is contained in:
Martine Lenders 2016-03-05 23:59:29 +01:00
commit cf9bef8f16
18 changed files with 108 additions and 228 deletions

1
.gitignore vendored
View File

@ -46,3 +46,4 @@ Makefile.local
# YouCompleteMe (https://github.com/Valloric/YouCompleteMe)
.ycm_extra_conf.py
.ycm_extra_conf.pyc
__pycache__

35
dist/tools/testrunner/testrunner.py vendored Executable file
View File

@ -0,0 +1,35 @@
#!/usr/bin/env python3
# Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
# 2014 Martine Lenders <mlenders@inf.fu-berlin.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
import os, signal, sys, subprocess
from pexpect import spawnu, TIMEOUT, EOF
def run(testfunc, timeout=5, echo=True):
env = os.environ.copy()
child = spawnu("make term", env=env, timeout=timeout)
if echo:
child.logfile = sys.stdout
try:
subprocess.check_output(('make', 'reset'), env=env,
stderr=subprocess.PIPE)
except subprocess.CalledProcessError:
# make reset yields error on some boards even if successful
pass
try:
testfunc(child)
except TIMEOUT:
print("Timeout in expect script")
return 1
finally:
print("")
os.killpg(os.getpgid(child.pid), signal.SIGKILL)
child.close()
return 0

View File

@ -1,9 +0,0 @@
#!/usr/bin/env bash
test -f ~/.buildbot && . ~/.buildbot
export REVISION=${1}
export ROOT=${ROOT:-.}
${ROOT}/tools/testsuite/svn_test_revision.sh ${REVISION}
${ROOT}/tools/testsuite/generate_html.sh

View File

@ -1,25 +0,0 @@
#!/usr/bin/env bash
ROOT=${ROOT:-.}
TOOLROOT=${TOOLROOT:-${ROOT}}
HTMLDIR=${TOOLROOT}/tools/testsuite/html
test -f ~/.buildbot && . ~/.buildbot
OUTFILE=${HTMLFILE:-${HOME}/riot.html}
LOGDIR=${BUILDLOGS:-${HOME}/buildlogs}
{
cat ${HTMLDIR}/header
for i in `ls -t $LOGDIR/*.log`; do
${TOOLROOT}/tools/testsuite/parse_buildlog.sh $i
if [ "x${HTTPROOT}x"!="xx" ]; then
echo "<br>"
echo "Full build log: <a href=\"${HTTPROOT}/`basename ${i}`\"> click here </a>."
fi
done
cat ${HTMLDIR}/footer
} > ${OUTFILE}

View File

@ -1 +0,0 @@
</body>

View File

@ -1,5 +0,0 @@
<html>
<header>
<title> Feuerwhere Build Bot results </title>
</header>
<body>

View File

@ -1,41 +0,0 @@
#!/usr/bin/env bash
LOG=${1}
if [ "xx${PARSELOG_ALWAYS}xx"=!"xxyxx" ]; then
if [ -f ${LOG}.parsed ]; then
cat ${LOG}.parsed
exit 0
fi
fi
{
#BUILD_FAIL=`grep '\[BUILD FAILED\]' ${LOG} | wc -l`
NUM_FAIL=`grep '\[.* FAILED\]' ${LOG} | wc -l`
NUM_OK=`grep '\[TEST SUCCESSFUL\]' ${LOG} | wc -l`
REVISION=`awk '/^Revision:/ { print $2; exit}' $LOG`
REPO=`awk '/^Repo:/ { print $2; exit}' $LOG`
if [ -f ${LOG}.lock ]; then
BUILD_STATUS="build in progress..."
elif (($NUM_FAIL==0)); then
BUILD_STATUS="OK"
else
BUILD_STATUS="broken!"
fi
echo "<h2>Revision: ${REVISION} Status: ${BUILD_STATUS}</h2>"
svn log --incremental -v -l 1 ${REPO}@${REVISION} | sed -e 's/$/<br>/'
echo "------------------------------------------------------------------------<br>"
if (($NUM_FAIL==0)); then
true
else
echo "<br> Failed builds/tests: <br>"
grep '\[.* FAILED\]' ${LOG} | uniq | sed -e 's/$/<br>/'
fi
} | tee ${1}.parsed

View File

@ -1,42 +0,0 @@
#!/usr/bin/env bash
TOOLROOT=${TOOLROOT:-.}
flash() {
echo "Building ${1}..."
jam -aq flash || ( echo "[BUILD FAILED] ${1}" && false )
}
run_tests() {
TESTDIR=projects/${1}/tests
flash ${APPLICATION} || return
for tst in `ls ${TESTDIR}/`; do
echo "Project \"${1}\": Running test ${tst}..."
$TESTDIR/$tst || (
echo
echo "[TEST FAILED] ${TESTDIR}/${tst}"
) || echo "[TEST SUCCESSFUL] ${TESTDIR}/${tst}"
done
}
echo
echo "Running tests..."
echo
for i in projects/*; do
export APPLICATION=`basename $i`
if [ -d projects/${APPLICATION}/tests ]; then
{
echo "Testing project ${APPLICATION}..."
PORT="`sh ${TOOLROOT}/tools/lock_board.sh`"
FLASHUTIL_SHELL="sh -c"
echo "Using Target connecting to ${PORT}."
export PORT FLASHUTIL_SHELL
run_tests ${APPLICATION}
sh ${TOOLROOT}/tools/unlock_board.sh ${PORT}
} 2>&1
fi
done

View File

@ -29,7 +29,7 @@ static_tests_groups = ["static-tests"]
known_mcu_groups = arm_mcu_groups + msp_mcu_groups + x86_mcu_groups + \
avr8_mcu_groups + static_tests_groups
common_pkgs = ["pcregrep", "libpcre3", "python3"]
common_pkgs = ["pcregrep", "libpcre3", "python3", "python3-pexpect"]
# testing the relic pkg and its RIOT specific unit test requires cmake
common_pkgs = common_pkgs + ["cmake"]

View File

@ -1,33 +1,19 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Copyright (C) 2014 Martine Lenders <mlenders@inf.fu-berlin.de>
# Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
import os, signal, sys
from pexpect import spawn, TIMEOUT, EOF
import os
import sys
sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner'))
import testrunner
DEFAULT_TIMEOUT = 5
def main():
p = None
try:
p = spawn("make term", timeout=DEFAULT_TIMEOUT)
p.logfile = sys.stdout
p.expect("Test successful.")
except TIMEOUT as exc:
print(exc)
return 1
finally:
if p and not p.terminate():
os.killpg(p.pid, signal.SIGKILL)
return 0
def testfunc(child):
child.expect(u"Test successful.")
if __name__ == "__main__":
sys.exit(main())
sys.exit(testrunner.run(testfunc))

View File

@ -12,4 +12,4 @@ DISABLE_MODULE += auto_init
include $(RIOTBASE)/Makefile.include
test:
python tests/01-run.py
tests/01-run.py

View File

@ -1,20 +1,16 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
#!/usr/bin/env python3
# Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
import os
import sys
import pexpect
def init():
term = pexpect.spawn("make term", timeout=1.1)
term.logfile = sys.stdout
return term
sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner'))
import testrunner
def test1(term):
term.expect_exact("######################### TEST1:")
@ -91,10 +87,12 @@ def test4(term):
term.expect_exact("first: timed out")
term.expect(r"first: waited 1\d{6} usec")
def testfunc(child):
test1(child)
test2(child)
test3(child)
test4(child)
child.expect("######################### DONE")
if __name__ == "__main__":
TERM = init()
test1(TERM)
test2(TERM)
test3(TERM)
test4(TERM)
TERM.expect("######################### DONE")
sys.exit(testrunner.run(testfunc))

View File

@ -4,3 +4,6 @@ include ../Makefile.tests_common
DISABLE_MODULE += auto_init
include $(RIOTBASE)/Makefile.include
test:
./tests/test_thread.py

View File

@ -1,8 +1,20 @@
#!/usr/bin/python
#!/usr/bin/env python3
import pexpect
# Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
term = pexpect.spawn("make term")
import os
import sys
term.expect('first thread\r\n')
term.expect('second thread\r\n')
sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner'))
import testrunner
def testfunc(child):
child.expect('first thread\r\n')
child.expect('second thread\r\n')
if __name__ == "__main__":
sys.exit(testrunner.run(testfunc))

View File

@ -1,38 +1,19 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Copyright (C) 2014 Martine Lenders <mlenders@inf.fu-berlin.de>
# Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
import os, signal, sys, subprocess
from pexpect import spawn, TIMEOUT, EOF
import os
import sys
DEFAULT_TIMEOUT = 5
sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner'))
import testrunner
def main():
env = os.environ.copy()
child = spawn("make term", env=env, timeout=DEFAULT_TIMEOUT,
encoding="utf-8")
child.logfile = sys.stdout
try:
subprocess.check_output(('make', 'reset'), env=env,
stderr=subprocess.PIPE)
except subprocess.CalledProcessError:
# make reset yields error on some boards even if successful
pass
try:
child.expect(u"OK \\([0-9]+ tests\\)")
except TIMEOUT:
print("There where errors in the unittests")
return 1
finally:
print("")
child.close()
return 0
def testfunc(child):
child.expect(u"OK \\([0-9]+ tests\\)")
if __name__ == "__main__":
sys.exit(main())
sys.exit(testrunner.run(testfunc))

View File

@ -4,4 +4,7 @@ include ../Makefile.tests_common
FEATURES_REQUIRED += periph_timer
USEMODULE += xtimer
test:
tests/01-run.py
include $(RIOTBASE)/Makefile.include

View File

@ -29,6 +29,8 @@
#include "xtimer.h"
#include "timex.h"
#define TEST_PERIOD (100000LU)
int main(void)
{
msg_t m, tmsg;
@ -37,8 +39,8 @@ int main(void)
tmsg.type = 44;
for (int i = 0; i < 10; i++) {
xtimer_set_msg(&t, SEC_IN_USEC + offset, &tmsg, sched_active_pid);
if (xtimer_msg_receive_timeout(&m, SEC_IN_USEC) < 0) {
xtimer_set_msg(&t, TEST_PERIOD + offset, &tmsg, sched_active_pid);
if (xtimer_msg_receive_timeout(&m, TEST_PERIOD) < 0) {
puts("Timeout!");
}
else {

View File

@ -1,39 +1,21 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Copyright (C) 2015 INRIA
# Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
import os, signal, sys
from pexpect import TIMEOUT, EOF
if sys.version_info[0] == 2:
from pexpect import spawn
else:
from pexpect import spawnu as spawn
import os
import sys
DEFAULT_TIMEOUT = 2
sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner'))
import testrunner
def main():
p = None
try:
p = spawn("make term", timeout=DEFAULT_TIMEOUT)
p.logfile = sys.stdout
for i in range(10):
p.expect("Message received: 44")
p.expect("Timeout")
except TIMEOUT as exc:
print(exc)
return 1
finally:
if p and not p.terminate():
print("SUCCESS")
os.killpg(p.pid, signal.SIGKILL)
return 0
def testfunc(child):
for i in range(5):
child.expect("Message received: 44")
child.expect("Timeout!")
if __name__ == "__main__":
sys.exit(main())
sys.exit(testrunner.run(testfunc))