Infratasterで社内の難解プロジェクトの仕様を把握してみた

渋谷.rbのFacebookページ徘徊してて、とてもよさそうなテストフレームワークあったので使ってみました。

ryotarai/infrataster https://github.com/ryotarai/infrataster

Serverspecが完全にサーバの状態テストなのに対して、こちらは状態テストよりもアプリケーションレイヤ重点にテストしてくれるものっぽいです。

で、最近担当することになった、ストレージを持たない構成的には簡素なプロジェクトがあるんですが、処理が非常に難解で、ドキュメント読んでもチンプンカンプンな状態に陥っております。

このドメインでこのパラメータ、このクッキーでアクセスくると、こういう処理をして・・・という処理が何パターンもあるうえ、テストが全くないという状態です。

そこで、自身の理解を深めると同時に唯一のテストを入れるために使ってみました。

serverspec-initと違い、特にイニシャライザ用意されてないのでGemfile作ってrspec --initすれば基本構成は出来上がります。

Gemfileはこんな感じ。

RSpecに関しては、個人的にexpect記法が好かないのでワンライナーshould記法使ってます。rspec-itsはそれによるものです。

source 'https://rubygems.org/'

gem 'infrataster'
gem 'rspec-its'

spec_helperはこんな感じで。

require 'infrataster/rspec'
require 'rspec/its'

RSpec.configure do |c|
  c.expose_current_running_example_as :example
end

Infrataster::Server.define(
  :app01,
  '192.168.100.10',
  vagrant: false
)

公式だとネットワークアドレス書いてますけど、同じサブネットに色んなプロジェクトのサーバあるので、個別IP指定してます。。。

あとは通常通りRSpecかけばおk

describe server(:app01) do
  context 'without cookie' do
    context 'without parameter' do
      describe http('http://tekitouna.domain:3000/hoge/') do
        subject { response }
        its(:status)  { should eql 200 }
        its(:body)    { should include "BODY" }
        its(:headers) { should_not include 'set-cookie' }
        its(:headers) { should_not include 'location' }
      end

      describe http('http://tekitouna.domain:3000/fuga/') do
        subject { response }
        its(:status)  { should eql 200 }
        its(:body)    { should include "BODY" }
        its(:headers) { should_not include 'location' }
        describe 'response.headers["set-cookie"]' do
          subject { response.headers["set-cookie"] }
          it { should match /DATA=[0-9a-f]{36}; Domain=.tekitouna.domain;/ }
        end
      end
    end
  end
end

あとは仕様書を元にツラツラと書いて完成です。 条件によってはsuit文全く同じなところもあるので、外出ししようかと思ってみたりしました。

あと、httpリソースのところなんですが、ドメインにしたところ、ヘッダのHostに入れてくれるようで、「インターナルでは3000ポートなんだけど、LBからフォワードしてるんだ」みたいなケースだとポート書かないとConecction Refuseされちゃうようです。

個人的に書いてて思ったのは、このテストがパスされなければLBにぶら下げないという、最終確認的な使い方になりそうだなーと思いました。 capybaraリソースとかもあるので、「リリースしたらエラーで真っ白になりました」を避ける事が出来そう。

ということで、テストがないプロジェクトが一つ減りました。めでたしめでたし。 (オンプレのJenkinsでCI予定です)