rspec-puppet-augeas 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -33,12 +33,20 @@ module RSpec::Puppet::Augeas
33
33
  end
34
34
  end
35
35
 
36
- # Runs a particular resource via a catalog
37
- def apply(resource)
36
+ # Runs a particular resource via a catalog and stores logs in the caller's
37
+ # supplied array
38
+ def apply(resource, logs)
39
+ logs.clear
40
+ Puppet::Util::Log.newdestination(Puppet::Test::LogCollector.new(logs))
41
+ Puppet::Util::Log.level = 'debug'
42
+
38
43
  catalog = Puppet::Resource::Catalog.new
39
44
  catalog.add_resource resource
40
45
  catalog = catalog.to_ral if resource.is_a? Puppet::Resource
41
- catalog.apply
46
+ txn = catalog.apply
47
+
48
+ Puppet::Util::Log.close_all
49
+ txn
42
50
  end
43
51
  end
44
52
  end
@@ -43,24 +43,37 @@ module RSpec::Puppet::Augeas::Matchers
43
43
  end
44
44
 
45
45
  def failure_message_for_should
46
- # FIXME: the branch should depend on outcome, not chaining
47
- if idempotent
48
- "#{resource} isn't idempotent, it changes on every run"
49
- elsif change
50
- "#{resource} doesn't change when executed"
51
- else
52
- "#{resource} fails when executed"
46
+ if resource.txn.any_failed?
47
+ "#{resource} fails when executing:\n#{format_logs(resource.logs)}"
48
+ elsif change and !resource.txn.changed?.any?
49
+ "#{resource} doesn't change when executed:\n#{format_logs(resource.logs)}"
50
+ elsif idempotent and resource.idempotent.changed?.any?
51
+ "#{resource} isn't idempotent, it changes on every run:\n#{format_logs(resource.logs_idempotent)}"
53
52
  end
54
53
  end
55
54
 
56
55
  def failure_message_for_should_not
57
- if idempotent
58
- "#{resource} is idempotent, it doesn't change on every run"
59
- elsif change
60
- "#{resource} changes when executed"
61
- else
62
- "#{resource} succeeds when executed"
56
+ if resource.txn.any_failed?
57
+ "#{resource} succeeds when executed:\n#{format_logs(resource.logs)}"
58
+ elsif change and !resource.txn.changed?.any?
59
+ "#{resource} changes when executed:\n#{format_logs(resource.logs)}"
60
+ elsif idempotent and resource.idempotent.changed?.any?
61
+ "#{resource} is idempotent, it doesn't change on every run:\n#{format_logs(resource.logs_idempotent)}"
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def format_logs(logs)
68
+ # Sometimes two transactions are run, sometimes one, so filter out the
69
+ # first (it appears the idempotent test only sees one txn)
70
+ if logs.map { |log| log.message }.grep(/Finishing transaction/).size > 1
71
+ logs = logs.clone.drop_while { |log| log.message !~ /Finishing transaction/ }
72
+ logs.shift
63
73
  end
74
+ # Ignore everything after the txn end
75
+ logs = logs.take_while { |log| log.message !~ /Finishing transaction/ }
76
+ logs.map { |log| "#{log.level}: #{log.message}" }.join("\n")
64
77
  end
65
78
  end
66
79
 
@@ -2,10 +2,11 @@ require 'rspec-puppet-augeas/fixtures'
2
2
 
3
3
  module RSpec::Puppet::Augeas
4
4
  class Resource
5
- attr_reader :resource, :txn, :txn_idempotent, :root
5
+ attr_reader :resource, :txn, :txn_idempotent, :root, :logs, :logs_idempotent
6
6
 
7
7
  def initialize(resource, fixtures)
8
8
  @resource = resource
9
+ @logs = []
9
10
 
10
11
  # The directory where the resource has run will be valuable, so keep it
11
12
  # for analysis and tests by the user
@@ -13,7 +14,7 @@ module RSpec::Puppet::Augeas
13
14
  ObjectSpace.define_finalizer(self, self.class.finalize(@root))
14
15
 
15
16
  resource[:root] = @root
