Why can't chefspec find the chef_handler cookbook? - unit-testing

in trying to write chefspec tests, following the examples on the chefspec README (https://github.com/acrmp/chefspec), I get the following error. I tried adding "depends 'chef_handler'" to my metadata.rb, without success:
$ bundle exec rspec
*[2013-08-15T11:55:01-07:00] WARN: found a directory cookbooks in the cookbook path, but it contains no cookbook files. skipping.
F*
Pending:
example::default should include
# Your recipe examples go here.
# ./spec/default_spec.rb:6
example::single_node should do something
# Your recipe examples go here.
# ./spec/single_node_spec.rb:5
Failures:
1) example::default logs the foo attribute
Failure/Error: chef_run.converge 'example::default'
Chef::Exceptions::CookbookNotFound:
Cookbook chef_handler not found. If you're loading chef_handler from another cookbook, make sure you configure the dependency in your metadata
# ./spec/default_spec.rb:16:in `block (2 levels) in <top (required)>'

I had the same problem trying to test a custom Chef handler, but I was trying to use Berkshelf to pull dependencies down via ChefSpec's native support for Berkshelf. Here's what worked for me:
Add a spec/spec_helper.rb with
require 'chefspec'
require 'chefspec/berkshelf'
Add a .rspec file to the root of the cookbook project with
--color
--format progress
--require spec_helper
Ensure your spec (spec/default_spec.rb) is setup correctly
describe 'my_chef_handlers::default' do
handler_path = File.join('files', 'default')
let(:chef_run) do
chef_runner = ChefSpec::Runner.new do |node|
node.set['chef_handler']['handler_path'] = handler_path
node.set['statsd']['server'] = '127.0.0.1'
end
chef_runner.converge 'my_chef_handlers::default'
end
end
Setting up the ChefSpec runner outside the let statement caused cookbook not found errors.

I ran into the same problem recently. Because chefspec aims to be fast and only simulate chef runs, it doesn't clone cookbooks from the chef server. It requires that the chef_handler cookbook needs to be local. By default, it looks for it at the same level as the cookbook you are testing.
e.g.
./test_cookbook
./chef_handler

Related

SQLite in an AWS Lambda Ruby function

