scotttam-resque 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/.gitignore +3 -0
  2. data/.kick +26 -0
  3. data/CONTRIBUTORS +23 -0
  4. data/HISTORY.md +80 -0
  5. data/LICENSE +20 -0
  6. data/README.markdown +767 -0
  7. data/Rakefile +66 -0
  8. data/bin/resque +57 -0
  9. data/bin/resque-web +18 -0
  10. data/config.ru +14 -0
  11. data/deps.rip +6 -0
  12. data/examples/async_helper.rb +31 -0
  13. data/examples/demo/README.markdown +71 -0
  14. data/examples/demo/Rakefile +3 -0
  15. data/examples/demo/app.rb +38 -0
  16. data/examples/demo/config.ru +19 -0
  17. data/examples/demo/job.rb +22 -0
  18. data/examples/god/resque.god +53 -0
  19. data/examples/god/stale.god +26 -0
  20. data/examples/instance.rb +11 -0
  21. data/examples/simple.rb +30 -0
  22. data/init.rb +1 -0
  23. data/lib/resque/errors.rb +7 -0
  24. data/lib/resque/failure/base.rb +58 -0
  25. data/lib/resque/failure/hoptoad.rb +121 -0
  26. data/lib/resque/failure/multiple.rb +44 -0
  27. data/lib/resque/failure/redis.rb +33 -0
  28. data/lib/resque/failure.rb +63 -0
  29. data/lib/resque/helpers.rb +57 -0
  30. data/lib/resque/job.rb +146 -0
  31. data/lib/resque/server/public/idle.png +0 -0
  32. data/lib/resque/server/public/jquery-1.3.2.min.js +19 -0
  33. data/lib/resque/server/public/jquery.relatize_date.js +95 -0
  34. data/lib/resque/server/public/poll.png +0 -0
  35. data/lib/resque/server/public/ranger.js +24 -0
  36. data/lib/resque/server/public/reset.css +48 -0
  37. data/lib/resque/server/public/style.css +76 -0
  38. data/lib/resque/server/public/working.png +0 -0
  39. data/lib/resque/server/views/error.erb +1 -0
  40. data/lib/resque/server/views/failed.erb +35 -0
  41. data/lib/resque/server/views/key.erb +17 -0
  42. data/lib/resque/server/views/layout.erb +38 -0
  43. data/lib/resque/server/views/next_more.erb +10 -0
  44. data/lib/resque/server/views/overview.erb +4 -0
  45. data/lib/resque/server/views/queues.erb +46 -0
  46. data/lib/resque/server/views/stats.erb +62 -0
  47. data/lib/resque/server/views/workers.erb +78 -0
  48. data/lib/resque/server/views/working.erb +69 -0
  49. data/lib/resque/server.rb +187 -0
  50. data/lib/resque/stat.rb +53 -0
  51. data/lib/resque/tasks.rb +39 -0
  52. data/lib/resque/version.rb +3 -0
  53. data/lib/resque/worker.rb +453 -0
  54. data/lib/resque.rb +246 -0
  55. data/tasks/redis.rake +135 -0
  56. data/tasks/resque.rake +2 -0
  57. data/test/redis-test.conf +132 -0
  58. data/test/resque_test.rb +220 -0
  59. data/test/test_helper.rb +96 -0
  60. data/test/worker_test.rb +260 -0
  61. metadata +172 -0
