rspec-puppet 2.4.0 → 2.5.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 +21 -1
- data/README.md +93 -2
- data/lib/rspec-puppet/example.rb +5 -0
- data/lib/rspec-puppet/example/application_example_group.rb +19 -0
- data/lib/rspec-puppet/example/function_example_group.rb +79 -16
- data/lib/rspec-puppet/matchers/run.rb +5 -21
- data/lib/rspec-puppet/raw_string.rb +16 -0
- data/lib/rspec-puppet/setup.rb +1 -1
- data/lib/rspec-puppet/support.rb +68 -24
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a4f52ea0428c49bc328570e7a71776b75b800b2
|
4
|
+
data.tar.gz: 461fadebe1cd4756715a99d54fefdf51c020a17b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f79f8be40bf4e2c77e11ddf68130ea0fe97b8e629cf4768c2da1a15a096ed65fad3dff160208a36b9d221f652564956fc15113b56589562a8890c01a4678098
|
7
|
+
data.tar.gz: bc64b10392874054ebf8cfe7712abc25874bfa3d44ebd3c6dced81d3eae7c99b359754dd3d74481dfc1851264ce347f8f76990e0022f8e653b622a77ade449d5
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,25 @@
|
|
2
2
|
All notable changes to this project will be documented in this file. This
|
3
3
|
project adheres to [Semantic Versioning](http://semver.org/).
|
4
4
|
|
5
|
+
## [2.5.0]
|
6
|
+
|
7
|
+
Headline features are app management, nested hashes in params, and testing for "internal" functions.
|
8
|
+
|
9
|
+
Thanks to everyone who contributed: Leo Arnold, Matt Schuchard, and Si Wilkins
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
|
13
|
+
* Updates to the README
|
14
|
+
* Improve Gemfile to work with older rubies
|
15
|
+
|
16
|
+
### Added
|
17
|
+
|
18
|
+
* Add support for app management testing
|
19
|
+
* Enable nested hashes in params
|
20
|
+
* After refactoring the function test code, puppet 4 "internal" functions can now be tested too
|
21
|
+
* Link functions and types on setup
|
22
|
+
* Increased test coverage
|
23
|
+
|
5
24
|
## [2.4.0]
|
6
25
|
|
7
26
|
This release now supports testing exported resources in the same way that normal resources in the catalog are tested. Access them in your examples using `exported_resources`. See "Testing Exported Resources" in the README for examples.
|
@@ -114,7 +133,8 @@ Thanks to Adrien Thebo, Alex Harvey, Brian, Dan Bode, Dominic Cleal, Javier Pala
|
|
114
133
|
## 1.0.1 and earlier
|
115
134
|
For changelog of versions 1.0.1 and earlier, see http://rspec-puppet.com/changelog/
|
116
135
|
|
117
|
-
[2.x]: https://github.com/rodjek/rspec-puppet/compare/v2.
|
136
|
+
[2.x]: https://github.com/rodjek/rspec-puppet/compare/v2.5.0...master
|
137
|
+
[2.5.0]: https://github.com/rodjek/rspec-puppet/compare/v2.4.0...v2.5.0
|
118
138
|
[2.4.0]: https://github.com/rodjek/rspec-puppet/compare/v2.3.2...v2.4.0
|
119
139
|
[2.3.2]: https://github.com/rodjek/rspec-puppet/compare/v2.3.1...v2.3.2
|
120
140
|
[2.3.1]: https://github.com/rodjek/rspec-puppet/compare/v2.3.0...v2.3.1
|
data/README.md
CHANGED
@@ -37,6 +37,10 @@ structure and naming convention.
|
|
37
37
|
| |
|
38
38
|
| +-- <define_name>_spec.rb
|
39
39
|
|
|
40
|
+
+-- applications
|
41
|
+
| |
|
42
|
+
| +-- <application_name>_spec.rb
|
43
|
+
|
|
40
44
|
+-- functions
|
41
45
|
| |
|
42
46
|
| +-- <function_name>_spec.rb
|
@@ -64,6 +68,10 @@ describe 'mydefine', :type => :define do
|
|
64
68
|
...
|
65
69
|
end
|
66
70
|
|
71
|
+
describe 'myapplication', :type => :application do
|
72
|
+
...
|
73
|
+
end
|
74
|
+
|
67
75
|
describe 'myfunction', :type => :puppet_function do
|
68
76
|
...
|
69
77
|
end
|
@@ -77,7 +85,7 @@ describe 'myhost.example.com', :type => :host do
|
|
77
85
|
end
|
78
86
|
```
|
79
87
|
|
80
|
-
## Defined Types &
|
88
|
+
## Defined Types, Classes & Applications
|
81
89
|
|
82
90
|
### Matchers
|
83
91
|
|
@@ -354,16 +362,45 @@ let(:title) { 'foo' }
|
|
354
362
|
|
355
363
|
#### Specifying the parameters to pass to a resources or parameterised class
|
356
364
|
|
365
|
+
Parameters of a defined type, class or application can be passed defining `:params` in a let,
|
366
|
+
and passing it a hash as seen below.
|
367
|
+
|
357
368
|
```ruby
|
358
369
|
let(:params) { {:ensure => 'present', ...} }
|
359
370
|
```
|
360
371
|
|
361
|
-
|
372
|
+
For passing Puppet's `undef` as a paremeter value, you can simply use `:undef` and it will
|
373
|
+
be translated to `undef` when compiling. For example:
|
362
374
|
|
363
375
|
```ruby
|
364
376
|
let(:params) { {:user => :undef, ...} }
|
365
377
|
```
|
366
378
|
|
379
|
+
For references to nodes or resources as seen when using `require` or `before` properties,
|
380
|
+
or an `application` resource you can pass the string as an argument to the `ref` helper:
|
381
|
+
|
382
|
+
```ruby
|
383
|
+
let(:params) { :require => ref('Package', 'sudoku') }
|
384
|
+
```
|
385
|
+
|
386
|
+
Which translates to:
|
387
|
+
|
388
|
+
```puppet
|
389
|
+
mydefine { 'mytitle': require => Package['sudoku'] }
|
390
|
+
```
|
391
|
+
|
392
|
+
Another example, for an application setup (when using `app_management`):
|
393
|
+
|
394
|
+
```ruby
|
395
|
+
let(:params) { { :nodes => { ref('Node', 'dbnode') => ref('Myapp::Mycomponent', 'myapp') } } }
|
396
|
+
```
|
397
|
+
|
398
|
+
Will translate to:
|
399
|
+
|
400
|
+
```puppet
|
401
|
+
site { myapp { 'myimpl': nodes => { Node['dbnode'] => Myapp::Mycomponent['myimpl'] } } }
|
402
|
+
```
|
403
|
+
|
367
404
|
#### Specifying the FQDN of the test node
|
368
405
|
|
369
406
|
If the manifest you're testing expects to run on host with a particular name,
|
@@ -450,6 +487,46 @@ You can also use `exported_resources` directly in a test:
|
|
450
487
|
it { expect(exported_resources).to contain_file('foo') }
|
451
488
|
```
|
452
489
|
|
490
|
+
#### Testing applications
|
491
|
+
|
492
|
+
Applications in some ways behave as defined resources, but are more complex so
|
493
|
+
require a number of elements already documented above to be combined for testing.
|
494
|
+
|
495
|
+
A full example of the simplest rspec test for a single component application:
|
496
|
+
|
497
|
+
```ruby
|
498
|
+
require 'spec_helper'
|
499
|
+
|
500
|
+
describe 'orch_app' do
|
501
|
+
let(:node) { 'my_node' }
|
502
|
+
let(:title) { 'my_awesome_app' }
|
503
|
+
let(:params) do
|
504
|
+
{
|
505
|
+
:nodes => {
|
506
|
+
ref('Node', node) => ref('Orch_app::Db', title),
|
507
|
+
}
|
508
|
+
}
|
509
|
+
end
|
510
|
+
|
511
|
+
it { should compile }
|
512
|
+
it { should contain_orch_app(title) }
|
513
|
+
end
|
514
|
+
```
|
515
|
+
|
516
|
+
Each piece is required:
|
517
|
+
|
518
|
+
* You must turn on app_management during testing for the handling to work
|
519
|
+
* The `:node` definition is required to be set so later on you can reference it in the `:nodes` argument within `:params`
|
520
|
+
* Applications act like defined resources, and each require a `:title` to be defined
|
521
|
+
* The `:nodes` key in `:params` requires the use of node reference mappings to resource
|
522
|
+
mappings. The `ref` keyword allows you to provide these (a normal string will not work).
|
523
|
+
|
524
|
+
Beyond these requirements, the very basic `should compile` test and other matchers
|
525
|
+
as you would expect will work the same as classes and defined resources.
|
526
|
+
|
527
|
+
**Note:** for the moment, cross-node support is not available and will return an error.
|
528
|
+
Ensure you model your tests to be single-node for the time being.
|
529
|
+
|
453
530
|
## Functions
|
454
531
|
|
455
532
|
### Matchers
|
@@ -554,6 +631,20 @@ before(:each) { scope.expects(:lookupvar).with('some_variable').returns('some_va
|
|
554
631
|
it { is_expected.to run.with_params('...').and_return('...') }
|
555
632
|
```
|
556
633
|
|
634
|
+
Note that this does not work when testing manifests which use custom functions. Instead,
|
635
|
+
you'll need to create a replacement function directly.
|
636
|
+
|
637
|
+
```ruby
|
638
|
+
before(:each) do
|
639
|
+
Puppet::Parser::Functions.newfunction(:custom_function, :type => :rvalue) { |args|
|
640
|
+
raise ArgumentError, 'expected foobar' unless args[0] == 'foobar'
|
641
|
+
'expected value'
|
642
|
+
}
|
643
|
+
end
|
644
|
+
|
645
|
+
```
|
646
|
+
|
647
|
+
|
557
648
|
## Hiera integration
|
558
649
|
|
559
650
|
### Configuration
|
data/lib/rspec-puppet/example.rb
CHANGED
@@ -5,6 +5,7 @@ require 'rspec-puppet/example/function_example_group'
|
|
5
5
|
require 'rspec-puppet/example/host_example_group'
|
6
6
|
require 'rspec-puppet/example/type_example_group'
|
7
7
|
require 'rspec-puppet/example/provider_example_group'
|
8
|
+
require 'rspec-puppet/example/application_example_group'
|
8
9
|
|
9
10
|
RSpec::configure do |c|
|
10
11
|
|
@@ -31,6 +32,9 @@ RSpec::configure do |c|
|
|
31
32
|
c.include RSpec::Puppet::ProviderExampleGroup, :type => :provider, :example_group => {
|
32
33
|
:file_path => c.escaped_path(%w[spec providers])
|
33
34
|
}
|
35
|
+
c.include RSpec::Puppet::ApplicationExampleGroup, :type => :application, :example_group => {
|
36
|
+
:file_path => c.escaped_path(%w[spec applications])
|
37
|
+
}
|
34
38
|
else
|
35
39
|
c.include RSpec::Puppet::DefineExampleGroup, :type => :define, :file_path => c.escaped_path(%w[spec defines])
|
36
40
|
c.include RSpec::Puppet::ClassExampleGroup, :type => :class, :file_path => c.escaped_path(%w[spec classes])
|
@@ -38,6 +42,7 @@ RSpec::configure do |c|
|
|
38
42
|
c.include RSpec::Puppet::HostExampleGroup, :type => :host, :file_path => c.escaped_path(%w[spec hosts])
|
39
43
|
c.include RSpec::Puppet::TypeExampleGroup, :type => :type, :file_path => c.escaped_path(%w[spec types])
|
40
44
|
c.include RSpec::Puppet::ProviderExampleGroup, :type => :provider, :file_path => c.escaped_path(%w[spec providers])
|
45
|
+
c.include RSpec::Puppet::ApplicationExampleGroup, :type => :application, :file_path => c.escaped_path(%w[spec applications])
|
41
46
|
end
|
42
47
|
|
43
48
|
# Hook for each example group type to remove any caches or instance variables, since they will remain
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RSpec::Puppet
|
2
|
+
# This module provides support for the application type
|
3
|
+
module ApplicationExampleGroup
|
4
|
+
include RSpec::Puppet::ManifestMatchers
|
5
|
+
include RSpec::Puppet::Support
|
6
|
+
|
7
|
+
def catalogue
|
8
|
+
@catalogue ||= load_catalogue(:application)
|
9
|
+
end
|
10
|
+
|
11
|
+
def exported_resources
|
12
|
+
lambda { load_catalogue(:application, true) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def rspec_puppet_cleanup
|
16
|
+
@catalogue = nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -4,27 +4,87 @@ module RSpec::Puppet
|
|
4
4
|
include RSpec::Puppet::ManifestMatchers
|
5
5
|
include RSpec::Puppet::Support
|
6
6
|
|
7
|
+
class V4FunctionWrapper
|
8
|
+
attr_reader :func, :func_name
|
9
|
+
|
10
|
+
def initialize(name, func, overrides)
|
11
|
+
@func_name = name
|
12
|
+
@func = func
|
13
|
+
@overrides = overrides
|
14
|
+
end
|
15
|
+
|
16
|
+
# This method is used by the `run` matcher to trigger the function execution, and provides a uniform interface across all puppet versions.
|
17
|
+
def execute(*args)
|
18
|
+
Puppet.override(@overrides, "rspec-test scope") do
|
19
|
+
@func.call(@overrides[:global_scope], *args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# compatibility alias for existing tests
|
24
|
+
def call(scope, *args)
|
25
|
+
RSpec.deprecate("subject.call", :replacement => "is_expected.to run.with().and_raise_error(), or execute()")
|
26
|
+
execute(*args)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class V3FunctionWrapper
|
31
|
+
attr_accessor :func_name
|
32
|
+
|
33
|
+
def initialize(name, func)
|
34
|
+
@func_name = name
|
35
|
+
@func = func
|
36
|
+
end
|
37
|
+
|
38
|
+
# This method is used by the `run` matcher to trigger the function execution, and provides a uniform interface across all puppet versions.
|
39
|
+
def execute(*args)
|
40
|
+
if args.nil?
|
41
|
+
@func.call
|
42
|
+
else
|
43
|
+
@func.call(args)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# This method was formerly used by the `run` matcher to trigger the function execution, and provides puppet versions dependant interface.
|
48
|
+
def call(*args)
|
49
|
+
RSpec.deprecate("subject.call", :replacement => "is_expected.to run.with().and_raise_error(), or execute()")
|
50
|
+
if args.nil?
|
51
|
+
@func.call
|
52
|
+
else
|
53
|
+
@func.call(*args)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# (at least) rspec 3.5 doesn't seem to memoize `subject` when called from
|
59
|
+
# a before(:each) hook, so we need to memoize it ourselves.
|
7
60
|
def subject
|
8
|
-
|
61
|
+
@subject ||= find_function
|
62
|
+
end
|
9
63
|
|
10
|
-
|
64
|
+
def find_function
|
65
|
+
function_name = self.class.top_level_description.downcase
|
11
66
|
|
12
|
-
|
67
|
+
with_vardir do
|
13
68
|
env = adapter.current_environment
|
14
|
-
loader = Puppet::Pops::Loaders.new(env)
|
15
|
-
func = loader.private_environment_loader.load(:function,function_name)
|
16
|
-
return func if func
|
17
|
-
end
|
18
69
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
70
|
+
if Puppet.version.to_f >= 4.0
|
71
|
+
context_overrides = compiler.context_overrides
|
72
|
+
func = nil
|
73
|
+
Puppet.override(context_overrides, "rspec-test scope") do
|
74
|
+
loader = Puppet::Pops::Loaders.new(env)
|
75
|
+
func = V4FunctionWrapper.new(function_name, loader.private_environment_loader.load(:function, function_name), context_overrides)
|
76
|
+
@scope = context_overrides[:global_scope]
|
77
|
+
end
|
78
|
+
|
79
|
+
return func if func.func
|
80
|
+
end
|
81
|
+
|
82
|
+
if Puppet::Parser::Functions.function(function_name)
|
83
|
+
V3FunctionWrapper.new(function_name, scope.method("function_#{function_name}".intern))
|
84
|
+
else
|
85
|
+
nil
|
86
|
+
end
|
25
87
|
end
|
26
|
-
FileUtils.rm_rf(vardir) if File.directory?(vardir)
|
27
|
-
scope.method("function_#{function_name}".intern)
|
28
88
|
end
|
29
89
|
|
30
90
|
def scope
|
@@ -36,6 +96,7 @@ module RSpec::Puppet
|
|
36
96
|
end
|
37
97
|
|
38
98
|
def rspec_puppet_cleanup
|
99
|
+
@subject = nil
|
39
100
|
@catalogue = nil
|
40
101
|
@compiler = nil
|
41
102
|
@scope = nil
|
@@ -71,7 +132,9 @@ module RSpec::Puppet
|
|
71
132
|
end
|
72
133
|
|
73
134
|
def build_scope(compiler, node_name)
|
74
|
-
if Puppet.version
|
135
|
+
if Puppet.version.to_f >= 4.0
|
136
|
+
return compiler.context_overrides[:global_scope]
|
137
|
+
elsif Puppet.version =~ /^2\.[67]/
|
75
138
|
# loadall should only be necessary prior to 3.x
|
76
139
|
# Please note, loadall needs to happen first when creating a scope, otherwise
|
77
140
|
# you might receive undefined method `function_*' errors
|
@@ -3,23 +3,11 @@ module RSpec::Puppet
|
|
3
3
|
class Run
|
4
4
|
def matches?(func_obj)
|
5
5
|
@func_obj = func_obj
|
6
|
-
if @params
|
7
|
-
if Puppet.version.to_f >= 4.0 and ! @func_obj.respond_to?(:receiver)
|
8
|
-
@func = lambda { func_obj.call({}, *@params) }
|
9
|
-
else
|
10
|
-
@func = lambda { func_obj.call(@params) }
|
11
|
-
end
|
12
|
-
else
|
13
|
-
if Puppet.version.to_f >= 4.0 and ! @func_obj.respond_to?(:receiver)
|
14
|
-
@func = lambda { func_obj.call({}) }
|
15
|
-
else
|
16
|
-
@func = lambda { func_obj.call }
|
17
|
-
end
|
18
|
-
end
|
19
6
|
|
20
7
|
@has_returned = false
|
21
8
|
begin
|
22
|
-
|
9
|
+
# `*nil` does not evaluate to "no params" on ruby 1.8 :-(
|
10
|
+
@actual_return = @params.nil? ? @func_obj.execute : @func_obj.execute(*@params)
|
23
11
|
@has_returned = true
|
24
12
|
rescue Exception => e
|
25
13
|
@actual_error = e
|
@@ -113,11 +101,7 @@ module RSpec::Puppet
|
|
113
101
|
|
114
102
|
private
|
115
103
|
def func_name
|
116
|
-
|
117
|
-
@func_name ||= @func_obj.class.name
|
118
|
-
else
|
119
|
-
@func_name ||= @func_obj.name.to_s.gsub(/^function_/, '')
|
120
|
-
end
|
104
|
+
@func_obj.func_name
|
121
105
|
end
|
122
106
|
|
123
107
|
def func_params
|
@@ -129,9 +113,9 @@ module RSpec::Puppet
|
|
129
113
|
''
|
130
114
|
elsif @actual_error
|
131
115
|
if @has_expected_return
|
132
|
-
" instead of raising #{@actual_error.class.inspect}(#{@actual_error})"
|
116
|
+
" instead of raising #{@actual_error.class.inspect}(#{@actual_error})\n#{@actual_error.backtrace.join("\n")}"
|
133
117
|
else
|
134
|
-
" instead of #{@actual_error.class.inspect}(#{@actual_error})"
|
118
|
+
" instead of #{@actual_error.class.inspect}(#{@actual_error})\n#{@actual_error.backtrace.join("\n")}"
|
135
119
|
end
|
136
120
|
else # function has returned
|
137
121
|
if @has_expected_error
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module RSpec::Puppet
|
2
|
+
# A raw string object, that is used by helpers to allow consumers to return non-quoted strings
|
3
|
+
# as part of their params section.
|
4
|
+
class RawString
|
5
|
+
# Create a new RawString object
|
6
|
+
# @param [String] value string to wrap
|
7
|
+
def initialize(value)
|
8
|
+
@value = value
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [String] raw string
|
12
|
+
def inspect
|
13
|
+
@value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/rspec-puppet/setup.rb
CHANGED
@@ -34,7 +34,7 @@ module RSpec::Puppet
|
|
34
34
|
|
35
35
|
safe_touch('spec/fixtures/manifests/site.pp')
|
36
36
|
|
37
|
-
%w(data manifests lib files templates).each do |dir|
|
37
|
+
%w(data manifests lib files templates functions types).each do |dir|
|
38
38
|
if File.exist? dir
|
39
39
|
safe_make_symlink("../../../../#{dir}", "spec/fixtures/modules/#{module_name}/#{dir}")
|
40
40
|
end
|
data/lib/rspec-puppet/support.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rspec-puppet/cache'
|
2
2
|
require 'rspec-puppet/adapters'
|
3
|
+
require 'rspec-puppet/raw_string'
|
3
4
|
|
4
5
|
module RSpec::Puppet
|
5
6
|
module Support
|
@@ -15,26 +16,25 @@ module RSpec::Puppet
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def load_catalogue(type, exported = false)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
19
|
+
with_vardir do
|
20
|
+
if Puppet.version.to_f >= 4.0 or Puppet[:parser] == 'future'
|
21
|
+
code = [pre_cond, test_manifest(type)].compact.join("\n")
|
22
|
+
else
|
23
|
+
code = [import_str, pre_cond, test_manifest(type)].compact.join("\n")
|
24
|
+
end
|
25
25
|
|
26
|
-
|
26
|
+
node_name = nodename(type)
|
27
27
|
|
28
|
-
|
28
|
+
hiera_config_value = self.respond_to?(:hiera_config) ? hiera_config : nil
|
29
29
|
|
30
|
-
|
30
|
+
catalogue = build_catalog(node_name, facts_hash(node_name), hiera_config_value, code, exported)
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
test_module = class_name.split('::').first
|
33
|
+
RSpec::Puppet::Coverage.add_filter(type.to_s, self.class.description)
|
34
|
+
RSpec::Puppet::Coverage.add_from_catalog(catalogue, test_module)
|
35
35
|
|
36
|
-
|
37
|
-
|
36
|
+
catalogue
|
37
|
+
end
|
38
38
|
end
|
39
39
|
|
40
40
|
def import_str
|
@@ -68,6 +68,12 @@ module RSpec::Puppet
|
|
68
68
|
else
|
69
69
|
"class { '#{class_name}': #{param_str} }"
|
70
70
|
end
|
71
|
+
elsif type == :application
|
72
|
+
if self.respond_to? :params
|
73
|
+
"site { #{class_name} { '#{title}': #{param_str} } }"
|
74
|
+
else
|
75
|
+
raise ArgumentException, "You need to provide params for an application"
|
76
|
+
end
|
71
77
|
elsif type == :define
|
72
78
|
if self.respond_to? :params
|
73
79
|
"#{class_name} { '#{title}': #{param_str} }"
|
@@ -81,7 +87,7 @@ module RSpec::Puppet
|
|
81
87
|
|
82
88
|
def nodename(type)
|
83
89
|
return node if self.respond_to?(:node)
|
84
|
-
if [:class, :define, :function].include? type
|
90
|
+
if [:class, :define, :function, :application].include? type
|
85
91
|
Puppet[:certname]
|
86
92
|
else
|
87
93
|
class_name
|
@@ -123,14 +129,28 @@ module RSpec::Puppet
|
|
123
129
|
end
|
124
130
|
|
125
131
|
def param_str
|
126
|
-
params
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
132
|
+
param_str_from_hash(params)
|
133
|
+
end
|
134
|
+
|
135
|
+
def str_from_value(value)
|
136
|
+
case value
|
137
|
+
when Hash
|
138
|
+
kvs = value.collect do |k,v|
|
139
|
+
"#{str_from_value(k)} => #{str_from_value(v)}"
|
140
|
+
end.join(", ")
|
141
|
+
"{ #{kvs} }"
|
142
|
+
when :undef
|
143
|
+
'undef' # verbatim undef keyword
|
144
|
+
else
|
145
|
+
escape_special_chars(value.inspect)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def param_str_from_hash(params_hash)
|
150
|
+
# the param_str has special quoting rules, because the top-level keys are the Puppet
|
151
|
+
# params, which may not be quoted
|
152
|
+
params_hash.collect do |k,v|
|
153
|
+
"#{k.to_s} => #{str_from_value(v)}"
|
134
154
|
end.join(', ')
|
135
155
|
end
|
136
156
|
|
@@ -138,6 +158,11 @@ module RSpec::Puppet
|
|
138
158
|
vardir = Dir.mktmpdir
|
139
159
|
Puppet[:vardir] = vardir
|
140
160
|
|
161
|
+
# Enable app_management by default for Puppet versions that support it
|
162
|
+
if Puppet.version.to_f >= 4.3
|
163
|
+
Puppet[:app_management] = true
|
164
|
+
end
|
165
|
+
|
141
166
|
adapter.modulepath.map do |d|
|
142
167
|
Dir["#{d}/*/lib"].entries
|
143
168
|
end.flatten.each do |lib|
|
@@ -147,6 +172,15 @@ module RSpec::Puppet
|
|
147
172
|
vardir
|
148
173
|
end
|
149
174
|
|
175
|
+
def with_vardir
|
176
|
+
begin
|
177
|
+
vardir = setup_puppet
|
178
|
+
return yield(vardir) if block_given?
|
179
|
+
ensure
|
180
|
+
FileUtils.rm_rf(vardir) if File.directory?(vardir)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
150
184
|
def build_catalog_without_cache(nodename, facts_val, hiera_config_val, code, exported)
|
151
185
|
|
152
186
|
# If we're going to rebuild the catalog, we should clear the cached instance
|
@@ -206,6 +240,16 @@ module RSpec::Puppet
|
|
206
240
|
end
|
207
241
|
end
|
208
242
|
|
243
|
+
# Helper to return a resource/node reference, so it gets translated in params to a raw string
|
244
|
+
# without quotes.
|
245
|
+
#
|
246
|
+
# @param [String] type reference type
|
247
|
+
# @param [String] title reference title
|
248
|
+
# @return [RSpec::Puppet::RawString] return a new RawString with the type/title populated correctly
|
249
|
+
def ref(type, title)
|
250
|
+
return RSpec::Puppet::RawString.new("#{type}['#{title}']")
|
251
|
+
end
|
252
|
+
|
209
253
|
# @!attribute [r] adapter
|
210
254
|
# @api private
|
211
255
|
# @return [Class < RSpec::Puppet::Adapters::Base]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-puppet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Sharpe
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -40,6 +40,7 @@ files:
|
|
40
40
|
- lib/rspec-puppet/coverage.rb
|
41
41
|
- lib/rspec-puppet/errors.rb
|
42
42
|
- lib/rspec-puppet/example.rb
|
43
|
+
- lib/rspec-puppet/example/application_example_group.rb
|
43
44
|
- lib/rspec-puppet/example/class_example_group.rb
|
44
45
|
- lib/rspec-puppet/example/define_example_group.rb
|
45
46
|
- lib/rspec-puppet/example/function_example_group.rb
|
@@ -56,6 +57,7 @@ files:
|
|
56
57
|
- lib/rspec-puppet/matchers/run.rb
|
57
58
|
- lib/rspec-puppet/matchers/type_matchers.rb
|
58
59
|
- lib/rspec-puppet/rake_task.rb
|
60
|
+
- lib/rspec-puppet/raw_string.rb
|
59
61
|
- lib/rspec-puppet/setup.rb
|
60
62
|
- lib/rspec-puppet/spec_helper.rb
|
61
63
|
- lib/rspec-puppet/support.rb
|