7

I'm trying to test a role with ChefSpec. I would rather not use Chef Zero (by requiring 'chefspec/server') just because it runs a bit slower than ChefSpec does on it's own.

Perhaps I'm reading the documentation wrong, but it doesn't look like Chef Zero is required to test a role. I haven't had any luck with my current configuration, however. This is my test:

require 'chefspec'

RSpec.configure do |config|
  config.cookbook_path = 'C:\projects\chef\cookbooks'
  config.role_path = 'C:\projects\chef\roles'
  config.log_level = :debug
  config.platform = 'ubuntu'
  config.version = '12.04'
end

describe 'my_cookbook::default' do
  let(:chef_run) do
    ChefSpec::Runner.new.converge('role[my_role]')
  end

  it 'runs without failing' do
    expect(chef_run)
  end
end

The role (located at roles/my_role.json):

{
    "name": "my_role",
    "description": "My role",
    "default_attributes": {
    },
    "run_list": [
        "recipe[my_cookbook::default]"
    ]
}

When I run the test, I receive:

NoMethodError: undefined method `run_list_for' for #<Hash:0x4fa3280>
./spec/role_spec.rb:13:in `block (2 levels) in <top (required)>'
./spec/role_spec.rb:17:in `block (2 levels) in <top (required)>'

If I modify my test to manually load the role into Chef Zero by requiring chefspec/server, that seems to work. I don't think I should have to mock the server from the way the documentation is written, but I could be wrong.

Am I doing something wrong? Is this a bug? Or do I have to use Chef Zero?

sethvargo
  • 26,739
  • 10
  • 86
  • 156
user949286
  • 1,259
  • 1
  • 13
  • 22
  • The method `run_list_for` does not appear in ChefSpec or Chef Zero. Can I see your method? – sethvargo Jan 29 '14 at 21:39
  • `run_list_for` (if that's what your referring to) is not my own method, it seems to be related to chef. The stack trace is generated on the `expect(chef_run)` line, and the default recipe itself is empty. The only references I could find are some posts related to old versions chef solo (version 10) that spewed out this same exception when the JSON didn't contain specific attribute values (like "json_class": "Chef::Role"). I added the JSON content, let me know if there's anything else I can post that may be helpful. – user949286 Jan 29 '14 at 22:44
  • What version of ChefSpec? – sethvargo Jan 30 '14 at 07:07
  • What line is line #26 in spec/role_spec.rb? The one the error refers to? – Draco Ater Jan 30 '14 at 08:00
  • What happens if you add `"json_class":"Chef::Role"` to your role? – sethvargo Jan 30 '14 at 15:57
  • @DracoAter - Sorry for the confusion, I've updated the original post to reflect the correct line numbers. I must have copied that before making some alterations to the code. – user949286 Jan 30 '14 at 17:52
  • @sethvargo - Well that seems to fix it, should that be added to the ChefSpec documentation? One thing I now realize is that the docs show the role as a Ruby file as opposed to a JSON file - does that matter? – user949286 Jan 30 '14 at 17:53
  • On disk, Chef roles can be described as `.rb` or `.json` files - it's really your preference which you use, though each has its own syntax. Chef server has its own representation and you can translate reasonably easily with `knife` utility methods. If you are using a Chef server and you use knife to create a role or create the role on the server directly, you don't automatically get a file on disk for that role. You have to [`knife role list`](http://docs.opscode.com/knife_role.html#list) with a `-f` format flag, then save that output to your /roles directory. – Patrick M Jan 30 '14 at 18:03
  • I am not certain what happens if you have a role specified in both `.rb` and `.json` files. It is recommended that you stick to one format for consistency and do not duplicate roles or re-use role names between the two formats. – Patrick M Jan 30 '14 at 18:04
  • @user949286 no, this isn't a ChefSpec issue, it's a Chef issue/misunderstanding. – sethvargo Jan 31 '14 at 18:20

1 Answers1

16

If you are using JSON roles, you must include the json_class:

"json_class": "Chef::Role"

If you are using Ruby roles, you don't need to do that.

sethvargo
  • 26,739
  • 10
  • 86
  • 156