sidekiq 3.4.1 → 7.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (235) hide show
  1. checksums.yaml +5 -5
  2. data/Changes.md +1118 -4
  3. data/LICENSE.txt +9 -0
  4. data/README.md +55 -47
  5. data/bin/multi_queue_bench +271 -0
  6. data/bin/sidekiq +26 -3
  7. data/bin/sidekiqload +247 -0
  8. data/bin/sidekiqmon +11 -0
  9. data/lib/generators/sidekiq/job_generator.rb +57 -0
  10. data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
  11. data/lib/generators/sidekiq/templates/job_spec.rb.erb +6 -0
  12. data/lib/generators/sidekiq/templates/job_test.rb.erb +8 -0
  13. data/lib/sidekiq/api.rb +714 -312
  14. data/lib/sidekiq/capsule.rb +130 -0
  15. data/lib/sidekiq/cli.rb +275 -241
  16. data/lib/sidekiq/client.rb +141 -110
  17. data/lib/sidekiq/component.rb +68 -0
  18. data/lib/sidekiq/config.rb +291 -0
  19. data/lib/sidekiq/deploy.rb +62 -0
  20. data/lib/sidekiq/embedded.rb +61 -0
  21. data/lib/sidekiq/fetch.rb +53 -121
  22. data/lib/sidekiq/iterable_job.rb +53 -0
  23. data/lib/sidekiq/job/interrupt_handler.rb +22 -0
  24. data/lib/sidekiq/job/iterable/active_record_enumerator.rb +53 -0
  25. data/lib/sidekiq/job/iterable/csv_enumerator.rb +47 -0
  26. data/lib/sidekiq/job/iterable/enumerators.rb +135 -0
  27. data/lib/sidekiq/job/iterable.rb +231 -0
  28. data/lib/sidekiq/job.rb +385 -0
  29. data/lib/sidekiq/job_logger.rb +64 -0
  30. data/lib/sidekiq/job_retry.rb +305 -0
  31. data/lib/sidekiq/job_util.rb +107 -0
  32. data/lib/sidekiq/launcher.rb +241 -66
  33. data/lib/sidekiq/logger.rb +131 -0
  34. data/lib/sidekiq/manager.rb +91 -192
  35. data/lib/sidekiq/metrics/query.rb +156 -0
  36. data/lib/sidekiq/metrics/shared.rb +95 -0
  37. data/lib/sidekiq/metrics/tracking.rb +140 -0
  38. data/lib/sidekiq/middleware/chain.rb +114 -56
  39. data/lib/sidekiq/middleware/current_attributes.rb +111 -0
  40. data/lib/sidekiq/middleware/i18n.rb +8 -7
  41. data/lib/sidekiq/middleware/modules.rb +21 -0
  42. data/lib/sidekiq/monitor.rb +146 -0
  43. data/lib/sidekiq/paginator.rb +29 -16
  44. data/lib/sidekiq/processor.rb +248 -112
  45. data/lib/sidekiq/rails.rb +61 -27
  46. data/lib/sidekiq/redis_client_adapter.rb +114 -0
  47. data/lib/sidekiq/redis_connection.rb +68 -48
  48. data/lib/sidekiq/ring_buffer.rb +29 -0
  49. data/lib/sidekiq/scheduled.rb +173 -52
  50. data/lib/sidekiq/sd_notify.rb +149 -0
  51. data/lib/sidekiq/systemd.rb +24 -0
  52. data/lib/sidekiq/testing/inline.rb +7 -5
  53. data/lib/sidekiq/testing.rb +206 -65
  54. data/lib/sidekiq/transaction_aware_client.rb +51 -0
  55. data/lib/sidekiq/version.rb +4 -1
  56. data/lib/sidekiq/web/action.rb +99 -0
  57. data/lib/sidekiq/web/application.rb +479 -0
  58. data/lib/sidekiq/web/csrf_protection.rb +183 -0
  59. data/lib/sidekiq/web/helpers.rb +415 -0
  60. data/lib/sidekiq/web/router.rb +104 -0
  61. data/lib/sidekiq/web.rb +158 -200
  62. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  63. data/lib/sidekiq.rb +100 -132
  64. data/sidekiq.gemspec +27 -23
  65. data/web/assets/images/apple-touch-icon.png +0 -0
  66. data/web/assets/images/favicon.ico +0 -0
  67. data/web/assets/javascripts/application.js +177 -72
  68. data/web/assets/javascripts/base-charts.js +106 -0
  69. data/web/assets/javascripts/chart.min.js +13 -0
  70. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  71. data/web/assets/javascripts/dashboard-charts.js +192 -0
  72. data/web/assets/javascripts/dashboard.js +37 -286
  73. data/web/assets/javascripts/metrics.js +298 -0
  74. data/web/assets/stylesheets/application-dark.css +147 -0
  75. data/web/assets/stylesheets/application-rtl.css +163 -0
  76. data/web/assets/stylesheets/application.css +228 -247
  77. data/web/assets/stylesheets/bootstrap-rtl.min.css +9 -0
  78. data/web/assets/stylesheets/bootstrap.css +4 -8
  79. data/web/locales/ar.yml +87 -0
  80. data/web/locales/cs.yml +62 -52
  81. data/web/locales/da.yml +60 -53
  82. data/web/locales/de.yml +65 -53
  83. data/web/locales/el.yml +43 -24
  84. data/web/locales/en.yml +86 -61
  85. data/web/locales/es.yml +70 -53
  86. data/web/locales/fa.yml +80 -0
  87. data/web/locales/fr.yml +86 -56
  88. data/web/locales/gd.yml +99 -0
  89. data/web/locales/he.yml +80 -0
  90. data/web/locales/hi.yml +59 -59
  91. data/web/locales/it.yml +53 -53
  92. data/web/locales/ja.yml +78 -56
  93. data/web/locales/ko.yml +52 -52
  94. data/web/locales/lt.yml +83 -0
  95. data/web/locales/{no.yml → nb.yml} +62 -54
  96. data/web/locales/nl.yml +52 -52
  97. data/web/locales/pl.yml +45 -45
  98. data/web/locales/pt-br.yml +83 -55
  99. data/web/locales/pt.yml +51 -51
  100. data/web/locales/ru.yml +68 -60
  101. data/web/locales/sv.yml +53 -53
  102. data/web/locales/ta.yml +60 -60
  103. data/web/locales/tr.yml +101 -0
  104. data/web/locales/uk.yml +77 -0
  105. data/web/locales/ur.yml +80 -0
  106. data/web/locales/vi.yml +83 -0
  107. data/web/locales/zh-cn.yml +43 -16
  108. data/web/locales/zh-tw.yml +42 -8
  109. data/web/views/_footer.erb +22 -9
  110. data/web/views/_job_info.erb +27 -6
  111. data/web/views/_metrics_period_select.erb +12 -0
  112. data/web/views/_nav.erb +8 -22
  113. data/web/views/_paging.erb +3 -1
  114. data/web/views/_poll_link.erb +4 -0
  115. data/web/views/_summary.erb +7 -7
  116. data/web/views/busy.erb +91 -31
  117. data/web/views/dashboard.erb +52 -22
  118. data/web/views/dead.erb +5 -4
  119. data/web/views/filtering.erb +7 -0
  120. data/web/views/layout.erb +19 -7
  121. data/web/views/metrics.erb +91 -0
  122. data/web/views/metrics_for_job.erb +59 -0
  123. data/web/views/morgue.erb +26 -20
  124. data/web/views/queue.erb +36 -25
  125. data/web/views/queues.erb +24 -7
  126. data/web/views/retries.erb +29 -21
  127. data/web/views/retry.erb +6 -5
  128. data/web/views/scheduled.erb +20 -17
  129. data/web/views/scheduled_job_info.erb +2 -1
  130. metadata +101 -232
  131. data/.gitignore +0 -12
  132. data/.travis.yml +0 -16
  133. data/3.0-Upgrade.md +0 -70
  134. data/COMM-LICENSE +0 -85
  135. data/Contributing.md +0 -32
  136. data/Gemfile +0 -22
  137. data/LICENSE +0 -9
  138. data/Pro-2.0-Upgrade.md +0 -138
  139. data/Pro-Changes.md +0 -412
  140. data/Rakefile +0 -9
  141. data/bin/sidekiqctl +0 -93
  142. data/lib/generators/sidekiq/templates/worker_spec.rb.erb +0 -6
  143. data/lib/generators/sidekiq/templates/worker_test.rb.erb +0 -8
  144. data/lib/generators/sidekiq/worker_generator.rb +0 -49
  145. data/lib/sidekiq/actor.rb +0 -39
  146. data/lib/sidekiq/core_ext.rb +0 -105
  147. data/lib/sidekiq/exception_handler.rb +0 -30
  148. data/lib/sidekiq/extensions/action_mailer.rb +0 -56
  149. data/lib/sidekiq/extensions/active_record.rb +0 -39
  150. data/lib/sidekiq/extensions/class_methods.rb +0 -39
  151. data/lib/sidekiq/extensions/generic_proxy.rb +0 -24
  152. data/lib/sidekiq/logging.rb +0 -104
  153. data/lib/sidekiq/middleware/server/active_record.rb +0 -13
  154. data/lib/sidekiq/middleware/server/logging.rb +0 -35
  155. data/lib/sidekiq/middleware/server/retry_jobs.rb +0 -206
  156. data/lib/sidekiq/util.rb +0 -55
  157. data/lib/sidekiq/web_helpers.rb +0 -234
  158. data/lib/sidekiq/worker.rb +0 -89
  159. data/test/config.yml +0 -9
  160. data/test/env_based_config.yml +0 -11
  161. data/test/fake_env.rb +0 -0
  162. data/test/fixtures/en.yml +0 -2
  163. data/test/helper.rb +0 -39
  164. data/test/test_api.rb +0 -494
  165. data/test/test_cli.rb +0 -365
  166. data/test/test_client.rb +0 -269
  167. data/test/test_exception_handler.rb +0 -55
  168. data/test/test_extensions.rb +0 -120
  169. data/test/test_fetch.rb +0 -104
  170. data/test/test_logging.rb +0 -34
  171. data/test/test_manager.rb +0 -164
  172. data/test/test_middleware.rb +0 -159
  173. data/test/test_processor.rb +0 -166
  174. data/test/test_redis_connection.rb +0 -127
  175. data/test/test_retry.rb +0 -373
  176. data/test/test_scheduled.rb +0 -120
  177. data/test/test_scheduling.rb +0 -71
  178. data/test/test_sidekiq.rb +0 -69
  179. data/test/test_testing.rb +0 -82
  180. data/test/test_testing_fake.rb +0 -271
  181. data/test/test_testing_inline.rb +0 -93
  182. data/test/test_web.rb +0 -594
  183. data/test/test_web_helpers.rb +0 -52
  184. data/test/test_worker_generator.rb +0 -17
  185. data/web/assets/images/bootstrap/glyphicons-halflings-white.png +0 -0
  186. data/web/assets/images/bootstrap/glyphicons-halflings.png +0 -0
  187. data/web/assets/images/status/active.png +0 -0
  188. data/web/assets/images/status/idle.png +0 -0
  189. data/web/assets/javascripts/locales/README.md +0 -27
  190. data/web/assets/javascripts/locales/jquery.timeago.ar.js +0 -96
  191. data/web/assets/javascripts/locales/jquery.timeago.bg.js +0 -18
  192. data/web/assets/javascripts/locales/jquery.timeago.bs.js +0 -49
  193. data/web/assets/javascripts/locales/jquery.timeago.ca.js +0 -18
  194. data/web/assets/javascripts/locales/jquery.timeago.cs.js +0 -18
  195. data/web/assets/javascripts/locales/jquery.timeago.cy.js +0 -20
  196. data/web/assets/javascripts/locales/jquery.timeago.da.js +0 -18
  197. data/web/assets/javascripts/locales/jquery.timeago.de.js +0 -18
  198. data/web/assets/javascripts/locales/jquery.timeago.el.js +0 -18
  199. data/web/assets/javascripts/locales/jquery.timeago.en-short.js +0 -20
  200. data/web/assets/javascripts/locales/jquery.timeago.en.js +0 -20
  201. data/web/assets/javascripts/locales/jquery.timeago.es.js +0 -18
  202. data/web/assets/javascripts/locales/jquery.timeago.et.js +0 -18
  203. data/web/assets/javascripts/locales/jquery.timeago.fa.js +0 -22
  204. data/web/assets/javascripts/locales/jquery.timeago.fi.js +0 -28
  205. data/web/assets/javascripts/locales/jquery.timeago.fr-short.js +0 -16
  206. data/web/assets/javascripts/locales/jquery.timeago.fr.js +0 -17
  207. data/web/assets/javascripts/locales/jquery.timeago.he.js +0 -18
  208. data/web/assets/javascripts/locales/jquery.timeago.hr.js +0 -49
  209. data/web/assets/javascripts/locales/jquery.timeago.hu.js +0 -18
  210. data/web/assets/javascripts/locales/jquery.timeago.hy.js +0 -18
  211. data/web/assets/javascripts/locales/jquery.timeago.id.js +0 -18
  212. data/web/assets/javascripts/locales/jquery.timeago.it.js +0 -16
  213. data/web/assets/javascripts/locales/jquery.timeago.ja.js +0 -19
  214. data/web/assets/javascripts/locales/jquery.timeago.ko.js +0 -17
  215. data/web/assets/javascripts/locales/jquery.timeago.lt.js +0 -20
  216. data/web/assets/javascripts/locales/jquery.timeago.mk.js +0 -20
  217. data/web/assets/javascripts/locales/jquery.timeago.nl.js +0 -20
  218. data/web/assets/javascripts/locales/jquery.timeago.no.js +0 -18
  219. data/web/assets/javascripts/locales/jquery.timeago.pl.js +0 -31
  220. data/web/assets/javascripts/locales/jquery.timeago.pt-br.js +0 -16
  221. data/web/assets/javascripts/locales/jquery.timeago.pt.js +0 -16
  222. data/web/assets/javascripts/locales/jquery.timeago.ro.js +0 -18
  223. data/web/assets/javascripts/locales/jquery.timeago.rs.js +0 -49
  224. data/web/assets/javascripts/locales/jquery.timeago.ru.js +0 -34
  225. data/web/assets/javascripts/locales/jquery.timeago.sk.js +0 -18
  226. data/web/assets/javascripts/locales/jquery.timeago.sl.js +0 -44
  227. data/web/assets/javascripts/locales/jquery.timeago.sv.js +0 -18
  228. data/web/assets/javascripts/locales/jquery.timeago.th.js +0 -20
  229. data/web/assets/javascripts/locales/jquery.timeago.tr.js +0 -16
  230. data/web/assets/javascripts/locales/jquery.timeago.uk.js +0 -34
  231. data/web/assets/javascripts/locales/jquery.timeago.uz.js +0 -19
  232. data/web/assets/javascripts/locales/jquery.timeago.zh-cn.js +0 -20
  233. data/web/assets/javascripts/locales/jquery.timeago.zh-tw.js +0 -20
  234. data/web/views/_poll.erb +0 -10
  235. /data/web/assets/images/{status-sd8051fd480.png → status.png} +0 -0