I am attempting to use SQLite within an AWS Lambda Ruby function, but having trouble with the sqlite3 gem. Has anyone been able to do this successfully?
I have a simple Gemfile:
source "https://rubygems.org"
gem "activerecord", "~> 7.0"
gem "sqlite3", "~> 1.4"
After a few false starts trying to run the function on Lambda itself, I looked at this question on Ruby gems with native extensions on AWS Lambda, so am trying to package dependencies using a Lambda-like Docker image. bundle install fails at the sqlite3 native extension step. When I try to install the gem by itself:
docker run --rm -v "$PWD":/var/task lambci/lambda:build-ruby2.7 gem install sqlite3
I see:
Building native extensions. This could take a while...
ERROR: Error installing sqlite3:
ERROR: Failed to build gem native extension.
current directory: /var/runtime/gems/sqlite3-1.4.2/ext/sqlite3
/var/lang/bin/ruby -I /var/lang/lib/ruby/site_ruby/2.7.0 -r ./siteconf20220430-1-n5ip9q.rb extconf.rb
checking for sqlite3.h... no
sqlite3.h is missing. Try 'brew install sqlite3',
'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
and check your shared library search path (the
location where your sqlite3 shared library is located).
The docs for the Docker image seem to indicate that sqlite-devel has been installed, though. When I ask which -a sqlite3, it says:
/usr/bin/sqlite3
/bin/sqlite3
When I try to build --with-sqlite3-dir=/bin/sqlite3 or --with-sqlite3-dir=/usr/bin/sqlite3:
Building native extensions with: '--with-sqlite3-dir=/bin/sqlite3'
This could take a while...
ERROR: Error installing sqlite3:
ERROR: Failed to build gem native extension.
current directory: /var/runtime/gems/sqlite3-1.4.2/ext/sqlite3
/var/lang/bin/ruby -I /var/lang/lib/ruby/site_ruby/2.7.0 -r ./siteconf20220430-1-1rgbak9.rb extconf.rb --with-sqlite3-dir\=/bin/sqlite3
checking for sqlite3.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.
Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/var/lang/bin/$(RUBY_BASE_NAME)
--with-sqlcipher
--without-sqlcipher
--with-sqlite3-config
--without-sqlite3-config
--with-pkg-config
--without-pkg-config
--with-sqlcipher
--without-sqlcipher
--with-sqlite3-dir
--with-sqlite3-include
--without-sqlite3-include=${sqlite3-dir}/include
--with-sqlite3-lib
--without-sqlite3-lib=${sqlite3-dir}/lib
/var/lang/lib/ruby/2.7.0/mkmf.rb:471:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
from /var/lang/lib/ruby/2.7.0/mkmf.rb:613:in `try_cpp'
from /var/lang/lib/ruby/2.7.0/mkmf.rb:1177:in `block in find_header'
from /var/lang/lib/ruby/2.7.0/mkmf.rb:971:in `block in checking_for'
from /var/lang/lib/ruby/2.7.0/mkmf.rb:361:in `block (2 levels) in postpone'
from /var/lang/lib/ruby/2.7.0/mkmf.rb:331:in `open'
from /var/lang/lib/ruby/2.7.0/mkmf.rb:361:in `block in postpone'
from /var/lang/lib/ruby/2.7.0/mkmf.rb:331:in `open'
from /var/lang/lib/ruby/2.7.0/mkmf.rb:357:in `postpone'
from /var/lang/lib/ruby/2.7.0/mkmf.rb:970:in `checking_for'
from /var/lang/lib/ruby/2.7.0/mkmf.rb:1176:in `find_header'
from extconf.rb:68:in `<main>'
To see why this extension failed to compile, please check the mkmf.log which can be found here:
/var/runtime/extensions/x86_64-linux/2.7.0/sqlite3-1.4.2/mkmf.log
extconf failed, exit code 1
Gem files will remain installed in /var/runtime/gems/sqlite3-1.4.2 for inspection.
Results logged to /var/runtime/extensions/x86_64-linux/2.7.0/sqlite3-1.4.2/gem_make.out
This is where I am stuck. I note the message:
/var/lang/lib/ruby/2.7.0/mkmf.rb:471:in 'try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
But not sure how to make headway on that. I'm also pretty new to Docker and have been having trouble trying to read mkmf.log; I am getting No such file or directory when I try to cat it.
I found some questions/answers that indicate people have gotten SQLite working with Node and Python Lambda functions, but I don't see any discussion of Ruby functions. I also found this layer for adding SQLite support in Python functions. But didn't find any such layer for Ruby.
Is a Ruby layer necessary, or is there something else I am missing? Thanks very much!

RSpec 3, capybara 2.3.0, Guard 2.6.1, Rails 4.1.1 uninitialized constant (NameError)

I've recently had to migrate a project from rails 4.0 to rails 4.1 and in the process I've also updated RSpec to RSpec (3.0.0).
The project previously had the following in certain feature specs being tested with Capybara:
require 'spec_helper' require 'support/integration_helpers.rb'
require 'support/admin_support/admin_user_creation_helpers.rb'
include BuildDefaults
The include BuildDefaults refers to a module spec/support/build_defaults.rb and has various helper methods to ensure that the database has been populated correctly. For some reason this has now stopped working and gives the following error (and stack trace):
path_to/spec/features/admin_features/admin_login_out_spec.rb:4:in
<top (required)>': uninitialized constant BuildDefaults (NameError)
from
/Users/u_name/.rvm/gems/ruby-2.1.2#gemset_name/gems/rspec-core-3.0.2/lib/rspec/core/configuration.rb:1057:in
block in load_spec_files' from
/Users/u_name/.rvm/gems/ruby-2.1.2#gemset_name/gems/rspec-core-3.0.2/lib/rspec/core/configuration.rb:1057:in
each' from
/Users/u_name/.rvm/gems/ruby-2.1.2#gemset_name/gems/rspec-core-3.0.2/lib/rspec/core/configuration.rb:1057:in
load_spec_files' from
/Users/u_name/.rvm/gems/ruby-2.1.2#gemset_name/gems/rspec-core-3.0.2/lib/rspec/core/runner.rb:97:in setup' from
/Users/u_name/.rvm/gems/ruby-2.1.2#gemset_name/gems/rspec-core-3.0.2/lib/rspec/core/runner.rb:85:inrun' from
/Users/u_name/.rvm/gems/ruby-2.1.2#gemset_name/gems/rspec-core-3.0.2/lib/rspec/core/runner.rb:70:in run' from
/Users/u_name/.rvm/gems/ruby-2.1.2#gemset_name/gems/rspec-core-3.0.2/lib/rspec/core/runner.rb:38:ininvoke' from
/Users/u_name/.rvm/gems/ruby-2.1.2#gemset_name/gems/rspec-core-3.0.2/exe/rspec:4:in
<top (required)>' from
/Users/u_name/Documents/rails/work/c_central_4.1.1/gemset_name/bin/rspec:7:in
' from
/Users/u_name/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in
require' from
/Users/u_name/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in
require' from -e:1:in `'
Would anybody happen to know why this has happened?
I would greatly appreciate any help on the matter.
I have looked at various other SO questions with a similar title as this one but none of them seem to be relevant.
Side note 1
It is worth noting that I have removed Spork from my test environment as it was not playing nicely for some reasons but have instead configured the project to use Spring. Though I don't think that this has anything to do with the issue, I did have to completely rebuild the test environment (running rails g rspec:install for instance) and then used Transpec to update the Rspec syntax.
Having spent some time looking around for a solution to this I eventually came across the official upgrade documentation (I know, I know).
As it says in the docs,
Default helper files created in RSpec 3.x have changed
In prior versions, only a single spec_helper.rb file was generated. This file
has been moved to rails_helper.rb. The new spec_helper.rb is the same
standard helper generated by running rspec --init.
This change was made to accomplish two general goals:
Keep the installation process in sync with regular RSpec changes
Provide an out-of-the-box way to avoid loading Rails for those specs
that do not require it
This second point got me thinking about the fact that a feature spec for capybara would need to load the application stack. As such, by loading the rails_helper.rb instead of the spec_helper.rb the spec/support/build_defaults.rb is now included in the load path.
Hope this helps somebody in the future.

