21
1
Fork 0
mirror of https://github.com/Evolix/chexpire.git synced 2024-04-25 21:40:49 +02:00

Checks processor refactoring for more flexibility

This commit is contained in:
Colin Darie 2018-07-02 14:25:35 +02:00
parent 47d8641a66
commit db4e7d42b2
No known key found for this signature in database
GPG key ID: 4FB865FDBCA4BCC4
9 changed files with 120 additions and 50 deletions

View file

@ -0,0 +1,25 @@
class CheckDomainProcessor
include CheckProcessor
protected
def configuration_key
"checks_domain"
end
def resolvers
%i[
resolve_last_run_failed
resolve_expire_short_term
resolve_expire_long_term
resolve_unknown_expiry
]
end
def scope
base_scope.domain
end
def process(check)
WhoisSyncJob.perform_now(check.id)
end
end

View file

@ -1,17 +1,12 @@
class CheckProcessor
module CheckProcessor
attr_reader :configuration
def initialize(configuration = nil)
@configuration = configuration || default_configuration
end
def sync_dates # rubocop:disable Metrics/MethodLength
%i[
resolve_last_run_failed
resolve_expire_short_term
resolve_expire_long_term
resolve_unknown_expiry
].each do |resolver|
def sync_dates
resolvers.each do |resolver|
public_send(resolver).find_each(batch_size: 100).each do |check|
process(check)
@ -20,6 +15,12 @@ class CheckProcessor
end
end
# :nocov:
def resolvers
fail NotImplementedError, "#{self.class.name} did not implemented method #{__callee__}"
end
# :nocov:
def resolve_last_run_failed
scope.last_run_failed
end
@ -41,25 +42,32 @@ class CheckProcessor
scope.where("domain_expires_at IS NULL")
end
private
protected
def scope
def base_scope
Check
.active
.where("last_run_at IS NULL OR last_run_at < DATE_SUB(NOW(), INTERVAL 12 HOUR)")
end
def process(check)
case check.kind.to_sym
when :domain
WhoisSyncJob.perform_now(check.id)
else
fail ArgumentError, "Unsupported check kind `#{check.kind}`"
end
# :nocov:
def scope
fail NotImplementedError, "#{self.class.name} did not implemented method #{__callee__}"
end
def process(check)
fail NotImplementedError, "#{self.class.name} did not implemented method #{__callee__}"
end
def configuration_key
fail NotImplementedError, "#{self.class.name} did not implemented method #{__callee__}"
end
# :nocov:
private
def default_configuration
config = Rails.configuration.chexpire.fetch("checks", {})
config = Rails.configuration.chexpire.fetch(configuration_key, {})
OpenStruct.new(
interval: config.fetch("interval") { 0.00 },

View file

@ -3,7 +3,7 @@ default: &default
notifier:
interval: 0.00
failure_days: 3
checks:
checks_domain:
interval: 0.5
long_term: 60
long_term_frequency: 10

View file

@ -4,7 +4,7 @@ test:
notifier:
interval: 0.00
failure_days: 3
checks:
checks_domain:
interval: 0.00
long_term: 60
long_term_frequency: 10

View file

@ -19,7 +19,7 @@ set :output, standard: "log/cron.log"
# Learn more: http://github.com/javan/whenever
every 1.day, at: '4:30 am', roles: [:app] do
rake "checks:sync_dates"
rake "checks:sync_dates:all"
end
every 1.day, at: '10:30 am', roles: [:app] do

View file

@ -1,7 +1,11 @@
namespace :checks do
desc "Refresh expiry dates for checks"
task sync_dates: :environment do
process = CheckProcessor.new
process.sync_dates
namespace :sync_dates do
task all: [:domain]
desc "Refresh domains expiry dates"
task domain: :environment do
process = CheckDomainProcessor.new
process.sync_dates
end
end
end

View file

@ -44,6 +44,10 @@ FactoryBot.define do
kind :domain
end
trait :ssl do
kind :ssl
end
trait :nil_dates do
domain_created_at nil
domain_updated_at nil

View file

@ -0,0 +1,34 @@
require "test_helper"
class CheckDomainProcessorTest < ActiveSupport::TestCase
setup do
@processor = CheckDomainProcessor.new
end
test "process WhoisSyncJob for domain checks" do
domain = "domain.fr"
check = create(:check, :domain, :nil_dates, domain: domain)
mock_system_command("whois", domain, stdout: file_fixture("whois/domain.fr.txt").read) do
@processor.send(:process, check)
end
check.reload
assert_equal Time.new(2019, 2, 17, 0, 0, 0, 0), check.domain_expires_at
end
test "scope concerns only checks of kind 'domain'" do
domains = create_list(:check, 2, :domain)
create_list(:check, 2, :ssl)
assert_equal domains, @processor.send(:scope)
end
test "resolvers returns an array of methods returning a scope" do
assert_not_empty @processor.send(:resolvers)
@processor.send(:resolvers).each do |method|
assert_kind_of ActiveRecord::Relation, @processor.public_send(method)
end
end
end

View file

@ -1,31 +1,26 @@
require "test_helper"
class CheckDummyProcessor
include CheckProcessor
def scope
base_scope
end
def configuration_key
"checks_dummy"
end
def resolvers
%i[
resolve_expire_short_term
resolve_expire_long_term
]
end
end
class CheckProcessorTest < ActiveSupport::TestCase
setup do
@processor = CheckProcessor.new
end
test "process WhoisSyncJob for domain checks" do
domain = "domain.fr"
check = create(:check, :domain, :nil_dates, domain: domain)
mock_system_command("whois", domain, stdout: file_fixture("whois/domain.fr.txt").read) do
@processor.send(:process, check)
end
check.reload
assert_equal Time.new(2019, 2, 17, 0, 0, 0, 0), check.domain_expires_at
end
test "raises an error for an unsupported check kind" do
check = build(:check)
check.stub :kind, :unknown do
assert_raises ArgumentError do
@processor.send(:process, check)
end
end
@processor = CheckDummyProcessor.new
end
test "resolve_last_run_failed includes already and never succeeded" do
@ -113,7 +108,7 @@ class CheckProcessorTest < ActiveSupport::TestCase
configuration.expect(:interval, 0.000001)
end
processor = CheckProcessor.new(configuration)
processor = CheckDummyProcessor.new(configuration)
mock = Minitest::Mock.new
assert_stub = lambda { |actual_time|