chefspec 3.0.0.beta.1 → 3.0.0.beta.2
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/berkshelf.rb +24 -8
- data/lib/chefspec/extensions/chef/resource.rb +15 -0
- data/lib/chefspec/matchers/notifications_matcher.rb +1 -0
- data/lib/chefspec/matchers/render_file_matcher.rb +16 -2
- data/lib/chefspec/matchers/resource_matcher.rb +44 -11
- data/lib/chefspec/runner.rb +62 -3
- data/lib/chefspec/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 500cc20cbae81f4fe09ee9a0ad02d0910b30f901
|
4
|
+
data.tar.gz: 1fd9ab8312366fd9b755b6ce0b1ac7fa88d5befd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9955d1c754d878ea7db155b89d79bd44e6868d0f1f8bf91fa2561ddf2bae1df303194dedb506a12d8c5dae87dbdebeaa6ddc9ae09d23c7422805093e3dc08de0
|
7
|
+
data.tar.gz: 6d9a11b65adec8e5910c7460a1aac740438bb005cc64070344ba2a939031f41e51c9b5196d7b1b169d92df63ff1608d947d2e7366c9d4e65d30e760f2af12cf6
|
data/lib/chefspec/berkshelf.rb
CHANGED
@@ -11,27 +11,43 @@ module ChefSpec
|
|
11
11
|
class Berkshelf
|
12
12
|
class << self
|
13
13
|
extend Forwardable
|
14
|
-
def_delegators :instance, :setup!
|
14
|
+
def_delegators :instance, :setup!, :teardown!
|
15
15
|
end
|
16
16
|
|
17
17
|
include Singleton
|
18
18
|
|
19
19
|
def initialize
|
20
|
-
|
20
|
+
@tmpdir = Dir.mktmpdir
|
21
21
|
end
|
22
22
|
|
23
|
+
#
|
24
|
+
# Setup and install the necessary dependencies in the temporary directory.
|
25
|
+
#
|
23
26
|
def setup!
|
24
|
-
tmpdir
|
27
|
+
FileUtils.rm_rf(@tmpdir) # Berkshelf 3.0 requires the directory to be empty
|
28
|
+
FileUtils.mkdir_p(@tmpdir)
|
25
29
|
|
26
30
|
::Berkshelf.ui.mute do
|
27
|
-
::Berkshelf::Berksfile.
|
31
|
+
if ::Berkshelf::Berksfile.method_defined?(:vendor)
|
32
|
+
::Berkshelf::Berksfile.from_file('Berksfile').vendor(@tmpdir)
|
33
|
+
else
|
34
|
+
::Berkshelf::Berksfile.from_file('Berksfile').install(path: @tmpdir)
|
35
|
+
end
|
28
36
|
end
|
29
37
|
|
30
|
-
::RSpec.configure
|
31
|
-
|
32
|
-
|
38
|
+
::RSpec.configure { |config| config.cookbook_path = @tmpdir }
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Destroy the installed Berkshelf at the temporary directory.
|
43
|
+
#
|
44
|
+
def teardown!
|
45
|
+
FileUtils.rm_rf(@tmpdir) if File.exists?(@tmpdir)
|
33
46
|
end
|
34
47
|
end
|
35
48
|
end
|
36
49
|
|
37
|
-
|
50
|
+
RSpec.configure do |config|
|
51
|
+
config.before(:suite) { ChefSpec::Berkshelf.setup! }
|
52
|
+
config.after(:suite) { ChefSpec::Berkshelf.teardown! }
|
53
|
+
end
|
@@ -17,6 +17,10 @@ class Chef::Resource
|
|
17
17
|
old_run_action(action, notification_type, notifying_resource)
|
18
18
|
end
|
19
19
|
|
20
|
+
if node.runner.compiling?
|
21
|
+
@compile_time = true
|
22
|
+
end
|
23
|
+
|
20
24
|
Chef::Log.info("Processing #{self} action #{action} (#{defined_at})")
|
21
25
|
|
22
26
|
# Append the currently run action to the existing resource actions,
|
@@ -24,4 +28,15 @@ class Chef::Resource
|
|
24
28
|
@action = [self.action, action].flatten.compact.map(&:to_sym).uniq
|
25
29
|
node.runner.resources[self.to_s] ||= self
|
26
30
|
end
|
31
|
+
|
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
|
41
|
+
end
|
27
42
|
end
|
@@ -20,13 +20,27 @@ module ChefSpec::Matchers
|
|
20
20
|
|
21
21
|
def failure_message_for_should
|
22
22
|
message = "expected Chef run to render '#{@path}'"
|
23
|
-
|
23
|
+
if @expected_content
|
24
|
+
message << " with:"
|
25
|
+
message << "\n\n"
|
26
|
+
message << @expected_content
|
27
|
+
message << "\n\n"
|
28
|
+
message << "but got:"
|
29
|
+
message << "\n\n"
|
30
|
+
message << @actual_content
|
31
|
+
message << "\n "
|
32
|
+
end
|
24
33
|
message
|
25
34
|
end
|
26
35
|
|
27
36
|
def failure_message_for_should_not
|
28
37
|
message = "expected file '#{@path}'"
|
29
|
-
|
38
|
+
if @expected_content
|
39
|
+
message << " with:"
|
40
|
+
message << "\n\n"
|
41
|
+
message << @expected_content
|
42
|
+
message << "\n\n"
|
43
|
+
end
|
30
44
|
message << " to not be in Chef run"
|
31
45
|
end
|
32
46
|
|
@@ -11,6 +11,18 @@ module ChefSpec::Matchers
|
|
11
11
|
self
|
12
12
|
end
|
13
13
|
|
14
|
+
def at_compile_time
|
15
|
+
raise ArgumentError, 'Cannot specify both .at_converge_time and .at_compile_time!' if @converge_time
|
16
|
+
@compile_time = true
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def at_converge_time
|
21
|
+
raise ArgumentError, 'Cannot specify both .at_compile_time and .at_converge_time!' if @compile_time
|
22
|
+
@converge_time = true
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
14
26
|
#
|
15
27
|
# Allow users to specify fancy #with matchers.
|
16
28
|
#
|
@@ -27,7 +39,7 @@ module ChefSpec::Matchers
|
|
27
39
|
@runner = runner
|
28
40
|
|
29
41
|
if resource
|
30
|
-
resource_actions.include?(@expected_action) && unmatched_parameters.empty?
|
42
|
+
resource_actions.include?(@expected_action) && unmatched_parameters.empty? && correct_phase?
|
31
43
|
else
|
32
44
|
false
|
33
45
|
end
|
@@ -36,12 +48,19 @@ module ChefSpec::Matchers
|
|
36
48
|
def failure_message_for_should
|
37
49
|
if resource
|
38
50
|
if resource_actions.include?(@expected_action)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
51
|
+
if unmatched_parameters.empty?
|
52
|
+
if @compile_time
|
53
|
+
"expected '#{resource.to_s}' to be run at compile time, but was converge time"
|
54
|
+
else
|
55
|
+
"expected '#{resource.to_s}' to be run at converge time, but was compile time"
|
56
|
+
end
|
57
|
+
else
|
58
|
+
"expected '#{resource.to_s}' to have parameters:" \
|
59
|
+
"\n\n" \
|
60
|
+
" " + unmatched_parameters.collect { |parameter, h|
|
61
|
+
"#{parameter} #{h[:expected].inspect}, was #{h[:actual].inspect}"
|
62
|
+
}.join("\n ")
|
63
|
+
end
|
45
64
|
else
|
46
65
|
"expected '#{resource.to_s}' actions #{resource_actions.inspect}" \
|
47
66
|
" to include ':#{@expected_action}'"
|
@@ -51,16 +70,20 @@ module ChefSpec::Matchers
|
|
51
70
|
" action ':#{@expected_action}' to be in Chef run. Other" \
|
52
71
|
" #{@resource_name} resources:" \
|
53
72
|
"\n\n" \
|
54
|
-
" " + similar_resources.map(&:to_s).join("\n ")
|
73
|
+
" " + similar_resources.map(&:to_s).join("\n ") + "\n "
|
55
74
|
end
|
56
75
|
end
|
57
76
|
|
58
77
|
def failure_message_for_should_not
|
59
78
|
if resource
|
60
|
-
"expected '#{resource.to_s}' actions #{resource_actions.inspect} to not exist"
|
79
|
+
message = "expected '#{resource.to_s}' actions #{resource_actions.inspect} to not exist"
|
61
80
|
else
|
62
|
-
"expected '#{resource.to_s}' to not exist"
|
81
|
+
message = "expected '#{resource.to_s}' to not exist"
|
63
82
|
end
|
83
|
+
|
84
|
+
message << " at compile time" if @compile_time
|
85
|
+
message << " at converge time" if @converge_time
|
86
|
+
message
|
64
87
|
end
|
65
88
|
|
66
89
|
def description
|
@@ -94,6 +117,16 @@ module ChefSpec::Matchers
|
|
94
117
|
end
|
95
118
|
end
|
96
119
|
|
120
|
+
def correct_phase?
|
121
|
+
if @compile_time
|
122
|
+
resource.compile_time?
|
123
|
+
elsif @converge_time
|
124
|
+
!resource.compile_time?
|
125
|
+
else
|
126
|
+
true
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
97
130
|
def safe_send(parameter)
|
98
131
|
resource.send(parameter)
|
99
132
|
rescue NoMethodError
|
@@ -107,7 +140,7 @@ module ChefSpec::Matchers
|
|
107
140
|
# @return [Array<Chef::Resource>]
|
108
141
|
#
|
109
142
|
def similar_resources
|
110
|
-
@_similar_resources ||= @runner.find_resources(@resource_name)
|
143
|
+
@_similar_resources ||= @runner.find_resources(@resource_name).values
|
111
144
|
end
|
112
145
|
|
113
146
|
#
|
data/lib/chefspec/runner.rb
CHANGED
@@ -100,6 +100,9 @@ module ChefSpec
|
|
100
100
|
# A reference to the calling Runner (for chaining purposes)
|
101
101
|
#
|
102
102
|
def apply(*recipe_names)
|
103
|
+
# Start compiling
|
104
|
+
@compiling = true
|
105
|
+
|
103
106
|
recipe_names.each do |recipe_name|
|
104
107
|
cookbook, recipe = Chef::Recipe.parse_recipe_name(recipe_name)
|
105
108
|
recipe_path = File.join(Dir.pwd, 'recipes', "#{recipe}.rb")
|
@@ -108,9 +111,18 @@ module ChefSpec
|
|
108
111
|
recipe.from_file(recipe_path)
|
109
112
|
end
|
110
113
|
|
114
|
+
# Reset the resource collection
|
111
115
|
@resources = {}
|
116
|
+
|
117
|
+
# Expand the run_list
|
118
|
+
expand_run_list!
|
119
|
+
|
120
|
+
# Setup the run_context
|
112
121
|
@run_context = Chef::RunContext.new(client.node, {}, client.events)
|
113
122
|
|
123
|
+
# We are done compiling now
|
124
|
+
@compiling = false
|
125
|
+
|
114
126
|
Chef::Runner.new(@run_context).converge
|
115
127
|
self
|
116
128
|
end
|
@@ -133,6 +145,9 @@ module ChefSpec
|
|
133
145
|
# A reference to the calling Runner (for chaining purposes)
|
134
146
|
#
|
135
147
|
def converge(*recipe_names)
|
148
|
+
# Start compiling
|
149
|
+
@compiling = true
|
150
|
+
|
136
151
|
node.run_list.reset!
|
137
152
|
recipe_names.each { |recipe_name| node.run_list.add(recipe_name) }
|
138
153
|
|
@@ -141,9 +156,15 @@ module ChefSpec
|
|
141
156
|
# Reset the resource collection
|
142
157
|
@resources = {}
|
143
158
|
|
144
|
-
|
159
|
+
# Expand the run_list
|
160
|
+
expand_run_list!
|
161
|
+
|
162
|
+
# Setup the run_context
|
145
163
|
@run_context = client.setup_run_context
|
146
164
|
|
165
|
+
# We are done compiling now
|
166
|
+
@compiling = false
|
167
|
+
|
147
168
|
Chef::Runner.new(@run_context).converge
|
148
169
|
self
|
149
170
|
end
|
@@ -156,7 +177,7 @@ module ChefSpec
|
|
156
177
|
def node
|
157
178
|
return @node if @node
|
158
179
|
|
159
|
-
@node = client.
|
180
|
+
@node = client.build_node
|
160
181
|
@node.instance_variable_set(:@runner, self)
|
161
182
|
@node.class.send(:attr_reader, :runner)
|
162
183
|
@node
|
@@ -232,10 +253,22 @@ module ChefSpec
|
|
232
253
|
!!options[:dry_run]
|
233
254
|
end
|
234
255
|
|
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
|
+
|
235
267
|
#
|
236
268
|
# This runner as a string.
|
237
269
|
#
|
238
|
-
# @return [String] Currently includes the run_list. Format of the string
|
270
|
+
# @return [String] Currently includes the run_list. Format of the string
|
271
|
+
# may change between versions of this gem.
|
239
272
|
#
|
240
273
|
def to_s
|
241
274
|
return "chef_run: #{node.run_list.to_s}" unless node.run_list.empty?
|
@@ -252,6 +285,14 @@ module ChefSpec
|
|
252
285
|
end
|
253
286
|
|
254
287
|
private
|
288
|
+
#
|
289
|
+
# The inferred path from the calling spec.
|
290
|
+
#
|
291
|
+
# @param [Array<String>] kaller
|
292
|
+
# the calling trace
|
293
|
+
#
|
294
|
+
# @return [String]
|
295
|
+
#
|
255
296
|
def calling_cookbook_path(kaller)
|
256
297
|
calling_spec = kaller.find { |line| line =~ /\/spec/ }
|
257
298
|
bits = calling_spec.split(':', 2).first.split(File::SEPARATOR)
|
@@ -260,6 +301,10 @@ module ChefSpec
|
|
260
301
|
File.expand_path(File.join(bits.slice(0, spec_dir), '..'))
|
261
302
|
end
|
262
303
|
|
304
|
+
#
|
305
|
+
# The +Chef::Client+ for this runner.
|
306
|
+
#
|
307
|
+
# @return [Chef::Runner]
|
263
308
|
#
|
264
309
|
def client
|
265
310
|
return @client if @client
|
@@ -270,5 +315,19 @@ module ChefSpec
|
|
270
315
|
@client.build_node
|
271
316
|
@client
|
272
317
|
end
|
318
|
+
|
319
|
+
#
|
320
|
+
# We really need a way to just expand the run_list, but that's done by
|
321
|
+
# +Chef::Client#build_node+. However, that same method also resets the
|
322
|
+
# automatic attributes, making it impossible to mock them. So we are
|
323
|
+
# stuck +instance_eval+ing against the client and manually expanding
|
324
|
+
# the mode object.
|
325
|
+
#
|
326
|
+
def expand_run_list!
|
327
|
+
client.instance_eval do
|
328
|
+
@run_list_expansion = @node.expand!('disk')
|
329
|
+
@expanded_run_list_with_versions = @run_list_expansion.recipes.with_version_constraints_strings
|
330
|
+
end
|
331
|
+
end
|
273
332
|
end
|
274
333
|
end
|
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.2
|
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-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: chef
|
@@ -219,6 +219,6 @@ rubyforge_project:
|
|
219
219
|
rubygems_version: 2.0.3
|
220
220
|
signing_key:
|
221
221
|
specification_version: 4
|
222
|
-
summary: chefspec-3.0.0.beta.
|
222
|
+
summary: chefspec-3.0.0.beta.2
|
223
223
|
test_files: []
|
224
224
|
has_rdoc:
|