mirror of
https://github.com/discourse/discourse.git
synced 2024-12-12 22:05:48 +08:00
0c875cb4d5
Previously the problem check registry simply looked at the subclasses of ProblemCheck. This was causing some confusion in environments where eager loading is not enabled, as the registry would appear empty as a result of the classes never being referenced (and thus never loaded.) This PR changes the approach to a more explicit one. I followed other implementations (bookmarkable and hashtag autocomplete.) As a bonus, this now has a neat plugin entry point as well.
163 lines
4.6 KiB
Ruby
163 lines
4.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe Jobs::RunProblemCheck do
|
|
after { Discourse.redis.flushdb }
|
|
|
|
context "when there are problems" do
|
|
around do |example|
|
|
ProblemCheck::TestCheck =
|
|
Class.new(ProblemCheck) do
|
|
self.perform_every = 30.minutes
|
|
self.max_retries = 0
|
|
|
|
def call
|
|
[
|
|
ProblemCheck::Problem.new("Big problem"),
|
|
ProblemCheck::Problem.new(
|
|
"Yuge problem",
|
|
priority: "high",
|
|
identifier: "config_is_a_mess",
|
|
),
|
|
]
|
|
end
|
|
end
|
|
|
|
stub_const(ProblemCheck, "CORE_PROBLEM_CHECKS", [ProblemCheck::TestCheck], &example)
|
|
|
|
ProblemCheck.send(:remove_const, "TestCheck")
|
|
end
|
|
|
|
it "adds the messages to the Redis problems array" do
|
|
described_class.new.execute(check_identifier: :test_check)
|
|
|
|
problems = AdminDashboardData.load_found_scheduled_check_problems
|
|
|
|
expect(problems.map(&:to_s)).to contain_exactly("Big problem", "Yuge problem")
|
|
end
|
|
end
|
|
|
|
context "with multiple problems with the same identifier" do
|
|
around do |example|
|
|
ProblemCheck::TestCheck =
|
|
Class.new(ProblemCheck) do
|
|
self.perform_every = 30.minutes
|
|
self.max_retries = 0
|
|
|
|
def call
|
|
[
|
|
ProblemCheck::Problem.new(
|
|
"Yuge problem",
|
|
priority: "high",
|
|
identifier: "config_is_a_mess",
|
|
),
|
|
ProblemCheck::Problem.new(
|
|
"Nasty problem",
|
|
priority: "high",
|
|
identifier: "config_is_a_mess",
|
|
),
|
|
]
|
|
end
|
|
end
|
|
|
|
stub_const(ProblemCheck, "CORE_PROBLEM_CHECKS", [ProblemCheck::TestCheck], &example)
|
|
|
|
ProblemCheck.send(:remove_const, "TestCheck")
|
|
end
|
|
|
|
it "does not add the same problem twice" do
|
|
described_class.new.execute(check_identifier: :test_check)
|
|
|
|
problems = AdminDashboardData.load_found_scheduled_check_problems
|
|
|
|
expect(problems.map(&:to_s)).to match_array(["Yuge problem"])
|
|
end
|
|
end
|
|
|
|
context "when there are retries remaining" do
|
|
around do |example|
|
|
ProblemCheck::TestCheck =
|
|
Class.new(ProblemCheck) do
|
|
self.perform_every = 30.minutes
|
|
self.max_retries = 2
|
|
|
|
def call
|
|
[ProblemCheck::Problem.new("Yuge problem")]
|
|
end
|
|
end
|
|
|
|
stub_const(ProblemCheck, "CORE_PROBLEM_CHECKS", [ProblemCheck::TestCheck], &example)
|
|
|
|
ProblemCheck.send(:remove_const, "TestCheck")
|
|
end
|
|
|
|
it "does not yet update the problem check tracker" do
|
|
expect {
|
|
described_class.new.execute(check_identifier: :test_check, retry_count: 1)
|
|
}.not_to change { ProblemCheckTracker.where("blips > ?", 0).count }
|
|
end
|
|
|
|
it "schedules a retry" do
|
|
expect_enqueued_with(
|
|
job: :run_problem_check,
|
|
args: {
|
|
check_identifier: :test_check,
|
|
retry_count: 1,
|
|
},
|
|
) { described_class.new.execute(check_identifier: :test_check) }
|
|
end
|
|
end
|
|
|
|
context "when there are no retries remaining" do
|
|
around do |example|
|
|
ProblemCheck::TestCheck =
|
|
Class.new(ProblemCheck) do
|
|
self.perform_every = 30.minutes
|
|
self.max_retries = 1
|
|
|
|
def call
|
|
[ProblemCheck::Problem.new("Yuge problem")]
|
|
end
|
|
end
|
|
|
|
stub_const(ProblemCheck, "CORE_PROBLEM_CHECKS", [ProblemCheck::TestCheck], &example)
|
|
|
|
ProblemCheck.send(:remove_const, "TestCheck")
|
|
end
|
|
|
|
it "updates the problem check tracker" do
|
|
expect {
|
|
described_class.new.execute(check_identifier: :test_check, retry_count: 1)
|
|
}.to change { ProblemCheckTracker.where("blips > ?", 0).count }.by(1)
|
|
end
|
|
|
|
it "does not schedule a retry" do
|
|
expect_not_enqueued_with(job: :run_problem_check) do
|
|
described_class.new.execute(check_identifier: :test_check, retry_count: 1)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the check unexpectedly errors out" do
|
|
around do |example|
|
|
ProblemCheck::TestCheck =
|
|
Class.new(ProblemCheck) do
|
|
self.max_retries = 1
|
|
|
|
def call
|
|
raise StandardError.new("Something went wrong")
|
|
end
|
|
end
|
|
|
|
stub_const(ProblemCheck, "CORE_PROBLEM_CHECKS", [ProblemCheck::TestCheck], &example)
|
|
|
|
ProblemCheck.send(:remove_const, "TestCheck")
|
|
end
|
|
|
|
it "does not add a problem to the Redis array" do
|
|
described_class.new.execute(check_identifier: :test_check)
|
|
|
|
expect(AdminDashboardData.load_found_scheduled_check_problems).to be_empty
|
|
end
|
|
end
|
|
end
|