Docker: PHPのコンテナが正しくビルドされたかを手っ取り早くテストする


* バージョンや拡張、php.iniの設定が意図したものなのか確認したい。
* serverspecとかを使わずに入ってるツールだけで済ませたい。

## バージョンが意図したものかテストする

```console
$ sudo docker run --rm $(IMAGE) php -v | grep 'PHP 5.5.9'
PHP 5.5.9-1ubuntu4.3 (cli) (built: Jul  7 2014 16:36:58)
```

## 拡張がインストールされてるかテストする

```console
$ sudo docker run --rm $(IMAGE) php -m | grep mbstring
mbstring
```

## php.iniが正しく設定されたかテストする

これはちょっとしたスクリプトを書いておいたほうが管理しやすい。このスクリプトは複数のSAPIに対応するために、HTTPヘッダで500を返したり、終了ステータスを1にセットしたりしている。

```php:test.php
<?php

assert_options(ASSERT_CALLBACK, function($script, $line, $message) {
  header("HTTP", null, 500);
  echo "FAIL: " . file($script)[$line - 1];
  register_shutdown_function(function(){ exit(1); });
});

assert(ini_get("date.timezone") === "Asia/Tokyo");
assert(ini_get("expose_php") === "0");
assert(ini_get("display_errors") === "0");
assert(ini_get("log_errors") === "1");
assert(ini_get("log_errors_max_len") === "4096");
assert(ini_get("error_log") === "/var/log/php_error.log");
assert(ini_get("register_globals") === false);
assert(ini_get("register_long_arrays") === false);
assert(ini_get("allow_url_include") === "0");
assert(ini_get("default_charset") === "UTF-8");
assert(ini_get("phar.readonly") === "1");
php_sapi_name() == "cli" and assert(ini_get("max_execution_time") === "0");
php_sapi_name() == "apache" and assert(ini_get("max_execution_time") === "30");
php_sapi_name() == "apache2handler" and assert(ini_get("max_execution_time") === "30");
assert(ini_get("memory_limit") === "128M");
assert(ini_get("upload_max_filesize") === "32M");

// mbstring
assert(ini_get("mbstring.language") === "Japanese");
assert(ini_get("mbstring.internal_encoding") === "UTF-8");
assert(ini_get("mbstring.http_input") === "pass");
assert(ini_get("mbstring.http_output") === "pass");
assert(ini_get("mbstring.encoding_translation") === "");
assert(ini_get("mbstring.detect_order") === "UTF-8, EUC-JP, SJIS, ASCII");
assert(ini_get("mbstring.substitute_character") === "");

```

UbuntuだとSAPIによって読まれる設定ファイルが変わるので、SAPIの数だけテストしておく。

### CLIをテストする方法

```console
$ sudo docker run --rm -v /vagrant:/vagrant $(IMAGE) php /vagrant/php/test.php
```

### Apacheをテストする方法

docker run で Apache が立ち上がるのが追いつかない場合があるので wget に `--retry-conrefused` をつけている。本当は curl を使いたいところだが、これと同等のオプションが curl では見つけられなかったので wget を使っている。

```console
sudo docker rm -f http || true
sudo docker run -d -i -t --name http -v /vagrant:/vagrant --net host $(IMAGE)
wget --retry-connrefused --content-on-error localhost/test.php -qO -
sudo docker rm -f http
```

## これらをとりあえずMakefileにしておくといい

テストコマンドをMakefileに並べておけばテストも行えるし、テストがコケた場合でもわかりやすい。

```mk:Makefile
IMAGE := my/php

build:
	sudo docker build -t $(IMAGE) .

test:
	sudo docker run --rm $(IMAGE) php -v | grep 'PHP 5.5.9'
	sudo docker run --rm $(IMAGE) php -m | grep mbstring
	sudo docker run --rm $(IMAGE) php -m | grep mysql
	sudo docker run --rm $(IMAGE) php -m | grep curl
	sudo docker run --rm -v /vagrant:/vagrant $(IMAGE) php /vagrant/php/test.php

	sudo docker rm -f http || true
	sudo docker run -d -i -t --name http -v /vagrant:/vagrant --net host $(IMAGE)
	wget --retry-connrefused --content-on-error localhost/test.php -qO -
	sudo docker rm -f http
```