1

I have a Serverspec test using inifile gem:

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

The test passes if rake is executed locally on the machine (either on Ubuntu guest or OS X host, where inifile gem is installed).

However, when I run rake against Vagrant box (i.e. on host connecting with SSH to Ubuntu on Vagrant) it fails with the following message:

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)>'

I use Serverspec's default Rakefile and spec_helper.rb.

/tmp/testfile1.ini is as below, although the test fails regardless of the contents:

[section1]
variable1=value1

It seems to me like some kind of problem with characters not-escaped, but I am not really sure.

What can be wrong?

techraf
  • 64,883
  • 27
  • 193
  • 198
  • 1
    The error is telling you that `file_ini` is nil/undefined in this test when performed in your vagrant instance. I would start troubleshooting from there. Also `file_ini = IniFile.load(file)` is almost certainly being performed locally and not remotely. – Matthew Schuchard Jun 20 '16 at 11:40
  • Interesting... If it's local call, then it all makes sense. But then how does Serverspec work remotely at all? Checking... Yes, if I create the file locally on host, it works even though other tasks are executed remotely. – techraf Jun 20 '16 at 11:48

2 Answers2

1

After ensuring that inifile is installed on the Vagrant instance, a rather inelegant way of doing this would be something like this:

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

I do not know if the file variable scope would work inside of that command method, so I played it safe.

Asker techraf adds this cleaner route given a good knowledge of the inifile API.

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

With some collaboration, we arrive at this hopefully optimal solution.

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
Matthew Schuchard
  • 25,172
  • 3
  • 47
  • 67
  • Yeah, that is because symbol key-value pairs in `ruby 1.9.3` got a new syntax of `symbol_key: value`. There is a really good in-depth explanation somewhere on stack overflow about it. Good callout. – Matthew Schuchard Jun 20 '16 at 14:03
0
NoMethodError:
     undefined method `[]' for nil:NilClass

The above error can indicate that the :ssh backend hasn't been configured correctly, with required properties (possibly missing the target host)

Configure the :ssh backend by setting the following properties:

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

In the above snippet, the host to connect to is passed in using environment variables (possibly configured using Rake)

If you require finer grained control over the ssh connection, e.g. using SSH keys, or ProxyCommand, you need to add set :ssh_options, options

Example: require '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
Tim
  • 726
  • 5
  • 18