data/test/test_web.rb DELETED
@@ -1,594 +0,0 @@
1
- # encoding: utf-8
2
- require_relative 'helper'
3
- require 'sidekiq'
4
- require 'sidekiq/web'
5
- require 'rack/test'
6
-
7
- class TestWeb < Sidekiq::Test
8
-
9
- describe 'sidekiq web' do
10
- include Rack::Test::Methods
11
-
12
- def app
13
- Sidekiq::Web
14
- end
15
-
16
- def job_params(job, score)
17
- "#{score}-#{job['jid']}"
18
- end
19
-
20
- before do
21
- Sidekiq.redis = REDIS
22
- Sidekiq.redis {|c| c.flushdb }
23
- end
24
-
25
- class WebWorker
26
- include Sidekiq::Worker
27
-
28
- def perform(a, b)
29
- a + b
30
- end
31
- end
32
-
33
- it 'can show text with any locales' do
34
- rackenv = {'HTTP_ACCEPT_LANGUAGE' => 'ru,en'}
35
- get '/', {}, rackenv
36
- assert_match(/Панель управления/, last_response.body)
37
- rackenv = {'HTTP_ACCEPT_LANGUAGE' => 'es,en'}
38
- get '/', {}, rackenv
39
- assert_match(/Panel de Control/, last_response.body)
40
- rackenv = {'HTTP_ACCEPT_LANGUAGE' => 'en-us'}
41
- get '/', {}, rackenv
42
- assert_match(/Dashboard/, last_response.body)
43
- end
44
-
45
- describe 'busy' do
46
-
47
- it 'can display workers' do
48
- Sidekiq.redis do |conn|
49
- conn.incr('busy')
50
- conn.sadd('processes', 'foo:1234')
51
- conn.hmset('foo:1234', 'info', Sidekiq.dump_json('hostname' => 'foo', 'started_at' => Time.now.to_f, "queues" => []), 'at', Time.now.to_f, 'busy', 4)
52
- identity = 'foo:1234:workers'
53
- hash = {:queue => 'critical', :payload => { 'class' => WebWorker.name, 'args' => [1,'abc'] }, :run_at => Time.now.to_i }
54
- conn.hmset(identity, 1001, Sidekiq.dump_json(hash))
55
- end
56
- assert_equal ['1001'], Sidekiq::Workers.new.map { |pid, tid, data| tid }
57
-
58
- get '/busy'
59
- assert_equal 200, last_response.status
60
- assert_match(/status-active/, last_response.body)
61
- assert_match(/critical/, last_response.body)
62
- assert_match(/WebWorker/, last_response.body)
63
- end
64
-
65
- it 'can quiet a process' do
66
- identity = 'identity'
67
- signals_key = "#{identity}-signals"
68
-
69
- assert_nil Sidekiq.redis { |c| c.lpop signals_key }
70
- post '/busy', 'quiet' => '1', 'identity' => identity
71
- assert_equal 302, last_response.status
72
- assert_equal 'USR1', Sidekiq.redis { |c| c.lpop signals_key }
73
- end
74
-
75
- it 'can stop a process' do
76
- identity = 'identity'
77
- signals_key = "#{identity}-signals"
78
-
79
- assert_nil Sidekiq.redis { |c| c.lpop signals_key }
80
- post '/busy', 'stop' => '1', 'identity' => identity
81
- assert_equal 302, last_response.status
82
- assert_equal 'TERM', Sidekiq.redis { |c| c.lpop signals_key }
83
- end
84
- end
85
-
86
- it 'can display queues' do
87
- assert Sidekiq::Client.push('queue' => :foo, 'class' => WebWorker, 'args' => [1, 3])
88
-
89
- get '/queues'
90
- assert_equal 200, last_response.status
91
- assert_match(/foo/, last_response.body)
92
- refute_match(/HardWorker/, last_response.body)
93
- end
94
-
95
- it 'handles queue view' do
96
- get '/queues/default'
97
- assert_equal 200, last_response.status
98
- end
99
-
100
- it 'can delete a queue' do
101
- Sidekiq.redis do |conn|
102
- conn.rpush('queue:foo', '{}')
103
- conn.sadd('queues', 'foo')
104
- end
105
-
106
- get '/queues/foo'
107
- assert_equal 200, last_response.status
108
-
109
- post '/queues/foo'
110
- assert_equal 302, last_response.status
111
-
112
- Sidekiq.redis do |conn|
113
- refute conn.smembers('queues').include?('foo')
114
- refute conn.exists('queue:foo')
115
- end
116
- end
117
-
118
- it 'can delete a job' do
119
- Sidekiq.redis do |conn|
120
- conn.rpush('queue:foo', "{}")
121
- conn.rpush('queue:foo', "{\"foo\":\"bar\"}")
122
- conn.rpush('queue:foo', "{\"foo2\":\"bar2\"}")
123
- end
124
-
125
- get '/queues/foo'
126
- assert_equal 200, last_response.status
127
-
128
- post '/queues/foo/delete', key_val: "{\"foo\":\"bar\"}"
129
- assert_equal 302, last_response.status
130
-
131
- Sidekiq.redis do |conn|
132
- refute conn.lrange('queue:foo', 0, -1).include?("{\"foo\":\"bar\"}")
133
- end
134
- end
135
-
136
- it 'can display retries' do
137
- get '/retries'
138
- assert_equal 200, last_response.status
139
- assert_match(/found/, last_response.body)
140
- refute_match(/HardWorker/, last_response.body)
141
-
142
- add_retry
143
-
144
- get '/retries'
145
- assert_equal 200, last_response.status
146
- refute_match(/found/, last_response.body)
147
- assert_match(/HardWorker/, last_response.body)
148
- end
149
-
150
- it 'can display a single retry' do
151
- params = add_retry
152
- get '/retries/0-shouldntexist'
153
- assert_equal 302, last_response.status
154
- get "/retries/#{job_params(*params)}"
155
- assert_equal 200, last_response.status
156
- assert_match(/HardWorker/, last_response.body)
157
- end
158
-
159
- it 'handles missing retry' do
160
- get "/retries/0-shouldntexist"
161
- assert_equal 302, last_response.status
162
- end
163
-
164
- it 'can delete a single retry' do
165
- params = add_retry
166
- post "/retries/#{job_params(*params)}", 'delete' => 'Delete'
167
- assert_equal 302, last_response.status
168
- assert_equal 'http://example.org/retries', last_response.header['Location']
169
-
170
- get "/retries"
171
- assert_equal 200, last_response.status
172
- refute_match(/#{params.first['args'][2]}/, last_response.body)
173
- end
174
-
175
- it 'can delete all retries' do
176
- 3.times { add_retry }
177
-
178
- post "/retries/all/delete", 'delete' => 'Delete'
179
- assert_equal 0, Sidekiq::RetrySet.new.size
180
- assert_equal 302, last_response.status
181
- assert_equal 'http://example.org/retries', last_response.header['Location']
182
- end
183
-
184
- it 'can retry a single retry now' do
185
- params = add_retry
186
- post "/retries/#{job_params(*params)}", 'retry' => 'Retry'
187
- assert_equal 302, last_response.status
188
- assert_equal 'http://example.org/retries', last_response.header['Location']
189
-
190
- get '/queues/default'
191
- assert_equal 200, last_response.status
192
- assert_match(/#{params.first['args'][2]}/, last_response.body)
193
- end
194
-
195
- it 'can kill a single retry now' do
196
- params = add_retry
197
- post "/retries/#{job_params(*params)}", 'kill' => 'Kill'
198
- assert_equal 302, last_response.status
199
- assert_equal 'http://example.org/retries', last_response.header['Location']
200
-
201
- get '/morgue'
202
- assert_equal 200, last_response.status
203
- assert_match(/#{params.first['args'][2]}/, last_response.body)
204
- end
205
-
206
- it 'can display scheduled' do
207
- get '/scheduled'
208
- assert_equal 200, last_response.status
209
- assert_match(/found/, last_response.body)
210
- refute_match(/HardWorker/, last_response.body)
211
-
212
- add_scheduled
213
-
214
- get '/scheduled'
215
- assert_equal 200, last_response.status
216
- refute_match(/found/, last_response.body)
217
- assert_match(/HardWorker/, last_response.body)
218
- end
219
-
220
- it 'can display a single scheduled job' do
221
- params = add_scheduled
222
- get '/scheduled/0-shouldntexist'
223
- assert_equal 302, last_response.status
224
- get "/scheduled/#{job_params(*params)}"
225
- assert_equal 200, last_response.status
226
- assert_match(/HardWorker/, last_response.body)
227
- end
228
-
229
- it 'handles missing scheduled job' do
230
- get "/scheduled/0-shouldntexist"
231
- assert_equal 302, last_response.status
232
- end
233
-
234
- it 'can add to queue a single scheduled job' do
235
- params = add_scheduled
236
- post "/scheduled/#{job_params(*params)}", 'add_to_queue' => true
237
- assert_equal 302, last_response.status
238
- assert_equal 'http://example.org/scheduled', last_response.header['Location']
239
-
240
- get '/queues/default'
241
- assert_equal 200, last_response.status
242
- assert_match(/#{params.first['args'][2]}/, last_response.body)
243
- end
244
-
245
- it 'can delete a single scheduled job' do
246
- params = add_scheduled
247
- post "/scheduled/#{job_params(*params)}", 'delete' => 'Delete'
248
- assert_equal 302, last_response.status
249
- assert_equal 'http://example.org/scheduled', last_response.header['Location']
250
-
251
- get "/scheduled"
252
- assert_equal 200, last_response.status
253
- refute_match(/#{params.first['args'][2]}/, last_response.body)
254
- end
255
-
256
- it 'can delete scheduled' do
257
- params = add_scheduled
258
- Sidekiq.redis do |conn|
259
- assert_equal 1, conn.zcard('schedule')
260
- post '/scheduled', 'key' => [job_params(*params)], 'delete' => 'Delete'
261
- assert_equal 302, last_response.status
262
- assert_equal 'http://example.org/scheduled', last_response.header['Location']
263
- assert_equal 0, conn.zcard('schedule')
264
- end
265
- end
266
-
267
- it "can move scheduled to default queue" do
268
- q = Sidekiq::Queue.new
269
- params = add_scheduled
270
- Sidekiq.redis do |conn|
271
- assert_equal 1, conn.zcard('schedule')
272
- assert_equal 0, q.size
273
- post '/scheduled', 'key' => [job_params(*params)], 'add_to_queue' => 'AddToQueue'
274
- assert_equal 302, last_response.status
275
- assert_equal 'http://example.org/scheduled', last_response.header['Location']
276
- assert_equal 0, conn.zcard('schedule')
277
- assert_equal 1, q.size
278
- get '/queues/default'
279
- assert_equal 200, last_response.status
280
- assert_match(/#{params[0]['args'][2]}/, last_response.body)
281
- end
282
- end
283
-
284
- it 'can retry all retries' do
285
- msg = add_retry.first
286
- add_retry
287
-
288
- post "/retries/all/retry", 'retry' => 'Retry'
289
- assert_equal 302, last_response.status
290
- assert_equal 'http://example.org/retries', last_response.header['Location']
291
- assert_equal 2, Sidekiq::Queue.new("default").size
292
-
293
- get '/queues/default'
294
- assert_equal 200, last_response.status
295
- assert_match /#{msg['args'][2]}/, last_response.body
296
- end
297
-
298
- it 'escape job args and error messages' do
299
- # on /retries page
300
- params = add_xss_retry
301
- get '/retries'
302
- assert_equal 200, last_response.status
303
- assert_match(/FailWorker/, last_response.body)
304
-
305
- assert last_response.body.include?( "fail message: &lt;a&gt;hello&lt;&#x2F;a&gt;" )
306
- assert !last_response.body.include?( "fail message: <a>hello</a>" )
307
-
308
- assert last_response.body.include?( "args\">&quot;&lt;a&gt;hello&lt;&#x2F;a&gt;&quot;<" )
309
- assert !last_response.body.include?( "args\"><a>hello</a><" )
310
-
311
- # on /workers page
312
- Sidekiq.redis do |conn|
313
- pro = 'foo:1234'
314
- conn.sadd('processes', pro)
315
- conn.hmset(pro, 'info', Sidekiq.dump_json('started_at' => Time.now.to_f, 'labels' => ['frumduz'], 'queues' =>[]), 'busy', 1, 'beat', Time.now.to_f)
316
- identity = "#{pro}:workers"
317
- hash = {:queue => 'critical', :payload => { 'class' => "FailWorker", 'args' => ["<a>hello</a>"] }, :run_at => Time.now.to_i }
318
- conn.hmset(identity, 100001, Sidekiq.dump_json(hash))
319
- conn.incr('busy')
320
- end
321
-
322
- get '/busy'
323
- assert_equal 200, last_response.status
324
- assert_match(/FailWorker/, last_response.body)
325
- assert_match(/frumduz/, last_response.body)
326
- assert last_response.body.include?( "&lt;a&gt;hello&lt;&#x2F;a&gt;" )
327
- assert !last_response.body.include?( "<a>hello</a>" )
328
-
329
-
330
- # on /queues page
331
- params = add_xss_retry # sorry, don't know how to easily make this show up on queues page otherwise.
332
- post "/retries/#{job_params(*params)}", 'retry' => 'Retry'
333
- assert_equal 302, last_response.status
334
-
335
- get '/queues/foo'
336
- assert_equal 200, last_response.status
337
- assert last_response.body.include?( "&lt;a&gt;hello&lt;&#x2F;a&gt;" )
338
- assert !last_response.body.include?( "<a>hello</a>" )
339
- end
340
-
341
- it 'can show user defined tab' do
342
- begin
343
- Sidekiq::Web.tabs['Custom Tab'] = '/custom'
344
-
345
- get '/'
346
- assert_match 'Custom Tab', last_response.body
347
-
348
- ensure
349
- Sidekiq::Web.tabs.delete 'Custom Tab'
350
- end
351
- end
352
-
353
- it 'can display home' do
354
- get '/'
355
- assert_equal 200, last_response.status
356
- end
357
-
358
- Sidekiq::Web.settings.locales << File.join(File.dirname(__FILE__), "fixtures")
359
- it 'can show user defined tab with custom locales' do
360
- begin
361
- Sidekiq::Web.tabs['Custom Tab'] = '/custom'
362
- Sidekiq::Web.get('/custom') do
363
- t('translated_text')
364
- end
365
-
366
- get '/custom'
367
- assert_match(/Changed text/, last_response.body)
368
-
369
- ensure
370
- Sidekiq::Web.tabs.delete 'Custom Tab'
371
- end
372
- end
373
-
374
- describe 'dashboard/stats' do
375
- it 'redirects to stats' do
376
- get '/dashboard/stats'
377
- assert_equal 302, last_response.status
378
- assert_equal 'http://example.org/stats', last_response.header['Location']
379
- end
380
- end
381
-
382
- describe 'stats' do
383
- include Sidekiq::Util
384
-
385
- before do
386
- Sidekiq.redis do |conn|
387
- conn.set("stat:processed", 5)
388
- conn.set("stat:failed", 2)
389
- conn.sadd("queues", "default")
390
- end
391
- 2.times { add_retry }
392
- 3.times { add_scheduled }
393
- 4.times { add_worker }
394
-
395
- get '/stats'
396
- @response = Sidekiq.load_json(last_response.body)
397
- end
398
-
399
- it 'can refresh dashboard stats' do
400
- assert_equal 200, last_response.status
401
- end
402
-
403
- describe "for sidekiq" do
404
- it 'are namespaced' do
405
- assert_includes @response.keys, "sidekiq"
406
- end
407
-
408
- it 'reports processed' do
409
- assert_equal 5, @response["sidekiq"]["processed"]
410
- end
411
-
412
- it 'reports failed' do
413
- assert_equal 2, @response["sidekiq"]["failed"]
414
- end
415
-
416
- it 'reports busy' do
417
- assert_equal 4, @response["sidekiq"]["busy"]
418
- end
419
-
420
- it 'reports processes' do
421
- assert_equal 1, @response["sidekiq"]["processes"]
422
- end
423
-
424
- it 'reports retries' do
425
- assert_equal 2, @response["sidekiq"]["retries"]
426
- end
427
-
428
- it 'reports scheduled' do
429
- assert_equal 3, @response["sidekiq"]["scheduled"]
430
- end
431
-
432
- it 'reports latency' do
433
- assert_equal 0, @response["sidekiq"]["default_latency"]
434
- end
435
- end
436
-
437
- describe "for redis" do
438
- it 'are namespaced' do
439
- assert_includes @response.keys, "redis"
440
- end
441
-
442
- it 'reports version' do
443
- assert_includes @response["redis"].keys, "redis_version"
444
- end
445
-
446
- it 'reports uptime' do
447
- assert_includes @response["redis"].keys, "uptime_in_days"
448
- end
449
-
450
- it 'reports connected clients' do
451
- assert_includes @response["redis"].keys, "connected_clients"
452
- end
453
-
454
- it 'reports user memory' do
455
- assert_includes @response["redis"].keys, "used_memory_human"
456
- end
457
-
458
- it 'reports memory peak' do
459
- assert_includes @response["redis"].keys, "used_memory_peak_human"
460
- end
461
- end
462
- end
463
-
464
- describe 'stats/queues' do
465
- include Sidekiq::Util
466
-
467
- before do
468
- Sidekiq.redis do |conn|
469
- conn.set("stat:processed", 5)
470
- conn.set("stat:failed", 2)
471
- conn.sadd("queues", "default")
472
- conn.sadd("queues", "queue2")
473
- end
474
- 2.times { add_retry }
475
- 3.times { add_scheduled }
476
- 4.times { add_worker }
477
-
478
- get '/stats/queues'
479
- @response = Sidekiq.load_json(last_response.body)
480
- end
481
-
482
- it 'reports the queue depth' do
483
- assert_equal 0, @response["default"]
484
- assert_equal 0, @response["queue2"]
485
- end
486
- end
487
-
488
- describe 'dead jobs' do
489
- it 'shows empty index' do
490
- get 'morgue'
491
- assert_equal 200, last_response.status
492
- end
493
-
494
- it 'shows index with jobs' do
495
- (_, score) = add_dead
496
- get 'morgue'
497
- assert_equal 200, last_response.status
498
- assert_match(/#{score}/, last_response.body)
499
- end
500
-
501
- it 'can delete all dead' do
502
- 3.times { add_dead }
503
-
504
- assert_equal 3, Sidekiq::DeadSet.new.size
505
- post "/morgue/all/delete", 'delete' => 'Delete'
506
- assert_equal 0, Sidekiq::DeadSet.new.size
507
- assert_equal 302, last_response.status
508
- assert_equal 'http://example.org/morgue', last_response.header['Location']
509
- end
510
-
511
- it 'can retry a dead job' do
512
- params = add_dead
513
- post "/morgue/#{job_params(*params)}", 'retry' => 'Retry'
514
- assert_equal 302, last_response.status
515
- assert_equal 'http://example.org/morgue', last_response.header['Location']
516
-
517
- get '/queues/foo'
518
- assert_equal 200, last_response.status
519
- assert_match(/#{params.first['args'][2]}/, last_response.body)
520
- end
521
- end
522
-
523
- def add_scheduled
524
- score = Time.now.to_f
525
- msg = { 'class' => 'HardWorker',
526
- 'args' => ['bob', 1, Time.now.to_f],
527
- 'jid' => SecureRandom.hex(12) }
528
- Sidekiq.redis do |conn|
529
- conn.zadd('schedule', score, Sidekiq.dump_json(msg))
530
- end
531
- [msg, score]
532
- end
533
-
534
- def add_retry
535
- msg = { 'class' => 'HardWorker',
536
- 'args' => ['bob', 1, Time.now.to_f],
537
- 'queue' => 'default',
538
- 'error_message' => 'Some fake message',
539
- 'error_class' => 'RuntimeError',
540
- 'retry_count' => 0,
541
- 'failed_at' => Time.now.to_f,
542
- 'jid' => SecureRandom.hex(12) }
543
- score = Time.now.to_f
544
- Sidekiq.redis do |conn|
545
- conn.zadd('retry', score, Sidekiq.dump_json(msg))
546
- end
547
- [msg, score]
548
- end
549
-
550
- def add_dead
551
- msg = { 'class' => 'HardWorker',
552
- 'args' => ['bob', 1, Time.now.to_f],
553
- 'queue' => 'foo',
554
- 'error_message' => 'Some fake message',
555
- 'error_class' => 'RuntimeError',
556
- 'retry_count' => 0,
557
- 'failed_at' => Time.now.utc,
558
- 'jid' => SecureRandom.hex(12) }
559
- score = Time.now.to_f
560
- Sidekiq.redis do |conn|
561
- conn.zadd('dead', score, Sidekiq.dump_json(msg))
562
- end
563
- [msg, score]
564
- end
565
-
566
- def add_xss_retry
567
- msg = { 'class' => 'FailWorker',
568
- 'args' => ['<a>hello</a>'],
569
- 'queue' => 'foo',
570
- 'error_message' => 'fail message: <a>hello</a>',
571
- 'error_class' => 'RuntimeError',
572
- 'retry_count' => 0,
573
- 'failed_at' => Time.now.to_f,
574
- 'jid' => SecureRandom.hex(12) }
575
- score = Time.now.to_f
576
- Sidekiq.redis do |conn|
577
- conn.zadd('retry', score, Sidekiq.dump_json(msg))
578
- end
579
- [msg, score]
580
- end
581
-
582
- def add_worker
583
- key = "#{hostname}:#{$$}"
584
- msg = "{\"queue\":\"default\",\"payload\":{\"retry\":true,\"queue\":\"default\",\"timeout\":20,\"backtrace\":5,\"class\":\"HardWorker\",\"args\":[\"bob\",10,5],\"jid\":\"2b5ad2b016f5e063a1c62872\"},\"run_at\":1361208995}"
585
- Sidekiq.redis do |conn|
586
- conn.multi do
587
- conn.sadd("processes", key)
588
- conn.hmset(key, 'info', Sidekiq.dump_json('hostname' => 'foo', 'started_at' => Time.now.to_f, "queues" => []), 'at', Time.now.to_f, 'busy', 4)
589
- conn.hmset("#{key}:workers", Time.now.to_f, msg)
590
- end
591
- end
592
- end
593
- end
594
- end
@@ -1,52 +0,0 @@
1
- require_relative 'helper'
2
- require 'sidekiq'
3
- require 'sidekiq/web_helpers'
4
-
5
- class TestWebHelpers < Sidekiq::Test
6
-
7
- class Helpers
8
- include Sidekiq::WebHelpers
9
-
10
- def initialize(params={})
11
- @thehash = default.merge(params)
12
- end
13
-
14
- def request
15
- self
16
- end
17
-
18
- def settings
19
- self
20
- end
21
-
22
- def locales
23
- ['web/locales']
24
- end
25
-
26
- def env
27
- @thehash
28
- end
29
-
30
- def default
31
- {
32
- }
33
- end
34
- end
35
-
36
- def test_locale_determination
37
- obj = Helpers.new
38
- assert_equal 'en', obj.locale
39
-
40
- obj = Helpers.new('HTTP_ACCEPT_LANGUAGE' => 'fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,ru;q=0.2')
41
- assert_equal 'fr', obj.locale
42
-
43
- obj = Helpers.new('HTTP_ACCEPT_LANGUAGE' => 'zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4,ru;q=0.2')
44
- assert_equal 'zh-cn', obj.locale
45
-
46
- obj = Helpers.new('HTTP_ACCEPT_LANGUAGE' => 'en-us; *')
47
- assert_equal 'en', obj.locale
48
-
49
- obj = Helpers.new('HTTP_ACCEPT_LANGUAGE' => '*')
50
- assert_equal 'en', obj.locale
51
- end
52
- end
@@ -1,17 +0,0 @@
1
- require_relative 'helper'
2
- require 'rails/generators/test_case'
3
- require 'generators/sidekiq/worker_generator'
4
-
5
- class WorkerGeneratorTest < Rails::Generators::TestCase
6
- tests Sidekiq::Generators::WorkerGenerator
7
- arguments %w(foo)
8
- destination File.expand_path("../tmp", File.dirname(__FILE__))
9
- setup :prepare_destination
10
-
11
- test "worker is created and its test" do
12
- run_generator
13
-
14
- assert_file "app/workers/foo_worker.rb"
15
- assert_file "test/workers/foo_worker_test.rb"
16
- end
17
- end
Binary file
Binary file
@@ -1,27 +0,0 @@
1
- # Locale override examples for timeago
2
-
3
- You can represent time statements in most western languages where
4
- a prefix and/or suffix is used.
5
-
6
- The default case is to use suffix only (as in English), which you
7
- do by providing the `suffixAgo` and `suffixFromNow` settings in
8
- the strings hash (earlier versions of timeago used the deprecated
9
- `ago` and `fromNow` options). If present, they are used.
10
-
11
- 2 minutes [suffixAgo]
12
- 2 minutes [suffixFromNow]
13
-
14
- In case you want to use prefix only instead of
15
- suffix (e.g. Greek), you provide the `prefixAgo` and
16
- `prefixFromNow` options in the strings hash and leave `suffixAgo`
17
- and `suffixFromNow` empty or null.
18
-
19
- [prefixAgo] 2 minutes
20
- [prefixFromNow] 2 minutes
21
-
22
- For languages where you want to use a prefix only for future
23
- tense and prefix/suffix for past tense (for example swedish), you
24
- can combine the prefix and suffixes as needed.
25
-
26
- [prefixAgo] 2 minutes [suffixAgo]
27
- [prefixFromNow] 2 minutes