chefspec 4.2.0 → 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +20 -15
  3. data/CHANGELOG.md +22 -0
  4. data/README.md +50 -8
  5. data/chefspec.gemspec +1 -1
  6. data/examples/chef_gem/recipes/install.rb +8 -3
  7. data/examples/chef_gem/recipes/purge.rb +6 -3
  8. data/examples/chef_gem/recipes/reconfig.rb +6 -3
  9. data/examples/chef_gem/recipes/remove.rb +6 -3
  10. data/examples/chef_gem/recipes/upgrade.rb +6 -3
  11. data/examples/directory/recipes/create.rb +4 -0
  12. data/examples/directory/spec/create_spec.rb +4 -0
  13. data/examples/reboot/recipes/cancel.rb +3 -0
  14. data/examples/reboot/recipes/now.rb +3 -0
  15. data/examples/reboot/recipes/request.rb +3 -0
  16. data/examples/reboot/spec/cancel_spec.rb +10 -0
  17. data/examples/reboot/spec/now_spec.rb +10 -0
  18. data/examples/reboot/spec/request_spec.rb +10 -0
  19. data/examples/render_file/spec/default_spec.rb +40 -0
  20. data/examples/server/spec/search_spec.rb +4 -0
  21. data/examples/windows_service/recipes/configure_startup.rb +13 -0
  22. data/examples/windows_service/recipes/disable.rb +13 -0
  23. data/examples/windows_service/recipes/enable.rb +13 -0
  24. data/examples/windows_service/recipes/reload.rb +13 -0
  25. data/examples/windows_service/recipes/restart.rb +13 -0
  26. data/examples/windows_service/recipes/start.rb +13 -0
  27. data/examples/windows_service/recipes/stop.rb +13 -0
  28. data/examples/windows_service/spec/configure_startup_spec.rb +19 -0
  29. data/examples/windows_service/spec/disable_spec.rb +19 -0
  30. data/examples/windows_service/spec/enable_spec.rb +19 -0
  31. data/examples/windows_service/spec/reload_spec.rb +19 -0
  32. data/examples/windows_service/spec/restart_spec.rb +19 -0
  33. data/examples/windows_service/spec/start_spec.rb +19 -0
  34. data/examples/windows_service/spec/stop_spec.rb +19 -0
  35. data/features/reboot.feature +19 -0
  36. data/features/windows_service.feature +23 -0
  37. data/gemfiles/chefspec.gemfile +9 -0
  38. data/lib/chefspec.rb +1 -1
  39. data/lib/chefspec/api.rb +2 -0
  40. data/lib/chefspec/api/reboot.rb +18 -0
  41. data/lib/chefspec/api/windows_service.rb +286 -0
  42. data/lib/chefspec/coverage.rb +1 -1
  43. data/lib/chefspec/coverage/filters.rb +2 -1
  44. data/lib/chefspec/matchers/render_file_matcher.rb +19 -2
  45. data/lib/chefspec/mixins/normalize.rb +7 -1
  46. data/lib/chefspec/renderer.rb +2 -4
  47. data/lib/chefspec/rspec.rb +1 -0
  48. data/lib/chefspec/server_methods.rb +1 -0
  49. data/lib/chefspec/solo_runner.rb +5 -1
  50. data/lib/chefspec/version.rb +1 -1
  51. data/spec/unit/coverage/filters_spec.rb +60 -0
  52. data/spec/unit/renderer_spec.rb +20 -2
  53. data/spec/unit/solo_runner_spec.rb +2 -0
  54. metadata +33 -8
  55. data/gemfiles/chef-11.14.0.gemfile +0 -5
  56. data/gemfiles/chef-11.16.0.gemfile +0 -5
  57. data/gemfiles/chef-12.0.0.gemfile +0 -5
  58. data/gemfiles/chef-master.gemfile +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 75d0edf1b239bc0e3f2925b5369b05446c94e5af
4
- data.tar.gz: 05c29cdc3052844db10148b184b9b8476c88c016
3
+ metadata.gz: aa3e59bb811bc68639e3c2c4214f10cbf7e89731
4
+ data.tar.gz: c1129471fe9e8ed5cc656048ac19dfdd566f4a81
5
5
  SHA512:
