ページ

2016年12月17日土曜日

DockerのテストをServerSpec+CircleCIでやる



Dockerfileで作成したimageをテストしてみたいと思います。
ServerSpecとCircleCIを使います。
サンプルとして作成するimageはAndroidがビルドできる環境のimageを作成します。

最終的な構成


↓の構成でリポジトリを作成します。
.
├── circle.yml
├── run-tests.sh   # 各imageのテストを実行
├── android        # image毎にサブディレクトリを作成
│   ├── Dockerfile
│   ├── docker-build.sh # docker build用のスクリプト
│   └── spec
│       ├── Gemfile
│       └── spec
│           ├── android_docker_spec.rb
│           └── spec_helper.rb
├── xxxxxxx
│
リポジトリのRootにcircle.ymlがあり、各image毎にサブディレクトリを
作成し、テストの時はリポジトリ配下にある全imageをテストします。

Androidビルド環境image


まずはAndroidビルド環境用のDockerfileを作成
# Image for android dev.
#
FROM java:openjdk-8-jdk
ENV HOME_DIR /usr/local
WORKDIR $HOME_DIR

# Update packages.
RUN apt-get update && apt-get -y install sudo

# Install wget for download android sdk.
RUN sudo apt-get -y install wget

RUN sudo apt-get -y install lib32stdc++6 lib32z1

# Download android sdk.
RUN wget http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
RUN tar zxvfo android-sdk_r24.4.1-linux.tgz
RUN rm -rf android-sdk_r24.4.1-linux.tgz

# Environment variables
ENV ANDROID_HOME /usr/local/android-sdk-linux
ENV PATH $ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$PATH

RUN echo y | android update sdk --no-ui --all --filter "android-23,build-tools-25.0.0"
RUN echo y | android update sdk --no-ui --all --filter "extra-android-m2repository"
やってる事はAndroid SDKをダウンロードし、ANDROID_HOMEの環境変数を設定
最後にplatformとbuild-tools、supportライブラリをダウンロードしています。
ビルド用のスクリプトを用意しておきます。
#!/usr/bin/env bash
# Build docker image for Circle CI

docker build -t slowhand/android:1.0 .
imageの名前は好きな名前で。
試しにスクリプトを実行させてみてimageができていればOKです。

Spec


ここからテストを作成していきます。
今回はserverspecを使うのでGemfileを用意します。
source "https://rubygems.org"

gem "docker-api"

group :test do
  gem 'specinfra', '2.12.7'
  gem 'serverspec'
end
serverspecでDockerを扱うdocker-apiも入れておきます。
次にspec_helper.rbと実際のテストコードを記述するandroid_docker_spec.rbです
  • spec_helper.rb
    # encoding: utf-8
    require 'docker'
    require 'serverspec'
    
    set :backend, :docker
    set :docker_url, ENV['DOCKER_HOST']
    set :docker_image, 'slowhand/android:1.0'
    
    Excon.defaults[:ssl_verify_peer] = false
  • android_docker_spec.rb
    # encoding: utf-8
    require 'spec_helper'
    
    if ENV['CIRCLECI']
      class Docker::Container
        def remove(options={}); end
        alias_method :delete, :remove
      end
    end
    
    %w(wget lib32stdc++6 lib32z1).each do |pkg|
      describe package(pkg) do
        it { should be_installed }
      end
    end
    
    describe file('/usr/local/android-sdk-linux') do
      it { should be_directory }
    end
    
    describe command('env') do
      its(:stdout) { should match /ANDROID_HOME/ }
    end
    ↑の通りですが、 wget lib32stdc++6 lib32z1のインストール確認と
    $ANDROID_HOMEのパスと環境変数の確認をテストしています。

CircleCI


最後にcircle.ymlとテストを起動させるスクリプトです。
  • circle.yml
    machine:
      services:
        - docker
    
    dependencies:
      override:
        - docker info
    
    test:
      override:
        - ./run-tests.sh
    ↑ではテスト時にrun-tests.shを起動するだけのシンプルなものです。
  • run-tests.sh
    #!/usr/bin/env bash
    
    WORKDIR=$PWD
    
    # Find target directory.
    for entity in `find . -type d -mindepth 1 -maxdepth 1 -not -name ".git"`; do
      # Only exist spec directory.
      if [ -e $entity/spec ]; then
        # Build docker image.
        cd $entity
        ./docker-build.sh
    
        cd spec
        # Install gems via bundler.
        bundle install --path vendor/bundle
        bundle exec rspec
        cd $WORKDIR
      fi
    done
    少し込み入ってますが、image用のサブディレクトリ内にspecディレクトリがあれば
    中に入ってテストを実行しています。

ここまでくれば、あとはpushすればCIが動作しテストを行ってくれます。
こちらで公開してますので宜しかったらどうぞ。

0 件のコメント:

コメントを投稿