chefspec 3.0.0.beta.2 → 3.0.0.beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 500cc20cbae81f4fe09ee9a0ad02d0910b30f901
4
- data.tar.gz: 1fd9ab8312366fd9b755b6ce0b1ac7fa88d5befd
3
+ metadata.gz: 7308d36040d62aec7a7c6cf1f8db5a055bc443db
4
+ data.tar.gz: 2431011f1b6831872267062ebd68bd8081858bb3
5
5
  SHA512:
6
- metadata.gz: 9955d1c754d878ea7db155b89d79bd44e6868d0f1f8bf91fa2561ddf2bae1df303194dedb506a12d8c5dae87dbdebeaa6ddc9ae09d23c7422805093e3dc08de0
7
- data.tar.gz: 6d9a11b65adec8e5910c7460a1aac740438bb005cc64070344ba2a939031f41e51c9b5196d7b1b169d92df63ff1608d947d2e7366c9d4e65d30e760f2af12cf6
6
+ metadata.gz: 1ab357238fb71ea97cda205efa9fcf964ca892ac072ab551c4a7476269580f3531edde90bb53f52334cde560e6a1195e9f7c736eade511048907c221eb227656
7
+ data.tar.gz: e56256e20086ca15252e5dea80822b7d1545b7aa8c28e22c825c165a76d428f8d05a826750fba45bb5050ae7de64b3ab6a73cd25c1839a44dadfa10807ebbe8b
@@ -4,6 +4,7 @@ require_relative 'chefspec/extensions/chef/client'
4
4
  require_relative 'chefspec/extensions/chef/conditional'
5
5
  require_relative 'chefspec/extensions/chef/data_query'
6
6
  require_relative 'chefspec/extensions/chef/lwrp_base'
7
+ require_relative 'chefspec/extensions/chef/provider'
7
8
  require_relative 'chefspec/extensions/chef/resource'
8
9
  require_relative 'chefspec/extensions/chef/securable'
9
10
 
@@ -25,6 +26,7 @@ require_relative 'chefspec/formatter'
25
26
  require_relative 'chefspec/macros'
26
27
  require_relative 'chefspec/matchers'
27
28
  require_relative 'chefspec/renderer'
29
+ require_relative 'chefspec/reporter'
28
30
  require_relative 'chefspec/rspec'
29
31
  require_relative 'chefspec/runner'
30
32
  require_relative 'chefspec/version'
@@ -24,11 +24,9 @@ module ChefSpec
24
24
  # Setup and install the necessary dependencies in the temporary directory.
25
25
  #
26
26
  def setup!
27
- FileUtils.rm_rf(@tmpdir) # Berkshelf 3.0 requires the directory to be empty
28
- FileUtils.mkdir_p(@tmpdir)
29
-
30
27
  ::Berkshelf.ui.mute do
31
28
  if ::Berkshelf::Berksfile.method_defined?(:vendor)
29
+ FileUtils.rm_rf(@tmpdir) # Berkshelf 3.0 requires the directory to not exist
32
30
  ::Berkshelf::Berksfile.from_file('Berksfile').vendor(@tmpdir)
33
31
  else
34
32
  ::Berkshelf::Berksfile.from_file('Berksfile').install(path: @tmpdir)
@@ -0,0 +1,20 @@
1
+ require 'chef/provider'
2
+
3
+ class Chef::Provider
4
+ alias_method :old_run_action, :run_action unless method_defined?(:old_run_action)
5
+
6
+ def run_action(action = nil)
7
+ Chef::Log.debug("Running action '#{action}' for #{self} (skipping because ChefSpec)")
8
+ @new_resource.updated_by_last_action(true)
9
+
10
+ if node.runner.step_into.include?(@new_resource.resource_name.to_s)
11
+ Chef::Log.debug("Stepping into LWRP #{@new_resource.resource_name.to_s}")
12
+
13
+ if whyrun_supported?
14
+ Chef::Log.warn("#{self} does not support whyrun mode. This could be dangerous!")
15
+ end
16
+
17
+ old_run_action(action)
18
+ end
19
+ end
20
+ end
@@ -1,42 +1,31 @@
1
1
  require 'chef/resource'
2
2
 
3
3
  class Chef::Resource
4
- alias :old_run_action :run_action unless method_defined?(:old_run_action)
4
+ alias_method :old_initialize, :initialize
5
5
 
