blob: f83c5a0b94c7c2c82337910c033ae10bb26e4ded [file] [log] [blame]
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
r"""Runs a binary on the verilated system, which is expected to write
one of "PASS!\r\n" or "FAIL!\r\n" to UART to determine success or failure.
Failing to write either will result in a timeout.
This test requires some configuration options. Use the following steps to run
the test manually after building a Verilator simulation and the device boot ROM
and a device software target.
$ cd ${REPO_TOP}
$ pytest -s -v test/systemtest/functional_verilator_test.py \
--test_bin sw.elf \
--rom_bin boot_rom.elf \
--verilator_model build/lowrisc_systems_top_earlgrey_verilator_0.1/sim-verilator/Vtop_earlgrey_verilator
"""
import logging
import re
import pytest
import test_utils
logging.basicConfig(level=logging.DEBUG)
class TestFunctionalVerilator:
"""
Execute a test binary in a Verilator-simulated hardware build, using UART
output to validate test success or failure.
"""
@pytest.fixture
def sim_top_earlgrey(self, tmp_path, sim_top_build, sw_test_bin, rom_bin):
cmd_sim = [
str(sim_top_build),
'--meminit=flash,' + str(sw_test_bin),
'--meminit=rom,' + str(rom_bin)
]
p_sim = test_utils.Process(cmd_sim,
logdir=str(tmp_path),
cwd=str(tmp_path),
startup_done_expect='Simulation running',
startup_timeout=10)
p_sim.run()
yield p_sim
p_sim.terminate()
@pytest.mark.timeout(120)
def test_execute_binary(self, sim_top_earlgrey, uart_timeout, logfile):
"""
Executes the binary and inspects its UART for "PASS!\r\n" or "FAIL!\r\n".
"""
logger = logging.getLogger(__name__)
test_utils.setup_logfile(logger, logfile)
# Verilator will print the string "UART: created /dev/pts/#" to
# indicate which pseudoterminal the UART port is bound to.
uart_match = sim_top_earlgrey.find_in_output(
re.compile('UART: Created (/dev/pts/\\d+)'), 5)
assert uart_match is not None
uart_path = uart_match.group(1)
logger.info("Found UART port at %s." % uart_path)
# Now, open the UART device and read line by line until we pass or
# fail.
with open(uart_path, 'rb') as uart_device:
uart_fd = uart_device.fileno()
pattern = re.compile('.*?(PASS!\r\n|FAIL!\r\n)')
match = test_utils.stream_fd_to_log(uart_fd, logger, pattern,
uart_timeout)
assert match is not None, ('Deadline exceeded: did not see PASS! or FAIL! within %ds.' % uart_timeout)
assert match.group(1).strip() == 'PASS!'