I'm trying to run puppet-rspec, but get a not very specific error

I'm trying to get rspec to work on my Puppet module, but I get this error:
1) apache when called with no parameters on redhat
Failure/Error: })
Puppet::Error:
Could not parse for environment production: No file(s) found for import of '' at line 4 on node testhost.example.com
# ./spec/classes/apache_spec.rb:10:in `block (3 levels) in <top (required)>'
I have run puppet-rspec-init and put a simple spec in spec/classes/apache_spec.rb
This is the part that I'm most curious about; what is it trying to load?
No file(s) found for import of '' at line 4
I do have a .fixtures.yml in place (modules/apache/.fixtures.yml):
fixtures:
symlinks:
"apache": "#{source_dir}"
Could someone nudge me in the right direction? I've probably missed something obvious... :S
Thanks,
Ger.
I've seen a similarly phrased error when I didn't have a site.pp file in fixtures, though I haven't been able to duplicate that problem. If you haven't already, get your first spec running with just
it { should compile.with_all_deps }
...before you write any additional tests. Just getting the tools set up to work right (and keeping up with changes) is a lot harder than writing the tests; the tests are the easy part.
The .fixtures file should create the symlink for you when you run the appropriate rake task, but if it doesn't, make sure your module is symlinked in fixtures, as well as any dependent modules symlinked as well.
I like puppetlabs_spec_helper alongside rspec-puppet, though you end up with rake spec and rake rspec both available, one or the other of which may not work quite right.
Some code changes in PE 3.2 requires that I do this before a 'rake spec'
export MODULEPATH=/etc/puppetlabs/puppet/modules
Thanks to Ben from PuppetLabs.

Listing files of webdirectory with rails 4

Ruby 2.0, Rails 4.
I made a site which serves static files.
I used
Dir.glob
to list static files
Now I have to save the files outside the app because the slugsize in Heroku will be too big otherwise
For this reason, i would like a directory listing of a public web folder. (Served by apache server)
I tried:
Gemfile:
gem 'net-ssh'
Controller:
def index
require 'net/ssh'
ssh = Net::SSH.start( 'http://www.domain.ch/path/to/directory', 'gast')
#files =ssh.exec!( 'ls . ').split("\n")
ssh.close
end
This raised the error:
Errno::ENOENT - No such file or directory - getaddrinfo:
net-ssh (2.7.0) lib/net/ssh/transport/session.rb:67:in `block in initialize'
/home/benutzer/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/timeout.rb:52:in `timeout'
/home/benutzer/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/timeout.rb:97:in `timeout'
net-ssh (2.7.0) lib/net/ssh/transport/session.rb:67:in `initialize'
net-ssh (2.7.0) lib/net/ssh.rb:200:in `start'
...
I never heard of a file called getaddrinfo
The answer on this thread `initialize': No such file or directory - getaddrinfo (Errno::ENOENT) when Rails new app (updating rvm) didnt solve the problem.
Additional info:
$gem -v bundler
2.0.5
$rvm - v
rvm 1.21.12 (stable)
$rvm - v
rvm 1.23.9 (master)
One of the big advantages of Ruby is, that it relies on just a couple of basic things to implement different functionalities. One of the things where this taken to an extreme is IO. Borrowed from the UNIX principle "everything is a file", in Ruby "everything is IO".
So the error Errno::ENOENT - No such file or directory - getaddrinfo: is just a generic IO error, telling you that the address http://www.domain.ch/path/to/directory could not be found. It would be even easier to spot this error if you had provided the line-numbers in your code, as they map 1 to 1 to the stack-trace you posted.
From what I know about SSH, it does not care about URLs. It cares about host and user, optionally about a password, but it's better to use key based authentication.
So if you look at the net/ssh example, you will see that you have to pass the host and not an URL. In your example this would translate to something like this:
require 'net/ssh'
Net::SSH.start('www.domain.ch', 'gast') do |ssh|
ssh.exec!('ls path/to/directory')
end

Given a typical Rails 3 environment, why am I unable to execute any tests?

