go言語でDockerコンテナを操作する関数を書く機会がありました。テストコードを書くにあたり愚直にテストする以外方法が思いつかなかったが、実装した関数をシェアしておきます。もっと楽な方法を知っている方がいたらコメントしていただければ幸いです。
テスト対象関数
今回実装した中で一番シンプルなコンテナを削除し、エラーを返す関数を例にとります。
killContainer.go
func killContainer(containerID string) (err error) {
cmd := "docker rm " + containerID
err = exec.Command("sh", "-c", cmd).Run()
return err
}
docker rmコマンドは、コンテナIDの冒頭を返すので、Output()を使って取得しても良いかもです。
テスト関数
killContainer_test.go
func TestKillContainer(t *testing.T) {
containerID, err := exec.Command("sh", "-c", "docker create alpine ls /").Output()
if err != nil {
t.Fatalf("コンテナ作成時にエラーが発生しました。%v", err)
}
err = killContainer(string(containerID))
if err != nil {
t.Fatalf("killContainer()実行中にエラーが発生しました。%v", err)
}
cmd := "docker ps -a | grep " + string(containerID[0:12])
err = exec.Command("sh", "-c", cmd).Run()
if err.Error() != "exit status 1" {
t.Fatalf("コンテナを削除できていません。")
}
}
execを利用してコンテナを作成し関数を実行、その後"dokcer ps -a"を実行し、grepでコンテナIDが存在するかどうか確かめています。
"grep xxx"で、標準入力されたもののうちxxxを含む行を返します。対象の行が存在しない場合"exit status 1"になるので、そこで存在を判断しています。
解説
みてわかるように非常に愚直な方法で実装しています。全部shellコマンド使っています。
テストはパスしたのでこれで良いような気がしますが、もっと楽な方法もある気がします。