data/tasks/redis.rake ADDED
@@ -0,0 +1,135 @@
1
+ # Inspired by rabbitmq.rake the Redbox project at http://github.com/rick/redbox/tree/master
2
+ require 'fileutils'
3
+ require 'open-uri'
4
+
5
+ class RedisRunner
6
+
7
+ def self.redisdir
8
+ "/tmp/redis/"
9
+ end
10
+
11
+ def self.redisconfdir
12
+ server_dir = File.dirname(`which redis-server`)
13
+ conf_file = "#{server_dir}/../etc/redis.conf"
14
+ unless File.exists? conf_file
15
+ conf_file = "#{server_dir}/../../etc/redis.conf"
16
+ end
17
+ conf_file
18
+ end
19
+
20
+ def self.dtach_socket
21
+ '/tmp/redis.dtach'
22
+ end
23
+
24
+ # Just check for existance of dtach socket
25
+ def self.running?
26
+ File.exists? dtach_socket
27
+ end
28
+
29
+ def self.start
30
+ puts 'Detach with Ctrl+\ Re-attach with rake redis:attach'
31
+ sleep 1
32
+ command = "dtach -A #{dtach_socket} redis-server #{redisconfdir}"
33
+ sh command
34
+ end
35
+
36
+ def self.attach
37
+ exec "dtach -a #{dtach_socket}"
38
+ end
39
+
40
+ def self.stop
41
+ sh 'echo "SHUTDOWN" | nc localhost 6379'
42
+ end
43
+
44
+ end
45
+
46
+ namespace :redis do
47
+
48
+ desc 'About redis'
49
+ task :about do
50
+ puts "\nSee http://code.google.com/p/redis/ for information about redis.\n\n"
51
+ end
52
+
53
+ desc 'Start redis'
54
+ task :start do
55
+ RedisRunner.start
56
+ end
57
+
58
+ desc 'Stop redis'
59
+ task :stop do
60
+ RedisRunner.stop
61
+ end
62
+
63
+ desc 'Restart redis'
64
+ task :restart do
65
+ RedisRunner.stop
66
+ RedisRunner.start
67
+ end
68
+
69
+ desc 'Attach to redis dtach socket'
70
+ task :attach do
71
+ RedisRunner.attach
72
+ end
73
+
74
+ desc 'Install the latest verison of Redis from Github (requires git, duh)'
75
+ task :install => [:about, :download, :make] do
76
+ ENV['PREFIX'] and bin_dir = "#{ENV['PREFIX']}/bin" or bin_dir = '/usr/bin'
77
+ %w(redis-benchmark redis-cli redis-server).each do |bin|
78
+ sh "cp /tmp/redis/#{bin} #{bin_dir}"
79
+ end
80
+
81
+ puts "Installed redis-benchmark, redis-cli and redis-server to #{bin_dir}"
82
+
83
+ ENV['PREFIX'] and conf_dir = "#{ENV['PREFIX']}/etc" or conf_dir = '/etc'
84
+ unless File.exists?("#{conf_dir}/redis.conf")
85
+ sh "mkdir #{conf_dir}" unless File.exists?("#{conf_dir}")
86
+ sh "cp /tmp/redis/redis.conf #{conf_dir}/redis.conf"
87
+ puts "Installed redis.conf to #{conf_dir} \n You should look at this file!"
88
+ end
89
+ end
90
+
91
+ task :make do
92
+ sh "cd #{RedisRunner.redisdir} && make clean"
93
+ sh "cd #{RedisRunner.redisdir} && make"
94
+ end
95
+
96
+ desc "Download package"
97
+ task :download do
98
+ sh 'rm -rf /tmp/redis/' if File.exists?("#{RedisRunner.redisdir}/.svn")
99
+ sh 'git clone git://github.com/antirez/redis.git /tmp/redis' unless File.exists?(RedisRunner.redisdir)
100
+ sh "cd #{RedisRunner.redisdir} && git pull" if File.exists?("#{RedisRunner.redisdir}/.git")
101
+ end
102
+
103
+ end
104
+
105
+ namespace :dtach do
106
+
107
+ desc 'About dtach'
108
+ task :about do
109
+ puts "\nSee http://dtach.sourceforge.net/ for information about dtach.\n\n"
110
+ end
111
+
112
+ desc 'Install dtach 0.8 from source'
113
+ task :install => [:about] do
114
+
115
+ Dir.chdir('/tmp/')
116
+ unless File.exists?('/tmp/dtach-0.8.tar.gz')
117
+ require 'net/http'
118
+
119
+ url = 'http://downloads.sourceforge.net/project/dtach/dtach/0.8/dtach-0.8.tar.gz'
120
+ open('/tmp/dtach-0.8.tar.gz', 'wb') do |file| file.write(open(url).read) end
121
+ end
122
+
123
+ unless File.directory?('/tmp/dtach-0.8')
124
+ system('tar xzf dtach-0.8.tar.gz')
125
+ end
126
+
127
+ ENV['PREFIX'] and bin_dir = "#{ENV['PREFIX']}/bin" or bin_dir = "/usr/bin"
128
+ Dir.chdir('/tmp/dtach-0.8/')
129
+ sh 'cd /tmp/dtach-0.8/ && ./configure && make'
130
+ sh "cp /tmp/dtach-0.8/dtach #{bin_dir}"
131
+
132
+ puts "Dtach successfully installed to #{bin_dir}"
133
+ end
134
+ end
135
+
data/tasks/resque.rake ADDED
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'resque/tasks'
@@ -0,0 +1,132 @@
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
116
+
117
+ # Use object sharing. Can save a lot of memory if you have many common
118
+ # string in your dataset, but performs lookups against the shared objects
119
+ # pool so it uses more CPU and can be a bit slower. Usually it's a good
120
+ # idea.
121
+ #
122
+ # When object sharing is enabled (shareobjects yes) you can use
123
+ # shareobjectspoolsize to control the size of the pool used in order to try
124
+ # object sharing. A bigger pool size will lead to better sharing capabilities.
125
+ # In general you want this value to be at least the double of the number of
126
+ # very common strings you have in your dataset.
127
+ #
128
+ # WARNING: object sharing is experimental, don't enable this feature
129
+ # in production before of Redis 1.0-stable. Still please try this feature in
130
+ # your development environment so that we can test it better.
131
+ shareobjects no
132
+ shareobjectspoolsize 1024
@@ -0,0 +1,220 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ context "Resque" do
4
+ setup do
5
+ Resque.redis.flush_all
6
+
7
+ Resque.push(:people, { 'name' => 'chris' })
8
+ Resque.push(:people, { 'name' => 'bob' })
9
+ Resque.push(:people, { 'name' => 'mark' })
10
+ end
11
+
12
+ test "can put jobs on a queue" do
13
+ assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
14
+ assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
15
+ end
16
+
17
+ test "can grab jobs off a queue" do
18
+ Resque::Job.create(:jobs, 'some-job', 20, '/tmp')
19
+
20
+ job = Resque.reserve(:jobs)
21
+
22
+ assert_kind_of Resque::Job, job
23
+ assert_equal SomeJob, job.payload_class
24
+ assert_equal 20, job.args[0]
25
+ assert_equal '/tmp', job.args[1]
26
+ end
27
+
28
+ test "can re-queue jobs" do
29
+ Resque::Job.create(:jobs, 'some-job', 20, '/tmp')
30
+
31
+ job = Resque.reserve(:jobs)
32
+ job.recreate
33
+
34
+ assert_equal job, Resque.reserve(:jobs)
35
+ end
36
+
37
+ test "can put jobs on a queue by way of an ivar" do
38
+ assert_equal 0, Resque.size(:ivar)
39
+ assert Resque.enqueue(SomeIvarJob, 20, '/tmp')
40
+ assert Resque.enqueue(SomeIvarJob, 20, '/tmp')
41
+
42
+ job = Resque.reserve(:ivar)
43
+
44
+ assert_kind_of Resque::Job, job
45
+ assert_equal SomeIvarJob, job.payload_class
46
+ assert_equal 20, job.args[0]
47
+ assert_equal '/tmp', job.args[1]
48
+
49
+ assert Resque.reserve(:ivar)
50
+ assert_equal nil, Resque.reserve(:ivar)
51
+ end
52
+
53
+ test "can remove jobs from a queue by way of an ivar" do
54
+ assert_equal 0, Resque.size(:ivar)
55
+ assert Resque.enqueue(SomeIvarJob, 20, '/tmp')
56
+ assert Resque.enqueue(SomeIvarJob, 30, '/tmp')
57
+ assert Resque.enqueue(SomeIvarJob, 20, '/tmp')
58
+ assert Resque::Job.create(:ivar, 'blah-job', 20, '/tmp')
59
+ assert Resque.enqueue(SomeIvarJob, 20, '/tmp')
60
+ assert_equal 5, Resque.size(:ivar)
61
+
62
+ assert Resque.dequeue(SomeIvarJob, 30, '/tmp')
63
+ assert_equal 4, Resque.size(:ivar)
64
+ assert Resque.dequeue(SomeIvarJob)
65
+ assert_equal 1, Resque.size(:ivar)
66
+ end
67
+
68
+ test "jobs have a nice #inspect" do
69
+ assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
70
+ job = Resque.reserve(:jobs)
71
+ assert_equal '(Job{jobs} | SomeJob | [20, "/tmp"])', job.inspect
72
+ end
73
+
74
+ test "jobs can be destroyed" do
75
+ assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
76
+ assert Resque::Job.create(:jobs, 'BadJob', 20, '/tmp')
77
+ assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
78
+ assert Resque::Job.create(:jobs, 'BadJob', 30, '/tmp')
79
+ assert Resque::Job.create(:jobs, 'BadJob', 20, '/tmp')
80
+
81
+ assert_equal 5, Resque.size(:jobs)
82
+ assert_equal 2, Resque::Job.destroy(:jobs, 'SomeJob')
83
+ assert_equal 3, Resque.size(:jobs)
84
+ assert_equal 1, Resque::Job.destroy(:jobs, 'BadJob', 30, '/tmp')
85
+ assert_equal 2, Resque.size(:jobs)
86
+ end
87
+
88
+ test "jobs can test for equality" do
89
+ assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
90
+ assert Resque::Job.create(:jobs, 'some-job', 20, '/tmp')
91
+ assert_equal Resque.reserve(:jobs), Resque.reserve(:jobs)
92
+
93
+ assert Resque::Job.create(:jobs, 'SomeMethodJob', 20, '/tmp')
94
+ assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
95
+ assert_not_equal Resque.reserve(:jobs), Resque.reserve(:jobs)
96
+
97
+ assert Resque::Job.create(:jobs, 'SomeJob', 20, '/tmp')
98
+ assert Resque::Job.create(:jobs, 'SomeJob', 30, '/tmp')
99
+ assert_not_equal Resque.reserve(:jobs), Resque.reserve(:jobs)
100
+ end
101
+
102
+ test "can put jobs on a queue by way of a method" do
103
+ assert_equal 0, Resque.size(:method)
104
+ assert Resque.enqueue(SomeMethodJob, 20, '/tmp')
105
+ assert Resque.enqueue(SomeMethodJob, 20, '/tmp')
106
+
107
+ job = Resque.reserve(:method)
108
+
109
+ assert_kind_of Resque::Job, job
110
+ assert_equal SomeMethodJob, job.payload_class
111
+ assert_equal 20, job.args[0]
112
+ assert_equal '/tmp', job.args[1]
113
+
114
+ assert Resque.reserve(:method)
115
+ assert_equal nil, Resque.reserve(:method)
116
+ end
117
+
118
+ test "needs to infer a queue with enqueue" do
119
+ assert_raises Resque::NoQueueError do
120
+ Resque.enqueue(SomeJob, 20, '/tmp')
121
+ end
122
+ end
123
+
124
+ test "can put items on a queue" do
125
+ assert Resque.push(:people, { 'name' => 'jon' })
126
+ end
127
+
128
+ test "can pull items off a queue" do
129
+ assert_equal({ 'name' => 'chris' }, Resque.pop(:people))
130
+ assert_equal({ 'name' => 'bob' }, Resque.pop(:people))
131
+ assert_equal({ 'name' => 'mark' }, Resque.pop(:people))
132
+ assert_equal nil, Resque.pop(:people)
133
+ end
134
+
135
+ test "knows how big a queue is" do
136
+ assert_equal 3, Resque.size(:people)
137
+
138
+ assert_equal({ 'name' => 'chris' }, Resque.pop(:people))
139
+ assert_equal 2, Resque.size(:people)
140
+
141
+ assert_equal({ 'name' => 'bob' }, Resque.pop(:people))
142
+ assert_equal({ 'name' => 'mark' }, Resque.pop(:people))
143
+ assert_equal 0, Resque.size(:people)
144
+ end
145
+
146
+ test "can peek at a queue" do
147
+ assert_equal({ 'name' => 'chris' }, Resque.peek(:people))
148
+ assert_equal 3, Resque.size(:people)
149
+ end
150
+
151
+ test "can peek multiple items on a queue" do
152
+ assert_equal({ 'name' => 'bob' }, Resque.peek(:people, 1, 1))
153
+
154
+ assert_equal([{ 'name' => 'bob' }, { 'name' => 'mark' }], Resque.peek(:people, 1, 2))
155
+ assert_equal([{ 'name' => 'chris' }, { 'name' => 'bob' }], Resque.peek(:people, 0, 2))
156
+ assert_equal([{ 'name' => 'chris' }, { 'name' => 'bob' }, { 'name' => 'mark' }], Resque.peek(:people, 0, 3))
157
+ assert_equal({ 'name' => 'mark' }, Resque.peek(:people, 2, 1))
158
+ assert_equal nil, Resque.peek(:people, 3)
159
+ assert_equal [], Resque.peek(:people, 3, 2)
160
+ end
161
+
162
+ test "knows what queues it is managing" do
163
+ assert_equal %w( people ), Resque.queues
164
+ Resque.push(:cars, { 'make' => 'bmw' })
165
+ assert_equal %w( cars people ), Resque.queues
166
+ end
167
+
168
+ test "queues are always a list" do
169
+ Resque.redis.flush_all
170
+ assert_equal [], Resque.queues
171
+ end
172
+
173
+ test "can delete a queue" do
174
+ Resque.push(:cars, { 'make' => 'bmw' })
175
+ assert_equal %w( cars people ), Resque.queues
176
+ Resque.remove_queue(:people)
177
+ assert_equal %w( cars ), Resque.queues
178
+ assert_equal nil, Resque.pop(:people)
179
+ end
180
+
181
+ test "keeps track of resque keys" do
182
+ assert_equal ["queue:people", "queues"], Resque.keys
183
+ end
184
+
185
+ test "badly wants a class name, too" do
186
+ assert_raises Resque::NoClassError do
187
+ Resque::Job.create(:jobs, nil)
188
+ end
189
+ end
190
+
191
+ test "keeps stats" do
192
+ Resque::Job.create(:jobs, SomeJob, 20, '/tmp')
193
+ Resque::Job.create(:jobs, BadJob)
194
+ Resque::Job.create(:jobs, GoodJob)
195
+
196
+ Resque::Job.create(:others, GoodJob)
197
+ Resque::Job.create(:others, GoodJob)
198
+
199
+ stats = Resque.info
200
+ assert_equal 8, stats[:pending]
201
+
202
+ @worker = Resque::Worker.new(:jobs)
203
+ @worker.register_worker
204
+ 2.times { @worker.process }
205
+ job = @worker.reserve
206
+ @worker.working_on job
207
+
208
+ stats = Resque.info
209
+ assert_equal 1, stats[:working]
210
+ assert_equal 1, stats[:workers]
211
+
212
+ @worker.done_working
213
+
214
+ stats = Resque.info
215
+ assert_equal 3, stats[:queues]
216
+ assert_equal 3, stats[:processed]
217
+ assert_equal 1, stats[:failed]
218
+ assert_equal ['localhost:9736'], stats[:servers]
219
+ end
220
+ end
@@ -0,0 +1,96 @@
1
+ dir = File.dirname(File.expand_path(__FILE__))
2
+ $LOAD_PATH.unshift dir + '/../lib'
3
+ $TESTING = true
4
+ require 'test/unit'
5
+ require 'rubygems'
6
+ require 'resque'
7
+
8
+
9
+ #
10
+ # make sure we can run redis
11
+ #
12
+
13
+ if !system("which redis-server")
14
+ puts '', "** can't find `redis-server` in your path"
15
+ puts "** try running `sudo rake install`"
16
+ abort ''
17
+ end
18
+
19
+
20
+ #
21
+ # start our own redis when the tests start,
22
+ # kill it when they end
23
+ #
24
+
25
+ at_exit do
26
+ next if $!
27
+
28
+ if defined?(MiniTest)
29
+ exit_code = MiniTest::Unit.new.run(ARGV)
30
+ else
31
+ exit_code = Test::Unit::AutoRunner.run
32
+ end
33
+
34
+ pid = `ps -e -o pid,command | grep [r]edis-test`.split(" ")[0]
35
+ puts "Killing test redis server..."
36
+ `rm -f #{dir}/dump.rdb`
37
+ Process.kill("KILL", pid.to_i)
38
+ exit exit_code
39
+ end
40
+
41
+ puts "Starting redis for testing at localhost:9736..."
42
+ `redis-server #{dir}/redis-test.conf`
43
+ Resque.redis = 'localhost:9736'
44
+
45
+
46
+ ##
47
+ # test/spec/mini 3
48
+ # http://gist.github.com/25455
49
+ # chris@ozmm.org
50
+ #
51
+ def context(*args, &block)
52
+ return super unless (name = args.first) && block
53
+ require 'test/unit'
54
+ klass = Class.new(defined?(ActiveSupport::TestCase) ? ActiveSupport::TestCase : Test::Unit::TestCase) do
55
+ def self.test(name, &block)
56
+ define_method("test_#{name.gsub(/\W/,'_')}", &block) if block
57
+ end
58
+ def self.xtest(*args) end
59
+ def self.setup(&block) define_method(:setup, &block) end
60
+ def self.teardown(&block) define_method(:teardown, &block) end
61
+ end
62
+ (class << klass; self end).send(:define_method, :name) { name.gsub(/\W/,'_') }
63
+ klass.class_eval &block
64
+ end
65
+
66
+
67
+ #
68
+ # fixture classes
69
+ #
70
+
71
+ class SomeJob
72
+ def self.perform(repo_id, path)
73
+ end
74
+ end
75
+
76
+ class SomeIvarJob < SomeJob
77
+ @queue = :ivar
78
+ end
79
+
80
+ class SomeMethodJob < SomeJob
81
+ def self.queue
82
+ :method
83
+ end
84
+ end
85
+
86
+ class BadJob
87
+ def self.perform
88
+ raise "Bad job!"
89
+ end
90
+ end
91
+
92
+ class GoodJob
93
+ def self.perform(name)
94
+ "Good job, #{name}"
95
+ end
96
+ end