Python製のサーバ環境テストツールTestinfraの環境構築から動作テストまでの手順

# Python製インフラテストライブラリTestinfraの環境を構築した

## 背景

社内ではサーバ系のテストは、手動メインで行われているようなので自動化の仕組みを導入して効率化したい。
以前の職場ではサーバテストツールとしてRuby製のServerspecとInfratasterを取り入れようとしたが、構成管理ツールのAnsibleやFabricと合わせてPython製に統一したいと思った。調べるとTestinfraというテストツールが見つかった。
公式サイトでもTestinfraはRubyのServerspecのようなツールと書かれていたたため使ってみた。
今回は環境構築から動作テストまでの導入部分の手順を記した。

## 1. インストール手順

### 1-1. 前提条件

下記環境ができていることとする
1. pipがインストールされていること
2. SSHで接続できるサーバが最低２台あること

### 1-2. 流れ

1. testinfraのインストール
2. ssh接続設定（クライアント側)
3. ssh接続設定（サーバ側）
4. テストコードの作成
5. テストコードの実行（ローカルホスト）
6. テストコードの実行（リモートホスト）

### 2. 手順

#### 2-1. testinfraのインストール
<pre>
$ pip install testinfra
</pre>

#### 2-2. ssh接続設定（クライアント側)
  1. private keyとpublic keyを作成する
<pre>
$ cd $HOME/.ssh
$ ssh-keygen -t rsa -f test_server
</pre>
  2. scpでリモート接続先のサーバへpublic keyを転送する
<pre>
$ scp test_server.pub permit@192.168.1.31:/var/tmp/
</pre>
  3. 「3. ssh接続設定（サーバ側）」の2の手順を完了後、鍵認証のssh接続を試す
<pre>
$ ssh -i $HOME/.ssh/test_server permit@192.168.1.31
</pre>
  4. ssh_configを作成
<pre>
$ vi $HOME/.ssh/ssh_config
</pre>
ここではリモートサーバのホスト名を"redmine"とした
<pre>
Host redmine
  HostName     192.168.1.31
  Port         22
  User         permit
  IdentityFile ~/.ssh/test_server
</pre>

#### 2-3. ssh接続設定（サーバ側）
  1. ssh接続用アカウントを作成する  
  今回は"permit"ユーザを作成した
<pre>
$ useradd -m permit -G wheel
$ passwd permit
</pre>
  2. クライアントのpublic keyを authorized_keysに書き込む
<pre>
$ mkdir $HOME/.ssh
$ mv /var/tmp/test_server.pub $HOME/.ssh/
$ cd $HOME/.ssh/
$ cat test_server.pub >> authorized_keys
$ chmod 600 authorized_keys
$ rm test_server.pub
</pre>

#### 2-4. テストコードの作成
  1. テストコードを作成する
<pre>
$ vi test.py
</pre>
  テストコード例  

```py
def test_passwd_file(File):
    passwd = File("/etc/passwd")
    assert passwd.contains("root")
    assert passwd.user == "root"
    assert passwd.group == "root"
    assert passwd.mode == 0o644
```

#### 2-5. テストコードの実行（ローカルホスト）
  1. ローカルホストのテスト実行
<pre>
$ testinfra -v test.py
</pre>
  2. 実行結果の確認

```text
=================================== test session starts ====================================
platform linux2 -- Python 2.7.9, pytest-3.0.1, py-1.4.31, pluggy-0.3.1 -- /usr/local/bin/python2.7
cachedir: .cache
rootdir: /root, inifile: 
plugins: testinfra-1.4.2, pep8-1.0.6
collected 1 items 

test.py::test_passwd_file[local] PASSED

================================== pytest-warning summary ==================================
WP1 None Modules are already imported so can not be re-written: testinfra
======================= 1 passed, 1 pytest-warnings in 0.03 seconds ========================
```

#### 2-6. テストコードの実行（リモートホスト）
  1. リモートホストのテスト実行
<pre>
$ testinfra test.py --connection=ssh --hosts=permit@redmine --ssh-config=/root/.ssh/ssh_config
</pre>
  2. 実行結果の確認

```text
=================================== test session starts ====================================
platform linux2 -- Python 2.7.9, pytest-3.0.1, py-1.4.31, pluggy-0.3.1 -- /usr/local/bin/python2.7
cachedir: .cache
rootdir: /root, inifile: 
plugins: testinfra-1.4.2, pep8-1.0.6
collected 1 items 

test.py::test_passwd_file[ssh://redmine] PASSED

================================== pytest-warning summary ==================================
WP1 None Modules are already imported so can not be re-written: testinfra
======================= 1 passed, 1 pytest-warnings in 0.66 seconds ========================
```

## 3. 参考
* [Testinfra](http://testinfra.readthedocs.io/)