メニュー
本ハンズオンのゴール
- 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
# コメントです # ハンズオン内で実行するコマンドです(コピー&ペーストで貼り付けて利用して下さい) command "foo" "bar"
以下、出力例の表示です。
output
# コマンドの実行後の出力例です foo bar
上記に実行例と異なる出力を確認した場合にはお声がけ下さい。
事前準備について
- ハンズオンを円滑に進めるにあたって事前準備は出来るだけ行うようにして下さい
資料内で紹介する各種ツールのバージョンについて
資料内で紹介する各種ツールのバージョンは以下の通りです。
- OS
output
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 14.04.4 LTS Release: 14.04 Codename: trusty
- Ruby
output
$ ruby -v ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
- Serverspec
output
$ bundle exec gem list | grep serverspec serverspec (2.36.0)
- Infrataster
output
$ bundle exec gem list | grep infrataster infrataster (0.3.2)
- Docker Engine
output
$ 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
参考書籍
ハンズオン資料
ハンズオン教材
https://github.com/inokappa/handson-serverspec
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_spec.rb
# 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
を選択した場合)
spec_helper.rb
require 'serverspec' set :backend, :exec
2.3. リソースタイプ
- リソースタイプ = テスト対象の種類
- リソース = テスト対象
example_spec.rb
# 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
を実行する。
command
cd ~/handson-serverspec/ mkdir first_test cd first_test bundle exec serverspec-init
以下のように spec ファイルの雛形や spec_helper.rb や Rakefile を生成される。(OS type
と backend type
を選択する)
output
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 を以下のように書き換える。
spec/localhost/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. テスト実行
以下のようにテストを実行する。
command
bundle exec rake
以下のように出力されることを確認する。
output
(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 を確認する。
command
cd ~/handson-serverspec cat docker/Dockerfile
以下のように出力されることを確認する。
output
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 ファイルを確認する。
command
cd ~/handson-serverspec cat spec/docker_dockerfile_spec.rb
以下のように出力されることを確認する。
output
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. テスト
以下のコマンドを実行してテストを実行する。(初めて実行する場合にはコンテナのビルドが走るので時間が掛かるので気長に待つ)
command
cd ~/handson-serverspec bundle exec rspec spec/docker_dockerfile_spec.rb
以下のように出力されることを確認する。
output
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 ファイルを確認する。
command
cd ~/handson-serverspec cat spec/docker_site_spec.rb
以下のように出力されることを確認する。
ruby
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. テスト
以下のコマンドを実行してテストを実行する。
command
cd ~/handson-serverspec bundle exec rspec spec/docker_site_spec.rb
以下のように出力されることを確認する。
output
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 のテストと一気通貫でテストする
以下のコマンドを実行してテストを実行する。
command
cd ~/handson-serverspec bundle exec rspec spec/docker_*_spec.rb
以下のように出力されることを確認する。
output
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 サイトの振る舞いをテスト
ハンズオンで利用したリソースの削除
- 本日作成した仮想マシンはハンズオン終了後、不要であれば削除しておきましょう
「Serverspec ハンズオン資料(Jenkins おじさんお届け編)」に続く…