resque-scheduler 2.3.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of resque-scheduler might be problematic. Click here for more details.

Files changed (49) hide show
  1. data/.gitignore +3 -0
  2. data/.rubocop.yml +11 -11
  3. data/.simplecov +1 -0
  4. data/.travis.yml +5 -2
  5. data/AUTHORS.md +3 -0
  6. data/HISTORY.md +26 -2
  7. data/LICENSE +1 -1
  8. data/README.md +120 -31
  9. data/ROADMAP.md +10 -0
  10. data/Rakefile +7 -19
  11. data/bin/resque-scheduler +5 -0
  12. data/examples/Rakefile +2 -0
  13. data/examples/config/initializers/resque-web.rb +37 -0
  14. data/examples/dynamic-scheduling/README.md +28 -0
  15. data/examples/dynamic-scheduling/app/jobs/fix_schedules_job.rb +54 -0
  16. data/examples/dynamic-scheduling/app/jobs/send_email_job.rb +9 -0
  17. data/examples/dynamic-scheduling/app/models/user.rb +16 -0
  18. data/examples/dynamic-scheduling/config/resque.yml +4 -0
  19. data/examples/dynamic-scheduling/config/static_schedule.yml +7 -0
  20. data/examples/dynamic-scheduling/lib/tasks/resque.rake +48 -0
  21. data/examples/run-resque-web +3 -0
  22. data/lib/resque-scheduler.rb +2 -0
  23. data/lib/resque/scheduler.rb +130 -41
  24. data/lib/resque/scheduler/lock/resilient.rb +1 -1
  25. data/lib/resque/scheduler_locking.rb +3 -1
  26. data/lib/resque_scheduler.rb +73 -31
  27. data/lib/resque_scheduler/cli.rb +160 -0
  28. data/lib/resque_scheduler/logger_builder.rb +27 -8
  29. data/lib/resque_scheduler/plugin.rb +10 -7
  30. data/lib/resque_scheduler/server.rb +52 -11
  31. data/lib/resque_scheduler/server/views/delayed.erb +2 -0
  32. data/lib/resque_scheduler/server/views/delayed_schedules.erb +20 -0
  33. data/lib/resque_scheduler/server/views/scheduler.erb +4 -12
  34. data/lib/resque_scheduler/tasks.rb +15 -27
  35. data/lib/resque_scheduler/version.rb +1 -1
  36. data/resque-scheduler.gemspec +2 -0
  37. data/test/cli_test.rb +286 -0
  38. data/test/delayed_queue_test.rb +70 -1
  39. data/test/resque-web_test.rb +36 -1
  40. data/test/scheduler_args_test.rb +51 -17
  41. data/test/scheduler_hooks_test.rb +1 -1
  42. data/test/scheduler_locking_test.rb +63 -1
  43. data/test/scheduler_setup_test.rb +54 -18
  44. data/test/scheduler_task_test.rb +35 -0
  45. data/test/scheduler_test.rb +130 -42
  46. data/test/support/redis_instance.rb +8 -3
  47. data/test/test_helper.rb +47 -20
  48. metadata +77 -6
  49. checksums.yaml +0 -15
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/test_helper'
1
+ require_relative 'test_helper'
2
2
 
3
3
  # Pull in the server test_helper from resque
4
4
  require 'resque/server/test_helper.rb'
@@ -45,6 +45,41 @@ context "on GET to /delayed" do
45
45
  should_respond_with_success
46
46
  end
47
47
 
48
+ context "on GET to /delayed/jobs/:klass" do
49
+ setup do
50
+ @t = Time.now + 3600
51
+ Resque.enqueue_at(@t, SomeIvarJob, 'foo', 'bar')
52
+ get URI("/delayed/jobs/SomeIvarJob?args=" + URI.encode(%w{foo bar}.to_json)).to_s
53
+ end
54
+
55
+ should_respond_with_success
56
+
57
+ test 'see the scheduled job' do
58
+ assert last_response.body.include?(@t.to_s)
59
+ end
60
+
61
+ context 'with a namespaced class' do
62
+ setup do
63
+ @t = Time.now + 3600
64
+ module Foo
65
+ class Bar
66
+ def self.queue
67
+ 'bar'
68
+ end
69
+ end
70
+ end
71
+ Resque.enqueue_at(@t, Foo::Bar, 'foo', 'bar')
72
+ get URI("/delayed/jobs/Foo::Bar?args=" + URI.encode(%w{foo bar}.to_json)).to_s
73
+ end
74
+
75
+ should_respond_with_success
76
+
77
+ test 'see the scheduled job' do
78
+ assert last_response.body.include?(@t.to_s)
79
+ end
80
+ end
81
+ end
82
+
48
83
  def resque_schedule
