Running Rspec fails if variables can be passed to a class in Puppet - testing

Problem
If variables can be passed to a Puppet class, e.g.:
class module_name (
$variable='hello_world'
) {
package { 'package_name': }
}
and rspec is run it fails, i.e.:
[user#host module_name]$ rspec
...............................FFFFFFFFFFFF..........................................
Failures:
1) opsview should contain Class[module_name]
Failure/Error: it { should contain_class('module_name') }
Puppet::Error:
Error from DataBinding 'hiera' while looking up 'module_name::variable':
FileSystem implementation expected Pathname, got: 'Hash' on node host
# /usr/share/ruby/vendor_ruby/puppet/resource.rb:393:
in `rescue in lookup_with_databinding'
# /usr/share/ruby/vendor_ruby/puppet/resource.rb:387:
in `lookup_with_databinding'
# /usr/share/ruby/vendor_ruby/puppet/resource.rb:381:
in `lookup_external_default_for'
Main issue
Error from DataBinding while looking up FileSystem implementation expected Pathname,
got: 'Hash' on node
Configuration
Versions
[vagrant#vm-one opsview]$ puppet --version
3.7.5
[vagrant#vm-one opsview]$ rspec --version
3.2.2
Spec_helper
[vagrant#vm-one opsview]$ cat spec/spec_helper.rb
require 'rspec-puppet'
require 'hiera-puppet-helper'
fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures'))
RSpec.configure do |c|
c.module_path = File.join(fixture_path, 'modules')
c.manifest_dir = File.join(fixture_path, 'manifests')
c.hiera_config = '/etc/puppet/hiera.yaml'
end
at_exit { RSpec::Puppet::Coverage.report! }
Attempt
According to this Q&A hiera-puppet-helper is causing the
issue. Rspec-puppet seems to support testing of hiera and
'hiera-puppet-helper' could be replaced. Ok perhaps this solves the issue, but what is causing the issue?
This post contains the same issue, but not a solution to solve
the issue
This post indicates that removing the class parameters solves the issue, but this class is used by multiple modules and therefore this is not a solution.

There's a problem with the hiera_config, it should be:
c.hiera_config = 'spec/fixtures/hiera/hiera.yaml'
assuming that you have directory structure like:
\spec
\fixtures
\hiera
hiera.yaml
default.yaml
and hiera.yaml:
---
:backends:
- yaml
:hierarchy:
- '%{::clientcert}'
- default
:yaml:
:datadir: './spec/fixtures/hiera'
The hiera-puppet-helper gem is indeed not required, in fact it shouldn't be there. I'd recommend generating module structure using Garethr's skeleton which already contains working setup for Hiera and can save you a lot of time.

Related

Load elixir configs hierarchal in multiple projects

I am writing a small project in Elixir, where I will use the built in configuration capability. The way it looks like I have a general project that will call APIs:
api/confix.exs:
use Mix.Config
config :api, :status, "awesome"
I now have a second project that should utilize these variables
api_consumer/mix.exs
def application do
[applications: [:logger, :api]]
end
When I run a console in api_consumer accessing the variable yields a nil result.
iex -S mix
iex(1)> Application.get_env(:api, :status)
=> nil
From what I understand (and from what I read here) that should work.
Does anybody know what's going on here?
mix.exs is used to configure the current application, while config.exs is used to configure other applications. In your :api application, you should put the default values in the application/0 function inside mix.exs:
# api/mix.exs
def application do
[
applications: [:logger, :api],
env: [status: "awesome"]
]
end
Then, you can override this setting in your :api_consumer application inside the config.exs file:
# api_consumer/config/config.exs
config :api, status: "fantastic"
More info can be found here.

JRuby - disable Apache Common Logging

I'm trying to disable Apache Common Logging in JRuby this way:
require 'java'
...
module ...
java_import org.apache.commons.logging.Log
java_import org.apache.commons.logging.LogFactory
java::lang.static {
java::lang.System.setProperty("org.apache.commons.logging.Log",
"org.apache.commons.logging.impl.NoOpLog")
}
based on Java code:
static {
System.setProperty("org.apache.commons.logging.Log",
"org.apache.commons.logging.impl.NoOpLog");
}
In Java above code disables logging but in JRuby logging is still enabled.
the java::lang.static just does nothing (it works since JRuby needs to lazily allow package names since it can not know before-hand which packages will exists until a class is loaded from a given package).
in Ruby and thus JRuby there's no static initializers - code is executed as it's parsed thus simply do a (no need for the java_imports neither since you're not using those classes) :
java::lang.System.setProperty("org.apache.commons.logging.Log",
"org.apache.commons.logging.impl.NoOpLog")

Jasmine runner at '/specs' returned a 302 error: Found

I'm using jasmine-rails-0.4.5 and devise-2.2.3 in a standard rails-3.2 app. When I run bundle exec rake spec:javascript, in order to run the jasmine specs, I'm getting the following message: "Jasmine runner at '/specs' returned a 302 error: Found"
Since I'm using devise any request against the server that is not authenticated yet, it's being redirected to the log-in page. So far so good, that is the expected behavior from devise, but jasmine-rails need to access the /specs url in order to run the tests, so when it tries to access this it, it's getting this error: "Jasmine runner at '/specs' returned a 302 error: Found"
In my routes.rb file I added this line: "*mount JasmineRails::Engine => "/my_specs" if defined?(JasmineRails)*"
Any clue?
Thanks
This is what it fixed the issue (I did an upgrade for a newer version):
update your js libraries
get rid of all the entries under the section "src_files" except for "assets/application.js" on the spec/javascripts/support/jasmine.yml file
Add this file:
+++ b/spec/javascripts/support/jasmine_helper.rb
## -0,0 +1,13 ##
+#Use this file to set/override Jasmine configuration options
+#You can remove it if you don't need it.
+#This file is loaded *after* jasmine.yml is interpreted.
+#
+#Example: using a different boot file.
+#Jasmine.configure do |config|
+# #config.boot_dir = '/absolute/path/to/boot_dir'
+# #config.boot_files = lambda { ['/absolute/path/to/boot_dir/file.js'] }
+#end
+#
+
+Rails.application.config.action_controller.asset_host = "//localhost:8888"
+Rails.application.config.base_url = ENV['BASE_URL'] || "http://localhost:8888"
Get rid of this file: spec/javascripts/support/jasmine_runner.rb
Hope this helps

Set up RSpec to test a gem (not Rails)

It is pretty easy with the added generator of rspec-rails to set up RSpec for testing a Rails application. But how about adding RSpec for testing a gem in development?
I am not using jeweler or such tools. I just used Bundler (bundle gem my_gem) to setup the structure for the new gem and edit the *.gemspec manually.
I also added s.add_development_dependency "rspec", ">= 2.0.0" to gemspec and did a bundle install.
Is there some nice tutorial what to do next to get RSpec working?
I've updated this answer to match current best practices:
Bundler supports gem development perfectly. If you are creating a gem, the only thing you need to have in your Gemfile is the following:
source "https://rubygems.org"
gemspec
This tells Bundler to look inside your gemspec file for the dependencies when you run bundle install.
Next up, make sure that RSpec is a development dependency of your gem. Edit the gemspec so it reads:
spec.add_development_dependency "rspec"
Next, create spec/spec_helper.rb and add something like:
require 'bundler/setup'
Bundler.setup
require 'your_gem_name' # and any other gems you need
RSpec.configure do |config|
# some (optional) config here
end
The first two lines tell Bundler to load only the gems inside your gemspec. When you install your own gem on your own machine, this will force your specs to use your current code, not the version you have installed separately.
Create a spec, for example spec/foobar_spec.rb:
require 'spec_helper'
describe Foobar do
pending "write it"
end
Optional: add a .rspec file for default options and put it in your gem's root path:
--color
--format documentation
Finally: run the specs:
$ rspec spec/foobar_spec.rb
Iain's solution above works great!
If you also want a Rakefile, this is all you need:
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
# If you want to make this the default task
task default: :spec
Check the RDoc for RakeTask for various options that you can optionally pass into the task definition.
You can generate your new gem with rspec by running bundler gem --test=rspec my_gem. No additional Setup!
I always forget this. It's implemented here: https://github.com/bundler/bundler/blob/33d2f67d56fe8bf00b0189c26125d27527ef1516/lib/bundler/cli/gem.rb#L36
Here's a cheap and easy (though not officially recommended) way:
Make a dir in your gem's root called spec, put your specs in there. You probably already have rspec installed, but if you don't, just do a gem install rspec and forget Gemfiles and bundler.
Next, you'll make a spec, and you need to tell it where your app is, where your files are, and include the file you want to test (along with any dependencies it has):
# spec/awesome_gem/awesome.rb
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
$: << File.join(APP_ROOT, 'lib/awesome_gem') # so rspec knows where your file could be
require 'some_file_in_the_above_dir' # this loads the class you want to test
describe AwesomeGem::Awesome do
before do
#dog = AwesomeGem::Awesome.new(name: 'woofer!')
end
it 'should have a name' do
#dog.name.should eq 'woofer!'
end
context '#lick_things' do
it 'should return the dog\'s name in a string' do
#dog.lick_things.should include 'woofer!:'
end
end
end
Open up Terminal and run rspec:
~/awesome_gem $ rspec
..
Finished in 0.56 seconds
2 examples, 0 failures
If you want some .rspec options love, go make a .rspec file and put it in your gem's root path. Mine looks like this:
# .rspec
--format documentation --color --debug --fail-fast
Easy, fast, neat!
I like this because you don't have to add any dependencies to your project at all, and the whole thing remains very fast. bundle exec slows things down a little, which is what you'd have to do to make sure you're using the same version of rspec all the time. That 0.56 seconds it took to run two tests was 99% taken up by the time it took my computer to load up rspec. Running hundreds of specs should be extremely fast. The only issue you could run into that I'm aware of is if you change versions of rspec and the new version isn't backwards compatible with some function you used in your test, you might have to re-write some tests.
This is nice if you are doing one-off specs or have some good reason to NOT include rspec in your gemspec, however it's not very good for enabling sharing or enforcing compatibility.

Rails 3: how to load files in /lib?

I'm new to rails and making some sort of noob mistake: I frequently need to count the number of lines in a file, so I'm trying to monkey patch class File like this:
class File
def self.line_count( filename )
%x{wc -l #{filename}}.split.first.to_i
end
end
I saved this to /lib/file_util.rb. I thought that this was supposed to be auto-required, so that I could just use it, but that doesn't work:
$ rails console
>> File.line_count('Gemfile')
NoMethodError: undefined method `line_count' for File:Class
...
So I try to require it manually, no joy:
>> require '<myproj>/lib/file_util.rb' # same result with require 'file_util.rb'
=>nil
But it works if I require it within IRB:
$ irb
>> require '<myproj>/lib/file_util.rb'
=> true
>> File.line_count('Gemfile')
=> 22
I also tried to to add the require to config/application.rb:
...
Bundler.require(:default, Rails.env) if defined?(Bundler)
require 'file_util.rb'
module <myproj>
...
and I get:
$ rails console
<myproj>/config/application.rb:9:in `require': no such file to load -- file_util.rb (LoadError)
What am I doing wrong?
Ok, I seem to have mostly figured it out. Rails doesn't automatically require everything under /lib. It only auto loads when you try to use a new class name that matches a file name in lib. So if I define line_count in class FileUtil instead of File it automatically finds and loads 'file_util.rb'. But patching File and naming the patch file 'file.rb' doesn't work, since the File class is already defined, so Rails doesn't go looking for a definition.
My other problem was that I was trying to do the require too soon in the startup sequence, before Rails had a chance to enhance require to look in its directories. When I added "require 'file_util'" to config/environments/development.rb it works fine.
But this doesn't explain why I can't manually require the file from within rails console.
Monkeypatching classes can be done more easily by adding a file in config/initializers. All of those files are automatically loaded by Rails at startup.
You can call your initializer file anything you want. Try config/initializers/file.rb.