1

I'm having an issue with Serverspec. I'm trying to test an infrastructure deployed on a cloud VM, from a CloudBees jenkins build server using ansible. I created a test for each ansible role using Serverspec. Right now I'm just trying to check if I can run the tests correctly, and connect to my VM.

The thing is, once I run "rake spec" I get a "Don't know how to build task 'spec:84'" error, which isn't in my code.

The whole log is in here:

########## Testing infrastructure ##########
+ cd openshift-testing/
+ rake spec --trace
** Invoke spec (first_time)
** Invoke spec:all (first_time) rake aborted! Don't know how to build task 'spec:84'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task_manager.rb:62:in
`[]'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:57:in
`lookup_prerequisite'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:53:in
`block in prerequisite_tasks'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:53:in
`map'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:53:in
`prerequisite_tasks'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:199:in
`invoke_prerequisites'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:178:in
`block in invoke_with_call_chain' /usr/share/ruby/monitor.rb:211:in
`mon_synchronize'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:172:in
`invoke_with_call_chain'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:201:in
`block in invoke_prerequisites'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:199:in
`each'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:199:in
`invoke_prerequisites'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:178:in
`block in invoke_with_call_chain' /usr/share/ruby/monitor.rb:211:in
`mon_synchronize'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:172:in
`invoke_with_call_chain'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/task.rb:165:in
`invoke'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/application.rb:150:in
`invoke_task'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/application.rb:106:in
`block (2 levels) in top_level'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/application.rb:106:in
`each'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/application.rb:106:in
`block in top_level'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/application.rb:115:in
`run_with_threads'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/application.rb:100:in
`top_level'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/application.rb:78:in
`block in run'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/application.rb:176:in
`standard_exception_handling'
/home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/lib/rake/application.rb:75:in
`run' /home/jenkins/.gem/ruby/1.9.1/gems/rake-10.4.2/bin/rake:33:in
`<top (required)>' /usr/local/bin/rake:23:in `load'
/usr/local/bin/rake:23:in `<main>'

Here is my Rakefile:

  1 require 'rake'
  2 require 'rspec/core/rake_task'
  3 
  4 hosts = %w(
  5   84.39.33.93 
  6 )
  7 
  8 task :spec => 'spec:all'
  9 
 10 namespace :spec do
 11   task :all => hosts.map {|h| 'spec:' + h.split('.')[0] }
 12   hosts.each do |host|
 13     short_name = "sca-vm"
 14     role       = "common"
 15 
 16     desc "Run serverspec to #{host}"
 17     RSpec::Core::RakeTask.new(short_name) do |t|
 18       ENV['TARGET_HOST'] = host
 19       t.pattern = "spec/base,#{role}/*_spec.rb"
 20     end
 21   end
 22 end                                                                         
~           

spec_helper.rb:

require 'serverspec'
require 'net/ssh'

set :backend, :ssh

if ENV['ASK_SUDO_PASSWORD']
  begin
    require 'highline/import'
  rescue LoadError
    fail "highline is not available. Try installing it."
  end
  set :sudo_password, ask("Enter sudo password: ") { |q| q.echo = false }
else
  set :sudo_password, ENV['SUDO_PASSWORD']
end

host = ENV['TARGET_HOST']

options = Net::SSH::Config.for(host)

options[:user] ||= Etc.getlogin

set :host,        options[:host_name] || host
set :ssh_options, options

# Disable sudo
# set :disable_sudo, true


# Set environment variables
# set :env, :LANG => 'C', :LC_MESSAGES => 'C' 

# Set PATH
# set :path, '/sbin:/usr/local/sbin:$PATH'

Finally, here's the test_spec I'm using, it just verifies the existence of a plaint text file called now.txt:

require 'spec_helper'

describe file('~/now.txt') do
  it { should be_file }
end

I'm really confused right now. Could you guys please help me understand what's going on?

udondan
  • 57,263
  • 20
  • 190
  • 175
Sebiwi
  • 109
  • 2
  • 12

1 Answers1

0

The code snippet

hosts.map {|h| 'spec:' + h.split('.')[0] }

alone yields: ["spec:84"]. Now, the task spec:all depends on that task. In the loop starting with

hosts.each do |host|

there's only a single task defined and it's called 'scm-va':

RSpec::Core::RakeTask.new(short_name) do |t|
   # ...
end

Also note that this task is defined for every element of hosts (in your example that's only one, but you've made hosts an Array for a reason, I assume).

Try rake -T -A on the command line to list all tasks, even the one's without a description, to see what tasks are actually known to Rake.

In other words: The code example declares spec:all to depend on a task (or tasks) that's not defined.

If you change the line to

    RSpec::Core::RakeTask.new('spec:' + host.split('.')[0]) do |t|

the code doesn't raise an exception, but I'm not sure that fixes your problem. Maybe it's important that 'scm-vm' is in fact part of the task name defined.

However if that's what you want, you should refactor host.split('.')[0] into a method of it's own.

Stephan
  • 75
  • 1
  • 9