Skip to content

Commit

Permalink
Fixes #37322 - Add timestamp to exit status
Browse files Browse the repository at this point in the history
  • Loading branch information
adamruzicka committed Nov 5, 2024
1 parent 56614ae commit d6e6a73
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 5 deletions.
1 change: 1 addition & 0 deletions lib/smart_proxy_dynflow/action/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def kill_run

def finish_run(update)
output[:exit_status] = update.exit_status
output[:exit_status_timestamp] = update.exit_status_timestamp.to_f
output[:result] = output_result
drop_output_chunks!
end
Expand Down
3 changes: 2 additions & 1 deletion lib/smart_proxy_dynflow/runner/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def publish_exception(context, exception, fatal = true)

def publish_exit_status(status)
@exit_status = status
@exit_status_timestamp = Time.now.utc
end

def dispatch_exception(context, exception)
Expand All @@ -90,7 +91,7 @@ def no_update
end

def new_update(data, exit_status)
{ @suspended_action => Runner::Update.new(data, exit_status) }
{ @suspended_action => Runner::Update.new(data, exit_status, exit_status_timestamp: @exit_status_timestamp) }
end

def initialize_continuous_outputs
Expand Down
4 changes: 2 additions & 2 deletions lib/smart_proxy_dynflow/runner/parent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ def initialize(targets = {}, suspended_action: nil, id: nil)

def generate_updates
base = {}
base[@suspended_action] = Runner::Update.new(Proxy::Dynflow::ContinuousOutput.new, @exit_status) if @exit_status
base[@suspended_action] = Runner::Update.new(Proxy::Dynflow::ContinuousOutput.new, @exit_status, exit_status_timestamp: @exit_status_timestamp) if @exit_status
# Operate on all hosts if the main process ended or only on hosts for which we have updates
@outputs.reject { |_, output| @exit_status.nil? && output.empty? }
.reduce(base) do |acc, (identifier, output)|
@outputs[identifier] = Proxy::Dynflow::ContinuousOutput.new # Create a new ContinuousOutput for next round of updates
exit_status = @exit_statuses[identifier] || @exit_status if @exit_status
acc.merge(host_action(identifier) => Runner::Update.new(output, exit_status))
acc.merge(host_action(identifier) => Runner::Update.new(output, exit_status, exit_status_timestamp: @exit_status_timestamp))
end
end

Expand Down
5 changes: 3 additions & 2 deletions lib/smart_proxy_dynflow/runner/update.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ module Runner
# Runner::Update represents chunk of data produced by runner that
# can be consumed by other components, such as RunnerAction
class Update
attr_reader :continuous_output, :exit_status
attr_reader :continuous_output, :exit_status, :exit_status_timestamp

def initialize(continuous_output, exit_status)
def initialize(continuous_output, exit_status, exit_status_timestamp: nil)
@continuous_output = continuous_output
@exit_status = exit_status
@exit_status_timestamp = exit_status_timestamp || Time.now.utc if @exit_status
end

def self.encode_exception(context, exception, fatal = true)
Expand Down
39 changes: 39 additions & 0 deletions test/runner_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ class RunnerTest < Minitest::Spec
_(update.continuous_output.raw_outputs.count).must_equal 1
end
end

describe '#publish_exit_status' do
it 'sets exit status and timestamp' do
runner.publish_exit_status(0)
updates = runner.generate_updates
assert_equal 0, updates[suspended_action].exit_status
assert_instance_of Time, updates[suspended_action].exit_status_timestamp
end
end
end

describe Parent do
Expand Down Expand Up @@ -194,6 +203,36 @@ class RunnerTest < Minitest::Spec
runner.publish_exception('general failure', exception, true)
end
end

describe '#publish_exit_status' do
it 'sets exit status and timestamp' do
runner.publish_exit_status(0)
updates = runner.generate_updates

# There are updates for all targets
assert_equal 3, updates.keys.count

# They all share the same exit status and timestamp
assert_equal 1, updates.values.map(&:exit_status).uniq.count
assert_equal 1, updates.values.map(&:exit_status_timestamp).uniq.count

assert_equal 0, updates[suspended_action].exit_status
assert_instance_of Time, updates[suspended_action].exit_status_timestamp
end

it 'allows settings exit status per-host' do
runner.publish_exit_status_for('foo', 1)
runner.publish_exit_status(0)
updates = runner.generate_updates
assert_equal 3, updates.keys.count

assert_equal(1, updates.values.count { |update| update.exit_status == 1 })
assert_equal(2, updates.values.count { |update| update.exit_status.zero? })

# They all share the same timestamp
assert_equal 1, updates.values.map(&:exit_status_timestamp).uniq.count
end
end
end
end
end
Expand Down

0 comments on commit d6e6a73

Please sign in to comment.