blob: 117e3ed2894c11f902f3699a443d690b8947f31e [file] [log] [blame]
Miguel Osorio9a8e4b82019-09-25 07:58:24 -07001# Copyright lowRISC contributors.
2# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3# SPDX-License-Identifier: Apache-2.0
4
5import logging
6import os
7import shutil
8import subprocess
9from pathlib import Path
10
11import pytest
12import yaml
13
14
15def pytest_addoption(parser):
16 """Test harness configuration options."""
17 parser.addoption("--test_bin", action="store", default="")
18 parser.addoption("--rom_bin", action="store", default="")
19 parser.addoption("--verilator_model", action="store", default="")
20 parser.addoption("--openocd", action="store", default="openocd")
Miguel Young de la Sota04c81522019-10-14 13:27:19 -050021 parser.addoption("--uart_timeout", action="store", default="60")
Miguel Young de la Sota8a0c2cb2019-10-21 12:45:50 -050022 parser.addoption("--fpga_uart", action="store", default="")
23 parser.addoption("--spiflash", action="store", default="")
Timothy Chen07269642019-11-05 15:05:11 -080024 parser.addoption("--log", action="store", default="")
Miguel Osorio9a8e4b82019-09-25 07:58:24 -070025
26@pytest.hookimpl(tryfirst=True)
27def pytest_exception_interact(node, call, report):
28 """Dump all log files in case of a test failure."""
29 try:
30 if not report.failed:
31 return
Philipp Wagner416770c2019-12-02 18:17:23 +000032 if not 'tmp_path' in node.funcargs:
Miguel Osorio9a8e4b82019-09-25 07:58:24 -070033 return
34 except:
35 return
36
Philipp Wagner416770c2019-12-02 18:17:23 +000037 tmp_path = str(node.funcargs['tmp_path'])
Greg Chadwick941be0f2020-04-21 14:31:04 +010038 logging.debug("================= DUMP OF ALL TEMPORARY FILES =================")
Miguel Osorio9a8e4b82019-09-25 07:58:24 -070039
Philipp Wagner416770c2019-12-02 18:17:23 +000040 for f in os.listdir(tmp_path):
41 f_abs = os.path.join(tmp_path, f)
Miguel Osorio9a8e4b82019-09-25 07:58:24 -070042 if not os.path.isfile(f_abs):
43 continue
Greg Chadwick941be0f2020-04-21 14:31:04 +010044 logging.debug("vvvvvvvvvvvvvvvvvvvv {} vvvvvvvvvvvvvvvvvvvv".format(f))
Miguel Osorio9a8e4b82019-09-25 07:58:24 -070045 with open(f_abs, 'r') as fp:
Greg Chadwick941be0f2020-04-21 14:31:04 +010046 for line in fp.readlines():
47 logging.debug(line.rstrip())
48 logging.debug("^^^^^^^^^^^^^^^^^^^^ {} ^^^^^^^^^^^^^^^^^^^^".format(f))
Miguel Osorio9a8e4b82019-09-25 07:58:24 -070049
50
51@pytest.fixture(scope="session")
52def localconf(request):
53 """Host-local configuration."""
54 if os.getenv('OPENTITAN_TEST_LOCALCONF') and os.path.isfile(
55 os.environ['OPENTITAN_TEST_LOCALCONF']):
56 localconf_yaml_file = os.environ['OPENTITAN_TEST_LOCALCONF']
57 else:
58 XDG_CONFIG_HOME = os.getenv(
59 'XDG_CONFIG_HOME', os.path.join(os.environ['HOME'], '.config'))
60 localconf_yaml_file = os.path.join(XDG_CONFIG_HOME, 'opentitan',
61 'test-localconf.yaml')
62 logging.getLogger(__name__).info('Reading configuration from ' +
63 localconf_yaml_file)
64
65 with open(str(localconf_yaml_file), 'r') as fp:
66 return yaml.load(fp)
67
68
69@pytest.fixture(scope="session")
70def topsrcdir(request):
71 """Return the top-level source directory as Path object."""
72 # TODO: Consider making this configurable using a pytest arg.
Miguel Young de la Sota7a363d02019-10-21 16:35:20 -050073 path = (Path(os.path.dirname(__file__)) / '..' / '..').resolve()
74 assert path.is_dir()
75 return path
Miguel Osorio9a8e4b82019-09-25 07:58:24 -070076
77
78@pytest.fixture(scope="session")
79def sw_test_bin(pytestconfig):
80 """Return path to software test binary."""
Miguel Young de la Sota7a363d02019-10-21 16:35:20 -050081 path = Path(pytestconfig.getoption('test_bin')).resolve()
82 assert path.is_file()
83 return path
Miguel Osorio9a8e4b82019-09-25 07:58:24 -070084
85@pytest.fixture(scope="session")
86def rom_bin(pytestconfig):
87 """Return path to boot_rom binary."""
Miguel Young de la Sota7a363d02019-10-21 16:35:20 -050088 path = Path(pytestconfig.getoption('rom_bin')).resolve()
89 assert path.is_file()
90 return path
Miguel Osorio9a8e4b82019-09-25 07:58:24 -070091
92
93@pytest.fixture(scope="session")
94def sim_top_build(pytestconfig):
95 """Return path to Verilator sim model."""
Miguel Young de la Sota7a363d02019-10-21 16:35:20 -050096 path = Path(pytestconfig.getoption('verilator_model')).resolve()
97 assert path.is_file()
98 return path
Miguel Osorio9a8e4b82019-09-25 07:58:24 -070099
100
101@pytest.fixture(scope="session")
102def openocd(pytestconfig):
103 """Return path to OpenOCD executable."""
Miguel Young de la Sotae7d86432019-10-23 10:39:07 -0500104 path = Path(pytestconfig.getoption('openocd'))
105 # TODO: Require that the OpenOCD executable be passed as a command-line
106 # argument in the future, rather than relying on $PATH lookup.
107 # assert path.is_file()
Miguel Young de la Sota7a363d02019-10-21 16:35:20 -0500108 return path
Miguel Young de la Sota04c81522019-10-14 13:27:19 -0500109
110@pytest.fixture(scope="session")
111def uart_timeout(pytestconfig):
112 """Return the timeout in seconds for UART to print PASS."""
113 return int(pytestconfig.getoption('uart_timeout'))
Miguel Young de la Sota8a0c2cb2019-10-21 12:45:50 -0500114
115@pytest.fixture(scope="session")
116def fpga_uart(pytestconfig):
117 """Return the path to the UART attached to the FPGA."""
118 path = Path(pytestconfig.getoption('fpga_uart')).resolve()
Timothy Chen4dda5f02019-10-29 17:17:05 -0700119 assert path.exists() and not path.is_dir()
Miguel Young de la Sota8a0c2cb2019-10-21 12:45:50 -0500120 return path
121
122@pytest.fixture(scope="session")
123def spiflash(pytestconfig):
124 """Return the path to the spiflash executable."""
125 path = Path(pytestconfig.getoption('spiflash')).resolve()
126 assert path.is_file()
127 return path
Timothy Chen07269642019-11-05 15:05:11 -0800128
129@pytest.fixture(scope="session")
130def logfile(pytestconfig):
131 """Return path to logfile."""
132 log = pytestconfig.getoption('log')
133 if not log:
134 return
Timothy Chen7d1436d2019-12-04 17:26:14 -0800135 # The strict option is only availabe on python 3.6
136 # CI currently uses >=3.5.2
137 # Turns out however even not using resolve doesn't work.
138 # The logging function in 3.5 uses os.path.isabs to check whether
139 # path is absolute and does not accept POSIXPATH objects
140 # path = Path(log).resolve(strict=False)
141 # assert not path.is_dir()
142
143 path = os.path.abspath(log)
144 assert not os.path.isdir(path)
Timothy Chen07269642019-11-05 15:05:11 -0800145 return path