テストプロデューサー

クライアント側では、LNTには多くの組み込みテストデータプロデューサーが付属しています。このセクションでは、LNTインフラストラクチャを使用して実行される主要なテストであるため、LLVMテストスイート(別名ナイトリーテスト)ジェネレーターに焦点を当てますが、LNTには、Clangのコンパイル時パフォーマンスなど、他の興味深いデータのテストも含まれていることに注意してください。

LNTでは、新しいテストデータプロデューサーを簡単に追加することもできます。また、カスタムデータインポーター(例:buildbotビルド情報をインポートする)や動的テストデータジェネレーター(例:インフラストラクチャを悪用してグラフをプロットする)の例も含まれています。

ローカルサーバーの実行

個人的な使用のため、またはパブリックサーバーに送信する前に結果をプレビューするために、テスト結果を表示するためのローカルLNTサーバーをセットアップすると便利です。テスト用に使い捨てのサーバーをセットアップするには

# Create a new installation in /tmp/FOO.
$ lnt create /tmp/FOO
created LNT configuration in '/tmp/FOO'
...

# Run a local LNT server.
$ lnt runserver /tmp/FOO &> /tmp/FOO/runserver.log &
[2] 69694

# Watch the server log.
$ tail -f /tmp/FOO/runserver.log
* Running on https://127.0.0.1:8000/
...

テストの実行

組み込みテストは、lntツールを介して実行するように設計されています。組み込みテストで作業するための以下のツールが利用可能です

lnt showtests

利用可能なテストを一覧表示します。テストは拡張可能なアーキテクチャで定義されています。FIXME: 新しいテストを追加する方法に関するドキュメントを指す。

lnt runtest [<実行 オプション>] <テスト 名> ... テスト 引数 ...

指定されたテストを実行します。実行ツール自体は、すべてのテストに共通の多くのオプションを受け入れます。最も一般的なオプションは、--submit=<url>で、テスト完了後に結果を送信するサーバーを指定します。利用可能なオプションの詳細については、lnt runtest --helpを参照してください。

残りのオプションはテストツール自体に渡されます。オプションはテストに固有ですが、適切に動作するテストはlnt runtest <テスト 名> --helpに応答する必要があります。次のセクションでは、組み込みテストに関する具体的なドキュメントを提供します。

組み込みテスト

LLVM CMakeテストスイート

llvmテストスイートは、test-suite組み込みテストで実行できます。

CMakeとlitを介してテストスイートを実行すると、別のLNTテストが使用されます

rm -rf /tmp/BAR
lnt runtest test-suite \
     --sandbox /tmp/BAR \
     --cc ~/llvm.obj.64/Release+Asserts/bin/clang \
     --cxx ~/llvm.obj.64/Release+Asserts/bin/clang++ \
     --use-cmake=/usr/local/bin/cmake \
     --use-lit=~/llvm/utils/lit/lit.py \
     --test-suite ~/llvm-test-suite \
     --cmake-cache Release

CMakeテストスイートはlitを使用してテストを実行し、その出力を比較するため、LNTはLLVM litインストールへのパスを知る必要があります。テストスイートは、CMakeキャッシュにいくつかの一般的な構成を保持しています。--cmake-cacheフラグと--cmake-defineフラグを使用すると、テストスイート実行のためにLNTがcmakeを構成する方法を変更できます。

LLVM Makefileテストスイート (別名 LLVM Nightly Test)

注記

Makefileテストスイートは非推奨です。代わりにcmakeベースのlnt runtest test-suiteモードを使用することを検討してください。これは積極的に保守されており、コードサイズなどの追加のメトリクスを収集し、PGOデータの生成と使用などの追加機能を備えています。

nt組み込みテストは、「ナイトリーテスト」構成でLLVMテストスイートの実行とパフォーマンステストを実行します。このテストでは、さまざまなコンパイルオプションを使用して、いくつかの異なる構成(たとえば、clangllvm-gccなどのLLVMコンパイラを使用する、LLVM JITコンパイラでLLVM lliビットコードインタープリターを使用して実行する、または新しいコードジェネレーターパスをテストする)で、多くの異なるアプリケーションとベンチマーク(例:SPEC)を実行できます。

ntテストでは、LLVMテストスイートリポジトリ、動作するLLVMコンパイラ、およびLLVMソースとビルドツリーが利用可能である必要があります。現在、LLVMビルドツリーはRelease + Asserts構成でビルドされている必要があります。以前のNewNightlyTest.plとは異なり、ntツールはチェックアウトやビルドを行いません。ユーザーは独自のLLVMソースとビルドツリーを管理することが期待されています。理想的には、各コンポーネントは同じLLVMリビジョンに基づいている必要があります(おそらくLLVMテストスイートを除く)が、これは必須ではありません。