49
84
  {
50
85
  'job_without_params' => {
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/test_helper'
1
+ require_relative 'test_helper'
2
2
 
3
3
  context "scheduling jobs with arguments" do
4
4
 
@@ -28,40 +28,74 @@ context "scheduling jobs with arguments" do
28
28
  Resque::Scheduler.enqueue_from_config('cron' => "* * * * *", 'class' => 'SomeIvarJob', 'custom_job_class' => 'FakeCustomJobClass', 'args' => "/tmp")
29
29
  end
30
30
 
31
- test "enqueue_from_config puts stuff in resquewhen rails_env matches" do
32
- # The job should be loaded : its rails_env config matches the RAILS_ENV variable:
33
- ENV['RAILS_ENV'] = 'production'
31
+ test 'enqueue_from_config puts stuff in resque when env matches' do
32
+ Resque::Scheduler.env = 'production'
34
33
  assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
35
34
 
36
- Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'production'}}
35
+ Resque.schedule = {
36
+ 'some_ivar_job' => {
37
+ 'cron' => '* * * * *',
38
+ 'class' => 'SomeIvarJob',
39
+ 'args' => '/tmp',
40
+ 'rails_env' => 'production'
41
+ }
42
+ }
43
+
37
44
  Resque::Scheduler.load_schedule!
38
45
  assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
39
46
 
40
- # we allow multiple rails_env definition, it should work also:
41
- Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'staging, production'}}
47
+ Resque.schedule = {
48
+ 'some_ivar_job' => {
49
+ 'cron' => '* * * * *',
50
+ 'class' => 'SomeIvarJob',
51
+ 'args' => '/tmp',
52
+ 'env' => 'staging, production'
53
+ }
54
+ }
55
+
42
56
  Resque::Scheduler.load_schedule!
43
57
  assert_equal(2, Resque::Scheduler.rufus_scheduler.all_jobs.size)
44
58
  end
45
59
 
46
- test "enqueue_from_config doesnt put stuff in resque when rails_env doesnt match" do
47
- # RAILS_ENV is not set:
60
+ test 'enqueue_from_config does not enqueue when env does not match' do
61
+ Resque::Scheduler.env = nil
48
62
  assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
49
- Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'staging'}}
63
+ Resque.schedule = {
64
+ 'some_ivar_job' => {
65
+ 'cron' => '* * * * *',
66
+ 'class' => 'SomeIvarJob',
67
+ 'args' => '/tmp',
68
+ 'rails_env' => 'staging'
69
+ }
70
+ }
71
+
50
72
  Resque::Scheduler.load_schedule!
51
73
  assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
52
74
 
53
- # SET RAILS_ENV to a common value:
54
- ENV['RAILS_ENV'] = 'production'
55
- Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'staging'}}
75
+ Resque::Scheduler.env = 'production'
76
+ Resque.schedule = {
77
+ 'some_ivar_job' => {
78
+ 'cron' => '* * * * *',
79
+ 'class' => 'SomeIvarJob',
80
+ 'args' => '/tmp',
81
+ 'env' => 'staging'
82
+ }
83
+ }
56
84
  Resque::Scheduler.load_schedule!
57
85
  assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
58
86
  end
59
87
 
60
- test "enqueue_from_config when rails env arg is not set" do
61
- # The job should be loaded, since a missing rails_env means ALL envs.
62
- ENV['RAILS_ENV'] = 'production'
88
+ test 'enqueue_from_config when env env arg is not set' do
89
+ Resque::Scheduler.env = 'production'
63
90
  assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
64
- Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"}}
91
+
92
+ Resque.schedule = {
93
+ 'some_ivar_job' => {
94
+ 'cron' => '* * * * *',
95
+ 'class' => 'SomeIvarJob',
96
+ 'args' => '/tmp'
97
+ }
98
+ }
65
99
  Resque::Scheduler.load_schedule!
66
100
  assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
67
101
  end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/test_helper'
1
+ require_relative 'test_helper'
2
2
 
3
3
  context "scheduling jobs with hooks" do
4
4
  setup do
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/test_helper'
1
+ require_relative 'test_helper'
2
2
 
3
3
  module LockTestHelper
4
4
  def lock_is_not_held(lock)
@@ -6,6 +6,68 @@ module LockTestHelper
6
6
  end
7
7
  end
8
8
 
9
+ context '#master_lock_key' do
10
+ setup do
11
+ @subject = Class.new { extend Resque::SchedulerLocking }
12
+ end
13
+
14
+ teardown do
15
+ Resque.redis.del(@subject.master_lock.key)
16
+ end
17
+
18
+ test 'it should have resque prefix' do
19
+ assert_equal @subject.master_lock.key, 'resque:resque_scheduler_master_lock'
20
+ end
21
+
22
+ context 'with a prefix set via ENV' do
23
+ setup do
24
+ ENV['RESQUE_SCHEDULER_MASTER_LOCK_PREFIX'] = 'my.prefix'
25
+ @subject = Class.new { extend Resque::SchedulerLocking }
26
+ end
27
+
28
+ teardown do
29
+ Resque.redis.del(@subject.master_lock.key)
30
+ end
31
+
32
+ test 'it should have ENV prefix' do
33
+ assert_equal @subject.master_lock.key, 'resque:my.prefix:resque_scheduler_master_lock'
34
+ end
35
+ end
36
+
37
+ context 'with a namespace set for resque' do
38
+ setup do
39
+ Resque.redis.namespace = 'my.namespace'
40
+ @subject = Class.new { extend Resque::SchedulerLocking }
41
+ end
42
+
43
+ teardown do
44
+ Resque.redis.namespace = 'resque'
45
+ Resque.redis.del(@subject.master_lock.key)
46
+ end
47
+
48
+ test 'it should have resque prefix' do
49
+ assert_equal @subject.master_lock.key, 'my.namespace:resque_scheduler_master_lock'
50
+ end
51
+
52
+ context 'with a prefix set via ENV' do
53
+ setup do
54
+ Resque.redis.namespace = 'my.namespace'
55
+ ENV['RESQUE_SCHEDULER_MASTER_LOCK_PREFIX'] = 'my.prefix'
56
+ @subject = Class.new { extend Resque::SchedulerLocking }
57
+ end
58
+
59
+ teardown do
60
+ Resque.redis.namespace = 'resque'
61
+ Resque.redis.del(@subject.master_lock.key)
62
+ end
63
+
64
+ test 'it should have ENV prefix' do
65
+ assert_equal @subject.master_lock.key, 'my.namespace:my.prefix:resque_scheduler_master_lock'
66
+ end
67
+ end
68
+ end
69
+ end
70
+
9
71
  context 'Resque::SchedulerLocking' do
10
72
  setup do
11
73
  @subject = Class.new { extend Resque::SchedulerLocking }
@@ -1,59 +1,95 @@
1
- require File.dirname(__FILE__) + '/test_helper'
1
+ require_relative 'test_helper'
2
2
 
3
3
  context "Resque::Scheduler" do
4
-
5
4
  setup do
5
+ ENV['VERBOSE'] = nil
6
+ nullify_logger
6
7
  Resque::Scheduler.dynamic = false
7
8
  Resque.redis.flushall
8
9
  Resque::Scheduler.clear_schedule!
9
10
  end
10
11
 
12
+ teardown { restore_devnull_logfile }
13
+
11
14
  test 'set custom logger' do
12
15
  custom_logger = Logger.new('/dev/null')
13
16
  Resque::Scheduler.logger = custom_logger
14
17
  assert_equal(custom_logger, Resque::Scheduler.logger)
