Class: ChefSpec::SoloRunner

Inherits:
Object
  • Object
show all
Includes:
Normalize
Defined in:
lib/chefspec/solo_runner.rb

Direct Known Subclasses

ServerRunner

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Normalize

#resource_name

Constructor Details

#initialize(options = {}) {|node| ... } ⇒ SoloRunner

Instantiate a new SoloRunner to run examples with.

Examples:

Instantiate a new Runner

ChefSpec::SoloRunner.new

Specifying the platform and version

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

Specifying the cookbook path

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

Specifying the log level

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

Parameters:

  • options (Hash) (defaults to: {})

    The options for the new runner

Options Hash (options):

  • :log_level (Symbol)

    The log level to use (default is :warn)

  • :platform (String)

    The platform to load Ohai attributes from (must be present in fauxhai)

  • :version (String)

    The version of the platform to load Ohai attributes from (must be present in fauxhai)

  • :path (String)

    Path of a json file that will be passed to fauxhai as :path option

  • :step_into (Array<String>)

    The list of LWRPs to evaluate

  • String (])

    tring] :file_cache_path File caching path, if absent ChefSpec will use a temporary directory generated on the fly

Yields:

  • (node)

    Configuration block for Chef::Node


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

def initialize(options = {})
  @options = with_default_options(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[:client_name]     = nil
  Chef::Config[:node_name]       = nil
  Chef::Config[:file_cache_path] = @options[:file_cache_path] || file_cache_path
  Chef::Config[:cookbook_path]   = Array(@options[:cookbook_path])
  Chef::Config[:no_lazy_load]    = true
  Chef::Config[:role_path]       = Array(@options[:role_path])
  Chef::Config[:force_logger]    = true
  Chef::Config[:solo]            = true
  Chef::Config[:environment_path] = @options[:environment_path]

  yield node if block_given?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &block) ⇒ Object

Respond to custom matchers defined by the user.


255
256
257
258
259
260
261
# File 'lib/chefspec/solo_runner.rb', line 255

def method_missing(m, *args, &block)
  if block = ChefSpec.matchers[resource_name(m.to_sym)]
    instance_exec(args.first, &block)
  else
    super
  end
end

Instance Attribute Details

#optionsHash (readonly)

Returns:

  • (Hash)

25
26
27
# File 'lib/chefspec/solo_runner.rb', line 25

def options
  @options
end

#run_contextChef::RunContext (readonly)

Returns:

  • (Chef::RunContext)

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

def run_context
  @run_context
end

Class Method Details

.converge(*recipe_names) ⇒ Object

Handy class method for just converging a runner if you do not care about initializing the runner with custom options.

Examples:

ChefSpec::SoloRunner.converge('cookbook::recipe')

16
17
18
19
20
# File 'lib/chefspec/solo_runner.rb', line 16

def self.converge(*recipe_names)
  new.tap do |instance|
    instance.converge(*recipe_names)
  end
end

Instance Method Details

#compiling?true, false

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

Returns:

  • (true, false)

199
200
201
# File 'lib/chefspec/solo_runner.rb', line 199

def compiling?
  !@converging
end

#converge(*recipe_names) ⇒ ChefSpec::SoloRunner

Execute the given `run_list` on the node, without actually converging the node. Each time #converge is called, the `run_list` is reset to the new value (it is *not* additive).

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:


105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/chefspec/solo_runner.rb', line 105

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!

  # 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?true, false

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

Returns:

  • (true, false)

227
228
229
# File 'lib/chefspec/solo_runner.rb', line 227

def dry_run?
  !!options[:dry_run]
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


164
165
166
167
168
169
170
171
172
# File 'lib/chefspec/solo_runner.rb', line 164

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:


187
188
189
190
191
# File 'lib/chefspec/solo_runner.rb', line 187

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)

246
247
248
249
250
# File 'lib/chefspec/solo_runner.rb', line 246

def inspect
  "#<#{self.class.name}" \
  " options: #{options.inspect}," \
  " run_list: [#{node.run_list}]>"
end

#nodeChef::Node

The Chef::Node corresponding to this Runner.

Returns:

  • (Chef::Node)

130
131
132
133
134
135
136
137
# File 'lib/chefspec/solo_runner.rb', line 130

def node
  return @node if @node

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

#resource_collectionHash<String, Chef::Resource>

The full collection of resources for this Runner.

Returns:


144
145
146
# File 'lib/chefspec/solo_runner.rb', line 144

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

#respond_to_missing?(m, include_private = false) ⇒ Boolean

Inform Ruby that we respond to methods that are defined as custom matchers.

Returns:

  • (Boolean)

267
268
269
# File 'lib/chefspec/solo_runner.rb', line 267

def respond_to_missing?(m, include_private = false)
  ChefSpec.matchers.key?(m.to_sym) || super
end

#step_into?(resource) ⇒ true, false

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:

  • (true, false)

217
218
219
220
# File 'lib/chefspec/solo_runner.rb', line 217

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


237
238
239
# File 'lib/chefspec/solo_runner.rb', line 237

def to_s
  "#<#{self.class.name} run_list: [#{node.run_list}]>"
end