6
- #
7
- # Pretend to run resource actions, adding them to the resource collection
8
- # to prevent actually executing resources
9
- #
10
- # @see Chef::Resource#run_action
11
- #
12
- def run_action(action, notification_type = nil, notifying_resource = nil)
13
- return if should_skip?(action)
6
+ def initialize(*args)
7
+ @performed_actions = {}
8
+ old_initialize(*args)
9
+ end
14
10
 
15
- if node.runner.step_into.include?(self.resource_name.to_s)
16
- instance_eval { @not_if = []; @only_if = [] }
17
- old_run_action(action, notification_type, notifying_resource)
18
- end
11
+ def perform_action(action, options = {})
12
+ @performed_actions[action.to_sym] ||= {}
13
+ @performed_actions[action.to_sym].merge!(options)
14
+ end
19
15
 
20
- if node.runner.compiling?
21
- @compile_time = true
22
- end
16
+ def unperform_action(action)
17
+ @performed_actions.delete(action.to_sym)
18
+ end
23
19
 
24
- Chef::Log.info("Processing #{self} action #{action} (#{defined_at})")
20
+ def performed_action(action)
21
+ @performed_actions[action.to_sym]
22
+ end
25
23
 
26
- # Append the currently run action to the existing resource actions,
27
- # making sure it's a unique array of symbols.
28
- @action = [self.action, action].flatten.compact.map(&:to_sym).uniq
29
- node.runner.resources[self.to_s] ||= self
24
+ def performed_action?(action)
25
+ !!performed_action(action)
30
26
  end
31
27
 
32
- #
33
- # Determine if the current resource is a compile-time resource (as opposed
34
- # to a converge time resource). Compile-time resources are executed with the
35
- # +run_action+ command at load time, rather than at comverge time.
36
- #
37
- # @return [Boolean]
38
- #
39
- def compile_time?
40
- !!@compile_time
28
+ def performed_actions
29
+ @performed_actions.keys
41
30
  end
42
31
  end
@@ -6,7 +6,10 @@ module ChefSpec::Matchers
6
6
 
7
7
  def matches?(link)
8
8
  @link = link
9
- @link.is_a?(Chef::Resource::Link) && @path === @link.to
9
+
10
+ @link.is_a?(Chef::Resource::Link) &&
11
+ @link.performed_action?(:create) &&
12
+ @path === @link.to
10
13
  end
11
14
 
12
15
  def description
@@ -9,18 +9,20 @@ module ChefSpec::Matchers
9
9
  def matches?(resource)
10
10
  @resource = resource
11
11
 
12
- block = Proc.new do |notified|
13
- notified.resource.resource_name.to_s == @expected_resource_type &&
14
- (@expected_resource_name === notified.resource.identity.to_s || @expected_resource_name === notified.resource.name.to_s) &&
15
- matches_action?(notified)
16
- end
12
+ if @resource
13
+ block = Proc.new do |notified|
14
+ notified.resource.resource_name.to_s == @expected_resource_type &&
15
+ (@expected_resource_name === notified.resource.identity.to_s || @expected_resource_name === notified.resource.name.to_s) &&
16
+ matches_action?(notified)
17
+ end
17
18
 
18
- if @immediately
19
- immediate_notifications.any?(&block)
20
- elsif @delayed
21
- delayed_notifications.any?(&block)
22
- else
23
- all_notifications.any?(&block)
19
+ if @immediately
20
+ immediate_notifications.any?(&block)
21
+ elsif @delayed
22
+ delayed_notifications.any?(&block)
23
+ else
24
+ all_notifications.any?(&block)
25
+ end
24
26
  end
25
27
  end
26
28
 
@@ -48,15 +50,29 @@ module ChefSpec::Matchers
48
50
  end
49
51
 
50
52
  def failure_message_for_should
