Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions lib/foreman_inventory_upload/async/upload_report_direct_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ def try_execute

move_to_done_folder
done!
rescue RestClient::ExceptionWithResponse => e
if non_retryable_upload_error?(e)
logger.warn(
"Upload skipped for organization '#{organization}' " \
"due to non-retryable response (#{e.http_code}): #{sanitized_http_body(e)}"
)
output[:status] = 'upload_skipped_non_retryable'
done!
return
end

raise
end

def upload_file(cer_path)
Expand Down Expand Up @@ -161,6 +173,24 @@ def content_disconnected?
!Setting[:subscription_connection_enabled]
end

def non_retryable_upload_error?(exception)
code = exception.http_code.to_i
code >= 400 && code < 500 && ![408, 429].include?(code)
end

def sanitized_http_body(exception)
body = exception.http_body.to_s
max_length = 500

if body.length > max_length
"#{body[0, max_length]}... [truncated]"
else
body
end
rescue StandardError
exception.message.to_s
end

def logger
Foreman::Logging.logger('background')
end
Expand Down
40 changes: 40 additions & 0 deletions test/jobs/upload_report_direct_job_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,46 @@ class UploadReportDirectJobTest < ActiveSupport::TestCase
end
end

test 'marks action done on non-retryable client upload errors' do
response = mock('response')
response.stubs(:code).returns(422)
response.stubs(:body).returns('No eligible hosts in report')

ForemanInventoryUpload::Async::UploadReportDirectJob.any_instance.stubs(:upload_file)
.raises(RestClient::UnprocessableEntity.new(response))

action = create_action(ForemanInventoryUpload::Async::UploadReportDirectJob)
action.expects(:action_subject).with(@organization)
plan_action(action, @filename, @organization.id)
runtime_output = {}
action.stubs(:output).returns(runtime_output)

# Non-retryable 4xx responses should not raise and should end polling.
action.send(:try_execute)
assert action.done?
assert_equal 'upload_skipped_non_retryable', runtime_output[:status]
end

test 'keeps retry behavior for retryable client upload errors' do
response = mock('response')
response.stubs(:code).returns(429)
response.stubs(:body).returns('Too Many Requests')

ForemanInventoryUpload::Async::UploadReportDirectJob.any_instance.stubs(:upload_file)
.raises(RestClient::TooManyRequests.new(response))

action = create_action(ForemanInventoryUpload::Async::UploadReportDirectJob)
action.expects(:action_subject).with(@organization)
plan_action(action, @filename, @organization.id)
runtime_output = {}
action.stubs(:output).returns(runtime_output)

assert_raises(RestClient::TooManyRequests) do
action.send(:try_execute)
end
Comment thread
nofaralfasi marked this conversation as resolved.
assert_nil runtime_output[:status]
end

test 'uses proxy configuration from ForemanRhCloud' do
proxy_url = 'http://proxy.example.com:8080'
ForemanRhCloud.stubs(:transformed_http_proxy_string).returns(proxy_url)
Expand Down
Loading