On a cookbook I defined a class Rds::Checks that shares methods for building unix commands for bash/execute resources and Guards. A sample of the file libraries/checks.rb is:
module Rds
class Checks
class << self
def ssh_config_entry_present host, config_file, key_name
"cat #{config_file} | grep #{key_name}"
end
def redmine_migrated user, pass, name
"if [ `mysql -u#{user} -p#{pass} -e 'select count(id) FROM #{name}.users;' | sed -n '2 p'` -gt 0 ]; then echo '0'; else echo '1'; fi"
end
end
end
end
On LWPR providers, recipes and chefspec tests the file is loaded without problems, but when I use it inside serverspec through kitchen verify
it raise an error.
paolo@tower:~/cookbooks/rds$ cat test/integration/install/serverspec/localhost/install_spec.rb
...
it 'do migrations' do
cmd = Rds::Checks.redmine_migrated
expect(command(cmd).stdout).to eq 0
end
...
paolo@tower:~/cookbooks/rds$ kitchen verify
...
NameError:
uninitialized constant Rds
I would really like keep methods that builds bash/sh commands on a common layer so that I can test it separately and don't bother about them on unit and integration tests
You would have to load it very manually, probably add the temp folder holding the cookbook data to the load path, I think it is under
/tmp/kitchen/cookbooks
. Add the correctlibraries/
folder and then require as per normal. Overall the converge and verify phases have nothing to do with each other, since test-kitchen can be used with things other than Chef.You might want to look at something like minitest handler which runs tests in the Chef converge context, or the audit mode proposal which does similar things.
Using something like one of those, you would write your tests in the cookbook itself, so converge would actually be both converging the node and then running the tests, and verify would either be a no-op or would run additional, external tests.