mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 02:11:08 -06:00
e60876ce49
When running checks, we look to the existing problem check trackers and try to grab their ProblemCheck classes. In some cases this is no longer in the problem check repository, e.g. when the check was part of a plugin that has been uninstalled. In the case where the check was scheduled, this would lead to an error in one of the jobs
260 lines
7.0 KiB
Ruby
260 lines
7.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe ProblemCheckTracker do
|
|
describe "validations" do
|
|
let(:record) { described_class.new(identifier: "twitter_login") }
|
|
|
|
it { expect(record).to validate_presence_of(:identifier) }
|
|
it { expect(record).to validate_uniqueness_of(:identifier).scoped_to(:target) }
|
|
|
|
it { expect(record).to validate_numericality_of(:blips).is_greater_than_or_equal_to(0) }
|
|
end
|
|
|
|
describe ".[]" do
|
|
before { Fabricate(:problem_check_tracker, identifier: "twitter_login") }
|
|
|
|
context "when the problem check tracker already exists" do
|
|
it { expect(described_class[:twitter_login]).not_to be_new_record }
|
|
end
|
|
|
|
context "when the problem check tracker doesn't exist yet" do
|
|
it { expect(described_class[:facebook_login]).to be_previously_new_record }
|
|
end
|
|
end
|
|
|
|
describe "#check" do
|
|
before do
|
|
Fabricate(:problem_check_tracker, identifier: "twitter_login")
|
|
Fabricate(:problem_check_tracker, identifier: "missing_check")
|
|
end
|
|
|
|
context "when the tracker has a corresponding check" do
|
|
it { expect(described_class[:twitter_login].check.new).to be_a(ProblemCheck) }
|
|
end
|
|
|
|
context "when the checking logic of the tracker has been removed or renamed" do
|
|
it do
|
|
expect { described_class[:missing_check].check }.to change { described_class.count }.by(-1)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#ready_to_run?" do
|
|
let(:problem_tracker) { described_class.new(next_run_at:) }
|
|
|
|
context "when the next run timestamp is not set" do
|
|
let(:next_run_at) { nil }
|
|
|
|
it { expect(problem_tracker).to be_ready_to_run }
|
|
end
|
|
|
|
context "when the next run timestamp is in the past" do
|
|
let(:next_run_at) { 5.minutes.ago }
|
|
|
|
it { expect(problem_tracker).to be_ready_to_run }
|
|
end
|
|
|
|
context "when the next run timestamp is in the future" do
|
|
let(:next_run_at) { 5.minutes.from_now }
|
|
|
|
it { expect(problem_tracker).not_to be_ready_to_run }
|
|
end
|
|
end
|
|
|
|
describe "#failing?" do
|
|
before { freeze_time }
|
|
|
|
let(:problem_tracker) { described_class.new(last_problem_at:, last_run_at:, last_success_at:) }
|
|
|
|
context "when the last run passed" do
|
|
let(:last_run_at) { 1.minute.ago }
|
|
let(:last_success_at) { 1.minute.ago }
|
|
let(:last_problem_at) { 11.minutes.ago }
|
|
|
|
it { expect(problem_tracker).not_to be_failing }
|
|
end
|
|
|
|
context "when the last run had a problem" do
|
|
let(:last_run_at) { 1.minute.ago }
|
|
let(:last_success_at) { 11.minutes.ago }
|
|
let(:last_problem_at) { 1.minute.ago }
|
|
|
|
it { expect(problem_tracker).to be_failing }
|
|
end
|
|
end
|
|
|
|
describe "#passing?" do
|
|
before { freeze_time }
|
|
|
|
let(:problem_tracker) { described_class.new(last_problem_at:, last_run_at:, last_success_at:) }
|
|
|
|
context "when the last run passed" do
|
|
let(:last_run_at) { 1.minute.ago }
|
|
let(:last_success_at) { 1.minute.ago }
|
|
let(:last_problem_at) { 11.minutes.ago }
|
|
|
|
it { expect(problem_tracker).to be_passing }
|
|
end
|
|
|
|
context "when the last run had a problem" do
|
|
let(:last_run_at) { 1.minute.ago }
|
|
let(:last_success_at) { 11.minutes.ago }
|
|
let(:last_problem_at) { 1.minute.ago }
|
|
|
|
it { expect(problem_tracker).not_to be_passing }
|
|
end
|
|
end
|
|
|
|
describe "#problem!" do
|
|
let(:problem_tracker) do
|
|
Fabricate(
|
|
:problem_check_tracker,
|
|
identifier: "twitter_login",
|
|
target: "foo",
|
|
**original_attributes,
|
|
)
|
|
end
|
|
|
|
let(:original_attributes) do
|
|
{
|
|
blips:,
|
|
last_problem_at: 1.week.ago,
|
|
last_success_at: 24.hours.ago,
|
|
last_run_at: 24.hours.ago,
|
|
next_run_at: nil,
|
|
}
|
|
end
|
|
|
|
let(:blips) { 0 }
|
|
let(:updated_attributes) { { blips: 1 } }
|
|
|
|
it do
|
|
freeze_time
|
|
|
|
expect { problem_tracker.problem!(next_run_at: 24.hours.from_now) }.to change {
|
|
problem_tracker.attributes
|
|
}.to(hash_including(updated_attributes))
|
|
end
|
|
|
|
context "when the maximum number of blips have been surpassed" do
|
|
let(:blips) { 1 }
|
|
|
|
it "sounds the alarm" do
|
|
expect { problem_tracker.problem!(next_run_at: 24.hours.from_now) }.to change {
|
|
AdminNotice.problem.count
|
|
}.by(1)
|
|
end
|
|
end
|
|
|
|
context "when there's an alarm sounding for multi-target trackers" do
|
|
let(:blips) { 1 }
|
|
|
|
before do
|
|
Fabricate(
|
|
:admin_notice,
|
|
subject: "problem",
|
|
identifier: "twitter_login",
|
|
details: {
|
|
target: target,
|
|
},
|
|
)
|
|
end
|
|
|
|
context "when the alarm is for a different target" do
|
|
let(:target) { "bar" }
|
|
|
|
it "sounds the alarm" do
|
|
expect { problem_tracker.problem!(next_run_at: 24.hours.from_now) }.to change {
|
|
AdminNotice.problem.count
|
|
}.by(1)
|
|
end
|
|
end
|
|
|
|
context "when the alarm is for a the same target" do
|
|
let(:target) { "foo" }
|
|
|
|
it "does not duplicate the alarm" do
|
|
expect { problem_tracker.problem!(next_run_at: 24.hours.from_now) }.not_to change {
|
|
AdminNotice.problem.count
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when there are still blips to go" do
|
|
let(:blips) { 0 }
|
|
|
|
before { ProblemCheck::TwitterLogin.stubs(:max_blips).returns(1) }
|
|
|
|
it "does not sound the alarm" do
|
|
puts ProblemCheck::TwitterLogin.max_blips
|
|
expect { problem_tracker.problem!(next_run_at: 24.hours.from_now) }.not_to change {
|
|
AdminNotice.problem.count
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#no_problem!" do
|
|
let(:problem_tracker) do
|
|
Fabricate(:problem_check_tracker, identifier: "twitter_login", **original_attributes)
|
|
end
|
|
|
|
let(:original_attributes) do
|
|
{
|
|
blips: 0,
|
|
last_problem_at: 1.week.ago,
|
|
last_success_at: Time.current,
|
|
last_run_at: 24.hours.ago,
|
|
next_run_at: nil,
|
|
}
|
|
end
|
|
|
|
let(:updated_attributes) { { blips: 0 } }
|
|
|
|
it do
|
|
freeze_time
|
|
|
|
expect { problem_tracker.no_problem!(next_run_at: 24.hours.from_now) }.to change {
|
|
problem_tracker.attributes
|
|
}.to(hash_including(updated_attributes))
|
|
end
|
|
|
|
context "when there's an alarm sounding" do
|
|
before { Fabricate(:admin_notice, subject: "problem", identifier: "twitter_login") }
|
|
|
|
it "silences the alarm" do
|
|
expect { problem_tracker.no_problem!(next_run_at: 24.hours.from_now) }.to change {
|
|
AdminNotice.problem.count
|
|
}.by(-1)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#reset" do
|
|
let(:problem_tracker) do
|
|
Fabricate(:problem_check_tracker, identifier: "twitter_login", **original_attributes)
|
|
end
|
|
|
|
let(:original_attributes) do
|
|
{
|
|
blips: 0,
|
|
last_problem_at: 1.week.ago,
|
|
last_success_at: Time.current,
|
|
last_run_at: 24.hours.ago,
|
|
next_run_at: nil,
|
|
}
|
|
end
|
|
|
|
let(:updated_attributes) { { blips: 0 } }
|
|
|
|
it do
|
|
freeze_time
|
|
|
|
expect { problem_tracker.reset(next_run_at: 24.hours.from_now) }.to change {
|
|
problem_tracker.attributes
|
|
}.to(hash_including(updated_attributes))
|
|
end
|
|
end
|
|
end
|