51
- message = "expected '#{@resource.resource_name}[#{@resource.name}]' to notify '#{@expected_resource_type}[#{@expected_resource_name}]'"
52
- message << " with action #{@action.inspect}" if @action
53
- message << " immediately" if @immediately
54
- message << " delayed" if @delayed
55
- message << ", but did not."
56
- message << "\n\n"
57
- message << "Other notifications were:\n#{format_notifications}"
58
- message << "\n "
59
- message
53
+ if @resource
54
+ message = "expected '#{@resource.resource_name}[#{@resource.name}]' to notify '#{@expected_resource_type}[#{@expected_resource_name}]'"
55
+ message << " with action #{@action.inspect}" if @action
56
+ message << " immediately" if @immediately
57
+ message << " delayed" if @delayed
58
+ message << ", but did not."
59
+ message << "\n\n"
60
+ message << "Other notifications were:\n\n#{format_notifications}"
61
+ message << "\n "
62
+ message
63
+ else
64
+ message = "expected _something_ to notify '#{@expected_resource_type}[#{@expected_resource_name}]"
65
+ message << " with action #{@action.inspect}" if @action
66
+ message << " immediately" if @immediately
67
+ message << " delayed" if @delayed
68
+ message << ", but the _something_ you gave me was nil! If you are running a test like:"
69
+ message << "\n\n"
70
+ message << " expect(_something_).to notify('...')"
71
+ message << "\n\n"
72
+ message << "Make sure that `_something_` exists, because I got nil"
73
+ message << "\n "
74
+ message
75
+ end
60
76
  end
61
77
 
62
78
  private
@@ -78,10 +94,11 @@ module ChefSpec::Matchers
78
94
  end
79
95
 
80
96
  def format_notification(notification)
97
+ notifying_resource = notification.notifying_resource
81
98
  resource = notification.resource
82
99
  type = notification.notifying_resource.immediate_notifications.include?(notification) ? :immediately : :delayed
83
100
 
84
- "notifies :#{notification.action}, '#{resource.resource_name}[#{resource.name}]', :#{type}"
101
+ " #{notifying_resource.to_s} notifies '#{resource.resource_name}[#{resource.name}]' to :#{notification.action}, :#{type}"
85
102
  end
86
103
 
87
104
  def format_notifications
@@ -59,7 +59,7 @@ module ChefSpec::Matchers
59
59
  # @return [Boolean]
60
60
  #
61
61
  def has_create_action?
62
- !([:create, :create_if_missing] & Array(resource.action).map(&:to_sym)).empty?
62
+ [:create, :create_if_missing].any? { |action| resource.performed_action?(action) }
63
63
  end
64
64
 
65
65
  #
@@ -39,7 +39,7 @@ module ChefSpec::Matchers
39
39
  @runner = runner
40
40
 
41
41
  if resource
42
- resource_actions.include?(@expected_action) && unmatched_parameters.empty? && correct_phase?
42
+ resource.performed_action?(@expected_action) && unmatched_parameters.empty? && correct_phase?
43
43
  else
44
44
  false
45
45
  end
@@ -47,7 +47,7 @@ module ChefSpec::Matchers
47
47
 
48
48
  def failure_message_for_should
49
49
  if resource
50
- if resource_actions.include?(@expected_action)
50
+ if resource.performed_action?(@expected_action)
51
51
  if unmatched_parameters.empty?
52
52
  if @compile_time
53
53
  "expected '#{resource.to_s}' to be run at compile time, but was converge time"
@@ -62,7 +62,7 @@ module ChefSpec::Matchers
62
62
  }.join("\n ")
63
63
  end
64
64
  else
65
- "expected '#{resource.to_s}' actions #{resource_actions.inspect}" \
65
+ "expected '#{resource.to_s}' actions #{resource.performed_actions.inspect}" \
66
66
  " to include ':#{@expected_action}'"
67
67
  end
68
68
  else
@@ -76,7 +76,7 @@ module ChefSpec::Matchers
76
76
 
77
77
  def failure_message_for_should_not
78
78
  if resource
79
- message = "expected '#{resource.to_s}' actions #{resource_actions.inspect} to not exist"
79
+ message = "expected '#{resource.to_s}' actions #{resource.performed_actions.inspect} to not exist"
80
80
  else
81
81
  message = "expected '#{resource.to_s}' to not exist"
82
82
  end
@@ -119,9 +119,9 @@ module ChefSpec::Matchers
119
119
 
120
120
  def correct_phase?
121
121
  if @compile_time
122
- resource.compile_time?
122
+ resource.performed_action(@expected_action)[:compile_time]
123
123
  elsif @converge_time
124
- !resource.compile_time?
124
+ resource.performed_action(@expected_action)[:converge_time]
125
125
  else
126
126
  true
127
127
  end
@@ -140,7 +140,7 @@ module ChefSpec::Matchers
140
140
  # @return [Array<Chef::Resource>]
141
141
  #
142
142
  def similar_resources
143
- @_similar_resources ||= @runner.find_resources(@resource_name).values
143
+ @_similar_resources ||= @runner.find_resources(@resource_name)
144
144
  end