15
18
  end
16
19
 
17
- context 'logger default settings' do
18
- setup do
19
- nullify_logger
20
+ test 'configure block' do
21
+ Resque::Scheduler.mute = false
22
+ Resque::Scheduler.configure do |c|
23
+ c.mute = true
20
24
  end
25
+ assert_equal(Resque::Scheduler.mute, true)
26
+ end
27
+
28
+ context 'when getting the env' do
29
+ def wipe
30
+ Resque::Scheduler.env = nil
31
+ Rails.env = nil
32
+ ENV['RAILS_ENV'] = nil
33
+ end
34
+
35
+ setup { wipe }
36
+ teardown { wipe }
37
+
38
+ test 'uses the value if set' do
39
+ Resque::Scheduler.env = 'foo'
40
+ assert_equal('foo', Resque::Scheduler.env)
41
+ end
42
+
43
+ test 'uses Rails.env if present' do
44
+ Rails.env = 'bar'
45
+ assert_equal('bar', Resque::Scheduler.env)
46
+ end
47
+
48
+ test 'uses $RAILS_ENV if present' do
49
+ ENV['RAILS_ENV'] = 'baz'
50
+ assert_equal('baz', Resque::Scheduler.env)
51
+ end
52
+ end
53
+
54
+ context 'logger default settings' do
55
+ setup { nullify_logger }
56
+ teardown { restore_devnull_logfile }
21
57
 
22
58
  test 'uses STDOUT' do
23
- assert_equal(Resque::Scheduler.logger.instance_variable_get(:@logdev).dev, STDOUT)
59
+ assert_equal(
60
+ Resque::Scheduler.logger.instance_variable_get(:@logdev).dev, $stdout
61
+ )
24
62
  end
63
+
25
64
  test 'not verbose' do
26
65
  assert Resque::Scheduler.logger.level > Logger::DEBUG
27
66
  end
67
+
28
68
  test 'not muted' do
29
69
  assert Resque::Scheduler.logger.level < Logger::FATAL
30
70
  end
31
-
32
- teardown do
33
- nullify_logger
34
- end
35
71
  end
36
72
 
37
73
  context 'logger custom settings' do
38
- setup do
39
- nullify_logger
40
- end
74
+ setup { nullify_logger }
75
+ teardown { restore_devnull_logfile }
41
76
 
42
77
  test 'uses logfile' do
43
78
  Resque::Scheduler.logfile = '/dev/null'
44
- assert_equal(Resque::Scheduler.logger.instance_variable_get(:@logdev).filename, '/dev/null')
79
+ assert_equal(
80
+ Resque::Scheduler.logger.instance_variable_get(:@logdev).filename,
81
+ '/dev/null'
82
+ )
45
83
  end
84
+
46
85
  test 'set verbosity' do
47
86
  Resque::Scheduler.verbose = true
48
87
  assert Resque::Scheduler.logger.level == Logger::DEBUG
49
88
  end
89
+
50
90
  test 'mute logger' do
51
91
  Resque::Scheduler.mute = true
52
92
  assert Resque::Scheduler.logger.level == Logger::FATAL
53
93
  end
54
-
55
- teardown do
56
- nullify_logger
57
- end
58
94
  end
59
95
  end
@@ -0,0 +1,35 @@
1
+ require_relative 'test_helper'
2
+
3
+ context "Resque::Scheduler" do
4
+ setup do
5
+ Resque::Scheduler.dynamic = false
6
+ Resque.redis.flushall
7
+ Resque::Scheduler.mute = true
8
+ Resque::Scheduler.clear_schedule!
9
+ Resque::Scheduler.send(:class_variable_set, :@@scheduled_jobs, {})
10
+ Resque::Scheduler.send(:instance_variable_set, :@shutdown, false)
11
+ end
12
+
13
+ test "shutdown raises Interrupt when sleeping" do
14
+ Thread.current.expects(:raise).with(Interrupt)
15
+ Resque::Scheduler.send(:instance_variable_set, :@th, Thread.current)
16
+ Resque::Scheduler.send(:instance_variable_set, :@sleeping, true)
17
+ Resque::Scheduler.shutdown
18
+ end
19
+
20
+ test "sending TERM to scheduler breaks out of poll_sleep" do
21
+ Resque::Scheduler.expects(:release_master_lock!)
22
+ fork do
23
+ sleep(0.5)
24
+ system("kill -TERM #{Process.ppid}")
25
+ exit!
26
+ end
27
+
28
+ assert_raises SystemExit do
29
+ Resque::Scheduler.run
30
+ end
31
+
32
+ Resque::Scheduler.unstub(:release_master_lock!)
33
+ Resque::Scheduler.release_master_lock!
34
+ end
35
+ end
@@ -1,41 +1,56 @@
1
- require File.dirname(__FILE__) + '/test_helper'
2
-
3
- context "Resque::Scheduler" do
1
+ require_relative 'test_helper'
4
2
 
