Edited at

serverspecでWindowsのテストをお試しする

More than 3 years have passed since last update.

お仕事でWindowsサーバをserverspecでテストしたい!という要件があり、ご自宅のWindows PCで色々と実験するための環境を作ってみた。


動作環境

ご自宅にはマトモな環境が無いので、WindowsマシンをホストOSにして、VirtualBoxでLinuxのゲストOSを作った。ゲストOSでserverspecを実行し、リモートでホストOSをテストできるようにする。


  • ホストOS(テスト対象ホスト)


    • OSはWindows7 Home Premium

    • ゲストOS用にVirtualBox 4.3.2をインストール



  • ゲストOS(serverspec実行環境)


    • テスト対象ホストのVirtualBoxで動作。ネットワーク設定は以下の通り。


      • アダプター1はNAT

      • アダプター2はホストオンリーアダプター



    • OSはCentOSで、事前にRubyがインストールされている。バージョンは以下の通り。


      • CentOS 6.3

      • Ruby 2.0.0p481






serverspecの設定を行う

serverspec実行環境にserverspecをインストールする。

まずはserverspec用のディレクトリを作る。

$ mkdir serverspec

$ cd serverspec

Gemfileにserverspec等、必要なgemを書いてインストールする。

Windowsホストをリモートでテストする為に、winrmもインストールする。

$ vi Gemfile

$ cat Gemfile
source 'https://rubygems.org'

gem 'serverspec'
gem 'rake'
gem 'winrm'
$ bundle install --path=vendor/bundle

serverspec-initコマンドを実行し、設定のひな型を作成する。

OS typeに「Windows」、backend typeに「WinRM」を選択する。

bundle exec serverspec-init

Select OS type:

1) UN*X
2) Windows

Select number: 2

Select a backend type:

1) WinRM
2) Cmd (local)

Select number: 1

+ spec/
+ spec/localhost/
+ spec/localhost/httpd_spec.rb
+ spec/spec_helper.rb
+ Rakefile

動く事が確認出来れば良いので、とりあえずホスト名をテストするシナリオを作成する。

※デフォで作成されるhttpd_specは、邪魔だったので一旦削除した。

$ vi spec/localhost/host_spec.rb

$ cat spec/localhost/host_spec.rb
require 'spec_helper'

describe command('hostname') do
its(:stdout) { should match /Win-PC/ }
end

serverspecの設定はひとまずここで完了。


テスト対象ホストでWinRMを設定する。

WinRM(Windows Remote Management)は、HTTP/HTTPSでコンピュータをリモート管理するプロトコルで、serverspecからリモートのWindowsホストをテストする際も、WinRMでアクセスしてテストするのが一般的らしい。

まずは、管理者権限でpower shellを起動する。

「アクセサリ」->「Windows PowerShell」->「Windows PowerShell」を右クリックして「管理者として実行」をクリックし起動する。

以下のコマンドを発行し、WinRMの初期設定を行う。

PS C:\windows\system32> winrm qc

WinRM はこのコンピューター上で要求を受信するように設定されていません。
次の変更を行う必要があります:

WinRM サービスを開始します。

変更しますか [y/n]? y

WinRM は要求を受信するように更新されました。

WinRM サービスが開始されました。
このコンピュータ上のあらゆる IP への WS-Man 要求を受け付けるため、HTTP://* 上に WinRM リスナを作成します。

変更しますか [y/n]?

WinRM はリモート管理用に更新されました。

WinRM サービスの種類を正しく変更できました。
WinRM サービスが開始されました。
このコンピュータ上のあらゆる IP への WS-Man 要求を受け付けるため、HTTP://* 上に WinRM リスナを作成しました。

接続ネットワークに、PrivateもしくはDomain以外のものが存在する場合、以下のエラーが発生する。今回はVirtualBox Host-Only Networkが「識別されていないネットワーク」になっていた為、このエラーでハマってしまった。

Set-WSManQuickConfig : このコンピューターのネットワーク接続の種類の 1 つが Public に設定されているため、WinRM ファイアウォール例外は機能しません。 

ネットワーク接続の種類を Domain または Private に変更して、やり直してください。

ローカル・セキュリティ・ポリシー等で設定可能なようだが、Windows7がHome Premiumである為使えず。。。なので、以下リンクの通りレジストリを修正して対応する。

http://27213143.at.webry.info/201207/article_1.html

次にBasic認証と暗号化していないメッセージを受けるけるよう設定する。

この設定を行っていないと、テスト実行時に401エラーが出てテストがfailになる。

PS C:\windows\system32> winrm set winrm/config/service/auth '@{Basic="true"}'

Auth
Basic = true
(略)
PS C:\windows\system32> winrm set winrm/config/service '@{AllowUnencrypted="true"}'
Service
(略)
AllowUnencrypted = true
(略)

serverspec用のユーザーを作成する。コントロールパネルのユーザーアカウントから管理者権限をつけたユーザーを作成。

これでWinRMの設定は完了。


serverspecを実行する。

実行する前に、ユーザー情報をspec_helper.rbに設定する。

$ vi spec/spec_helper.rb

$ cat spec/spec_helper.rb
require 'serverspec'
require 'winrm'

set :backend, :winrm

user = '(WIndowsユーザー名)'
pass = '(パスワード)'
endpoint = "http://#{ENV['TARGET_HOST']}:5985/wsman"

winrm = ::WinRM::WinRMWebService.new(endpoint, :ssl, :user => user, :pass => pass, :basic_auth_only => true)
winrm.set_timeout 300 # 5 minutes max timeout for any operation
Specinfra.configuration.winrm = winrm

テストを実行する。テスト通った。

bundle exec rake spec

/usr/local/rvm/rubies/ruby-1.9.3-p448/bin/ruby -S rspec spec/localhost/host_spec.rb
.

Finished in 0.64601 seconds
1 example, 0 failures

これでWindowsサーバのテストシナリオの実装が捗るぜ!