Class: ChefSpec::Runner

Inherits:
Object
  • Object
show all
Includes:
Normalize
Defined in:
lib/chefspec/runner.rb,
lib/chefspec/deprecations.rb,
lib/chefspec/server.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Normalize

#resource_name

Constructor Details

#initialize(options = {}, &block) ⇒ Runner

Override the existing initialize method, setting the appropriate configuration to use a real Chef Server instead.

See Also:



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/chefspec/runner.rb', line 65

def initialize(options = {}, &block)
  @options = options = {
    cookbook_path: RSpec.configuration.cookbook_path || calling_cookbook_path(caller),
    role_path:     RSpec.configuration.role_path || default_role_path,
    log_level:     RSpec.configuration.log_level,
    path:          RSpec.configuration.path,
    platform:      RSpec.configuration.platform,
    version:       RSpec.configuration.version,
  }.merge(options)

  Chef::Log.level = options[:log_level]

  Chef::Config.reset!
  Chef::Config.formatters.clear
  Chef::Config.add_formatter('chefspec')
  Chef::Config[:cache_type]     = 'Memory'
  Chef::Config[:client_key]     = nil
  Chef::Config[:cookbook_path]  = Array(options[:cookbook_path])
  Chef::Config[:role_path]      = Array(options[:role_path])
  Chef::Config[:force_logger]   = true
  Chef::Config[:solo]           = true

  yield node if block_given?
end

Instance Attribute Details

#optionsHash (readonly)

Returns:

  • (Hash)


28
29
30
# File 'lib/chefspec/runner.rb', line 28

def options
  @options
end

#run_contextChef::RunContext (readonly)

Returns:

  • (Chef::RunContext)


31
32
33
# File 'lib/chefspec/runner.rb', line 31

def run_context
  @run_context
end

Class Method Details

.define_runner_method(resource_name) ⇒ self

Defines a new runner method on the ChefSpec::Runner.

Parameters:

  • resource_name (Symbol)

    the name of the resource to define a method

Returns:

  • (self)


19
20
21
22
23
24
25
# File 'lib/chefspec/runner.rb', line 19

def self.define_runner_method(resource_name)
  define_method(resource_name) do |identity|
    find_resource(resource_name, identity)
  end

  self
end

Instance Method Details

#compiling?Boolean

Boolean method to determine the current phase of the Chef run (compiling or converging)

Returns:

  • (Boolean)


207
208
209
# File 'lib/chefspec/runner.rb', line 207

def compiling?
  !@converging
end

#converge(*recipe_names) ⇒ ChefSpec::Runner

Execute the given ‘run_list` on the node, without actually converging the node.

Examples:

Converging a single recipe

chef_run.converge('example::default')

Converging multiple recipes

chef_run.converge('example::default', 'example::secondary')

Parameters:

  • recipe_names (Array)

    The names of the recipe or recipes to converge

Returns:

  • (ChefSpec::Runner)

    A reference to the calling Runner (for chaining purposes)



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/chefspec/runner.rb', line 107

def converge(*recipe_names)
  node.run_list.reset!
  recipe_names.each { |recipe_name| node.run_list.add(recipe_name) }

  return self if dry_run?

  # Expand the run_list
  expand_run_list!

  # Save the node back to the server for searching purposes
  unless Chef::Config[:solo]
    client.register
    node.save
  end

  # Setup the run_context
  @run_context = client.setup_run_context

  # Allow stubbing/mocking after the cookbook has been compiled but before the converge
  yield if block_given?

  @converging = true
  @client.converge(@run_context)
  self
end

#dry_run?Boolean

Boolean method to determine if this Runner is in ‘dry_run` mode.

Returns:

  • (Boolean)


235
236
237
# File 'lib/chefspec/runner.rb', line 235

def dry_run?
  !!options[:dry_run]
end

#existing_initialize {|node| ... } ⇒ Runner

Instantiate a new Runner to run examples with.

Examples:

Instantiate a new Runner

ChefSpec::Runner.new

Specifying the platform and version

ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04')

Specifying the cookbook path

ChefSpec::Runner.new(cookbook_path: ['/cookbooks'])

Specifying the log level

ChefSpec::Runner.new(log_level: :info)

Parameters:

  • options (Hash)

    The options for the new runner

Yields:

  • (node)

    Configuration block for Chef::Node

Returns:

  • (Runner)

    a new instance of Runner



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/chefspec/deprecations.rb', line 32

def initialize(options = {}, &block)
  @options = options = {
    cookbook_path: RSpec.configuration.cookbook_path || calling_cookbook_path(caller),
    role_path:     RSpec.configuration.role_path || default_role_path,
    log_level:     RSpec.configuration.log_level,
    path:          RSpec.configuration.path,
    platform:      RSpec.configuration.platform,
    version:       RSpec.configuration.version,
  }.merge(options)

  Chef::Log.level = options[:log_level]

  Chef::Config.reset!
  Chef::Config.formatters.clear
  Chef::Config.add_formatter('chefspec')
  Chef::Config[:cache_type]     = 'Memory'
  Chef::Config[:client_key]     = nil
  Chef::Config[:cookbook_path]  = Array(options[:cookbook_path])
  Chef::Config[:role_path]      = Array(options[:role_path])
  Chef::Config[:force_logger]   = true
  Chef::Config[:solo]           = true

  yield node if block_given?
