From 831eadcc6daf9e24b6a9776d8b957b2c3d516473 Mon Sep 17 00:00:00 2001 From: Mariusz Glebocki Date: Fri, 31 Jan 2020 17:31:11 +0100 Subject: [PATCH] travis: add simulation tests --- .sim-test.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++ .travis.yml | 72 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 143 insertions(+), 6 deletions(-) create mode 100755 .sim-test.py diff --git a/.sim-test.py b/.sim-test.py new file mode 100755 index 0000000..0e143d6 --- /dev/null +++ b/.sim-test.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +import os +import sys +import pexpect +import time +from argparse import ArgumentParser + + +parser = ArgumentParser() +parser.add_argument("--sdram-module", type=str) +args = parser.parse_args() + + +tests = [ + { + 'id': 'litex_sim', + 'command': f'litex_sim --with-sdram --sdram-module {args.sdram_module}', + 'cwd': os.getcwd(), + 'checkpoints': [ + { 'timeout': 240, 'good': [b'\n\\s*BIOS built on[^\n]+\n'] }, + { 'timeout': 30, 'good': [b'Memtest OK'], + 'bad': [b'(Memory initialization failed|Booting from)'] }, + ] + } +] + + +def run_test(id, command, cwd, checkpoints): + print(f'*** Test ID: {id}') + print(f'*** CWD: {cwd}') + print(f'*** Command: {command}') + os.chdir(cwd) + p = pexpect.spawn(command, timeout=None, logfile=sys.stdout.buffer) + + checkpoint_id = 0 + for cp in checkpoints: + good = cp.get('good', []) + bad = cp.get('bad', []) + patterns = good + bad + timeout = cp.get('timeout', None) + + timediff = time.time() + try: + match_id = p.expect(patterns, timeout=timeout) + except pexpect.EOF: + print(f'\n*** {id}: premature termination') + return False; + except pexpect.TIMEOUT: + timediff = time.time() - timediff + print(f'\n*** {id}: timeout (checkpoint {checkpoint_id}: +{int(timediff)}s)') + return False; + timediff = time.time() - timediff + + if match_id >= len(good): + break + + sys.stdout.buffer.write(b'<>' % (checkpoint_id, int(timediff))) + checkpoint_id += 1 + + is_success = checkpoint_id == len(checkpoints) + + # Let it print rest of line + match_id = p.expect_exact([b'\n', pexpect.TIMEOUT, pexpect.EOF], timeout=1) + p.terminate(force=True) + + line_break = '\n' if match_id != 0 else '' + print(f'{line_break}*** {id}: {"success" if is_success else "failure"}') + + return is_success + + +for test in tests: + success = run_test(**test) + if not success: + sys.exit(1) + +sys.exit(0) diff --git a/.travis.yml b/.travis.yml index 265ad9a..03348b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,75 @@ language: python dist: Xenial python: "3.6" +before_install: + - export DL_DIR=$HOME/downloads + - mkdir -p $DL_DIR + - cd $DL_DIR + + # Install and configure Conda + - wget -O miniconda.sh https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh + - bash miniconda.sh -b -p $HOME/miniconda + - source "$HOME/miniconda/etc/profile.d/conda.sh" + - hash -r + - conda config --set always_yes yes --set changeps1 no + - conda update -q conda + - conda info -a + install: + # Create Conda environment with required packages + - conda create -q -n litedram -c 'conda-forge' -c 'litex-hub' + verilator libevent json-c + gcc-riscv64-elf-nostdc + - conda activate litedram + # Get Migen / LiteX / Cores - wget https://raw.githubusercontent.com/enjoy-digital/litex/master/litex_setup.py - python3 litex_setup.py init install -before_script: - # Get RISC-V toolchain - - wget https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-20171231-x86_64-linux-centos6.tar.gz - - tar -xvf riscv64-unknown-elf-gcc-20171231-x86_64-linux-centos6.tar.gz - - export PATH=$PATH:$PWD/riscv64-unknown-elf-gcc-20171231-x86_64-linux-centos6/bin/ + # Simulation script dependences + - pip install pexpect + + # Replace litex' litedram with currently tested revision + - cd $TRAVIS_BUILD_DIR + - ./setup.py install -f + +script: ./.sim-test.py --sdram-module="$SDRAM_MODULE" + +jobs: + include: + - stage: "Unit tests" + script: python setup.py test + + - stage: "Simulations" + env: SDRAM_MODULE=IS42S16160 + - env: SDRAM_MODULE=IS42S16320 + - env: SDRAM_MODULE=MT48LC4M16 + - env: SDRAM_MODULE=MT48LC16M16 + - env: SDRAM_MODULE=AS4C16M16 + - env: SDRAM_MODULE=AS4C32M16 + - env: SDRAM_MODULE=AS4C32M8 + - env: SDRAM_MODULE=M12L64322A + - env: SDRAM_MODULE=M12L16161A + - env: SDRAM_MODULE=MT46V32M16 + - env: SDRAM_MODULE=MT46H32M16 + - env: SDRAM_MODULE=MT46H32M32 + - env: SDRAM_MODULE=MT47H128M8 + - env: SDRAM_MODULE=MT47H32M16 + - env: SDRAM_MODULE=MT47H64M16 + - env: SDRAM_MODULE=P3R1GE4JGF + - env: SDRAM_MODULE=MT41K64M16 + - env: SDRAM_MODULE=MT41J128M16 + - env: SDRAM_MODULE=MT41J256M16 + - env: SDRAM_MODULE=K4B1G0446F + - env: SDRAM_MODULE=K4B2G1646F + - env: SDRAM_MODULE=H5TC4G63CFR + - env: SDRAM_MODULE=IS43TR16128B + - env: SDRAM_MODULE=MT8JTF12864 + - env: SDRAM_MODULE=MT8KTF51264 + - env: SDRAM_MODULE=MT18KSF1G72HZ + - env: SDRAM_MODULE=AS4C256M16D3A + - env: SDRAM_MODULE=MT16KTF1G64HZ + - env: SDRAM_MODULE=EDY4016A + - env: SDRAM_MODULE=MT40A1G8 + - env: SDRAM_MODULE=MT40A512M16 -script: python setup.py test