Skip to content

Commit

Permalink
Merge pull request #15483 from NickLaMuro/fix_heartbeat_to_file_bug
Browse files Browse the repository at this point in the history
Fix pseudo heartbeating when HB file missing
  • Loading branch information
jrafanie authored Jun 30, 2017
2 parents d418207 + abd1b70 commit 465bd15
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
2 changes: 1 addition & 1 deletion app/models/miq_server/worker_management/heartbeat.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,6 @@ def workers_last_heartbeat_to_drb(w)
end

def workers_last_heartbeat_to_file(w)
File.exist?(w.heartbeat_file) ? File.mtime(w.heartbeat_file).utc : Time.now.utc
File.mtime(w.heartbeat_file).utc if File.exist?(w.heartbeat_file)
end
end
70 changes: 70 additions & 0 deletions spec/models/miq_server/worker_management/heartbeat_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,75 @@
expect(worker.reload.last_heartbeat).to be_within(1.second).of(t)
end
end

# Iterating by 5 each time to allow enough spacing to be more than 1 second
# apart when using be_within(x).of(t)
context "when using file based heartbeating" do
let!(:first_heartbeat) { Time.now.utc }
let!(:heartbeat_file) { "/path/to/worker.hb" }

around do |example|
ENV["WORKER_HEARTBEAT_METHOD"] = "file"
ENV["WORKER_HEARTBEAT_FILE"] = heartbeat_file
example.run
ENV.delete("WORKER_HEARTBEAT_METHOD")
ENV.delete("WORKER_HEARTBEAT_FILE")
end

context "with an existing heartbeat file" do
it "sets initial and subsequent heartbeats" do
expect(File).to receive(:exist?).with(heartbeat_file).and_return(true, true)
expect(File).to receive(:mtime).with(heartbeat_file).and_return(first_heartbeat, first_heartbeat + 5)

[0, 5].each do |i|
Timecop.freeze(first_heartbeat) do
miq_server.worker_heartbeat(pid)
miq_server.validate_heartbeat(worker)
end

expect(worker.reload.last_heartbeat).to be_within(1.second).of(first_heartbeat + i)
end
end
end

context "with a missing heartbeat file" do
it "sets initial heartbeat only" do
expect(File).to receive(:exist?).with(heartbeat_file).and_return(false).exactly(4).times
expect(File).to receive(:mtime).with(heartbeat_file).never

# This has different results first iteration of the loop compared to
# the rest:
# 1. Sets the initial heartbeat
# 2. Doesn't update the worker's last_heartbeat value after that
#
# So the result from the database should not change after the first
# iteration of the loop
[0, 5, 10, 15].each do |i|
Timecop.freeze(first_heartbeat + i) do
miq_server.worker_heartbeat(pid)
miq_server.validate_heartbeat(worker)
end

expect(worker.reload.last_heartbeat).to be_within(1.second).of(first_heartbeat)
end
end
end

context "with a missing heartbeat file on the first validate" do
it "sets initial heartbeat default, and updates the heartbeat from the file second" do
expect(File).to receive(:exist?).with(heartbeat_file).and_return(false, true)
expect(File).to receive(:mtime).with(heartbeat_file).and_return(first_heartbeat + 5)

[0, 5].each do |i|
Timecop.freeze(first_heartbeat) do
miq_server.worker_heartbeat(pid)
miq_server.validate_heartbeat(worker)
end

expect(worker.reload.last_heartbeat).to be_within(1.second).of(first_heartbeat + i)
end
end
end
end
end
end

0 comments on commit 465bd15

Please sign in to comment.