end

#find_resource(type, name) ⇒ Chef::Resource?

Find the resource with the declared type and resource name.

Examples:

Find a template at ‘/etc/foo`

chef_run.find_resource(:template, '/etc/foo') #=> #<Chef::Resource::Template>

Parameters:

  • type (Symbol)

    The type of resource (sometimes called ‘resource_name`) such as `file` or `directory`.

  • name (String, Regexp)

    The value of the name attribute or identity attribute for the resource.

Returns:

  • (Chef::Resource, nil)

    The matching resource, or nil if one is not found



172
173
174
175
176
177
178
179
180
# File 'lib/chefspec/runner.rb', line 172

def find_resource(type, name)
  begin
    return resource_collection.lookup("#{type}[#{name}]")
  rescue Chef::Exceptions::ResourceNotFound; end

  resource_collection.all_resources.find do |resource|
    resource_name(resource) == type && (name === resource.identity || name === resource.name)
  end
end

#find_resources(type) ⇒ Array<Chef::Resource>

Find the resource with the declared type.

Examples:

Find all template resources

chef_run.find_resources(:template) #=> [#<Chef::Resource::Template>, #...]

Parameters:

  • type (Symbol)

    The type of resource such as ‘:file` or `:directory`.

Returns:



195
196
197
198
199
# File 'lib/chefspec/runner.rb', line 195

def find_resources(type)
  resource_collection.all_resources.select do |resource|
    resource_name(resource) == type.to_sym
  end
end

#inspectString

The runner as a String with helpful output.

Returns:

  • (String)


255
256
257
# File 'lib/chefspec/runner.rb', line 255

def inspect
  "#<#{self.class} options: #{options.inspect}, run_list: '#{node.run_list.to_s}'>"
end

#nodeChef::Node

The Chef::Node corresponding to this Runner.

Returns:

  • (Chef::Node)


138
139
140
141
142
143
144
145
# File 'lib/chefspec/runner.rb', line 138

def node
  return @node if @node

  @node = client.build_node
  @node.instance_variable_set(:@runner, self)
  @node.class.send(:attr_reader, :runner)
  @node
end

#old_initialize {|node| ... } ⇒ Runner

Instantiate a new Runner to run examples with.

Examples:

Instantiate a new Runner

ChefSpec::Runner.new

Specifying the platform and version

ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04')

Specifying the cookbook path

ChefSpec::Runner.new(cookbook_path: ['/cookbooks'])

Specifying the log level

ChefSpec::Runner.new(log_level: :info)

Parameters:

  • options (Hash)

    The options for the new runner

Yields:

  • (node)

    Configuration block for Chef::Node

Returns:

  • (Runner)

    a new instance of Runner



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/chefspec/server.rb', line 21

def initialize(options = {}, &block)
  @options = options = {
    cookbook_path: RSpec.configuration.cookbook_path || calling_cookbook_path(caller),
    role_path:     RSpec.configuration.role_path || default_role_path,
    log_level:     RSpec.configuration.log_level,
    path:          RSpec.configuration.path,
    platform:      RSpec.configuration.platform,
    version:       RSpec.configuration.version,
  }.merge(options)

  Chef::Log.level = options[:log_level]

  Chef::Config.reset!
  Chef::Config.formatters.clear
  Chef::Config.add_formatter('chefspec')
  Chef::Config[:cache_type]     = 'Memory'
  Chef::Config[:client_key]     = nil
  Chef::Config[:cookbook_path]  = Array(options[:cookbook_path])
  Chef::Config[:role_path]      = Array(options[:role_path])
  Chef::Config[:force_logger]   = true
  Chef::Config[:solo]           = true

  yield node if block_given?
end

#resource_collectionHash<String, Chef::Resource>

The full collection of resources for this Runner.

Returns:



152
153
154
# File 'lib/chefspec/runner.rb', line 152

def resource_collection
  @resource_collection ||= @run_context.resource_collection
end

#step_into?(resource) ⇒ Boolean

Determines if the runner should step into the given resource. The step_into option takes a string, but this method coerces everything to symbols for safety.

This method also substitutes any dashes (-) with underscores (_), because that’s what Chef does under the hood. (See GitHub issue #254 for more background)

Parameters:

  • resource (Chef::Resource)

    the Chef resource to try and step in to

Returns:

  • (Boolean)


225
226
227
228
# File 'lib/chefspec/runner.rb', line 225

def step_into?(resource)
  key = resource_name(resource)
  Array(options[:step_into]).map(&method(:resource_name)).include?(key)
end

#to_sString

This runner as a string.

may change between versions of this gem.

Returns:

  • (String)

    Currently includes the run_list. Format of the string



245
246
247
248
# File 'lib/chefspec/runner.rb', line 245

def to_s
  return "chef_run: #{node.run_list.to_s}" unless node.run_list.empty?
  'chef_run'
end