wercker 上で Aerospike を使ったテストをする

wercker が最近 Docker に対応しました。 これにより、 Docker を利用している場合にはテストからデプロイまでを共通したコンテナでおこなえるほか、既存のコンテナを再利用し、柔軟に組み合わせて利用できるようになりました。

最近 Aerospike という超優秀な KVS を利用しているのですが、 Docker ベースになった werkcer 上でこのクライアントライブラリのユニットテストを実行したいと思ったので試してみました。

werker には services という、 複数のコンテナを外部サービスとして利用する仕組みがあります。この機構により、使用するミドルウェアのコンテナイメージを用意すれば、 CI 時にそれを利用したテストを走らせることができます。素晴らしい仕組みです。たとえば、 Redis を使用したければ、wercker.ymlservices セクションに以下のように redis を追記します。

1
services:
  - redis

これにより、 CI 時に Docker Hub の Redis イメージが pull されてきて、 アプリケーションから利用できるようになります。 Aerospike を使う場合も同様で、 wercker.yml に以下のように書きます。

1
services:
  - aerospike

こうすると、ビルド時に Docker Hub の aerospike リポジトリからイメージを取得して、利用できるようにしてくれます。

では、アプリケーション側からこれらのサービスにアクセスするにはどうすればよいのでしょうか?
wercker では Docker のコンテナ間リンク機構 を利用して、 環境変数が自動で準備されるようになってます。 Aerospike を使用した場合には、以下のような環境変数が用意されることになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
AEROSPIKE_ENV_AEROSPIKE_SHA256=df810e67d363291f6f40c046564bbc7ab775fcdb45ebfb878368361705063015
AEROSPIKE_ENV_AEROSPIKE_VERSION=3.5.14
AEROSPIKE_NAME=/wercker-pipeline-55ae303ff32b86a92907041f/aerospike
AEROSPIKE_PORT=tcp://172.17.6.203:3000
AEROSPIKE_PORT_3000_TCP=tcp://172.17.6.203:3000
AEROSPIKE_PORT_3000_TCP_ADDR=172.17.6.203
AEROSPIKE_PORT_3000_TCP_END=tcp://172.17.6.203:3003
AEROSPIKE_PORT_3000_TCP_PORT=3000
AEROSPIKE_PORT_3000_TCP_PORT_END=3003
AEROSPIKE_PORT_3000_TCP_PORT_START=3000
AEROSPIKE_PORT_3000_TCP_PROTO=tcp
AEROSPIKE_PORT_3000_TCP_START=tcp://172.17.6.203:3000
AEROSPIKE_PORT_3001_TCP=tcp://172.17.6.203:3001
AEROSPIKE_PORT_3001_TCP_ADDR=172.17.6.203
AEROSPIKE_PORT_3001_TCP_PORT=3001
AEROSPIKE_PORT_3001_TCP_PROTO=tcp
AEROSPIKE_PORT_3002_TCP=tcp://172.17.6.203:3002
AEROSPIKE_PORT_3002_TCP_ADDR=172.17.6.203
AEROSPIKE_PORT_3002_TCP_PORT=3002
AEROSPIKE_PORT_3002_TCP_PROTO=tcp
AEROSPIKE_PORT_3003_TCP=tcp://172.17.6.203:3003
AEROSPIKE_PORT_3003_TCP_ADDR=172.17.6.203
AEROSPIKE_PORT_3003_TCP_PORT=3003
AEROSPIKE_PORT_3003_TCP_PROTO=tcp

ドキュメント にある通り、環境変数の命名規則は

1
<name>_PORT_<port>_<protocol>

をプレフィックスとして、 prefix_ADDR なら IP アドレス、 prefix_PORT ならポート番号、 prefix_PROTO ならプロトコル名になっています。なおかつ、Aerospike の Dockerfile が実行されるので、 3000 ~ 3003 番のポートに対応する環境変数がそれぞれ用意されていますね。

したがって、あとはアプリケーション側が環境変数から必要な値を取得するような実装になっていればよいことになります。たとえば Go 言語であれば、 以下のように os.Getenv() を使えばよいでしょう。

1
addr := os.Getenv("AEROSPIKE_PORT_3000_TCP_ADDR")

これで、 DB などの外部サービスに依存したテストも wercker 上で実行できるようになりました!