FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RustでRISC-V命令セットシミュレータを作ろう (10. Rustでテストケースを作成する)

f:id:msyksphinz:20190224185310p:plain:w400

Cargoのテスト環境を使ってリグレッションテストを作る

Rustで作った命令セットシミュレータについて、テストの方法を考え直した。 現在はMakefileで管理をしているが、Cargoの機能を使ってテスト環境を構築した方が良さそうだ。

そこでRustのmain()を直接呼び出してテストをするのではなく、1枚ラッパーをかませることで、テストではラッパーを呼び出すことでmain()による引数解析の部分をスキップする。

f:id:msyksphinz:20200204214740p:plain
Cargoを使用したリグレッション環境
  • swimmer_rust/src/main.rs
fn main() -> Result<(), Box<std::error::Error>> {
    // 引数の解析がここで行われるので、バイナリファイルの指定などがmain()を呼び出すだけでは行えない。
    let args = parse_args();
...
    let ret = swimmer_rust::swimmer_rust_exec(args.bin_file[0].clone());

swimmer_rust_exec()は引数解析などが終わった状態で、バイナリファイルのみを渡す形に変換されているのでテストプラットフォームからはこの関数を呼び出すだけでよい。

  • swimmer_rust/tests/lib.rs
extern crate swimmer_rust;
#[test]
fn rv64ui_p_add () {
    assert_eq!(
        swimmer_rust::swimmer_rust_exec("riscv-tests/isa/rv64ui-p-add.bin".to_string()),
        1);
}

これをひたすら並べていく。

  • swimmer_rust/tests/lib.rs
extern crate swimmer_rust;

#[test]fn rv64ui_p_add    () { assert_eq!(swimmer_rust::swimmer_rust_exec("riscv-tests/isa/rv64ui-p-add.bin"     .to_string()), 1); }
#[test]fn rv64ui_p_addi   () { assert_eq!(swimmer_rust::swimmer_rust_exec("riscv-tests/isa/rv64ui-p-addi.bin"    .to_string()), 1); }
#[test]fn rv64ui_p_addiw  () { assert_eq!(swimmer_rust::swimmer_rust_exec("riscv-tests/isa/rv64ui-p-addiw.bin"   .to_string()), 1); }
#[test]fn rv64ui_p_addw   () { assert_eq!(swimmer_rust::swimmer_rust_exec("riscv-tests/isa/rv64ui-p-addw.bin"    .to_string()), 1); }
...

cargo testで、これらの定義したテストをすべて実行することができる。

$ cargo test
     Running target/debug/deps/lib-8b291594c607df5d

running 128 tests
test rv64ui_p_auipc ... ok
test rv64ui_p_andi ... ok
test rv64ui_p_addiw ... ok
...
test rv64um_v_remw ... ok

test result: ok. 128 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out