6
- metadata.gz: fddcc55b0216f17d1d39eb0c8d5515a2efd09eb8f9db6e7ffc4affcc2c4c2f4c140d8e3a4abca91404b96040e8a3d5596dac00e5314fe617f7fd3c7df58fbe9d
7
- data.tar.gz: 49e6647e765e13381955b457ac19df13f000f974344030648356afc589ee1c646676a40033bf667df0f1f274b4a62cb9e9eda38b48eadaf437628e962435be7e
6
+ metadata.gz: 55e9765354fac8ee356d820c3e37a84932458bcf2ad6df72e38790cb6eb316f30534bb13bccf1250ca4da5ac132f940460377480a451c78563a8fa50571e40ba
7
+ data.tar.gz: ad94b0e9a758bfbca910593de93bdb30dfea1599461bcfc24014b6efc95a0d5372807aff0c7b3caffe3e5582c811fdaf411c9745b24798f1892b1c12b52431ff
data/.travis.yml CHANGED
@@ -1,31 +1,36 @@
1
+ language: ruby
2
+ cache: bundler
1
3
  sudo: false
2
4
 
3
5
  rvm:
4
6
  - 2.0.0
5
7
  - 2.1
8
+ - 2.2
6
9
 
7
10
  branches:
8
11
  only:
9
12
  - master
10
13
 
11
- notifications:
12
- irc:
13
- channels:
14
- - "chat.freenode.net#chefspec"
15
- use_notice: true
16
- skip_join: true
17
- template:
18
- - "%{message} (%{author}): %{build_url}"
19
-
20
14
  bundler_args: --jobs 7 --retry 3
21
15
 
22
- gemfile:
23
- - gemfiles/chef-11.14.0.gemfile
24
- - gemfiles/chef-11.16.0.gemfile
25
- - gemfiles/chef-12.0.0.gemfile
26
- - gemfiles/chef-master.gemfile
16
+ gemfile: gemfiles/chefspec.gemfile
17
+
18
+ env:
19
+ - CHEF_VERSION=master
20
+ - CHEF_VERSION=12.2.1
21
+ - CHEF_VERSION=12.1.2
22
+ - CHEF_VERSION=12.1.1
23
+ - CHEF_VERSION=12.1.0
24
+ - CHEF_VERSION=12.0.3
25
+ - CHEF_VERSION=11.18.6
26
+ - CHEF_VERSION=11.18.0
27
+ - CHEF_VERSION=11.16.4
28
+ - CHEF_VERSION=11.16.2
29
+ - CHEF_VERSION=11.16.0
30
+ - CHEF_VERSION=11.14.6
31
+ - CHEF_VERSION=11.14.2
27
32
 
28
33
  matrix:
29
34
  fast_finish: true
30
35
  allow_failures:
31
- - gemfile: gemfiles/chef-master.gemfile
36
+ - env: CHEF_VERSION=master
data/CHANGELOG.md CHANGED
@@ -1,6 +1,28 @@
1
1
  CHANGELOG for ChefSpec
2
2
  ======================
3
3
 
4
+ ## 4.3.0 (July 16, 2015)
5
+
6
+ Bugfixes:
7
+ - Improved documentation
8
+ - Use TemplateContext's `_extend_modules` for passing on template helper
9
+ modules to nested partial templates
10
+ - Only exit if the status is a failure [GH-565]
11
+ - Fix load order on Windows when using the `rights` attributes
12
+ - Improve testing matrix and remove deprecated Chef versions
13
+ - Supress chef_gem compile_time warnings
14
+ - Fix exceptions on converge for Chef 12.1.0 masking
15
+ - Update Librarian `Cheffile` site URL to supermerket.chef.io
16
+ - Filter Windows and Unix paths for test coverage report with Berkshelf
17
+
18
+ Improvements:
19
+ - Added possibility to specify file_cache_path globally
20
+ - Added new capabilities for reboot resouce
21
+ - Use `Chef::Resource#declared_type` first if available (Chef >= 12),
22
+ otherwise fall back to `Chef::Resource#resource_name` (Chef <= 11)
23
+ - Extend render_file to yield the content as a block
24
+ - Add windows_service resource
25
+
4
26
  ## 4.2.0 (December 25, 2014)