16
- @txn = apply(resource)
17
+ @txn = apply(resource, @logs)
17
18
  end
18
19
 
19
20
  def self.finalize(root)
@@ -24,11 +25,12 @@ module RSpec::Puppet::Augeas
24
25
  #
25
26
  # @return [Puppet::Transaction] repeated transaction
26
27
  def idempotent
28
+ @logs_idempotent = []
27
29
  root = load_fixtures(resource, {"." => "#{@root}/."})
28
30
 
29
31
  oldroot = resource[:root]
30
32
  resource[:root] = root
31
- @txn_idempotent = apply(resource)
33
+ @txn_idempotent = apply(resource, @logs_idempotent)
32
34
  FileUtils.rm_r root
33
35
  resource[:root] = oldroot
34
36
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rspec-puppet-augeas'
3
- s.version = '0.2.1'
3
+ s.version = '0.2.2'
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'
@@ -33,6 +33,11 @@ describe 'sshd' do
33
33
  describe_augeas 'root login', :lens => 'Sshd', :target => 'etc/ssh/sshd_config', :fixture => 'etc/ssh/sshd_config_2' do
34
34
  it 'should test resource with second fixture' do
35
35
  aug_get('#comment[1]').should == 'Fixture 2'
36
+
37
+ # Example of increasing logging, which captures augeas provider's
38
+ # debug logging on failure
39
+ Puppet::Util::Log.level = 'debug'
40
+
36
41
  should execute.with_change
37
42
  aug_get('PermitRootLogin').should == 'yes'
38
43
  should execute.idempotently
@@ -100,7 +105,33 @@ describe 'sshd' do
100
105
  # Testing for deliberate failure
101
106
  describe_augeas 'fail to add root login' do
102
107
  it 'should fail to run entirely' do
108
+ # Deliberate failure means this is inverted with "not"
103
109
  should_not execute
110
+
111
+ # Verify the matcher message contains logs
112
+ e = execute
113
+ e.matches? subject
114
+ e.description.should =~ /should execute/
115
+ e.failure_message_for_should.should =~ /^err:.*false/
116
+ e.failure_message_for_should_not.should =~ /^err:.*false/
117
+ # Check for debug logs
118
+ e.failure_message_for_should.should =~ /^debug:.*Opening augeas/
119
+ # Ignore transaction stuff
120
+ e.failure_message_for_should.split("\n").grep(/Finishing transaction/).empty?.should be_true
121
+ end
122
+ end
123
+
124
+ # Testing for deliberate no-op
125
+ run_augeas 'make no change' do
126
+ it 'should fail on with_change' do
127
+ should_not execute.with_change
128
+
129
+ # Verify the matcher message contains logs
130
+ e = execute
131
+ e.with_change.matches? subject
132
+ e.description.should =~ /should change successfully/
133
+ e.failure_message_for_should.should =~ /doesn't change/
134
+ e.failure_message_for_should_not.should =~ /changes/
104
135
  end
105
136
  end
106
137
 
@@ -110,6 +141,13 @@ describe 'sshd' do
110
141
  should execute.with_change
111
142
  aug_match('PermitRootLogin').size.should == 2
112
143
  should_not execute.idempotently
144
+
145
+ # Verify the matcher message contains logs
146
+ e = execute
147
+ e.idempotently.matches? subject
148
+ e.description.should =~ /should change once only/
149
+ e.failure_message_for_should.should =~ /^notice:.*success/
150
+ e.failure_message_for_should_not.should =~ /^notice:.*success/
113
151
  end
114
152
  end
115
153
  end
@@ -22,4 +22,9 @@ class sshd {
22
22
  context => '/files/etc/ssh/sshd_config',
23
23
  changes => 'ins PermitRootLogin after *[last()]',
24
24
  }
25
+
26
+ augeas { "make no change":
27
+ context => '/files/etc/ssh/sshd_config',
28
+ changes => 'set /foo bar',
29
+ }
25
30
  }
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.1
4
+ version: 0.2.2
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-30 00:00:00.000000000 Z
12
+ date: 2013-02-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec-puppet