"undefined method `[]' for nil:NilClass" 运行 Serverspec 远程测试时出错

"undefined method `[]' for nil:NilClass" error when running Serverspec test remotely

我使用 inifile gem:

进行了 Serverspec 测试
require 'spec_helper'
require 'inifile'

describe 'inifile test -' do
  file = '/tmp/testfile1.ini'
  file_ini = IniFile.load(file)
  it 'testfile1.ini should contain expected values' do
    expect(file_ini['section1']['variable1']).to eq('value1')
  end
end

如果 rake 在机器上本地执行(在 Ubuntu 来宾或 OS X 主机上执行,则测试通过,其中 inifile gem 是安装)。

但是,当我 运行 rake 针对 Vagrant box(即在主机上使用 SSH 连接到 Vagrant 上的 Ubuntu 时)它失败并显示以下消息:

1) inifile test - testfile1.ini should contain expected values
   On host `molecule-test'
   Failure/Error: expect(file_ini['section1']['variable1']).to eq('value1')
   NoMethodError:
     undefined method `[]' for nil:NilClass

   # ./spec/inifile_spec.rb:8:in `block (2 levels) in <top (required)>'

我使用 Serverspec 的默认 Rakefilespec_helper.rb

/tmp/testfile1.ini如下,虽然无论内容如何测试都失败:

[section1]
variable1=value1

在我看来,字符未转义存在某种问题,但我不太确定。

有什么问题吗?

确保在 Vagrant 实例上安装了 inifile 之后,一种相当不优雅的方式是这样的:

describe 'inifile test -' do
  file_ini = command("ruby -rinifile -e \"print IniFile.load('/tmp/testfile1.ini')['section1']['variable1']\"").stdout
  it 'testfile1.ini should contain expected values' do
    expect(file_ini).to eq('value1')
  end
end

我不知道 file 变量范围是否可以在那个 command 方法内部工作,所以我谨慎行事。

鉴于对 inifile API.

的充分了解,Asker techraf 添加了这条更清晰的路线
describe 'inifile test -' do
  file_ini = IniFile.new(content: command("cat /tmp/testfile1.ini").stdout)
  it 'testfile1.ini should contain expected values' do
    expect(file_ini['section1']['variable1']).to eq('value1')
  end
end

通过一些协作,我们得出了这个有希望的最佳解决方案。

describe 'inifile test -' do
  file_ini = IniFile.new(content: file('/tmp/testfile1.ini').content)
  it 'testfile1.ini should contain expected values' do
    expect(file_ini['section1']['variable1']).to eq('value1')
  end
end
NoMethodError:
     undefined method `[]' for nil:NilClass

上述错误表明 :ssh 后端配置不正确,没有正确配置所需的属性(可能缺少目标主机)

通过设置以下属性来配置 :ssh 后端:

set :backend, :ssh
set :host,       ENV['TARGET_HOST']

在上面的代码片段中,要连接的主机是使用环境变量传入的(可能使用 Rake 配置)

如果您需要对 ssh 连接进行更细粒度的控制,例如使用 SSH 密钥或 ProxyCommand,您需要添加 set :ssh_options, options

示例: 需要 'net/ssh'

# ...

host = ENV['TARGET_HOST']

#Configure SSH options
options = Net::SSH::Config.for(host)
options[:user] = ENV['USER']
options[:port] = 22
options[:keys] = ENV['TARGET_PRIVATE_KEY']

# Configure serverspec with the target host and SSH options
set :host,        host
set :ssh_options, options