resque-status 0.4.3 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +2 -2
- data/README.rdoc +30 -47
- data/lib/resque/plugins/status.rb +2 -2
- data/lib/resque/plugins/status/hash.rb +12 -6
- data/lib/resque/server/views/status.erb +5 -3
- data/lib/resque/server/views/status_styles.erb +6 -0
- data/lib/resque/server/views/statuses.erb +13 -11
- data/lib/resque/status_server.rb +9 -5
- data/resque-status.gemspec +4 -4
- data/test/redis-test.conf +3 -8
- data/test/test_helper.rb +12 -22
- data/test/test_resque_plugins_status.rb +97 -93
- data/test/test_resque_plugins_status_hash.rb +49 -49
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae0e88243130c82e68fd3c7067afe397241581f9
|
4
|
+
data.tar.gz: db0b3eb29ed79f8508a11bef17561f525e54f37c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c38a1f2b8365011691d842b240b57e1de4a5828e199f8c2e3333ff17b20ab1991b75b25d92930ba8d2c204520ab2793b11d1c092c81e2ed6ec13e8aaba9c6c41
|
7
|
+
data.tar.gz: e5083dd52ffd3cece9dc3817ae2c0d3bc69656cbd3df19d900dbdce6096282b15e4d8eceb0187542b747c9eed864a57d6c4b86d9afa64fb7800fbefeb622d721
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -27,6 +27,7 @@ GEM
|
|
27
27
|
json (1.8.1)
|
28
28
|
metaclass (0.0.2)
|
29
29
|
mini_portile (0.5.2)
|
30
|
+
minitest (5.5.1)
|
30
31
|
mocha (0.14.0)
|
31
32
|
metaclass (~> 0.0.1)
|
32
33
|
multi_json (1.3.6)
|
@@ -50,7 +51,6 @@ GEM
|
|
50
51
|
redis-namespace (~> 1.0)
|
51
52
|
sinatra (>= 0.9.2)
|
52
53
|
vegas (~> 0.1.2)
|
53
|
-
shoulda (2.10.3)
|
54
54
|
sinatra (1.3.3)
|
55
55
|
rack (~> 1.3, >= 1.3.6)
|
56
56
|
rack-protection (~> 1.2)
|
@@ -64,6 +64,6 @@ PLATFORMS
|
|
64
64
|
|
65
65
|
DEPENDENCIES
|
66
66
|
jeweler
|
67
|
+
minitest (~> 5.5)
|
67
68
|
mocha (~> 0.9)
|
68
69
|
resque (~> 1.19)
|
69
|
-
shoulda (~> 2.10.2)
|
data/README.rdoc
CHANGED
@@ -4,25 +4,20 @@ resque-status is an extension to the resque queue system that provides simple tr
|
|
4
4
|
|
5
5
|
== About
|
6
6
|
|
7
|
-
resque-status provides a set of simple classes that extend resque's default
|
7
|
+
resque-status provides a set of simple classes that extend resque's default
|
8
8
|
functionality (with 0% monkey patching) to give apps a way to track specific
|
9
9
|
job instances and their status. It achieves this by giving job instances UUID's
|
10
10
|
and allowing the job instances to report their status from within their iterations.
|
11
11
|
|
12
12
|
== Installation
|
13
13
|
|
14
|
-
resque-status *requires Redis >= 1.1* (though I recommend getting the latest stable version).
|
15
|
-
You can download Redis here: http://code.google.com/p/redis/ or install it
|
14
|
+
resque-status *requires Redis >= 1.1* (though I recommend getting the latest stable version).
|
15
|
+
You can download Redis here: http://code.google.com/p/redis/ or install it
|
16
16
|
using homebrew (brew install redis).
|
17
17
|
|
18
18
|
Install the resque-status gem (which will pull in the dependencies).
|
19
19
|
|
20
20
|
gem install resque-status
|
21
|
-
|
22
|
-
To use with Rails 2.x, you can install as a plugin or add the gem to you're config:
|
23
|
-
|
24
|
-
# environment.rb
|
25
|
-
config.gem 'resque-status'
|
26
21
|
|
27
22
|
With newer Rails add this to your Gemfile:
|
28
23
|
|
@@ -30,64 +25,52 @@ With newer Rails add this to your Gemfile:
|
|
30
25
|
gem 'resque-status'
|
31
26
|
|
32
27
|
Then in an initializer:
|
33
|
-
|
28
|
+
|
34
29
|
# config/initializers/resque.rb
|
35
30
|
Resque.redis = "your/redis/socket" # default localhost:6379
|
36
31
|
Resque::Plugins::Status::Hash.expire_in = (24 * 60 * 60) # 24hrs in seconds
|
37
32
|
|
38
|
-
== NOTES ABOUT UPGRADING TO >= v0.3
|
39
|
-
|
40
|
-
Even though this was one of the first resque plugins, later versions of resque added stricter plugin conventions
|
41
|
-
that resque-status did not completely conform to (See: https://github.com/defunkt/resque/blob/master/docs/PLUGINS.md)
|
42
|
-
|
43
|
-
Thanks to some work from @EugZol and @bukowskis v0.3 moved around some code to conform:
|
44
|
-
|
45
|
-
`Resque::Status` is now `Resque::Plugins::Status` and is now an `include`able module.
|
46
|
-
`Resque::Status.get/etc` have been moved to `Resque::Plugins::Status::Hash`
|
47
|
-
|
48
33
|
== Usage
|
49
34
|
|
50
|
-
The most direct way to use resque-status is to create your jobs using the
|
35
|
+
The most direct way to use resque-status is to create your jobs using the
|
51
36
|
Resque::Plugins::Status module. An example job would look something like:
|
52
37
|
|
53
38
|
class SleepJob
|
54
39
|
include Resque::Plugins::Status
|
55
|
-
|
40
|
+
|
56
41
|
def perform
|
57
42
|
total = (options['length'] || 1000).to_i
|
58
|
-
|
59
|
-
|
43
|
+
total.times do |i|
|
44
|
+
num = i+1
|
60
45
|
at(num, total, "At #{num} of #{total}")
|
61
46
|
sleep(1)
|
62
|
-
num += 1
|
63
47
|
end
|
64
48
|
end
|
65
|
-
|
66
49
|
end
|
67
50
|
|
68
|
-
One major difference is that instead of implementing <tt>perform</tt> as a
|
51
|
+
One major difference is that instead of implementing <tt>perform</tt> as a
|
69
52
|
class method, we do our job implementation within instances of the job class.
|
70
53
|
|
71
54
|
In order to queue a SleepJob up, we also won't use <tt>Resque.enqueue</tt>, instead
|
72
|
-
we'll use the <tt>create</tt> class method which will wrap <tt>enqueue</tt> and
|
55
|
+
we'll use the <tt>create</tt> class method which will wrap <tt>enqueue</tt> and
|
73
56
|
creating a unique id (UUID) for us to track the job with.
|
74
57
|
|
75
|
-
job_id = SleepJob.create(:
|
76
|
-
|
58
|
+
job_id = SleepJob.create(length: 100)
|
59
|
+
|
77
60
|
This will create a UUID enqueue the job and pass the :length option on the SleepJob
|
78
61
|
instance as options['length'] (as you can see above).
|
79
62
|
|
80
63
|
Now that we have a UUID its really easy to get the status:
|
81
64
|
|
82
65
|
status = Resque::Plugins::Status::Hash.get(job_id)
|
83
|
-
|
66
|
+
|
84
67
|
This returns a Resque::Plugins::Status::Hash object, which is a Hash (with benefits).
|
85
68
|
|
86
69
|
status.pct_complete #=> 0
|
87
70
|
status.status #=> 'queued'
|
88
71
|
status.queued? #=> true
|
89
72
|
status.working? #=> false
|
90
|
-
status.time #=> Time object
|
73
|
+
status.time #=> Time object
|
91
74
|
status.message #=> "Created at ..."
|
92
75
|
|
93
76
|
Once the worker reserves the job, the instance of SleepJob updates the status at
|
@@ -96,8 +79,8 @@ each iteration using <tt>at()</tt>
|
|
96
79
|
status = Resque::Plugins::Status::Hash.get(job_id)
|
97
80
|
status.working? #=> true
|
98
81
|
status.num #=> 5
|
99
|
-
status.total
|
100
|
-
status.pct_complete
|
82
|
+
status.total #=> 100
|
83
|
+
status.pct_complete #=> 5
|
101
84
|
|
102
85
|
If an error occurs within the job instance, the status is set to 'failed' and then
|
103
86
|
the error is re-raised so that Resque can capture it.
|
@@ -115,7 +98,7 @@ download by the user.
|
|
115
98
|
|
116
99
|
A Status is actually just a hash, so inside a job you can do:
|
117
100
|
|
118
|
-
|
101
|
+
set_status(filename: "myfilename")
|
119
102
|
|
120
103
|
Also, all the status setting methods take any number of hash arguments. So you could do:
|
121
104
|
|
@@ -129,7 +112,7 @@ by UUID.
|
|
129
112
|
|
130
113
|
Resque::Plugins::Status::Hash.kill(job_id)
|
131
114
|
|
132
|
-
The next time the job at job_id calls <tt>at</tt> or <tt>tick</tt>, it will raise a <tt>Killed</tt>
|
115
|
+
The next time the job at job_id calls <tt>at</tt> or <tt>tick</tt>, it will raise a <tt>Killed</tt>
|
133
116
|
error and set the status to killed.
|
134
117
|
|
135
118
|
=== Percent Complete and setting the message
|
@@ -142,53 +125,53 @@ is raised if the job is killed.
|
|
142
125
|
|
143
126
|
=== Expiration
|
144
127
|
|
145
|
-
Since Redis is RAM based, we probably don't want to keep these statuses around forever
|
128
|
+
Since Redis is RAM based, we probably don't want to keep these statuses around forever
|
146
129
|
(at least until @antirez releases the VM feature). By setting expire_in, all statuses
|
147
130
|
and their related keys will expire in expire_in seconds from the last time theyre updated:
|
148
131
|
|
149
132
|
Resque::Plugins::Status::Hash.expire_in = (60 * 60) # 1 hour
|
150
133
|
=== Testing
|
151
134
|
|
152
|
-
Recent versions of Resque introduced `Resque.inline` which changes the behavior to
|
135
|
+
Recent versions of Resque introduced `Resque.inline` which changes the behavior to
|
153
136
|
instead of enqueueing and performing jobs to just executing them inline. In Resque
|
154
137
|
itself this removes the dependency on a Redis, however, `Resque::Status` uses Redis
|
155
138
|
to store information about jobs, so though `inline` "works", you will still need
|
156
|
-
to use or mock a redis connection. You should be able to use a library like
|
139
|
+
to use or mock a redis connection. You should be able to use a library like
|
157
140
|
https://github.com/causes/mock_redis alongside `inline` if you really want to
|
158
141
|
avoid Redis connections in your test.
|
159
142
|
|
160
143
|
=== resque-web
|
161
144
|
|
162
145
|
Though the main purpose of these trackable jobs is to allow you to surface the status
|
163
|
-
of user created jobs through
|
146
|
+
of user created jobs through your apps' own UI, I've added a simple example UI
|
164
147
|
as a plugin to resque-web.
|
165
148
|
|
166
149
|
To use, you need to setup a resque-web config file:
|
167
150
|
|
168
|
-
# ~/resque_conf.rb
|
151
|
+
# ~/resque_conf.rb
|
169
152
|
require 'resque/status_server'
|
170
|
-
|
153
|
+
|
171
154
|
Then start resque-web with your config:
|
172
155
|
|
173
156
|
resque-web ~/resque_conf.rb
|
174
|
-
|
157
|
+
|
175
158
|
This should launch resque-web in your browser and you should see a 'Statuses' tab.
|
176
159
|
|
177
160
|
http://img.skitch.com/20100119-k166xyijcjpkk6xtwnw3854a8g.jpg
|
178
|
-
|
161
|
+
|
179
162
|
== More
|
180
163
|
|
181
164
|
Source: http://github.com/quirkey/resque-status
|
182
165
|
API Docs: http://rdoc.info/projects/quirkey/resque-status
|
183
166
|
Examples: http://github.com/quirkey/resque-status/tree/master/examples
|
184
167
|
Resque: http://github.com/defunkt/resque
|
185
|
-
|
168
|
+
|
186
169
|
== Thanks
|
187
170
|
|
188
|
-
Resque is awesome, @defunkt needs a shout-out.
|
189
|
-
|
171
|
+
Resque is awesome, @defunkt needs a shout-out.
|
172
|
+
|
190
173
|
== Note on Patches/Pull Requests
|
191
|
-
|
174
|
+
|
192
175
|
* Fork the project.
|
193
176
|
* Make your feature addition or bug fix.
|
194
177
|
* Add tests for it. This is important so I don't break it in a
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Resque
|
2
2
|
module Plugins
|
3
3
|
|
4
|
-
# Resque::Plugins::Status is a module
|
4
|
+
# Resque::Plugins::Status is a module your jobs will include.
|
5
5
|
# It provides helper methods for updating the status/etc from within an
|
6
6
|
# instance as well as class methods for creating and queuing the jobs.
|
7
7
|
#
|
@@ -28,7 +28,7 @@ module Resque
|
|
28
28
|
# This job would iterate num times updating the status as it goes. At the end
|
29
29
|
# we update the status telling anyone listening to this job that its complete.
|
30
30
|
module Status
|
31
|
-
VERSION = '0.
|
31
|
+
VERSION = '0.5.0'
|
32
32
|
|
33
33
|
STATUS_QUEUED = 'queued'
|
34
34
|
STATUS_WORKING = 'working'
|
@@ -56,17 +56,23 @@ module Resque
|
|
56
56
|
|
57
57
|
def self.clear_completed(range_start = nil, range_end = nil)
|
58
58
|
status_ids(range_start, range_end).select do |id|
|
59
|
-
get(id).completed?
|
60
|
-
|
61
|
-
|
59
|
+
if get(id).completed?
|
60
|
+
remove(id)
|
61
|
+
true
|
62
|
+
else
|
63
|
+
false
|
64
|
+
end
|
62
65
|
end
|
63
66
|
end
|
64
67
|
|
65
68
|
def self.clear_failed(range_start = nil, range_end = nil)
|
66
69
|
status_ids(range_start, range_end).select do |id|
|
67
|
-
get(id).failed?
|
68
|
-
|
69
|
-
|
70
|
+
if get(id).failed?
|
71
|
+
remove(id)
|
72
|
+
true
|
73
|
+
else
|
74
|
+
false
|
75
|
+
end
|
70
76
|
end
|
71
77
|
end
|
72
78
|
|
@@ -1,18 +1,20 @@
|
|
1
1
|
<%= status_view :status_styles, :layout => false %>
|
2
2
|
|
3
|
-
<h1 class='wi'>
|
3
|
+
<h1 class='wi'>Status <%= @status.uuid %></h1>
|
4
4
|
<p class='intro'>Viewing a specific job created with Resque::Plugins::Status. <a href="<%= u(:statuses) %>">Return to the list of statuses</a></p>
|
5
5
|
|
6
6
|
<div class="status-holder" rel="<%= @status.status %>" id="status_<%= @status.uuid %>">
|
7
|
+
<h2>Overview</h2>
|
7
8
|
<div class="status-progress">
|
8
9
|
<div class="status-progress-bar status-<%= @status.status %>" style="width: <%= @status.pct_complete %>%;"></div>
|
9
10
|
<p><%= @status.pct_complete %>%</p>
|
10
11
|
</div>
|
11
12
|
<div class="status-message"><%= @status.message %></div>
|
12
13
|
<div class="status-time"><%= @status.time? ? @status.time : 'Not started' %></div>
|
14
|
+
|
13
15
|
<h2>Details</h2>
|
14
16
|
<div class="status-details">
|
15
|
-
<table>
|
17
|
+
<table class="vertically-top">
|
16
18
|
<thead>
|
17
19
|
<tr>
|
18
20
|
<th>Key</th>
|
@@ -81,7 +83,7 @@
|
|
81
83
|
time.setTime(value * 1000);
|
82
84
|
return time.toUTCString();
|
83
85
|
} else {
|
84
|
-
return JSON.stringify(value);
|
86
|
+
return JSON.stringify(value, null, " ");
|
85
87
|
}
|
86
88
|
}
|
87
89
|
|
@@ -1,19 +1,21 @@
|
|
1
1
|
<%= status_view :status_styles, :layout => false %>
|
2
2
|
|
3
3
|
<h1 class='wi'>Statuses</h1>
|
4
|
+
|
4
5
|
<%unless @statuses.empty?%>
|
5
|
-
<form method="POST" action="<%= u(:statuses) %>/clear" class='clear-failed'>
|
6
|
-
|
7
|
-
</form>
|
8
|
-
<form method="POST" action="<%= u(:statuses) %>/clear/completed" class='clear-failed'>
|
9
|
-
|
10
|
-
</form>
|
11
|
-
<form method="POST" action="<%= u(:statuses) %>/clear/failed" class='clear-failed'>
|
12
|
-
|
13
|
-
</form>
|
6
|
+
<form method="POST" action="<%= u(:statuses) %>/clear" class='clear-failed'>
|
7
|
+
<input type='submit' name='' value='Clear Statuses' onclick='return confirm("Are you absolutely sure? This cannot be undone.");' />
|
8
|
+
</form>
|
9
|
+
<form method="POST" action="<%= u(:statuses) %>/clear/completed" class='clear-failed'>
|
10
|
+
<input type='submit' name='' value='Clear Completed Statuses' onclick='return confirm("Are you absolutely sure? This cannot be undone.");' />
|
11
|
+
</form>
|
12
|
+
<form method="POST" action="<%= u(:statuses) %>/clear/failed" class='clear-failed'>
|
13
|
+
<input type='submit' name='' value='Clear Failed Statuses' onclick='return confirm("Are you absolutely sure? This cannot be undone.");' />
|
14
|
+
</form>
|
14
15
|
<%end%>
|
16
|
+
|
15
17
|
<p class='intro'>These are recent jobs created with the Resque::Plugins::Status class</p>
|
16
|
-
<table>
|
18
|
+
<table class="vertically-top">
|
17
19
|
<tr>
|
18
20
|
<th>ID</th>
|
19
21
|
<th>Name</th>
|
@@ -46,7 +48,7 @@
|
|
46
48
|
</table>
|
47
49
|
|
48
50
|
<% unless @statuses.empty? %>
|
49
|
-
<%= partial :next_more, :start => @start, :size => @size %>
|
51
|
+
<%= partial :next_more, :start => @start, :size => @size, :per_page => per_page %>
|
50
52
|
<% end %>
|
51
53
|
|
52
54
|
<%= status_poll(@start) %>
|
data/lib/resque/status_server.rb
CHANGED
@@ -5,14 +5,15 @@ module Resque
|
|
5
5
|
module StatusServer
|
6
6
|
|
7
7
|
VIEW_PATH = File.join(File.dirname(__FILE__), 'server', 'views')
|
8
|
+
PER_PAGE = 50
|
8
9
|
|
9
10
|
def self.registered(app)
|
10
11
|
|
11
12
|
app.get '/statuses' do
|
12
13
|
@start = params[:start].to_i
|
13
|
-
@end = @start + (params[:per_page] ||
|
14
|
+
@end = @start + (params[:per_page] || per_page) - 1
|
14
15
|
@statuses = Resque::Plugins::Status::Hash.statuses(@start, @end)
|
15
|
-
@size =
|
16
|
+
@size = Resque::Plugins::Status::Hash.count
|
16
17
|
status_view(:statuses)
|
17
18
|
end
|
18
19
|
|
@@ -52,14 +53,17 @@ module Resque
|
|
52
53
|
@polling = true
|
53
54
|
|
54
55
|
@start = params[:start].to_i
|
55
|
-
@end = @start + (params[:per_page] ||
|
56
|
+
@end = @start + (params[:per_page] || per_page) - 1
|
56
57
|
@statuses = Resque::Plugins::Status::Hash.statuses(@start, @end)
|
57
|
-
@size =
|
58
|
-
|
58
|
+
@size = Resque::Plugins::Status::Hash.count
|
59
59
|
status_view(:statuses, {:layout => false})
|
60
60
|
end
|
61
61
|
|
62
62
|
app.helpers do
|
63
|
+
def per_page
|
64
|
+
PER_PAGE
|
65
|
+
end
|
66
|
+
|
63
67
|
def status_view(filename, options = {}, locals = {})
|
64
68
|
erb(File.read(File.join(::Resque::StatusServer::VIEW_PATH, "#{filename}.erb")), options, locals)
|
65
69
|
end
|
data/resque-status.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: resque-status 0.
|
5
|
+
# stub: resque-status 0.5.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "resque-status"
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.5.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Aaron Quint"]
|
14
|
-
s.date = "
|
14
|
+
s.date = "2015-03-18"
|
15
15
|
s.description = "resque-status is an extension to the resque queue system that provides simple trackable jobs. It provides a Resque::Plugins::Status::Hash class which can set/get the statuses of jobs and a Resque::Plugins::Status class that when included provides easily trackable/killable jobs."
|
16
16
|
s.email = "aaron@quirkey.com"
|
17
17
|
s.extra_rdoc_files = [
|
@@ -44,7 +44,7 @@ Gem::Specification.new do |s|
|
|
44
44
|
]
|
45
45
|
s.homepage = "http://github.com/quirkey/resque-status"
|
46
46
|
s.rubyforge_project = "quirkey"
|
47
|
-
s.rubygems_version = "2.2.
|
47
|
+
s.rubygems_version = "2.2.2"
|
48
48
|
s.summary = "resque-status is an extension to the resque queue system that provides simple trackable jobs."
|
49
49
|
|
50
50
|
if s.respond_to? :specification_version then
|
data/test/redis-test.conf
CHANGED
@@ -48,10 +48,10 @@ dir ./test/
|
|
48
48
|
# warning (only very important / critical messages are logged)
|
49
49
|
loglevel debug
|
50
50
|
|
51
|
-
# Specify the log file name. Also
|
52
|
-
#
|
51
|
+
# Specify the log file name. Also the empty string can be used to force
|
52
|
+
# Redis to log on the standard output. Note that if you use standard
|
53
53
|
# output for logging but daemonize, logs will be sent to /dev/null
|
54
|
-
logfile
|
54
|
+
logfile ""
|
55
55
|
|
56
56
|
# Set the number of databases. The default database is DB 0, you can select
|
57
57
|
# a different one on a per-connection basis using SELECT <dbid> where
|
@@ -109,11 +109,6 @@ databases 16
|
|
109
109
|
|
110
110
|
############################### ADVANCED CONFIG ###############################
|
111
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
112
|
# Use object sharing. Can save a lot of memory if you have many common
|
118
113
|
# string in your dataset, but performs lookups against the shared objects
|
119
114
|
# pool so it uses more CPU and can be a bit slower. Usually it's a good
|
data/test/test_helper.rb
CHANGED
@@ -1,15 +1,8 @@
|
|
1
|
-
|
2
|
-
$LOAD_PATH.unshift dir + '/../lib'
|
3
|
-
$TESTING = true
|
4
|
-
require 'test/unit'
|
5
|
-
require 'rubygems'
|
6
|
-
require 'shoulda'
|
7
|
-
require 'mocha/setup'
|
8
|
-
|
1
|
+
require 'bundler/setup'
|
9
2
|
require 'resque-status'
|
10
3
|
|
11
|
-
|
12
|
-
|
4
|
+
require 'minitest/autorun'
|
5
|
+
require 'mocha/setup'
|
13
6
|
|
14
7
|
#
|
15
8
|
# make sure we can run redis
|
@@ -26,23 +19,20 @@ end
|
|
26
19
|
# kill it when they end
|
27
20
|
#
|
28
21
|
|
29
|
-
at_exit do
|
30
|
-
next if $!
|
31
22
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
23
|
+
class << Minitest
|
24
|
+
def exit(*args)
|
25
|
+
pid = `ps -e -o pid,command | grep [r]edis.*9736`.split(" ")[0]
|
26
|
+
puts "Killing test redis server..."
|
27
|
+
Process.kill("KILL", pid.to_i)
|
28
|
+
super
|
36
29
|
end
|
37
|
-
|
38
|
-
pid = `ps -e -o pid,command | grep [r]edis-test`.split(" ")[0]
|
39
|
-
puts "Killing test redis server..."
|
40
|
-
Process.kill("KILL", pid.to_i)
|
41
|
-
exit exit_code
|
42
30
|
end
|
43
31
|
|
32
|
+
dir = File.expand_path("../", __FILE__)
|
44
33
|
puts "Starting redis for testing at localhost:9736..."
|
45
|
-
`rm -f #{dir}/dump.rdb && redis-server #{dir}/redis-test.conf`
|
34
|
+
result = `rm -f #{dir}/dump.rdb && redis-server #{dir}/redis-test.conf`
|
35
|
+
raise "Redis failed to start: #{result}" unless $?.success?
|
46
36
|
Resque.redis = 'localhost:9736/1'
|
47
37
|
|
48
38
|
#### Fixtures
|
@@ -1,220 +1,224 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class TestResquePluginsStatus < Test
|
3
|
+
class TestResquePluginsStatus < Minitest::Test
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
describe "Resque::Plugins::Status" do
|
6
|
+
before do
|
7
7
|
Resque.redis.flushall
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
describe ".create" do
|
11
|
+
describe "not inline" do
|
12
|
+
before do
|
13
13
|
@uuid = WorkingJob.create('num' => 100)
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
it "add the job to the queue" do
|
17
17
|
assert_equal 1, Resque.size(:statused)
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
it "set the queued object to the current class" do
|
21
21
|
job = Resque.pop(:statused)
|
22
22
|
assert_equal @uuid, job['args'].first
|
23
23
|
assert_equal "WorkingJob", job['class']
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
it "add the uuid to the statuses" do
|
27
|
+
assert_includes Resque::Plugins::Status::Hash.status_ids, @uuid
|
28
28
|
end
|
29
29
|
|
30
|
-
|
30
|
+
it "return a UUID" do
|
31
31
|
assert_match(/^\w{32}$/, @uuid)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
describe "inline" do
|
36
|
+
before do
|
37
37
|
Resque.stubs(:inline?).returns(true)
|
38
38
|
end
|
39
39
|
|
40
|
-
|
40
|
+
it "not queue a job" do
|
41
41
|
@uuid = WorkingJob.create('num' => 100)
|
42
42
|
assert_equal 0, Resque.size(:statused)
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
it "call perform" do
|
46
46
|
WorkingJob.any_instance.expects(:perform).once
|
47
47
|
@uuid = WorkingJob.create('num' => 100)
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
|
53
|
-
|
52
|
+
describe ".create with a failing before_enqueue hook" do
|
53
|
+
before do
|
54
54
|
@size = Resque.size(:statused)
|
55
55
|
@status_ids_size = Resque::Plugins::Status::Hash.status_ids.length
|
56
56
|
@res = NeverQueuedJob.create(:num => 100)
|
57
57
|
end
|
58
58
|
|
59
|
-
|
59
|
+
it "return nil" do
|
60
60
|
assert_equal nil, @res
|
61
61
|
end
|
62
62
|
|
63
|
-
|
63
|
+
it "not create a status" do
|
64
64
|
assert_equal @size, Resque.size(:statused)
|
65
65
|
end
|
66
66
|
|
67
|
-
|
67
|
+
it "not add the uuid to the statuses" do
|
68
68
|
assert_equal @status_ids_size, Resque::Plugins::Status::Hash.status_ids.length
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
|
73
|
-
|
72
|
+
describe ".scheduled" do
|
73
|
+
before do
|
74
74
|
@job_args = {'num' => 100}
|
75
75
|
@uuid = WorkingJob.scheduled(:queue_name, WorkingJob, @job_args)
|
76
76
|
end
|
77
77
|
|
78
|
-
|
78
|
+
it "create the job with the provided arguments" do
|
79
79
|
job = Resque.pop(:queue_name)
|
80
80
|
assert_equal @job_args, job['args'].last
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
|
85
|
-
|
84
|
+
describe ".enqueue" do
|
85
|
+
it "delegate to enqueue_to, filling in the queue from the class" do
|
86
86
|
@uuid = BasicJob.enqueue(WorkingJob, :num => 100)
|
87
87
|
@payload = Resque.pop(:statused)
|
88
88
|
assert_equal "WorkingJob", @payload['class']
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
-
|
93
|
-
|
92
|
+
describe ".enqueue_to" do
|
93
|
+
before do
|
94
94
|
@uuid = BasicJob.enqueue_to(:new_queue, WorkingJob, :num => 100)
|
95
95
|
@payload = Resque.pop(:new_queue)
|
96
96
|
end
|
97
97
|
|
98
|
-
|
98
|
+
it "add the job with the specific class to the queue" do
|
99
99
|
assert_equal "WorkingJob", @payload['class']
|
100
100
|
end
|
101
101
|
|
102
|
-
|
102
|
+
it "add the arguments to the options hash" do
|
103
103
|
assert_equal @uuid, @payload['args'].first
|
104
104
|
end
|
105
105
|
|
106
|
-
|
107
|
-
|
106
|
+
it "add the uuid to the statuses" do
|
107
|
+
assert_includes Resque::Plugins::Status::Hash.status_ids, @uuid
|
108
108
|
end
|
109
109
|
|
110
|
-
|
110
|
+
it "return UUID" do
|
111
111
|
assert_match(/^\w{32}$/, @uuid)
|
112
112
|
end
|
113
113
|
|
114
114
|
end
|
115
115
|
|
116
|
-
|
117
|
-
|
116
|
+
describe ".dequeue" do
|
117
|
+
before do
|
118
118
|
@uuid1 = BasicJob.enqueue(WorkingJob, :num => 100)
|
119
119
|
@uuid2 = BasicJob.enqueue(WorkingJob, :num => 100)
|
120
120
|
end
|
121
121
|
|
122
|
-
|
122
|
+
it "dequeue the job with the uuid from the correct queue" do
|
123
123
|
size = Resque.size(:statused)
|
124
124
|
BasicJob.dequeue(WorkingJob, @uuid2)
|
125
125
|
assert_equal size-1, Resque.size(:statused)
|
126
126
|
end
|
127
|
-
|
127
|
+
it "not dequeue any jobs with different uuids for same class name" do
|
128
128
|
BasicJob.dequeue(WorkingJob, @uuid2)
|
129
129
|
assert_equal @uuid1, Resque.pop(:statused)['args'].first
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
133
|
-
|
134
|
-
|
133
|
+
describe ".perform" do
|
134
|
+
let(:expectation) { }
|
135
|
+
|
136
|
+
before do
|
137
|
+
expectation
|
135
138
|
@uuid = WorkingJob.create(:num => 100)
|
136
139
|
@payload = Resque.pop(:statused)
|
137
140
|
@performed = WorkingJob.perform(*@payload['args'])
|
138
141
|
end
|
139
142
|
|
140
|
-
|
143
|
+
it "load load a new instance of the klass" do
|
141
144
|
assert @performed.is_a?(WorkingJob)
|
142
145
|
end
|
143
146
|
|
144
|
-
|
147
|
+
it "set the uuid" do
|
145
148
|
assert_equal @uuid, @performed.uuid
|
146
149
|
end
|
147
150
|
|
148
|
-
|
151
|
+
it "set the status" do
|
149
152
|
assert @performed.status.is_a?(Resque::Plugins::Status::Hash)
|
150
153
|
assert_equal 'WorkingJob({"num"=>100})', @performed.status.name
|
151
154
|
end
|
152
155
|
|
153
|
-
|
154
|
-
WorkingJob.any_instance.expects(:perform).once
|
156
|
+
describe "before" do
|
157
|
+
let(:expectation) { WorkingJob.any_instance.expects(:perform).once }
|
158
|
+
it("call perform on the inherited class") {}
|
155
159
|
end
|
156
160
|
end
|
157
161
|
|
158
|
-
|
159
|
-
|
162
|
+
describe "manually failing a job" do
|
163
|
+
before do
|
160
164
|
@uuid = FailureJob.create(:num => 100)
|
161
165
|
@payload = Resque.pop(:statused)
|
162
166
|
@performed = FailureJob.perform(*@payload['args'])
|
163
167
|
end
|
164
168
|
|
165
|
-
|
169
|
+
it "load load a new instance of the klass" do
|
166
170
|
assert @performed.is_a?(FailureJob)
|
167
171
|
end
|
168
172
|
|
169
|
-
|
173
|
+
it "set the uuid" do
|
170
174
|
assert_equal @uuid, @performed.uuid
|
171
175
|
end
|
172
176
|
|
173
|
-
|
177
|
+
it "set the status" do
|
174
178
|
assert @performed.status.is_a?(Resque::Plugins::Status::Hash)
|
175
179
|
assert_equal 'FailureJob({"num"=>100})', @performed.status.name
|
176
180
|
end
|
177
181
|
|
178
|
-
|
182
|
+
it "be failed" do
|
179
183
|
assert_match(/failure/, @performed.status.message)
|
180
184
|
assert @performed.status.failed?
|
181
185
|
end
|
182
186
|
|
183
187
|
end
|
184
188
|
|
185
|
-
|
186
|
-
|
189
|
+
describe "killing a job" do
|
190
|
+
before do
|
187
191
|
@uuid = KillableJob.create(:num => 100)
|
188
192
|
@payload = Resque.pop(:statused)
|
189
193
|
Resque::Plugins::Status::Hash.kill(@uuid)
|
190
|
-
|
194
|
+
assert_includes Resque::Plugins::Status::Hash.kill_ids, @uuid
|
191
195
|
@performed = KillableJob.perform(*@payload['args'])
|
192
196
|
@status = Resque::Plugins::Status::Hash.get(@uuid)
|
193
197
|
end
|
194
198
|
|
195
|
-
|
199
|
+
it "set the status to killed" do
|
196
200
|
assert @status.killed?
|
197
201
|
assert !@status.completed?
|
198
202
|
end
|
199
203
|
|
200
|
-
|
204
|
+
it "only perform iterations up to kill" do
|
201
205
|
assert_equal 1, Resque.redis.get("#{@uuid}:iterations").to_i
|
202
206
|
end
|
203
207
|
|
204
|
-
|
205
|
-
|
208
|
+
it "not persist the kill key" do
|
209
|
+
refute_includes Resque::Plugins::Status::Hash.kill_ids, @uuid
|
206
210
|
end
|
207
211
|
end
|
208
212
|
|
209
|
-
|
210
|
-
|
213
|
+
describe "killing all jobs" do
|
214
|
+
before do
|
211
215
|
@uuid1 = KillableJob.create(:num => 100)
|
212
216
|
@uuid2 = KillableJob.create(:num => 100)
|
213
217
|
|
214
218
|
Resque::Plugins::Status::Hash.killall
|
215
219
|
|
216
|
-
|
217
|
-
|
220
|
+
assert_includes Resque::Plugins::Status::Hash.kill_ids, @uuid1
|
221
|
+
assert_includes Resque::Plugins::Status::Hash.kill_ids, @uuid2
|
218
222
|
|
219
223
|
@payload1 = Resque.pop(:statused)
|
220
224
|
@payload2 = Resque.pop(:statused)
|
@@ -225,34 +229,34 @@ class TestResquePluginsStatus < Test::Unit::TestCase
|
|
225
229
|
@status1, @status2 = Resque::Plugins::Status::Hash.mget([@uuid1, @uuid2])
|
226
230
|
end
|
227
231
|
|
228
|
-
|
232
|
+
it "set the status to killed" do
|
229
233
|
assert @status1.killed?
|
230
234
|
assert !@status1.completed?
|
231
235
|
assert @status2.killed?
|
232
236
|
assert !@status2.completed?
|
233
237
|
end
|
234
238
|
|
235
|
-
|
239
|
+
it "only perform iterations up to kill" do
|
236
240
|
assert_equal 1, Resque.redis.get("#{@uuid1}:iterations").to_i
|
237
241
|
assert_equal 1, Resque.redis.get("#{@uuid2}:iterations").to_i
|
238
242
|
end
|
239
243
|
|
240
|
-
|
241
|
-
|
242
|
-
|
244
|
+
it "not persist the kill key" do
|
245
|
+
refute_includes Resque::Plugins::Status::Hash.kill_ids, @uuid1
|
246
|
+
refute_includes Resque::Plugins::Status::Hash.kill_ids, @uuid2
|
243
247
|
end
|
244
248
|
|
245
249
|
end
|
246
250
|
|
247
|
-
|
248
|
-
|
251
|
+
describe "invoking killall jobs to kill a range" do
|
252
|
+
before do
|
249
253
|
@uuid1 = KillableJob.create(:num => 100)
|
250
254
|
@uuid2 = KillableJob.create(:num => 100)
|
251
255
|
|
252
|
-
Resque::Plugins::Status::Hash.killall(0,0) # only @uuid2
|
256
|
+
Resque::Plugins::Status::Hash.killall(0,0) # only @uuid2 it be killed
|
253
257
|
|
254
|
-
|
255
|
-
|
258
|
+
refute_includes Resque::Plugins::Status::Hash.kill_ids, @uuid1
|
259
|
+
assert_includes Resque::Plugins::Status::Hash.kill_ids, @uuid2
|
256
260
|
|
257
261
|
@payload1 = Resque.pop(:statused)
|
258
262
|
@payload2 = Resque.pop(:statused)
|
@@ -263,86 +267,86 @@ class TestResquePluginsStatus < Test::Unit::TestCase
|
|
263
267
|
@status1, @status2 = Resque::Plugins::Status::Hash.mget([@uuid1, @uuid2])
|
264
268
|
end
|
265
269
|
|
266
|
-
|
270
|
+
it "set the status to killed" do
|
267
271
|
assert !@status1.killed?
|
268
272
|
assert @status1.completed?
|
269
273
|
assert @status2.killed?
|
270
274
|
assert !@status2.completed?
|
271
275
|
end
|
272
276
|
|
273
|
-
|
277
|
+
it "only perform iterations up to kill" do
|
274
278
|
assert_equal 100, Resque.redis.get("#{@uuid1}:iterations").to_i
|
275
279
|
assert_equal 1, Resque.redis.get("#{@uuid2}:iterations").to_i
|
276
280
|
end
|
277
281
|
|
278
|
-
|
279
|
-
|
280
|
-
|
282
|
+
it "not persist the kill key" do
|
283
|
+
refute_includes Resque::Plugins::Status::Hash.kill_ids, @uuid1
|
284
|
+
refute_includes Resque::Plugins::Status::Hash.kill_ids, @uuid2
|
281
285
|
end
|
282
286
|
|
283
287
|
end
|
284
288
|
|
285
|
-
|
286
|
-
|
289
|
+
describe "with an invoked job" do
|
290
|
+
before do
|
287
291
|
@job = WorkingJob.new('123', {'num' => 100})
|
288
292
|
end
|
289
293
|
|
290
|
-
|
291
|
-
|
294
|
+
describe "#at" do
|
295
|
+
before do
|
292
296
|
@job.at(50, 100, "At 50%")
|
293
297
|
end
|
294
298
|
|
295
|
-
|
299
|
+
it "calculate percent" do
|
296
300
|
assert_equal 50, @job.status.pct_complete
|
297
301
|
end
|
298
302
|
|
299
|
-
|
303
|
+
it "set status" do
|
300
304
|
assert @job.status.working?
|
301
305
|
end
|
302
306
|
|
303
|
-
|
307
|
+
it "save message" do
|
304
308
|
assert_equal "At 50%", @job.status.message
|
305
309
|
end
|
306
310
|
end
|
307
311
|
|
308
|
-
|
309
|
-
|
312
|
+
describe "#failed" do
|
313
|
+
before do
|
310
314
|
@job.failed("OOOOPS!")
|
311
315
|
end
|
312
316
|
|
313
|
-
|
317
|
+
it "set status" do
|
314
318
|
assert @job.status.failed?
|
315
319
|
end
|
316
320
|
|
317
|
-
|
321
|
+
it "set message" do
|
318
322
|
assert_equal "OOOOPS!", @job.status.message
|
319
323
|
end
|
320
324
|
end
|
321
325
|
|
322
|
-
|
323
|
-
|
326
|
+
describe "#completed" do
|
327
|
+
before do
|
324
328
|
@job.completed
|
325
329
|
end
|
326
330
|
|
327
|
-
|
331
|
+
it "set status" do
|
328
332
|
assert @job.status.completed?
|
329
333
|
end
|
330
334
|
|
331
|
-
|
335
|
+
it "set message" do
|
332
336
|
assert_match(/complete/i, @job.status.message)
|
333
337
|
end
|
334
338
|
|
335
339
|
end
|
336
340
|
|
337
|
-
|
338
|
-
|
341
|
+
describe "#safe_perform!" do
|
342
|
+
before do
|
339
343
|
@job = ErrorJob.new("123")
|
340
344
|
assert_raises(RuntimeError) do
|
341
345
|
@job.safe_perform!
|
342
346
|
end
|
343
347
|
end
|
344
348
|
|
345
|
-
|
349
|
+
it "set status as failed" do
|
346
350
|
assert @job.status.failed?
|
347
351
|
end
|
348
352
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class TestResquePluginsStatusHash < Test
|
3
|
+
class TestResquePluginsStatusHash < Minitest::Test
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
describe "Resque::Plugins::Status::Hash" do
|
6
|
+
before do
|
7
7
|
Resque.redis.flushall
|
8
8
|
Resque::Plugins::Status::Hash.expire_in = nil
|
9
9
|
@uuid = Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid)
|
@@ -11,24 +11,24 @@ class TestResquePluginsStatusHash < Test::Unit::TestCase
|
|
11
11
|
@uuid_with_json = Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid, {"im" => "json"})
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
describe ".get" do
|
15
|
+
it "return the status as a Resque::Plugins::Status::Hash for the uuid" do
|
16
16
|
status = Resque::Plugins::Status::Hash.get(@uuid)
|
17
17
|
assert status.is_a?(Resque::Plugins::Status::Hash)
|
18
18
|
assert_equal 'my status', status.message
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
it "return nil if the status is not set" do
|
22
22
|
assert_nil Resque::Plugins::Status::Hash.get('invalid_uuid')
|
23
23
|
end
|
24
24
|
|
25
|
-
|
25
|
+
it "decode encoded json" do
|
26
26
|
assert_equal("json", Resque::Plugins::Status::Hash.get(@uuid_with_json)['im'])
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
30
|
+
describe ".mget" do
|
31
|
+
it "return statuses as array of Resque::Plugins::Status::Hash for the uuids" do
|
32
32
|
uuid2 = Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid)
|
33
33
|
Resque::Plugins::Status::Hash.set(uuid2, "my status2")
|
34
34
|
statuses = Resque::Plugins::Status::Hash.mget([@uuid, uuid2])
|
@@ -37,7 +37,7 @@ class TestResquePluginsStatusHash < Test::Unit::TestCase
|
|
37
37
|
assert_equal ['my status', 'my status2'], statuses.map(&:message)
|
38
38
|
end
|
39
39
|
|
40
|
-
|
40
|
+
it "return nil if a status is not set" do
|
41
41
|
statuses = Resque::Plugins::Status::Hash.mget(['invalid_uuid', @uuid])
|
42
42
|
assert_equal 2, statuses.size
|
43
43
|
assert_nil statuses[0]
|
@@ -45,56 +45,56 @@ class TestResquePluginsStatusHash < Test::Unit::TestCase
|
|
45
45
|
assert_equal 'my status', statuses[1].message
|
46
46
|
end
|
47
47
|
|
48
|
-
|
48
|
+
it "decode encoded json" do
|
49
49
|
assert_equal ['json'],
|
50
50
|
Resque::Plugins::Status::Hash.mget([@uuid_with_json]).map{|h| h['im']}
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
describe ".set" do
|
55
55
|
|
56
|
-
|
56
|
+
it "set the status for the uuid" do
|
57
57
|
assert Resque::Plugins::Status::Hash.set(@uuid, "updated")
|
58
58
|
assert_equal "updated", Resque::Plugins::Status::Hash.get(@uuid).message
|
59
59
|
end
|
60
60
|
|
61
|
-
|
61
|
+
it "return the status" do
|
62
62
|
assert Resque::Plugins::Status::Hash.set(@uuid, "updated").is_a?(Resque::Plugins::Status::Hash)
|
63
63
|
end
|
64
64
|
|
65
65
|
end
|
66
66
|
|
67
|
-
|
68
|
-
|
67
|
+
describe ".create" do
|
68
|
+
it "add an item to a key set" do
|
69
69
|
before = Resque::Plugins::Status::Hash.status_ids.length
|
70
70
|
Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid)
|
71
71
|
after = Resque::Plugins::Status::Hash.status_ids.length
|
72
72
|
assert_equal 1, after - before
|
73
73
|
end
|
74
74
|
|
75
|
-
|
75
|
+
it "return a uuid" do
|
76
76
|
assert_match(/^\w{32}$/, Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid))
|
77
77
|
end
|
78
78
|
|
79
|
-
|
79
|
+
it "store any status passed" do
|
80
80
|
uuid = Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid, "initial status")
|
81
81
|
status = Resque::Plugins::Status::Hash.get(uuid)
|
82
82
|
assert status.is_a?(Resque::Plugins::Status::Hash)
|
83
83
|
assert_equal "initial status", status.message
|
84
84
|
end
|
85
85
|
|
86
|
-
|
86
|
+
it "expire keys if expire_in is set" do
|
87
87
|
Resque::Plugins::Status::Hash.expire_in = 1
|
88
88
|
uuid = Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid, "new status")
|
89
|
-
|
89
|
+
assert_includes Resque::Plugins::Status::Hash.status_ids, uuid
|
90
90
|
assert_equal "new status", Resque::Plugins::Status::Hash.get(uuid).message
|
91
91
|
sleep 2
|
92
92
|
Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid)
|
93
|
-
|
93
|
+
refute_includes Resque::Plugins::Status::Hash.status_ids, uuid
|
94
94
|
assert_nil Resque::Plugins::Status::Hash.get(uuid)
|
95
95
|
end
|
96
96
|
|
97
|
-
|
97
|
+
it "store the options for the job created" do
|
98
98
|
uuid = Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid, "new", :options => {'test' => '123'})
|
99
99
|
assert uuid
|
100
100
|
status = Resque::Plugins::Status::Hash.get(uuid)
|
@@ -103,93 +103,93 @@ class TestResquePluginsStatusHash < Test::Unit::TestCase
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
-
|
107
|
-
|
106
|
+
describe ".clear" do
|
107
|
+
before do
|
108
108
|
Resque::Plugins::Status::Hash.clear
|
109
109
|
end
|
110
110
|
|
111
|
-
|
111
|
+
it "clear any statuses" do
|
112
112
|
assert_nil Resque::Plugins::Status::Hash.get(@uuid)
|
113
113
|
end
|
114
114
|
|
115
|
-
|
115
|
+
it "clear any recent statuses" do
|
116
116
|
assert Resque::Plugins::Status::Hash.status_ids.empty?
|
117
117
|
end
|
118
118
|
|
119
119
|
end
|
120
120
|
|
121
|
-
|
122
|
-
|
121
|
+
describe ".clear_completed" do
|
122
|
+
before do
|
123
123
|
@completed_status_id = Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid, {'status' => "completed"})
|
124
124
|
@not_completed_status_id = Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid)
|
125
125
|
Resque::Plugins::Status::Hash.clear_completed
|
126
126
|
end
|
127
127
|
|
128
|
-
|
128
|
+
it "clear completed status" do
|
129
129
|
assert_nil Resque::Plugins::Status::Hash.get(@completed_status_id)
|
130
130
|
end
|
131
131
|
|
132
|
-
|
132
|
+
it "not clear not-completed status" do
|
133
133
|
status = Resque::Plugins::Status::Hash.get(@not_completed_status_id)
|
134
134
|
assert status.is_a?(Resque::Plugins::Status::Hash)
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
|
-
|
139
|
-
|
138
|
+
describe ".clear_failed" do
|
139
|
+
before do
|
140
140
|
@failed_status_id = Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid, {'status' => "failed"})
|
141
141
|
@not_failed_status_id = Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid)
|
142
142
|
Resque::Plugins::Status::Hash.clear_failed
|
143
143
|
end
|
144
144
|
|
145
|
-
|
145
|
+
it "clear failed status" do
|
146
146
|
assert_nil Resque::Plugins::Status::Hash.get(@failed_status_id)
|
147
147
|
end
|
148
148
|
|
149
|
-
|
149
|
+
it "not clear not-failed status" do
|
150
150
|
status = Resque::Plugins::Status::Hash.get(@not_failed_status_id)
|
151
151
|
assert status.is_a?(Resque::Plugins::Status::Hash)
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
|
-
|
156
|
-
|
155
|
+
describe ".remove" do
|
156
|
+
before do
|
157
157
|
Resque::Plugins::Status::Hash.remove(@uuid)
|
158
158
|
end
|
159
159
|
|
160
|
-
|
160
|
+
it "clear specify status" do
|
161
161
|
assert_nil Resque::Plugins::Status::Hash.get(@uuid)
|
162
162
|
end
|
163
163
|
end
|
164
164
|
|
165
|
-
|
165
|
+
describe ".status_ids" do
|
166
166
|
|
167
|
-
|
167
|
+
before do
|
168
168
|
@uuids = []
|
169
169
|
30.times{ Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid) }
|
170
170
|
end
|
171
171
|
|
172
|
-
|
172
|
+
it "return an array of job ids" do
|
173
173
|
assert Resque::Plugins::Status::Hash.status_ids.is_a?(Array)
|
174
174
|
assert_equal 32, Resque::Plugins::Status::Hash.status_ids.size # 30 + 2
|
175
175
|
end
|
176
176
|
|
177
|
-
|
177
|
+
it "let you paginate through the statuses" do
|
178
178
|
assert_equal Resque::Plugins::Status::Hash.status_ids[0, 10], Resque::Plugins::Status::Hash.status_ids(0, 9)
|
179
179
|
assert_equal Resque::Plugins::Status::Hash.status_ids[10, 10], Resque::Plugins::Status::Hash.status_ids(10, 19)
|
180
180
|
# assert_equal Resque::Plugins::Status::Hash.status_ids.reverse[0, 10], Resque::Plugins::Status::Hash.status_ids(0, 10)
|
181
181
|
end
|
182
182
|
end
|
183
183
|
|
184
|
-
|
184
|
+
describe ".statuses" do
|
185
185
|
|
186
|
-
|
186
|
+
it "return an array status objects" do
|
187
187
|
statuses = Resque::Plugins::Status::Hash.statuses
|
188
188
|
assert statuses.is_a?(Array)
|
189
|
-
|
189
|
+
assert_equal [@uuid_with_json, @uuid].sort, statuses.map(&:uuid).sort
|
190
190
|
end
|
191
191
|
|
192
|
-
|
192
|
+
it "return an empty array when no statuses are available" do
|
193
193
|
Resque.redis.flushall
|
194
194
|
statuses = Resque::Plugins::Status::Hash.statuses
|
195
195
|
assert_equal [], statuses
|
@@ -198,18 +198,18 @@ class TestResquePluginsStatusHash < Test::Unit::TestCase
|
|
198
198
|
end
|
199
199
|
|
200
200
|
Resque::Plugins::Status::STATUSES.each do |status_code|
|
201
|
-
|
201
|
+
describe ".#{status_code}?" do
|
202
202
|
|
203
|
-
|
203
|
+
before do
|
204
204
|
uuid = Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid, {'status' => status_code})
|
205
205
|
@status = Resque::Plugins::Status::Hash.get(uuid)
|
206
206
|
end
|
207
207
|
|
208
|
-
|
208
|
+
it "return true for the current status" do
|
209
209
|
assert @status.send("#{status_code}?"), status_code
|
210
210
|
end
|
211
211
|
|
212
|
-
|
212
|
+
it "return false for other statuses" do
|
213
213
|
(Resque::Plugins::Status::STATUSES - [status_code]).each do |other_status_code|
|
214
214
|
assert !@status.send("#{other_status_code}?"), other_status_code
|
215
215
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-status
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Quint
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: resque
|
@@ -90,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
90
|
version: '0'
|
91
91
|
requirements: []
|
92
92
|
rubyforge_project: quirkey
|
93
|
-
rubygems_version: 2.2.
|
93
|
+
rubygems_version: 2.2.2
|
94
94
|
signing_key:
|
95
95
|
specification_version: 4
|
96
96
|
summary: resque-status is an extension to the resque queue system that provides simple
|