Files
ubicloud/spec/model/strand_spec.rb
Benjamin Satzger 207f1f7cbf Reduce amount of obtained/cleared lease log lines
The system currently generates a large number of "obtained lease" and "lease cleared" log
entries, which contributes to increased downstream costs. Since some views rely on these
log entries, this update does not eliminate them entirely. Instead, it reduces their
frequency by emitting them at a rate of approximately one per thousand.
2025-01-03 13:11:25 +01:00

116 lines
3.4 KiB
Ruby

# frozen_string_literal: true
require_relative "spec_helper"
RSpec.describe Strand do
let(:st) {
described_class.new(id: described_class.generate_uuid,
prog: "Test",
label: "start")
}
context "when leasing" do
it "can take a lease only if one is not already taken" do
st.save_changes
did_it = st.take_lease_and_reload {
expect(st.take_lease_and_reload {
:never_happens
}).to be false
:did_it
}
expect(did_it).to be :did_it
end
it "does an integrity check that deleted records are gone" do
st.label = "hop_exit"
st.save_changes
original = DB.method(:[])
original = original.super_method unless original.owner == Sequel::Database
expect(DB).to receive(:[]) do |*args, **kwargs|
case args
when ["SELECT FROM strand WHERE id = ?", st.id]
instance_double(Sequel::Dataset, empty?: false)
else
original.call(*args, **kwargs)
end
end.at_least(:once)
expect { st.run }.to raise_error RuntimeError, "BUG: strand with @deleted set still exists in the database"
end
it "does an integrity check that the lease was modified as expected" do
st.label = "napper"
st.save_changes
original = DB.method(:[])
original = original.super_method unless original.owner == Sequel::Database
expect(DB).to receive(:[]) do |*args, **kwargs|
case args[0]
when <<SQL
UPDATE strand
SET lease = NULL
WHERE id = ? AND lease = ?
SQL
instance_double(Sequel::Dataset, update: 0)
else
original.call(*args, **kwargs)
end
end.at_least(:once)
expect(Clog).to receive(:emit).with("lease violated data").and_call_original
allow(Clog).to receive(:emit).and_call_original
expect { st.run }.to raise_error RuntimeError, "BUG: lease violated"
end
end
it "can load a prog" do
expect(st.load).to be_instance_of Prog::Test
end
it "can hop" do
st.save_changes
st.label = "hop_entry"
expect(st).to receive(:load).and_return Prog::Test.new(st)
expect {
st.unsynchronized_run
}.to change(st, :label).from("hop_entry").to("hop_exit")
end
it "rejects prog names that are not in the right module" do
expect {
described_class.prog_verify(Object)
}.to raise_error RuntimeError, "BUG: prog must be in Prog module"
end
it "crashes if a label does not provide flow control" do
expect {
st.unsynchronized_run
}.to raise_error RuntimeError, "BUG: Prog Test#start did not provide flow control"
end
it "can run labels consecutively if a deadline is not reached" do
st.label = "hop_entry"
st.save_changes
expect {
st.run(10)
}.to change { [st.label, st.exitval] }.from(["hop_entry", nil]).to(["hop_exit", {msg: "hop finished"}])
end
it "logs end of strand if it took long" do
st.label = "napper"
st.save_changes
expect(Time).to receive(:now).and_return(Time.now - 10, Time.now, Time.now)
expect(Clog).to receive(:emit).with("finished strand").and_call_original
st.unsynchronized_run
end
it "occasionally logs acquisition and release of lease" do
st.label = "napper"
st.save_changes
expect(st).to receive(:rand).and_return(0)
expect(Clog).to receive(:emit).with("obtained lease").and_call_original
expect(Clog).to receive(:emit).with("lease cleared").and_call_original
st.take_lease_and_reload {}
end
end