Skip to content

Commit b8d8817

Browse files
authored
Merge pull request #241 from seanmil/issue_214-reset_context_after_failure
Reset context.failed? between resources
2 parents 7fd8724 + 8384cba commit b8d8817

File tree

7 files changed

+103
-1
lines changed

7 files changed

+103
-1
lines changed

lib/puppet/resource_api.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,10 @@ def flush
331331
else
332332
my_provider.set(context, rsapi_title => { is: @rsapi_current_state, should: target_state }) unless noop?
333333
end
334-
raise 'Execution encountered an error' if context.failed?
334+
if context.failed?
335+
context.reset_failed
336+
raise 'Execution encountered an error'
337+
end
335338

336339
# remember that we have successfully reached our desired state
337340
@rsapi_current_state = target_state

lib/puppet/resource_api/base_context.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ def failed?
3333
@failed
3434
end
3535

36+
def reset_failed
37+
@failed = false
38+
end
39+
3640
def feature_support?(feature)
3741
Puppet.deprecation_warning('context.feature_support? is deprecated. Please use context.type.feature? instead.')
3842
type.feature?(feature)

spec/acceptance/failure_spec.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
require 'spec_helper'
2+
require 'tempfile'
3+
4+
RSpec.describe 'a provider showing failure' do
5+
let(:common_args) { '--verbose --trace --strict=error --modulepath spec/fixtures --detailed-exitcodes' }
6+
7+
describe 'using `puppet apply`' do
8+
let(:result) { Open3.capture2e("puppet apply #{common_args} -e \"#{manifest.delete("\n").squeeze(' ')}\"") }
9+
let(:stdout_str) { result[0] }
10+
let(:status) { result[1] }
11+
12+
context 'when changes are made' do
13+
let(:manifest) do
14+
<<DOC
15+
test_failure {
16+
one: failure=>false;
17+
two: failure=>true;
18+
three: failure=>false;
19+
}
20+
DOC
21+
end
22+
23+
it 'applies a catalog with some failing resources' do
24+
expect(stdout_str).to match %r{Creating 'one' with \{:name=>"one", :failure=>false, :ensure=>"present"\}}
25+
expect(stdout_str).to match %r{Creating 'two' with \{:name=>"two", :failure=>true, :ensure=>"present"\}}
26+
expect(stdout_str).to match %r{Creating: Failed.*A failure for two}
27+
expect(stdout_str).to match %r{Could not evaluate: Execution encountered an error}
28+
expect(stdout_str).to match %r{Creating 'three' with \{:name=>"three", :failure=>false, :ensure=>"present"\}}
29+
expect(stdout_str).not_to match %r{Creating: Failed.*A failure for three}
30+
expect(stdout_str).to match %r{test_failure\[three\]: Finished}
31+
expect(status.exitstatus).to eq 6
32+
end
33+
end
34+
end
35+
end
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
require 'puppet/resource_api'
2+
require 'puppet/resource_api/simple_provider'
3+
4+
# Implementation for the test_bool type using the Resource API.
5+
class Puppet::Provider::TestFailure::TestFailure
6+
def get(_context)
7+
[]
8+
end
9+
10+
def set(context, changes)
11+
changes.each do |name, change|
12+
is = change[:is]
13+
should = change[:should]
14+
15+
context.notice(name, "Creating '#{name}' with #{should.inspect}")
16+
if should[:failure]
17+
context.creating(name) do
18+
raise "A failure for #{name}"
19+
end
20+
end
21+
context.notice(name, "Finished")
22+
end
23+
end
24+
end
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
require 'puppet/resource_api'
2+
3+
Puppet::ResourceApi.register_type(
4+
name: 'test_failure',
5+
docs: <<-DOC,
6+
This type provides Puppet with the capabilities to manage ...
7+
DOC
8+
features: [],
9+
attributes: {
10+
ensure: {
11+
type: 'Enum[present, absent]',
12+
desc: 'Whether this resource should be present or absent on the target system.',
13+
default: 'present',
14+
},
15+
name: {
16+
type: 'String',
17+
desc: 'The name of the resource you want to manage.',
18+
behaviour: :namevar,
19+
},
20+
failure: {
21+
type: 'Boolean',
22+
desc: 'A boolean property for testing.',
23+
default: false,
24+
},
25+
},
26+
)

spec/puppet/resource_api/base_context_spec.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,4 +364,13 @@ def send_log(log, msg)
364364
context.feature_support?('anything')
365365
}
366366
end
367+
368+
describe '#reset_failed' do
369+
it 'resets the failure state' do
370+
context.failing('bad_resource') { raise StandardError, 'Bad Resource!' }
371+
expect(context).to be_failed
372+
context.reset_failed
373+
expect(context).not_to be_failed
374+
end
375+
end
367376
end

spec/spec_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
require 'bundler/setup'
22
require 'rspec-puppet'
3+
require 'open3'
34

45
RSpec.configure do |config|
56
# Enable flags like --only-failures and --next-failure

0 commit comments

Comments
 (0)