rspec-puppet-augeas 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +1 -0
- data/README.md +11 -2
- data/lib/rspec-puppet-augeas/example/run_augeas_example_group.rb +21 -10
- data/lib/rspec-puppet-augeas/fixtures.rb +1 -16
- data/rspec-puppet-augeas.gemspec +2 -1
- data/spec/classes/sshd_config_spec.rb +51 -17
- data/spec/fixtures/modules/sshd/manifests/init.pp +6 -0
- data/spec/spec_helper.rb +5 -0
- metadata +18 -2
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -23,7 +23,7 @@ Extend your usual rspec-puppet class test, e.g. for the 'sshd' class:
|
|
23
23
|
end
|
24
24
|
|
25
25
|
# Expects Augeas['root login']
|
26
|
-
describe_augeas 'root login' do
|
26
|
+
describe_augeas 'root login', :lens => 'Sshd', :target => 'etc/ssh/sshd_config' do
|
27
27
|
it 'should change PermitRootLogin' do
|
28
28
|
# Run the resource against the fixtures, check it changed
|
29
29
|
should execute.with_change
|
@@ -57,6 +57,9 @@ fixtures directory.
|
|
57
57
|
|
58
58
|
## Usage
|
59
59
|
|
60
|
+
Read the spec file(s) at `spec/classes/*.rb` to see various real-life examples
|
61
|
+
of the features below.
|
62
|
+
|
60
63
|
### describe\_augeas example group
|
61
64
|
|
62
65
|
`describe_augeas` adds an example group, like describe/context, but that describes
|
@@ -69,13 +72,14 @@ It takes optional hash arguments:
|
|
69
72
|
* a hash of fixtures to copy from the source (under augeas\_fixtures) to a
|
70
73
|
destination path, e.g. `{ 'dest/file/location' => 'src/file/location' }`
|
71
74
|
* a string of the source path, copied to the path given by the resource's
|
72
|
-
`incl` parameter
|
75
|
+
`incl` parameter or `:target`
|
73
76
|
* nil, by default copies all fixtures
|
74
77
|
* `:target` is the path of the file that the resource should modify
|
75
78
|
* `:lens` is the lens to use when opening the target file (for `aug_*` etc.)
|
76
79
|
|
77
80
|
It sets the following variables inside examples:
|
78
81
|
|
82
|
+
* `resource` to the Puppet resource object
|
79
83
|
* `subject` (used implicitly) to an object representing the resource
|
80
84
|
* `output_root` to the path of the fixtures directory after one run
|
81
85
|
|
@@ -128,6 +132,11 @@ New RSpec configuration options:
|
|
128
132
|
* `augeas_fixtures` is the path to the root of the fixtures directory
|
129
133
|
containing source files
|
130
134
|
|
135
|
+
## Background reading
|
136
|
+
|
137
|
+
This module inherited code from the tests used in [augeasproviders](http://augeasproviders.com).
|
138
|
+
The test methodology is described in [Testing techniques for Puppet providers using Augeas](http://augeasproviders.com/documentation/specs.html).
|
139
|
+
|
131
140
|
## Issues
|
132
141
|
|
133
142
|
Please file any issues or suggestions [on GitHub](https://github.com/domcleal/rspec-puppet-augeas/issues).
|
@@ -22,17 +22,24 @@ module RSpec::Puppet::Augeas
|
|
22
22
|
# to the augeas resource object
|
23
23
|
|
24
24
|
# initialise arguments passed into the run_augeas block
|
25
|
-
# TODO: target can be initialised from incl if available
|
26
25
|
target = options.delete(:target)
|
27
|
-
let(:target)
|
26
|
+
let(:target) do
|
27
|
+
target || resource[:incl]
|
28
|
+
end
|
28
29
|
|
29
|
-
# TODO: ditto
|
30
30
|
lens = options.delete(:lens)
|
31
|
-
let(:lens)
|
31
|
+
let(:lens) do
|
32
|
+
lens || resource[:lens]
|
33
|
+
end
|
32
34
|
|
33
35
|
fixture = options.delete(:fixture)
|
34
|
-
fixture
|
35
|
-
|
36
|
+
let(:fixture) do
|
37
|
+
if fixture and !fixture.is_a? Hash
|
38
|
+
raise ArgumentError, ":target must be supplied" unless self.target
|
39
|
+
fixture = { self.target => fixture.to_s }
|
40
|
+
end
|
41
|
+
fixture
|
42
|
+
end
|
36
43
|
|
37
44
|
class_exec(&block)
|
38
45
|
end
|
@@ -45,19 +52,23 @@ module RSpec::Puppet::Augeas
|
|
45
52
|
end
|
46
53
|
|
47
54
|
module InstanceMethods
|
48
|
-
# Initialises the implicit example group 'subject' to an Augeas resource
|
49
|
-
#
|
50
55
|
# Requires that the title of this example group is the resource title and
|
51
56
|
# that the parent example group subject is a catalog (use rspec-puppet)
|
52
|
-
def
|
57
|
+
def resource
|
53
58
|
unless @resource
|
54
59
|
title = self.class.description
|
55
60
|
title = $1 if title =~ /^Augeas\[(.*)\]$/
|
56
|
-
@resource =
|
61
|
+
@resource = catalogue.resource('Augeas', title)
|
57
62
|
end
|
58
63
|
@resource
|
59
64
|
end
|
60
65
|
|
66
|
+
# Initialises the implicit example group 'subject' to a wrapped Augeas
|
67
|
+
# resource
|
68
|
+
def subject
|
69
|
+
@subject ||= Resource.new(self.resource, fixture)
|
70
|
+
end
|
71
|
+
|
61
72
|
def output_root
|
62
73
|
subject.root
|
63
74
|
end
|
@@ -6,8 +6,6 @@ module RSpec::Puppet::Augeas
|
|
6
6
|
module Fixtures
|
7
7
|
# Copies test fixtures to a temporary directory
|
8
8
|
# If file is nil, copies the entire augeas_fixtures directory
|
9
|
-
# If file is a string, it copies that file from augeas_fixtures
|
10
|
-
# to the path being edited by the resource
|
11
9
|
# If file is a hash, it copies the "value" from augeas_fixtures
|
12
10
|
# to each "key" path
|
13
11
|
def load_fixtures(resource, file)
|
@@ -26,28 +24,15 @@ module RSpec::Puppet::Augeas
|
|
26
24
|
def prepare_fixtures(dir, resource, file)
|
27
25
|
if file.nil?
|
28
26
|
FileUtils.cp_r File.join(RSpec.configuration.augeas_fixtures, "."), dir
|
29
|
-
|
27
|
+
else
|
30
28
|
file.each do |dest,src|
|
31
29
|
FileUtils.mkdir_p File.join(dir, File.dirname(dest))
|
32
30
|
src = File.join(RSpec.configuration.augeas_fixtures, src) unless src.start_with? File::SEPARATOR
|
33
31
|
FileUtils.cp_r src, File.join(dir, dest)
|
34
32
|
end
|
35
|
-
elsif file.respond_to? :to_s
|
36
|
-
target = get_resource_target(resource)
|
37
|
-
raise ArgumentError, "Unable to determine file being edited from #{resource.name}. Supply :fixtures as a hash of { '/dest/path' => 'source/fixture/path' } instead." unless target
|
38
|
-
FileUtils.mkdir_p File.join(dir, File.dirname(target))
|
39
|
-
FileUtils.cp File.join(RSpec.configuration.augeas_fixtures, file.to_s), File.join(dir, target)
|
40
33
|
end
|
41
34
|
end
|
42
35
|
|
43
|
-
# Take a best guess at the file the user's editing
|
44
|
-
def get_resource_target(resource)
|
45
|
-
return resource[:incl] if resource[:incl]
|
46
|
-
# TODO: make reliable
|
47
|
-
#return $1 if resource[:context] and resource[:context] =~ %r{/files(/.*)}
|
48
|
-
nil
|
49
|
-
end
|
50
|
-
|
51
36
|
# Runs a particular resource via a catalog
|
52
37
|
def apply(resource)
|
53
38
|
catalog = Puppet::Resource::Catalog.new
|
data/rspec-puppet-augeas.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'rspec-puppet-augeas'
|
3
|
-
s.version = '0.2.
|
3
|
+
s.version = '0.2.1'
|
4
4
|
s.homepage = 'https://github.com/domcleal/rspec-puppet-augeas/'
|
5
5
|
s.summary = 'RSpec tests for Augeas resources in Puppet manifests'
|
6
6
|
s.description = 'RSpec tests for Augeas resources in Puppet manifests'
|
@@ -29,6 +29,7 @@ Gem::Specification.new do |s|
|
|
29
29
|
]
|
30
30
|
|
31
31
|
s.add_dependency 'rspec-puppet'
|
32
|
+
s.add_dependency 'puppetlabs_spec_helper'
|
32
33
|
|
33
34
|
s.authors = ['Dominic Cleal']
|
34
35
|
s.email = 'dcleal@redhat.com'
|
@@ -1,25 +1,50 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
# Tests all features of rspec-puppet-augeas against the class under
|
4
|
+
# spec/fixtures/module/sshd/manifests/init.pp
|
3
5
|
describe 'sshd' do
|
6
|
+
# Basic rspec-puppet example
|
4
7
|
it 'should have an augeas resource' do
|
5
8
|
should contain_augeas('root login')
|
6
9
|
end
|
7
10
|
|
11
|
+
# Basic rspec-puppet-example
|
12
|
+
# uses all fixtures, lens + target are specified for aug_* functions to work
|
8
13
|
describe 'specify target+lens upfront, use all fixtures' do
|
9
14
|
describe_augeas 'root login', :lens => 'Sshd', :target => 'etc/ssh/sshd_config' do
|
10
15
|
it 'should test resource' do
|
16
|
+
# Verify this is the right fixture, using Augeas and simple parsing
|
11
17
|
aug_get('#comment[1]').should =~ /OpenBSD/
|
12
18
|
open_target { |f| f.readline.should =~ /OpenBSD/ }
|
13
19
|
|
20
|
+
# Check it changes
|
14
21
|
should execute.with_change
|
15
22
|
aug_get('PermitRootLogin').should == 'yes'
|
16
23
|
open_target { |f| f.read.should =~ /^PermitRootLogin\s+yes$/ }
|
17
24
|
|
25
|
+
# Idempotency test last, as a broken resource may cause false positives
|
18
26
|
should execute.idempotently
|
19
27
|
end
|
20
28
|
end
|
21
29
|
end
|
22
30
|
|
31
|
+
# Example of using a second fixture file to test a resource
|
32
|
+
describe 'specify target and non-standard fixture' do
|
33
|
+
describe_augeas 'root login', :lens => 'Sshd', :target => 'etc/ssh/sshd_config', :fixture => 'etc/ssh/sshd_config_2' do
|
34
|
+
it 'should test resource with second fixture' do
|
35
|
+
aug_get('#comment[1]').should == 'Fixture 2'
|
36
|
+
should execute.with_change
|
37
|
+
aug_get('PermitRootLogin').should == 'yes'
|
38
|
+
should execute.idempotently
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Fixtures can be a hash of destination path to source fixture path
|
44
|
+
# Note that all paths are relative to augeas_fixtures (in spec_helper.rb)
|
45
|
+
# and have no leading /
|
46
|
+
#
|
47
|
+
# Unusually, lens + target are specified on each aug_* function instead here.
|
23
48
|
describe 'specify fixtures as a hash' do
|
24
49
|
describe_augeas 'root login', :fixture => { 'etc/ssh/sshd_config' => 'etc/ssh/sshd_config_2' } do
|
25
50
|
it 'should test resource with second fixture' do
|
@@ -31,9 +56,10 @@ describe 'sshd' do
|
|
31
56
|
end
|
32
57
|
end
|
33
58
|
|
34
|
-
|
35
|
-
|
36
|
-
|
59
|
+
# When incl/lens are given on the resource, :target and :lens are resolved
|
60
|
+
describe 'target detection from resource' do
|
61
|
+
describe_augeas 'incl root login', :fixture => 'etc/ssh/sshd_config_2' do
|
62
|
+
it 'should test resource with second fixture at incl location' do
|
37
63
|
aug_get('#comment[1]').should == 'Fixture 2'
|
38
64
|
should execute.with_change
|
39
65
|
aug_get('PermitRootLogin').should == 'yes'
|
@@ -42,20 +68,10 @@ describe 'sshd' do
|
|
42
68
|
end
|
43
69
|
end
|
44
70
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
run_augeas 'add root login', :lens => 'Sshd', :target => 'etc/ssh/sshd_config' do
|
52
|
-
it 'should fail on idempotency' do
|
53
|
-
should execute.with_change
|
54
|
-
aug_match('PermitRootLogin').size.should == 2
|
55
|
-
should_not execute.idempotently
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
71
|
+
# Other test utilities:
|
72
|
+
# augparse compares the entire fixture file to the { "key" = "value" } tree.
|
73
|
+
# Call augparse with no argument initially and it will print out the tree
|
74
|
+
# representation of the fixture file for reference.
|
59
75
|
describe 'augparse' do
|
60
76
|
describe_augeas 'root login', :lens => 'Sshd', :target => 'etc/ssh/sshd_config', :fixture => 'etc/ssh/sshd_config_2' do
|
61
77
|
it 'should run augparse against the whole file' do
|
@@ -68,6 +84,8 @@ describe 'sshd' do
|
|
68
84
|
end
|
69
85
|
end
|
70
86
|
|
87
|
+
# augparse_filter first runs a filter against the fixture file before running
|
88
|
+
# it through augparse. Here, it filters out all non-comment entries.
|
71
89
|
describe 'augparse_filter' do
|
72
90
|
describe_augeas 'root login', :lens => 'Sshd', :target => 'etc/ssh/sshd_config', :fixture => 'etc/ssh/sshd_config_2' do
|
73
91
|
it 'should filter non-comments' do
|
@@ -78,4 +96,20 @@ describe 'sshd' do
|
|
78
96
|
end
|
79
97
|
end
|
80
98
|
end
|
99
|
+
|
100
|
+
# Testing for deliberate failure
|
101
|
+
describe_augeas 'fail to add root login' do
|
102
|
+
it 'should fail to run entirely' do
|
103
|
+
should_not execute
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Testing for deliberate idempotency failure
|
108
|
+
run_augeas 'add root login', :lens => 'Sshd', :target => 'etc/ssh/sshd_config' do
|
109
|
+
it 'should fail on idempotency' do
|
110
|
+
should execute.with_change
|
111
|
+
aug_match('PermitRootLogin').size.should == 2
|
112
|
+
should_not execute.idempotently
|
113
|
+
end
|
114
|
+
end
|
81
115
|
end
|
@@ -4,6 +4,12 @@ class sshd {
|
|
4
4
|
changes => 'set PermitRootLogin yes',
|
5
5
|
}
|
6
6
|
|
7
|
+
augeas { "incl root login":
|
8
|
+
incl => '/etc/ssh/sshd_config',
|
9
|
+
lens => 'Sshd.lns',
|
10
|
+
changes => 'set PermitRootLogin yes',
|
11
|
+
}
|
12
|
+
|
7
13
|
augeas { "add root login":
|
8
14
|
context => '/files/etc/ssh/sshd_config',
|
9
15
|
changes => [
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-puppet-augeas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec-puppet
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: puppetlabs_spec_helper
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
30
46
|
description: RSpec tests for Augeas resources in Puppet manifests
|
31
47
|
email: dcleal@redhat.com
|
32
48
|
executables: []
|