News and Views 2013 Winter / Vol. 4: 上流設計&組込み

検証マネジメントの自動化(バッチスクリプトの限界)

はじめに

機能検証のプロセスは誰でもが自動化をしたいと思うことでしょう。検証エンジニアやプロジェクト・リーダーは、カバレッジのクロージャ、バグ・ハンティング、スモークテストなどのタスクを大量のリグレッションの中で行わなくてはなりません。リグレッションテストでは、シェルスクリプトを用いることが一般的です。しかしシェルスクリプトを実行する側のユーザは、スクリプトの中身を理解せずに実行している場合も多く、またスクリプトがうまく実行されない場合に、それを開発した人に問い合わせるため、その対応を待たされることもあります。

本当の意味での自動化を行うなら、機能検証プロセスの特質に向いたリグレッション・システムを検討する必要があります。このシステムの活用により、機能検証の生産性を「平均で20倍」上げることが可能です。今回のNews & Views online Winterの「上流設計&組込み」トピックでは、その秘訣をご紹介します。

機能検証に特有のマネジメント

機能検証プロセスのマネジメントには、以下のような要素が含まれます。

  • 制約付きランダムテストに用いるシード値のマネジメントの自動化
  • フェイルしたテストをデバッグ・オプション付きで再実行
  • 多数のシミュレーション全体でのカバレッジを知るためのマージ
  • ツールのタイムアウト管理
  • グリッドシステムとの連携

大規模設計に対する複雑な機能検証を、スクリプトだけで管理しようとするには限界があります。
シミュレーション実行には「アクション」があり、それに対してテストパターンの指定やオプション指定などを「キャプチャ」します。前のテスト結果に基づいて次に実行すべきテスト内容を再度キャプチャするなどのフロー的な「コントロール」、タイムアウトからの再実行やテンポラリファイルの自動消去などの「オートメーション」、リグレッションの状況を見える化する「ビジビリティ」、この要素すべてを1つのスクリプト、あるいは互いにコールし合う複数のスクリプトで実現することは、非常に困難であると言わざるを得ません。検証エンジニアには、彼ら本来の仕事、つまり機能カバレッジのモデル化や、検証全体の戦略を考えることに時間を費やしてもらうべきでしょう。

アクションのキャプチャ

リグレッションテストは非常に複雑なプロセスです。リグレッションテストに含まれる各タスクの目的は、スクリプトの実行そのものではなく、次のアクションが起こせるようなデータを生成することにあります。ここで重要なのは、各アクションをキャプチャする部分とコントロールする部分を分けること、アクション同士の依存関係を定義できることです。例えば、ビルド、オプティマイズ、シミュレーション実行という3つのアクションに対し、まずビルドは、その後工程となるオプティマイズへと進むために正しく終了されなくてはなりません。オプティマイズも正しく終了されない限り、シミュレーションを実行できません。シーケンシャルな実行の依存関係や、並行して実行する際の依存関係も定義できなくてはなりません。複数のビルド、複数のシミュレーションは、通常、並行して実行されます。

アクションをキャプチャする際にパラメータ化しておくことは、同じアクションに対して異なるコンフィギュレーションを指定して実行するためにはとても有効です。コンフィギュレーションの例としては、デバッグモードか最適化モードか、カバレッジを取得するかしないか、あるいはツールのバージョンを変えて複数回実行するかなどが含まれます。ユーザ定義のパラメータ化を行い、それをグローバルに、またはローカルに上書きできることも大切であり、その際の継承の機能は、繰り返しキャプチャする条件設定に同じものが含まれる場合に非常に有効です。

Questa VRM(Verification Run Manager)において、重要な構成要素は「runnable」と呼ばれます。「runnable」は階層的な構成が可能で、依存情報や親からの継承情報を持ちます。「group」は「runnable」の集合体で、アクションの前処理、後処理を指定できます。前処理としては設定やファイルの確認、後処理はクリーンナップなどが良い例です。「runnable」はベースとなる「runnable」から継承し、階層のどのレベルであっても挿入が可能です。「runnable」タスクはリーフレベルのアクションです。例えば、実行権を持つシェルやコマンドがそれに当たります。デフォルトはQuestaのシェル・インタープリタになります。

「runnable」は実行の設定で、シリアル実行、パラレル実行に対応します。また条件に応じた実行、カウンタや変数リストを用いた繰り返しも可能です。もちろんパラメータも使用できます。
「runnable」のコンフィギュレーションは実行時にグラフ展開され、アクションのスケジューリングと依存性により構築されます。実行時にはユーザへの問い合わせも可能ですし、パラメータ値の上書きにより異なるグラフ構成に変更することも可能です。既存設定を再利用して、複数プロジェクトへの再利用展開が可能です。

図1.リグレッションテストのグラフ展開図1. リグレッションテストのグラフ展開

リグレッションのコントロール

キャプチャしたアクションを抽出して、それぞれのアクションがいつ、どのように実行されるかを完全にコントロールします。基本はローカルな実行となりますが、もちろん「rsh」や「ssh」、グリッドやLSFと組み合わせてネットワーク内でコントロール可能です。

グリッドへのジョブ投入やサスペンド、レジュームなど、いかに実行するかを「メソッド」と呼んでいます。「メソッド」はパラメータ次第で条件付きメソッドにもなり、階層の親から指定することで柔軟性の高いコントロールが可能です。

この「メソッド」はグリッドへのインタフェース・レイヤとして簡素化をもたらし、例えばアレイジョブなどのメリットも享受できます。アクションをアレイとしてパッケージ化し、1つのコマンドでグリッドにお任せしてしまう、というやり方です。またアクションをグルーピングし、1つのアクションとして実行させることも可能です。特に有効なのは、アクションが短い割にジョブ設定やスタートアップの時間の割合が長い場合です。オーバーヘッドの割合を減らし、スループットを上げるように工夫すべきでしょう。

