chefspec 4.7.0 → 5.0.0
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/.travis.yml +7 -21
- data/CHANGELOG.md +18 -0
- data/Gemfile +1 -0
- data/README.md +37 -20
- data/chefspec.gemspec +4 -4
- data/examples/apt_repository/recipes/add.rb +8 -0
- data/examples/apt_repository/recipes/remove.rb +4 -0
- data/examples/apt_repository/spec/add_spec.rb +14 -0
- data/examples/apt_repository/spec/remove_spec.rb +9 -0
- data/examples/apt_update/recipes/periodic.rb +5 -0
- data/examples/apt_update/recipes/update.rb +3 -0
- data/examples/apt_update/spec/periodic_spec.rb +14 -0
- data/examples/apt_update/spec/update_spec.rb +9 -0
- data/examples/attributes/spec/default_spec.rb +1 -1
- data/examples/notifications/recipes/before.rb +7 -0
- data/examples/notifications/spec/before_spec.rb +16 -0
- data/examples/server/spec/node_spec.rb +3 -3
- data/examples/server/spec/search_spec.rb +4 -4
- data/examples/stub_node/spec/default_spec.rb +2 -2
- data/examples/subscribes/recipes/before.rb +5 -0
- data/examples/subscribes/spec/before_spec.rb +16 -0
- data/examples/user/spec/create_spec.rb +1 -1
- data/examples/user/spec/lock_spec.rb +1 -1
- data/examples/user/spec/manage_spec.rb +1 -1
- data/examples/user/spec/modify_spec.rb +1 -1
- data/examples/user/spec/remove_spec.rb +1 -1
- data/examples/user/spec/unlock_spec.rb +1 -1
- data/features/chocolatey_package.feature +0 -10
- data/features/dsc_resource.feature +0 -9
- data/features/notifications.feature +8 -0
- data/features/reboot.feature +0 -7
- data/features/step_into.feature +0 -7
- data/features/subscribes.feature +8 -0
- data/features/windows_package.feature +0 -9
- data/features/windows_service.feature +0 -7
- data/gemfiles/chefspec.gemfile +6 -0
- data/lib/chefspec/api/apt_repository.rb +56 -0
- data/lib/chefspec/api/apt_update.rb +53 -0
- data/lib/chefspec/cacher.rb +3 -2
- data/lib/chefspec/coverage.rb +38 -5
- data/lib/chefspec/errors.rb +3 -0
- data/lib/chefspec/extensions/chef/data_query.rb +2 -2
- data/lib/chefspec/matchers/notifications_matcher.rb +23 -2
- data/lib/chefspec/matchers/subscribes_matcher.rb +9 -0
- data/lib/chefspec/version.rb +1 -1
- data/spec/spec_helper.rb +5 -0
- data/spec/unit/cacher_spec.rb +17 -1
- data/spec/unit/matchers/notifications_matcher_spec.rb +1 -0
- data/spec/unit/matchers/subscribes_matcher_spec.rb +1 -0
- data/spec/unit/solo_runner_spec.rb +1 -1
- data/templates/coverage/json.erb +8 -0
- data/templates/coverage/table.erb +14 -0
- data/templates/errors/erb_template_parse_error.erb +5 -0
- data/templates/errors/template_not_found.erb +9 -0
- metadata +26 -11
- data/spec/unit/extensions/lwrp_base_spec.rb +0 -96
@@ -2,8 +2,8 @@ require 'chefspec'
|
|
2
2
|
|
3
3
|
describe 'stub_node::default' do
|
4
4
|
let(:my_node) do
|
5
|
-
stub_node('example.com', platform: 'ubuntu', version: '
|
6
|
-
node.
|
5
|
+
stub_node('example.com', platform: 'ubuntu', version: '14.04') do |node|
|
6
|
+
node.normal['foo']['bar'] = 'zip'
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'chefspec'
|
2
|
+
|
3
|
+
describe 'subscribes::before' do
|
4
|
+
let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
|
5
|
+
let(:service) { chef_run.service('receiving_resource') }
|
6
|
+
|
7
|
+
it 'subscribes to the template creation' do
|
8
|
+
expect(service).to subscribe_to('template[/tmp/notifying_resource]').before
|
9
|
+
expect(service).to_not subscribe_to('template[/tmp/not_notifying_resource]').before
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'subscribes to the specific action on the resource before' do
|
13
|
+
expect(service).to subscribe_to('template[/tmp/notifying_resource]').on(:create).before
|
14
|
+
expect(service).to_not subscribe_to('template[/tmp/notifying_resource]').on(:delete).immediately
|
15
|
+
end
|
16
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'chefspec'
|
2
2
|
|
3
3
|
describe 'user::create' do
|
4
|
-
let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
|
4
|
+
let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04').converge(described_recipe) }
|
5
5
|
|
6
6
|
it 'creates a user with the default action' do
|
7
7
|
expect(chef_run).to create_user('default_action')
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'chefspec'
|
2
2
|
|
3
3
|
describe 'user::lock' do
|
4
|
-
let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
|
4
|
+
let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04').converge(described_recipe) }
|
5
5
|
|
6
6
|
it 'locks a user with an explicit action' do
|
7
7
|
expect(chef_run).to lock_user('explicit_action')
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'chefspec'
|
2
2
|
|
3
3
|
describe 'user::manage' do
|
4
|
-
let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
|
4
|
+
let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04').converge(described_recipe) }
|
5
5
|
|
6
6
|
it 'manages a user with an explicit action' do
|
7
7
|
expect(chef_run).to manage_user('explicit_action')
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'chefspec'
|
2
2
|
|
3
3
|
describe 'user::modify' do
|
4
|
-
let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
|
4
|
+
let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04').converge(described_recipe) }
|
5
5
|
|
6
6
|
it 'modifys a user with an explicit action' do
|
7
7
|
expect(chef_run).to modify_user('explicit_action')
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'chefspec'
|
2
2
|
|
3
3
|
describe 'user::remove' do
|
4
|
-
let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
|
4
|
+
let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04').converge(described_recipe) }
|
5
5
|
|
6
6
|
it 'removes a user with an explicit action' do
|
7
7
|
expect(chef_run).to remove_user('explicit_action')
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'chefspec'
|
2
2
|
|
3
3
|
describe 'user::unlock' do
|
4
|
-
let(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) }
|
4
|
+
let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '14.04').converge(described_recipe) }
|
5
5
|
|
6
6
|
it 'unlocks a user with an explicit action' do
|
7
7
|
expect(chef_run).to unlock_user('explicit_action')
|
@@ -1,17 +1,7 @@
|
|
1
|
-
@not_chef_11_14_2
|
2
|
-
@not_chef_11_14_6
|
3
|
-
@not_chef_11_16_0
|
4
|
-
@not_chef_11_16_2
|
5
|
-
@not_chef_11_16_4
|
6
|
-
@not_chef_11_18_0
|
7
|
-
@not_chef_11_18_6
|
8
1
|
@not_chef_12_0_3
|
9
|
-
@not_chef_12_1_0
|
10
|
-
@not_chef_12_1_1
|
11
2
|
@not_chef_12_1_2
|
12
3
|
@not_chef_12_2_1
|
13
4
|
@not_chef_12_3_0
|
14
|
-
@not_chef_12_4_0
|
15
5
|
@not_chef_12_4_3
|
16
6
|
@not_chef_12_5_1
|
17
7
|
@not_chef_12_6_0
|
@@ -1,13 +1,4 @@
|
|
1
|
-
@not_chef_11_14_2
|
2
|
-
@not_chef_11_14_6
|
3
|
-
@not_chef_11_16_0
|
4
|
-
@not_chef_11_16_2
|
5
|
-
@not_chef_11_16_4
|
6
|
-
@not_chef_11_18_0
|
7
|
-
@not_chef_11_18_6
|
8
1
|
@not_chef_12_0_3
|
9
|
-
@not_chef_12_1_0
|
10
|
-
@not_chef_12_1_1
|
11
2
|
@not_chef_12_1_2
|
12
3
|
Feature: The dsc_resource matcher
|
13
4
|
Background:
|
@@ -1,3 +1,10 @@
|
|
1
|
+
@not_chef_12_0_3
|
2
|
+
@not_chef_12_1_2
|
3
|
+
@not_chef_12_2_1
|
4
|
+
@not_chef_12_3_0
|
5
|
+
@not_chef_12_4_3
|
6
|
+
@not_chef_12_5_1
|
7
|
+
|
1
8
|
Feature: The notifications matcher
|
2
9
|
Background:
|
3
10
|
* I am using the "notifications" cookbook
|
@@ -7,6 +14,7 @@ Feature: The notifications matcher
|
|
7
14
|
* the output should contain "0 failures"
|
8
15
|
Examples:
|
9
16
|
| Matcher |
|
17
|
+
| before |
|
10
18
|
| chained |
|
11
19
|
| default |
|
12
20
|
| delayed |
|
data/features/reboot.feature
CHANGED
data/features/step_into.feature
CHANGED
data/features/subscribes.feature
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
@not_chef_12_0_3
|
2
|
+
@not_chef_12_1_2
|
3
|
+
@not_chef_12_2_1
|
4
|
+
@not_chef_12_3_0
|
5
|
+
@not_chef_12_4_3
|
6
|
+
@not_chef_12_5_1
|
7
|
+
|
1
8
|
Feature: The subscribes matcher
|
2
9
|
Background:
|
3
10
|
* I am using the "subscribes" cookbook
|
@@ -7,6 +14,7 @@ Feature: The subscribes matcher
|
|
7
14
|
* the output should contain "0 failures"
|
8
15
|
Examples:
|
9
16
|
| Matcher |
|
17
|
+
| before |
|
10
18
|
| chained |
|
11
19
|
| default |
|
12
20
|
| delayed |
|
@@ -1,13 +1,4 @@
|
|
1
|
-
@not_chef_11_14_2
|
2
|
-
@not_chef_11_14_6
|
3
|
-
@not_chef_11_16_0
|
4
|
-
@not_chef_11_16_2
|
5
|
-
@not_chef_11_16_4
|
6
|
-
@not_chef_11_18_0
|
7
|
-
@not_chef_11_18_6
|
8
1
|
@not_chef_12_0_3
|
9
|
-
@not_chef_12_1_0
|
10
|
-
@not_chef_12_1_1
|
11
2
|
@not_chef_12_1_2
|
12
3
|
@not_chef_12_2_1
|
13
4
|
@not_chef_12_3_0
|
data/gemfiles/chefspec.gemfile
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
+
# travis runs on older chef releases failed while including
|
4
|
+
# rack 2.X on Ruby 2.1. When we remove Ruby 2.1 support this can go
|
5
|
+
if ENV['CHEF_VERSION'].to_f < 12.6
|
6
|
+
gem 'rack', '~> 1.0'
|
7
|
+
end
|
8
|
+
|
3
9
|
if ENV['CHEF_VERSION'] == 'master'
|
4
10
|
gem 'chef', github: 'chef/chef'
|
5
11
|
else
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module ChefSpec::API
|
2
|
+
# @since 3.0.0
|
3
|
+
module AptRepositoryMatchers
|
4
|
+
ChefSpec.define_matcher :apt_repository
|
5
|
+
|
6
|
+
#
|
7
|
+
# Assert that an +apt_repository+ resource exists in the Chef run with the
|
8
|
+
# action +:add+. Given a Chef Recipe that adds "rsyslog" as an
|
9
|
+
# +apt_repository+:
|
10
|
+
#
|
11
|
+
# apt_repository 'rsyslog' do
|
12
|
+
# uri 'ppa:adiscon/v8-stable'
|
13
|
+
# action :add
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# The Examples section demonstrates the different ways to test an
|
17
|
+
# +apt_repository+ resource with ChefSpec.
|
18
|
+
#
|
19
|
+
# @example Assert that an +apt_repository+ was added
|
20
|
+
# expect(chef_run).to add_apt_repository('rsyslog')
|
21
|
+
# @param [String, Regex] resource_name
|
22
|
+
# the name of the resource to match
|
23
|
+
#
|
24
|
+
# @return [ChefSpec::Matchers::ResourceMatcher]
|
25
|
+
|
26
|
+
def add_apt_repository(resource_name)
|
27
|
+
ChefSpec::Matchers::ResourceMatcher.new(:apt_repository, :add,
|
28
|
+
resource_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Assert that an +apt_repository+ resource exists in the Chef run with the
|
33
|
+
# action +:remove+. Given a Chef Recipe that removes "rsyslog" as an
|
34
|
+
# +apt_repository+:
|
35
|
+
#
|
36
|
+
# apt_repository 'rsyslog' do
|
37
|
+
# uri 'ppa:adiscon/v8-stable'
|
38
|
+
# action :remove
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# The Examples section demonstrates the different ways to test an
|
42
|
+
# +apt_repository+ resource with ChefSpec.
|
43
|
+
#
|
44
|
+
# @example Assert that an +apt_repository+ was removed
|
45
|
+
# expect(chef_run).to remove_apt_repository('rsyslog')
|
46
|
+
# @param [String, Regex] resource_name
|
47
|
+
# the name of the resource to match
|
48
|
+
#
|
49
|
+
# @return [ChefSpec::Matchers::ResourceMatcher]
|
50
|
+
|
51
|
+
def remove_apt_repository(resource_name)
|
52
|
+
ChefSpec::Matchers::ResourceMatcher.new(:apt_repository, :remove,
|
53
|
+
resource_name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ChefSpec::API
|
2
|
+
# @since 3.0.0
|
3
|
+
module AptUpdateMatchers
|
4
|
+
ChefSpec.define_matcher :apt_update
|
5
|
+
|
6
|
+
#
|
7
|
+
# Assert that an +apt_update+ resource exists in the Chef run with the
|
8
|
+
# action +:update+. Given a Chef Recipe that adds "rsyslog" as a repository
|
9
|
+
# to update.
|
10
|
+
# apt_repository 'rsyslog' do
|
11
|
+
# action :update
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# The Examples section demonstrates the different ways to test an
|
15
|
+
# +apt_update+ resource with ChefSpec.
|
16
|
+
#
|
17
|
+
# @example Assert that an +apt_update+ was run
|
18
|
+
# expect(chef_run).to update_apt_update('rsyslog')
|
19
|
+
# @param [String, Regex] resource_name
|
20
|
+
# the name of the resource to match
|
21
|
+
#
|
22
|
+
# @return [ChefSpec::Matchers::ResourceMatcher]
|
23
|
+
|
24
|
+
def update_apt_update(resource_name)
|
25
|
+
ChefSpec::Matchers::ResourceMatcher.new(:apt_update, :update,
|
26
|
+
resource_name)
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Assert that an +apt_update+ resource exists in the Chef run
|
31
|
+
# with the action +:periodic+. Given a Chef Recipe that updates "rsyslog"
|
32
|
+
# as an +apt_update+: periodically
|
33
|
+
#
|
34
|
+
# apt_update 'rsyslog' do
|
35
|
+
# action :periodic
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# The Examples section demonstrates the different ways to test an
|
39
|
+
# +apt_update+ resource with ChefSpec.
|
40
|
+
#
|
41
|
+
# @example Assert that an +apt_update+ was updated periodically
|
42
|
+
# expect(chef_run).to periodic_apt_update('rsyslog')
|
43
|
+
# @param [String, Regex] resource_name
|
44
|
+
# the name of the resource to match
|
45
|
+
#
|
46
|
+
# @return [ChefSpec::Matchers::ResourceMatcher]
|
47
|
+
|
48
|
+
def periodic_apt_update(resource_name)
|
49
|
+
ChefSpec::Matchers::ResourceMatcher.new(:apt_update, :periodic,
|
50
|
+
resource_name)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/chefspec/cacher.rb
CHANGED
@@ -35,8 +35,9 @@ module ChefSpec
|
|
35
35
|
|
36
36
|
def cached(name, &block)
|
37
37
|
location = ancestors.first.metadata[:location]
|
38
|
-
unless
|
39
|
-
location += ancestors.first.metadata[:description]
|
38
|
+
unless location.nil?
|
39
|
+
location += ancestors.first.metadata[:description] unless ancestors.first.metadata[:description].nil?
|
40
|
+
location += ancestors.first.metadata[:scoped_id] unless ancestors.first.metadata[:scoped_id].nil?
|
40
41
|
end
|
41
42
|
location ||= ancestors.first.metadata[:parent_example_group][:location]
|
42
43
|
|
data/lib/chefspec/coverage.rb
CHANGED
@@ -28,6 +28,7 @@ module ChefSpec
|
|
28
28
|
def initialize
|
29
29
|
@collection = {}
|
30
30
|
@filters = {}
|
31
|
+
@template = ChefSpec.root.join('templates', 'coverage', 'human.erb')
|
31
32
|
end
|
32
33
|
|
33
34
|
#
|
@@ -67,7 +68,26 @@ module ChefSpec
|
|
67
68
|
|
68
69
|
true
|
69
70
|
end
|
70
|
-
|
71
|
+
#
|
72
|
+
# Change the template for reporting of converage analysis.
|
73
|
+
#
|
74
|
+
# @param [string] path
|
75
|
+
# The template file to use for the output of the report
|
76
|
+
#
|
77
|
+
# @return [true]
|
78
|
+
#
|
79
|
+
def set_template(file = 'human.erb')
|
80
|
+
[
|
81
|
+
ChefSpec.root.join('templates', 'coverage', file),
|
82
|
+
File.expand_path(file, Dir.pwd)
|
83
|
+
].each do |temp|
|
84
|
+
if File.exist?(temp)
|
85
|
+
@template = temp
|
86
|
+
return
|
87
|
+
end
|
88
|
+
end
|
89
|
+
raise Error::TemplateNotFound.new(path: file)
|
90
|
+
end
|
71
91
|
#
|
72
92
|
# Add a resource to the resource collection. Only new resources are added
|
73
93
|
# and only resources that match the given filter are covered (which is *
|
@@ -130,10 +150,14 @@ module ChefSpec
|
|
130
150
|
report[:untouched_resources] = @collection.collect do |_, resource|
|
131
151
|
resource unless resource.touched?
|
132
152
|
end.compact
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
153
|
+
report[:all_resources] = @collection.values
|
154
|
+
|
155
|
+
begin
|
156
|
+
erb = Erubis::Eruby.new(File.read(@template))
|
157
|
+
puts erb.evaluate(report)
|
158
|
+
rescue NameError => e
|
159
|
+
raise Error::ErbTemplateParseError.new(original_error: e.message)
|
160
|
+
end
|
137
161
|
|
138
162
|
# Ensure we exit correctly (#351)
|
139
163
|
Kernel.exit(exit_status) if exit_status && exit_status > 0
|
@@ -160,6 +184,15 @@ module ChefSpec
|
|
160
184
|
@resource.to_s
|
161
185
|
end
|
162
186
|
|
187
|
+
def to_json
|
188
|
+
{
|
189
|
+
"source_file" => source_file,
|
190
|
+
"source_line" => source_line,
|
191
|
+
"touched" => touched?,
|
192
|
+
"resource" => to_s
|
193
|
+
}.to_json
|
194
|
+
end
|
195
|
+
|
163
196
|
def source_file
|
164
197
|
@source_file ||= if @resource.source_line
|
165
198
|
shortname(@resource.source_line.split(':').first)
|
data/lib/chefspec/errors.rb
CHANGED
@@ -33,8 +33,8 @@ module Chef::DSL::DataQuery
|
|
33
33
|
|
34
34
|
# @see Chef::DSL::DataQuery#data_bag_item
|
35
35
|
alias_method :old_data_bag_item, :data_bag_item
|
36
|
-
def data_bag_item(bag, id)
|
37
|
-
return old_data_bag_item(bag, id) unless Chef::Config[:solo]
|
36
|
+
def data_bag_item(bag, id, secret = nil)
|
37
|
+
return old_data_bag_item(bag, id, secret) unless Chef::Config[:solo]
|
38
38
|
|
39
39
|
stub = ChefSpec::Stubs::DataBagItemRegistry.stub_for(bag, id)
|
40
40
|
|