puppet-spec 1.0.2 → 1.1.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/lib/puppet/application/spec.rb +25 -83
- data/lib/puppet/parser/functions/stub_class.rb +3 -1
- data/lib/puppet/parser/functions/stub_type.rb +2 -8
- data/lib/puppet/provider/assertion/evaluator.rb +31 -0
- data/lib/puppet/type/assertion.rb +7 -6
- data/lib/puppet/util/assertion/printer.rb +52 -0
- data/lib/puppet/util/assertion/reporter.rb +82 -0
- data/lib/puppet/util/assertion/stubs.rb +16 -0
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e1b2a6f102ca870df851cd6b7e8b3fe181466d71
|
|
4
|
+
data.tar.gz: fbf64c3b18cda7e63ffd17261dae625ecd7dab38
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f14eb73db5ebfe8cf67ff076159ef9ba3dc1bd9fe6ff0082a0780be50475316e799a7c9108db91e51ee0130cd2bf23193894550f4a658b882045a4eab61ff6ff
|
|
7
|
+
data.tar.gz: 656f782afe6f0ce5b44b57a5cc77e0a7a60dbd0565885a884bf10c7012fa218e5389a3832497f7a77af1e3710541dccd9794c5545266d86f84d93a56264e4c27
|
|
@@ -1,48 +1,52 @@
|
|
|
1
1
|
require 'puppet'
|
|
2
2
|
require 'puppet/test/test_helper'
|
|
3
|
-
require 'puppet/util/
|
|
3
|
+
require 'puppet/util/assertion/reporter'
|
|
4
4
|
require 'fileutils'
|
|
5
5
|
|
|
6
6
|
class Puppet::Application::Spec < Puppet::Application
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
option("--manifest manifest", "-m manifest")
|
|
9
|
+
|
|
10
|
+
attr_reader :reporter
|
|
8
11
|
|
|
9
12
|
def run_command
|
|
10
|
-
|
|
13
|
+
@reporter = Puppet::Util::Assertion::Reporter.new
|
|
11
14
|
|
|
12
15
|
begin
|
|
13
16
|
Puppet::Test::TestHelper.initialize
|
|
14
|
-
|
|
17
|
+
evaluate_assertions
|
|
18
|
+
reporter.print_footer
|
|
15
19
|
rescue Exception => e
|
|
16
|
-
|
|
17
|
-
exit 1
|
|
20
|
+
reporter.print_error(e)
|
|
18
21
|
end
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
exit 1 unless reporter.failed == 0
|
|
24
|
+
exit 0
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def evaluate_assertions
|
|
28
|
+
if options[:manifest]
|
|
29
|
+
process_spec(options[:manifest])
|
|
22
30
|
else
|
|
23
|
-
|
|
31
|
+
process_spec_directory(specdir)
|
|
24
32
|
end
|
|
25
33
|
end
|
|
26
34
|
|
|
27
35
|
def process_spec_directory(specdir)
|
|
28
|
-
|
|
29
|
-
output = visit_assertions(results)
|
|
30
|
-
print_results(output)
|
|
31
|
-
output
|
|
36
|
+
Dir.glob("#{specdir}/**/*_spec.pp").map { |spec| process_spec(spec) }
|
|
32
37
|
end
|
|
33
38
|
|
|
34
39
|
def process_spec(path)
|
|
35
40
|
catalog = catalog(path)
|
|
36
|
-
notify_compiled
|
|
37
|
-
|
|
38
41
|
assertions = catalog.resources.select {|res| res.type == 'Assertion' }
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
assertions.each do |res|
|
|
44
|
+
# Get the subject resource from the catalog rather than the
|
|
45
|
+
# reference provided from the parser. The reference's resource
|
|
46
|
+
# object does not contain any parameters for whatever reason.
|
|
44
47
|
res[:subject] = catalog.resource(res[:subject].to_s)
|
|
45
|
-
|
|
48
|
+
|
|
49
|
+
reporter << res.to_ral
|
|
46
50
|
end
|
|
47
51
|
end
|
|
48
52
|
|
|
@@ -60,68 +64,6 @@ class Puppet::Application::Spec < Puppet::Application
|
|
|
60
64
|
catalog
|
|
61
65
|
end
|
|
62
66
|
|
|
63
|
-
# Return a hash that contains
|
|
64
|
-
# data to be displayed to the
|
|
65
|
-
# user which represents the results
|
|
66
|
-
# of the assertions.
|
|
67
|
-
def visit_assertions(assertions)
|
|
68
|
-
count = 0
|
|
69
|
-
failed_count = 0
|
|
70
|
-
|
|
71
|
-
msg = assertions.map do |assertion|
|
|
72
|
-
count += 1
|
|
73
|
-
validate_assertion(assertion)
|
|
74
|
-
|
|
75
|
-
unless assertion[:expectation] == assertion[:subject][assertion[:attribute]]
|
|
76
|
-
failed_count += 1
|
|
77
|
-
file = assertion[:subject].file.split('manifests/').last
|
|
78
|
-
|
|
79
|
-
msg = colorize(:red, "#{failed_count}) Assertion #{assertion[:name]} failed on #{assertion[:subject].to_s}\n")
|
|
80
|
-
msg += colorize(:yellow, " On line #{assertion[:subject].line} of #{file}\n")
|
|
81
|
-
msg += colorize(:blue, " Wanted: ")
|
|
82
|
-
msg += "#{assertion[:attribute]} => '#{assertion[:expectation]}'\n"
|
|
83
|
-
msg += colorize(:blue, " Got: ")
|
|
84
|
-
msg += "#{assertion[:attribute]} => '#{assertion[:subject][assertion[:attribute]]}'\n\n"
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
{
|
|
89
|
-
:msg => msg.join,
|
|
90
|
-
:count => count,
|
|
91
|
-
:failed => failed_count,
|
|
92
|
-
}
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# Given the resulting hash
|
|
96
|
-
# from .visit_assertions,
|
|
97
|
-
# present the output to the
|
|
98
|
-
# user.
|
|
99
|
-
def print_results(results)
|
|
100
|
-
print "\n\n"
|
|
101
|
-
print results[:msg] if results[:msg]
|
|
102
|
-
|
|
103
|
-
if results[:count] == 1
|
|
104
|
-
print colorize(:yellow, "Evaluated #{results[:count]} assertion\n")
|
|
105
|
-
else
|
|
106
|
-
print colorize(:yellow, "Evaluated #{results[:count]} assertions\n")
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# Validate assertion raises an error
|
|
111
|
-
# if the assertion does not contain
|
|
112
|
-
# a subject, or if it contains a
|
|
113
|
-
# expectation without attribute.
|
|
114
|
-
def validate_assertion(assertion)
|
|
115
|
-
raise Puppet::Error, "#{assertion} requires a subject" unless assertion[:subject]
|
|
116
|
-
raise Puppet::Error, "#{assertion} requires an attribute when an expectation is given" if assertion[:expectation] and not assertion[:attribute]
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# Print an rspec style dot
|
|
120
|
-
# to signify spec compilation
|
|
121
|
-
def notify_compiled
|
|
122
|
-
print colorize(:green, '.')
|
|
123
|
-
end
|
|
124
|
-
|
|
125
67
|
# Given a node object, return
|
|
126
68
|
# the first modulepath
|
|
127
69
|
def get_modulepath(node)
|
|
@@ -152,7 +94,7 @@ class Puppet::Application::Spec < Puppet::Application
|
|
|
152
94
|
pwd = Dir.pwd
|
|
153
95
|
specdir = File.join(pwd, 'spec')
|
|
154
96
|
unless Dir.exist?(specdir)
|
|
155
|
-
raise 'No spec directory was found under the CWD.
|
|
97
|
+
raise 'No spec directory was found under the CWD. A spec manifest can be specified with the --manifest flag'
|
|
156
98
|
end
|
|
157
99
|
specdir
|
|
158
100
|
end
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
require 'puppet/util/assertion/stubs'
|
|
2
|
+
|
|
1
3
|
Puppet::Parser::Functions.newfunction(:stub_class, :arity => 1) do |values|
|
|
2
4
|
|
|
3
5
|
raise Puppet::Error, "stub_class accepts a class name in the form of a string" unless values[0].is_a?(String)
|
|
4
6
|
|
|
5
|
-
compiler.environment.known_resource_types << Puppet::
|
|
7
|
+
compiler.environment.known_resource_types << Puppet::Util::Assertion::Stubs::Type.new(:hostclass, values[0])
|
|
6
8
|
|
|
7
9
|
end
|
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
# Allow the stub type to receive
|
|
3
|
-
# assignments on any parameter key.
|
|
4
|
-
def valid_parameter?(name)
|
|
5
|
-
true
|
|
6
|
-
end
|
|
7
|
-
end
|
|
1
|
+
require 'puppet/util/assertion/stubs'
|
|
8
2
|
|
|
9
3
|
Puppet::Parser::Functions.newfunction(:stub_type, :arity => 1) do |values|
|
|
10
4
|
|
|
11
5
|
raise Puppet::Error, "stub_type accepts a type name in the form of a string" unless values[0].is_a?(String)
|
|
12
6
|
|
|
13
|
-
compiler.environment.known_resource_types << Puppet::
|
|
7
|
+
compiler.environment.known_resource_types << Puppet::Util::Assertion::Stubs::Type.new(:definition, values[0])
|
|
14
8
|
|
|
15
9
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Puppet::Type.type(:assertion).provide(:evaluator) do
|
|
2
|
+
|
|
3
|
+
# Returns the complete path to the
|
|
4
|
+
# subject's manifest after /manifests
|
|
5
|
+
def relative_path
|
|
6
|
+
@resource[:subject].file.split('manifests/').last
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Returns a hash containing the assertion's
|
|
10
|
+
# attribute as the single key, with the value
|
|
11
|
+
# of the expectation. Used for rendering the
|
|
12
|
+
# results to the console.
|
|
13
|
+
def wanted
|
|
14
|
+
{ @resource[:attribute] => @resource[:expectation] }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Returns a hash containing the assertion's
|
|
18
|
+
# attribute as the single key, with the value
|
|
19
|
+
# of the subject's attribute. Used for rendering the
|
|
20
|
+
# results to the console.
|
|
21
|
+
def got
|
|
22
|
+
{ @resource[:attribute] => @resource[:subject][@resource[:attribute]] }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Return false if the subject's attribute is
|
|
26
|
+
# equal to the expectation, true otherwise.
|
|
27
|
+
def failed?
|
|
28
|
+
@resource[:expectation] != @resource[:subject][@resource[:attribute]]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
@@ -6,6 +6,12 @@ Puppet::Type.newtype(:assertion) do
|
|
|
6
6
|
spec application.
|
|
7
7
|
"
|
|
8
8
|
|
|
9
|
+
validate do
|
|
10
|
+
fail Puppet::Error, "a subject is required" unless @parameters[:subject]
|
|
11
|
+
fail Puppet::Error, "an attribute is required when an expectation is given" if @parameters[:expectation] and not @parameters[:attribute]
|
|
12
|
+
fail Puppet::Error, "an expectation is required when an attribute is given" if @parameters[:attribute] and not @parameters[:expectation]
|
|
13
|
+
end
|
|
14
|
+
|
|
9
15
|
newparam(:name) do
|
|
10
16
|
desc "A plain text message describing what the assertion is intended to prove.
|
|
11
17
|
|
|
@@ -21,17 +27,12 @@ Puppet::Type.newtype(:assertion) do
|
|
|
21
27
|
"
|
|
22
28
|
|
|
23
29
|
validate do |value|
|
|
24
|
-
fail Puppet::Error, "
|
|
25
|
-
fail Puppet::Error, "Attributes must be a resource reference" unless value.is_a? Puppet::Resource
|
|
30
|
+
fail Puppet::Error, "Subject must be a resource reference" unless value.is_a? Puppet::Resource
|
|
26
31
|
end
|
|
27
32
|
end
|
|
28
33
|
|
|
29
34
|
newparam(:attribute) do
|
|
30
35
|
desc "An attribute of the subject resource to assert against"
|
|
31
|
-
|
|
32
|
-
validate do |value|
|
|
33
|
-
fail Puppet::Error, "You must provide attribute to be asserted" unless value
|
|
34
|
-
end
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
newparam(:expectation) do
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'puppet/util/colors'
|
|
2
|
+
|
|
3
|
+
module Puppet::Util
|
|
4
|
+
module Assertion
|
|
5
|
+
class Printer
|
|
6
|
+
include Puppet::Util::Colors
|
|
7
|
+
|
|
8
|
+
attr_reader :stack
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
@stack = []
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def red(msg)
|
|
15
|
+
stack << colorize(:red, msg)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def blue(msg)
|
|
19
|
+
stack << colorize(:blue, msg)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def yellow(msg)
|
|
23
|
+
stack << colorize(:yellow, msg)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def white(msg)
|
|
27
|
+
stack << msg
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def newline
|
|
31
|
+
stack << "\n"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def to_s
|
|
35
|
+
stack.join
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Styler is a mixin that provides a helper
|
|
39
|
+
# method that parses a styled string by
|
|
40
|
+
# evaluating the given proc on an instance
|
|
41
|
+
# of Printer.
|
|
42
|
+
module Styler
|
|
43
|
+
def style(&proc)
|
|
44
|
+
printer = Puppet::Util::Assertion::Printer.new
|
|
45
|
+
printer.instance_eval(&proc)
|
|
46
|
+
print printer.to_s
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require 'puppet/util/assertion/printer'
|
|
2
|
+
|
|
3
|
+
module Puppet::Util
|
|
4
|
+
module Assertion
|
|
5
|
+
class Reporter
|
|
6
|
+
include Puppet::Util::Assertion::Printer::Styler
|
|
7
|
+
|
|
8
|
+
attr_reader :evaluated, :failed
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
@evaluated = 0
|
|
12
|
+
@failed = 0
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Given an assertion resource, evaluate it for success
|
|
16
|
+
# and send it to .report on failure. Increment the counter
|
|
17
|
+
# for each resource, and the failed counter for failed resources.
|
|
18
|
+
def <<(assertion)
|
|
19
|
+
count
|
|
20
|
+
if assertion.provider.failed?
|
|
21
|
+
fail
|
|
22
|
+
report(assertion)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Print the summary of evaluated assertions
|
|
27
|
+
def print_footer
|
|
28
|
+
# Shim the reporter into the local scope
|
|
29
|
+
reporter = self
|
|
30
|
+
|
|
31
|
+
style do
|
|
32
|
+
if reporter.evaluated == 1
|
|
33
|
+
yellow "Evaluated 1 assertion\n"
|
|
34
|
+
else
|
|
35
|
+
yellow "Evaluated #{reporter.evaluated} assertions\n"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def print_error(err)
|
|
41
|
+
fail #Mark an assertion so the application exits 1
|
|
42
|
+
style do
|
|
43
|
+
red err.message
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Pretty print the results of an assertion to the console
|
|
48
|
+
def report(assertion)
|
|
49
|
+
# Shim the value of failed into the
|
|
50
|
+
# local scope in order to access it
|
|
51
|
+
# from the style proc.
|
|
52
|
+
failed = @failed
|
|
53
|
+
|
|
54
|
+
style do
|
|
55
|
+
red "#{failed}) Assertion #{assertion[:name]} failed on #{assertion[:subject].to_s}"
|
|
56
|
+
newline
|
|
57
|
+
|
|
58
|
+
yellow " On line #{assertion[:subject].line} of #{assertion.provider.relative_path}"
|
|
59
|
+
newline
|
|
60
|
+
|
|
61
|
+
blue " Wanted: "
|
|
62
|
+
white assertion.provider.wanted.to_s
|
|
63
|
+
newline
|
|
64
|
+
|
|
65
|
+
blue " Got: "
|
|
66
|
+
white assertion.provider.got.to_s
|
|
67
|
+
newline
|
|
68
|
+
newline
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def count
|
|
73
|
+
@evaluated += 1
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def fail
|
|
77
|
+
@failed += 1
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'puppet/resource/type'
|
|
2
|
+
|
|
3
|
+
module Puppet::Util::Assertion
|
|
4
|
+
class Stubs
|
|
5
|
+
|
|
6
|
+
# This type reimplements the Puppet::Resource::Type class
|
|
7
|
+
# and overwrites the parameter validation in order to
|
|
8
|
+
# allow any param to be assigned a value.
|
|
9
|
+
class Type < Puppet::Resource::Type
|
|
10
|
+
def valid_parameter?(name)
|
|
11
|
+
true
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: puppet-spec
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jordan Olshevski
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-09-
|
|
11
|
+
date: 2015-09-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: puppet
|
|
@@ -50,7 +50,11 @@ files:
|
|
|
50
50
|
- lib/puppet/parser/functions/stub_class.rb
|
|
51
51
|
- lib/puppet/parser/functions/stub_facts.rb
|
|
52
52
|
- lib/puppet/parser/functions/stub_type.rb
|
|
53
|
+
- lib/puppet/provider/assertion/evaluator.rb
|
|
53
54
|
- lib/puppet/type/assertion.rb
|
|
55
|
+
- lib/puppet/util/assertion/printer.rb
|
|
56
|
+
- lib/puppet/util/assertion/reporter.rb
|
|
57
|
+
- lib/puppet/util/assertion/stubs.rb
|
|
54
58
|
homepage: http://github.com/jolshevski/puppet-spec
|
|
55
59
|
licenses:
|
|
56
60
|
- Apache-2.0
|