テストは、ユーザーが指定したサンドボックスディレクトリ内でLLVMテストスイートのビルドと実行を実行します。デフォルトでは、各テスト実行はサンドボックス内のタイムスタンプ付きディレクトリで行われ、結果は事後分析のために残されます。現在、ユーザーはディスク容量を管理するためにこれらのディレクトリをクリーンアップする必要があります。

テストは常にツリー外のビルドを使用して実行されることが期待されています。これはより堅 robust なモデルであり、多くのテスト実行で同じソースツリーを共有できます。現在の制限の1つは、ツリー内ビルドを実行してからツリー外ビルドを実行すると、LLVMテストスイートリポジトリが正しく機能しないことです。LLVMテストスイートリポジトリを元の状態のままにしておくことは非常に重要です。

次のコマンドは、ローカルビルドでntテストスイートを実行する例を示しています

$ rm -rf /tmp/BAR
$ lnt runtest nt \
     --sandbox /tmp/BAR \
     --cc ~/llvm.obj.64/Release+Asserts/bin/clang \
     --cxx ~/llvm.obj.64/Release+Asserts/bin/clang++ \
     --llvm-src ~/llvm \
     --llvm-obj ~/llvm.obj.64 \
     --test-suite ~/llvm-test-suite \
     TESTER_NAME \
      -j 16
2010-04-17 23:46:40: using nickname: 'TESTER_NAME__clang_DEV__i386'
2010-04-17 23:46:40: creating sandbox: '/tmp/BAR'
2010-04-17 23:46:40: starting test in '/private/tmp/BAR/test-2010-04-17_23-46-40'
2010-04-17 23:46:40: configuring...
2010-04-17 23:46:50: testing...
2010-04-17 23:51:04: loading test data...
2010-04-17 23:51:05: generating report: '/private/tmp/BAR/test-2010-04-17_23-46-40/report.json'

最初の7つの引数はすべて必須です。これらは、サンドボックスパス、テストするコンパイラ、および必要なソースとビルドへのパスを指定します。TESTER_NAME引数は、このテスターの名前を導出するために使用されます(テスト中のコンパイラに関するいくつかの推測情報と組み合わせて)。この名前は、テストマシンの短い識別子として使用されます。通常、これはマシンのホスト名またはテスターを担当する人物の名前である必要があります。-j 16引数はオプションです。この場合、最大16のプロセスを使用してテストを並列で実行することを指定します。

この場合、出力から、テストが新しいサンドボックスディレクトリを作成し、そのサンドボックスのサブディレクトリでテストを実行したことがわかります。テストは、テストの進行中に限られた量の要約情報を出力します。完全な情報は、テストビルドディレクトリ内の.logファイル(例:configure.logおよびtest.log)にあります。

最後のテスト手順は、テストディレクトリ内にテストレポートを生成することでした。このレポートは、LNTサーバーに直接送信できるようになりました。たとえば、前述のようにローカルサーバーが実行されている場合、次を実行できます

$ lnt submit https://127.0.0.1:8000/submitRun \
    /tmp/BAR/test-2010-04-17_23-46-40/report.json
STATUS: 0

OUTPUT:
IMPORT: /tmp/FOO/lnt_tmp/data-2010-04-17_16-54-35ytpQm_.plist
  LOAD TIME: 0.34s
  IMPORT TIME: 5.23s
ADDED: 1 machines
ADDED: 1 runs
ADDED: 1990 tests
COMMITTING RESULT: DONE
TOTAL IMPORT TIME: 5.57s

そして、ローカルサーバーで結果を表示します。

LNTベースのNTテストモジュール

より複雑なテスト、またはLLVMテストスイートモジュールのより厳密なSingleSourceまたはMultiSourceレイアウトに簡単に統合できないテストをサポートするために、nt組み込みテストは、拡張テストモジュールを定義するだけのLLVMテストスイートテストのメカニズムを提供します。これらのテストには、テスト実行のユーザー構成パラメータが渡され、LNTネイティブ形式でテスト結果を返すことが期待されます。

テストモジュールは、LLVMテストスイートリポジトリ内の`LNTBased`ルートディレクトリのサブディレクトリに`TestModule`ファイルを提供することで定義されます。 `TestModule`ファイルは、`lnt.tests.nt.TestModule`抽象基底クラスのサブクラスであるべき`test_class`グローバル変数を提供する、整形式のPythonモジュールである必要があります。

テストクラスは、テスト実行に適用されるNTユーザーパラメータを含むオプション辞書を渡される`execute_test`メソッドをオーバーライドする必要があり、テストはテスト結果を`lnt.testing.TestSamples`オブジェクトのリストとして返す必要があります。