図2.  オーバーヘッドを減らす工夫図2. オーバーヘッドを減らす工夫

例えば、スタートアップが5分、シミュレーションが2分、シミュレーション数が1000、これを20 CPUのファームにジョブ投入します。20 CPUに分けると各CPUで50シミュレーション、各アクションは7分となります。つまり、すべてが終わるまでに350分を要するという寸法です。

そこで10個のシミュレーションをグルーピングすると、スタートアップが5分、シミュレーションが20分、合計で25分のジョブとなります。ジョブ数は100ですから、20CPUに分散すれば各CPUで5ジョブ実行すれば良いことになります。つまり25分のジョブを5つ実行するのですべてが終わるまでに125分で済みます。グルーピングにより、約3倍のスループットを得ることができるのです。

メソッドは実行時間の最大値を変数のキューとして持っていて、グリッド投入前からアクション間でバランスを取り、スケジューリングすることが可能です。キューイング時でも実行時でもパラメータを介したタイムアウト設定が可能です。例えば、あるアクションがハングしてしまったためにリグレッションが止まり、後続するアクションが実行されないといった事態を自動的に回避できます。

各アクションとその実行はステートマシンとして管理されます。リグレッションの中でアクションをスケジューリングする際、各アクションの開始後でかつ次のアクションの開始前に、ルーチンがコールされます。ルーチンにはデフォルト実装がありますが、上書きが可能です。このルーチンは非常にパワフルで、何かのイベントが発生した際にリグレッションを止める、ある時間まで実行させる、ある一定のカバレッジが達成するまで走らせる、アクションのフェイルが指定した回数に達した場合にリグレッションを止めるなど、さまざまな役割を果たします(これはほんの一例にすぎません。)。パラメータを介したコントロールのカスタマイズは無限に可能です。あるアクションに条件を付け、マシンリソースがあってライセンス・フィーチャーがある場合にのみ実行させることも可能です。またアクションで必要なライセンスがない場合には、一旦キューに戻し、ある時間経過後にリトライさせるなども可能です。

このようなことができるのは、アクションそのものの定義とコントロールを別に定義しているからに他なりません。

リグレッションの自動化(オートメーション)

アクションのキャプチャとコントロールを個別に定義できるシステムにおいて、オートメーションは非常に簡単です。リグレッション・システムでは、正しいデータを見つけ出し、すでに走っているアクションの結果に基づいて新たな検証タスクのトリガーとすべきです。アクション実行が返すステータスとしてはUCDB(Unified Coverage DataBase)内の「TESTSTATUS」というアトリビュート項目を使用し、終了したジョブがパスしたか、フェイルしたかを知ることができます。このアトリビュート項目にはジョブ実行中に起こったワーストケースの情報が自動的に記録されます。

このステータスはトリアージでも使用されます。トリアージではフェイルした情報を他のアクションからも抽出し、それを比較検討できるようなデータベースを作成します。複数のシミュレーションで、同じアサーションがフェイルしている場合、なるべく早いシミュレーション時間でフェイルが発生しているアクションの方がデバッグしやすいだろうという判断ができるようになります。またフェイルしたシミュレーションを自動で再実行させ、ただし再実行時にはデバッグ・オプションを付加し、波形をダンプさせるよう設定することも可能です。フェイル直後に再実行させることも、グローバルなリグレッションすべてが終了した後に再実行させることもできます。またはタイムアウトを使用して再実行させることも可能です。終夜運転させて翌朝出社するまでに、とにかくデバッグや解析に必要なデータを揃えておく、といったことが可能になります。

またマージする複数のUCDBをキューイングし、定期的にマージを行うこともできます。Microsoft Excelなどでテストプランを作成している場合には、テストプランと複数UCDBをマージし、テストプランに対してリグレッション全体のカバレッジを対応付け、常にマネージャーが把握できるようにしておくことが可能です。マージしたUCDBは、過去のものをすべて保存しておくと、膨大なディスクスペースを必要としてしまいます。トレンド解析用のデータベースに必要な情報だけを抽出して保存したり、アクションの後処理として自動的にクリーンナップをかけたりすることもお奨めです。

図3. Questa VMの構成図3. Questa VMの構成

ビジビリティ

リグレッションの途中経過を知りたいこともあるでしょう。すでに完了したアクション、現在実行中のアクション、今後実行され得るアクションなどが考えられます。Questa VRMは、検証エンジニアがリグレッションの状況を把握するために、コマンドラインのインタフェースだけでなくGUIも提供しています。このGUIを使って、リグレッション内にあるすべてのアクションの開始やモニタ、解析を行うことが可能です。またQuesta Verification Management(VM: 検証マネジメント)の他の機能と同様に、HTML化も可能です。Questaを使用しない管理者、経営者層には最適と言えるでしょう。

まとめ

コンフィギュレーションを含むアクションと、そのコントロールを明確に分けたリグレッション・システムを活用することにより、全体でのスループットを上げ、保守性を高めることができます。複雑なシェルスクリプトを保守していくよりも、より高度な管理や自動化が可能になります。Questa VRMを使用している多くのユーザ事例で、リグレッションテストのパフォーマンス、スループット、デバッグ効率、ディスクのキャパシティなどが劇的に改善され、高い生産性につながっていることが証明されています。ますます複雑化する検証プロセスを考えると、平均で20倍の生産性向上を実現することは決して驚きではなく、むしろ設計プロジェクトの基盤として必要不可欠な技術と言えます。

劇的に改善したリグレッションテストのベンチマーク結果を複数紹介!

今すぐダウンロード