Wercker Postgres、MongoDB絡みのjunitを、実行できるようにする。


Bitbucketにソースをチェックインすると、 Werckerbuild するようにしているのですが、
Databaseportが違うらしくJunit のテストケースが毎回落ちるので、
実行できるように、postgressmongoDb を対象に環境設定してみました。
設定の流れは以下の通りです。


使用ライブラリについて

以下、使っているライブラリになります。
これらの関連設定、関連Javaクラスの記載があります。

  • eclipselink 2.6.3
  • guice 4.0
  • mongo-java-driver 3.2.2

Werckerの環境変数の説明

まず、前提となるWerckerの環境変数についてです。
wercker.yml で 以下のように services の指定をすると、各サービスの環境変数が取得できるようになります。

テストクラスに以下の記述をして、Wercker テスト実行すると、

    @BeforeClass
    public static void setUpClass() {
        System.out.println("---------------------------------------");
        System.out.println("System.getenv()");
        System.out.println("-----------");
        System.getenv().keySet().stream().forEach((key) -> {
            String value = System.getenv((String) key);
            System.out.println(key + "=" + value);

        });
    }

以下のような環境変数が出力されます。 (MongoDBPOSTGRES 関連の変数のみ抜粋しています。)
これらの環境変数をpom.xml 上で取得して、
Wercker 上でJunitテストを実行できるようにします。

CI=true
MONGO_ENV_GPG_KEYS=XXXXXXXXXXXX     XXXXXXXXXXXXXXX
MONGO_ENV_MONGO_MAJOR=3.2
MONGO_ENV_MONGO_VERSION=3.2.6
MONGO_NAME=/wercker-pipeline-XXXXXXXX/mongo
MONGO_PORT=tcp://172.XXX.XXX.XXX:27017
MONGO_PORT_27017_TCP=tcp://172.XXX.XXX.XXX:27017
MONGO_PORT_27017_TCP_ADDR=172.XXX.XXX.XXX
MONGO_PORT_27017_TCP_PORT=27017
POSTGRES_ENV_GOSU_VERSION=1.7
POSTGRES_ENV_LANG=en_US.utf8
POSTGRES_ENV_PG_MAJOR=9.5
POSTGRES_ENV_PG_VERSION=9.5.3-1.pgdg80+1
POSTGRES_ENV_PGDATA=/var/lib/postgresql/data
POSTGRES_ENV_POSTGRES_PASSWORD=XXXXXXXXXX
POSTGRES_ENV_POSTGRES_USER=festival4partypeople
POSTGRES_NAME=/wercker-pipeline-XXXXXXXX/postgres
POSTGRES_PORT=tcp://172.XXX.XXX.XXX:5432
POSTGRES_PORT_5432_TCP=tcp://172.XXX.XXX.XXX:5432
POSTGRES_PORT_5432_TCP_ADDR=172.XXX.XXX.XXX
POSTGRES_PORT_5432_TCP_PORT=5432
POSTGRES_PORT_5432_TCP_PROTO=tcp
WERCKER=true

pom.xml に、profile LOCALと、WERCKERを追加

maven-resources-plugin と、 プロファイル機能 を使用して、
Wercker 上の接続情報を取得できるようにします。
profile での指定値で、設定ファイルを置換できるように、maven-resources-plugin を追加、
各種設定ファイルに、置換対象の変数を埋め込みます。

    <profiles>
        <profile>
            <id>Local</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <jdbc.url>jdbc:postgresql://localhost:5432/databaseName</jdbc.url>
                <jdbc.username>databaseName</jdbc.username>
                <jdbc.password>xxxxxxxxxxxx</jdbc.password>
                <jdbc.driver>org.postgresql.Driver</jdbc.driver>
                <mongoDb.host>localhost</mongoDb.host>
                <mongoDb.port>27017</mongoDb.port>
                <mongoDb.databaseName>mongoDatabaseName</mongoDb.databaseName>
                <jpa.ddl-generation>none</jpa.ddl-generation>
            </properties>
        </profile>
        <profile>
            <id>WERCKER</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <properties>
                <jdbc.url>jdbc:postgresql://${env.POSTGRES_PORT_5432_TCP_ADDR}:${env.POSTGRES_PORT_5432_TCP_PORT}/${env.POSTGRES_ENV_POSTGRES_USER}</jdbc.url>
                <jdbc.username>${env.POSTGRES_ENV_POSTGRES_USER}</jdbc.username>
                <jdbc.password>${env.POSTGRES_ENV_POSTGRES_PASSWORD}</jdbc.password>
                <jdbc.driver>org.postgresql.Driver</jdbc.driver>
                <mongoDb.host>${env.MONGO_PORT_27017_TCP_ADDR}</mongoDb.host>
                <mongoDb.port>${env.MONGO_PORT_27017_TCP_PORT}</mongoDb.port>
                <mongoDb.databaseName>mongoDatabaseName</mongoDb.databaseName>
                <jpa.ddl-generation>drop-and-create-tables</jpa.ddl-generation>
            </properties>
        </profile>
    </profiles>
  • mongoDb.properties
    pom.xmlprofile で指定した変数を埋め込むため、
    MongoDB の接続情報をプロパティファイル化しました。
host=${mongoDb.host}
port=${mongoDb.port}
databaseName=${mongoDb.databaseName}
  • MongoDatabaseProvider.java
    MongoDatabaseProvider クラスとして、以下作成しました。
    プロパティファイルから、接続情報を取得するようにします。
package xyz.monotalk.xxx;

import com.google.inject.Provider;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
import java.util.Locale;
import java.util.ResourceBundle;

/**
 * MongoDatabaseProvider
 *
 * @author Kem
 */
public class MongoDatabaseProvider implements Provider<MongoDatabase> {

    @Override
    public MongoDatabase get() {
        // New MongoClient
        ResourceBundle rb = ResourceBundle.getBundle("mongoDb", Locale.JAPAN);
        String host = rb.getString("host");
        int port = Integer.valueOf(rb.getString("port"));
        MongoClient client = new MongoClient(host, port);
        // New Database
        String databaseName = rb.getString("databaseName");
        MongoDatabase mongoDatabase = client.getDatabase(databaseName);
        return mongoDatabase;
    }
}
  • persistence.xml
    同様に、接続情報を変数化しました。
    eclipselink.ddl-generation で初回接続時に Table を作成するかを指定しています。
    Wercker 上には Table が存在しないため、drop-and-create-tablesTableを作成し、
    ローカル環境では、Table は既に存在し、データが削除されると不都合があるため、none を指定しています。
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence persistence_1_0.xsd">
    <persistence-unit name="Local" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>xyz.monotalk.xxx....</class>
        <properties>
            <!-- JDBC configuration -->
            <property name="javax.persistence.jdbc.url" value="${jdbc.url}"/>
            <property name="javax.persistence.jdbc.user" value="${jdbc.username}"/>
            <property name="javax.persistence.jdbc.driver" value="${jdbc.driver}"/>
            <property name="javax.persistence.jdbc.password" value="${jdbc.password}"/>

            <!-- Logging FOR DEVELOPMENT-->
            <property name="eclipselink.logging.level.sql" value="FINE"/>
            <property name="eclipselink.logging.parameters" value="true"/>

            <!-- DDL generation -->
            <property name="eclipselink.ddl-generation" value="${jpa.ddl-generation}"/>

        </properties>
    </persistence-unit>
</persistence>

wercker.yml の修正

上記pom.xml に、profile LOCALと、WERCKERを追加に合わせて、
wercker.yml を修正しました。

  • wercker.yml

box: jamesdbloom/docker-java8-maven は、java8 環境下で maven のインストールまで、行ってくれる box です。
ポータビリティは gradle の方が高い(java がインストールされていれば実行可能)ということを知りました。
$PSQL_USER$PSQL_PASSWORDBitBucket にチェックインするのがセキュリティ的に微妙なので、
Wercker の画面上から、設定することにします。
mvn -P WERCKER test で、プロファイル指定し、test フェーズまで実行しています。
何故test までかというと、verify フェーズにはinfer がいるのですが、
インストールがうまくいかず実行できなかったからです。

# docker box definition
box: jamesdbloom/docker-java8-maven
services:
   - id: mongo
   - id: postgres
     env:
       POSTGRES_USER: $PSQL_USER
       POSTGRES_PASSWORD: $PSQL_PASSWORD
# This is the build pipeline. Pipelines are the core of wercker
# Read more about pipelines on our dev center
# http://devcenter.wercker.com/docs/pipelines/index.html
build:
    # Steps make up the actions in your pipeline
    # Read more about steps on our dev center:
    # http://devcenter.wercker.com/docs/steps/index.html
  steps:
    - script:
        name: build
        code: |
          mvn -P WERCKER test

設定画面からDB、ユーザー、パスワードを追加

Wercker のサイトから、$PSQL_USER$PSQL_PASSWORD を設定します。

  • 設定画面
    wercker にログインし、対象リポジトリのsettings に移動して、Environment variables をクリックします。
    settings options

  • 環境変数追加
    $PSQL_USER$PSQL_PASSWORD を追加します。($は削除)
    protectedを設定しておくと、設定した値は画面上非表示となります。
    Environment variables

設定は完了です。
これで、Wercker 上でJunit テストケースが動作するようになりました。
以上です。

コメント