Edited at

Python 製のインフラテストツール Testinfra を使ってみる

Testinfra は Python 製のインフラテストツールです。サーバの構成やサービスの稼働状況などが正しいかテストするのに便利です。

デプロイ時や、定期的にテストを実行して健全性をチェックしたりなど、自動化、省力化の様々な局面で使えるかと思います。

この記事ではサクッと要点を紹介しようと思います。実のところ、公式ドキュメントが必要なことを分かりやすく簡潔に書いてくれているので、この記事を読まずにいきなり公式ドキュメントでもいいかとは思います。

[公式ドキュメントはこちら]

https://testinfra.readthedocs.io/en/latest/index.html


インストール

testinfra パッケージをインストールします。ここでは、仮想環境を作ってその中にパッケージをインストールする手順を示します。

$ python -m venv testinfra

$ source testinfra/bin/activate
$ pip install testinfra


早速、使ってみる

公式ドキュメントのサンプルをそのまま動かしてみます。

https://testinfra.readthedocs.io/en/latest/

何をテストしているかは、コードから直感的に理解できるかと思います。

def test_passwd_file(host):

passwd = host.file("/etc/passwd")
assert passwd.contains("root")
assert passwd.user == "root"
assert passwd.group == "root"
assert passwd.mode == 0o644

def test_nginx_is_installed(host):
nginx = host.package("nginx")
assert nginx.is_installed
assert nginx.version.startswith("1.2")

def test_nginx_running_and_enabled(host):
nginx = host.service("nginx")
assert nginx.is_running
assert nginx.is_enabled

次のコマンドを実行します。戻り値は成功時に「0」、失敗時に「1」となります。

$ py.test -v test_myinfra.py

...()
test_myinfra.py::test_passwd_file[local] PASSED [ 33%]
test_myinfra.py::test_nginx_is_installed[local] FAILED [ 66%]
test_myinfra.py::test_nginx_running_and_enabled[local] FAILED [100%]

...()

============== 2 failed, 1 passed in 0.14 seconds ==============

# 今回はテストに通らなかったので、戻り値が「1」になっています。
$ echo $?
1


パラメータ化

複数のパッケージについてインストールされているか、バージョンは正しいかをテストしたい場合があると思います。そういう場合は、パラメータ化することで、パラメータ化した項目を一括でテストできます。

以下は、インストールされているパッケージ、サービスの設定と稼働状況、カーネルパラメータについて、それぞれパラメータ化してテストするコードになります。

import pytest

@pytest.mark.parametrize("name, version", [
("python36", "3.6.6"),
("chrony", ""),
])

def test_packages(host, name, version):
pkg = host.package(name)
assert pkg.is_installed
assert pkg.version.startswith(version)

@pytest.mark.parametrize("service", [
("chronyd"),
("crond"),
])

def test_services(host, service):
assert host.service(service).is_running
assert host.service(service).is_enabled

@pytest.mark.parametrize("param, value", [
("/proc/sys/vm/overcommit_memory", "0"),
("/proc/sys/vm/overcommit_ratio", "50"),
("/proc/sys/vm/dirty_ratio", "30")
])

def test_parameters(host, param, value):
assert host.file(param).contains(value)


リモートのホストに対する実行

paramiko パッケージが必要になります。

$ pip install paramiko

--host オプションでホスト名を指定してください。

$ py.test --host ホスト名 -v ./test_myinfra.py 


最後に

上述の通り、セットアップが簡単で覚えることも少なく利用できます。私は普段遣いの言語が Python ということもあり、仕事でも testinfra を利用させてもらって作業が楽になっています。便利なツールなので、こうして紹介させていただきました。