blob: ea8383cdfc887ccdc01bb763c9603e716989e201 [file] [log] [blame]
#!/usr/bin/env python3
# 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 an FPGA, which is expected to write
one of "PASS!\r\n" or "FAIL!\r\n" to the UART to determine success or failure.
Failing to write either will result in a timeout.
This test requires some setup and some configuration. This test expects you
to have:
- A supported FPGA connected to your workstation.
- That FPGA must be flashed with a synthesized EarlGrey bitfile, which has
been spliced with the OpenTitan bootloader.
- A prebuilt spiflash executable.
You must then provide this test with the .bin file for the test, the UART
device path for the FPGA, and the spiflash executable. For example:
$ cd ${REPO_TOP}
$ pytest -s -v test/systemtest/functional_fpga_test.py \
--test_bin sw/tests/hmac/sw.bin \
--fpga_uart /dev/ttyUSB2 \
--spiflash sw/host/spiflash/spiflash
"""
import logging
from pathlib import Path
import re
import pytest
import test_utils
logging.basicConfig(level=logging.DEBUG)
class TestFunctionalFpga:
"""
Execute a test binary on a locally connected FPGA, using UART
output to validate test success or failure.
"""
@pytest.fixture
def spiflash_proc(self, tmp_path, spiflash, sw_test_bin):
cmd_flash = [str(spiflash), '--input', str(sw_test_bin)]
p_flash = test_utils.Process(cmd_flash,
logdir=str(tmp_path),
cwd=str(tmp_path),
startup_done_expect='Running SPI flash update.',
startup_timeout=10)
p_flash.run()
yield p_flash
p_flash.terminate()
def test_execute_binary(self, spiflash_proc, fpga_uart, uart_timeout):
"""
Executes the binary and inspects its UART for "PASS!\r\n" or "FAIL!\r\n".
"""
logger = logging.getLogger(__name__)
# Open the UART device and read line by line until we pass or fail.
with fpga_uart.open('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)
if match == None:
pytest.fail('Deadline exceeded: did not see PASS! or FAIL! within %ds.', uart_timeout)
if match.group(1) == 'PASS!\r\n':
logger.debug('Got PASS! from binary.')
else:
pytest.fail('Got FAIL! from binary.')