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 +4 -4
- data/lib/chefspec.rb +2 -0
- data/lib/chefspec/berkshelf.rb +1 -3
- data/lib/chefspec/extensions/chef/provider.rb +20 -0
- data/lib/chefspec/extensions/chef/resource.rb +19 -30
- data/lib/chefspec/matchers/link_to_matcher.rb +4 -1
- data/lib/chefspec/matchers/notifications_matcher.rb +38 -21
- data/lib/chefspec/matchers/render_file_matcher.rb +1 -1
- data/lib/chefspec/matchers/resource_matcher.rb +7 -16
- data/lib/chefspec/reporter.rb +51 -0
- data/lib/chefspec/runner.rb +14 -40
- data/lib/chefspec/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7308d36040d62aec7a7c6cf1f8db5a055bc443db
|
4
|
+
data.tar.gz: 2431011f1b6831872267062ebd68bd8081858bb3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ab357238fb71ea97cda205efa9fcf964ca892ac072ab551c4a7476269580f3531edde90bb53f52334cde560e6a1195e9f7c736eade511048907c221eb227656
|
7
|
+
data.tar.gz: e56256e20086ca15252e5dea80822b7d1545b7aa8c28e22c825c165a76d428f8d05a826750fba45bb5050ae7de64b3ab6a73cd25c1839a44dadfa10807ebbe8b
|
data/lib/chefspec.rb
CHANGED
@@ -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'
|
data/lib/chefspec/berkshelf.rb
CHANGED
@@ -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
|
-
|
4
|
+
alias_method :old_initialize, :initialize
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
16
|
+
def unperform_action(action)
|
17
|
+
@performed_actions.delete(action.to_sym)
|
18
|
+
end
|
23
19
|
|
24
|
-
|
20
|
+
def performed_action(action)
|
21
|
+
@performed_actions[action.to_sym]
|
22
|
+
end
|
25
23
|
|
26
|
-
|
27
|
-
|
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
|
-
|
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
|
@@ -9,18 +9,20 @@ module ChefSpec::Matchers
|
|
9
9
|
def matches?(resource)
|
10
10
|
@resource = resource
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
-
"
|
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
|
-
|
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
|
-
|
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
|
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 #{
|
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 #{
|
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
|
-
|
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)
|
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
|
data/lib/chefspec/runner.rb
CHANGED
@@ -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]
|
78
|
-
Chef::Config[:
|
79
|
-
Chef::Config[:
|
80
|
-
Chef::Config[:
|
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
|
-
|
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
|
-
|
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
|
192
|
-
@
|
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
|
-
|
195
|
+
begin
|
196
|
+
return resource_collection.lookup("#{type}[#{name}]")
|
197
|
+
rescue Chef::Exceptions::ResourceNotFound; end
|
213
198
|
|
214
|
-
|
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
|
-
|
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
|
#
|
data/lib/chefspec/version.rb
CHANGED
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.
|
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-
|
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.
|
224
|
+
summary: chefspec-3.0.0.beta.3
|
223
225
|
test_files: []
|
224
226
|
has_rdoc:
|