Ubuntu Weekly Recipe

第311回 autopkgtestでパッケージのテストを自動化する

この記事を読むのに必要な時間:およそ 5 分

autopkgtest

いろいろなフェーズのテストが自動化される中,動作確認だけは依然としてほぼ手動な状態です。たしかに不具合によって確認すべきことがばらばらですし,ソフトウェアによってはユーザーのグラフィカルな操作も必要ですので,そう簡単には自動化できないものではあります。

それでも可能な限り自動化できないか,と考えるのが人間の性というもの。たとえばライブラリパッケージなどは,そのライブラリをリンクするプログラムを作ってビルドして出力結果を確認するスクリプトを作れば自動化可能です。そんな考えのもとに提案されたのがautopkgtestという仕組みです。

ようやくここからが本題です。

autopkgtestの仕組み

autpkgtestはバイナリパッケージに対して,debian/tests/以下に記載されたテストを実行する仕組みです。状況やテスト内容に従って,対象のバイナリパッケージやテストに必要なパッケージがインストールされますし,複数のテストを記載すればそれを順番に実行してくれます。

最近のソフトウェアには,最初からテストプログラムが付随しているものも多く存在します。これらはソースパッケージからバイナリパッケージへビルドするときに自動的に実行されますし,テストが失敗すればビルド自体がエラーになることが一般的です。ただし,これらはあくまでソフトウェアをビルドした結果を対象としたテストです。それをバイナリパッケージとして構築し,システムにインストールしたあとも正しく動くかどうかというとそれはまた別の話です。autopkgtestは,パッケージインストール後にソースパッケージに含まれているテストを実行する仕組みも存在します。

Debianでは現在,このautopkgtestはDEP 8としてDRAFT段階にあります。

Ubuntuでは既にいくつかのパッケージはautopkgtestを導入しています。導入されたパッケージについては,QAチームのJenkins上でテストが実行されその結果が表示されます。

サンプルで試してみる

では実際に試してみましょう。まずはテストしたい環境でautopkgtestパッケージをインストールしておきます。

$ sudo apt-get update
$ sudo apt-get install autopkgtest

いきなりテストを書くのではなく,既にあるテストを確認してみましょう。シンプルな例としてlibxml2が存在します。

$ mkdir /tmp/pkgtest-libxml2; cd /tmp/pkgtest-libxml2
$ apt-get source libxml2
$ cd libxml2-2.9.1+dfsg1/
$ ls debian/tests
build  control  python
$ cat debian/tests/control
Tests: build python
Depends: libxml2-dev, python-libxml2, build-essential, pkg-config

このうちcontrolがテストの設定を行うファイルです。Testsフィールドで「build」「python」という名前のテストを実行することを宣言し,Dependsフィールドでテストを行うには「libxml2-dev,python-libxml2,build-essential,pkg-config」パッケージが必要なことを指定しています。

テストごとに同名のファイルを作って,そこにテストを記述します。たとえばbuildはlibxml2ライブラリを使うC言語のプログラムをビルドし,実行しています。リンク先を見てもらうとわかるとおり,これはただのシェルスクリプトです。pythonのほうもlibxml2のPythonバインディングを使ったテストになっています。

このテストを実行するにはadt-runコマンドを使用します。

$ sudo adt-run --no-built-binaries --built-tree=. --- adt-virt-null
adt-run: $ vserver: adt-virt-null
adt-run: $ genkey: sh -ec <SCRIPT> x /home/shibata/.autopkgtest/gpg
+ gpg --homedir=/home/shibata/.autopkgtest/gpg --batch --gen-key key-gen-params

(中略)

adt-run: & apt0t-build: [----------------------------------------
adt-run: & apt0t-build: ----------------------------------------]
adt-run: & apt0t-build:  - - - - - - - - - - results - - - - - - - - - -
apt0t-build          PASS
adt-run: & apt0t-build:  - - - - - - - - - - stdout - - - - - - - - - -
build: OK
run: OK

(中略)

adt-run: & tree0t-python: [----------------------------------------
adt-run: & tree0t-python: ----------------------------------------]
adt-run: & tree0t-python:  - - - - - - - - - - results - - - - - - - - - -
tree0t-python        PASS
adt-run: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ tests done.

「build」「python」テストがそれぞれ実行され,⁠PASS」と表示されていることがわかります。

ちなみに上記を実行すると「手元の環境に」libxml2とdebian/tests/controlファイルのDependsに指定したパッケージがインストールされるので注意してください。

「--no-build-binaries」は指定したソースパッケージをビルドしないことを意味します。バイナリパッケージが必要になる場合は適宜アーカイブからインストールします。

「--built-tree」はソースパッケージのビルドツリーを指定します。要するにソースパッケージを展開した先です。これ以外にも「--source」でソースパッケージそのものを指定できます。

