Playframework2.5 Java+PostgreSQLアプリケーションをTravis-CIでテスト自動化してみた話

JenkinsさんラブですがこのたびTravis CIに乗り換えてみましたので、備忘録。

# 前提環境

- playframework > 2.5
- Java >= 1.8
- PostgreSQL >= 9.5
- GitHub

# .travis.yml作成

travisコマンドもあるようだけどまずは下記ドキュメントを漁りながら書いてみた。

https://docs.travis-ci.com/user/database-setup/

## プログラム言語とか設定とか

sudo: requiredをいれないと各種インストールができないので最初に書く。jdkはoraclejdk8を利用するように明記しないと1.7になる。

```yaml:.travis.yml
sudo: required

language: java

jdk:
  - oraclejdk8

env:
  - PLAY_VERSION=2.5.9↲
```

## PostgreSQL

postgresqlは先にaddonsでバージョンを指定してからserviceで開始の流れにする。
これはログをみていると順番に実行されるようだ。

```yaml:.travis.yml
addons:
  postgresql: "9.5"

services:
  - postgresql
```

さらにCOLLATIONの指定をja_JP.UTF-8を利用するためにロケールをインストールして利用できるようにする。日本人必須項目？入れた後はpostgresを再起動する。とりあえずロケールは全部入れちゃう。

```yaml:.travis.yml
before_script:
  - sudo apt-get update
  - sudo apt-get install language-pack-es
  - sudo apt-get install language-pack-ja
  - psql -U postgres -c "create extension postgis"
  - sudo /etc/init.d/postgresql stop
  - sudo /etc/init.d/postgresql start 9.5
```

## データベース作成とテストデータ投入

before_scriptに下記追記してpsqlコマンドのコマンドラインで色々実行していく。
まずはロールとデータベースを作成

```yaml:.travis.yml
  - psql -U postgres -c 'CREATE ROLE foo WITH LOGIN PASSWORD "var";'
  - psql -U postgres -c 'CREATE DATABASE hogehoge  WITH OWNER=foo ENCODING="UTF8" TABLESPACE="pg_default" template="template0" lc_collate="ja_JP.UTF-8" lc_ctype="ja_JP.UTF-8";'
```

テストデータはTSVファイルで用意してCOPYコマンドで取り込むことにした。
travis.ymlは普通に順番にシェル実行してくれるだけなので下記のようにカレントフォルダを変数に入れてフルパスで指定する。
TSVファイルはプロジェクト内のmisc/data/test.tsvでコミットした。データは15,000行くらい。

```yaml:.travis.yml
  - export CDIR=`pwd`
  - psql -U postgres -c "COPY users FROM '${CDIR}/misc/data/test.tsv';" -d foo
```

## テスト実行

```yaml:.travis.yml
script:↲
  - ./bin/activator test↲
```

## ログが出すぎて止まってるのに終わらない

これでtravis側でリポジトリをセッティングするとプッシュとプルリクエストで自動でテストが走るようになった。ところが問題が発生。ローカルだと10分程度で終わる全て終わるテストが１時間以上たってもいっこうに終わらない。ログを見るとjob terminated log is over 4Mとかでてジョブがkillされているにもかかわらずテストのステータスは実行中のまま。有料プランを使っているのになんてひどい仕様だ。いやステータスが実行中のままkillされている時点でバグだと思うのだが・・

とりあえず4Mまでしかログ吐けないとのことなのでSQL関連のログをテスト実行時にはかないように設定するしかない。誰かいい解決法知ってたら教えろください。

playframeworkででるSQLのログを停止するためにtravisでのテスト用にapplication_test.confとlogback_test.xmlを作成

これを./bin/activator testで読み込めるようにするためにbuild.sbtの末尾に下記を追加

```scala:build.sbt
fork in Test := true
javaOptions in Test += "-Dconfig.resource=application_test.conf"
javaOptions in Test += "-Dlogger.resource=logback_test.xml"
```

application.confはデータベース接続設定にlogSql=false

```application_test.conf
db {
  default {
    driver=org.postgresql.Driver
    url="jdbc:postgresql://localhost:5432/hoge"
    username="foo"
    password="var"
    logSql=false
  }
}
```

logback_test.xmlには
https://www.playframework.com/documentation/2.5.x/ScalaDatabase#How-to-configure-SQL-log-statement
を参考に下記を追記

```logback_test.xml
  <logger name="org.jdbcdslog.ConnectionLogger" level="OFF"  />
  <logger name="org.jdbcdslog.StatementLogger"  level="INFO" />
  <logger name="org.jdbcdslog.ResultSetLogger"  level="OFF"  />
```

これで./bin/activator test実行時にSQL結果レコードが表示されることがなくなりやっとテストが通った。
Travisでテストやチェックの成果物を結果画面に取り込んだり見る方法がわからないので引き続き調査だけどコンソールログが4Mまでというのはやっぱり面倒というか痛い。Jenkins先生用にインフラを用意して運用するよりかなり低価格とはいえ低価格なりというところですかね。