メニュー
本ハンズオンのゴール
- Serverspec で提供される各種バックエンドを試してみます
- Docker バックエンドを利用して Dockerfile のテストを作成し、テストを行います
- Infrataster を利用して Web サイトの振る舞いのテストを行います
- おまけで Jenkins を利用してテスト、Docker Hub へのコンテナイメージの自動化も行います
注意
- 資料の見方
- 事前準備について
- 資料内で紹介する各種ツールのバージョンについて
- 後片付けはしっかりと
参考資料
- 参考 URL
- 参考書籍
- ハンズオン資料
- ハンズオン教材
2. テストコードの書き方
2.1. Rspec とは
2.2. spec_helper.rb
2.3. Resouce Type
2.4. テストを書いてみよう
3. Docker バックエンドを利用して Dockerfile をテストする
3.1. バックエンドとは
3.2. 要件
3.3. テストを書く
3.4. 初めてのテスト
3.5. Dockerfile の作成
3.6. テスト
4. Infrataster サイトの振る舞いをテストする
4.1. Infrataster とは
4.2. Infrataster のセットアップ
4.3. 要件
4.4. テストを書く
4.5. 初めてのテスト
4.6. テスト
5. まとめ
- 今日やったこと
- ハンズオンで利用したリソースの削除
本ハンズオンのゴール
- Serverspec で提供される各種バックエンドを試してみます
- Docker バックエンドを利用して Dockerfile のテストを作成し、テストを行います
- Infrataster を利用して Web サイトの振る舞いのテストを行います
注意
資料の見方
以下、実行するコマンドの表示です。
# コメントです
# ハンズオン内で実行するコマンドです(コピー&ペーストで貼り付けて利用して下さい)
command "foo" "bar"
以下、出力例の表示です。
# コマンドの実行後の出力例です
foo
bar
上記に実行例と異なる出力を確認した場合にはお声がけ下さい。
事前準備について
- ハンズオンを円滑に進めるにあたって事前準備は出来るだけ行うようにして下さい
資料内で紹介する各種ツールのバージョンについて
資料内で紹介する各種ツールのバージョンは以下の通りです。
- OS
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.4 LTS
Release: 14.04
Codename: trusty
- Ruby
$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
- Serverspec
$ bundle exec gem list | grep serverspec
serverspec (2.36.0)
- Infrataster
$ bundle exec gem list | grep infrataster
infrataster (0.3.2)
- Docker Engine
$ docker version
Client:
Version: 1.11.2
API version: 1.23
Go version: go1.5.4
Git commit: b9f10c9
Built: Wed Jun 1 21:47:50 2016
OS/Arch: linux/amd64
Server:
Version: 1.11.2
API version: 1.23
Go version: go1.5.4
Git commit: b9f10c9
Built: Wed Jun 1 21:47:50 2016
OS/Arch: linux/amd64
後片付けはしっかりと
本日作成した仮想マシンはハンズオン終了後、不要であれば削除しておきましょう。
参考資料
参考 URL
- http://serverspec.org/
- http://web-k.github.io/blog/2012/09/27/rspec_basic/
- http://qiita.com/jnchito/items/42193d066bd61c740612
参考書籍
ハンズオン資料
ハンズオン教材
2. テストコードの書き方
2.1. Rspec(Serverspec を始めるあたって知っておきたい Rspec の入り口の入り口)
2.1.1. Rspec とは
- Ruby で実装されたポピュラーなテストフレームワーク(他には Test::Unit という標準で組み込まれているフレームワークもある)
- 英語っぽくテストを書くことが出来る
2.1.2. Rspec の基本
- テストファイルを spec ファイルと呼ぶ
- it で始める部分が example(テスト)となる
- describe do ~ end で囲まれた部分を example グループと呼ぶ
- 期待値と実際の値を比較した結果をかえすオブジェクトをマッチャ(抹茶ではない)と呼ぶ
2.1.3. spec ファイル例
Serverspec で利用する spec ファイルの例。
# example グループ
describe package('httpd') do
# example
# - should = べきである
# - be_installed = マッチャ
it { should be_installed }
end
# 日本語に訳すと
# パッケージ "httpd" について
# それは(it)インストールされている(be_installed)べき(should)
# である
# example グループ
describe command('ls -al /') do
# example
# - match = マッチャ
its(:stdout) { should match /bin/ }
end
# 日本語に訳すと
# コマンド "ls -al /" について
# その出力(its(:stdout))は "bin" にマッチ(match)でするべき(should)
# である
※ should
の部分を expect
(いくすぺくと)メソッドに置き換えることが出来るが、本資料では should
メソッドを利用する
2.2. spec_helper.rb
Rspec の挙動を制御する為に利用されるファイルで Serverspec でも利用される。Serverspec では serverspec-init
を実行すると以下のような内容となっている。(バックエンドを Exec
を選択した場合)
require 'serverspec'
set :backend, :exec
2.3. リソースタイプ
- リソースタイプ = テスト対象の種類
- リソース = テスト対象
# interface がテスト対象となるリソースタイプ
# interface('eth0') がテスト対象となるリソース
describe interface('eth0') do
its(:speed) { should eq 1000 }
end
Serverspec で扱えるリソースタイプについては、以下の URL に掲載されているので必要に応じて確認する。
2.4. テストを書いてみよう
2.4.1. テスト要件
- OS のバージョンは Ubuntu 14.04 であることを確認する
- docker-engine がインストールされていることを確認する
- docker-engine 起動していることを確認する
- docker のバージョンを確認する
- Ruby や servespec や infrataster がインストールされていることを確認する
2.4.2. serverspec-init
serverspec-init
を実行するとテストに必要な各種ファイルや spec ファイルの雛形を生成されるので、以下のように serverspec-init
を実行する。
cd ~/handson-serverspec/
mkdir first_test
cd first_test
bundle exec serverspec-init
以下のように spec ファイルの雛形や spec_helper.rb や Rakefile を生成される。(OS type
と backend type
を選択する)
Select OS type:
1) UN*X
2) Windows
Select number: 1 #=> 1 を選択
Select a backend type:
1) SSH
2) Exec (local)
Select number: 2 #=> 2 を選択
+ spec/
+ spec/localhost/
+ spec/localhost/sample_spec.rb
+ spec/spec_helper.rb
+ Rakefile
+ .rspec
2.4.3. テストを書く
テスト要件に基いて、sample_spec.rb を以下のように書き換える。
require 'spec_helper'
describe "OS のバージョンは Ubuntu 14.04 であることを確認する" do
describe command("lsb_release -a") do
its(:stdout) { should match /Ubuntu 14.04/ }
end
end
describe "docker-engine がインストールされていることを確認する" do
describe package('docker-engine'), :if => os[:family] == 'ubuntu' do
it { should be_installed }
end
end
describe "docker-engine 起動していること / docker のバージョンを確認する" do
describe service('docker'), :if => os[:family] == 'ubuntu' do
it { should be_running }
end
describe command("docker version") do
its(:stdout) { should match /1.11.2/ }
end
end
describe "Ruby や servespec / infrataster がインストールされていることを確認する" do
it "インストールされている Ruby のバージョンは 2.3.1 である" do
expect(check_ruby_version).to include("2.3.1")
end
it "Serverspec がインストールされている" do
expect(check_packages("serverspec")).to include("serverspec")
end
it "Infrataster がインストールされている" do
expect(check_packages("infrataster")).to include("infrataster")
end
def check_ruby_version
command("ruby -v").stdout
end
def check_packages(package)
command("bundle exec gem list | grep #{package}").stdout
end
end
2.4.4. テスト実行
以下のようにテストを実行する。
bundle exec rake
以下のように出力されることを確認する。
(snip)
OS のバージョンは Ubuntu 14.04 であることを確認する
Command "lsb_release -a"
stdout
should match /Ubuntu 14.04/
docker-engine がインストールされていることを確認する
Package "docker-engine"
should be installed
docker-engine 起動していること / docker のバージョンを確認する
Service "docker"
should be running Command "docker version" stdout
should match /1.11.2/
Ruby や servespec / infrataster がインストールされていることを確認する
インストールされている Ruby のバージョンは 2.3.1 である
Serverspec がインストールされている
Infrataster がインストールされている
Finished in 0.68314 seconds (files took 0.31922 seconds to load)
7 examples, 0 failures
実際の出力画面は以下のように表示される。
3. Docker バックエンドを利用して Dockerfile をテストする
3.1. バックエンドとは
3.1.1. バックエンドとは
- Serverspec(実際には Specinfra)では核となる部分
- ざっくり言うと...実行形式の違いを意識することなくコマンドを実行することが出来るレイヤー
- テスト対象ホスト OS に応じたコマンドをバックエンドに応じた実行形式で実行する
3.1.2. バックエンドの種類
以下のようなバックエンドが利用出来る。
- exec
- ssh
- powershell
- cmd
- docker
- lxc
- winrm
- shell_script
- dockerfile
- telnet
3.2. 要件
以下のような要件の Docker コンテナ作ってテストしたい。
- Web アプリケーションコンテナ
- Web サーバーは Apache
- コンテンツは静的な index.html 一枚
3.3. Dockerfile の作成
以下のコマンドを実行して作成済みの Dockerfile を確認する。
cd ~/handson-serverspec
cat docker/Dockerfile
以下のように出力されることを確認する。
FROM ubuntu:14.04
RUN apt-get update && \
apt-get install -y apache2 && \
mkdir /var/run/apache2 && \
mkdir /var/lock/apache2
ADD index.html /var/www/html/
EXPOSE 80
env APACHE_RUN_USER www-data
env APACHE_RUN_GROUP www-data
env APACHE_PID_FILE /var/run/apache2.pid
env APACHE_RUN_DIR /var/run/apache2
env APACHE_LOCK_DIR /var/lock/apache2
env APACHE_LOG_DIR /var/log/apache2
env LANG C
CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]
3.4. テストの作成
以下のコマンドを実行して作成済みの spec ファイルを確認する。
cd ~/handson-serverspec
cat spec/docker_dockerfile_spec.rb
以下のように出力されることを確認する。
require "serverspec"
require "docker"
describe "Dockerfile Check" do
#
# 最初に一度だけ実行される
#
before(:all) do
image = Docker::Image.build_from_dir('./docker/')
set :os, family: :debian
set :backend, :docker # Serverspec の Docker バックエンドを利用してテスト
set :docker_image, image.id
end
describe command("lsb_release -a") do
its(:stdout) { should match /Ubuntu 14/ }
end
describe package("apache2") do
it { should be_installed }
end
describe process("apache2") do
it { should be_running }
end
describe port(80) do
it { should be_listening }
end
describe file("/var/www/html/index.html") do
it { should exist }
its(:content) { should match /I love mentai.co/ }
end
end
3.5. テスト
以下のコマンドを実行してテストを実行する。(初めて実行する場合にはコンテナのビルドが走るので時間が掛かるので気長に待つ)
cd ~/handson-serverspec
bundle exec rspec spec/docker_dockerfile_spec.rb
以下のように出力されることを確認する。
Dockerfile Check
Command "lsb_release -a"
stdout
should match /Ubuntu 14/
Package "apache2"
should be installed
Process "apache2"
should be running
Port "80"
should be listening
File "/var/www/html/index.html"
should exist
content
should match /I love mentai.co/
Finished in 0.4776 seconds (files took 0.35406 seconds to load)
6 examples, 0 failures
4. Infrataster サイトの振る舞いをテストする
4.1. Infrataster とは
- https://github.com/ryotarai/infrataster
- インフラの外部から各種リソースの振る舞いをテストするツール
- Web サイトや DNS クエリ、Redis や memcacned の振る舞いをテストすることが出来る
4.2. 要件
前のステップ(3. Docker バックエンドを利用して Dockerfile をテストする)さ作成した Docker コンテナサイトに対して以下ようなテストを行いたい。
- HTTP レスポンスコード 200 が返ってくること
- HTTP レスポンスヘッダ
Content-Type
はtext/html
が含まれていること - HTTP レスポンスボディ に
I love menti.co
が含まれていること
4.3. テストを書く
以下のコマンドを実行して作成済みの spec ファイルを確認する。
cd ~/handson-serverspec
cat spec/docker_site_spec.rb
以下のように出力されることを確認する。
require "infrataster/rspec"
#
# Infrataster のテストで利用するコンテナを用意する定義
# - コンテナをビルドする
# - コンテナを起動する(コンテナを作成して start する)
# - コンテナの IP アドレスを取得する
#
image = Docker::Image.build_from_dir("./docker/")
container = Docker::Container.create("Image" => image.id)
container.start
ip = container.json["NetworkSettings"]["IPAddress"]
#
# テストの最後に実行される処理を定義
# - コンテナを削除する
#
RSpec.configure do |config|
config.after(:suite) do
container.delete(:force => true)
end
end
#
# Infrataster のサーバー定義
#
Infrataster::Server.define(:docker) do |s|
s.address = ip
end
#
# Infrataster によるサイトの振る舞いテスト
#
describe "Site Check" do
describe server(:docker) do
describe http("http://docker") do
it "responds as 'text/html'" do
expect(response.headers['content-type']).to match(%r{^text/html})
end
it "responds as '200'" do
expect(response.status).to be 200
end
it "responds as 'I love mentai.co'" do
expect(response.body).to include("I love mentai.co")
end
end
end
end
4.4. テスト
以下のコマンドを実行してテストを実行する。
cd ~/handson-serverspec
bundle exec rspec spec/docker_site_spec.rb
以下のように出力されることを確認する。
Site Check
server 'docker'
http 'http://docker' with {:params=>{}, :method=>:get, :headers=>{}}
responds as 'text/html'
responds as '200'
responds as 'I love mentai.co'
Finished in 0.0607 seconds (files took 0.6372 seconds to load)
3 examples, 0 failures
5.5. Dockerfile のテストと一気通貫でテストする
以下のコマンドを実行してテストを実行する。
cd ~/handson-serverspec
bundle exec rspec spec/docker_*_spec.rb
以下のように出力されることを確認する。
Site Check
server 'docker'
http 'http://docker' with {:params=>{}, :method=>:get, :headers=>{}}
responds as 'text/html'
responds as '200'
responds as 'I love mentai.co'
Finished in 0.0607 seconds (files took 0.6372 seconds to load)
3 examples, 0 failures
root@(none):~/handson-serverspec# bundle exec rspec spec/docker_*_spec.rb
Dockerfile Check
Command "lsb_release -a"
stdout
should match /Ubuntu 14/
Package "apache2"
should be installed
Process "apache2"
should be running
Port "80"
should be listening
File "/var/www/html/index.html"
should exist
content
should match /I love mentai.co/
Site Check
server 'docker'
http 'http://docker' with {:params=>{}, :method=>:get, :headers=>{}}
responds as 'text/html'
responds as '200'
responds as 'I love mentai.co'
Finished in 0.53204 seconds (files took 0.78807 seconds to load)
9 examples, 0 failures
5. まとめ
今日やったこと
- 簡単な spec ファイルを作成してテスト
- Docker バックエンドを利用して Dockerfile のテスト
- Infrataster を利用して Web サイトの振る舞いをテスト
ハンズオンで利用したリソースの削除
- 本日作成した仮想マシンはハンズオン終了後、不要であれば削除しておきましょう