puppet-spec 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []