Class: ChefSpec::SoloRunner
- Inherits:
-
Object
- Object
- ChefSpec::SoloRunner
- Includes:
- Normalize
- Defined in:
- lib/chefspec/solo_runner.rb,
lib/chefspec/deprecations.rb
Direct Known Subclasses
Instance Attribute Summary collapse
- #options ⇒ Hash readonly
- #run_context ⇒ Chef::RunContext readonly
Class Method Summary collapse
-
.converge(*recipe_names) ⇒ Object
Handy class method for just converging a runner if you do not care about initializing the runner with custom options.
-
.define_runner_method(resource_name) ⇒ Object
deprecated
Deprecated.
SoloRunner.define_runner_method is deprecated. Please use define_matcher instead.
Instance Method Summary collapse
-
#compiling? ⇒ true, false
Boolean method to determine the current phase of the Chef run (compiling or converging).
-
#converge(*recipe_names) {|node| ... } ⇒ ChefSpec::SoloRunner
Execute the given ‘run_list` on the node, without actually converging the node.
-
#converge_block(&block) ⇒ ChefSpec::SoloRunner
Execute a block of recipe code.
-
#dry_run? ⇒ true, false
Boolean method to determine if this Runner is in ‘dry_run` mode.
-
#find_resource(type, name, action = nil) ⇒ Chef::Resource?
Find the resource with the declared type and resource name, and optionally match a performed action.
-
#find_resources(type) ⇒ Array<Chef::Resource>
Find the resource with the declared type.
-
#initialize(options = {}) {|node| ... } ⇒ SoloRunner
constructor
Instantiate a new SoloRunner to run examples with.
-
#inspect ⇒ String
The runner as a String with helpful output.
-
#method_missing(m, *args, &block) ⇒ Object
Respond to custom matchers defined by the user.
-
#node ⇒ Chef::Node
The
Chef::Node
corresponding to this Runner. -
#preload! ⇒ void
Run a static preload of the cookbook under test.
-
#resource_collection ⇒ Hash<String, Chef::Resource>
The full collection of resources for this Runner.
-
#respond_to_missing?(m, include_private = false) ⇒ Boolean
Inform Ruby that we respond to methods that are defined as custom matchers.
-
#step_into?(resource) ⇒ true, false
Determines if the runner should step into the given resource.
-
#to_s ⇒ String
This runner as a string.
Methods included from Normalize
Constructor Details
#initialize(options = {}) {|node| ... } ⇒ SoloRunner
Instantiate a new SoloRunner to run examples with.
65 66 67 68 69 |
# File 'lib/chefspec/solo_runner.rb', line 65 def initialize( = {}) @options = () apply_chef_config! 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.
296 297 298 299 300 301 302 303 |
# File 'lib/chefspec/solo_runner.rb', line 296 def method_missing(m, *args, &block) block = ChefSpec.matchers[resource_name(m.to_sym)] if block instance_exec(args.first, &block) else super end end |
Instance Attribute Details
#options ⇒ Hash (readonly)
26 27 28 |
# File 'lib/chefspec/solo_runner.rb', line 26 def @options end |
#run_context ⇒ Chef::RunContext (readonly)
29 30 31 |
# File 'lib/chefspec/solo_runner.rb', line 29 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.
17 18 19 20 21 |
# File 'lib/chefspec/solo_runner.rb', line 17 def self.converge(*recipe_names) new.tap do |instance| instance.converge(*recipe_names) end end |
.define_runner_method(resource_name) ⇒ Object
define_runner_method is deprecated. Please use ChefSpec.define_matcher instead.
25 26 27 28 29 30 31 |
# File 'lib/chefspec/deprecations.rb', line 25 def self.define_runner_method(resource_name) deprecated "`ChefSpec::Runner.define_runner_method' is deprecated." \ " It is being used in the #{resource_name} resource matcher." \ " Please use `ChefSpec.define_matcher' instead." ChefSpec.define_matcher(resource_name) end |
Instance Method Details
#compiling? ⇒ true, false
Boolean method to determine the current phase of the Chef run (compiling or converging)
240 241 242 |
# File 'lib/chefspec/solo_runner.rb', line 240 def compiling? !@converging end |
#converge(*recipe_names) {|node| ... } ⇒ 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).
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/chefspec/solo_runner.rb', line 89 def converge(*recipe_names) # Re-apply the Chef config before converging in case something else # called Config.reset too. apply_chef_config! @converging = false node.run_list.reset! recipe_names.each { |recipe_name| node.run_list.add(recipe_name) } return self if dry_run? # Expand the run_list # Merge in provided node attributes. Default and override use the role_ # levels so they win over the relevant bits from cookbooks since otherwise # they would not and that would be confusing. node.attributes.role_default = Chef::Mixin::DeepMerge.merge(node.attributes.role_default, [:default_attributes]) if [:default_attributes] node.attributes.normal = Chef::Mixin::DeepMerge.merge(node.attributes.normal, [:normal_attributes]) if [:normal_attributes] node.attributes.role_override = Chef::Mixin::DeepMerge.merge(node.attributes.role_override, [:override_attributes]) if [:override_attributes] node.attributes.automatic = Chef::Mixin::DeepMerge.merge(node.attributes.automatic, [:automatic_attributes]) if [:automatic_attributes] # Setup the run_context, rescuing the exception that happens when a # resource is not defined on a particular platform begin @run_context = client.setup_run_context rescue Chef::Exceptions::NoSuchResourceType => e raise Error::MayNeedToSpecifyPlatform.new(original_error: e.) end # Allow stubbing/mocking after the cookbook has been compiled but before the converge yield node if block_given? @converging = true converge_val = @client.converge(@run_context) if converge_val.is_a?(Exception) raise converge_val end self end |
#converge_block(&block) ⇒ ChefSpec::SoloRunner
Execute a block of recipe code.
138 139 140 141 142 143 |
# File 'lib/chefspec/solo_runner.rb', line 138 def converge_block(&block) converge do recipe = Chef::Recipe.new(cookbook_name, "_test", run_context) recipe.instance_exec(&block) end end |
#dry_run? ⇒ true, false
Boolean method to determine if this Runner is in ‘dry_run` mode.
268 269 270 |
# File 'lib/chefspec/solo_runner.rb', line 268 def dry_run? !![:dry_run] end |
#find_resource(type, name, action = nil) ⇒ Chef::Resource?
Find the resource with the declared type and resource name, and optionally match a performed action.
If multiples match it returns the last (which more or less matches the chef last-inserter-wins semantics)
209 210 211 212 213 |
# File 'lib/chefspec/solo_runner.rb', line 209 def find_resource(type, name, action = nil) resource_collection.all_resources.reverse_each.find do |resource| resource.declared_type == type.to_sym && (name === resource.name || name === resource.identity) && (action.nil? || resource.performed_action?(action)) end end |
#find_resources(type) ⇒ Array<Chef::Resource>
Find the resource with the declared type.
228 229 230 231 232 |
# File 'lib/chefspec/solo_runner.rb', line 228 def find_resources(type) resource_collection.all_resources.select do |resource| resource_name(resource) == type.to_sym end end |
#inspect ⇒ String
The runner as a String with helpful output.
287 288 289 290 291 |
# File 'lib/chefspec/solo_runner.rb', line 287 def inspect "#<#{self.class.name}" \ " options: #{.inspect}," \ " run_list: [#{node.run_list}]>" end |
#node ⇒ Chef::Node
The Chef::Node
corresponding to this Runner.
170 171 172 173 174 175 176 177 178 |
# File 'lib/chefspec/solo_runner.rb', line 170 def node runner = self @node ||= begin apply_chef_config! client.build_node.tap do |node| node.define_singleton_method(:runner) { runner } end end end |
#preload! ⇒ void
This method returns an undefined value.
Run a static preload of the cookbook under test. This will load libraries and resources, but not attributes or recipes.
151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/chefspec/solo_runner.rb', line 151 def preload! # Flag to disable preloading for situations where it doesn't make sense. return if ENV["CHEFSPEC_NO_PRELOAD"] begin old_preload = $CHEFSPEC_PRELOAD $CHEFSPEC_PRELOAD = true converge("recipe[#{cookbook_name}]") node.run_list.reset! ensure $CHEFSPEC_PRELOAD = old_preload end end |
#resource_collection ⇒ Hash<String, Chef::Resource>
The full collection of resources for this Runner.
185 186 187 |
# File 'lib/chefspec/solo_runner.rb', line 185 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.
309 310 311 |
# File 'lib/chefspec/solo_runner.rb', line 309 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)
258 259 260 261 |
# File 'lib/chefspec/solo_runner.rb', line 258 def step_into?(resource) key = resource_name(resource) Array([:step_into]).map(&method(:resource_name)).include?(key) end |
#to_s ⇒ String
This runner as a string.
may change between versions of this gem.
278 279 280 |
# File 'lib/chefspec/solo_runner.rb', line 278 def to_s "#<#{self.class.name} run_list: [#{node.run_list}]>" end |