mirror of
https://github.com/plashchynski/crono.git
synced 2026-07-08 22:05:08 +02:00
Lint the whole project
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
|
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
||||||
|
|
||||||
require "crono/cli"
|
require 'crono/cli'
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Crono::CLI.instance.run
|
Crono::CLI.instance.run
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# cronotab.rb — Crono configuration file
|
# cronotab.rb - Crono configuration file
|
||||||
#
|
#
|
||||||
# Here you can specify periodic jobs and schedule.
|
# Here you can specify periodic jobs and schedule.
|
||||||
# You can use ActiveJob's jobs from `app/jobs/`
|
# You can use ActiveJob's jobs from `app/jobs/`
|
||||||
@@ -7,9 +7,8 @@
|
|||||||
#
|
#
|
||||||
class TestJob
|
class TestJob
|
||||||
def perform
|
def perform
|
||||||
puts "Test!"
|
puts 'Test!'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Crono.perform(TestJob).every 2.days, at: "15:30"
|
Crono.perform(TestJob).every 2.days, at: '15:30'
|
||||||
|
|
||||||
|
|||||||
+11
-10
@@ -1,14 +1,15 @@
|
|||||||
|
# Crono main module
|
||||||
module Crono
|
module Crono
|
||||||
end
|
end
|
||||||
|
|
||||||
require "active_support/all"
|
require 'active_support/all'
|
||||||
require "crono/version"
|
require 'crono/version'
|
||||||
require "crono/logging"
|
require 'crono/logging'
|
||||||
require "crono/period"
|
require 'crono/period'
|
||||||
require "crono/job"
|
require 'crono/job'
|
||||||
require "crono/scheduler"
|
require 'crono/scheduler'
|
||||||
require "crono/config"
|
require 'crono/config'
|
||||||
require "crono/performer_proxy"
|
require 'crono/performer_proxy'
|
||||||
require "crono/orm/active_record/crono_job"
|
require 'crono/orm/active_record/crono_job'
|
||||||
|
|
||||||
Crono.autoload :Web, "crono/web"
|
Crono.autoload :Web, 'crono/web'
|
||||||
|
|||||||
+18
-12
@@ -4,6 +4,7 @@ require 'optparse'
|
|||||||
module Crono
|
module Crono
|
||||||
mattr_accessor :scheduler
|
mattr_accessor :scheduler
|
||||||
|
|
||||||
|
# Crono::CLI - Main class for the crono daemon exacutable `bin/crono`
|
||||||
class CLI
|
class CLI
|
||||||
include Singleton
|
include Singleton
|
||||||
include Logging
|
include Logging
|
||||||
@@ -18,12 +19,7 @@ module Crono
|
|||||||
def run
|
def run
|
||||||
parse_options(ARGV)
|
parse_options(ARGV)
|
||||||
|
|
||||||
if config.daemonize
|
setup_log
|
||||||
set_log_to(config.logfile)
|
|
||||||
daemonize
|
|
||||||
else
|
|
||||||
set_log_to(STDOUT)
|
|
||||||
end
|
|
||||||
|
|
||||||
write_pid
|
write_pid
|
||||||
load_rails
|
load_rails
|
||||||
@@ -33,7 +29,17 @@ module Crono
|
|||||||
start_working_loop
|
start_working_loop
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def setup_log
|
||||||
|
if config.daemonize
|
||||||
|
self.logifile = config.logfile
|
||||||
|
daemonize
|
||||||
|
else
|
||||||
|
self.logfile = STDOUT
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def daemonize
|
def daemonize
|
||||||
::Process.daemon(true, true)
|
::Process.daemon(true, true)
|
||||||
|
|
||||||
@@ -42,7 +48,7 @@ module Crono
|
|||||||
io.sync = true
|
io.sync = true
|
||||||
end
|
end
|
||||||
|
|
||||||
$stdin.reopen("/dev/null")
|
$stdin.reopen('/dev/null')
|
||||||
end
|
end
|
||||||
|
|
||||||
def write_pid
|
def write_pid
|
||||||
@@ -54,16 +60,16 @@ module Crono
|
|||||||
logger.info "Loading Crono #{Crono::VERSION}"
|
logger.info "Loading Crono #{Crono::VERSION}"
|
||||||
logger.info "Running in #{RUBY_DESCRIPTION}"
|
logger.info "Running in #{RUBY_DESCRIPTION}"
|
||||||
|
|
||||||
logger.info "Jobs:"
|
logger.info 'Jobs:'
|
||||||
Crono.scheduler.jobs.each do |job|
|
Crono.scheduler.jobs.each do |job|
|
||||||
logger.info %{"#{job.performer}" with rule "#{job.period.description}" next time will perform at #{job.next}}
|
logger.info %("#{job.performer}" with rule "#{job.period.description}" next time will perform at #{job.next})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_rails
|
def load_rails
|
||||||
ENV['RACK_ENV'] = ENV['RAILS_ENV'] = config.environment
|
ENV['RACK_ENV'] = ENV['RAILS_ENV'] = config.environment
|
||||||
require 'rails'
|
require 'rails'
|
||||||
require File.expand_path("config/environment.rb")
|
require File.expand_path('config/environment.rb')
|
||||||
::Rails.application.eager_load!
|
::Rails.application.eager_load!
|
||||||
require File.expand_path(config.cronotab)
|
require File.expand_path(config.cronotab)
|
||||||
end
|
end
|
||||||
@@ -75,7 +81,7 @@ module Crono
|
|||||||
end
|
end
|
||||||
|
|
||||||
def start_working_loop
|
def start_working_loop
|
||||||
while job = Crono.scheduler.next do
|
while (job = Crono.scheduler.next)
|
||||||
sleep(job.next - Time.now)
|
sleep(job.next - Time.now)
|
||||||
job.perform
|
job.perform
|
||||||
end
|
end
|
||||||
|
|||||||
+5
-4
@@ -1,8 +1,9 @@
|
|||||||
module Crono
|
module Crono
|
||||||
|
# Crono::Config stores Crono configuration
|
||||||
class Config
|
class Config
|
||||||
CRONOTAB = "config/cronotab.rb"
|
CRONOTAB = 'config/cronotab.rb'
|
||||||
LOGFILE = "log/crono.log"
|
LOGFILE = 'log/crono.log'
|
||||||
PIDFILE = "tmp/pids/crono.pid"
|
PIDFILE = 'tmp/pids/crono.pid'
|
||||||
|
|
||||||
attr_accessor :cronotab, :logfile, :pidfile, :daemonize, :environment
|
attr_accessor :cronotab, :logfile, :pidfile, :daemonize, :environment
|
||||||
|
|
||||||
@@ -11,7 +12,7 @@ module Crono
|
|||||||
self.logfile = LOGFILE
|
self.logfile = LOGFILE
|
||||||
self.pidfile = PIDFILE
|
self.pidfile = PIDFILE
|
||||||
self.daemonize = false
|
self.daemonize = false
|
||||||
self.environment = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development"
|
self.environment = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+23
-16
@@ -2,10 +2,12 @@ require 'stringio'
|
|||||||
require 'logger'
|
require 'logger'
|
||||||
|
|
||||||
module Crono
|
module Crono
|
||||||
|
# Crono::Job represents a Crono job
|
||||||
class Job
|
class Job
|
||||||
include Logging
|
include Logging
|
||||||
|
|
||||||
attr_accessor :performer, :period, :last_performed_at, :job_log, :job_logger, :healthy
|
attr_accessor :performer, :period, :last_performed_at, :job_log,
|
||||||
|
:job_logger, :healthy
|
||||||
|
|
||||||
def initialize(performer, period)
|
def initialize(performer, period)
|
||||||
self.performer, self.period = performer, period
|
self.performer, self.period = performer, period
|
||||||
@@ -36,10 +38,14 @@ module Crono
|
|||||||
|
|
||||||
def save
|
def save
|
||||||
@semaphore.synchronize do
|
@semaphore.synchronize do
|
||||||
log = model.reload.log || ""
|
log = model.reload.log || ''
|
||||||
log << job_log.string
|
log << job_log.string
|
||||||
job_log.truncate(job_log.rewind)
|
job_log.truncate(job_log.rewind)
|
||||||
model.update(last_performed_at: last_performed_at, log: log, healthy: healthy)
|
model.update(
|
||||||
|
last_performed_at: last_performed_at,
|
||||||
|
log: log,
|
||||||
|
healthy: healthy
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -47,20 +53,21 @@ module Crono
|
|||||||
self.last_performed_at = model.last_performed_at
|
self.last_performed_at = model.last_performed_at
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def perform_job
|
def perform_job
|
||||||
begin
|
performer.new.perform
|
||||||
performer.new.perform
|
finished_time_sec = format('%.2f', Time.now - last_performed_at)
|
||||||
rescue Exception => e
|
rescue StandardError => e
|
||||||
log_error "Finished #{performer} in %.2f seconds with error: #{e.message}" % (Time.now - last_performed_at)
|
log_error "Finished #{performer} in #{finished_time_sec} seconds"\
|
||||||
log_error e.backtrace.join("\n")
|
"with error: #{e.message}"
|
||||||
self.healthy = false
|
log_error e.backtrace.join("\n")
|
||||||
else
|
self.healthy = false
|
||||||
self.healthy = true
|
else
|
||||||
log "Finished #{performer} in %.2f seconds" % (Time.now - last_performed_at)
|
self.healthy = true
|
||||||
ensure
|
log "Finished #{performer} in #{finished_time_sec} seconds"
|
||||||
save
|
ensure
|
||||||
end
|
save
|
||||||
end
|
end
|
||||||
|
|
||||||
def log_error(message)
|
def log_error(message)
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
module Crono
|
module Crono
|
||||||
mattr_accessor :logger
|
mattr_accessor :logger
|
||||||
|
|
||||||
|
# Crono::Logging is a standart Ruby logger wrapper
|
||||||
module Logging
|
module Logging
|
||||||
def set_log_to(logfile)
|
def logfile=(logfile)
|
||||||
Crono.logger = Logger.new(logfile)
|
Crono.logger = Logger.new(logfile)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
require 'active_record'
|
require 'active_record'
|
||||||
|
|
||||||
module Crono
|
module Crono
|
||||||
|
# Crono::CronoJob is a ActiveRecord model to store job state
|
||||||
class CronoJob < ActiveRecord::Base
|
class CronoJob < ActiveRecord::Base
|
||||||
self.table_name = "crono_jobs"
|
self.table_name = 'crono_jobs'
|
||||||
validates :job_id, presence: true, uniqueness: true
|
validates :job_id, presence: true, uniqueness: true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
module Crono
|
module Crono
|
||||||
|
# PerformerProxy is a proxy used in cronotab.rb semantic
|
||||||
class PerformerProxy
|
class PerformerProxy
|
||||||
def initialize(performer, scheduler)
|
def initialize(performer, scheduler)
|
||||||
@performer = performer
|
@performer = performer
|
||||||
|
|||||||
+6
-4
@@ -1,4 +1,5 @@
|
|||||||
module Crono
|
module Crono
|
||||||
|
# Period describe frequency of performing a task
|
||||||
class Period
|
class Period
|
||||||
def initialize(period, at: nil)
|
def initialize(period, at: nil)
|
||||||
@period = period
|
@period = period
|
||||||
@@ -17,7 +18,7 @@ module Crono
|
|||||||
|
|
||||||
def description
|
def description
|
||||||
desc = "every #{@period.inspect}"
|
desc = "every #{@period.inspect}"
|
||||||
desc += " at %.2i:%.2i" % [@at_hour, @at_min] if @at_hour && @at_min
|
desc += format(' at %.2i:%.2i', @at_hour, @at_min) if @at_hour && @at_min
|
||||||
desc
|
desc
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -29,13 +30,14 @@ module Crono
|
|||||||
when Hash
|
when Hash
|
||||||
return at[:hour], at[:min]
|
return at[:hour], at[:min]
|
||||||
else
|
else
|
||||||
raise "Unknown 'at' format"
|
fail "Unknown 'at' format"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def time_atts
|
def time_atts
|
||||||
{hour: @at_hour, min: @at_min}.compact
|
{ hour: @at_hour, min: @at_min }.compact
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
module Crono
|
module Crono
|
||||||
|
# Scheduler is a container for job list and queue
|
||||||
class Scheduler
|
class Scheduler
|
||||||
attr_accessor :jobs
|
attr_accessor :jobs
|
||||||
|
|
||||||
@@ -15,7 +16,8 @@ module Crono
|
|||||||
queue.first
|
queue.first
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def queue
|
def queue
|
||||||
jobs.sort_by(&:next)
|
jobs.sort_by(&:next)
|
||||||
end
|
end
|
||||||
|
|||||||
+4
-3
@@ -2,10 +2,11 @@ require 'haml'
|
|||||||
require 'sinatra/base'
|
require 'sinatra/base'
|
||||||
|
|
||||||
module Crono
|
module Crono
|
||||||
|
# Web is a Web UI Sinatra app
|
||||||
class Web < Sinatra::Base
|
class Web < Sinatra::Base
|
||||||
set :root, File.expand_path(File.dirname(__FILE__) + "/../../web")
|
set :root, File.expand_path(File.dirname(__FILE__) + '/../../web')
|
||||||
set :public_folder, Proc.new { "#{root}/assets" }
|
set :public_folder, proc { "#{root}/assets" }
|
||||||
set :views, Proc.new { "#{root}/views" }
|
set :views, proc { "#{root}/views" }
|
||||||
|
|
||||||
get '/' do
|
get '/' do
|
||||||
@jobs = Crono::CronoJob.all
|
@jobs = Crono::CronoJob.all
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ module Crono
|
|||||||
ActiveRecord::Generators::Base.next_migration_number(path)
|
ActiveRecord::Generators::Base.next_migration_number(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
desc "Installs crono and generates the necessary configuration files"
|
desc 'Installs crono and generates the necessary configuration files'
|
||||||
source_root File.expand_path("../templates", __FILE__)
|
source_root File.expand_path('../templates', __FILE__)
|
||||||
|
|
||||||
def copy_config
|
def copy_config
|
||||||
template 'cronotab.rb.erb', 'config/cronotab.rb'
|
template 'cronotab.rb.erb', 'config/cronotab.rb'
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
#
|
#
|
||||||
# class TestJob
|
# class TestJob
|
||||||
# def perform
|
# def perform
|
||||||
# puts "Test!"
|
# puts 'Test!'
|
||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
# Crono.perform(TestJob).every 2.days, at: "15:30"
|
# Crono.perform(TestJob).every 2.days, at: '15:30'
|
||||||
#
|
#
|
||||||
|
|||||||
+22
-21
@@ -1,15 +1,16 @@
|
|||||||
require "spec_helper"
|
require 'spec_helper'
|
||||||
require 'crono/cli'
|
require 'crono/cli'
|
||||||
|
|
||||||
class TestJob
|
class TestJob
|
||||||
def perform;end
|
def perform
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Crono::CLI do
|
describe Crono::CLI do
|
||||||
let(:cli) { Crono::CLI.instance }
|
let(:cli) { Crono::CLI.instance }
|
||||||
|
|
||||||
describe "#run" do
|
describe '#run' do
|
||||||
it "should try to initialize rails with #load_rails and start working loop" do
|
it 'should initialize rails with #load_rails and start working loop' do
|
||||||
expect(cli).to receive(:load_rails)
|
expect(cli).to receive(:load_rails)
|
||||||
expect(cli).to receive(:start_working_loop)
|
expect(cli).to receive(:start_working_loop)
|
||||||
expect(cli).to receive(:parse_options)
|
expect(cli).to receive(:parse_options)
|
||||||
@@ -18,34 +19,34 @@ describe Crono::CLI do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#start_working_loop" do
|
describe '#start_working_loop' do
|
||||||
it "should start working loop"
|
it 'should start working loop'
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#parse_options" do
|
describe '#parse_options' do
|
||||||
it "should set cronotab" do
|
it 'should set cronotab' do
|
||||||
cli.send(:parse_options, ["--cronotab", "/tmp/cronotab.rb"])
|
cli.send(:parse_options, ['--cronotab', '/tmp/cronotab.rb'])
|
||||||
expect(cli.config.cronotab).to be_eql "/tmp/cronotab.rb"
|
expect(cli.config.cronotab).to be_eql '/tmp/cronotab.rb'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should set logfile" do
|
it 'should set logfile' do
|
||||||
cli.send(:parse_options, ["--logfile", "log/crono.log"])
|
cli.send(:parse_options, ['--logfile', 'log/crono.log'])
|
||||||
expect(cli.config.logfile).to be_eql "log/crono.log"
|
expect(cli.config.logfile).to be_eql 'log/crono.log'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should set pidfile" do
|
it 'should set pidfile' do
|
||||||
cli.send(:parse_options, ["--pidfile", "tmp/pids/crono.0.log"])
|
cli.send(:parse_options, ['--pidfile', 'tmp/pids/crono.0.log'])
|
||||||
expect(cli.config.pidfile).to be_eql "tmp/pids/crono.0.log"
|
expect(cli.config.pidfile).to be_eql 'tmp/pids/crono.0.log'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should set daemonize" do
|
it 'should set daemonize' do
|
||||||
cli.send(:parse_options, ["--daemonize"])
|
cli.send(:parse_options, ['--daemonize'])
|
||||||
expect(cli.config.daemonize).to be true
|
expect(cli.config.daemonize).to be true
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should set environment" do
|
it 'should set environment' do
|
||||||
cli.send(:parse_options, ["--environment", "production"])
|
cli.send(:parse_options, ['--environment', 'production'])
|
||||||
expect(cli.config.environment).to be_eql("production")
|
expect(cli.config.environment).to be_eql('production')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+5
-5
@@ -1,15 +1,15 @@
|
|||||||
require "spec_helper"
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Crono::Config do
|
describe Crono::Config do
|
||||||
describe "#initialize" do
|
describe '#initialize' do
|
||||||
it "should initialize with default configuration options" do
|
it 'should initialize with default configuration options' do
|
||||||
ENV["RAILS_ENV"] = "test"
|
ENV['RAILS_ENV'] = 'test'
|
||||||
@config = Crono::Config.new
|
@config = Crono::Config.new
|
||||||
expect(@config.cronotab).to be Crono::Config::CRONOTAB
|
expect(@config.cronotab).to be Crono::Config::CRONOTAB
|
||||||
expect(@config.logfile).to be Crono::Config::LOGFILE
|
expect(@config.logfile).to be Crono::Config::LOGFILE
|
||||||
expect(@config.pidfile).to be Crono::Config::PIDFILE
|
expect(@config.pidfile).to be Crono::Config::PIDFILE
|
||||||
expect(@config.daemonize).to be false
|
expect(@config.daemonize).to be false
|
||||||
expect(@config.environment).to be_eql ENV["RAILS_ENV"]
|
expect(@config.environment).to be_eql ENV['RAILS_ENV']
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+31
-30
@@ -1,12 +1,13 @@
|
|||||||
require "spec_helper"
|
require 'spec_helper'
|
||||||
|
|
||||||
class TestJob
|
class TestJob
|
||||||
def perform;end
|
def perform
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class TestFailingJob
|
class TestFailingJob
|
||||||
def perform
|
def perform
|
||||||
raise "Some error"
|
fail 'Some error'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -15,52 +16,52 @@ describe Crono::Job do
|
|||||||
let(:job) { Crono::Job.new(TestJob, period) }
|
let(:job) { Crono::Job.new(TestJob, period) }
|
||||||
let(:failing_job) { Crono::Job.new(TestFailingJob, period) }
|
let(:failing_job) { Crono::Job.new(TestFailingJob, period) }
|
||||||
|
|
||||||
it "should contain performer and period" do
|
it 'should contain performer and period' do
|
||||||
expect(job.performer).to be TestJob
|
expect(job.performer).to be TestJob
|
||||||
expect(job.period).to be period
|
expect(job.period).to be period
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#perform" do
|
describe '#perform' do
|
||||||
after { job.send(:model).destroy }
|
after { job.send(:model).destroy }
|
||||||
|
|
||||||
it "should run performer in separate thread" do
|
it 'should run performer in separate thread' do
|
||||||
expect(job).to receive(:save)
|
expect(job).to receive(:save)
|
||||||
thread = job.perform.join
|
thread = job.perform.join
|
||||||
expect(thread).to be_stop
|
expect(thread).to be_stop
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should save performin errors to log" do
|
it 'should save performin errors to log' do
|
||||||
thread = failing_job.perform.join
|
thread = failing_job.perform.join
|
||||||
expect(thread).to be_stop
|
expect(thread).to be_stop
|
||||||
saved_log = Crono::CronoJob.find_by(job_id: failing_job.job_id).log
|
saved_log = Crono::CronoJob.find_by(job_id: failing_job.job_id).log
|
||||||
expect(saved_log).to include "Some error"
|
expect(saved_log).to include 'Some error'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should set Job#healthy to true if perform ok" do
|
it 'should set Job#healthy to true if perform ok' do
|
||||||
thread = job.perform.join
|
job.perform.join
|
||||||
expect(job.healthy).to be true
|
expect(job.healthy).to be true
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should set Job#healthy to false if perform with error" do
|
it 'should set Job#healthy to false if perform with error' do
|
||||||
thread = failing_job.perform.join
|
failing_job.perform.join
|
||||||
expect(failing_job.healthy).to be false
|
expect(failing_job.healthy).to be false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#description" do
|
describe '#description' do
|
||||||
it "should return job identificator" do
|
it 'should return job identificator' do
|
||||||
expect(job.description).to be_eql("Perform TestJob every 2 days")
|
expect(job.description).to be_eql('Perform TestJob every 2 days')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#save" do
|
describe '#save' do
|
||||||
it "should save new job to DB" do
|
it 'should save new job to DB' do
|
||||||
expect(Crono::CronoJob.where(job_id: job.job_id)).to_not exist
|
expect(Crono::CronoJob.where(job_id: job.job_id)).to_not exist
|
||||||
job.save
|
job.save
|
||||||
expect(Crono::CronoJob.where(job_id: job.job_id)).to exist
|
expect(Crono::CronoJob.where(job_id: job.job_id)).to exist
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should update saved job" do
|
it 'should update saved job' do
|
||||||
job.last_performed_at = Time.now
|
job.last_performed_at = Time.now
|
||||||
job.healthy = true
|
job.healthy = true
|
||||||
job.save
|
job.save
|
||||||
@@ -69,8 +70,8 @@ describe Crono::Job do
|
|||||||
expect(@crono_job.healthy).to be true
|
expect(@crono_job.healthy).to be true
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should save and truncate job log" do
|
it 'should save and truncate job log' do
|
||||||
message = "test message"
|
message = 'test message'
|
||||||
job.send(:log, message)
|
job.send(:log, message)
|
||||||
job.save
|
job.save
|
||||||
expect(job.send(:model).reload.log).to include message
|
expect(job.send(:model).reload.log).to include message
|
||||||
@@ -78,37 +79,37 @@ describe Crono::Job do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#load" do
|
describe '#load' do
|
||||||
before do
|
before do
|
||||||
@saved_last_performed_at = job.last_performed_at = Time.now
|
@saved_last_performed_at = job.last_performed_at = Time.now
|
||||||
job.save
|
job.save
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should load last_performed_at from DB" do
|
it 'should load last_performed_at from DB' do
|
||||||
@job = Crono::Job.new(TestJob, period)
|
@job = Crono::Job.new(TestJob, period)
|
||||||
@job.load
|
@job.load
|
||||||
expect(@job.last_performed_at.utc.to_s).to be_eql @saved_last_performed_at.utc.to_s
|
expect(@job.last_performed_at.utc.to_s).to be_eql @saved_last_performed_at.utc.to_s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#log" do
|
describe '#log' do
|
||||||
it "should write log messages to both common and job log" do
|
it 'should write log messages to both common and job log' do
|
||||||
message = "Test message"
|
message = 'Test message'
|
||||||
expect(job.logger).to receive(:log).with(Logger::INFO, message)
|
expect(job.logger).to receive(:log).with(Logger::INFO, message)
|
||||||
expect(job.job_logger).to receive(:log).with(Logger::INFO, message)
|
expect(job.job_logger).to receive(:log).with(Logger::INFO, message)
|
||||||
job.send(:log, message)
|
job.send(:log, message)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should write job log to Job#job_log" do
|
it 'should write job log to Job#job_log' do
|
||||||
message = "Test message"
|
message = 'Test message'
|
||||||
job.send(:log, message)
|
job.send(:log, message)
|
||||||
expect(job.job_log.string).to include(message)
|
expect(job.job_log.string).to include(message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#log_error" do
|
describe '#log_error' do
|
||||||
it "should call log with ERROR severity" do
|
it 'should call log with ERROR severity' do
|
||||||
message = "Test message"
|
message = 'Test message'
|
||||||
expect(job).to receive(:log).with(message, Logger::ERROR)
|
expect(job).to receive(:log).with(message, Logger::ERROR)
|
||||||
job.send(:log_error, message)
|
job.send(:log_error, message)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
require "spec_helper"
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Crono::CronoJob do
|
describe Crono::CronoJob do
|
||||||
let(:valid_attrs) do
|
let(:valid_attrs) do
|
||||||
{
|
{
|
||||||
job_id: "Perform TestJob every 3 days"
|
job_id: 'Perform TestJob every 3 days'
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should validate presence of job_id" do
|
it 'should validate presence of job_id' do
|
||||||
@crono_job = Crono::CronoJob.new()
|
@crono_job = Crono::CronoJob.new
|
||||||
expect(@crono_job).not_to be_valid
|
expect(@crono_job).not_to be_valid
|
||||||
expect(@crono_job.errors.added?(:job_id, :blank)).to be true
|
expect(@crono_job.errors.added?(:job_id, :blank)).to be true
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should validate uniqueness of job_id" do
|
it 'should validate uniqueness of job_id' do
|
||||||
Crono::CronoJob.create!(job_id: "TestJob every 2 days")
|
Crono::CronoJob.create!(job_id: 'TestJob every 2 days')
|
||||||
@crono_job = Crono::CronoJob.create(job_id: "TestJob every 2 days")
|
@crono_job = Crono::CronoJob.create(job_id: 'TestJob every 2 days')
|
||||||
expect(@crono_job).not_to be_valid
|
expect(@crono_job).not_to be_valid
|
||||||
expect(@crono_job.errors.added?(:job_id, :taken)).to be true
|
expect(@crono_job.errors.added?(:job_id, :taken)).to be true
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should save job_id to DB" do
|
it 'should save job_id to DB' do
|
||||||
Crono::CronoJob.create!(valid_attrs)
|
Crono::CronoJob.create!(valid_attrs)
|
||||||
@crono_job = Crono::CronoJob.find_by(job_id: valid_attrs[:job_id])
|
@crono_job = Crono::CronoJob.find_by(job_id: valid_attrs[:job_id])
|
||||||
expect(@crono_job).to be_present
|
expect(@crono_job).to be_present
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
require "spec_helper"
|
require 'spec_helper'
|
||||||
|
|
||||||
class TestJob
|
class TestJob
|
||||||
def perform;end
|
def perform
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Crono::PerformerProxy do
|
describe Crono::PerformerProxy do
|
||||||
it "should add job to schedule" do
|
it 'should add job to schedule' do
|
||||||
expect(Crono.scheduler).to receive(:add_job).with(kind_of(Crono::Job))
|
expect(Crono.scheduler).to receive(:add_job).with(kind_of(Crono::Job))
|
||||||
Crono.perform(TestJob).every(2.days, at: "15:30")
|
Crono.perform(TestJob).every(2.days, at: '15:30')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+15
-14
@@ -1,4 +1,4 @@
|
|||||||
require "spec_helper"
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Crono::Period do
|
describe Crono::Period do
|
||||||
around(:each) do |example|
|
around(:each) do |example|
|
||||||
@@ -7,47 +7,48 @@ describe Crono::Period do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#description" do
|
describe '#description' do
|
||||||
it "should return period description" do
|
it 'should return period description' do
|
||||||
@period = Crono::Period.new(2.day, at: "15:20")
|
@period = Crono::Period.new(2.day, at: '15:20')
|
||||||
expect(@period.description).to be_eql("every 2 days at 15:20")
|
expect(@period.description).to be_eql('every 2 days at 15:20')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#next" do
|
describe '#next' do
|
||||||
context "in daily basis" do
|
context 'in daily basis' do
|
||||||
it "should return the time 2 days from now" do
|
it 'should return the time 2 days from now' do
|
||||||
@period = Crono::Period.new(2.day)
|
@period = Crono::Period.new(2.day)
|
||||||
expect(@period.next).to be_eql(2.day.from_now)
|
expect(@period.next).to be_eql(2.day.from_now)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should set time to 'at' time as a string" do
|
it "should set time to 'at' time as a string" do
|
||||||
time = 10.minutes.ago
|
time = 10.minutes.ago
|
||||||
@period = Crono::Period.new(2.day, at: [time.hour, time.min].join(':'))
|
at = [time.hour, time.min].join(':')
|
||||||
|
@period = Crono::Period.new(2.day, at: at)
|
||||||
expect(@period.next).to be_eql(2.day.from_now.change(hour: time.hour, min: time.min))
|
expect(@period.next).to be_eql(2.day.from_now.change(hour: time.hour, min: time.min))
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should set time to 'at' time as a hash" do
|
it "should set time to 'at' time as a hash" do
|
||||||
time = 10.minutes.ago
|
time = 10.minutes.ago
|
||||||
at = {hour: time.hour, min: time.min}
|
at = { hour: time.hour, min: time.min }
|
||||||
@period = Crono::Period.new(2.day, at: at)
|
@period = Crono::Period.new(2.day, at: at)
|
||||||
expect(@period.next).to be_eql(2.day.from_now.change(at))
|
expect(@period.next).to be_eql(2.day.from_now.change(at))
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should raise error when 'at' is wrong" do
|
it "should raise error when 'at' is wrong" do
|
||||||
expect {
|
expect {
|
||||||
@period = Crono::Period.new(2.day, at: 1)
|
Crono::Period.new(2.day, at: 1)
|
||||||
}.to raise_error("Unknown 'at' format")
|
}.to raise_error("Unknown 'at' format")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return time in relation to last time" do
|
it 'should return time in relation to last time' do
|
||||||
@period = Crono::Period.new(2.day)
|
@period = Crono::Period.new(2.day)
|
||||||
expect(@period.next(since: 1.day.ago)).to be_eql(1.day.from_now)
|
expect(@period.next(since: 1.day.ago)).to be_eql(1.day.from_now)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return today time if it is first run and not too late" do
|
it 'should return today time if it is first run and not too late' do
|
||||||
time = 10.minutes.from_now
|
time = 10.minutes.from_now
|
||||||
at = {hour: time.hour, min: time.min}
|
at = { hour: time.hour, min: time.min }
|
||||||
@period = Crono::Period.new(2.day, at: at)
|
@period = Crono::Period.new(2.day, at: at)
|
||||||
expect(@period.next.utc.to_s).to be_eql(Time.now.change(at).utc.to_s)
|
expect(@period.next.utc.to_s).to be_eql(Time.now.change(at).utc.to_s)
|
||||||
end
|
end
|
||||||
|
|||||||
+11
-10
@@ -1,30 +1,31 @@
|
|||||||
require "spec_helper"
|
require 'spec_helper'
|
||||||
|
|
||||||
class TestJob
|
class TestJob
|
||||||
def perform;end
|
def perform
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe Crono::Scheduler do
|
describe Crono::Scheduler do
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@scheduler = Crono::Scheduler.new
|
@scheduler = Crono::Scheduler.new
|
||||||
@jobs = [
|
@jobs = [
|
||||||
Crono::Period.new(3.day, at: 10.minutes.from_now.strftime("%H:%M")),
|
Crono::Period.new(3.day, at: 10.minutes.from_now.strftime('%H:%M')),
|
||||||
Crono::Period.new(1.day, at: 20.minutes.from_now.strftime("%H:%M")),
|
Crono::Period.new(1.day, at: 20.minutes.from_now.strftime('%H:%M')),
|
||||||
Crono::Period.new(7.day, at: 40.minutes.from_now.strftime("%H:%M"))
|
Crono::Period.new(7.day, at: 40.minutes.from_now.strftime('%H:%M'))
|
||||||
].map { |period| Crono::Job.new(TestJob, period) }
|
].map { |period| Crono::Job.new(TestJob, period) }
|
||||||
@scheduler.jobs = @jobs
|
@scheduler.jobs = @jobs
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#add_job" do
|
describe '#add_job' do
|
||||||
it "should call Job#load on Job" do
|
it 'should call Job#load on Job' do
|
||||||
@job = Crono::Job.new(TestJob, Crono::Period.new(10.day, at: "04:05"))
|
@job = Crono::Job.new(TestJob, Crono::Period.new(10.day, at: '04:05'))
|
||||||
expect(@job).to receive(:load)
|
expect(@job).to receive(:load)
|
||||||
@scheduler.add_job(@job)
|
@scheduler.add_job(@job)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#next" do
|
describe '#next' do
|
||||||
it "should return next job in schedule" do
|
it 'should return next job in schedule' do
|
||||||
expect(@scheduler.next).to be @jobs[0]
|
expect(@scheduler.next).to be @jobs[0]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+5
-4
@@ -6,9 +6,10 @@ require 'byebug'
|
|||||||
require 'crono'
|
require 'crono'
|
||||||
require 'generators/crono/install/templates/migrations/create_crono_jobs.rb'
|
require 'generators/crono/install/templates/migrations/create_crono_jobs.rb'
|
||||||
|
|
||||||
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: "file::memory:?cache=shared")
|
ActiveRecord::Base.establish_connection(
|
||||||
|
adapter: 'sqlite3',
|
||||||
|
database: 'file::memory:?cache=shared'
|
||||||
|
)
|
||||||
|
|
||||||
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
||||||
CreateCronoJobs.up
|
CreateCronoJobs.up
|
||||||
|
|
||||||
RSpec.configure do |config|
|
|
||||||
end
|
|
||||||
|
|||||||
+16
-13
@@ -1,44 +1,47 @@
|
|||||||
require "spec_helper"
|
require 'spec_helper'
|
||||||
require "rack/test"
|
require 'rack/test'
|
||||||
include Rack::Test::Methods
|
include Rack::Test::Methods
|
||||||
|
|
||||||
describe Crono::Web do
|
describe Crono::Web do
|
||||||
let(:app) { Crono::Web }
|
let(:app) { Crono::Web }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
@test_job_id = "Perform TestJob every 5 seconds"
|
@test_job_id = 'Perform TestJob every 5 seconds'
|
||||||
@test_job_log = "All runs ok"
|
@test_job_log = 'All runs ok'
|
||||||
@test_job = Crono::CronoJob.create!(job_id: @test_job_id, log: @test_job_log)
|
@test_job = Crono::CronoJob.create!(
|
||||||
|
job_id: @test_job_id,
|
||||||
|
log: @test_job_log
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
after { @test_job.destroy }
|
after { @test_job.destroy }
|
||||||
|
|
||||||
describe "/" do
|
describe '/' do
|
||||||
it "should show all jobs" do
|
it 'should show all jobs' do
|
||||||
get '/'
|
get '/'
|
||||||
expect(last_response).to be_ok
|
expect(last_response).to be_ok
|
||||||
expect(last_response.body).to include @test_job_id
|
expect(last_response.body).to include @test_job_id
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should show a error mark when a job is unhealthy" do
|
it 'should show a error mark when a job is unhealthy' do
|
||||||
@test_job.update(healthy: false)
|
@test_job.update(healthy: false)
|
||||||
get '/'
|
get '/'
|
||||||
expect(last_response.body).to include "Error"
|
expect(last_response.body).to include 'Error'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "/job/:id" do
|
describe '/job/:id' do
|
||||||
it "should show job log" do
|
it 'should show job log' do
|
||||||
get "/job/#{@test_job.id}"
|
get "/job/#{@test_job.id}"
|
||||||
expect(last_response).to be_ok
|
expect(last_response).to be_ok
|
||||||
expect(last_response.body).to include @test_job_id
|
expect(last_response.body).to include @test_job_id
|
||||||
expect(last_response.body).to include @test_job_log
|
expect(last_response.body).to include @test_job_log
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should show a message about the unhealthy job" do
|
it 'should show a message about the unhealthy job' do
|
||||||
@test_job.update(healthy: false)
|
@test_job.update(healthy: false)
|
||||||
get "/job/#{@test_job.id}"
|
get "/job/#{@test_job.id}"
|
||||||
expect(last_response.body).to include "An error occurs during the last execution of this job"
|
expect(last_response.body).to include 'An error occurs during the last execution of this job'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user