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:
commit
cf9bef8f16
1
.gitignore
vendored
1
.gitignore
vendored
@ -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
35
dist/tools/testrunner/testrunner.py
vendored
Executable 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
|
||||
@ -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
|
||||
25
dist/tools/testsuite/generate_html.sh
vendored
25
dist/tools/testsuite/generate_html.sh
vendored
@ -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}
|
||||
1
dist/tools/testsuite/html/footer
vendored
1
dist/tools/testsuite/html/footer
vendored
@ -1 +0,0 @@
|
||||
</body>
|
||||
5
dist/tools/testsuite/html/header
vendored
5
dist/tools/testsuite/html/header
vendored
@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<header>
|
||||
<title> Feuerwhere Build Bot results </title>
|
||||
</header>
|
||||
<body>
|
||||
41
dist/tools/testsuite/parse_buildlog.sh
vendored
41
dist/tools/testsuite/parse_buildlog.sh
vendored
@ -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
|
||||
42
dist/tools/testsuite/run_tests.sh
vendored
42
dist/tools/testsuite/run_tests.sh
vendored
@ -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
|
||||
2
dist/tools/travis-scripts/get-pkg-list.py
vendored
2
dist/tools/travis-scripts/get-pkg-list.py
vendored
@ -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"]
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -12,4 +12,4 @@ DISABLE_MODULE += auto_init
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
|
||||
test:
|
||||
python tests/01-run.py
|
||||
tests/01-run.py
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -4,3 +4,6 @@ include ../Makefile.tests_common
|
||||
DISABLE_MODULE += auto_init
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
|
||||
test:
|
||||
./tests/test_thread.py
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -4,4 +4,7 @@ include ../Makefile.tests_common
|
||||
FEATURES_REQUIRED += periph_timer
|
||||
USEMODULE += xtimer
|
||||
|
||||
test:
|
||||
tests/01-run.py
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user