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

Sign up to get free protection for your applications and to get access to all the features.
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: