ã¤ã³ãã©é¨ã®èäºï¼@ryot_a_raiï¼ã§ãããã®è¨äºã§ã¯ã¤ã³ãã©ã®æ¯ãèããã¹ãã®ãã¼ã«ã§ããInfratasterã使ã£ã¦ãªãã¼ã¹ãããã·ã®è¨å®ã®ãã¹ãããã¦ã¿ããã¨æãã¾ãã
Infratasterã¨ã¯â¨
Infratasterã¯ã¤ã³ãã©ã®æ¯ãèãããã¹ããããã¬ã¼ã ã¯ã¼ã¯ã§ãRSpecã®ãã¹ããã«ãã¨ãã¦æ©è½ãã¾ããä¾ãã°ã
- ç¹å®ã®ãããä»ãã®HTTPãªã¯ã¨ã¹ããéä¿¡ããæã«ããã¬ã¹ãã³ã¹ããããè¿ã£ã¦ãããã¨ããã¹ããã
- Capybaraã使ã£ã¦å®éã®Webãã©ã¦ã¶ä¸ã§ã®æåããã¹ããã
- MySQLã®SHOW VARIABLESã®çµæããã¹ããã
ã¨ãã£ããã¨ãå¯è½ã«ãªãã¾ãã
ç´°ããæ¦è¦ã«ã¤ãã¦ã¯ãã¡ãã®ã¹ã©ã¤ããREADMEãã覧ãã ããã
Serverspecã¨ã®éã
ã¤ã³ãã©ã®ãã¹ãã¨ããã°Serverspecãæåãã¨æãã¾ãããInfratasterã¯Serverspecã¨ã¯ãã¹ãããé åãç°ãªã£ã¦ãã¾ããServerspecã¯ãµã¼ãã®å é¨ã®ããã«ã¦ã§ã¢ããã¡ã¤ã«ããã¹ããã¾ãããInfratasterã¯ãµã¼ãã®å¤é¨ãããã¹ãããã¾ããã¤ã¾ããInfratasterã¯ä¸ã§åãã¦ããããã«ã¦ã§ã¢ãä½ãã¯é¢ä¿ãªããå¤ããè¦ã¦ã©ããã£ãæ¯ãèããããããæ¤è¨¼ããããã®ãã®ã§ãã
Infratasterã使ã£ã¦nginxã®è¨å®ã®ãã¹ãããã
ä¸ã§ç´¹ä»ããInfratasterã¨ä»®æ³ãã·ã³ï¼Vagrant, VirtualBoxï¼ã使ã£ã¦nginxã®è¨å®ãæå³ããã¨ããè¡ããã¦ãããããã¹ããã¦ã¿ããã¨æãã¾ãã
æ¬è¨äºã®ã³ã¼ã㯠https://github.com/ryotarai/proxy-configtest-sample ã«ããã¾ãã
ä»®æ³ãã·ã³ãç¨æãã
Vagrantãã¤ãã£ã¦ãã¹ãç¨ã®ä»®æ³ãã·ã³ãç¨æãã¾ããVagrantã§ä»®æ³ãã·ã³ãèµ·åãã»ããã¢ãããããã¨ã§åç¾æ§ã®ãããã¹ãç°å¢ãç¨æãããã¨ãå¯è½ã«ãªãã¾ãã
VirtualBoxãVagrantãã¤ã³ã¹ãã¼ã«å¾ããããã·ç¨ãããã¯ã¨ã³ãç¨ã«1ã¤ãã¤Vagrant VMãç«ã¦ã¾ãããä»åã¯ãã¡ãã®Vagrantfileã使ãã¾ãããã®Vagrantfileã§ã¯ãproxy VMã«/etc/hostsãç½®ãã¦ãããã¯ã¨ã³ãã¸ã®ã¢ã¯ã»ã¹ãapp VMã«åãã¦ãã¹ããããããã¦ãã¾ãã
Vagrantfileãç½®ãããã¨ãvagrant up
ãå®è¡ãã¦ããã¾ãã
Infratasterãã¤ã³ã¹ãã¼ã«ãã
Infrataster, RSpecãGemã¨ãã¦ã¤ã³ã¹ãã¼ã«ãã¾ãã
# Gemfile source 'https://rubygems.org' gem 'infrataster' gem 'rspec-json_matcher'
rspecã³ãã³ãã使ã£ã¦ããã¹ãã«å¿ è¦ãªãã¡ã¤ã«ã®ã²ãªå½¢ãçæãã¾ãã
$ bundle exec rspec --init
Infratasterï¼ã¨rspec-json_matcherï¼ã使ãããã«ãçæãããspec/spec_helper.rbã®å é ã«ä»¥ä¸ã追è¨ãã¾ãã
require 'rspec/json_matcher' require 'infrataster/rspec' RSpec.configuration.include RSpec::JsonMatcher Infrataster::Server.define( :proxy, # name '192.168.0.0/16', # proxy VM's IP address vagrant: true # for vagrant VM )
200ãè¿ã£ã¦ãããã¨ããã¹ããã
æºåãã§ããã®ã§ããããã·ã«å¯¾ãããã¹ããæ¸ãã¦ã¿ã¾ããæå§ãã«ãhttp://foo.example.com
ã«ã¢ã¯ã»ã¹ããæã«200ãè¿ã£ã¦ãããã¨ããã¹ããã¾ãã
# spec/foo_spec.rb require 'spec_helper' describe server(:proxy) do describe http('http://foo.example.com') do it 'returns 200' do expect(response.status).to eq(200) end end end
ã¾ã nginxã®è¨å®ãæ¸ãã¦ããªãã®ã§ããã¹ãã¯å¤±æãã¾ãã
$ bundle exec rspec 1) server 'proxy' http 'http://foo.example.com' with {:params=>{}, :method=>:get, :headers=>{}} returns 200 Failure/Error: expect(response.status).to eq(200) Faraday::ConnectionFailed: Connection refused - connect(2) for "192.168.33.10" port 80
ãã¹ã対象ã®nginxã®è¨å®ãæ¸ãã¾ãã
# nginx/foo.conf server { listen 80; server_name foo.example.com; location / { proxy_pass http://app-001/; } }
ãã®ã¾ã¾ã ã¨proxy VMå ã§app-001ãåå解決ã§ããªãã®ã§ã/etc/hostsã§app VMã«åãã¾ãã
# Vagrantfile -hosts = %w!! +hosts = %w!app-001!
å度ãã¹ããèµ°ãããã¨ãéããã¨ã確èªã§ããã¨æãã¾ãã
$ vagrant provision $ bundle exec rspec server 'proxy' http 'http://foo.example.com' with {:params=>{}, :method=>:get, :headers=>{}} returns 200 Finished in 0.01166 seconds 1 example, 0 failures
æå³ãããã¹ãã«ãããã·ããã¦ãããããã¹ããã
ã¤ãã«ãæå³ãããã¹ãã«ãããã·ããã¦ãããããã¹ããã¦ã¿ã¾ããapp VMã®nginxã§X-MOCK-HOST
ããããã¤ããããã«ããã®ã§ãããã使ãã¾ããã¢ãã¯ç¨ã®ã¢ããªã¯ãªã¯ã¨ã¹ããããããã®ã¾ã¾JSONã«ãã¦è¿ãããã«ãªã£ã¦ããã®ã§ãã¬ã¹ãã³ã¹ããã¹ããããã¨ã§ãããã·âããã¯ã¨ã³ãã®ãªã¯ã¨ã¹ããããããã¹ããããã¨ãã§ãã¾ãã
--- a/spec/foo_spec.rb +++ b/spec/foo_spec.rb @@ -5,6 +5,12 @@ describe server(:proxy) do it 'returns 200' do expect(response.status).to eq(200) end + + it 'proxies to app-001' do + expect(response.body).to be_json_including({ + 'X_MOCK_HOST' => 'app-001', + }) + end end end
$ bundle exec rspec server 'proxy' http 'http://foo.example.com' with {:params=>{}, :method=>:get, :headers=>{}} returns 200 proxies to app-001 Finished in 0.01675 seconds 2 examples, 0 failures
ç¡äºããããã·å ã®ãã¹ãã®ç¢ºèªãã§ãã¾ããã
ã¬ã¹ãã³ã¹ãããããã¹ããã
ãããã·ã§Cache-Controlããããè¿ãããã«ãã¦ã¿ã¾ããå ã«ãã¹ããæ¸ãã¦ã失æããã¦ããè¨å®ãæ¸ãã¾ãã
--- a/spec/foo_spec.rb +++ b/spec/foo_spec.rb @@ -12,5 +12,11 @@ describe server(:proxy) do }) end end + + describe http('http://foo.example.com/isucon') do + it 'returns Cache-Control header' do + expect(response.headers['Cache-Control']).to eq('max-age=86400') + end + end end
$ bundle exec rspec 1) server 'proxy' http 'http://foo.example.com/isucon' with {:params=>{}, :method=>:get, :headers=>{}} returns Cache-Control header Failure/Error: expect(response.headers['Cache-Control']).to eq('max-age=86400') expected: "max-age=86400" got: nil (compared using ==) # ./spec/foo_spec.rb:18:in `block (3 levels) in <top (required)>'
nginxã®è¨å®ã追å ãã¾ãã
--- a/nginx/foo.conf +++ b/nginx/foo.conf @@ -1,6 +1,12 @@ server { listen 80; server_name foo.example.com; + + location /isucon { + expires 24h; + proxy_pass http://app-001/; + } + location / { proxy_pass http://app-001/; }
å度ãã¹ããå®è¡ããã¨ãé©åã«è¨å®ããã¦ãããã¨ã確èªã§ãã¾ãã
$ vagrant provision $ bundle exec rspec server 'proxy' http 'http://foo.example.com' with {:params=>{}, :method=>:get, :headers=>{}} returns 200 proxies to app-001 http 'http://foo.example.com/isucon' with {:params=>{}, :method=>:get, :headers=>{}} returns Cache-Control header
ã¾ã¨ã
Infratasterã使ã£ã¦ãªãã¼ã¹ãããã·ã®è¨å®ããã¹ãããæ¹æ³ãç´¹ä»ãã¾ãããæ¬è¨äºã§ã¯nginxãä¾ã«åºãã¾ããããApacheããã®ä»ã®ã½ããã¦ã§ã¢ã§ãåæ§ã«ãã¹ããããã¨ãã§ãã¾ãã
ãããã·ã®è¨å®ã¯å¾ã ã«è¤éåãã¦ãããæåãè¦ããªããªã£ã¦ãããã¡ã§ãããã¹ããæ¸ãã¦ããã°ãæå³ããªãæåã®å¤æ´ãé²ãããããã¹ãèªä½ãããã¥ã¡ã³ãã¨ãã¦ä½¿ããã¨ãã§ãã¾ãããã®è¨äºãInfratasterã使ã£ããã¹ãã®åèã«ãªãã°å¹¸ãã§ãã