27493
Serverspec で数値の範囲指定がしたいのですが、上手くいきません

  * 当方環境 
    * serverspec-2.31.0
    * ruby 2.2.3p173

要件としては  
**_config fileにある設定値に対し、あいまいな値によるテストがしたい_**  
です。

  * 例 
    1. php-fpmのpool configに以下の設定がある  
`start_servers = 10`

    2. start_serversの値が 9以上20以下だったらTestをpassにしたいなど

file resource typeにはそのような判定機能がありません

そこでcommand resource typeを使い戻り値を Rspecの be_within + of
による範囲指定(あいまいな検査)でTestを行おうと考えましたが、上手くいきませんでした

`its(:stdout) { should be_within(9.0).of(20.0) }`  
とか  
`expect(:stdout).to be_within(9.0).of(20.0)`  
とか書いても  
`:stdout` に当然Symbolで返ってきていて、String型で 10\nが入っています  
それをCast (明示的な型変換)をしても0になってしまいます  
(inspect.to_f or {to_s,inspect}.to_f などしても 0になってしまう)

また、start_with().and end_with()で指定しても成功しませんでした

```

    describe command("awk '\$1~/start_servers/{ print \$3}' /etc/php-fpm.d/#{ENV['PJCODE']}.conf") do
        it "start_servers は 2から10までの値である" do
          expect(:stdout).to_s.to_i { start_with(2).and end_with(10) }
          expect(:stdout).to start_with(2).and end_with(10)
        end
    
        it "start_servers は 12から15までの値ではないのでerrorになる" do
          expect(:stdout).to_s.to_i { start_with(12).and end_with(15) }
          p expect(:stdout).to_s.to_i
        end
      end
    
```

  * Result

```

    .......................................................................... Failed on 10.1.1.100
    F0
    ...
    
    Failures:
    
      1) Command "awk '$1~/start_servers/{ print $3}' /etc/php-fpm.d/wp-vagrant.conf" start_servers は 2から10までの値である
         On host `wordpress'
         Failure/Error: expect(:stdout).to start_with(2).and end_with(10)
              expected :stdout to start with 2
    
           ...and:
    
              expected :stdout to end with 10
    
         # ./spec/php-fpm/main_spec.rb:52:in `block (2 levels) in <top (required)>'
    
    Finished in 4.27 seconds (files took 0.6914 seconds to load)
    78 examples, 1 failure
    
```

やはり型変換ができていません

  * should be > の場合

```

    its(:stdout) { should be.inspect.to_i > 12 }
    its(:stdout) { should be.inspect.to_i > 9 }
    its(:stdout) { should be.to_s.to_i > 12 }
    its(:stdout) { should be.to_s.to_i > 9 }
    its(:stdout) { should.inspect.to_i > 12 }
    its(:stdout) { should.inspect.to_i > 9 }
    its(:stdout) { should.to_s.to_i > 12 }
    its(:stdout) { should.to_s.to_i > 9 }
    
```

  * これらは全てTestがスルー (無視でpassed)されてしまいます 
    * この例ですと:stdoutが"10\n"なのでそれを数値に変換したとして > 12はfailed になってほしいです
  * どうもbe_within(), start_with()の時と同じく型変換で Falseになり、 0:Fixnum と変換されているのかと思いましたが、以下でしたので0になる原因がよくわかっていません...

```

    [61] pry(main)> 0 === false ? true : false
    => false
    [28] pry(main)> Process.wait
    => 18988
    [29] pry(main)> $?.exitstatus
    => 0
    [30] pry(main)> $?.exitstatus === true ? true : false
    => false
    [31] pry(main)> $?.exitstatus
    => 0
    [32] pry(main)> $?.exitstatus === false ? true : false
    => false
    
    [33] pry(main)> p !0
    false
    => false
    [34] pry(main)> p !!0
    true
    => true
    [35] pry(main)> p 0
    0
    => 0
    [36] pry(main)> p !1
    false
    => false
    [37] pry(main)> p !!1
    true
    => true
    
```

なにか良い方法をご存知の方いらっしゃいますでしょうか?  
新しいresource typeを用意する以外は方法がなさそうでしょうか?

よろしくお願いいたします。
CC BY-SA 3.0
2016-04-03T13:34:59.030
23703
2016-11-06T15:46:58.297
2016-11-06T15:46:58.297
754
15020
question
ruby
Serverspec で 範囲指定をしたい (Rspec でいう be_within + of や start_with..)
以下のように`its('stdout.to_i')`を検証するとよいのではないでしょうか。

```

    describe command("awk '\$1~/start_servers/{ print \$3}' /etc/php-fpm.d/#{ENV['PJCODE']}.conf") do
      its('stdout.to_i') { should be_within(9.0).of(20.0) }
    end
    
```

上記のコードは以下のように書くのと同じです。

```

    describe command("awk '\$1~/start_servers/{ print \$3}' /etc/php-fpm.d/#{ENV['PJCODE']}.conf") do
      it "start_servers は 2から10までの値である" do
        expect(subject.stdout.to_i).to be_within(9.0).of(20.0)
      end
    end
    
```

`its(:stdout) { should 〜 }`と書いた場合、subjectの`stdout`メソッドを呼び出した結果を検証します。

`describe`している対象がcommandリソースタイプなので、subjectには[ServerSpec::Type::Command](https://github.com/mizzy/serverspec/blob/master/lib/serverspec/type/command.rb)が設定されています。

単にシンボルを渡して`its(:stdout)`と書くと`ServerSpec::Type::Command#stdout`が呼び出され、その結果を検証します。

`its`は[rspec/rspec-its](https://github.com/rspec/rspec-
its#usage)の機能で、シンボルの他に文字列を受け取ることができ、`.`でつなげるとsubjectの下のネストした属性を取れます。
CC BY-SA 3.0
2016-07-10T03:33:51.183
27493
2016-07-10T03:33:51.183
2599
23703
answer