3
+ context 'Resque::Scheduler' do
5
4
  setup do
6
- Resque::Scheduler.dynamic = false
5
+ Resque::Scheduler.configure do |c|
6
+ c.dynamic = false
7
+ c.mute = true
8
+ c.env = nil
9
+ c.app_name = nil
10
+ end
7
11
  Resque.redis.flushall
8
- Resque::Scheduler.mute = true
9
12
  Resque::Scheduler.clear_schedule!
10
13
  Resque::Scheduler.send(:class_variable_set, :@@scheduled_jobs, {})
11
14
  end
12
15
 
13
- test "enqueue constantizes" do
14
- # The job should be loaded, since a missing rails_env means ALL envs.
15
- ENV['RAILS_ENV'] = 'production'
16
- config = {'cron' => "* * * * *", 'class' => 'SomeRealClass', 'args' => "/tmp"}
17
- Resque::Job.expects(:create).with(SomeRealClass.queue, SomeRealClass, '/tmp')
16
+ test 'enqueue constantizes' do
17
+ Resque::Scheduler.env = 'production'
18
+ config = {
19
+ 'cron' => '* * * * *',
20
+ 'class' => 'SomeRealClass',
21
+ 'args' => '/tmp'
22
+ }
23
+ Resque::Job.expects(:create).with(
24
+ SomeRealClass.queue, SomeRealClass, '/tmp'
25
+ )
18
26
  Resque::Scheduler.enqueue_from_config(config)
19
27
  end
20
28
 
21
- test "enqueue runs hooks" do
22
- # The job should be loaded, since a missing rails_env means ALL envs.
23
- ENV['RAILS_ENV'] = 'production'
24
- config = {'cron' => "* * * * *", 'class' => 'SomeRealClass', 'args' => "/tmp"}
29
+ test 'enqueue runs hooks' do
30
+ Resque::Scheduler.env = 'production'
31
+ config = {
32
+ 'cron' => '* * * * *',
33
+ 'class' => 'SomeRealClass',
34
+ 'args' => '/tmp'
35
+ }
25
36
 
26
- Resque::Job.expects(:create).with(SomeRealClass.queue, SomeRealClass, '/tmp')
27
- SomeRealClass.expects(:before_delayed_enqueue_example).with("/tmp")
28
- SomeRealClass.expects(:before_enqueue_example).with("/tmp")
29
- SomeRealClass.expects(:after_enqueue_example).with("/tmp")
37
+ Resque::Job.expects(:create).with(
38
+ SomeRealClass.queue, SomeRealClass, '/tmp'
39
+ )
40
+ SomeRealClass.expects(:before_delayed_enqueue_example).with('/tmp')
41
+ SomeRealClass.expects(:before_enqueue_example).with('/tmp')
42
+ SomeRealClass.expects(:after_enqueue_example).with('/tmp')
30
43
 
31
44
  Resque::Scheduler.enqueue_from_config(config)
32
45
  end
33
46
 
34
- test "enqueue_from_config respects queue params" do
35
- config = {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'queue' => 'high'}
36
-
47
+ test 'enqueue_from_config respects queue params' do
48
+ config = {
49
+ 'cron' => '* * * * *',
50
+ 'class' => 'SomeIvarJob',
51
+ 'queue' => 'high'
52
+ }
37
53
  Resque.expects(:enqueue_to).with('high', SomeIvarJob)
