[Linux] Oracle's new Kernel Test Framework for Linux

原文はこちら。
https://blogs.oracle.com/linuxkernel/oracles-new-kernel-test-framework-for-linux

カーネル開発者であるKnut OmangとAlan Maguireは、新しいプロジェクトKTFに協力しています。githubから利用できるKTFは、Linux開発者のためのより良いテストと検証を行うための拡張可能なフレームワークです。Knut氏が知らせたいように、テスト駆動開発は新しいデバイスドライバを作成する上でも有用です。その理由は、以前のプロジェクトで実際に実施したからです。

Kernel Test Framework (KTF)は、カーネルの内部および外部プログラミングインターフェイスをより簡単にテストできるように開発した単体テストフレームワークです。単体テストとテスト駆動開発(TDD)は、ユーザー空間プロジェクトで多く使われている開発方法です。カーネルの要素は、現在、ユーザーランド単体テストライブラリ、または、標準のアプリケーションとスクリプトロジック、およびユーザーランドからのよりアドホックなテストフレームワークでテストされています。ユーザランドテストは、ユーザ空間コードから到達可能なインタフェースとコードパスを直接的にしか実行できないという点で制約があるため、潜在的なカバレッジが制限されます。つまり、エラーパスと、ユーザ空間コードから呼び出しづらいその他のパスは、簡単にテストできません。また、実施可能なテストは、多くの機能を実行するという点で、非常にハイレベルすぎる場合があります。複雑なカーネルの問題をデバッグすることは非常に複雑ですが、カーネル内で小さなコードを実行するだけという、狙いを定めたテストを行う方法だと、こうした問題を絞り込む上で有用です。KTFを使うと、例えばカーネルモジュールや他のカーネルコンポーネントの内部コンポーネント、つまり公開されていないインターフェイスをテストするために、別々のカーネルモジュールにテストを書くことができます。

広範なカバレッジを持つユーザーランドテストは、ユースケースの検証には適していますが、特定された問題の分析およびデバッグのための開発ツールとしては適していません。また、単体テストの重要な用途として、開発者自身が既存のコードや新しいコードがどのように動作するかという実行上の仮定を立てることがあります。コードを作成したり問題が見つかった際に段階的にテストを追加する継続的インテグレーションシステムと組み合わせると、この形式のテスト駆動型またはアサーション駆動型開発は、個々の開発者が自身が利用するインターフェースのセマンティクスに関して立てた前提の周りに見張りを立てることができる点で、強力です。後日のカーネルの変更により、これらの前提条件のいずれかが破られた場合、テストによって検出され、依存モジュールの回帰が回避されます。

KTFはgithubで公開されていて利用可能です。
Kernel Test Framework - a unit test framework for the Linux kernel
https://github.com/oracle/ktf
TDDを大切にし、LInuxカーネルにTDDを持ち込もうと思っている人たちと協力したいと思っています!インテルのようなカーネルコントリビュータがcontinuous integrationを採用することを奨励しています。
Continuous-integration testing for Intel graphics
https://lwn.net/Articles/735468/
KTFは、以下のような明確な認識で構想されました。
  • 単体テストや、より一般的で体系的なテストで弾みがつくよう、シンプルで使いやすいものである必要がある
  • 個々の開発者が自分自身のためにテストを追加したり、 他の人が利用できるようにすることでメリットを享受したり、自動化されたテスト実行が簡単になると感じられなければならない
KTFでは、これらの考慮事項を設計に取り入れようとしました。

KTFでは、以下を実現して、テスト駆動開発を容易にしようとしています。
  1. 簡単にテストを実行できます。ktfモジュールがロードされると、カーネルテストセットが専用モジュールを介して追加されます。ロードされると、利用可能なすべてのテストは、ユーザーレベルのテストプログラムである "ktfrun"コマンドを使用して実行できます。このユーザプログラムにはテストコードは含まれておらず、netlinkを使用してカーネルktfモジュールと通信し、利用可能なテストを問い合わせます。次に、よく知られているユーザランドユニットテストフレームワークであるgtestの機能を使用して、実行するテストを選択し、結果のきれいにフォーマットされたレポートを生成します。
    Google Test
    https://github.com/google/googletest
    テスト開発者は、何も設定しないテストを書くか、もしくは少なくとも合理的なデフォルト設定で実行されるテストを書くことをお勧めします。たとえば、ネットワークテストでは、可能であればデフォルトでループバックを使用できます。
  2. テストの失敗は簡単にデバッグや診断が可能です。テストは、アサーションテンプレートのセット、すなわち、テスト中に真であると予想されるものを使って記述します。アサーションに失敗した場合は、エラーが発生した行番号/ファイルとともにエラーが記録されるため、障害の診断に役立ちます。gtestの出力は合格/不合格を強調し、失敗の詳細を示します。以前のテスト実行結果は、debugfs経由で常に利用可能です。以下のコマンドを使います。
    # cat /sys/kernel/debug/ktf/results/<testset>
    
    最悪のケースで、テストでカーネルパニックが発生した場合、クラッシュダンプの事後デバッグが可能です。後ほどそのやり方を説明します。個々のテストは独立していなければなりません。つまり、テストBはテストAで行われた設定に依存してはならないのです、これにより、合格と不合格がより整合性のある、再現性の高い環境を確保できます。
  3. テストの記述は簡単です。以下のように定義します。
    3.
    TEST(examples, hello_ok)
    {
        EXPECT_TRUE(true);
    }
    
    この例では、テストケースは "examples"、テストは"hello_ok"です。テストは、ASSERT_*()またはEXPECT_*()ステートメントと、アサーションを作成するために必要なsetup/teardownを組み合わせて構成されています。EXPECT_*()はASSERT_*()と異なります。後者はテストにとって致命的とみなされ、テストの実行は終了します。また、KTFはループテストをサポートしています。ループテストでは、テストに開始インデックスと終了インデックスが追加され、インデックスが暗黙的にテストに渡されて使用されます。ループテストの使用例については、examples/h2.cをご覧ください。最後に、KTFはfixtureの概念をサポートしています。これは共通のsetup/teardownで一連のテストを定義する方法です。fixtureの例については、examples/h3.cをご覧ください。
  4. テストの前後で簡単に分析できます。つまり、テスト・カバレッジやテスト中のメモリー使用率を測定できます。テストによるコードベースをカバレッジの測定は常に有益です。これは、既存のコードベースに対するテストが記述されている場合に特に当てはまります。Linuxカーネルはgccを介するコードカバレッジメカニズムを持っていますが、これらはgccバージョンに依存し、既にビルド済みのカーネルに動的に適用することはできません。そんなわけで、KTF向けに、シンプルなコードカバレッジをサポートするようにしました。
今のところ、KTFは独立したツリーモジュールで、同じソースツリーから別のカーネルバージョンに複数のビルドツリーを簡単に作成できましたが、KTFをカーネルリポジトリ自体に長期間置くと保守が容易になって、一連のテストが確実に増える可能性があること、そしてこれらのテストを日常的に実行するとも考えています。私たちは、他の人を排除せず、維持管理の負担を最小限に抑えながら、実際に整理する方法のアイデアをお持ちであると信じています。さらなる開発のためにこのブログをフォローしてください。

0 件のコメント:

コメントを投稿