chefspec 3.0.0.beta.1 → 3.0.0.beta.2

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: 804fd5cc6af81945c28e0e0e65d94e935ff0bb82
4
- data.tar.gz: d9d195301868641521b6159d67106e3ac7a6abd2
3
+ metadata.gz: 500cc20cbae81f4fe09ee9a0ad02d0910b30f901
4
+ data.tar.gz: 1fd9ab8312366fd9b755b6ce0b1ac7fa88d5befd
5
5
  SHA512:
6
- metadata.gz: 5f951adb7cdac28459d0e0df5172e6a2e1124776a4335dcc62a6ff06c80264ca7b39290de15df21cea551b51528252e304249c2fcf45ad3888ec3fe67b2970f5
7
- data.tar.gz: 7165b07393a29850245dd0fdff9d21f9222816acb723e9e381b5c195ff180f6e87be26e8013b9e5d99b73458fdde7861c510da479f7cd089f7cda21a327abf3a
6
+ metadata.gz: 9955d1c754d878ea7db155b89d79bd44e6868d0f1f8bf91fa2561ddf2bae1df303194dedb506a12d8c5dae87dbdebeaa6ddc9ae09d23c7422805093e3dc08de0
7
+ data.tar.gz: 6d9a11b65adec8e5910c7460a1aac740438bb005cc64070344ba2a939031f41e51c9b5196d7b1b169d92df63ff1608d947d2e7366c9d4e65d30e760f2af12cf6
@@ -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
- setup!
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 = Dir.mktmpdir
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.from_file('Berksfile').install(path: tmpdir)
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 do |config|
31
- config.cookbook_path = tmpdir
32
- end
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
- ChefSpec::Berkshelf.setup!
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
@@ -55,6 +55,7 @@ module ChefSpec::Matchers
55
55
  message << ", but did not."
56
56
  message << "\n\n"
57
57
  message << "Other notifications were:\n#{format_notifications}"
58
+ message << "\n "
58
59
  message
59
60
  end
60
61
 
@@ -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
- message << " with:\n\n#{@expected_content}\n\nbut got:\n\n#{@actual_content}" if @expected_content
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
- message << " with:\n\n#{@expected_content}\n\n" if @expected_content
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
- "expected '#{resource.to_s}' to have parameters:" \
40
- "\n\n" \
41
- " " + unmatched_parameters.collect { |parameter, h|
42
- "#{parameter} #{h[:expected].inspect}, was #{h[:actual].inspect}"
43
- }.join("\n ")
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
  #
@@ -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
- client.build_node
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.node
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 may change between versions of this gem.
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
@@ -1,3 +1,3 @@
1
1
  module ChefSpec
2
- VERSION = '3.0.0.beta.1'
2
+ VERSION = '3.0.0.beta.2'
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.1
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-10 00:00:00.000000000 Z
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.1
222
+ summary: chefspec-3.0.0.beta.2
223
223
  test_files: []
224
224
  has_rdoc: