rspec-puppet 2.11.0 → 4.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/CHANGELOG.md +154 -469
- data/README.md +71 -168
- data/bin/rspec-puppet-init +4 -3
- data/lib/rspec-puppet/adapters.rb +84 -230
- data/lib/rspec-puppet/cache.rb +3 -2
- data/lib/rspec-puppet/consts.rb +16 -14
- data/lib/rspec-puppet/coverage.rb +37 -42
- data/lib/rspec-puppet/errors.rb +6 -6
- data/lib/rspec-puppet/example/class_example_group.rb +3 -1
- data/lib/rspec-puppet/example/define_example_group.rb +3 -1
- data/lib/rspec-puppet/example/function_example_group.rb +42 -57
- data/lib/rspec-puppet/example/host_example_group.rb +3 -1
- data/lib/rspec-puppet/example/provider_example_group.rb +2 -0
- data/lib/rspec-puppet/example/type_alias_example_group.rb +4 -2
- data/lib/rspec-puppet/example/type_example_group.rb +3 -1
- data/lib/rspec-puppet/example.rb +6 -9
- data/lib/rspec-puppet/facter_impl.rb +11 -10
- data/lib/rspec-puppet/matchers/allow_value.rb +10 -10
- data/lib/rspec-puppet/matchers/compile.rb +54 -61
- data/lib/rspec-puppet/matchers/count_generic.rb +18 -18
- data/lib/rspec-puppet/matchers/create_generic.rb +69 -79
- data/lib/rspec-puppet/matchers/dynamic_matchers.rb +15 -4
- data/lib/rspec-puppet/matchers/include_class.rb +5 -4
- data/lib/rspec-puppet/matchers/parameter_matcher.rb +11 -12
- data/lib/rspec-puppet/matchers/raise_error.rb +5 -1
- data/lib/rspec-puppet/matchers/run.rb +41 -42
- data/lib/rspec-puppet/matchers/type_matchers.rb +37 -48
- data/lib/rspec-puppet/matchers.rb +2 -0
- data/lib/rspec-puppet/monkey_patches/win32/registry.rb +7 -5
- data/lib/rspec-puppet/monkey_patches/win32/taskscheduler.rb +3 -1
- data/lib/rspec-puppet/monkey_patches/windows/taskschedulerconstants.rb +208 -205
- data/lib/rspec-puppet/monkey_patches.rb +80 -93
- data/lib/rspec-puppet/rake_task.rb +6 -4
- data/lib/rspec-puppet/raw_string.rb +2 -0
- data/lib/rspec-puppet/sensitive.rb +31 -39
- data/lib/rspec-puppet/setup.rb +45 -56
- data/lib/rspec-puppet/spec_helper.rb +2 -3
- data/lib/rspec-puppet/support.rb +129 -177
- data/lib/rspec-puppet/tasks/release_test.rb +8 -5
- data/lib/rspec-puppet/version.rb +5 -0
- data/lib/rspec-puppet.rb +37 -61
- metadata +18 -15
- data/lib/rspec-puppet/example/application_example_group.rb +0 -19
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RSpec::Puppet
|
|
2
4
|
module DefineExampleGroup
|
|
3
5
|
include RSpec::Puppet::ManifestMatchers
|
|
@@ -8,7 +10,7 @@ module RSpec::Puppet
|
|
|
8
10
|
end
|
|
9
11
|
|
|
10
12
|
def exported_resources
|
|
11
|
-
|
|
13
|
+
-> { load_catalogue(:define, true) }
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
def rspec_puppet_cleanup
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RSpec::Puppet
|
|
2
4
|
module FunctionExampleGroup
|
|
3
5
|
include RSpec::Puppet::FunctionMatchers
|
|
@@ -15,14 +17,14 @@ module RSpec::Puppet
|
|
|
15
17
|
|
|
16
18
|
# This method is used by the `run` matcher to trigger the function execution, and provides a uniform interface across all puppet versions.
|
|
17
19
|
def execute(*args, &block)
|
|
18
|
-
Puppet.override(@overrides,
|
|
20
|
+
Puppet.override(@overrides, 'rspec-test scope') do
|
|
19
21
|
@func.call(@overrides[:global_scope], *freeze_arg(args), &block)
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
# compatibility alias for existing tests
|
|
24
|
-
def call(
|
|
25
|
-
RSpec.deprecate(
|
|
26
|
+
def call(_scope, *args)
|
|
27
|
+
RSpec.deprecate('subject.call', replacement: 'is_expected.to run.with().and_raise_error(), or execute()')
|
|
26
28
|
execute(*args)
|
|
27
29
|
end
|
|
28
30
|
|
|
@@ -36,7 +38,10 @@ module RSpec::Puppet
|
|
|
36
38
|
arg.each { |a| freeze_arg(a) }
|
|
37
39
|
arg.freeze
|
|
38
40
|
when Hash
|
|
39
|
-
arg.each
|
|
41
|
+
arg.each do |k, v|
|
|
42
|
+
freeze_arg(k)
|
|
43
|
+
freeze_arg(v)
|
|
44
|
+
end
|
|
40
45
|
arg.freeze
|
|
41
46
|
when String
|
|
42
47
|
arg.freeze
|
|
@@ -64,7 +69,7 @@ module RSpec::Puppet
|
|
|
64
69
|
|
|
65
70
|
# This method was formerly used by the `run` matcher to trigger the function execution, and provides puppet versions dependant interface.
|
|
66
71
|
def call(*args)
|
|
67
|
-
RSpec.deprecate(
|
|
72
|
+
RSpec.deprecate('subject.call', replacement: 'is_expected.to run.with().and_raise_error(), or execute()')
|
|
68
73
|
if args.nil?
|
|
69
74
|
@func.call
|
|
70
75
|
else
|
|
@@ -83,30 +88,27 @@ module RSpec::Puppet
|
|
|
83
88
|
with_vardir do
|
|
84
89
|
env = adapter.current_environment
|
|
85
90
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
return func if func.func
|
|
91
|
+
context_overrides = compiler.context_overrides
|
|
92
|
+
func = nil
|
|
93
|
+
loaders = Puppet.lookup(:loaders)
|
|
94
|
+
Puppet.override(context_overrides, 'rspec-test scope') do
|
|
95
|
+
func = V4FunctionWrapper.new(function_name,
|
|
96
|
+
loaders.private_environment_loader.load(:function, function_name), context_overrides)
|
|
97
|
+
@scope = context_overrides[:global_scope]
|
|
96
98
|
end
|
|
97
99
|
|
|
100
|
+
return func if func.func
|
|
101
|
+
|
|
98
102
|
if Puppet::Parser::Functions.function(function_name)
|
|
99
103
|
V3FunctionWrapper.new(function_name, scope.method("function_#{function_name}".intern))
|
|
100
|
-
else
|
|
101
|
-
nil
|
|
102
104
|
end
|
|
103
105
|
end
|
|
104
106
|
end
|
|
107
|
+
|
|
105
108
|
def call_function(function_name, *args)
|
|
106
|
-
|
|
107
|
-
# function.execute(*args)
|
|
108
|
-
scope.call_function(function_name, args)
|
|
109
|
+
scope.call_function(function_name, args)
|
|
109
110
|
end
|
|
111
|
+
|
|
110
112
|
def scope
|
|
111
113
|
@scope ||= build_scope(compiler, nodename(:function))
|
|
112
114
|
end
|
|
@@ -135,7 +137,7 @@ module RSpec::Puppet
|
|
|
135
137
|
trusted_values = trusted_facts_hash(node_name)
|
|
136
138
|
|
|
137
139
|
# Allow different Hiera configurations:
|
|
138
|
-
HieraPuppet.instance_variable_set(
|
|
140
|
+
HieraPuppet.instance_variable_set(:@hiera, nil) if defined? HieraPuppet
|
|
139
141
|
|
|
140
142
|
# if we specify a pre_condition, we should ensure that we compile that
|
|
141
143
|
# code into a catalog that is accessible from the scope where the
|
|
@@ -145,58 +147,41 @@ module RSpec::Puppet
|
|
|
145
147
|
node_facts = Puppet::Node::Facts.new(node_name, fact_values.dup)
|
|
146
148
|
|
|
147
149
|
node_options = {
|
|
148
|
-
:
|
|
149
|
-
:
|
|
150
|
+
parameters: fact_values,
|
|
151
|
+
facts: node_facts
|
|
150
152
|
}
|
|
151
153
|
|
|
152
154
|
stub_facts! fact_values
|
|
153
155
|
|
|
154
156
|
node = build_node(node_name, node_options)
|
|
155
157
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
)
|
|
163
|
-
end
|
|
158
|
+
Puppet.push_context(
|
|
159
|
+
{
|
|
160
|
+
trusted_information: Puppet::Context::TrustedInformation.new('remote', node_name, trusted_values)
|
|
161
|
+
},
|
|
162
|
+
'Context for spec trusted hash'
|
|
163
|
+
)
|
|
164
164
|
|
|
165
165
|
compiler = Puppet::Parser::Compiler.new(node)
|
|
166
166
|
compiler.compile
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
end
|
|
167
|
+
loaders = Puppet::Pops::Loaders.new(adapter.current_environment)
|
|
168
|
+
Puppet.push_context(
|
|
169
|
+
{
|
|
170
|
+
loaders: loaders,
|
|
171
|
+
global_scope: compiler.context_overrides[:global_scope]
|
|
172
|
+
},
|
|
173
|
+
'set globals'
|
|
174
|
+
)
|
|
176
175
|
compiler
|
|
177
176
|
end
|
|
178
177
|
|
|
179
|
-
def build_scope(compiler,
|
|
180
|
-
|
|
181
|
-
return compiler.context_overrides[:global_scope]
|
|
182
|
-
elsif Puppet.version =~ /^2\.[67]/
|
|
183
|
-
# loadall should only be necessary prior to 3.x
|
|
184
|
-
# Please note, loadall needs to happen first when creating a scope, otherwise
|
|
185
|
-
# you might receive undefined method `function_*' errors
|
|
186
|
-
Puppet::Parser::Functions.autoloader.loadall
|
|
187
|
-
scope = Puppet::Parser::Scope.new(:compiler => compiler)
|
|
188
|
-
else
|
|
189
|
-
scope = Puppet::Parser::Scope.new(compiler)
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
scope.source = Puppet::Resource::Type.new(:node, node_name)
|
|
193
|
-
scope.parent = compiler.topscope
|
|
194
|
-
scope
|
|
178
|
+
def build_scope(compiler, _node_name)
|
|
179
|
+
compiler.context_overrides[:global_scope]
|
|
195
180
|
end
|
|
196
181
|
|
|
197
182
|
def build_node(name, opts = {})
|
|
198
183
|
node_environment = adapter.current_environment
|
|
199
|
-
opts
|
|
184
|
+
opts[:environment] = node_environment
|
|
200
185
|
Puppet::Node.new(name, opts)
|
|
201
186
|
end
|
|
202
187
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RSpec::Puppet
|
|
2
4
|
module HostExampleGroup
|
|
3
5
|
include RSpec::Puppet::ManifestMatchers
|
|
@@ -8,7 +10,7 @@ module RSpec::Puppet
|
|
|
8
10
|
end
|
|
9
11
|
|
|
10
12
|
def exported_resources
|
|
11
|
-
|
|
13
|
+
-> { load_catalogue(:host, true) }
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
def rspec_puppet_cleanup
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RSpec::Puppet
|
|
2
4
|
module TypeAliasExampleGroup
|
|
3
5
|
include RSpec::Puppet::TypeAliasMatchers
|
|
4
6
|
include RSpec::Puppet::Support
|
|
5
7
|
|
|
6
8
|
def catalogue(test_value)
|
|
7
|
-
load_catalogue(:type_alias, false, :
|
|
9
|
+
load_catalogue(:type_alias, false, test_value: test_value)
|
|
8
10
|
end
|
|
9
11
|
|
|
10
12
|
def subject
|
|
11
|
-
|
|
13
|
+
->(test_value) { catalogue(test_value) }
|
|
12
14
|
end
|
|
13
15
|
end
|
|
14
16
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RSpec::Puppet
|
|
2
4
|
module TypeExampleGroup
|
|
3
5
|
include RSpec::Puppet::TypeMatchers
|
|
@@ -7,7 +9,7 @@ module RSpec::Puppet
|
|
|
7
9
|
@type_and_resource ||= begin
|
|
8
10
|
setup_puppet
|
|
9
11
|
type_name = self.class.top_level_description.downcase
|
|
10
|
-
my_params =
|
|
12
|
+
my_params = respond_to?(:params) ? params : {}
|
|
11
13
|
[
|
|
12
14
|
Puppet::Type.type(type_name),
|
|
13
15
|
# I don't want to create the resource here, so I have
|
data/lib/rspec-puppet/example.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'rspec-puppet/support'
|
|
2
4
|
require 'rspec-puppet/example/define_example_group'
|
|
3
5
|
require 'rspec-puppet/example/class_example_group'
|
|
@@ -6,17 +8,13 @@ require 'rspec-puppet/example/host_example_group'
|
|
|
6
8
|
require 'rspec-puppet/example/type_example_group'
|
|
7
9
|
require 'rspec-puppet/example/type_alias_example_group'
|
|
8
10
|
require 'rspec-puppet/example/provider_example_group'
|
|
9
|
-
require 'rspec-puppet/example/application_example_group'
|
|
10
|
-
|
|
11
|
-
RSpec::configure do |c|
|
|
12
11
|
|
|
12
|
+
RSpec.configure do |c|
|
|
13
13
|
def c.rspec_puppet_include(group, type, file_path)
|
|
14
14
|
escaped_file_path = Regexp.compile(file_path.join('[\\\/]'))
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
self.include group, :type => type, :file_path => lambda { |file_path, metadata| metadata[:type].nil? && escaped_file_path =~ file_path }
|
|
19
|
-
end
|
|
15
|
+
include group, type: type, file_path: lambda { |file_path, metadata|
|
|
16
|
+
metadata[:type].nil? && escaped_file_path =~ file_path
|
|
17
|
+
}
|
|
20
18
|
end
|
|
21
19
|
|
|
22
20
|
c.rspec_puppet_include RSpec::Puppet::DefineExampleGroup, :define, %w[spec defines]
|
|
@@ -26,7 +24,6 @@ RSpec::configure do |c|
|
|
|
26
24
|
c.rspec_puppet_include RSpec::Puppet::TypeExampleGroup, :type, %w[spec types]
|
|
27
25
|
c.rspec_puppet_include RSpec::Puppet::TypeAliasExampleGroup, :type_alias, %w[spec type_aliases]
|
|
28
26
|
c.rspec_puppet_include RSpec::Puppet::ProviderExampleGroup, :provider, %w[spec providers]
|
|
29
|
-
c.rspec_puppet_include RSpec::Puppet::ApplicationExampleGroup, :application, %w[spec applications]
|
|
30
27
|
|
|
31
28
|
# Hook for each example group type to remove any caches or instance variables, since they will remain
|
|
32
29
|
# and cause a memory leak. Can't be assigned per type by :file_path, so check for its presence.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
module RSpec::Puppet
|
|
3
4
|
# Implements a simple hash-based version of Facter to be used in module tests
|
|
4
5
|
# that use rspec-puppet.
|
|
5
6
|
class FacterTestImpl
|
|
@@ -8,7 +9,9 @@ module RSpec::Puppet
|
|
|
8
9
|
end
|
|
9
10
|
|
|
10
11
|
def value(fact_name)
|
|
11
|
-
@facts
|
|
12
|
+
@facts.dig(*fact_name.to_s.split('.'))
|
|
13
|
+
rescue TypeError
|
|
14
|
+
nil
|
|
12
15
|
end
|
|
13
16
|
|
|
14
17
|
def clear
|
|
@@ -19,8 +22,9 @@ module RSpec::Puppet
|
|
|
19
22
|
@facts
|
|
20
23
|
end
|
|
21
24
|
|
|
22
|
-
def add(name,
|
|
23
|
-
raise 'Facter.add expects a block' unless
|
|
25
|
+
def add(name, _options = {}, &block)
|
|
26
|
+
raise 'Facter.add expects a block' unless block
|
|
27
|
+
|
|
24
28
|
@facts[name.to_s] = instance_eval(&block)
|
|
25
29
|
end
|
|
26
30
|
|
|
@@ -36,14 +40,11 @@ module RSpec::Puppet
|
|
|
36
40
|
private
|
|
37
41
|
|
|
38
42
|
def setcode(string = nil, &block)
|
|
39
|
-
if
|
|
40
|
-
|
|
43
|
+
if block
|
|
44
|
+
yield
|
|
41
45
|
else
|
|
42
|
-
|
|
46
|
+
string
|
|
43
47
|
end
|
|
44
|
-
|
|
45
|
-
value
|
|
46
48
|
end
|
|
47
49
|
end
|
|
48
50
|
end
|
|
49
|
-
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RSpec::Puppet
|
|
2
4
|
module TypeAliasMatchers
|
|
3
5
|
class AllowValue
|
|
@@ -8,13 +10,11 @@ module RSpec::Puppet
|
|
|
8
10
|
|
|
9
11
|
def matches?(catalogue)
|
|
10
12
|
matches = @values.map do |test_value|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
false
|
|
17
|
-
end
|
|
13
|
+
catalogue.call(test_value)
|
|
14
|
+
true
|
|
15
|
+
rescue Puppet::Error => e
|
|
16
|
+
@error_msgs << e.message
|
|
17
|
+
false
|
|
18
18
|
end
|
|
19
19
|
matches.all?
|
|
20
20
|
end
|
|
@@ -28,11 +28,11 @@ module RSpec::Puppet
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def failure_message
|
|
31
|
-
"expected that the type alias would
|
|
31
|
+
"expected that the type alias would #{description} but it raised the #{@error_msgs.length == 1 ? 'error' : 'errors'} #{@error_msgs.join(', ')}"
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def failure_message_when_negated
|
|
35
|
-
"expected that the type alias would not
|
|
35
|
+
"expected that the type alias would not #{description} but it does"
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def supports_block_expectations
|
|
@@ -48,6 +48,6 @@ module RSpec::Puppet
|
|
|
48
48
|
RSpec::Puppet::TypeAliasMatchers::AllowValue.new(values)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
alias allow_values allow_value
|
|
52
52
|
end
|
|
53
53
|
end
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RSpec::Puppet
|
|
2
4
|
module ManifestMatchers
|
|
3
5
|
class Compile
|
|
4
6
|
def initialize
|
|
5
|
-
@failed_resource =
|
|
7
|
+
@failed_resource = ''
|
|
6
8
|
@check_deps = false
|
|
7
9
|
@cycles = []
|
|
8
|
-
@error_msg =
|
|
10
|
+
@error_msg = ''
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
def with_all_deps
|
|
@@ -19,31 +21,29 @@ module RSpec::Puppet
|
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
def matches?(catalogue)
|
|
22
|
-
|
|
23
|
-
@catalogue = catalogue.call
|
|
24
|
+
@catalogue = catalogue.call
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
end
|
|
26
|
+
if cycles_found?
|
|
27
|
+
false
|
|
28
|
+
elsif @check_deps == true && missing_dependencies?
|
|
29
|
+
false
|
|
30
|
+
else
|
|
31
|
+
@expected_error.nil?
|
|
32
|
+
end
|
|
33
|
+
rescue Puppet::Error => e
|
|
34
|
+
@error_msg = e.message
|
|
35
|
+
if @expected_error.nil?
|
|
36
|
+
false
|
|
37
|
+
else
|
|
38
|
+
method = @expected_error.is_a?(Regexp) ? :=~ : :==
|
|
39
|
+
e.message.send(method, @expected_error)
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def description
|
|
44
44
|
case @expected_error
|
|
45
45
|
when nil
|
|
46
|
-
|
|
46
|
+
'compile into a catalogue without dependency cycles'
|
|
47
47
|
when Regexp
|
|
48
48
|
"fail to compile and raise an error matching #{@expected_error.inspect}"
|
|
49
49
|
else
|
|
@@ -52,12 +52,8 @@ module RSpec::Puppet
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def failure_message
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
else
|
|
58
|
-
unless @error_msg.empty?
|
|
59
|
-
"error during compilation: #{@error_msg}"
|
|
60
|
-
else
|
|
55
|
+
if @cycles.empty?
|
|
56
|
+
if @error_msg.empty?
|
|
61
57
|
case @expected_error
|
|
62
58
|
when nil
|
|
63
59
|
"expected that the catalogue would include #{@failed_resource}"
|
|
@@ -66,15 +62,19 @@ module RSpec::Puppet
|
|
|
66
62
|
else
|
|
67
63
|
"expected that the catalogue would fail to compile and raise the error #{@expected_error.inspect}"
|
|
68
64
|
end
|
|
65
|
+
else
|
|
66
|
+
"error during compilation: #{@error_msg}"
|
|
69
67
|
end
|
|
68
|
+
else
|
|
69
|
+
"dependency cycles found: #{@cycles.join('; ')}"
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
def failure_message_when_negated
|
|
74
74
|
if @expected_error.nil?
|
|
75
|
-
|
|
75
|
+
'expected that the catalogue would not compile but it does'
|
|
76
76
|
else
|
|
77
|
-
|
|
77
|
+
'expected that the catalogue would compile but it does not'
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
80
|
|
|
@@ -87,19 +87,18 @@ module RSpec::Puppet
|
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
private
|
|
90
|
+
|
|
90
91
|
def missing_dependencies?
|
|
91
92
|
retval = false
|
|
92
93
|
|
|
93
94
|
resource_vertices = @catalogue.vertices.select { |v| v.is_a? Puppet::Resource }
|
|
94
95
|
resource_vertices.each do |vertex|
|
|
95
|
-
vertex.each do |param,value|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
end
|
|
102
|
-
end
|
|
96
|
+
vertex.each do |param, value|
|
|
97
|
+
next unless %i[require subscribe notify before].include? param
|
|
98
|
+
|
|
99
|
+
value = [value] unless value.is_a? Array
|
|
100
|
+
value.each do |val|
|
|
101
|
+
retval = true if val.is_a?(Puppet::Resource) && !resource_exists?(val, vertex)
|
|
103
102
|
end
|
|
104
103
|
end
|
|
105
104
|
end
|
|
@@ -108,19 +107,15 @@ module RSpec::Puppet
|
|
|
108
107
|
end
|
|
109
108
|
|
|
110
109
|
def resource_hash
|
|
111
|
-
@resource_hash ||=
|
|
110
|
+
@resource_hash ||= proc do
|
|
112
111
|
res_hash = {}
|
|
113
112
|
@catalogue.vertices.each do |vertex|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if vertex.uniqueness_key != [vertex.title]
|
|
121
|
-
res_hash["#{vertex.type.to_s}[#{vertex.uniqueness_key.first}]"] = 1
|
|
122
|
-
end
|
|
123
|
-
end
|
|
113
|
+
next unless vertex.is_a? Puppet::Resource
|
|
114
|
+
|
|
115
|
+
res_hash[vertex.ref] = 1
|
|
116
|
+
res_hash["#{vertex.type}[#{vertex[:alias]}]"] = 1 if vertex[:alias]
|
|
117
|
+
|
|
118
|
+
res_hash["#{vertex.type}[#{vertex.uniqueness_key.first}]"] = 1 if vertex.uniqueness_key != [vertex.title]
|
|
124
119
|
end
|
|
125
120
|
res_hash
|
|
126
121
|
end.call
|
|
@@ -129,7 +124,7 @@ module RSpec::Puppet
|
|
|
129
124
|
def check_resource(res)
|
|
130
125
|
if resource_hash[res.ref]
|
|
131
126
|
true
|
|
132
|
-
elsif res[:alias] && resource_hash["#{res.type
|
|
127
|
+
elsif res[:alias] && resource_hash["#{res.type}[#{res[:alias]}]"]
|
|
133
128
|
true
|
|
134
129
|
else
|
|
135
130
|
false
|
|
@@ -137,11 +132,11 @@ module RSpec::Puppet
|
|
|
137
132
|
end
|
|
138
133
|
|
|
139
134
|
def resource_exists?(res, vertex)
|
|
140
|
-
|
|
135
|
+
if check_resource(res)
|
|
136
|
+
true
|
|
137
|
+
else
|
|
141
138
|
@failed_resource = "#{res.ref} used at #{vertex.file}:#{vertex.line} in #{vertex.ref}"
|
|
142
139
|
false
|
|
143
|
-
else
|
|
144
|
-
true
|
|
145
140
|
end
|
|
146
141
|
end
|
|
147
142
|
|
|
@@ -159,20 +154,18 @@ module RSpec::Puppet
|
|
|
159
154
|
|
|
160
155
|
def find_cycles(catalogue)
|
|
161
156
|
cycles = catalogue.find_cycles_in_graph
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
157
|
+
return unless cycles.length.positive?
|
|
158
|
+
|
|
159
|
+
cycles.each do |cycle|
|
|
160
|
+
paths = catalogue.paths_in_cycle(cycle)
|
|
161
|
+
@cycles << (paths.map { |path| "(#{path.join(' => ')})" }.join("\n") + "\n")
|
|
167
162
|
end
|
|
168
163
|
end
|
|
169
164
|
|
|
170
165
|
def find_cycles_legacy(catalogue)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
@cycles = [e.message.rpartition(';').first.partition(':').last]
|
|
175
|
-
end
|
|
166
|
+
catalogue.topsort
|
|
167
|
+
rescue Puppet::Error => e
|
|
168
|
+
@cycles = [e.message.rpartition(';').first.partition(':').last]
|
|
176
169
|
end
|
|
177
170
|
end
|
|
178
171
|
end
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module RSpec::Puppet
|
|
2
4
|
module ManifestMatchers
|
|
3
5
|
class CountGeneric
|
|
4
6
|
DEFAULT_RESOURCES = [
|
|
5
7
|
'Class[main]',
|
|
6
8
|
'Class[Settings]',
|
|
7
|
-
'Stage[main]'
|
|
9
|
+
'Stage[main]'
|
|
8
10
|
].freeze
|
|
9
11
|
|
|
10
12
|
attr_reader :resource_type
|
|
11
13
|
|
|
12
14
|
def initialize(type, count, *method)
|
|
13
|
-
if type.nil?
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
@type = if type.nil?
|
|
16
|
+
method[0].to_s.gsub(/^have_(.+)_resource_count$/, '\1')
|
|
17
|
+
else
|
|
18
|
+
type
|
|
19
|
+
end
|
|
18
20
|
@resource_type = referenced_type(@type)
|
|
19
21
|
@expected_number = count.to_i
|
|
20
22
|
end
|
|
@@ -28,7 +30,7 @@ module RSpec::Puppet
|
|
|
28
30
|
|
|
29
31
|
@actual_number = if @type == 'resource'
|
|
30
32
|
resources.count do |res|
|
|
31
|
-
|
|
33
|
+
!%w[Class Node].include?(res.type)
|
|
32
34
|
end
|
|
33
35
|
else
|
|
34
36
|
resources.count do |res|
|
|
@@ -43,24 +45,22 @@ module RSpec::Puppet
|
|
|
43
45
|
desc = []
|
|
44
46
|
|
|
45
47
|
desc << "contain exactly #{@expected_number}"
|
|
46
|
-
if @type ==
|
|
47
|
-
desc <<
|
|
48
|
+
if @type == 'class'
|
|
49
|
+
desc << (@expected_number == 1 ? 'class' : 'classes').to_s
|
|
48
50
|
else
|
|
49
|
-
unless @type ==
|
|
50
|
-
|
|
51
|
-
end
|
|
52
|
-
desc << "#{@expected_number == 1 ? "resource" : "resources" }"
|
|
51
|
+
desc << @resource_type.to_s unless @type == 'resource'
|
|
52
|
+
desc << (@expected_number == 1 ? 'resource' : 'resources').to_s
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
desc.join(
|
|
55
|
+
desc.join(' ')
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def failure_message
|
|
59
|
-
"expected that the catalogue would
|
|
59
|
+
"expected that the catalogue would #{description} but it contains #{@actual_number}"
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
def failure_message_when_negated
|
|
63
|
-
"expected that the catalogue would not
|
|
63
|
+
"expected that the catalogue would not #{description} but it does"
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
def supports_block_expectations
|
|
@@ -71,10 +71,10 @@ module RSpec::Puppet
|
|
|
71
71
|
true
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
private
|
|
75
75
|
|
|
76
76
|
def referenced_type(type)
|
|
77
|
-
type.split('__').map
|
|
77
|
+
type.split('__').map(&:capitalize).join('::')
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
80
|
|