145
145
 
146
146
  #
@@ -155,15 +155,6 @@ module ChefSpec::Matchers
155
155
  @_resource ||= @runner.find_resource(@resource_name, @expected_identity)
156
156
  end
157
157
 
158
- #
159
- # The list of actions on this resource.
160
- #
161
- # @return [Array<Symbol>]
162
- #
163
- def resource_actions
164
- @_resource_actions ||= Array(resource.action).map(&:to_sym)
165
- end
166
-
167
158
  #
168
159
  # The list of parameters passed to the {with} matcher.
169
160
  #
@@ -0,0 +1,51 @@
1
+ require 'chef/event_dispatch/base'
2
+
3
+ module ChefSpec
4
+ class Reporter < ::Chef::EventDispatch::Base
5
+ #
6
+ # Called when a resource is converged ({Chef::Resource#run_action}).
7
+ # This appends the action to the resource's +performed_actions+ so that
8
+ # ChefSpec can assert the resource received the proper message.
9
+ #
10
+ # @param [Chef::Resource] resource
11
+ # the resource to report on
12
+ # @param [Symbol] action
13
+ # the action
14
+ #
15
+ def resource_action_start(resource, action, notification_type = nil, notifier = nil)
16
+ if @converging
17
+ resource.perform_action(action, converge_time: true)
18
+ else
19
+ resource.perform_action(action, compile_time: true)
20
+ end
21
+ end
22
+
23
+ #
24
+ # Called when a resource action is skipped (due to a resource guard
25
+ # or +action :nothing+). This removes the given action from the list
26
+ # of +performed_actions+ on the resource.
27
+ #
28
+ # @param [Chef::Resource] resource
29
+ # the resource to report on
30
+ # @param [Symbol] action
31
+ # the action
32
+ # @param [Chef::Resource::Conditional] conditional
33
+ # the conditional that ran
34
+ #
35
+ def resource_skipped(resource, action, conditional)
36
+ resource.unperform_action(action)
37
+ end
38
+
39
+ #
40
+ # Called when we start convering. This method sets an instance variable
41
+ # that other classes use to determine if a resource action was run during
42
+ # compile time or converge time.
43
+ #
44
+ # @param [Chef::RunContext] run_context
45
+ # the Chef run context
46
+ #
47
+ def converge_start(run_context)
48
+ @converging = true
49
+ end
50
+ end
51
+ end
@@ -74,10 +74,11 @@ module ChefSpec
74
74
  Chef::Config.reset!
75
75
  Chef::Config.formatters.clear
76
76
  Chef::Config.add_formatter('chefspec')
77
- Chef::Config[:cache_type] = 'Memory'
78
- Chef::Config[:cookbook_path] = Array(options[:cookbook_path])
79
- Chef::Config[:force_logger] = true
80
- Chef::Config[:solo] = true
77
+ Chef::Config[:cache_type] = 'Memory'
78
+ Chef::Config[:event_handlers] = ChefSpec::Reporter.new
79
+ Chef::Config[:cookbook_path] = Array(options[:cookbook_path])
80
+ Chef::Config[:force_logger] = true
81
+ Chef::Config[:solo] = true
81
82
 
82
83
  yield node if block_given?
83
84
  end
@@ -100,9 +101,6 @@ module ChefSpec
100
101
  # A reference to the calling Runner (for chaining purposes)
101
102
  #
102
103
  def apply(*recipe_names)
103
- # Start compiling
104
- @compiling = true
105
-
106
104
  recipe_names.each do |recipe_name|
107
105
  cookbook, recipe = Chef::Recipe.parse_recipe_name(recipe_name)
108
106
  recipe_path = File.join(Dir.pwd, 'recipes', "#{recipe}.rb")
@@ -111,19 +109,13 @@ module ChefSpec
111
109
  recipe.from_file(recipe_path)
112
110
  end
113
111
 
114
- # Reset the resource collection
115
- @resources = {}
116
-
117
112
  # Expand the run_list
118
113
  expand_run_list!
119
114
 
120
115
  # Setup the run_context
121
116
  @run_context = Chef::RunContext.new(client.node, {}, client.events)
122
117
 
123
- # We are done compiling now
124
- @compiling = false
125
-
126
- Chef::Runner.new(@run_context).converge
118
+ @client.converge(@run_context)
127
119
  self
128
120
  end
129
121
 
