【カスタム Docker イメージ】コンテナー上でRspec UnitTest
実施内容
IBM Cloud Continuous DeliveryのPipelineで、RubyのRspec Unit Testを実施します。 テストではPostgreSQLを利用するため、PostgreSQL、Rubyを動かすことができる カスタム Docker イメージを作成し、Pipelineで利用します。
Pipelineは、IBM Cloudのツールチェーンのテンプレートから作成したものを利用します。アプリのソースコードは、Githubから取得します。
rubyのアプリは、BackendのAPIとして利用し、DBはPostgreSQLに接続しています。
DBの接続先は、環境変数で切り替えます。
Ruby側は、ローカルでUnitTestが実施できる前提であり、ここではその設定を記載していません。
カスタム Docker イメージとは
IBM Cloud Continuous Deliveryのパイプラインで利用される基本イメージでは、利用できるツールが限られています。その際に、カスタムDockerイメージを利用し,必要なツールを利用することができます。
この記事では、カスタムDockerイメージを利用したUnitTestで実施した内容を簡単にですが記載したいと思います。
IBM Cloud 資料 -カスタム Docker イメージの操作-
パイプライン基本イメージは、すべてのビルドの要件をサポートしていないことがあります。 例えば、node、Java、またはその他のツールのバージョンを細かく制御する必要がある場合があります。 この問題に対処するには、一連の新規パッケージをインストールして、環境変数 (PATH など) を慎重に構成して環境をセットアップする最初のステップをパイプライン・ジョブに組み込みます。 しかし、さらに優れた方法は、ジョブの基礎として「カスタム Docker イメージ」を実行するためにパイプラインのサポートを使用することです。
考慮点
Continuous Delivery の Pipeline でカスタム・イメージを作成、利用するうえでの考慮です。
- Pipeline用に何かのベースイメージ利用する、というような制約はなく、どんなイメージも利用可能。
- Pipelineのステージやジョブ自体はパブリック・ワーカー上で動いているが、それはカスタム・イメージの外側で動いている。Gitや別ステージのビルド成果物からのファイルの取得や、出来上がったファイルのビルド成果物としての登録については、その外側のパブリック・ワーカーが実施する。
SCM/ビルド成果物からのインプットのファイルは、カスタム・イメージ内に展開されてくる。カスタムイメージ内は、pipelineで使用するスクリプトも展開される。WORKDIRを設定した場合、該当するディレクトリのみがカスタムイメージないのWORKDIRに展開される。処理実行後にも、WORKDIR以下にあるフォルダーをビルド成果物フォルダーとして指定できる。 (外側の処理が実行)
-
カスタム・イメージには、SCM/ビルド成果物からのインプットのファイルの他に以下のファイルが追加される。
-
_customer_script.sh
: Pipeline上のジョブ定義上に書いたスクリプト -
_pipeline_script.sh
: (おそらく)パイプラインがJobを実行するためのスクリプト -
_env
: 各環境変数 -
_toolchain.json
: ツールチェーンの情報など
-
Pipeline上のジョブ定義上に書いたスクリプトは、ジョブの実行時にファイル(
_customer_script.sh
)として保存されて、カスタム・イメージに引き渡される。 ジョブでは、_pipeline_script.sh
が_customer_script.sh
を呼びだす形で実行される。
DOCKER_RUN="$DOCKER run --env-file='_env' -v `pwd`:`pwd` -w `pwd` --entrypoint='' '$DOCKER_IMAGE' ./_customer_script.sh"
また、コンテナーを利用する場合は、下記に注意します。
ご使用の Docker イメージの Dockerfile の
ENTRYPOINT
とCMD
はオーバーライドされ、呼び出されません。 このため、場合によっては、初期化ステップをスクリプトに追加する必要があります。
IBM Cloud 資料 -カスタム Docker イメージの操作 スクリプトの指定-
カスタムDcokerイメージの準備
Dockerイメージの用意
イメージの作成
Dockerイメージを作成します。postgresイメージをベースにして、rbenv経由でrubyを導入しました。
FROM postgres:11.5-alpine
ENV PATH "/root/.rbenv/bin:$PATH"
ENV PATH "/root/.rbenv/versions/2.7.1/bin:$PATH"
ENV PGDATA /usr/local/var/postgres
ENV DATABASE_HOST localhost
ENV DATABASE_PORT 5432
ENV DATABASE_USER postgres
ENV DATABASE_PASSWORD password
RUN echo $PATH && \
apk update && \
apk upgrade && \
apk --upgrade --no-cache add --update --virtual .ruby-builddeps git gcc g++ musl openssl-dev zlib-dev make && \
git clone https://github.com/rbenv/rbenv.git ~/.rbenv && \
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build && \
rbenv install 2.7.1 && \
rbenv global 2.7.1 && \
apk del --purge .ruby-builddeps
COPY initdb.sql /docker-entrypoint-initdb.d/.
RUN crond restart
リポジトリに登録
まず、Dockerイメージを用意し、オンラインのリポジトリに配置する必要があります。例えば、以下の二つ
- Docker hub
- IBM Cloud Contianer Registry
レジストリは、PublicでもPrivateでも可能です。Privateの場合は、Pipelineのステージの環境プロパティーにユーザー名・パスワードを設定します。
DOCKER_USERNAME
にiamapikey
と記載。DOCKER_PASSWORD
にはkeyを入力します。
※ツールチェーンをテンプレートから作成するときに、API Keyも作成します。そのキーを再利用することができます。
ツールチェーンの作成>Kubernetes アプリの開発の画面のDelivery Pipelineの欄
Jobの編集
BUILDステージのUnit Testジョブを編集する。
- テスター・タイプ : カスタム Docker イメージ
- Docker イメージ名 : 作成したイメージ名を設定する。
- 作業ディレクトリ : 自由に指定(今回は指定していないので、github上のコードが全て展開されます。)
Jobには、デフォルトで以下のスクリプトが用意されています。
#!/bin/bash
#set -x
if [ -f ./tests/run-tests.sh ]; then
source ./tests/run-tests.sh
RESULT=$?
echo=$RESULT
if [ ! -z "${FILE_LOCATION}"]; then
if [ ${RESULT} -ne 0 ]; then STATUS=fail; else STATUS=pass; fi
if jq -e '.services[] | select(.service_id=="draservicebroker")' _toolchain.json; then
ibmcloud login --apikey ${IBM_CLOUD_API_KEY} --no-region
ibmcloud doi publishtestrecord --type unittest --buildnumber ${BUILD_NUMBER} --filelocation ${FILE_LOCATION} \
--buildnumber ${BUILD_NUMBER} --logicalappname ${IMAGE_NAME} --status ${STATUS}
fi
exit $RESULT
fi
else
echo "Test runner script not found: ./tests/run-tests.sh"
fi
テストスクリプトの作成
テスト用スクリプトに合わせて、/tests/run-tests.sh
を作成します。
考慮点の最後に記載した通り、ENTRYPOINT
と CMD
上書きされて呼び出されません。今回ベースに使用しているpostgres
イメージの場合、呼び出し時にDBが起動されません。そのため、dbの起動スクリプトを最初に記載しています。
apk add
の部分については、イメージを作る際にDockerfileに記載しておくことも可能です。しかし、イメージのサイズが大きくなってしまうため、今回はテスト時に実行しています。
#!/bin/sh
# PostgreSQLの起動
echo start postgres
docker-entrypoint.sh postgres &
echo version
ruby -v
#Bundole installの実施。必要なツールをapkで取得。(nokogiriなどを使う場合は要注意)
echo bundle install
apk --upgrade --no-cache add libxml2-dev libxslt-dev gcc g++ musl make
bin/bundle install
ERRCHK=$?
if [ ${ERRCHK} -ne 0 ]; then
echo "Bundle install faild. Exit code: ${ERRCHK}"
exit 1;
fi
#環境変数などの設定
echo Environment
export XXXXX_XXXXXX=xxxxxx
#テスト実行
echo test
RAILS_ENV=test; bin/rspec
ERRCHK=$?
if [ ${ERRCHK} -ne 0 ]; then
echo "RSpec Test faild. Exit code: ${ERRCHK}"
exit 1;
fi
Jobの実行
最終的に成功して終了しました。
Finished in 5 minutes 9 seconds (files took 12.22 seconds to load)
414 examples, 0 failures, 13 pending
Coverage report generated for RSpec to /home/pipeline/0c6813c0-71a3-4f0d-be6c-d1ad25af23f1/coverage. 1726 / 1877 LOC (91.96%) covered.
Finished: SUCCESS
環境変数が正しく設定されていなかったり、PostgreSQLが起動される前にテストが走ってしまtたりして、つまづくことがありました。
また、Docker for mac上でも、同じイメージを利用してコンテナーを起動・ソースコードをコンテナーにコピー・テストを実行することで、RspecUnitTestを行うことができました。
Author And Source
この問題について(【カスタム Docker イメージ】コンテナー上でRspec UnitTest), 我々は、より多くの情報をここで見つけました https://qiita.com/ymy_s/items/391aed3f7a88a3fa8f89著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .