crono 0.8.1 → 0.8.6.pre

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2fe5cc8fdfa89bc633c58c8f83c5c7f324753a97
4
- data.tar.gz: 59cd54c8f5dfc6ab98ea2969aab1c9821528e426
3
+ metadata.gz: be29ba1f77be7b2a7e34adc2f5992cb9d089ab02
4
+ data.tar.gz: 07e04cc2905f189ab7fbe5476b35baae88cd87d6
5
5
  SHA512:
6
- metadata.gz: d3d4c392b0d88d5c11d5eee6a1a138bfcda13c81369bacfa6400beeb87eef6a38e04184127d6f0f051ecc916ec577d066683a274ae0df2d49f2a75b3745a7ec4
7
- data.tar.gz: b2b03f125d780069004609f23dd95b3fb9d044e9aa3003a573a6d61016a6260a20ecdf8ebc6f8157facda0602613d297407c57d11a1bbb3334a63d4f9b8ecb21
6
+ metadata.gz: 83e0d5819ca476cc01efeec03b2f6744faa4501d9d0aef519776691796544e707241df2ec336348a7e8a4dc1531f254acc0b8e36a703fff9b3050613abe9d7a6
7
+ data.tar.gz: 12b9f8590c609f441829feb50be8c20e94f7de36298bf7563c3461e069b221f6bb13435210147cef80c96f64d2b503b2829c87953b26ecf9010d1e4973a42ec3
data/.gitignore CHANGED
@@ -1,4 +1,8 @@
1
- pkg/*
2
- *.gem
3
- .bundle
4
- tmp/*.sqlite3
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.rspec CHANGED
@@ -1,2 +1,2 @@
1
- --color
2
1
  --format documentation
2
+ --color
data/Gemfile CHANGED
@@ -1,2 +1,4 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in crono.gemspec
2
4
  gemspec
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- crono (0.8.0)
4
+ crono (0.8.6.pre)
5
5
  activejob (~> 4.0)
6
6
  activerecord (~> 4.0)
7
7
  activesupport (~> 4.0)
@@ -9,17 +9,17 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- activejob (4.2.0)
13
- activesupport (= 4.2.0)
12
+ activejob (4.2.1)
13
+ activesupport (= 4.2.1)
14
14
  globalid (>= 0.3.0)
15
- activemodel (4.2.0)
16
- activesupport (= 4.2.0)
15
+ activemodel (4.2.1)
16
+ activesupport (= 4.2.1)
17
17
  builder (~> 3.1)
18
- activerecord (4.2.0)
19
- activemodel (= 4.2.0)
20
- activesupport (= 4.2.0)
18
+ activerecord (4.2.1)
19
+ activemodel (= 4.2.1)
20
+ activesupport (= 4.2.1)
21
21
  arel (~> 6.0)
22
- activesupport (4.2.0)
22
+ activesupport (4.2.1)
23
23
  i18n (~> 0.7)
24
24
  json (~> 1.7, >= 1.7.7)
25
25
  minitest (~> 5.1)
@@ -27,14 +27,11 @@ GEM
27
27
  tzinfo (~> 1.1)
28
28
  arel (6.0.0)
29
29
  builder (3.2.2)
30
- byebug (3.5.1)
31
- columnize (~> 0.8)
32
- debugger-linecache (~> 1.2)
33
- slop (~> 3.6)
30
+ byebug (4.0.5)
31
+ columnize (= 0.9.0)
34
32
  columnize (0.9.0)
35
- debugger-linecache (1.2.0)
36
33
  diff-lcs (1.2.5)
37
- globalid (0.3.3)
34
+ globalid (0.3.5)
38
35
  activesupport (>= 4.1.0)
39
36
  haml (4.0.6)
40
37
  tilt
@@ -51,7 +48,7 @@ GEM
51
48
  rspec-core (~> 3.2.0)
52
49
  rspec-expectations (~> 3.2.0)
53
50
  rspec-mocks (~> 3.2.0)
54
- rspec-core (3.2.1)
51
+ rspec-core (3.2.2)
55
52
  rspec-support (~> 3.2.0)
56
53
  rspec-expectations (3.2.0)
57
54
  diff-lcs (>= 1.2.0, < 2.0)
@@ -64,7 +61,6 @@ GEM
64
61
  rack (~> 1.4)
65
62
  rack-protection (~> 1.4)
66
63
  tilt (~> 1.3, >= 1.3.4)
67
- slop (3.6.0)
68
64
  sqlite3 (1.3.10)
69
65
  thread_safe (0.3.5)
70
66
  tilt (1.4.1)
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  Crono — Job scheduler for Rails
2
2
  ------------------------
3
- [![Gem Version](https://badge.fury.io/rb/crono.svg)](http://badge.fury.io/rb/crono)Here's an example of a test job:
4
-
5
-
3
+ [![Gem Version](https://badge.fury.io/rb/crono.svg)](http://badge.fury.io/rb/crono)
6
4
  [![Build Status](https://travis-ci.org/plashchynski/crono.svg?branch=master)](https://travis-ci.org/plashchynski/crono)
7
5
  [![Code Climate](https://codeclimate.com/github/plashchynski/crono/badges/gpa.svg)](https://codeclimate.com/github/plashchynski/crono)
8
6
  [![security](https://hakiri.io/github/plashchynski/crono/master.svg)](https://hakiri.io/github/plashchynski/crono/master)
@@ -74,6 +72,33 @@ class TestJob # This is not an Active Job job, but pretty legal Crono job.
74
72
  end
75
73
  ```
76
74
 
75
+ Here's an example of a Rake Task within a job:
76
+
77
+ ```ruby
78
+ # config/cronotab.rb
79
+ require 'rake'
80
+ # Be sure to change AppName to your application name!
81
+ AppName::Application.load_tasks
82
+
83
+ class Test
84
+ def perform
85
+ Rake::Task['crono:hello'].invoke
86
+ end
87
+ end
88
+
89
+ Crono.perform(Test).every 5.seconds
90
+ ```
91
+ With the rake task of:
92
+ ```Ruby
93
+ # lib/tasks/test.rake
94
+ namespace :crono do
95
+ desc 'Update all tables'
96
+ task :hello => :environment do
97
+ puts "hello"
98
+ end
99
+ end
100
+ ```
101
+
77
102
  _Please note that crono uses threads, so your code should be thread-safe_
78
103
 
79
104
  #### Job Schedule
@@ -122,7 +147,7 @@ Crono comes with a Sinatra application that can display the current state of Cro
122
147
  Add `sinatra` and `haml` to your Gemfile
123
148
 
124
149
  ```ruby
125
- gam 'haml'
150
+ gem 'haml'
126
151
  gem 'sinatra', require: nil
127
152
  ```
128
153
 
data/Rakefile CHANGED
@@ -1,5 +1,4 @@
1
- require 'bundler'
2
- Bundler::GemHelper.install_tasks
1
+ require 'bundler/gem_tasks'
3
2
 
4
3
  require 'rspec/core/rake_task'
5
4
  RSpec::Core::RakeTask.new('spec')
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "crono"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -1,32 +1,34 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/crono/version', __FILE__)
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'crono/version'
3
5
 
4
- Gem::Specification.new do |s|
5
- s.name = 'crono'
6
- s.version = Crono::VERSION
7
- s.authors = ['Dzmitry Plashchynski']
8
- s.email = ['plashchynski@gmail.com']
9
- s.homepage = 'https://github.com/plashchynski/crono'
10
- s.description = s.summary = 'Job scheduler for Rails'
11
- s.license = 'Apache-2.0'
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'crono'
8
+ spec.version = Crono::VERSION
9
+ spec.authors = ['Dzmitry Plashchynski']
10
+ spec.email = ['plashchynski@gmail.com']
12
11
 
13
- s.required_rubygems_version = '>= 1.3.6'
14
- s.rubyforge_project = 'crono'
12
+ spec.summary = 'Job scheduler for Rails'
13
+ spec.description = 'A time-based background job scheduler daemon (just like Cron) for Rails'
14
+ spec.homepage = 'https://github.com/plashchynski/crono'
15
+ spec.license = 'Apache-2.0'
15
16
 
16
- s.add_runtime_dependency 'activejob', '~> 4.0'
17
- s.add_runtime_dependency 'activesupport', '~> 4.0'
18
- s.add_runtime_dependency 'activerecord', '~> 4.0'
19
- s.add_development_dependency 'rake', '~> 10.0'
20
- s.add_development_dependency 'bundler', '>= 1.0.0'
21
- s.add_development_dependency 'rspec', '~> 3.0'
22
- s.add_development_dependency 'timecop', '~> 0.7'
23
- s.add_development_dependency 'sqlite3'
24
- s.add_development_dependency 'byebug'
25
- s.add_development_dependency 'sinatra'
26
- s.add_development_dependency 'haml'
27
- s.add_development_dependency 'rack-test'
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = 'exe' # http://bundler.io/blog/2015/03/20/moving-bins-to-exe.html
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
28
21
 
29
- s.files = `git ls-files`.split("\n")
30
- s.executables = ['crono']
31
- s.require_path = 'lib'
22
+ spec.add_runtime_dependency 'activejob', '~> 4.0'
23
+ spec.add_runtime_dependency 'activesupport', '~> 4.0'
24
+ spec.add_runtime_dependency 'activerecord', '~> 4.0'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'bundler', '>= 1.0.0'
27
+ spec.add_development_dependency 'rspec', '~> 3.0'
28
+ spec.add_development_dependency 'timecop', '~> 0.7'
29
+ spec.add_development_dependency 'sqlite3'
30
+ spec.add_development_dependency 'byebug'
31
+ spec.add_development_dependency 'sinatra'
32
+ spec.add_development_dependency 'haml'
33
+ spec.add_development_dependency 'rack-test'
32
34
  end
File without changes
@@ -50,6 +50,7 @@ module Crono
50
50
  end
51
51
 
52
52
  def write_pid
53
+ return unless config.pidfile
53
54
  pidfile = File.expand_path(config.pidfile)
54
55
  File.write(pidfile, ::Process.pid)
55
56
  end
@@ -61,7 +62,7 @@ module Crono
61
62
  logger.info 'Jobs:'
62
63
  Crono.scheduler.jobs.each do |job|
63
64
  logger.info "'#{job.performer}' with rule '#{job.period.description}'"\
64
- "next time will perform at #{job.next}"
65
+ " next time will perform at #{job.next}"
65
66
  end
66
67
  end
67
68
 
@@ -79,9 +80,10 @@ module Crono
79
80
  end
80
81
 
81
82
  def start_working_loop
82
- while (job = Crono.scheduler.next)
83
- sleep(job.next - Time.now)
84
- job.perform
83
+ loop do
84
+ next_time, jobs = Crono.scheduler.next_jobs
85
+ sleep(next_time - Time.now)
86
+ jobs.each(&:perform)
85
87
  end
86
88
  end
87
89
 
@@ -10,9 +10,12 @@ module Crono
10
10
  def initialize
11
11
  self.cronotab = CRONOTAB
12
12
  self.logfile = LOGFILE
13
- self.pidfile = PIDFILE
14
13
  self.daemonize = false
15
14
  self.environment = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
16
15
  end
16
+
17
+ def pidfile
18
+ @pidfile || (daemonize ? PIDFILE : nil)
19
+ end
17
20
  end
18
21
  end
@@ -17,8 +17,7 @@ module Crono
17
17
  end
18
18
 
19
19
  def next
20
- next_time = period.next(since: last_performed_at)
21
- next_time.past? ? period.next : next_time
20
+ period.next(since: last_performed_at)
22
21
  end
23
22
 
24
23
  def description
@@ -61,9 +60,7 @@ module Crono
61
60
  end
62
61
 
63
62
  def perform_job
64
- performer_instance = performer.new
65
- performer_instance.instance_variable_set(:@_crono_job, self)
66
- performer_instance.perform
63
+ performer.new.perform
67
64
  finished_time_sec = format('%.2f', Time.now - last_performed_at)
68
65
  rescue StandardError => e
69
66
  handle_job_fail(e, finished_time_sec)
@@ -1,5 +1,5 @@
1
1
  module Crono
2
- # Period describe frequency of performing a task
2
+ # Period describe frequency of jobs
3
3
  class Period
4
4
  DAYS = [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday,
5
5
  :sunday]
@@ -14,7 +14,9 @@ module Crono
14
14
  return initial_next unless since
15
15
  @next = @period.since(since)
16
16
  @next = @next.beginning_of_week.advance(days: @on) if @on
17
- @next.change(time_atts)
17
+ @next = @next.change(time_atts)
18
+ return @next if @next.future?
19
+ Time.now
18
20
  end
19
21
 
20
22
  def description
@@ -12,14 +12,8 @@ module Crono
12
12
  jobs << job
13
13
  end
14
14
 
15
- def next
16
- queue.first
17
- end
18
-
19
- private
20
-
21
- def queue
22
- jobs.sort_by(&:next)
15
+ def next_jobs
16
+ jobs.group_by(&:next).sort_by {|time,_| time }.first
23
17
  end
24
18
  end
25
19
 
@@ -1,3 +1,3 @@
1
1
  module Crono
2
- VERSION = '0.8.1'
2
+ VERSION = '0.8.6.pre'
3
3
  end
@@ -6,7 +6,7 @@
6
6
  %tr
7
7
  %th Job
8
8
  %th Last performed at
9
- %th
9
+ %th Status
10
10
  %th
11
11
  - @jobs.each do |job|
12
12
  %tr
@@ -16,6 +16,12 @@
16
16
  - if job.healthy == false
17
17
  %a{ href: url("/job/#{job.id}") }
18
18
  %span.label.label-danger Error
19
+ - if job.healthy == true
20
+ %a{ href: url("/job/#{job.id}") }
21
+ %span.label.label-success Success
22
+ - else
23
+ %a{ href: url("/job/#{job.id}") }
24
+ %span.label.label-default Pending
19
25
  %td
20
26
  %a{ href: url("/job/#{job.id}") }
21
27
  Log
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crono
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.6.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dzmitry Plashchynski
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2015-03-22 00:00:00.000000000 Z
11
+ date: 2015-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -178,7 +178,7 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
- description: Job scheduler for Rails
181
+ description: A time-based background job scheduler daemon (just like Cron) for Rails
182
182
  email:
183
183
  - plashchynski@gmail.com
184
184
  executables:
@@ -196,11 +196,13 @@ files:
196
196
  - NOTICE
197
197
  - README.md
198
198
  - Rakefile
199
- - bin/crono
199
+ - bin/console
200
+ - bin/setup
200
201
  - crono.gemspec
201
202
  - examples/crono_web_ui.png
202
203
  - examples/cronotab.rb
203
204
  - examples/monitrc.conf
205
+ - exe/crono
204
206
  - lib/crono.rb
205
207
  - lib/crono/cli.rb
206
208
  - lib/crono/config.rb
@@ -217,18 +219,6 @@ files:
217
219
  - lib/generators/crono/install/templates/cronotab.rb.erb
218
220
  - lib/generators/crono/install/templates/migrations/create_crono_jobs.rb
219
221
  - lib/tasks/crono_tasks.rake
220
- - spec/assets/bad_cronotab.rb
221
- - spec/assets/good_cronotab.rb
222
- - spec/cli_spec.rb
223
- - spec/config_spec.rb
224
- - spec/job_spec.rb
225
- - spec/orm/active_record/crono_job_spec.rb
226
- - spec/performer_proxy_spec.rb
227
- - spec/period_spec.rb
228
- - spec/scheduler_spec.rb
229
- - spec/spec_helper.rb
230
- - spec/tasks/crono_tasks_spec.rb
231
- - spec/web_spec.rb
232
222
  - tmp/.gitkeep
233
223
  - web/assets/custom.css
234
224
  - web/views/dashboard.haml
@@ -249,11 +239,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
249
239
  version: '0'
250
240
  required_rubygems_version: !ruby/object:Gem::Requirement
251
241
  requirements:
252
- - - ">="
242
+ - - ">"
253
243
  - !ruby/object:Gem::Version
254
- version: 1.3.6
244
+ version: 1.3.1
255
245
  requirements: []
256
- rubyforge_project: crono
246
+ rubyforge_project:
257
247
  rubygems_version: 2.4.6
258
248
  signing_key:
259
249
  specification_version: 4
@@ -1,12 +0,0 @@
1
- # This is an example of a bad cronotab for tests
2
-
3
- class TestJob
4
- def perform
5
- puts 'Test!'
6
- end
7
- end
8
-
9
- # This is an error, because you can use `on` options with
10
- # a period less than 7 days.
11
-
12
- Crono.perform(TestJob).every 5.days, on: :sunday
@@ -1,9 +0,0 @@
1
- # This is an example of a good cronotab for tests
2
-
3
- class TestJob
4
- def perform
5
- puts 'Test!'
6
- end
7
- end
8
-
9
- Crono.perform(TestJob).every 5.seconds
@@ -1,43 +0,0 @@
1
- require 'spec_helper'
2
- require 'crono/cli'
3
-
4
- describe Crono::CLI do
5
- let(:cli) { Crono::CLI.instance }
6
-
7
- describe '#run' do
8
- it 'should initialize rails with #load_rails and start working loop' do
9
- expect(cli).to receive(:load_rails)
10
- expect(cli).to receive(:start_working_loop)
11
- expect(cli).to receive(:parse_options)
12
- expect(cli).to receive(:write_pid)
13
- cli.run
14
- end
15
- end
16
-
17
- describe '#parse_options' do
18
- it 'should set cronotab' do
19
- cli.send(:parse_options, ['--cronotab', '/tmp/cronotab.rb'])
20
- expect(cli.config.cronotab).to be_eql '/tmp/cronotab.rb'
21
- end
22
-
23
- it 'should set logfile' do
24
- cli.send(:parse_options, ['--logfile', 'log/crono.log'])
25
- expect(cli.config.logfile).to be_eql 'log/crono.log'
26
- end
27
-
28
- it 'should set pidfile' do
29
- cli.send(:parse_options, ['--pidfile', 'tmp/pids/crono.0.log'])
30
- expect(cli.config.pidfile).to be_eql 'tmp/pids/crono.0.log'
31
- end
32
-
33
- it 'should set daemonize' do
34
- cli.send(:parse_options, ['--daemonize'])
35
- expect(cli.config.daemonize).to be true
36
- end
37
-
38
- it 'should set environment' do
39
- cli.send(:parse_options, ['--environment', 'production'])
40
- expect(cli.config.environment).to be_eql('production')
41
- end
42
- end
43
- end
@@ -1,15 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Crono::Config do
4
- describe '#initialize' do
5
- it 'should initialize with default configuration options' do
6
- ENV['RAILS_ENV'] = 'test'
7
- @config = Crono::Config.new
8
- expect(@config.cronotab).to be Crono::Config::CRONOTAB
9
- expect(@config.logfile).to be Crono::Config::LOGFILE
10
- expect(@config.pidfile).to be Crono::Config::PIDFILE
11
- expect(@config.daemonize).to be false
12
- expect(@config.environment).to be_eql ENV['RAILS_ENV']
13
- end
14
- end
15
- end
@@ -1,114 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Crono::Job do
4
- let(:period) { Crono::Period.new(2.day) }
5
- let(:job) { Crono::Job.new(TestJob, period) }
6
- let(:failing_job) { Crono::Job.new(TestFailingJob, period) }
7
-
8
- it 'should contain performer and period' do
9
- expect(job.performer).to be TestJob
10
- expect(job.period).to be period
11
- end
12
-
13
- describe '#perform' do
14
- after { job.send(:model).destroy }
15
-
16
- it 'should run performer in separate thread' do
17
- expect(job).to receive(:save)
18
- thread = job.perform.join
19
- expect(thread).to be_stop
20
- end
21
-
22
- it 'should save performin errors to log' do
23
- thread = failing_job.perform.join
24
- expect(thread).to be_stop
25
- saved_log = Crono::CronoJob.find_by(job_id: failing_job.job_id).log
26
- expect(saved_log).to include 'Some error'
27
- end
28
-
29
- xit 'should set Job#healthy to true if perform ok' do
30
- class TestJob
31
- def perform
32
- @_crono_job
33
- end
34
- end
35
- job.perform.join
36
- end
37
-
38
- it 'should set Job#healthy to false if perform with error' do
39
- failing_job.perform.join
40
- expect(failing_job.healthy).to be false
41
- end
42
-
43
- it 'should set @_crono_job variable to instance' do
44
- job.perform
45
- end
46
- end
47
-
48
- describe '#description' do
49
- it 'should return job identificator' do
50
- expect(job.description).to be_eql('Perform TestJob every 2 days')
51
- end
52
- end
53
-
54
- describe '#save' do
55
- it 'should save new job to DB' do
56
- expect(Crono::CronoJob.where(job_id: job.job_id)).to_not exist
57
- job.save
58
- expect(Crono::CronoJob.where(job_id: job.job_id)).to exist
59
- end
60
-
61
- it 'should update saved job' do
62
- job.last_performed_at = Time.now
63
- job.healthy = true
64
- job.save
65
- @crono_job = Crono::CronoJob.find_by(job_id: job.job_id)
66
- expect(@crono_job.last_performed_at.utc.to_s).to be_eql job.last_performed_at.utc.to_s
67
- expect(@crono_job.healthy).to be true
68
- end
69
-
70
- it 'should save and truncate job log' do
71
- message = 'test message'
72
- job.send(:log, message)
73
- job.save
74
- expect(job.send(:model).reload.log).to include message
75
- expect(job.job_log.string).to be_empty
76
- end
77
- end
78
-
79
- describe '#load' do
80
- before do
81
- @saved_last_performed_at = job.last_performed_at = Time.now
82
- job.save
83
- end
84
-
85
- it 'should load last_performed_at from DB' do
86
- @job = Crono::Job.new(TestJob, period)
87
- @job.load
88
- expect(@job.last_performed_at.utc.to_s).to be_eql @saved_last_performed_at.utc.to_s
89
- end
90
- end
91
-
92
- describe '#log' do
93
- it 'should write log messages to both common and job log' do
94
- message = 'Test message'
95
- expect(job.logger).to receive(:log).with(Logger::INFO, message)
96
- expect(job.job_logger).to receive(:log).with(Logger::INFO, message)
97
- job.send(:log, message)
98
- end
99
-
100
- it 'should write job log to Job#job_log' do
101
- message = 'Test message'
102
- job.send(:log, message)
103
- expect(job.job_log.string).to include(message)
104
- end
105
- end
106
-
107
- describe '#log_error' do
108
- it 'should call log with ERROR severity' do
109
- message = 'Test message'
110
- expect(job).to receive(:log).with(message, Logger::ERROR)
111
- job.send(:log_error, message)
112
- end
113
- end
114
- end
@@ -1,28 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Crono::CronoJob do
4
- let(:valid_attrs) do
5
- {
6
- job_id: 'Perform TestJob every 3 days'
7
- }
8
- end
9
-
10
- it 'should validate presence of job_id' do
11
- @crono_job = Crono::CronoJob.new
12
- expect(@crono_job).not_to be_valid
13
- expect(@crono_job.errors.added?(:job_id, :blank)).to be true
14
- end
15
-
16
- it 'should validate uniqueness of job_id' do
17
- Crono::CronoJob.create!(job_id: 'TestJob every 2 days')
18
- @crono_job = Crono::CronoJob.create(job_id: 'TestJob every 2 days')
19
- expect(@crono_job).not_to be_valid
20
- expect(@crono_job.errors.added?(:job_id, :taken)).to be true
21
- end
22
-
23
- it 'should save job_id to DB' do
24
- Crono::CronoJob.create!(valid_attrs)
25
- @crono_job = Crono::CronoJob.find_by(job_id: valid_attrs[:job_id])
26
- expect(@crono_job).to be_present
27
- end
28
- end
@@ -1,8 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Crono::PerformerProxy do
4
- it 'should add job to schedule' do
5
- expect(Crono.scheduler).to receive(:add_job).with(kind_of(Crono::Job))
6
- Crono.perform(TestJob).every(2.days, at: '15:30')
7
- end
8
- end
@@ -1,100 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Crono::Period do
4
- around(:each) do |example|
5
- Timecop.freeze do
6
- example.run
7
- end
8
- end
9
-
10
- describe '#description' do
11
- it 'should return period description' do
12
- @period = Crono::Period.new(1.week, on: :monday, at: '15:20')
13
- expect(@period.description).to be_eql('every 7 days at 15:20 on Monday')
14
- end
15
- end
16
-
17
- describe '#next' do
18
- context 'in weakly basis' do
19
- it "should raise error if 'on' is wrong" do
20
- expect { @period = Crono::Period.new(7.days, on: :bad_day) }
21
- .to raise_error("Wrong 'on' day")
22
- end
23
-
24
- it 'should raise error when period is less than 1 week' do
25
- expect { @period = Crono::Period.new(6.days, on: :monday) }
26
- .to raise_error("period should be at least 1 week to use 'on'")
27
- end
28
-
29
- it "should return a 'on' day" do
30
- @period = Crono::Period.new(1.week, on: :thursday, at: '15:30')
31
- current_week = Time.now.beginning_of_week
32
- last_run_time = current_week.advance(days: 1) # last run on the tuesday
33
- next_run_at = Time.now.next_week.advance(days: 3)
34
- .change(hour: 15, min: 30)
35
- expect(@period.next(since: last_run_time)).to be_eql(next_run_at)
36
- end
37
-
38
- it "should return a next week day 'on'" do
39
- @period = Crono::Period.new(1.week, on: :thursday)
40
- Timecop.freeze(Time.now.beginning_of_week.advance(days: 4)) do
41
- expect(@period.next).to be_eql(Time.now.next_week.advance(days: 3))
42
- end
43
- end
44
-
45
- it 'should return a current week day on the first run if not too late' do
46
- @period = Crono::Period.new(7.days, on: :tuesday)
47
- beginning_of_the_week = Time.now.beginning_of_week
48
- tuesday = beginning_of_the_week.advance(days: 1)
49
- Timecop.freeze(beginning_of_the_week) do
50
- expect(@period.next).to be_eql(tuesday)
51
- end
52
- end
53
- end
54
-
55
- context 'in daily basis' do
56
- it 'should return the time 2 days from now' do
57
- @period = Crono::Period.new(2.day)
58
- expect(@period.next).to be_eql(2.day.from_now)
59
- end
60
-
61
- it "should set time to 'at' time as a string" do
62
- time = 10.minutes.ago
63
- at = [time.hour, time.min].join(':')
64
- @period = Crono::Period.new(2.day, at: at)
65
- expect(@period.next).to be_eql(2.day.from_now.change(hour: time.hour, min: time.min))
66
- end
67
-
68
- it "should set time to 'at' time as a hash" do
69
- time = 10.minutes.ago
70
- at = { hour: time.hour, min: time.min }
71
- @period = Crono::Period.new(2.day, at: at)
72
- expect(@period.next).to be_eql(2.day.from_now.change(at))
73
- end
74
-
75
- it "should raise error when 'at' is wrong" do
76
- expect {
77
- Crono::Period.new(2.day, at: 1)
78
- }.to raise_error("Unknown 'at' format")
79
- end
80
-
81
- it 'should raise error when period is less than 1 day' do
82
- expect {
83
- Crono::Period.new(5.hours, at: '15:30')
84
- }.to raise_error("period should be at least 1 day to use 'at'")
85
- end
86
-
87
- it 'should return time in relation to last time' do
88
- @period = Crono::Period.new(2.day)
89
- expect(@period.next(since: 1.day.ago)).to be_eql(1.day.from_now)
90
- end
91
-
92
- it 'should return today time if it is first run and not too late' do
93
- time = 10.minutes.from_now
94
- at = { hour: time.hour, min: time.min }
95
- @period = Crono::Period.new(2.day, at: at)
96
- expect(@period.next.utc.to_s).to be_eql(Time.now.change(at).utc.to_s)
97
- end
98
- end
99
- end
100
- end
@@ -1,27 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Crono::Scheduler do
4
- before(:each) do
5
- @scheduler = Crono::Scheduler.new
6
- @jobs = [
7
- Crono::Period.new(3.day, at: 10.minutes.from_now.strftime('%H:%M')),
8
- Crono::Period.new(1.day, at: 20.minutes.from_now.strftime('%H:%M')),
9
- Crono::Period.new(7.day, at: 40.minutes.from_now.strftime('%H:%M'))
10
- ].map { |period| Crono::Job.new(TestJob, period) }
11
- @scheduler.jobs = @jobs
12
- end
13
-
14
- describe '#add_job' do
15
- it 'should call Job#load on Job' do
16
- @job = Crono::Job.new(TestJob, Crono::Period.new(10.day, at: '04:05'))
17
- expect(@job).to receive(:load)
18
- @scheduler.add_job(@job)
19
- end
20
- end
21
-
22
- describe '#next' do
23
- it 'should return next job in schedule' do
24
- expect(@scheduler.next).to be @jobs[0]
25
- end
26
- end
27
- end
@@ -1,26 +0,0 @@
1
- require 'bundler/setup'
2
- Bundler.setup
3
-
4
- require 'timecop'
5
- require 'byebug'
6
- require 'crono'
7
- require 'generators/crono/install/templates/migrations/create_crono_jobs.rb'
8
-
9
- ActiveRecord::Base.establish_connection(
10
- adapter: 'sqlite3',
11
- database: 'file::memory:?cache=shared'
12
- )
13
-
14
- ActiveRecord::Base.logger = Logger.new(STDOUT)
15
- CreateCronoJobs.up
16
-
17
- class TestJob
18
- def perform
19
- end
20
- end
21
-
22
- class TestFailingJob
23
- def perform
24
- fail 'Some error'
25
- end
26
- end
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
- require 'rake'
3
-
4
- load 'tasks/crono_tasks.rake'
5
- Rake::Task.define_task(:environment)
6
-
7
- describe 'rake' do
8
- describe 'crono:clean' do
9
- it 'should clean unused tasks from DB' do
10
- Crono::CronoJob.create!(job_id: 'used_job')
11
- ENV['CRONOTAB'] = File.expand_path('../../assets/good_cronotab.rb', __FILE__)
12
- Rake::Task['crono:clean'].invoke
13
- expect(Crono::CronoJob.where(job_id: 'used_job')).not_to exist
14
- end
15
- end
16
-
17
- describe 'crono:check' do
18
- it 'should check cronotab syntax' do
19
- ENV['CRONOTAB'] = File.expand_path('../../assets/bad_cronotab.rb', __FILE__)
20
- expect { Rake::Task['crono:check'].invoke }.to raise_error
21
- end
22
- end
23
- end
@@ -1,49 +0,0 @@
1
- require 'spec_helper'
2
- require 'rack/test'
3
- include Rack::Test::Methods
4
-
5
- describe Crono::Web do
6
- let(:app) { Crono::Web }
7
-
8
- before do
9
- Crono::CronoJob.destroy_all
10
- @test_job_id = 'Perform TestJob every 5 seconds'
11
- @test_job_log = 'All runs ok'
12
- @test_job = Crono::CronoJob.create!(
13
- job_id: @test_job_id,
14
- log: @test_job_log
15
- )
16
- end
17
-
18
- after { @test_job.destroy }
19
-
20
- describe '/' do
21
- it 'should show all jobs' do
22
- get '/'
23
- expect(last_response).to be_ok
24
- expect(last_response.body).to include @test_job_id
25
- end
26
-
27
- it 'should show a error mark when a job is unhealthy' do
28
- @test_job.update(healthy: false)
29
- get '/'
30
- expect(last_response.body).to include 'Error'
31
- end
32
- end
33
-
34
- describe '/job/:id' do
35
- it 'should show job log' do
36
- get "/job/#{@test_job.id}"
37
- expect(last_response).to be_ok
38
- expect(last_response.body).to include @test_job_id
39
- expect(last_response.body).to include @test_job_log
40
- end
41
-
42
- it 'should show a message about the unhealthy job' do
43
- message = 'An error occurs during the last execution of this job'
44
- @test_job.update(healthy: false)
45
- get "/job/#{@test_job.id}"
46
- expect(last_response.body).to include message
47
- end
48
- end
49
- end