LoadBalancerのspecは、あるリクエストに対して、期待するレスポンスを返すか という表現では不十分である。実際にnodeにリクエストが到達するか ということを表現しなければいけない。そこで、LbspecというRSpecのMatcherを作った。これを使うと、LoadBalancerがnodeにリクエストを転送することをRSpecの書式で表現できる。
これでLoadBalancerもRSpecで定義できるはず。。
リンク
Installation
Gemfileに書く:
gem 'lbspec'
bundlerを実行する:
$ bundle
もしくはgem installする:
$ gem install lbspec
Requires
- nodeにsshで入れる(~/.ssh/configなどで定義されている)
Usage
こんな感じで spec_helper.rb
で require lbspec
する:
# spec/spec_helper.rb
require 'rspec'
require 'lbspec'
あとはSpecを記述する:
require_relative 'spec_helper'
describe 'vhost_a' do
it { should transfer('node_a') }
end
describe 'vhost_b' do
it { should transfer(['node_b','node_c']) }
end
describe 'vhost_c:80' do
it { should transfer(['node_b','node_c']).port(80) }
end
describe 'vhost_c:80' do
it { should transfer(['node_b','node_c']).port(53).udp }
end
describe 'vhost_c:80' do
it { should transfer('node_c').http.path('/test/') }
end
describe 'vhost_c:443' do
it { should transfer(['node_b','node_c']).port(80).https.path('/test/') }
end
How it works
#transfer
- nodeにsshでログインする
- nodeでprobeをキャプチャーする
- probeを使ってリクエストを投げる(or パケットを投げる)
- nodeにprobeが来ているかで判定する
ここで、nodeではコマンドを実行しているだけなので、nodeに特別なプログラムを入れる必要はない。(ngrepとかtcpdumpが簡単かもしれないが、access.logをgrepするのほうが簡単かもしれない。)
Configuration
#transfer
キャプチャとリクエストを投げる方法はカスタマイズできる。なので、キャプチャ方法を定義して、自分で投げたいリクエストを生成できる。
RSpec.configuration.lbspec_capture_command =
lambda do |port, prove|
port_str = port > 0 ? "port #{port}" : ''
"sudo ngrep #{prove} #{port_str} | grep -v \"match:\""
end
RSpec.configuration.lbspec_https_request_command =
lambda do |addr, port, path, prove|
uri = 'https://' + "#{addr}:#{port}#{path}?#{prove}"
system("curl -o /dev/null -sk #{uri}")
end
カスタマイズできるのは次のコマンド。
lbspec_capture_command
with|port, prove|
lbspec_udp_request_command
with|addr, port, prove|
lbspec_tcp_request_command
with|addr, port, prove|
lbspec_http_request_command
with|addr, port, path, prove|
lbspec_https_request_command
with|addr, port, path, prove|