rspec-puppet 2.11.1 → 3.0.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +139 -477
- data/README.md +18 -5
- data/bin/rspec-puppet-init +4 -3
- data/lib/rspec-puppet/adapters.rb +67 -61
- 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/application_example_group.rb +3 -1
- 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 +28 -23
- 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 -7
- 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 +68 -78
- data/lib/rspec-puppet/matchers/dynamic_matchers.rb +13 -2
- 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 +56 -56
- data/lib/rspec-puppet/rake_task.rb +6 -4
- data/lib/rspec-puppet/raw_string.rb +2 -0
- data/lib/rspec-puppet/sensitive.rb +9 -7
- data/lib/rspec-puppet/setup.rb +43 -48
- data/lib/rspec-puppet/spec_helper.rb +2 -0
- data/lib/rspec-puppet/support.rb +133 -134
- data/lib/rspec-puppet/tasks/release_test.rb +8 -5
- data/lib/rspec-puppet/version.rb +5 -0
- data/lib/rspec-puppet.rb +43 -51
- metadata +11 -9
@@ -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
|
@@ -87,8 +92,9 @@ module RSpec::Puppet
|
|
87
92
|
context_overrides = compiler.context_overrides
|
88
93
|
func = nil
|
89
94
|
loaders = Puppet.lookup(:loaders)
|
90
|
-
Puppet.override(context_overrides,
|
91
|
-
func = V4FunctionWrapper.new(function_name,
|
95
|
+
Puppet.override(context_overrides, 'rspec-test scope') do
|
96
|
+
func = V4FunctionWrapper.new(function_name,
|
97
|
+
loaders.private_environment_loader.load(:function, function_name), context_overrides)
|
92
98
|
@scope = context_overrides[:global_scope]
|
93
99
|
end
|
94
100
|
|
@@ -97,16 +103,14 @@ module RSpec::Puppet
|
|
97
103
|
|
98
104
|
if Puppet::Parser::Functions.function(function_name)
|
99
105
|
V3FunctionWrapper.new(function_name, scope.method("function_#{function_name}".intern))
|
100
|
-
else
|
101
|
-
nil
|
102
106
|
end
|
103
107
|
end
|
104
108
|
end
|
109
|
+
|
105
110
|
def call_function(function_name, *args)
|
106
|
-
|
107
|
-
# function.execute(*args)
|
108
|
-
scope.call_function(function_name, args)
|
111
|
+
scope.call_function(function_name, args)
|
109
112
|
end
|
113
|
+
|
110
114
|
def scope
|
111
115
|
@scope ||= build_scope(compiler, nodename(:function))
|
112
116
|
end
|
@@ -135,7 +139,7 @@ module RSpec::Puppet
|
|
135
139
|
trusted_values = trusted_facts_hash(node_name)
|
136
140
|
|
137
141
|
# Allow different Hiera configurations:
|
138
|
-
HieraPuppet.instance_variable_set(
|
142
|
+
HieraPuppet.instance_variable_set(:@hiera, nil) if defined? HieraPuppet
|
139
143
|
|
140
144
|
# if we specify a pre_condition, we should ensure that we compile that
|
141
145
|
# code into a catalog that is accessible from the scope where the
|
@@ -145,8 +149,8 @@ module RSpec::Puppet
|
|
145
149
|
node_facts = Puppet::Node::Facts.new(node_name, fact_values.dup)
|
146
150
|
|
147
151
|
node_options = {
|
148
|
-
:
|
149
|
-
:
|
152
|
+
parameters: fact_values,
|
153
|
+
facts: node_facts
|
150
154
|
}
|
151
155
|
|
152
156
|
stub_facts! fact_values
|
@@ -156,9 +160,9 @@ module RSpec::Puppet
|
|
156
160
|
if Puppet::Util::Package.versioncmp(Puppet.version, '4.3.0') >= 0
|
157
161
|
Puppet.push_context(
|
158
162
|
{
|
159
|
-
:
|
163
|
+
trusted_information: Puppet::Context::TrustedInformation.new('remote', node_name, trusted_values)
|
160
164
|
},
|
161
|
-
|
165
|
+
'Context for spec trusted hash'
|
162
166
|
)
|
163
167
|
end
|
164
168
|
|
@@ -168,10 +172,11 @@ module RSpec::Puppet
|
|
168
172
|
loaders = Puppet::Pops::Loaders.new(adapter.current_environment)
|
169
173
|
Puppet.push_context(
|
170
174
|
{
|
171
|
-
:
|
172
|
-
:
|
175
|
+
loaders: loaders,
|
176
|
+
global_scope: compiler.context_overrides[:global_scope]
|
173
177
|
},
|
174
|
-
|
178
|
+
'set globals'
|
179
|
+
)
|
175
180
|
end
|
176
181
|
compiler
|
177
182
|
end
|
@@ -179,12 +184,12 @@ module RSpec::Puppet
|
|
179
184
|
def build_scope(compiler, node_name)
|
180
185
|
if Puppet.version.to_f >= 4.0
|
181
186
|
return compiler.context_overrides[:global_scope]
|
182
|
-
elsif
|
187
|
+
elsif /^2\.[67]/.match?(Puppet.version)
|
183
188
|
# loadall should only be necessary prior to 3.x
|
184
189
|
# Please note, loadall needs to happen first when creating a scope, otherwise
|
185
190
|
# you might receive undefined method `function_*' errors
|
186
191
|
Puppet::Parser::Functions.autoloader.loadall
|
187
|
-
scope = Puppet::Parser::Scope.new(:
|
192
|
+
scope = Puppet::Parser::Scope.new(compiler: compiler)
|
188
193
|
else
|
189
194
|
scope = Puppet::Parser::Scope.new(compiler)
|
190
195
|
end
|
@@ -196,7 +201,7 @@ module RSpec::Puppet
|
|
196
201
|
|
197
202
|
def build_node(name, opts = {})
|
198
203
|
node_environment = adapter.current_environment
|
199
|
-
opts
|
204
|
+
opts[:environment] = node_environment
|
200
205
|
Puppet::Node.new(name, opts)
|
201
206
|
end
|
202
207
|
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'
|
@@ -8,15 +10,12 @@ require 'rspec-puppet/example/type_alias_example_group'
|
|
8
10
|
require 'rspec-puppet/example/provider_example_group'
|
9
11
|
require 'rspec-puppet/example/application_example_group'
|
10
12
|
|
11
|
-
RSpec
|
12
|
-
|
13
|
+
RSpec.configure do |c|
|
13
14
|
def c.rspec_puppet_include(group, type, file_path)
|
14
15
|
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
|
16
|
+
include group, type: type, file_path: lambda { |file_path, metadata|
|
17
|
+
metadata[:type].nil? && escaped_file_path =~ file_path
|
18
|
+
}
|
20
19
|
end
|
21
20
|
|
22
21
|
c.rspec_puppet_include RSpec::Puppet::DefineExampleGroup, :define, %w[spec defines]
|
@@ -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 = Array[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
|
|