Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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 を利用させてもらって作業が楽になっています。便利なツールなので、こうして紹介させていただきました。

ao_log
インフラ周りに興味があるエンジニア。ピアノを習い始めました。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした