Merge pull request #12107 from cladmi/pr/tests/cleanterm

Makefile.include: add cleanterm target and use it for tests
This commit is contained in:
benpicco 2019-10-01 17:51:48 +02:00 committed by GitHub
commit d7d7923f5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 103 additions and 2 deletions

View File

@ -630,6 +630,13 @@ term: $(filter flash flash-only, $(MAKECMDGOALS)) $(TERMDEPS)
$(call check_cmd,$(TERMPROG),Terminal program) $(call check_cmd,$(TERMPROG),Terminal program)
$(TERMPROG) $(TERMFLAGS) $(TERMPROG) $(TERMFLAGS)
# Term without the pyterm added logging
# TERMFLAGS must be exported for `jlink.sh term_rtt`.
cleanterm: export PYTERMFLAGS += --noprefix --no-repeat-command-on-empty-line
cleanterm: $(filter flash, $(MAKECMDGOALS)) $(TERMDEPS)
$(call check_cmd,$(TERMPROG),Terminal program)
$(TERMPROG) $(TERMFLAGS)
list-ttys: list-ttys:
$(Q)$(RIOTTOOLS)/usb-serial/list-ttys.sh $(Q)$(RIOTTOOLS)/usb-serial/list-ttys.sh

View File

@ -36,7 +36,7 @@ def find_exc_origin(exc_info):
def setup_child(timeout=10, spawnclass=pexpect.spawnu, env=None, logfile=None): def setup_child(timeout=10, spawnclass=pexpect.spawnu, env=None, logfile=None):
child = spawnclass("make term", env=env, timeout=timeout, child = spawnclass("make cleanterm", env=env, timeout=timeout,
codec_errors='replace', echo=False) codec_errors='replace', echo=False)
# on many platforms, the termprog needs a short while to be ready... # on many platforms, the termprog needs a short while to be ready...

View File

@ -68,7 +68,7 @@ _JLINK_IF=SWD
_JLINK_SPEED=2000 _JLINK_SPEED=2000
# default terminal frontend # default terminal frontend
_JLINK_TERMPROG=${RIOTTOOLS}/pyterm/pyterm _JLINK_TERMPROG=${RIOTTOOLS}/pyterm/pyterm
_JLINK_TERMFLAGS="-ts 19021" _JLINK_TERMFLAGS="-ts 19021 ${PYTERMFLAGS}"
# #
# a couple of tests for certain configuration options # a couple of tests for certain configuration options

View File

@ -27,3 +27,18 @@ An automated way of knowing if a test is available is to execute the
It executes without error if tests run by 'make test' are present. It executes without error if tests run by 'make test' are present.
make test/available make test/available
Interaction through the uart
----------------------------
Tests implemented with `testrunner` use the `cleanterm` target that
provides an interaction without adding extra text output or input handling.
It can currently be expected to have unmodified line based interaction with the
board.
The expected behavior is verified with the test in `tests/test_tools`.
Tests cannot rely on having on all boards and terminal programs:
* unbuffered input
* allowing sending special characters like `ctrl+c/ctrl+d`

View File

@ -15,6 +15,8 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "shell_commands.h" #include "shell_commands.h"
#include "shell.h" #include "shell.h"
@ -64,10 +66,62 @@ static int cmd_shellping(int argc, char **argv)
return 0; return 0;
} }
/**
* @brief Uppercase the first word
*
* First argument is read, converted to uppercase and printed with a newline.
*
* @param[in] argc Number of arguments
* @param[in] argv Array of arguments
*
* @return 0 on success
*
*/
static int cmd_toupper(int argc, char **argv)
{
if (argc != 2) {
puts("Invalid number of argument");
printf("Usage: %s <word>\n", argv[0]);
return 1;
}
size_t len = strlen(argv[1]);
for (size_t i = 0; i < len; i++) {
/* Cast to 'int' as llvm and some compilers complain about
* array subscript has type 'char' */
char c = toupper((int)argv[1][i]);
putchar(c);
}
putchar('\n');
return 0;
}
/**
* @brief getchar, read one character
*
* Read one character and print its hex value
*
* @param[in] argc Number of arguments
* @param[in] argv Array of arguments
*
* @return 0
*
*/
static int cmd_getchar(int argc, char **argv)
{
(void)argc;
(void)argv;
printf("%s 0x%02x\n", argv[0], getchar());
return 0;
}
static const shell_command_t shell_commands[] = { static const shell_command_t shell_commands[] = {
{ "shellping", "Just print 'shellpong'", cmd_shellping }, { "shellping", "Just print 'shellpong'", cmd_shellping },
{ "true", "do nothing, successfully", cmd_true }, { "true", "do nothing, successfully", cmd_true },
{ "toupper", "uppercase first argument", cmd_toupper },
{ "getchar", "Get one character and print the hex value", cmd_getchar },
{ NULL, NULL, NULL } { NULL, NULL, NULL }
}; };

View File

@ -38,12 +38,31 @@ def _test_no_local_echo(child):
assert res == 0, "There should have been a timeout and not match stdin" assert res == 0, "There should have been a timeout and not match stdin"
def _test_sending_newline(child):
"""Verify that a empty line can be send to the node.
The local terminal must NOT repeat the previous command.
"""
child.sendline('getchar')
child.sendline('') # send only one newline character
child.expect_exact('getchar 0x0a\r\n')
def _test_clean_output(child):
"""Verify that only what the node sends is received."""
child.sendline('toupper lowercase')
retline = child.readline()
assert retline.strip() == 'LOWERCASE'
def testfunc(child): def testfunc(child):
"""Run some tests to verify the board under test behaves correctly. """Run some tests to verify the board under test behaves correctly.
It currently tests: It currently tests:
* local echo * local echo
* getting some test output without other messages
* sending empty lines
""" """
child.expect_exact("Running 'tests_tools' application") child.expect_exact("Running 'tests_tools' application")
@ -55,6 +74,12 @@ def testfunc(child):
# The node should still answer after the previous one # The node should still answer after the previous one
_shellping(child) _shellping(child)
# Check that the output is clean without extra terminal output
_test_clean_output(child)
# It is possible to send an empty newline
_test_sending_newline(child)
if __name__ == "__main__": if __name__ == "__main__":
sys.exit(run(testfunc)) sys.exit(run(testfunc))