dockerコンテナ自動テストツール dgossを使ってみた

# はじめに
[goss](https://github.com/aelsabbahy/goss)のラッパーでdockerコンテナを自動テストできる[dgoss](https://github.com/aelsabbahy/goss/tree/master/extras/dgoss)というツールを見つけたので使ってみた

## gossとは
- golang製のserverspecのようなもの
- テスト定義はYAMLで記述
- 実行環境はバイナリファイル1つを配置するだけ
- goss add/goss autoaddコマンドである程度はテスト定義YAMLを自動生成できる

## dgossとは
- 前述のとおりgossのラッパー
- gossと同様のYAMLでdockerコンテナをテストできる

# 今回の目的
dgossの使い方を確認すること

# 今回のゴール
nginxのdockerイメージを作成
そのイメージをdgossを使ってテストできることを確認

# 使用する環境
- Mac OS X Yosemite 
- Docker for Mac 17.03.1

# テスト対象のdockerイメージ作成
**※今回のテーマではない部分なので読み飛ばしてオケ**

とりあえず手動で作成する
ベースイメージはなんとなくamazonlinuxを使用

公式のイメージから「AL」という名前でコンテナを作成し起動
同時にbashを起動してコンテナに接続

```
$ docker run -it --name AL amazonlinux /bin/bash
bash-4.2# cat /etc/system-release
Amazon Linux AMI release 2017.03
```

yumでnginxをインストール

```
bash-4.2# yum install -y nginx
```
バージョンを確認

```
bash-4.2# nginx -v
nginx version: nginx/1.10.2
```
index.htmlを適当に書き換え

```
bash-4.2# echo 'hello world!' > /usr/share/nginx/html/index.html
bash-4.2# cat /usr/share/nginx/html/index.html
hello world!
```

起動

```
bash-4.2# nginx
```

アクセスしてみる

```
bash-4.2# curl http://localhost:80
hello world!
```

とりあえず構築はここまでにしてexitしてコンテナを停止する

```
bash-4.2# exit
exit
```

作成したコンテナからイメージを作成する
とりあえずリポジトリ名「test1」/タグ名「nginx」で作成

```
$ docker commit AL test1:nginx
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
test1               nginx               23dbd0af6d74        6 minutes ago       267 MB
amazonlinux         latest              766ebb052d4f        5 weeks ago         162 MB
```

作成したイメージから「nginx」という名前でコンテナをバックグラウンド起動
同時にコンテナ内のnginxを起動させる
またMacの8080ポートをコンテナの80ポートにフォワードさせる

```
$ docker run --name nginx -d -p 8080:80 test1:nginx nginx -g "daemon off;"
```
Macの8080ポートにアクセスしてみる

```
$ curl http://localhost:8080
hello world!
```
とりあえずイメージとしては問題なし

# dgossのインストール
[README](https://github.com/aelsabbahy/goss/blob/master/extras/dgoss/README.md)を参考に行う

dgossのインストール

```
$ curl -L https://raw.githubusercontent.com/aelsabbahy/goss/master/extras/dgoss/dgoss -o /usr/local/bin/dgoss
$ chmod +rx /usr/local/bin/dgoss
$ which dgoss
/usr/local/bin/dgoss
```
ワークディレクトリを作る

```
$ mkdir test_dgoss
$ cd test_dgoss/
```
gossをワークディレクトリにインストール
実際はどこでも好きなとこに置いて良い

```
$ curl -L https://github.com/aelsabbahy/goss/releases/download/v0.3.2/goss-linux-amd64 -o ./goss-linux-amd64
$ export GOSS_PATH=`pwd`/goss-linux-amd64
```

# テスト定義YAMLの作成

今回は簡潔に

- nginxがインストールされていること
- nginxのバージョンが「1.10.2」であること
- nginxプロセスが起動していること
- 80番ポートをListenしていること
- index.htmlが存在していること
- index.htmlの中身が「hello world!」であること

をテストするYAMLを作成する
構文は[マニュアル](https://github.com/aelsabbahy/goss/blob/master/docs/manual.md)を参考にする

```
$ vi ./goss.yaml
```

```./goss.yaml
package:
  nginx:
    installed: true
    versions:
    - 1.10.2
process:
  nginx:
    running: true
port:
  tcp:80:
    listening: true
file:
  /usr/share/nginx/html/index.html:
    exists: true
    filetype: file
    contains:
    - "hello world!"
```

# テスト実行
テスト実行のコマンドは「docker run」実行時の「docker」の部分を「dgoss」にすればオケ

```
$ dgoss run test1:nginx nginx -g "daemon off;"
INFO: Starting docker container
INFO: Container ID: 6a015513
INFO: Sleeping for 0.2
INFO: Running Tests
File: /usr/share/nginx/html/index.html: exists: matches expectation: [true]
File: /usr/share/nginx/html/index.html: filetype: matches expectation: ["file"]
File: /usr/share/nginx/html/index.html: contains: matches expectation: [hello world!]
Process: nginx: running: matches expectation: [true]
Port: tcp:80: listening: matches expectation: [true]
Package: nginx: installed: matches expectation: [true]
Package: nginx: version: matches expectation: [["1.10.2"]]


Total Duration: 0.316s
Count: 7, Failed: 0, Skipped: 0
INFO: Deleting container
```
ちゃんとテストが成功した
しかもテストが終わったら作成されたコンテナを削除してくれるらしい

次はあえてテストが失敗されるようにYAMLを変更

```
$ diff ./goss.yaml ./goss.yaml.bak
5c5
<     - 1.10.3
---
>     - 1.10.2
11c11
<     listening: false
---
>     listening: true
17c17
<     - "Hello World!"
---
>     - "hello world!"
```

再度テストを実行

```
$ dgoss run test1:nginx nginx -g "daemon off;"
INFO: Starting docker container
INFO: Container ID: 647b118b
INFO: Sleeping for 0.2
INFO: Running Tests
File: /usr/share/nginx/html/index.html: exists: matches expectation: [true]
File: /usr/share/nginx/html/index.html: filetype: matches expectation: ["file"]
File: /usr/share/nginx/html/index.html: contains: patterns not found: [Hello World!]
Process: nginx: running: matches expectation: [true]
Port: tcp:80: listening:
Expected
    <bool>: true
to equal
    <bool>: false
Package: nginx: installed: matches expectation: [true]
Package: nginx: version:
Expected
    <[]string | len:1, cap:1>: ["1.10.2"]
to contain element matching
    <string>: 1.10.3


Failures/Skipped:

File: /usr/share/nginx/html/index.html: contains: patterns not found: [Hello World!]

Port: tcp:80: listening:
Expected
    <bool>: true
to equal
    <bool>: false

Package: nginx: version:
Expected
    <[]string | len:1, cap:1>: ["1.10.2"]
to contain element matching
    <string>: 1.10.3

Total Duration: 0.200s
Count: 7, Failed: 3, Skipped: 0
INFO: Deleting container
```

変更した3箇所がちゃんとエラーとなった


# まとめ
今回は**dgoss**を使い自作したdockerイメージをテストすることができた
実行環境も簡単に作れるので個人的にはとてもよかった
ただやはりYAMLを手動で作成するのは苦痛
どうにかしてgoss add/goss autoaddを使って自動生成したい
その辺は今後色々試してみたい