ealdent-resque-scheduler 2.0.0.e

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,115 @@
1
+ # Redis configuration file example
2
+
3
+ # By default Redis does not run as a daemon. Use 'yes' if you need it.
4
+ # Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
5
+ daemonize yes
6
+
7
+ # When run as a daemon, Redis write a pid file in /var/run/redis.pid by default.
8
+ # You can specify a custom pid file location here.
9
+ pidfile ./test/redis-test.pid
10
+
11
+ # Accept connections on the specified port, default is 6379
12
+ port 9736
13
+
14
+ # If you want you can bind a single interface, if the bind option is not
15
+ # specified all the interfaces will listen for connections.
16
+ #
17
+ # bind 127.0.0.1
18
+
19
+ # Close the connection after a client is idle for N seconds (0 to disable)
20
+ timeout 300
21
+
22
+ # Save the DB on disk:
23
+ #
24
+ # save <seconds> <changes>
25
+ #
26
+ # Will save the DB if both the given number of seconds and the given
27
+ # number of write operations against the DB occurred.
28
+ #
29
+ # In the example below the behaviour will be to save:
30
+ # after 900 sec (15 min) if at least 1 key changed
31
+ # after 300 sec (5 min) if at least 10 keys changed
32
+ # after 60 sec if at least 10000 keys changed
33
+ save 900 1
34
+ save 300 10
35
+ save 60 10000
36
+
37
+ # The filename where to dump the DB
38
+ dbfilename dump.rdb
39
+
40
+ # For default save/load DB in/from the working directory
41
+ # Note that you must specify a directory not a file name.
42
+ dir ./test/
43
+
44
+ # Set server verbosity to 'debug'
45
+ # it can be one of:
46
+ # debug (a lot of information, useful for development/testing)
47
+ # notice (moderately verbose, what you want in production probably)
48
+ # warning (only very important / critical messages are logged)
49
+ loglevel debug
50
+
51
+ # Specify the log file name. Also 'stdout' can be used to force
52
+ # the demon to log on the standard output. Note that if you use standard
53
+ # output for logging but daemonize, logs will be sent to /dev/null
54
+ logfile stdout
55
+
56
+ # Set the number of databases. The default database is DB 0, you can select
57
+ # a different one on a per-connection basis using SELECT <dbid> where
58
+ # dbid is a number between 0 and 'databases'-1
59
+ databases 16
60
+
61
+ ################################# REPLICATION #################################
62
+
63
+ # Master-Slave replication. Use slaveof to make a Redis instance a copy of
64
+ # another Redis server. Note that the configuration is local to the slave
65
+ # so for example it is possible to configure the slave to save the DB with a
66
+ # different interval, or to listen to another port, and so on.
67
+
68
+ # slaveof <masterip> <masterport>
69
+
70
+ ################################## SECURITY ###################################
71
+
72
+ # Require clients to issue AUTH <PASSWORD> before processing any other
73
+ # commands. This might be useful in environments in which you do not trust
74
+ # others with access to the host running redis-server.
75
+ #
76
+ # This should stay commented out for backward compatibility and because most
77
+ # people do not need auth (e.g. they run their own servers).
78
+
79
+ # requirepass foobared
80
+
81
+ ################################### LIMITS ####################################
82
+
83
+ # Set the max number of connected clients at the same time. By default there
84
+ # is no limit, and it's up to the number of file descriptors the Redis process
85
+ # is able to open. The special value '0' means no limts.
86
+ # Once the limit is reached Redis will close all the new connections sending
87
+ # an error 'max number of clients reached'.
88
+
89
+ # maxclients 128
90
+
91
+ # Don't use more memory than the specified amount of bytes.
92
+ # When the memory limit is reached Redis will try to remove keys with an
93
+ # EXPIRE set. It will try to start freeing keys that are going to expire
94
+ # in little time and preserve keys with a longer time to live.
95
+ # Redis will also try to remove objects from free lists if possible.
96
+ #
97
+ # If all this fails, Redis will start to reply with errors to commands
98
+ # that will use more memory, like SET, LPUSH, and so on, and will continue
99
+ # to reply to most read-only commands like GET.
100
+ #
101
+ # WARNING: maxmemory can be a good idea mainly if you want to use Redis as a
102
+ # 'state' server or cache, not as a real DB. When Redis is used as a real
103
+ # database the memory usage will grow over the weeks, it will be obvious if
104
+ # it is going to use too much memory in the long run, and you'll have the time
105
+ # to upgrade. With maxmemory after the limit is reached you'll start to get
106
+ # errors for write operations, and this may even lead to DB inconsistency.
107
+
108
+ # maxmemory <bytes>
109
+
110
+ ############################### ADVANCED CONFIG ###############################
111
+
112
+ # Glue small output buffers together in order to send small replies in a
113
+ # single TCP packet. Uses a bit more CPU but most of the times it is a win
114
+ # in terms of number of queries per second. Use 'yes' if unsure.
115
+ glueoutputbuf yes
@@ -0,0 +1,32 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ # Pull in the server test_helper from resque
4
+ require 'resque/server/test_helper.rb'
5
+
6
+ context "on GET to /schedule" do
7
+ setup { get "/schedule" }
8
+
9
+ should_respond_with_success
10
+ end
11
+
12
+ context "on GET to /schedule with scheduled jobs" do
13
+ setup do
14
+ ENV['rails_env'] = 'production'
15
+ Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'production'},
16
+ :some_other_job => {'queue' => 'high', 'class' => 'SomeOtherJob', 'args' => {:b => 'blah'}}}
17
+ Resque::Scheduler.load_schedule!
18
+ get "/schedule"
19
+ end
20
+
21
+ should_respond_with_success
22
+
23
+ test 'see the scheduled job' do
24
+ assert last_response.body.include?('SomeIvarJob')
25
+ end
26
+ end
27
+
28
+ context "on GET to /delayed" do
29
+ setup { get "/delayed" }
30
+
31
+ should_respond_with_success
32
+ end
@@ -0,0 +1,93 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ context "scheduling jobs with arguments" do
4
+ setup { Resque::Scheduler.clear_schedule! }
5
+
6
+ test "calls the worker without arguments when 'args' is missing from the config" do
7
+ Resque::Scheduler.enqueue_from_config(YAML.load(<<-YAML))
8
+ class: SomeIvarJob
9
+ YAML
10
+ SomeIvarJob.expects(:perform).once.with()
11
+ Resque.reserve('ivar').perform
12
+ end
13
+
14
+ test "calls the worker without arguments when 'args' is blank in the config" do
15
+ Resque::Scheduler.enqueue_from_config(YAML.load(<<-YAML))
16
+ class: SomeIvarJob
17
+ args:
18
+ YAML
19
+ SomeIvarJob.expects(:perform).once.with()
20
+ Resque.reserve('ivar').perform
21
+ end
22
+
23
+ test "calls the worker with a string when the config lists a string" do
24
+ Resque::Scheduler.enqueue_from_config(YAML.load(<<-YAML))
25
+ class: SomeIvarJob
26
+ args: string
27
+ YAML
28
+ SomeIvarJob.expects(:perform).once.with('string')
29
+ Resque.reserve('ivar').perform
30
+ end
31
+
32
+ test "calls the worker with a Fixnum when the config lists an integer" do
33
+ Resque::Scheduler.enqueue_from_config(YAML.load(<<-YAML))
34
+ class: SomeIvarJob
35
+ args: 1
36
+ YAML
37
+ SomeIvarJob.expects(:perform).once.with(1)
38
+ Resque.reserve('ivar').perform
39
+ end
40
+
41
+ test "calls the worker with multiple arguments when the config lists an array" do
42
+ Resque::Scheduler.enqueue_from_config(YAML.load(<<-YAML))
43
+ class: SomeIvarJob
44
+ args:
45
+ - 1
46
+ - 2
47
+ YAML
48
+ SomeIvarJob.expects(:perform).once.with(1, 2)
49
+ Resque.reserve('ivar').perform
50
+ end
51
+
52
+ test "calls the worker with an array when the config lists a nested array" do
53
+ Resque::Scheduler.enqueue_from_config(YAML.load(<<-YAML))
54
+ class: SomeIvarJob
55
+ args:
56
+ - - 1
57
+ - 2
58
+ YAML
59
+ SomeIvarJob.expects(:perform).once.with([1, 2])
60
+ Resque.reserve('ivar').perform
61
+ end
62
+
63
+ test "calls the worker with a hash when the config lists a hash" do
64
+ Resque::Scheduler.enqueue_from_config(YAML.load(<<-YAML))
65
+ class: SomeIvarJob
66
+ args:
67
+ key: value
68
+ YAML
69
+ SomeIvarJob.expects(:perform).once.with('key' => 'value')
70
+ Resque.reserve('ivar').perform
71
+ end
72
+
73
+ test "calls the worker with a nested hash when the config lists a nested hash" do
74
+ Resque::Scheduler.enqueue_from_config(YAML.load(<<-YAML))
75
+ class: SomeIvarJob
76
+ args:
77
+ first_key:
78
+ second_key: value
79
+ YAML
80
+ SomeIvarJob.expects(:perform).once.with('first_key' => {'second_key' => 'value'})
81
+ Resque.reserve('ivar').perform
82
+ end
83
+
84
+ test "poll_sleep_amount defaults to 5" do
85
+ assert_equal 5, Resque::Scheduler.poll_sleep_amount
86
+ end
87
+
88
+ test "poll_sleep_amount is settable" do
89
+ Resque::Scheduler.poll_sleep_amount = 1
90
+ assert_equal 1, Resque::Scheduler.poll_sleep_amount
91
+ end
92
+
93
+ end
@@ -0,0 +1,268 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Resque::SchedulerTest < Test::Unit::TestCase
4
+
5
+ class FakeJob
6
+ def self.scheduled(queue, klass, *args); end
7
+ end
8
+
9
+ def setup
10
+ Resque::Scheduler.dynamic = false
11
+ Resque.redis.del(:schedules)
12
+ Resque.redis.del(:schedules_changed)
13
+ Resque::Scheduler.mute = true
14
+ Resque::Scheduler.clear_schedule!
15
+ Resque::Scheduler.send(:class_variable_set, :@@scheduled_jobs, {})
16
+ end
17
+
18
+ def test_enqueue_from_config_puts_stuff_in_the_resque_queue_without_class_loaded
19
+ Resque::Job.stubs(:create).once.returns(true).with('joes_queue', 'BigJoesJob', '/tmp')
20
+ Resque::Scheduler.enqueue_from_config('cron' => "* * * * *", 'class' => 'BigJoesJob', 'args' => "/tmp", 'queue' => 'joes_queue')
21
+ end
22
+
23
+ def test_enqueue_from_config_with_every_syntax
24
+ Resque::Job.stubs(:create).once.returns(true).with('james_queue', 'JamesJob', '/tmp')
25
+ Resque::Scheduler.enqueue_from_config('every' => '1m', 'class' => 'JamesJob', 'args' => '/tmp', 'queue' => 'james_queue')
26
+ end
27
+
28
+ def test_enqueue_from_config_doesnt_crash_on_exception_when_enqueueing
29
+ Resque::Job.stubs(:create).raises(Resque::NoQueueError, 'test exception').with(:ivar, 'SomeIvarJob', '/tmp')
30
+ Resque::Scheduler.enqueue_from_config('cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp")
31
+ end
32
+
33
+ def test_enqueue_from_config_puts_stuff_in_the_resque_queue
34
+ Resque::Job.stubs(:create).once.returns(true).with(:ivar, SomeIvarJob, '/tmp')
35
+ Resque::Scheduler.enqueue_from_config('cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp")
36
+ end
37
+
38
+ def test_enqueue_from_config_with_custom_class_job_in_the_resque_queue
39
+ FakeJob.stubs(:scheduled).once.returns(true).with(:ivar, 'SomeIvarJob', '/tmp')
40
+ Resque::Scheduler.enqueue_from_config('cron' => "* * * * *", 'class' => 'SomeIvarJob', 'custom_job_class' => 'Resque::SchedulerTest::FakeJob', 'args' => "/tmp")
41
+ end
42
+
43
+ def test_enqueue_from_config_puts_stuff_in_the_resque_queue_when_env_match
44
+ # The job should be loaded : its rails_env config matches the RAILS_ENV variable:
45
+ ENV['RAILS_ENV'] = 'production'
46
+ assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
47
+
48
+ Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'production'}}
49
+ Resque::Scheduler.load_schedule!
50
+ assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
51
+
52
+ # we allow multiple rails_env definition, it should work also:
53
+ Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'staging, production'}}
54
+ Resque::Scheduler.load_schedule!
55
+ assert_equal(2, Resque::Scheduler.rufus_scheduler.all_jobs.size)
56
+ end
57
+
58
+ def test_enqueue_from_config_dont_puts_stuff_in_the_resque_queue_when_env_doesnt_match
59
+ # RAILS_ENV is not set:
60
+ assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
61
+ Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'staging'}}
62
+ Resque::Scheduler.load_schedule!
63
+ assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
64
+
65
+ # SET RAILS_ENV to a common value:
66
+ ENV['RAILS_ENV'] = 'production'
67
+ Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp", 'rails_env' => 'staging'}}
68
+ Resque::Scheduler.load_schedule!
69
+ assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
70
+ end
71
+
72
+ def test_enqueue_from_config_when_rails_env_arg_is_not_set
73
+ # The job should be loaded, since a missing rails_env means ALL envs.
74
+ ENV['RAILS_ENV'] = 'production'
75
+ assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
76
+ Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"}}
77
+ Resque::Scheduler.load_schedule!
78
+ assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
79
+ end
80
+
81
+ def test_enqueue_constantizes
82
+ # The job should be loaded, since a missing rails_env means ALL envs.
83
+ ENV['RAILS_ENV'] = 'production'
84
+ config = {'cron' => "* * * * *", 'class' => 'SomeRealClass', 'args' => "/tmp"}
85
+ Resque::Job.expects(:create).with(SomeRealClass.queue, SomeRealClass, '/tmp')
86
+ Resque::Scheduler.enqueue_from_config(config)
87
+ end
88
+
89
+ def test_enqueue_runs_hooks
90
+ # The job should be loaded, since a missing rails_env means ALL envs.
91
+ ENV['RAILS_ENV'] = 'production'
92
+ config = {'cron' => "* * * * *", 'class' => 'SomeRealClass', 'args' => "/tmp"}
93
+
94
+ Resque::Job.expects(:create).with(SomeRealClass.queue, SomeRealClass, '/tmp')
95
+ SomeRealClass.expects(:after_enqueue_example)
96
+
97
+ Resque::Scheduler.enqueue_from_config(config)
98
+ end
99
+
100
+ def test_config_makes_it_into_the_rufus_scheduler
101
+ assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
102
+
103
+ Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"}}
104
+ Resque::Scheduler.load_schedule!
105
+
106
+ assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
107
+ assert Resque::Scheduler.scheduled_jobs.include?(:some_ivar_job)
108
+ end
109
+
110
+ def test_can_reload_schedule
111
+ Resque::Scheduler.dynamic = true
112
+ Resque.schedule = {"some_ivar_job" => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"}}
113
+
114
+ Resque::Scheduler.load_schedule!
115
+
116
+ assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
117
+ assert Resque::Scheduler.scheduled_jobs.include?("some_ivar_job")
118
+
119
+ Resque.redis.del(:schedules)
120
+ Resque.redis.hset(:schedules, "some_ivar_job2", Resque.encode(
121
+ {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/2"}
122
+ ))
123
+
124
+ Resque::Scheduler.reload_schedule!
125
+
126
+ assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
127
+
128
+ assert_equal '/tmp/2', Resque.schedule["some_ivar_job2"]["args"]
129
+ assert Resque::Scheduler.scheduled_jobs.include?("some_ivar_job2")
130
+ end
131
+
132
+ def test_load_schedule_job
133
+ Resque::Scheduler.load_schedule_job("some_ivar_job", {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"})
134
+
135
+ assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
136
+ assert_equal(1, Resque::Scheduler.scheduled_jobs.size)
137
+ assert Resque::Scheduler.scheduled_jobs.keys.include?("some_ivar_job")
138
+ end
139
+
140
+ def test_load_schedule_job_with_no_cron
141
+ Resque::Scheduler.load_schedule_job("some_ivar_job", {'class' => 'SomeIvarJob', 'args' => "/tmp"})
142
+
143
+ assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
144
+ assert_equal(0, Resque::Scheduler.scheduled_jobs.size)
145
+ assert !Resque::Scheduler.scheduled_jobs.keys.include?("some_ivar_job")
146
+ end
147
+
148
+ def test_load_schedule_job_with_blank_cron
149
+ Resque::Scheduler.load_schedule_job("some_ivar_job", {'cron' => '', 'class' => 'SomeIvarJob', 'args' => "/tmp"})
150
+
151
+ assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
152
+ assert_equal(0, Resque::Scheduler.scheduled_jobs.size)
153
+ assert !Resque::Scheduler.scheduled_jobs.keys.include?("some_ivar_job")
154
+ end
155
+
156
+ def test_update_schedule
157
+ Resque::Scheduler.dynamic = true
158
+ Resque.schedule = {
159
+ "some_ivar_job" => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"},
160
+ "another_ivar_job" => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/5"},
161
+ "stay_put_job" => {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp"}
162
+ }
163
+
164
+ Resque::Scheduler.load_schedule!
165
+
166
+ Resque.set_schedule("some_ivar_job",
167
+ {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/2"}
168
+ )
169
+ Resque.set_schedule("new_ivar_job",
170
+ {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp/3"}
171
+ )
172
+ Resque.set_schedule("stay_put_job",
173
+ {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp"}
174
+ )
175
+ Resque.remove_schedule("another_ivar_job")
176
+
177
+ Resque::Scheduler.update_schedule
178
+
179
+ assert_equal(3, Resque::Scheduler.rufus_scheduler.all_jobs.size)
180
+ assert_equal(3, Resque::Scheduler.scheduled_jobs.size)
181
+ %w(some_ivar_job new_ivar_job stay_put_job).each do |job_name|
182
+ assert Resque::Scheduler.scheduled_jobs.keys.include?(job_name)
183
+ assert Resque.schedule.keys.include?(job_name)
184
+ end
185
+ assert !Resque::Scheduler.scheduled_jobs.keys.include?("another_ivar_job")
186
+ assert !Resque.schedule.keys.include?("another_ivar_job")
187
+ assert_equal 0, Resque.redis.scard(:schedules_changed)
188
+ end
189
+
190
+ def test_update_schedule_with_mocks
191
+ Resque::Scheduler.dynamic = true
192
+ Resque.schedule = {
193
+ "some_ivar_job" => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"},
194
+ "another_ivar_job" => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/5"},
195
+ "stay_put_job" => {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp"}
196
+ }
197
+
198
+ Resque::Scheduler.load_schedule!
199
+
200
+ Resque::Scheduler.rufus_scheduler.expects(:unschedule).with(Resque::Scheduler.scheduled_jobs["some_ivar_job"].job_id)
201
+ Resque::Scheduler.rufus_scheduler.expects(:unschedule).with(Resque::Scheduler.scheduled_jobs["another_ivar_job"].job_id)
202
+
203
+ Resque.set_schedule("some_ivar_job",
204
+ {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/2"}
205
+ )
206
+ Resque.set_schedule("new_ivar_job",
207
+ {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp/3"}
208
+ )
209
+ Resque.set_schedule("stay_put_job",
210
+ {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp"}
211
+ )
212
+ Resque.remove_schedule("another_ivar_job")
213
+
214
+ Resque::Scheduler.update_schedule
215
+
216
+ assert_equal(3, Resque::Scheduler.scheduled_jobs.size)
217
+ %w(some_ivar_job new_ivar_job stay_put_job).each do |job_name|
218
+ assert Resque::Scheduler.scheduled_jobs.keys.include?(job_name)
219
+ assert Resque.schedule.keys.include?(job_name)
220
+ end
221
+ assert !Resque::Scheduler.scheduled_jobs.keys.include?("another_ivar_job")
222
+ assert !Resque.schedule.keys.include?("another_ivar_job")
223
+ assert_equal 0, Resque.redis.scard(:schedules_changed)
224
+ end
225
+
226
+ def test_set_schedules
227
+ Resque::Scheduler.dynamic = true
228
+ Resque.schedule = {"my_ivar_job" => {
229
+ 'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/75"
230
+ }}
231
+ assert_equal({'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/75"},
232
+ Resque.decode(Resque.redis.hget(:schedules, "my_ivar_job")))
233
+ end
234
+
235
+ def test_set_schedule
236
+ Resque.set_schedule("some_ivar_job", {
237
+ 'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/22"
238
+ })
239
+ assert_equal({'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/22"},
240
+ Resque.decode(Resque.redis.hget(:schedules, "some_ivar_job")))
241
+ assert Resque.redis.sismember(:schedules_changed, "some_ivar_job")
242
+ end
243
+
244
+ def test_get_schedule
245
+ Resque.redis.hset(:schedules, "some_ivar_job2", Resque.encode(
246
+ {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/33"}
247
+ ))
248
+ assert_equal({'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/33"},
249
+ Resque.get_schedule("some_ivar_job2"))
250
+ end
251
+
252
+ def test_remove_schedule
253
+ Resque.redis.hset(:schedules, "some_ivar_job3", Resque.encode(
254
+ {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/44"}
255
+ ))
256
+ Resque.remove_schedule("some_ivar_job3")
257
+ assert_equal nil, Resque.redis.hget(:schedules, "some_ivar_job3")
258
+ assert Resque.redis.sismember(:schedules_changed, "some_ivar_job3")
259
+ end
260
+
261
+ def test_adheres_to_lint
262
+ assert_nothing_raised do
263
+ Resque::Plugin.lint(Resque::Scheduler)
264
+ Resque::Plugin.lint(ResqueScheduler)
265
+ end
266
+ end
267
+
268
+ end