crono 0.8.1 → 0.8.6.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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