I'm working on writing simple unit tests for a Rails 3 project, but I'm unable to actually execute any tests.
Case in point, attempting to run the test auto-generated by Rails fails:
require 'test_helper'
class UserTest < ActiveSupport::TestCase
# Replace this with your real tests.
test "the truth" do
assert true
end
end
Results in the following error:
<internal:lib/rubygems/custom_require>:29:in `require': no such file to load --
test_helper (LoadError)
from <internal:lib/rubygems/custom_require>:29:in `require'
from user_test.rb:1:in `<main>'
Commenting out the require 'test_helper' line and attempting to run the test results in this error:
user_test.rb:3:in `<main>': uninitialized constant Object::ActiveSupport (NameError)
The action pack gems appear to be properly installed and up to date:
actionmailer (3.0.3, 2.3.5)
actionpack (3.0.3, 2.3.5)
activemodel (3.0.3)
activerecord (3.0.3, 2.3.5)
activeresource (3.0.3, 2.3.5)
activesupport (3.0.3, 2.3.5)
Ruby is at 1.9.2p0 and Rails is at 3.0.3.
The sample dump of my test directory is as follows:
/fixtures
/functional
/integration
/performance
/unit
-- /helpers
-- user_helper_test.rb
-- user_test.rb
test_helper.rb
I've never seen this problem before - I've run the typical rake tasks for preparing the test environment. I have nothing out of the ordinary in my application or environment configuration files, nor have I installed any unusual gems that would interfere with the test environment.
Edit March 9th
Xavier Holt's suggestion, explicitly specifying the path to the test_helper worked; however, this revealed an issue with ActiveSupport.
Now when I attempt to run the test, I receive the following error message (as also listed above):
user_test.rb:3:in `<main>': uninitialized constant Object::ActiveSupport (NameError)
But as you can see above, Action Pack is all installed and update to date.
Edit March 13th
When attempting to run tests using rake test:units the following stack trace is dumped to the console:
test/unit/bookmark_test.rb:3:in `<top (required)>': uninitialized constant Objec
t::ActiveSupport (NameError)
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5:in `load'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5:in `block in <main>'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5:in `each'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5:in `<main>'
rake aborted!
So looking into the file listed above, I see the following:
#!/usr/bin/env ruby
# Load the test files from the command line.
ARGV.each { |f| load f unless f =~ /^-/ }
To my knowledge, everything looks as expected.
Your test/test_helper file should have been created when you generated the application. It contains this valuable content:
ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
#
# Note: You'll currently still have to declare fixtures explicitly in integration tests
# -- they do not yet inherit this setting
fixtures :all
# Add more helper methods to be used by all tests here...
end
The second line here is the most important: it requires the config/environment.rb file at the root of your application, which in turn requires a lot of other things, including the valuable (I like that word today, ok?) ActiveSupport constant.
When you generate a controller, model or scaffold it'll also generate tests for those. I just ran rails g scaffold ticket in my app and it generated test/unit/ticket_test.rb which contains this:
require 'test_helper'
class TicketTest < ActiveSupport::TestCase
# Replace this with your real tests.
test "the truth" do
assert true
end
end
The first line of this file will require the test/test_helper.rb file that we jut saw. This will load ActiveSupport and the TestCase class within it, thereby making this test feasible. Everything else just flows on from there.
With all that explanation out of the way (even though it's something that you already know), I'm placing a large wager on it's something that's masscaring your LOAD_PATH, causing the test directory to be removed from it.
What's really unusual is that when you do specify the full path to the test/test_helper.rb you're saying it loads it, but ActiveSupport is still undefined. Well, that should be loaded as-per the description above. Is it actually loading config/environment.rb? Can you put something such as:
puts "LOADING CONFIG/ENVIRONMENT.RB"
At the top of your config/environment.rb file and then run the tests again? It should be output. Very unusual.
Continuing on the thread about LOAD_PATH... Got a dirty little secret you're not telling us about?
Actually, Dan Cheail makes a good point. You could be running the tests using ruby test/unit/ticket_test.rb in which case test_helper wouldn't be available, but still that still doesn't explain why when you specify the full path you're still getting an undefined constant ActiveSupport.
If you want to run a single test you should be doing this:
ruby -Itest test/unit/ticket_test.rb
That -I option there adds the test directory to the load path, meaning the test_helper file will be available through a straight require 'test_helper'. If it still errors after this, I reckon your test/test_helper.rb is either empty or broken.
The problem you're having is the way you're executing tests. Simply calling ruby test/unit/user_test.rb doesn't set up the load path, which explains the problems you've been having.
rake test:units is what you want and should work straight away.
Sorry about the post here, but I am unable to comment on questions yet.
what environment are you running, Win (has an issue with a .gemspec file) Linux, Mac?
Are you using RVM?
Test-Unit is installed by default with Rails, if you installed the gem Test-Unit you will get a conflict between the 2. try uninstalling the gem and your tests should start working.
If running on windows I would gem uninstall "autotest", then navigate to the following dir
drive:\Ruby192\lib\ruby\gems\1.9.1\specifications
In here you will find .gemspec files. Ensure that you dont have 2 autotest.gemspec files or any, for that matter. if so remove(delete) them, then download and gem install the autotest gem again. Grab the latest by using version switch.
You should be able to run your autotests. I did come across this once before, so to fix I simply removed the view and helper test files and wrote everything in the standard test file. Other than that I know running on windows autotest had issues, because of the ruby installer and bundler not clearing out things correctly and forgetting files.
I will find the link for you, to better explain.