puppet-spec 1.0.2

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0345031ab1c4f7933dc095e0c18df8013024955b
4
+ data.tar.gz: 6793e3f07d6e388b31ff7d52298e9cc233a6cd93
5
+ SHA512:
6
+ metadata.gz: 3c2297d9f5306ca4808b5b7e06eee0183998901f11d4b5216364fe9f77aea2d5b492ceca5455f160145cb4bb6a70dc2916909a56bf18aab724da25570f8c7ab3
7
+ data.tar.gz: 7381fa58926e80438f6f75d41625a862b187dac73332b3604e540e78c5d6c6425e176f73acbeb613a3a7bd16d833239ec579eb6d9d851525ceb50c514b767859
@@ -0,0 +1,6 @@
1
+ require 'puppet/application/spec'
2
+
3
+ desc "Evaluate puppet-spec test cases and print the results"
4
+ task(:puppetspec) do
5
+ Puppet::Application::Spec.new.run
6
+ end
@@ -0,0 +1,160 @@
1
+ require 'puppet'
2
+ require 'puppet/test/test_helper'
3
+ require 'puppet/util/colors'
4
+ require 'fileutils'
5
+
6
+ class Puppet::Application::Spec < Puppet::Application
7
+ include Puppet::Util::Colors
8
+
9
+ def run_command
10
+ output = Hash.new
11
+
12
+ begin
13
+ Puppet::Test::TestHelper.initialize
14
+ output = process_spec_directory(specdir)
15
+ rescue Exception => e
16
+ print colorize(:red, "#{e.message}\n")
17
+ exit 1
18
+ end
19
+
20
+ if output[:failed] == 0
21
+ exit 0
22
+ else
23
+ exit 1
24
+ end
25
+ end
26
+
27
+ def process_spec_directory(specdir)
28
+ results = Dir.glob("#{specdir}/**/*_spec.pp").map { |spec| process_spec(spec) }.flatten
29
+ output = visit_assertions(results)
30
+ print_results(output)
31
+ output
32
+ end
33
+
34
+ def process_spec(path)
35
+ catalog = catalog(path)
36
+ notify_compiled
37
+
38
+ assertions = catalog.resources.select {|res| res.type == 'Assertion' }
39
+
40
+ # Get the subject resource from the catalog rather than the
41
+ # reference provided from the parser. The reference's resource
42
+ # object does not contain any parameters for whatever reason.
43
+ assertions.map do |res|
44
+ res[:subject] = catalog.resource(res[:subject].to_s)
45
+ res
46
+ end
47
+ end
48
+
49
+ def catalog(path)
50
+ Puppet::Test::TestHelper.before_each_test
51
+ Puppet[:code] = File.read(path)
52
+
53
+ node = Puppet::Node.new("spec")
54
+ modulepath = get_modulepath(node)
55
+ link_module(modulepath)
56
+ catalog = Puppet::Resource::Catalog.indirection.find(node.name, :use_node => node)
57
+ catalog.to_ral
58
+
59
+ Puppet::Test::TestHelper.after_each_test
60
+ catalog
61
+ end
62
+
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
+ # Given a node object, return
126
+ # the first modulepath
127
+ def get_modulepath(node)
128
+ node.environment.full_modulepath[0]
129
+ end
130
+
131
+ # Ensure that a symlink is present
132
+ # pointing from the node's env
133
+ # to the current directory
134
+ def link_module(modulepath)
135
+ pwd = Dir.pwd
136
+ name = File.basename(pwd)
137
+ symlink = File.join(modulepath, name)
138
+
139
+ # Ensure that the modulepath exists
140
+ # within the temp environment
141
+ FileUtils.mkdir_p(modulepath) unless Dir.exist?(modulepath)
142
+
143
+ # Ensure that a symlink to the
144
+ # cwd exists
145
+ FileUtils.ln_s(pwd, symlink) unless File.symlink?(symlink)
146
+ end
147
+
148
+ # Return the specdir under the
149
+ # CWD or raise an error if not
150
+ # found.
151
+ def specdir
152
+ pwd = Dir.pwd
153
+ specdir = File.join(pwd, 'spec')
154
+ unless Dir.exist?(specdir)
155
+ raise 'No spec directory was found under the CWD. You can optionally specifiy one with --specdir'
156
+ end
157
+ specdir
158
+ end
159
+
160
+ end
@@ -0,0 +1,7 @@
1
+ Puppet::Parser::Functions.newfunction(:stub_class, :arity => 1) do |values|
2
+
3
+ raise Puppet::Error, "stub_class accepts a class name in the form of a string" unless values[0].is_a?(String)
4
+
5
+ compiler.environment.known_resource_types << Puppet::Resource::Type.new(:hostclass, values[0])
6
+
7
+ end
@@ -0,0 +1,9 @@
1
+ Puppet::Parser::Functions.newfunction(:stub_facts, :arity => 1) do |values|
2
+
3
+ raise Puppet::Error, "stub_facts accepts a hash of fact/value pairs" unless values[0].is_a?(Hash)
4
+
5
+ values[0].each do |key, value|
6
+ compiler.topscope[key] = value
7
+ end
8
+
9
+ end
@@ -0,0 +1,15 @@
1
+ class Puppet::Resource::Type::Stub < Puppet::Resource::Type
2
+ # Allow the stub type to receive
3
+ # assignments on any parameter key.
4
+ def valid_parameter?(name)
5
+ true
6
+ end
7
+ end
8
+
9
+ Puppet::Parser::Functions.newfunction(:stub_type, :arity => 1) do |values|
10
+
11
+ raise Puppet::Error, "stub_type accepts a type name in the form of a string" unless values[0].is_a?(String)
12
+
13
+ compiler.environment.known_resource_types << Puppet::Resource::Type::Stub.new(:definition, values[0])
14
+
15
+ end
@@ -0,0 +1,41 @@
1
+ Puppet::Type.newtype(:assertion) do
2
+
3
+ @doc = "Makes assertions on the state of a resource in the catalog.
4
+
5
+ The assertion type defines an assertion that will be evaluated by the
6
+ spec application.
7
+ "
8
+
9
+ newparam(:name) do
10
+ desc "A plain text message describing what the assertion is intended to prove.
11
+
12
+ The given text should form a sentence using the type's name.
13
+ Example: assertion { 'that the configuration file has the correct contents': }
14
+ "
15
+ end
16
+
17
+ newparam(:subject) do
18
+ desc "A reference to the resource to be asserted upon.
19
+
20
+ The referenced resource will be the subject of any assertions made as a result of this resource declaration.
21
+ "
22
+
23
+ validate do |value|
24
+ fail Puppet::Error, "You must provide an assertion subject" unless value
25
+ fail Puppet::Error, "Attributes must be a resource reference" unless value.is_a? Puppet::Resource
26
+ end
27
+ end
28
+
29
+ newparam(:attribute) do
30
+ 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
+ end
36
+
37
+ newparam(:expectation) do
38
+ desc "The expected value of the subject's attribute"
39
+ end
40
+
41
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: puppet-spec
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Jordan Olshevski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: puppet
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: puppetlabs_spec_helper
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.10.3
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 0.10.3
41
+ description: A Puppet testing framework implemented in the native DSL
42
+ email:
43
+ - jordan@puppetlabs.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - lib/puppet-spec/tasks.rb
49
+ - lib/puppet/application/spec.rb
50
+ - lib/puppet/parser/functions/stub_class.rb
51
+ - lib/puppet/parser/functions/stub_facts.rb
52
+ - lib/puppet/parser/functions/stub_type.rb
53
+ - lib/puppet/type/assertion.rb
54
+ homepage: http://github.com/jolshevski/puppet-spec
55
+ licenses:
56
+ - Apache-2.0
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 2.4.6
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: Test Puppet code with Puppet code
78
+ test_files: []