@@ -145,27 +137,18 @@ module ChefSpec
145
137
  # A reference to the calling Runner (for chaining purposes)
146
138
  #
147
139
  def converge(*recipe_names)
148
- # Start compiling
149
- @compiling = true
150
-
151
140
  node.run_list.reset!
152
141
  recipe_names.each { |recipe_name| node.run_list.add(recipe_name) }
153
142
 
154
143
  return self if dry_run?
155
144
 
156
- # Reset the resource collection
157
- @resources = {}
158
-
159
145
  # Expand the run_list
160
146
  expand_run_list!
161
147
 
162
148
  # Setup the run_context
163
149
  @run_context = client.setup_run_context
164
150
 
165
- # We are done compiling now
166
- @compiling = false
167
-
168
- Chef::Runner.new(@run_context).converge
151
+ @client.converge(@run_context)
169
152
  self
170
153
  end
171
154
 
@@ -188,8 +171,8 @@ module ChefSpec
188
171
  #
189
172
  # @return [Hash<String, Chef::Resource>]
190
173
  #
191
- def resources
192
- @resources ||= {}
174
+ def resource_collection
175
+ @resource_collection ||= @run_context.resource_collection
193
176
  end
194
177
 
195
178
  #
@@ -209,9 +192,11 @@ module ChefSpec
209
192
  # The matching resource, or nil if one is not found
210
193
  #
211
194
  def find_resource(type, name)
212
- return resources["#{type}[#{name}]"] if resources["#{type}[#{name}]"]
195
+ begin
196
+ return resource_collection.lookup("#{type}[#{name}]")
197
+ rescue Chef::Exceptions::ResourceNotFound; end
213
198
 
214
- resources.values.find do |resource|
199
+ resource_collection.all_resources.find do |resource|
215
200
  resource.resource_name.to_sym == type && (name === resource.identity || name === resource.name)
216
201
  end
217
202
  end
@@ -230,7 +215,7 @@ module ChefSpec
230
215
  # The matching resources
231
216
  #
232
217
  def find_resources(type)
233
- resources.select do |_, resource|
218
+ resource_collection.all_resources.select do |resource|
234
219
  resource.resource_name.to_s == type.to_s
235
220
  end
236
221
  end
@@ -253,17 +238,6 @@ module ChefSpec
253
238
  !!options[:dry_run]
254
239
  end
255
240
 
256
- #
257
- # Boolean method to determine if the Runner is still compiling recipes.
258
- # This is used by the +Resource+ class to determine if a resource was
259
- # invoked at compile-time or converge-time.
260
- #
261
- # @return [Boolean]
262
- #
263
- def compiling?
264
- !!@compiling
265
- end
266
-
267
241
  #
268
242
  # This runner as a string.
269
243
  #
@@ -1,3 +1,3 @@
1
1
  module ChefSpec
2
- VERSION = '3.0.0.beta.2'
2
+ VERSION = '3.0.0.beta.3'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chefspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.beta.2
4
+ version: 3.0.0.beta.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Crump
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-15 00:00:00.000000000 Z
12
+ date: 2013-10-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: chef
@@ -171,6 +171,7 @@ files:
171
171
  - lib/chefspec/extensions/chef/conditional.rb
172
172
  - lib/chefspec/extensions/chef/data_query.rb
173
173
  - lib/chefspec/extensions/chef/lwrp_base.rb
174
+ - lib/chefspec/extensions/chef/provider.rb
174
175
  - lib/chefspec/extensions/chef/resource.rb
175
176
  - lib/chefspec/extensions/chef/securable.rb
176
177
  - lib/chefspec/formatter.rb
@@ -182,6 +183,7 @@ files:
182
183
  - lib/chefspec/matchers/resource_matcher.rb
183
184
  - lib/chefspec/matchers.rb
184
185
  - lib/chefspec/renderer.rb
186
+ - lib/chefspec/reporter.rb
185
187
  - lib/chefspec/rspec.rb
186
188
  - lib/chefspec/runner.rb
187
189
  - lib/chefspec/stubs/command_registry.rb
@@ -219,6 +221,6 @@ rubyforge_project:
219
221
  rubygems_version: 2.0.3
220
222
  signing_key:
221
223
  specification_version: 4
222
- summary: chefspec-3.0.0.beta.2
224
+ summary: chefspec-3.0.0.beta.3
223
225
  test_files: []
224
226
  has_rdoc: