rspec-puppet-augeas 0.2.0 → 0.2.1

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.
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ coverage/
1
2
  pkg/
2
3
  *.gem
3
4
  Gemfile.lock
data/Gemfile CHANGED
@@ -7,4 +7,5 @@ gem 'ruby-augeas'
7
7
  group :test do
8
8
  gem 'puppet'
9
9
  gem 'rake'
10
+ gem 'simplecov'
10
11
  end
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 (TODO: or `:target`)
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) { 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) { lens }
31
+ let(:lens) do
32
+ lens || resource[:lens]
33
+ end
32
34
 
33
35
  fixture = options.delete(:fixture)
34
- fixture = { target => fixture } if fixture.is_a? String and target
35
- let(:fixture) { fixture }
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 subject
57
+ def resource
53
58
  unless @resource
54
59
  title = self.class.description
55
60
  title = $1 if title =~ /^Augeas\[(.*)\]$/
56
- @resource = Resource.new(catalogue.resource('Augeas', title), fixture)
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
- elsif file.is_a? Hash
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
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rspec-puppet-augeas'
3
- s.version = '0.2.0'
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
- describe 'specify target and non-standard fixture' do
35
- describe_augeas 'root login', :lens => 'Sshd', :target => 'etc/ssh/sshd_config', :fixture => 'etc/ssh/sshd_config_2' do
36
- it 'should test resource with second fixture' do
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
- describe_augeas 'fail to add root login' do
46
- it 'should fail to run entirely' do
47
- should_not execute
48
- end
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
@@ -1,3 +1,8 @@
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ add_filter "/spec/"
4
+ end
5
+
1
6
  require 'rspec-puppet-augeas'
2
7
 
3
8
  RSpec.configure do |c|
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.0
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-29 00:00:00.000000000 Z
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: []