【问题标题】:Coerce command('stdout') to integer for math comparison将命令('stdout')强制转换为整数以进行数学比较
【发布时间】:2019-09-11 16:13:06
【问题描述】:

假设在路径/tmp/foo 处部署到我的服务器的检查器脚本具有以下内容...

#!/bin/bash
a=`cat /tmp/a`
b=`cat /tmp/b`
echo -n $( expr $a - $b )

...我有一个 InSpec 测试来评估 a 和 b 之间的差异是否在可接受的范围内。

describe command('/tmp/foo') do 
  its('stdout') { should be >= 0 }
  its('stdout') { should be < 120 }
end

遗憾的是,be matcher 不会将输入强制转换为可与数学运算符一起使用的类型。

如何将此值强制转换为整数?


到目前为止我已经尝试过

  • ('stdout').to_i
undefined method `to_i' for #<Class:0x00007f8a86b91f00> (NoMethodError) Did you mean?  to_s
  • ('stdout').to_s('stdout').to_s.to_i
   Command: `/tmp/foo`
     ↺  
     ↺  

Test Summary: 0 successful, 0 failures, 2 skipped
  • (('stdout').to_i)
undefined method `0' for Command: `/tmp/foo`:#<Class:0x00007f9a52b912e0>

对于背景,/tmp/a/tmp/b 是来自先前 InSpec 测试的一对 epoch 输出。

如果值在可接受的范围内,我可以检查客户端,但如果可能的话,我希望通过 InSpec 评估检查并报告这种差异,而不用正则表达式向导代替人类可读的数学表达式。

【问题讨论】:

  • 我对 InSpec 一点也不熟悉,但很明显你必须查看它的文档,看看如何才能访问命令的标准输出。

标签: ruby chef-infra test-kitchen inspec


【解决方案1】:

感谢@boduminchef community slack #InSpec channel

cmp 匹配的模糊输入

最简单的解决方案是使用cmp 匹配器而不是be 匹配器。虽然 [cmp 的官方文档] 中没有通过示例给出明确的数学运算符,但 cmp 匹配中的数学运算将正确评估

describe command('/tmp/foo') do 
  its('stdout') { should cmp >= 0 }
  its('stdout') { should cmp < 120 }
end

@aaronlippold

cmp 是我们在后端进行的逻辑比较……也就是 1 为真 TRUE 为真。因此,以 SSHD 配置为例……您可以使用 1 或 true 或 TRUE 或 True 等设置道具。它是一个更宽容的匹配器,我们已经构建了一个说服函数等。

【讨论】:

    【解决方案2】:

    归功于chef community slack #InSpec channel中的@cwolfe

    使用be 匹配和方法链接进行精确输入

    另一种方法是尝试在 stdout 文字中进行方法链接,如下所示:

    describe command("bash /tmp/foo") do 
      its('stdout.strip.to_i') { should be >= 5 }
    end
    

    InSpec 使用rspec-its library,它将点解释为方法调用。

    【讨论】:

      【解决方案3】:

      归功于@aaronlippoldchef community slack #InSpec channel

      使用 be 匹配和明确的主题语法进行精确输入

      InSpec commandstdout 可以缓存在describe 块之外并任意修改。在这里,我们要求 InSpec 运行脚本,获取它的 stdout 并删除行 (\n),然后查看结果并确保它在使用 be 匹配器语法的预期值之间进行严格的类型比较。

      x = inspec.command("bash /tmp/foo").stdout.strip.to_i
      
      describe x do 
        its { should be >= 5 }
        its { should be < 10 }
      end
      

      或者,您可以使用rspec explicit subject syntax 将返回值拉出,以便在代码中更清晰。

      describe "The value of my EPOC is between the required values" do
        subject { command("bash /tmp/foo").stdout.strip.to_i }
        it { should be >= 5 }
        it { should be < 10 }
      end
      

      这还可以让您更好地报告“什么”与“如何”。

      此方法的另一个语法选项使用puts()

      cmd = command("bash /tmp/foo")
      puts(cmd.inspect)
      describe cmd do 
        its('stdout') { expect(cmd.strip.to_i).to be >= 5 }
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-24
        • 2019-07-24
        • 2012-11-20
        • 2016-08-05
        • 1970-01-01
        • 1970-01-01
        • 2022-01-06
        • 2014-04-04
        相关资源
        最近更新 更多