Webアプリエンジニア養成読本 Advent Calendar 2014 20日目の記事です。
今日は、本に書ききれなかった内容について、第2弾です。
3.3節 P.114で、サーバの構築した状態をテストするツール「Serverspec」を紹介しましたが、ページ数の問題で使い方を説明しきれませんでした。そこで、今回は前回のエントリ「CentOS 7でWebアプリエンジニア養成読本のサンプルを動かしてみる(PHP編)」で構築したサーバが正しい状態に構築できているか、テストしてみます。
Serverspecを使えば、手動でテストをする時とは違い、設定変更や再構築・増設時にも自動かつ反復的にテストができるようになり、大変便利です。
今回は、「テスト計画の作成」「テストコードの作成」そして「テストの実施」に分けて書いて行きます。
テスト計画の作成
計画なくして、実行はできません。でも、言うは易し、行うは難し…ですね。実はここが一番難しいかもしれません。
Serverspecでテストする項目を作成するにあたって、最も簡単な方法は「手順」をベースにする事です。とはいえ、手順をそのままテストするのではなく、手順を通じて反映される状態とは何かをきちんと確認する事が重要です。
早速、前回のエントリで行った手順を棚卸ししてみましょう。
- MySQLのインストール
- MySQLをインストールしている
- MySQLを自動起動するようにしている
- MySQLが起動している
- MySQLが接続を待ち受けている(3306番で)
- MySQLにrootユーザでログインできる
- Apacheのインストール
- Apacheをインストールしている
- PHPをインストールしている
- PHPをインストールしている
- PHPの関連モジュールをインストールしている
- php.iniの設定を変更している
- Apacheを自動起動するようにしている
- Apacheを起動している
- Apacheが接続を待ち受けている(80番で)
- ルートディレクトリを取得した際にHTTP 200が返される
- Tinitterのデプロイ
- Tinitter用のMySQLユーザで接続できる
- ルートディレクトリを取得した際にTinitterと書かれたページが返される
多いでしょうか、少ないでしょうか。いずれにしても、上記は最低限確認する必要がある事がわかりました。
テストコードの作成
前提条件
作業前に、次の事柄を確認して下さい。
- テスト対象のサーバは、前回のエントリで構築したサーバです。CentOS 6に入れているサーバでもテスト可能かと思いますが、検証はしていません。
- 手元のマシン及びテスト対象のサーバに、先のムック 3.2節 P.115の「公開鍵認証」を設定して下さい。
- 手元のマシンにRubyをインストールしてください。インストールしていない方は、先のムック 2.8節 P.65以降を参考にして下さい。
Serverspec実行のための準備
テスト計画を基に、テストコードを作成しましょう。
次に、Serverspecをインストールします。次のコマンドを入力してください。
$ mkdir (コードを保存するディレクトリ) $ cd (コードを保存するディレクトリ) $ gem install bundler $ echo "gem 'rake'" >> Gemfile $ echo "gem 'serverspec'" >> Gemfile $ bundle install
Rubyさえ導入していれば、あっさり導入していただける事がわかるかと思います。
スケルトンの出力と接続設定
準備が終わりましたら、スクリプトを書く際に便利なスケルトンを出力します。例となるサーバのホスト名は”saito-hb-vm007″、IPアドレスは”192.168.29.107″とします。ここは、ご自身の環境に合わせて読み替えて下さい。
また、Serverspecを利用するにあたり、サーバに接続する際の情報を設定する必要があります。ここで、あわせて行います。
$ cd (コードを保存するディレクトリ) $ serverspec-init Select OS type: 1) UN*X 2) Windows Select number: 1 Select a backend type: 1) SSH 2) Exec (local) Select number: 1 Vagrant instance y/n: n Input target host name: saito-hb-vm007 + spec/ + spec/saito-hb-vm007/ + spec/saito-hb-vm007/sample_spec.rb + spec/spec_helper.rb + Rakefile $ vim ~/.ssh/sshd_config # 以下の通り編集
(.ssh/configの記述例)
Host saito-hb-vm007 HostName 192.168.29.107 User (任意のユーザ名)
以上で、スケルトンの出力と接続の準備が終わりました。
テストコードの作成
では、本題のテストコードの作成に入ります。
今回は、ページの文量上、既に僕が書いたコードを基に説明をします。ソースは GitHub – koemu/webapp_mook_servertest に保存しています。
ここでは、参考までにMySQLのテストを記述したmysql_spec.rbの冒頭を確認してみます。
require 'spec_helper' describe "MySQLのインストール" do describe "MySQLをインストールしている" do describe package("mysql-community-server") do it { should be_installed } end describe package("mysql-community-client") do it { should be_installed } end describe package("mysql-community-libs") do it { should be_installed } end describe package("mysql-community-common") do it { should be_installed } end end (中略) end
1行目は必ず書きます。
3, 5, 6のdescribeですが、3, 5行目はテストの内容を明確にするために階層化しています。実際は、6行目の階層のみでもテストは可能です。とはいえ、後でこのコードを読む人のために、わかりやすくしておく事は重要です。
6行目からが最も重要な部分です。ここでは、”mysql-community-server”パッケージについてテストをすると記述しています。そして、7行目で判定を行っています。これが、9, 12, 15行目のくくりで違うパッケージを対象にしてくり返されています。
何となく、わかりましたか?この後に続くそれぞれのリソースタイプの意味は、公式ドキュメント「Serverspec – Resource Types」で説明されています。ドキュメントと照らし合わせながら読み込んでみて下さい。
テストコードのダウンロード
取り急ぎ、テストを実行できるよう、僕の書いたコードをダウンロードして準備してしまいましょう。Windowsの方は、お手数ですがwgetではなくひとつひとつダウンロードしていただければと思います。
$ cd spec/[サーバのホスト名]/ $ wget https://raw.githubusercontent.com/koemu/webapp_mook_servertest/master/spec/saito-hb-vm007/httpd_spec.rb $ wget https://raw.githubusercontent.com/koemu/webapp_mook_servertest/master/spec/saito-hb-vm007/mysql_spec.rb $ wget https://raw.githubusercontent.com/koemu/webapp_mook_servertest/master/spec/saito-hb-vm007/tinitter_spec.rb $ cd ../../
テストの実施
実行!
たいへんおつかれさまでした。いよいよ、テストを実行してみましょう。作業ディレクトリの”Rakefile”があるディレクトリ(即ちルート)で、次のコマンドを実行して結果を確認してみて下さい。
$ SPEC_OPTS="--format documentation" bundle exec rake spec /Users/saito/.rbenv/versions/2.1.2/bin/ruby -I/Users/saito/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.7/lib:/Users/saito/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-support-3.1.2/lib /Users/saito/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.7/exe/rspec --pattern spec/saito-hb-vm007/\*_spec.rb Apacheのインストール Apacheをインストールしている Package "httpd" should be installed (中略) Finished in 1.49 seconds (files took 0.28415 seconds to load) 23 examples, 0 failures
どのようなテストが実施され、結果がどのようになっているかを確認していただけたかと思います。最後に”0 failures”と表示されていれば、成功です!おめでとうございます!!
テストが動かない?そんな時は!
辛い。動かない。そんな方もいたかと思います。代表的なトラブルと対策のポイントをお伝えします。
まず、こちらから。エラーメッセージは抜粋です。
/Users/saito/.rbenv/versions/2.1.2/bin/ruby -I/Users/saito/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.7/lib:/Users/saito/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-support-3.1.2/lib /Users/saito/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.7/exe/rspec --pattern spec/saito-hb-vm007/\*_spec.rb /Users/saito/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/net-ssh-2.9.1/lib/net/ssh.rb:219:in `start': Authentication failed for user root@192.168.29.107 (Net::SSH::AuthenticationFailed)
SSHの接続に失敗しています。~/.ssh/config に設定したSSHの接続先の設定を確認してみて下さい。または、sshコマンドを使って手動で接続できるかを確認しましょう。よーくエラーメッセージを読むと”AuthenticationFailed”書いてあるのがわかるかと思います。見つけるの、大変かも知れませんががんばって!
次は、こちら。エラーメッセージは抜粋です。
Failures: 1) Tinitterのデプロイ Tinitter用のMySQLユーザで接続できる Command "mysql -utinitter_user -ptinitter_pass tinitter -e "SELECT * FROM posts"" exit_status should eq 0 On host `saito-hb-vm007' Failure/Error: its(:exit_status) { should eq 0 } expected: 0 got: 1
MySQLの接続に失敗しています。テストコードに記載しているユーザ名・パスワードは、デフォルトです。ご自身で変更している場合は、編集をお願いします。または、サーバに対して適切に設定しているかを確認して下さい。後者であれば、Serverspecによるテストで作業の問題を見つけられた事を意味します。助かった!!
また、MySQLのテストの失敗と同様、一部の項目で失敗している事があるかもしれません。その時は、Serverspecを通じて、サーバ構築の適切な状態となっていない事を発見できた可能性が高いのです。テストの甲斐があった、と考えていただけたらいいかと思います!
他のエラーだった場合は…まずは自分でトラブルシューティングしてみて下さい。Rubyに詳しい方が身近にいれば、その方に支援をお願いするのも良いでしょう。
まとめ
Serverspecを使って、構築したサーバが正しい状態にあるかテストをする作業を、「テスト計画の作成」「テストコードの作成」そして「テストの実施」の3節に分けて紹介しました。
書いたプログラムにテストはあるのに、サーバ構築にはテストはないのか?という疑問が出るのは不思議ではありません。とはいえ、Serverspecが世に送り出されたのは2013年と比較的最近です。ありそうでなかった、そんなツールなのかも知れません。
ぜひ、業務でも活用いただけたらと思います!
最後にちょっとだけ宣伝です。
僕の現職の上司である @netmarkjp さんが、ITインフラの設計・構築・運用・そしてチューニングまでを体系的に解説した本を出します。特に、チューニングのための指標の読み方は多くの方に役立つものになると思います。ITインフラにお悩みの方、先のムックの内容より更に一歩進んでみたい方は、ぜひお買い求め下さい。
また、Webアプリエンジニア養成読本 Advent Calendar 2014では読者の皆様からの感想・実践エントリも大募集中です!ふるってご参加ください!!!
それでは皆様、ごきげんよう。
※大型書店で立ち読みしてみてね!