`execute_test`メソッドには、モジュール自体に関する情報を記述する以下のオプションが渡されます。

  • `MODULENAME` - モジュールの名前(主に、適切に構造化されたテスト名を作成するために使用されます)。

  • `SRCROOT` - モジュールのソースディレクトリへのパス。

  • `OBJROOT` - モジュールが一時的な出力(ビルド成果物)に使用するディレクトリへのパス。ディレクトリは存在することが保証されていますが、クリーンであることは保証されていません。

メソッドには、テストの実行方法に適用される以下のオプションが渡されます。

  • `THREADS` - テスト中に実行する並列プロセスの数。

  • `BUILD_THREADS` - テストのビルド中に使用する並列プロセスの数(該当する場合)。

メソッドには、テストをリモートで実行する方法と実行するかどうかを指定する以下のオプションが渡されます。 これらのパラメータのいずれかが存在する場合、すべてが存在することが保証されます。

  • `REMOTE_HOST` - テストを実行するリモートマシンのホスト名。

  • `REMOTE_USER` - リモートマシンにログインするユーザー。

  • `REMOTE_PORT` - リモートマシンに接続するポート。

  • `REMOTE_CLIENT` - リモートマシンへの接続に使用する`rsh`互換クライアント。

メソッドには、テストのビルド方法を指定する以下のオプションが渡されます。

  • `CC` - 使用するCコンパイラコマンド。

  • `CXX` - 使用するC++コンパイラコマンド。

  • `CFLAGS` - Cコードのビルドに使用するコンパイラフラグ。

  • `CXXFLAGS` - C++コードのビルドに使用するコンパイラフラグ。

メソッドには、さまざまなコマンドに使用する環境を指定する以下のオプションパラメータが渡されます。

  • `COMPILE_ENVIRONMENT_OVERRIDES` [オプション] - 指定されている場合、コンパイル時に使用する環境オーバーライドの`env`スタイルのリスト。

  • `LINK_ENVIRONMENT_OVERRIDES` [オプション] - 指定されている場合、リンク時に使用する環境オーバーライドの`env`スタイルのリスト。

  • `EXECUTION_ENVIRONMENT_OVERRIDES` [オプション] - 指定されている場合、テストの実行時に使用する環境オーバーライドの`env`スタイルのリスト。

詳細については、LLVMテストスイートリポジトリの`LNT/Examples`ディレクトリにあるテスト例を参照してください。

Linux perfプロファイル情報の取得

テストスイートでCMakeドライバを使用する場合、LNTはlinux perfを使用してプロファイル情報を取得することもできます。 取得した情報は、http://blog.llvm.org/2016/06/using-lnt-to-track-performance.html で示されているように、LNT Web UIを通じて確認できます。

これらのプロファイルをキャプチャするには、コマンドラインオプション`--use-perf=all`を使用します。 生成されたコードのパフォーマンスを評価するためにこれを使用する典型的なコマンドラインは、次のようになります。

lnt runtest test-suite \
     --sandbox SANDBOX \
     --cc ~/bin/clang \
     --use-cmake=/usr/local/bin/cmake \
     --use-lit=~/llvm/utils/lit/lit.py \
     --test-suite ~/llvm-test-suite \
     --benchmarking-only \
     --build-threads 8 \
     --threads 1 \
     --use-perf=all \
     --exec-multisample=5 \
     --run-under 'taskset -c 1'

2分探索: `--single-result`と`--single-result-predicate`

CMakeベースのテストスイート用のLNTドライバには、`llvmlab bisect`を使用して適合性とパフォーマンスの変化を2分探索するためのヘルパーが付属しています。

`llvmlab bisect`は`zorg`リポジトリの一部であり、ビルドキャッシュを通じて特定の条件式の2分探索を容易に行うことができます。 `llvmlab`を効果的に使用するための鍵は、優れた条件式コマンド、つまり「成功」でゼロを返し、「失敗」でゼロ以外を返すコマンドを設計することです。

LNTは通常、1つ以上のテストを実行してからテストレポートを作成します。 内部エラーが発生しない限り、常にステータスゼロで終了します。 `--single-result`引数はLNTの動作を変更します。特定のテストのみを実行し、そのテストの結果に条件式を適用してLNTの終了ステータスを決定します。

`--single-result-predicate`引数は、使用する条件式を定義します。 これは、事前に設定されたいくつかの変数を含むコンテキストで実行されるPython式です。

  • `status` - ブール値の成功または失敗(成功の場合はTrue、失敗の場合はFalse)。

  • `exec_time` - 実行時間(Pythonでは`exec`は予約語であることに注意してください!)

  • `compile`(または`compile_time`) - コンパイル時間

