【问题标题】:How to do numeric comparison on strings如何对字符串进行数字比较
【发布时间】:2015-10-30 21:50:40
【问题描述】:

我编写了一个 serverspec 测试,旨在检查服务器上的 ram 数量是否大于或等于属性文件中列出的挂载量

   describe command('perl -n -e "if (/MemTotal:\s+(\d+)/) { print \$1; last; }" /proc/meminfo') do
     its(:stdout){ should be >= "#{property['ram']}"}
    end

在我正在测试的机器上,命令给出“7539944”

如果属性 ram 设置为“888”,则测试错误地失败,因为字符串比较“888”大于“7539944”

有没有办法可以对 serverspec 中的字符串类型进行数字比较?

这个 irb 会议展示了我认为 ruby​​ 的行为方式以及我希望它的行为方式

$ irb
1.9.3-p484 :001 > prop="888"
 => "888" 
1.9.3-p484 :002 > command="7539944"
 => "7539944" 
1.9.3-p484 :003 > command > prop
 => false 
1.9.3-p484 :004 > command.to_i > prop.to_i
 => true 

如果我把描述改成这个

describe command('perl -n -e "if (/MemTotal:\s+(\d+)/) { print \$1; last; }" /proc/meminfo') do
 its(:stdout){ should be >= "#{property['ram']}".to_i}
end

我收到此错误

Failures:

      1) std Command "perl -n -e "if (/MemTotal:\s+(\d+)/) { print \$1; last; }" /proc/meminfo" stdout should be >= 888
         On host `foo.bar.org'
         Failure/Error: its(:stdout){ should be >= "#{property['ram']}".to_i}
         ArgumentError:
           comparison of String with 888 failed
           sudo -p 'Password: ' /bin/sh -c perl\ -n\ -e\ \"if\ \(/MemTotal:\\s\+\(\\d\+\)/\)\ \{\ print\ \\\$1\;\ last\;\ \}\"\ /proc/meminfo
           7539944
         Shared Example Group: "ram::init" called from ./spec/std/spec.rb:5
         # ./spec/shared/ram/init.rb:4:in `block (3 levels) in <top (required)>'

【问题讨论】:

  • 我想你自己给出了答案:如果你想将字符串作为整数进行比较,请使用.to_i将字符串转换为整数。
  • should be &gt;= property['ram'].to_i ;有用吗?
  • 我不知道如何将 its(:stdout) 变成整数,甚至不知道如何从中获取值。 &gt;= property['ram'].to_i 对 RHS 很好,但由于 LHS 是一个字符串,所以会出现类型错误

标签: ruby rspec serverspec


【解决方案1】:

这个工具在旧好的rspec 上运行。执行此任务不需要它的 DSL:

context 'memory' do
  it "should be greater than #{888}" do
    expect(`cat /proc/meminfo`[/MemTotal:\s+(\d+)/, 1].to_i).to be >= 888 
  end 
end

从 ruby​​ 调用 Perl 让我很开心,顺便说一句。

UPD 我用serverspec 玩了一会儿,但找不到任何直接实现您的要求的方法。因此,我建议你以这种方式对 String 进行猴子补丁:

class String
  def greater_than? other
    to_i > other.to_i rescue false
  end
end

这样你就可以在你的场景中写作:

its(:stdout) { should be_greater_than "#{property['ram']}" }

希望对你有帮助。

【讨论】:

  • 不确定我是否可以在 serverspec 中使用这样的反引号。 command "type" 被包装并通过 ssh 在遥控器上运行。 ssh'ing 由 serverspec 控制。很高兴你喜欢 perl :)
  • 谢谢!那行得通,我喜欢它。当然我也找到了另一种解决方案。使用“期望”语法而不是“应该”expect(subject.stdout.to_i).to be &gt;= "#{property['ram']}".to_i 确实有效。无法用“应该”来解决这个问题
  • 我怀疑你会成功,这就是为什么should 语法在现代rspecs 中改为expect
猜你喜欢
  • 1970-01-01
  • 2013-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-20
  • 1970-01-01
  • 2016-01-16
相关资源
最近更新 更多