38
-
39
54
  Resque::Scheduler.enqueue_from_config(config)
40
55
  end
41
56
 
@@ -71,46 +86,77 @@ context "Resque::Scheduler" do
71
86
  assert Resque::Scheduler.scheduled_jobs.include?("some_ivar_job2")
72
87
  end
73
88
 
74
- test "load_schedule_job loads a schedule" do
75
- Resque::Scheduler.load_schedule_job("some_ivar_job", {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"})
89
+ test 'load_schedule_job loads a schedule' do
90
+ Resque::Scheduler.load_schedule_job(
91
+ 'some_ivar_job', {
92
+ 'cron' => '* * * * *',
93
+ 'class' => 'SomeIvarJob',
94
+ 'args' => '/tmp'
95
+ }
96
+ )
76
97
 
77
98
  assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
78
99
  assert_equal(1, Resque::Scheduler.scheduled_jobs.size)
79
- assert Resque::Scheduler.scheduled_jobs.keys.include?("some_ivar_job")
100
+ assert Resque::Scheduler.scheduled_jobs.keys.include?('some_ivar_job')
80
101
  end
81
102
 
82
- test "load_schedule_job with every with options" do
83
- Resque::Scheduler.load_schedule_job("some_ivar_job", {'every' => ['30s', {'first_in' => '60s'}], 'class' => 'SomeIvarJob', 'args' => "/tmp"})
103
+ test 'load_schedule_job with every with options' do
104
+ Resque::Scheduler.load_schedule_job(
105
+ 'some_ivar_job', {
106
+ 'every' => ['30s', { 'first_in' => '60s' }],
107
+ 'class' => 'SomeIvarJob',
108
+ 'args' => '/tmp'
109
+ }
110
+ )
84
111
 
85
112
  assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
86
113
  assert_equal(1, Resque::Scheduler.scheduled_jobs.size)
87
- assert Resque::Scheduler.scheduled_jobs.keys.include?("some_ivar_job")
88
- assert Resque::Scheduler.scheduled_jobs["some_ivar_job"].params.keys.include?(:first_in)
114
+ assert Resque::Scheduler.scheduled_jobs.keys.include?('some_ivar_job')
115
+ job = Resque::Scheduler.scheduled_jobs['some_ivar_job']
116
+ assert job.params.keys.include?(:first_in)
89
117
  end
90
118
 
91
- test "load_schedule_job with cron with options" do
92
- Resque::Scheduler.load_schedule_job("some_ivar_job", {'cron' => ['* * * * *', {'allow_overlapping' => 'true'}], 'class' => 'SomeIvarJob', 'args' => "/tmp"})
119
+ test 'load_schedule_job with cron with options' do
120
+ Resque::Scheduler.load_schedule_job(
121
+ 'some_ivar_job', {
122
+ 'cron' => ['* * * * *', { 'allow_overlapping' => 'true' }],
123
+ 'class' => 'SomeIvarJob',
124
+ 'args' => '/tmp'
125
+ }
126
+ )
93
127
 
94
128
  assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
95
129
  assert_equal(1, Resque::Scheduler.scheduled_jobs.size)
96
- assert Resque::Scheduler.scheduled_jobs.keys.include?("some_ivar_job")
97
- assert Resque::Scheduler.scheduled_jobs["some_ivar_job"].params.keys.include?(:allow_overlapping)
130
+ assert Resque::Scheduler.scheduled_jobs.keys.include?('some_ivar_job')
131
+ job = Resque::Scheduler.scheduled_jobs['some_ivar_job']
132
+ assert job.params.keys.include?(:allow_overlapping)
98
133
  end
99
134
 
100
- test "load_schedule_job without cron" do
101
- Resque::Scheduler.load_schedule_job("some_ivar_job", {'class' => 'SomeIvarJob', 'args' => "/tmp"})
135
+ test 'load_schedule_job without cron' do
136
+ Resque::Scheduler.load_schedule_job(
137
+ 'some_ivar_job', {
138
+ 'class' => 'SomeIvarJob',
139
+ 'args' => '/tmp'
140
+ }
141
+ )
102
142
 
103
143
  assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
104
144
  assert_equal(0, Resque::Scheduler.scheduled_jobs.size)
105
- assert !Resque::Scheduler.scheduled_jobs.keys.include?("some_ivar_job")
145
+ assert !Resque::Scheduler.scheduled_jobs.keys.include?('some_ivar_job')
106
146
  end
107
147
 
108
- test "load_schedule_job with an empty cron" do
109
- Resque::Scheduler.load_schedule_job("some_ivar_job", {'cron' => '', 'class' => 'SomeIvarJob', 'args' => "/tmp"})
148
+ test 'load_schedule_job with an empty cron' do
149
+ Resque::Scheduler.load_schedule_job(
150
+ 'some_ivar_job', {
151
+ 'cron' => '',
152
+ 'class' => 'SomeIvarJob',
153
+ 'args' => '/tmp'
154
+ }
155
+ )
110
156
 
111
157
  assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
112
158
  assert_equal(0, Resque::Scheduler.scheduled_jobs.size)
113
- assert !Resque::Scheduler.scheduled_jobs.keys.include?("some_ivar_job")
159
+ assert !Resque::Scheduler.scheduled_jobs.keys.include?('some_ivar_job')
114
160
  end
115
161
 
116
162
  test "update_schedule" do
@@ -239,12 +285,32 @@ context "Resque::Scheduler" do
239
285
  end
240
286
 
241
287
  test "remove_schedule removes a schedule" do
242
- Resque.redis.hset(:schedules, "some_ivar_job3", Resque.encode(
243
- 'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/44"
244
- ))
288
+ Resque.set_schedule("some_ivar_job3",
289
+ {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/44", 'persist' => true}
290
+ )
291
+ Resque::Scheduler.load_schedule!
245
292
  Resque.remove_schedule("some_ivar_job3")
246
293
  assert_equal nil, Resque.redis.hget(:schedules, "some_ivar_job3")
247
294
  assert Resque.redis.sismember(:schedules_changed, "some_ivar_job3")
295
+ assert_equal [], Resque.redis.smembers(:persisted_schedules)
296
+ end
297
+
298
+ test "persisted schedules" do
299
+ Resque.set_schedule("some_ivar_job",
300
+ {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/2", 'persist' => true}
301
+ )
302
+ Resque.set_schedule("new_ivar_job",
303
+ {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp/3"}
304
+ )
305
+
306
+ Resque.schedule=({
307
+ 'a_schedule' => {'cron' => "* * * * *", 'class' => 'SomeOtherJob', 'args' => '/tmp'}
308
+ })
309
+ Resque::Scheduler.load_schedule!
310
+
311
+ assert_equal({'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/2"},
312
+ Resque.schedule['some_ivar_job'])
313
+ assert_equal(nil, Resque.schedule['some_job'])
248
314
  end
249
315
 
250
316
  test "adheres to lint" do
@@ -253,4 +319,26 @@ context "Resque::Scheduler" do
253
319
  Resque::Plugin.lint(ResqueScheduler)
254
320
  end
255
321
  end
322
+
323
+ test 'procline contains app_name when present' do
324
+ Resque::Scheduler.app_name = 'foo'
325
+ assert Resque::Scheduler.send(:build_procline, 'bar') =~ /\[foo\]:/
326
+ end
327
+
328
+ test 'procline omits app_name when absent' do
329
+ Resque::Scheduler.app_name = nil
330
+ assert Resque::Scheduler.send(:build_procline, 'bar') =~
331
+ /#{Resque::Scheduler.send(:internal_name)}: bar/
332
+ end
333
+
334
+ test 'procline contains env when present' do
335
+ Resque::Scheduler.env = 'derp'
336
+ assert Resque::Scheduler.send(:build_procline, 'cage') =~ /\[derp\]: cage/
337
+ end
338
+
339
+ test 'procline omits env when absent' do
340
+ Resque::Scheduler.env = nil
341
+ assert Resque::Scheduler.send(:build_procline, 'cage') =~
342
+ /#{Resque::Scheduler.send(:internal_name)}: cage/
343
+ end
256
344
  end