「score」や「hash」など、テストから返されたメトリクスもコンテキストに追加されます。

デフォルトの条件式は単に`status`です。そのため、これはそのまま使用して正確性の低下をデバッグできます。 より複雑な条件式も可能です。たとえば、`exec_time < 3.0`は、「良好な」結果が3秒未満かかると仮定して2分探索を行います。

`llvmlab`を使用してパフォーマンスの向上をデバッグする完全な例

llvmlab bisect --min-rev=261265 --max-rev=261369 \
  lnt runtest test-suite \
    --cc '%(path)s/bin/clang' \
    --sandbox SANDBOX \
    --test-suite /work/llvm-test-suite \
    --use-lit lit \
    --run-under 'taskset -c 5' \
    --cflags '-O3 -mthumb -mcpu=cortex-a57' \
    --single-result MultiSource/Benchmarks/TSVC/Expansion-flt/Expansion-flt \
    --single-result-predicate 'exec_time > 8.0'

診断レポートの作成

テストスイートモジュールは、ベンチマークで何が起こっているのかを把握するのに役立つ診断レポートを作成できます。

lnt runtest test-suite \
       --sandbox /tmp/BAR \
       --cc ~/llvm.obj.64/Release+Asserts/bin/clang \
       --cxx ~/llvm.obj.64/Release+Asserts/bin/clang++ \
       --use-cmake=/usr/local/bin/cmake \
       --use-lit=~/llvm/utils/lit/lit.py \
       --test-suite ~/llvm-test-suite \
       --cmake-cache Release \
       --diagnose --only-test SingleSource/Benchmarks/Stanford/Bubblesort

これはテストスイートを何度も実行し、レポートディレクトリに役立つ情報を収集します。 レポートは、実行プロファイル、コンパイラ時間レポート、中間ファイル、バイナリファイル、ビルド情報など、多くのものを収集します。

クロスコンパイル

cmakeドライバを使用してクロスコンパイル設定でテストスイートを実行する最良の方法は、可能な限りcmakeの組み込みクロスコンパイルサポートを使用することです。 実際には、クロスコンパイルの推奨方法は、cmakeツールチェーンファイルを使用することです(https://cmake.org/cmake/help/v3.0/manual/cmake-toolchains.7.html#cross-compiling を参照)。

AArch64 linuxをターゲットとするX86マシンでクロスコンパイルするためのコマンドラインの例は次のとおりです。

lnt runtest test-suite \
       --sandbox SANDBOX \
       --test-suite /work/llvm-test-suite \
       --use-lit lit \
       --cppflags="-O3" \
       --run-under=$HOME/dev/aarch64-emu/aarch64-qemu.sh \
       --cmake-define=CMAKE_TOOLCHAIN_FILE:FILEPATH=$HOME/clang_aarch64_linux.cmake

ここで重要な部分はCMAKE_TOOLCHAIN_FILEの定義です。 クロスコンパイルしているため、`--run-under`コマンドが必要になる場合があります。生成されたバイナリは開発マシンでネイティブに実行されない可能性が高いため、追加の処理(qemuシミュレータでの実行、または開発ボードへのバイナリの転送など)が必要になります。 ここではこれ以上説明しません。

ツールチェーンファイルでは、ツールチェーンを定義するcmake変数をCMakeCache.txtにキャッシュする必要があることを指定することが重要です。 lntはjsonレポートのメタデータを作成する必要がある場合に使用されたコンパイラを把握するために、CMakeCache.txtからこれらの変数を読み取ります。 以下は例です。 変数をCMakeCache.txtに表示させるための重要なキーワードは「CACHE STRING "" FORCE」です。

$ cat clang_aarch64_linux.cmake
set(CMAKE_SYSTEM_NAME Linux )
set(triple aarch64-linux-gnu )
set(CMAKE_C_COMPILER /home/user/build/bin/clang CACHE STRING "" FORCE)
set(CMAKE_C_COMPILER_TARGET ${triple} CACHE STRING "" FORCE)
set(CMAKE_CXX_COMPILER /home/user/build/bin/clang++ CACHE STRING "" FORCE)
set(CMAKE_CXX_COMPILER_TARGET ${triple} CACHE STRING "" FORCE)
set(CMAKE_SYSROOT /home/user/aarch64-emu/sysroot-glibc-linaro-2.23-2016.11-aarch64-linux-gnu )
set(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN /home/user/aarch64-emu/gcc-linaro-6.2.1-2016.11-x86_64_aarch64-linux-gnu )
set(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN /home/user/aarch64-emu/gcc-linaro-6.2.1-2016.11-x86_64_aarch64-linux-gnu )