Skip to content

Commit

Permalink
pytest: add capability to log nodes to file
Browse files Browse the repository at this point in the history
  • Loading branch information
miri64 committed Jul 31, 2020
1 parent 0898a8d commit 203ba10
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 1 deletion.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ be a good reference.

```
usage: pytest [--boards] [--hide-output] [--local] [--non-RC] [--self-test]
[--log-file-fmt=[LOG_FILE_FMT]]
optional arguments:
--boards String list of boards to use for the test, can be
Expand All @@ -216,6 +217,16 @@ optional arguments:
--non-RC Runs test even if RIOT version under test is not an RC
--self-test Tests the testutils rather than running the release
tests
--log-file-fmt=[LOG_FILE_FMT]
Format for the log file name. The available variables
are: `module`: The module (=specXX) of the test,
`function`: The function (=taskXX) of the test, `node`:
Name of the node (on IoT-LAB the URL of the node,
locally board name + port), `time`: UNIX timestamp at
creation time. If the provided argument is an empty
string the format will be
'{module}-{function}-{node}-{time}.log' and stored in
the current work directory
```

Running `tox` will do most of that for you
Expand Down
43 changes: 42 additions & 1 deletion conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
See https://docs.pytest.org/en/stable/fixture.html#conftest-py-sharing-fixture-functions
""" # noqa: E501

import re
import os
import subprocess
import sys
import time
from collections.abc import Iterable

import pytest
Expand Down Expand Up @@ -50,6 +52,19 @@ def pytest_addoption(parser):
"--self-test", action="store_true", default=False,
help="Tests the testutils rather than running the release tests",
)
parser.addoption(
"--log-file-fmt", nargs="?", default=None,
type=testutils.pytest.log_file_fmt,
help="Format for the log file name. The available variables are: "
"`module`: The module (=specXX) of the test, "
"`function`: The function (=taskXX) of the test, "
"`node`: Name of the node (on IoT-LAB the URL of the node, "
"locally board name + port), "
"`time`: UNIX timestamp at creation time. "
"If the provided argument is an empty string the format will be "
"'{module}-{function}-{node}-{time}.log' and stored in the "
"current work directory"
)


def pytest_ignore_collect(path, config):
Expand Down Expand Up @@ -116,6 +131,17 @@ def log_nodes(request):
return not request.config.getoption("--hide-output")


@pytest.fixture
def log_file_fmt(request):
"""
Show output of nodes
:return: True if output of nodes should be shown, False otherwise
"""
# use reverse, since from outside we most of the time _want_ to log
return request.config.getoption("--log-file-fmt")


@pytest.fixture
def local(request):
"""
Expand Down Expand Up @@ -202,7 +228,7 @@ def update_env(node, modules=None, cflags=None, port=None, termflags=None):


@pytest.fixture
def riot_ctrl(log_nodes, nodes, riotbase):
def riot_ctrl(log_nodes, log_file_fmt, nodes, riotbase, request):
"""
Factory to create RIOTCtrl objects from list nodes provided by nodes
fixture
Expand All @@ -218,6 +244,21 @@ def ctrl(nodes_idx, application_dir, shell_interaction_cls,
else:
node = nodes[nodes_idx]
update_env(node, modules, cflags, port, termflags)
# if the nodes are not logged, there is no sense in logging to a file
# so check if nodes are logged as well as if they should be logged to a
# file
if log_nodes and log_file_fmt:
if node.env.get("IOTLAB_NODE"):
node_name = node.env["IOTLAB_NODE"]
else:
node_name = "{}-{}".format(
node.board(), re.sub(r'\W+', '-', node.env["PORT"]))
node.env["TERMLOG"] = os.path.join(
os.getcwd(), log_file_fmt.format(
node=node_name, time=int(time.time()),
**get_namefmt(request)
)
)
# need to access private member here isn't possible otherwise sadly :(
# pylint: disable=W0212
node._application_directory = os.path.join(riotbase, application_dir)
Expand Down
20 changes: 20 additions & 0 deletions testutils/pytest.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,26 @@ def list_from_string(list_str=None):
return [v for v in value if v]


def log_file_fmt(fmt_str=None):
"""Get defaulted format string
>>> import os
>>> log_file_fmt(None)
>>> os.path.basename(log_file_fmt(''))
'{module}-{function}-{node}-{time}.log'
>>> log_file_fmt('foobar')
'foobar'
>>> log_file_fmt('{module}-{function}-{time}-{node}')
'{module}-{function}-{time}-{node}'
"""
if fmt_str is not None:
if len(fmt_str) > 0:
return fmt_str
return os.path.join(os.getcwd(),
"{module}-{function}-{node}-{time}.log")
return None


def check_ssh():
user, _ = IoTLABExperiment.user_credentials()
if user is None:
Expand Down

0 comments on commit 203ba10

Please # to comment.