たとえば次のようにパッケージ名そのものを指定した場合は,/tmpにソースパッケージを展開する所から自動で行ってくれます。

$ sudo adt-run libxml2 --- adt-virt-null

「---」以降は「virt server」の設定になります。テストはできるだけクリーンな環境で行うべきです。パッケージをインストールして動作をテストするなら何らかの仮想環境で行うことになります。autopkgtestでは「virt server」を選ぶことで,複数の種類の仮想環境を切り替えて使うことができます。

「adt-virt-null」はダミーの仮想環境で,ホストをそのまま仮想環境であると想定して使用します。よって先程述べたように,ホストにテスト対象のパッケージや依存パッケージがインストールされることになります。

adt-virt-lxcを使う

autopkgtestではLXCも仮想環境として使用できます。これはautopkgtestの2.4以降で追加された機能なので,Debianならjessie以降,UbuntuならTrustyが必要です。

まずLXCをインストールした上で,ベースとなるLXCコンテナーを作成しておきます。

$ sudo apt-get install lxc
$ sudo lxc-create -t ubuntu-cloud -n trusty-cloud  -- -r trusty

ubuntu-cloudはUbuntu Cloud Imageを使用するテンプレートです。EC2などと同様に,cloud-config用のUserDataを渡すこともできます。詳しくは「lxc-create -t ubuntu-cloud -h」を参照してください。もちろん,通常のubuntuテンプレートでもかまいません。⁠-n trusty-cloud」はコンテナーの名前で,⁠-r trusty」は作成するコンテナーのリリースを指定しています。

実際に作成されたコンテナーは次のコマンドで確認できます。

$ sudo lxc-ls --fancy
NAME          STATE    IPV4  IPV6  AUTOSTART
--------------------------------------------
trusty-cloud  STOPPED  -     -     NO

次に,autopkgtestを今度はadt-virt-lxcを使って実行しましょう。

$ sudo adt-run --no-built-binaries --built-tree=. --- adt-virt-lxc --ephemeral trusty-cloud
adt-run: $ vserver: adt-virt-lxc --ephemeral trusty-cloud
adt-run: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ builds ...
adt-run: @@@@@@@@@@@@@@@@@@@@ tree tree0
adt-run: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ builds done.
adt-run: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ tests ...
adt-run: @@@@@@@@@@@@@@@@@@@@ test tree tree0
adt-run: @@@@@@@@@@ run_tests ...
adt-run: & tree0t-build: preparing
(中略)
adt-run: & tree0t-python: [----------------------------------------
adt-run: & tree0t-python: ----------------------------------------]
adt-run: & tree0t-python:  - - - - - - - - - - results - - - - - - - - - -
tree0t-python        PASS
adt-run: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ tests done.

「adt-virt-lxc」に渡している「--ephemeral」は,テスト用のコンテナーを複製する代わりに,lxc-start-ephemeralコマンドによりoverlayfsを使った一時的なコピーを作成してそれを使用します。よってtrusty-cloudコンテナーそのものには影響を与えません。

たとえばテスト中にlxc-lsを実行すれば,新しいコンテナーが作成され,起動していることがわかるでしょう。

$ sudo lxc-ls --fancy
NAME                 STATE    IPV4        IPV6  AUTOSTART
---------------------------------------------------------
adt-virt-lxc-tcgnqo  RUNNING  10.0.3.247  -     NO
trusty-cloud         STOPPED  -           -     NO

ちなみにtrusty-cloudコンテナーを今後もテスト環境のベースコンテナーとして使い続けるなら,定期的にパッケージリストを更新する必要があります。これは普通にコンテナーを起動して,アップグレードしてください。今後はadt-virt-lxc側でアップグレードできる仕組みが追加されるはずです。

$ sudo lxc-start -n trusty-cloud
ユーザー名:ubuntu,パスワード:ubuntuでログイン
$ sudo apt-get update && sudo apt-get dist-upgrade
$ sudo halt

まとめ

現在どのパッケージがautopkgtestに対応しているかは次のコマンドで確認できます。

$ sudo apt-get install dctrl-tools
$ grep-dctrl -F Testsuite autopkgtest -s Package /var/lib/apt/lists/*Sources

Debianのsidだと254個,UbuntuのTrustyだと(Ubuntu独自パッケージの分嵩上げされて)312個表示されます。とくにUbuntu側は,Ubuntu Touchにおいてテストの自動化を積極的に推進している都合上,Ubuntu Touch関連のライブラリとコアパッケージの対応が急務となっています。

よってautopkgtestによるテストコードは,今後さまざまなパッケージに追加されることでしょう。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。

コメント

コメントの記入