5
27
  Bugfixes:
6
28
  - Updated README grep examples
data/README.md CHANGED
@@ -2,13 +2,9 @@ ChefSpec
2
2
  ========
3
3
  [![Gem Version](http://img.shields.io/gem/v/chefspec.svg)][gem]
4
4
  [![Build Status](http://img.shields.io/travis/sethvargo/chefspec.svg)][travis]
5
- [![Dependency Status](http://img.shields.io/gemnasium/sethvargo/chefspec.svg)][gemnasium]
6
- [![Code Climate](http://img.shields.io/codeclimate/github/sethvargo/chefspec.svg)][codeclimate]
7
5
 
8
6
  [gem]: https://rubygems.org/gems/chefspec
9
7
  [travis]: http://travis-ci.org/sethvargo/chefspec
10
- [gemnasium]: https://gemnasium.com/sethvargo/chefspec
11
- [codeclimate]: https://codeclimate.com/github/sethvargo/chefspec
12
8
 
13
9
  ChefSpec is a unit testing framework for testing Chef cookbooks. ChefSpec makes it easy to write examples and get fast feedback on cookbook changes without the need for virtual machines or cloud servers.
14
10
 
@@ -35,6 +31,15 @@ Important Notes
35
31
  - **ChefSpec aims to maintain compatability with the two most recent minor versions of Chef.** If you are running an older version of Chef it may work, or you will need to run an older version of ChefSpec.
36
32
 
37
33
 
34
+ Notes on Compatability with Chef Versions
35
+ -----------------------------------------
36
+ As a general rule, if it is tested in the Travis CI matrix, it is a supported version. The section below details any specific versions that are _not_ supported and why:
37
+
38
+ - Chef 12 prior to Chef 12.0.2 is not supported due to the lack of a declared resource type. This was fixed in [Chef 12.0.2](https://github.com/chef/chef/blob/12.0.2/lib/chef/resource.rb#L422-428).
39
+
40
+ Additionally, if you look at a cucumber feature and see a tag like `@not_chef_x_y_z`, that means that particular functionality is not supported on those versions of Chef.
41
+
42
+
38
43
  Writing a Cookbook Example
39
44
  --------------------------
40
45
  If you want `knife` to automatically generate spec stubs for you, install [knife-spec](https://github.com/sethvargo/knife-spec).
@@ -84,6 +89,9 @@ RSpec.configure do |config|
84
89
  # Specify the path for Chef Solo to find environments (default: [ascending search])
85
90
  config.environment_path = '/var/environments'
86
91
 
92
+ # Specify the path for Chef Solo file cache path (default: nil)
93
+ config.file_cache_path = '/var/chef/cache'
94
+
87
95
  # Specify the Chef log_level (default: :warn)
88
96
  config.log_level = :debug
89
97
 
@@ -158,7 +166,7 @@ have to write your `Cheffile` like this:
158
166
 
159
167
  ```ruby
160
168
  # Cheffile
161
- site 'http://community.opscode.com/api/v1'
169
+ site 'https://supermarket.chef.io/api/v1'
162
170
 
163
171
  cookbook 'name_of_your_cookbook', path: '.'
164
172
  ```
@@ -248,6 +256,24 @@ Assert that the Chef run included a recipe from another cookbook
248
256
  expect(chef_run).to include_recipe('other_cookbook::recipe')
249
257
  ```
250
258
 
259
+ Keep the resources from an included recipe from being loaded into the Chef run, but test that the recipe was included
260
+
261
+ ```ruby
262
+ describe 'example::default' do
263
+ let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
264
+
265
+ before do
266
+ allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).and_call_original
267
+ allow_any_instance_of(Chef::Recipe).to receive(:include_recipe).with('other_cookbook::default')
268
+ end
269
+
270
+ it 'includes the other_cookbook' do
271
+ expect_any_instance_of(Chef::Recipe).to receive(:include_recipe).with('other_cookbook::default')
272
+ chef_run
273
+ end
274
+ end
275
+ ```
276
+
251
277
  ##### notify
252
278
  Assert that a resource notifies another in the Chef run
253
279
 
@@ -271,6 +297,10 @@ Assert that the Chef run renders a file (with optional content); this will match
271
297
  expect(chef_run).to render_file('/etc/foo')
272
298
  expect(chef_run).to render_file('/etc/foo').with_content('This is content')
273
299
  expect(chef_run).to render_file('/etc/foo').with_content(/regex works too.+/)
300
+ expect(chef_run).to render_file('/etc/foo').with_content { |content|
301
+ # Regular RSpec matches work in here
302
+ expect(content).to include('any RSpec matcher')
303
+ }
274
304
  ```
275
305
 
276
306
  You can use any RSpec content matcher inside of the `with_content` predicate:
@@ -411,7 +441,19 @@ ChefSpec::ServerRunner.new do |node, server|
411
441
  end
412
442
  ```
413
443
 
414
- Note: the current "node" is always uploaded to the server.
444
+ Note: the current "node" is always uploaded to the server. However, due to the way the Chef Client compiles cookbooks, you must update the current node on the server if any attributes are changed:
445
+
446
+ ```ruby
447
+ ChefSpec::ServerRunner.new do |node, server|
448
+ node.set['attribute'] = 'value'
449
+
450
+ # At this point, the server already has a copy of the current node object due
451
+ # to the way Chef compiled the resources. However, that node does not have
452
+ # this new value. As such, you must "save" the node back to the server to
453
+ # persist this attribute update.
454
+ server.update_node(node)
455
+ end
456
+ ```
415
457
 
416
458
  You may also use the `stub_node` macro, which will create a new `Chef::Node` object and accepts the same parameters as the Chef Runner and a Fauxhai object:
417
459
 
@@ -786,12 +828,12 @@ Other developers can write RSpec tests against your LWRP in their cookbooks:
786
828
  expect(chef_run).to write_motd_message('my message')
787
829
  ```
788
830
 
789
- **Don't forget to include documentation in your cookbook's README noting the custom matcher and it's API!**
831
+ **Don't forget to include documentation in your cookbook's README noting the custom matcher and its API!**
790
832
 
791
833
 
792
834
  Writing Custom Matchers
793
835
  -----------------------
794
- If you are testing a cookbook that does not package it's LWRP matchers, you can create your own following the same pattern as the "Packaging Custom Matchers" section. Simply, create a file at `spec/support/matchers.rb` and add your resource matchers:
836
+ If you are testing a cookbook that does not package its LWRP matchers, you can create your own following the same pattern as the "Packaging Custom Matchers" section. Simply, create a file at `spec/support/matchers.rb` and add your resource matchers:
795
837
 
796
838
  ```ruby
797
839
  # spec/support/matchers.rb
data/chefspec.gemspec CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
14
14
  'ChefSpec makes it easy to write examples and get fast ' \
15
15
  'feedback on cookbook changes without the need for ' \
16
16
  'virtual machines or cloud servers.'
17
- s.homepage = 'http://code.sethvargo.com/chefspec'
17
+ s.homepage = 'https://sethvargo.github.io/chefspec/'
18
18
  s.license = 'MIT'
19
19
 
20
20
  # Packaging
@@ -1,13 +1,18 @@
1
- chef_gem 'default_action'
1
+ chef_gem 'default_action' do
2
+ compile_time false if respond_to?(:compile_time)
3
+ end
2
4
 
3
5
  chef_gem 'explicit_action' do
4
- action :install
6
+ action :install
7
+ compile_time false if respond_to?(:compile_time)
5
8
  end
6
9
 
7
10
  chef_gem 'with_attributes' do
8
- version '1.0.0'
11
+ version '1.0.0'
12
+ compile_time false if respond_to?(:compile_time)
9
13
  end
10
14
 
11
15
  chef_gem 'specifying the identity attribute' do
12
16
  package_name 'identity_attribute'
17
+ compile_time false if respond_to?(:compile_time)
13
18
  end
@@ -1,13 +1,16 @@
1
1
  chef_gem 'explicit_action' do
2
- action :purge
2
+ action :purge
3
+ compile_time false if respond_to?(:compile_time)
3
4
  end
4
5
 
5
6
  chef_gem 'with_attributes' do
6
- version '1.0.0'
7
- action :purge
7
+ version '1.0.0'
8
+ action :purge
9
+ compile_time false if respond_to?(:compile_time)
8
10
  end
9
11
 
10
12
  chef_gem 'specifying the identity attribute' do
11
13
  package_name 'identity_attribute'
12
14
  action :purge
15
+ compile_time false if respond_to?(:compile_time)
13
16
  end
@@ -1,13 +1,16 @@
1
1
  chef_gem 'explicit_action' do
2
- action :reconfig
2
+ action :reconfig
3
+ compile_time false if respond_to?(:compile_time)
3
4
  end
4
5
 
5
6
  chef_gem 'with_attributes' do
6
- version '1.0.0'
7
- action :reconfig
7
+ version '1.0.0'
8
+ action :reconfig
9
+ compile_time false if respond_to?(:compile_time)
8
10
  end
9
11
 
10
12
  chef_gem 'specifying the identity attribute' do
11
13
  package_name 'identity_attribute'
12
14
  action :reconfig
15
+ compile_time false if respond_to?(:compile_time)
13
16
  end
@@ -1,13 +1,16 @@
1
1
  chef_gem 'explicit_action' do
2
- action :remove
2
+ action :remove
3
+ compile_time false if respond_to?(:compile_time)
3
4
  end
4
5
 
5
6
  chef_gem 'with_attributes' do
6
- version '1.0.0'
7
- action :remove
7
+ version '1.0.0'
8
+ action :remove
9
+ compile_time false if respond_to?(:compile_time)
8
10
  end
9
11
 
10
12
  chef_gem 'specifying the identity attribute' do
11
13
  package_name 'identity_attribute'
12
14
  action :remove
15
+ compile_time false if respond_to?(:compile_time)
13
16
  end
@@ -1,13 +1,16 @@
1
1
  chef_gem 'explicit_action' do
2
- action :upgrade
2
+ action :upgrade
3
+ compile_time false if respond_to?(:compile_time)
3
4
  end
4
5
 
5
6
  chef_gem 'with_attributes' do
6
- version '1.0.0'
7
- action :upgrade
7
+ version '1.0.0'
8
+ action :upgrade
9
+ compile_time false if respond_to?(:compile_time)
8
10
  end
9
11
 
10
12
  chef_gem 'specifying the identity attribute' do
11
13
  package_name 'identity_attribute'
12
14
  action :upgrade
15
+ compile_time false if respond_to?(:compile_time)
13
16
  end
@@ -12,3 +12,7 @@ end
12
12
  directory 'specifying the identity attribute' do
13
13
  path '/tmp/identity_attribute'
14
14
  end
15
+
16
+ directory 'c:\temp\with_windows_rights' do
17
+ rights :read_execute, 'Users', applies_to_children: true
18
+ end
@@ -24,6 +24,10 @@ describe 'directory::create' do
24
24
  )
25
25
  end
26
26
 
27
+ it 'creates a directory with windows rights' do
28
+ expect(chef_run).to create_directory('c:\temp\with_windows_rights').with(rights: [{:permissions=>:read_execute, :principals=>"Users", :applies_to_children=>true}])
29
+ end
30
+
27
31
  it 'creates a directory when specifying the identity attribute' do
28
32
  expect(chef_run).to create_directory('/tmp/identity_attribute')
29
33
  end
@@ -0,0 +1,3 @@
1
+ reboot 'explicit cancel' do
2
+ action :cancel
3
+ end
@@ -0,0 +1,3 @@
1
+ reboot 'explicit_action' do
2
+ action :reboot_now
3
+ end
@@ -0,0 +1,3 @@
1
+ reboot 'explicit_action' do
2
+ action :request_reboot
3
+ end
@@ -0,0 +1,10 @@
1
+ require 'chefspec'
2
+
3
+ describe 'reboot::cancel' do
4
+ let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
5
+
6
+ it 'runs a cancel_reboot' do
7
+ expect(chef_run).to cancel_reboot('explicit cancel')
8
+ end
9
+ end
10
+
@@ -0,0 +1,10 @@
1
+ require 'chefspec'
2
+
3
+ describe 'reboot::now' do
4
+ let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
5
+
6
+ it 'runs a reboot_now when specifying action' do
7
+ expect(chef_run).to now_reboot('explicit_action')
8
+ end
9
+ end
10
+
@@ -0,0 +1,10 @@
1
+ require 'chefspec'
2
+
3
+ describe 'reboot::request' do
4
+ let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
5
+
6
+ it 'runs a request_reboot' do
7
+ expect(chef_run).to request_reboot('explicit_action')
8
+ end
9
+ end
10
+
@@ -19,6 +19,16 @@ describe 'render_file::default' do
19
19
  expect(chef_run).to_not render_file('/tmp/file').with_content(/^Not(.+)$/)
20
20
  end
21
21
 
22
+ it 'renders the file when given a block' do
23
+ expect(chef_run).to render_file('/tmp/file').with_content { |content|
24
+ expect(content).to include('This is content!')
25
+ }
26
+
27
+ expect(chef_run).to render_file('/tmp/file').with_content { |content|
28
+ expect(content).to_not include('This is not content!')
29
+ }
30
+ end
31
+
22
32
  it 'renders the file with content matching arbitrary matcher' do
23
33
  expect(chef_run).to render_file('/tmp/file').with_content(
24
34
  start_with('This')
@@ -46,6 +56,16 @@ describe 'render_file::default' do
46
56
  expect(chef_run).to_not render_file('/tmp/cookbook_file').with_content(/^Not(.+)$/)
47
57
  end
48
58
 
59
+ it 'renders the file when given a block' do
60
+ expect(chef_run).to render_file('/tmp/cookbook_file').with_content { |content|
61
+ expect(content).to include('This is content!')
62
+ }
63
+
64
+ expect(chef_run).to render_file('/tmp/cookbook_file').with_content { |content|
65
+ expect(content).to_not include('This is not content!')
66
+ }
67
+ end
68
+
49
69
  it 'renders the file with content matching arbitrary matcher' do
50
70
  expect(chef_run).to render_file('/tmp/cookbook_file').with_content(
51
71
  start_with('This')
@@ -86,6 +106,16 @@ describe 'render_file::default' do
86
106
  expect(chef_run).to_not render_file('/tmp/template').with_content(/^Not(.+)$/)
87
107
  end
88
108
 
109
+ it 'renders the file when given a block' do
110
+ expect(chef_run).to render_file('/tmp/template').with_content { |content|
111
+ expect(content).to include('This is content!')
112
+ }
113
+
114
+ expect(chef_run).to render_file('/tmp/template').with_content { |content|
115
+ expect(content).to_not include('This is not content!')
116
+ }
117
+ end
118
+
89
119
  it 'renders the file with content matching arbitrary matcher' do
90
120
  expect(chef_run).to render_file('/tmp/template').with_content(
91
121
  start_with('This')
@@ -107,6 +137,16 @@ describe 'render_file::default' do
107
137
  expect(chef_run).to_not render_file('/tmp/partial').with_content('This template has a partial: This is not a template partial!')
108
138
  end
109
139
 
140
+ it 'renders the file when given a block' do
141
+ expect(chef_run).to render_file('/tmp/partial').with_content { |content|
142
+ expect(content).to include('has a partial')
143
+ }
144
+
145
+ expect(chef_run).to render_file('/tmp/partial').with_content { |content|
146
+ expect(content).to_not include('not a template partial')
147
+ }
148
+ end
149
+
110
150
  it 'renders the file with matching content' do
111
151
  expect(chef_run).to render_file('/tmp/partial').with_content(/^This(.+)$/)
112
152
  expect(chef_run).to_not render_file('/tmp/partial').with_content(/^Not(.+)$/)