sidekiq-failures 0.4.3 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +10 -10
- data/CHANGELOG.md +34 -0
- data/Gemfile +6 -0
- data/README.md +1 -1
- data/lib/sidekiq/failures.rb +18 -4
- data/lib/sidekiq/failures/locales/ja.yml +6 -0
- data/lib/sidekiq/failures/locales/pt-BR.yml +5 -0
- data/lib/sidekiq/failures/middleware.rb +3 -2
- data/lib/sidekiq/failures/version.rb +1 -1
- data/lib/sidekiq/failures/views/failure.erb +1 -0
- data/lib/sidekiq/failures/views/failures.erb +26 -16
- data/lib/sidekiq/failures/web_extension.rb +12 -1
- data/sidekiq-failures.gemspec +10 -1
- data/test/failures_test.rb +16 -0
- data/test/middleware_test.rb +22 -14
- data/test/test_helper.rb +3 -5
- data/test/web_extension_test.rb +67 -45
- metadata +28 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 411bc0eb000e29f27b3d5afd27e39719c693df17ce7b08baace66e42f4b8c402
|
4
|
+
data.tar.gz: 88174d41395b3953bf089590775e8e34725c4f47109a379727df08c4331ad8d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90a60cb2e7b0e8dac73aa3cc188d81e4616354ecdc259bb82680fea63cf2e171e19ddb009f21b686ab95fe30fcb9b0090d45335aaaf16c4985d9770e584aa749
|
7
|
+
data.tar.gz: 76886912d60887ed578b1b9d2e3ac0b4824b0db0087d776f590ef6c2cf060ad543d331848173c4e0c285ce72789c315586a4bbea6ce7f8b777db9ea17a293057
|
data/.travis.yml
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
language: ruby
|
2
|
+
sudo: false
|
3
|
+
cache: bundler
|
2
4
|
services:
|
3
5
|
- redis-server
|
4
6
|
rvm:
|
5
|
-
- 1.
|
6
|
-
-
|
7
|
-
- 2.
|
8
|
-
- 2.
|
7
|
+
- jruby-9.1.6.0
|
8
|
+
- 2.2.4
|
9
|
+
- 2.3.0
|
10
|
+
- 2.4.0
|
9
11
|
env:
|
10
12
|
matrix:
|
11
|
-
- SIDEKIQ_VERSION="~>
|
12
|
-
- SIDEKIQ_VERSION="~> 2
|
13
|
-
- SIDEKIQ_VERSION="~>
|
14
|
-
- SIDEKIQ_VERSION="~> 3.1"
|
13
|
+
- SIDEKIQ_VERSION="~> 4.0"
|
14
|
+
- SIDEKIQ_VERSION="~> 4.2"
|
15
|
+
- SIDEKIQ_VERSION="~> 5.0"
|
15
16
|
matrix:
|
16
17
|
allow_failures:
|
17
|
-
- rvm: 1.
|
18
|
-
- rvm: jruby-19mode
|
18
|
+
- rvm: jruby-9.1.6.0
|
data/CHANGELOG.md
CHANGED
@@ -1,16 +1,45 @@
|
|
1
1
|
## Unreleased
|
2
2
|
|
3
|
+
## 1.0.1
|
4
|
+
|
5
|
+
* Add license config to the gemspec (#115 @reiz)
|
6
|
+
* Guard against failure error_message being `nil` (#122 @mcasper)
|
7
|
+
* Fix filtering failures with 0 results on Sidekiq Pro (#125 @substars)
|
8
|
+
|
9
|
+
## 1.0.0
|
10
|
+
|
11
|
+
* WebUI improvements (@bbtfr)
|
12
|
+
* Use ActiveJob to display info when available (@dreyks)
|
13
|
+
* New locales (@ryohashimoto @gurgelrenan)
|
14
|
+
* Sidekiq 4 and higher compatibility (@davekrupinski )
|
15
|
+
* Sidekiq 5 fixes (@fidelisrafael)
|
16
|
+
|
17
|
+
## 0.4.5
|
18
|
+
|
19
|
+
* Limit error message to 500 symbols (@antonzaytsev)
|
20
|
+
* Add conditional csrf_tag to each form instance (@JamesChevalier)
|
21
|
+
|
22
|
+
## 0.4.4
|
23
|
+
|
24
|
+
* Add paging to bottom of the view (@czarneckid)
|
25
|
+
* Always display failure count reset button (@mikeastock)
|
26
|
+
* Fix overflow for large backtrace messages (@marciotrindade)
|
27
|
+
|
3
28
|
## 0.4.3
|
29
|
+
|
4
30
|
* Handle numeric timestamps format (@krasnoukhov)
|
5
31
|
|
6
32
|
## 0.4.2
|
33
|
+
|
7
34
|
* Bump sidekiq dependency to 2.16.0 (@davetoxa)
|
8
35
|
* Handle legacy timestamps (@maltoe)
|
9
36
|
|
10
37
|
## 0.4.1
|
38
|
+
|
11
39
|
* Restore compatibility for failed payloads created with 0.3.0
|
12
40
|
|
13
41
|
## 0.4.0
|
42
|
+
|
14
43
|
* Bump sidekiq dependency to sidekiq >= 2.16.0
|
15
44
|
* Introduce delete(all) / retry(all) (@spectator)
|
16
45
|
* Fix Sidekiq 3 compatibility (@petergoldstein)
|
@@ -18,6 +47,7 @@
|
|
18
47
|
* Explicitly require sidekiq/api (@krasnoukhov)
|
19
48
|
|
20
49
|
## 0.3.0
|
50
|
+
|
21
51
|
* Bump sidekiq dependency to sidekiq >= 2.14.0
|
22
52
|
* Remove slim templates and dependecy
|
23
53
|
* Escape exception info when outputing to html
|
@@ -28,15 +58,18 @@
|
|
28
58
|
* Fix private method call (@bwthomas)
|
29
59
|
|
30
60
|
## 0.2.2
|
61
|
+
|
31
62
|
* Support ERB for sidekiq >= 2.14.0 (@tobiassvn)
|
32
63
|
* Bump sidekiq dep to >= 2.9.0
|
33
64
|
* Show newest failures first (@PlugIN73)
|
34
65
|
* Fix specs (@krasnoukhov)
|
35
66
|
|
36
67
|
## 0.2.1
|
68
|
+
|
37
69
|
* Fix exhausted mode when retry is disabled (@wr0ngway)
|
38
70
|
|
39
71
|
## 0.2.0
|
72
|
+
|
40
73
|
* Added processor identity to failure data (@krasnoukhov)
|
41
74
|
* Handle Sidekiq::Shutdown exceptions (@krasnoukhov)
|
42
75
|
* Add failures maximum count option (@mathieulaporte)
|
@@ -45,6 +78,7 @@
|
|
45
78
|
* Stop overloading find_template (@zquestz)
|
46
79
|
|
47
80
|
## 0.1.0
|
81
|
+
|
48
82
|
* Allow per worker configuration of failure tracking mode. Thanks to
|
49
83
|
@kbaum for most of the work.
|
50
84
|
* Prevent sidekiq-failures from loading up sidekiq/processor (and thus
|
data/Gemfile
CHANGED
@@ -4,3 +4,9 @@ source 'https://rubygems.org'
|
|
4
4
|
gemspec
|
5
5
|
|
6
6
|
gem 'sidekiq', ENV['SIDEKIQ_VERSION'] if ENV['SIDEKIQ_VERSION']
|
7
|
+
|
8
|
+
# to test Pro-specific functionality, set SIDEKIQ_PRO_CREDS on `bundle install`
|
9
|
+
# and SIDEKIQ_PRO_VERSION on `bundle install` and `rake test`
|
10
|
+
source "https://#{ENV['SIDEKIQ_PRO_CREDS']}@enterprise.contribsys.com/" do
|
11
|
+
gem 'sidekiq-pro', ENV['SIDEKIQ_PRO_VERSION'] if ENV['SIDEKIQ_PRO_VERSION']
|
12
|
+
end if ENV['SIDEKIQ_PRO_VERSION']
|
data/README.md
CHANGED
data/lib/sidekiq/failures.rb
CHANGED
@@ -5,6 +5,7 @@ rescue LoadError
|
|
5
5
|
end
|
6
6
|
|
7
7
|
require "sidekiq/api"
|
8
|
+
require "sidekiq/version"
|
8
9
|
require "sidekiq/failures/version"
|
9
10
|
require "sidekiq/failures/sorted_entry"
|
10
11
|
require "sidekiq/failures/failure_set"
|
@@ -47,9 +48,11 @@ module Sidekiq
|
|
47
48
|
|
48
49
|
# Fetches the failures max count value
|
49
50
|
def self.failures_max_count
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
if !instance_variable_defined?(:@failures_max_count) || @failures_max_count.nil?
|
52
|
+
1000
|
53
|
+
else
|
54
|
+
@failures_max_count
|
55
|
+
end
|
53
56
|
end
|
54
57
|
|
55
58
|
module Failures
|
@@ -62,12 +65,23 @@ module Sidekiq
|
|
62
65
|
def self.count
|
63
66
|
Sidekiq.redis {|r| r.zcard(LIST_KEY) }
|
64
67
|
end
|
68
|
+
|
69
|
+
def self.retry_middleware_class
|
70
|
+
if Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('5.0.0')
|
71
|
+
require 'sidekiq/job_retry'
|
72
|
+
Sidekiq::JobRetry
|
73
|
+
else
|
74
|
+
require 'sidekiq/middleware/server/retry_jobs'
|
75
|
+
Sidekiq::Middleware::Server::RetryJobs
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
65
79
|
end
|
66
80
|
end
|
67
81
|
|
68
82
|
Sidekiq.configure_server do |config|
|
69
83
|
config.server_middleware do |chain|
|
70
|
-
chain.insert_before Sidekiq::
|
84
|
+
chain.insert_before Sidekiq::Failures.retry_middleware_class,
|
71
85
|
Sidekiq::Failures::Middleware
|
72
86
|
end
|
73
87
|
end
|
@@ -80,11 +80,12 @@ module Sidekiq
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def retry_middleware
|
83
|
-
@retry_middleware ||=
|
83
|
+
@retry_middleware ||=
|
84
|
+
Sidekiq::Failures.retry_middleware_class.new
|
84
85
|
end
|
85
86
|
|
86
87
|
def default_max_retries
|
87
|
-
Sidekiq::
|
88
|
+
Sidekiq::Failures.retry_middleware_class::DEFAULT_MAX_RETRY_ATTEMPTS
|
88
89
|
end
|
89
90
|
|
90
91
|
def hostname
|
@@ -24,6 +24,7 @@
|
|
24
24
|
</tbody>
|
25
25
|
</table>
|
26
26
|
<form class="form-horizontal" action="<%= root_path %>failures/<%= job_params(@failure, @failure.score) %>" method="post">
|
27
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
27
28
|
<a class="btn" href="<%= root_path %>failures"><%= t('GoBack') %></a>
|
28
29
|
<input class="btn btn-primary" type="submit" name="retry" value="<%= t('RetryNow') %>" />
|
29
30
|
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<div class="col-sm-5">
|
3
3
|
<h3><%= t('FailedJobs') %></h3>
|
4
4
|
</div>
|
5
|
-
<% if @failures.
|
5
|
+
<% if @failures.count > 0 && @total_size > @count %>
|
6
6
|
<div class="col-sm-4">
|
7
7
|
<%= erb :_paging, :locals => { :url => "#{root_path}failures" } %>
|
8
8
|
</div>
|
@@ -10,8 +10,9 @@
|
|
10
10
|
<%= filtering('failures') if respond_to?(:filtering) %>
|
11
11
|
</header>
|
12
12
|
|
13
|
-
<% if @failures.
|
13
|
+
<% if @failures.count > 0 %>
|
14
14
|
<form action="<%= root_path %>failures" method="post">
|
15
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
15
16
|
<table class="table table-striped table-bordered table-white">
|
16
17
|
<thead>
|
17
18
|
<tr>
|
@@ -20,11 +21,11 @@
|
|
20
21
|
<input type="checkbox" class="check_all" />
|
21
22
|
</label>
|
22
23
|
</th>
|
23
|
-
<th
|
24
|
-
<th
|
25
|
-
<th
|
26
|
-
<th
|
27
|
-
<th
|
24
|
+
<th><%= t('FailedAt') %></th>
|
25
|
+
<th><%= t('Queue') %></th>
|
26
|
+
<th><%= t('Worker') %></th>
|
27
|
+
<th><%= t('Arguments') %></th>
|
28
|
+
<th><%= t('Error') %></th>
|
28
29
|
</tr>
|
29
30
|
</thead>
|
30
31
|
<% @failures.each do |entry| %>
|
@@ -34,19 +35,19 @@
|
|
34
35
|
<input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' />
|
35
36
|
</label>
|
36
37
|
</td>
|
37
|
-
<td><a href="<%= root_path %>failures/<%= job_params(entry.item, entry.score) %>"><%= entry
|
38
|
+
<td><a href="<%= root_path %>failures/<%= job_params(entry.item, entry.score) %>"><%= safe_relative_time(entry['failed_at']) %></a></td>
|
38
39
|
<td>
|
39
|
-
<
|
40
|
+
<a href="<%= root_path %>queues/<%= entry.queue %>"><%= entry.queue %></a>
|
40
41
|
</td>
|
42
|
+
<td><%= entry.respond_to?(:display_class) ? entry.display_class : entry.klass %></td>
|
41
43
|
<td>
|
42
|
-
<
|
44
|
+
<div class="args"><%= display_args(entry.respond_to?(:display_args) ? entry.display_args : entry.args) %></div>
|
43
45
|
</td>
|
44
|
-
<td><%= safe_relative_time(entry['failed_at']) %></td>
|
45
46
|
<td style="overflow: auto; padding: 10px;">
|
46
47
|
<a class="backtrace" href="#" onclick="$(this).next().toggle(); return false">
|
47
|
-
<%= h entry['error_class'] %>: <%= h entry['error_message'] %>
|
48
|
+
<%= h entry['error_class'] %>: <%= h entry['error_message'].to_s.size > 500 ? entry['error_message'][0..500] + '...' : entry['error_message'] %>
|
48
49
|
</a>
|
49
|
-
<pre style="display: none; background: none; border: 0; width: 100%; max-height: 30em; font-size: 0.8em; white-space: nowrap;">
|
50
|
+
<pre style="display: none; background: none; border: 0; width: 100%; max-height: 30em; font-size: 0.8em; white-space: nowrap; overflow: auto;">
|
50
51
|
<%= entry['error_backtrace'].join("<br />") if entry['error_backtrace'] %>
|
51
52
|
</pre>
|
52
53
|
<p>
|
@@ -60,16 +61,25 @@
|
|
60
61
|
<input class="btn btn-danger btn-xs pull-left" type="submit" name="delete" value="<%= t('Delete') %>" />
|
61
62
|
</form>
|
62
63
|
|
63
|
-
<form action="<%= root_path %>failures/all/reset" method="post">
|
64
|
-
<input class="btn btn-danger btn-xs pull-right" type="submit" name="reset" value="<%= t('Reset Counter') %>" data-confirm="<%= t('AreYouSure') %>" />
|
65
|
-
</form>
|
66
64
|
<form action="<%= root_path %>failures/all/delete" method="post">
|
65
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
67
66
|
<input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
|
68
67
|
</form>
|
69
68
|
<form action="<%= root_path %>failures/all/retry" method="post">
|
69
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
70
70
|
<input class="btn btn-danger btn-xs pull-right" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
|
71
71
|
</form>
|
72
72
|
|
73
|
+
<% if @failures.count > 0 && @total_size > @count %>
|
74
|
+
<div class="col-sm-4">
|
75
|
+
<%= erb :_paging, :locals => { :url => "#{root_path}failures" } %>
|
76
|
+
</div>
|
77
|
+
<% end %>
|
78
|
+
|
73
79
|
<% else %>
|
74
80
|
<div class="alert alert-success"><%= t('NoFailedJobsFound') %></div>
|
75
81
|
<% end %>
|
82
|
+
<form action="<%= root_path %>failures/all/reset" method="post">
|
83
|
+
<%= csrf_tag if respond_to?(:csrf_tag) %>
|
84
|
+
<input class="btn btn-danger btn-xs pull-right" type="submit" name="reset" value="<%= t('Reset Counter') %>" data-confirm="<%= t('AreYouSure') %>" />
|
85
|
+
</form>
|
@@ -19,7 +19,7 @@ module Sidekiq
|
|
19
19
|
|
20
20
|
app.get "/failures" do
|
21
21
|
@count = (params[:count] || 25).to_i
|
22
|
-
(@current_page, @total_size, @failures) = page(LIST_KEY, params[:page], @count)
|
22
|
+
(@current_page, @total_size, @failures) = page(LIST_KEY, params[:page], @count, :reverse => true)
|
23
23
|
@failures = @failures.map {|msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
|
24
24
|
|
25
25
|
render(:erb, File.read(File.join(view_path, "failures.erb")))
|
@@ -78,6 +78,17 @@ module Sidekiq
|
|
78
78
|
FailureSet.new.retry_all_failures
|
79
79
|
redirect "#{root_path}failures"
|
80
80
|
end
|
81
|
+
|
82
|
+
app.get '/filter/failures' do
|
83
|
+
redirect "#{root_path}failures"
|
84
|
+
end
|
85
|
+
|
86
|
+
app.post '/filter/failures' do
|
87
|
+
@failures = Sidekiq::Failures::FailureSet.new.scan("*#{params[:substr]}*")
|
88
|
+
@current_page = 1
|
89
|
+
@count = @total_size = @failures.count
|
90
|
+
render(:erb, File.read(File.join(view_path, "failures.erb")))
|
91
|
+
end
|
81
92
|
end
|
82
93
|
end
|
83
94
|
end
|
data/sidekiq-failures.gemspec
CHANGED
@@ -7,6 +7,7 @@ Gem::Specification.new do |gem|
|
|
7
7
|
gem.description = %q{Keep track of Sidekiq failed jobs}
|
8
8
|
gem.summary = %q{Keeps track of Sidekiq failed jobs and adds a tab to the Web UI to let you browse them. Makes use of Sidekiq's custom tabs and middleware chain.}
|
9
9
|
gem.homepage = "https://github.com/mhfs/sidekiq-failures/"
|
10
|
+
gem.license = "MIT"
|
10
11
|
|
11
12
|
gem.files = `git ls-files`.split($\)
|
12
13
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -15,8 +16,16 @@ Gem::Specification.new do |gem|
|
|
15
16
|
gem.require_paths = ["lib"]
|
16
17
|
gem.version = Sidekiq::Failures::VERSION
|
17
18
|
|
18
|
-
gem.add_dependency "sidekiq", ">=
|
19
|
+
gem.add_dependency "sidekiq", ">= 4.0.0"
|
19
20
|
|
21
|
+
# Redis 4.X is incompatible with Ruby < 2.3, but the Ruby version constraint
|
22
|
+
# wasn't added until 4.1.2, meaning you can get an incompatible version of the
|
23
|
+
# redis gem when running Ruby 2.2 without this constraint.
|
24
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.3.0")
|
25
|
+
gem.add_dependency "redis", "< 4.0"
|
26
|
+
end
|
27
|
+
|
28
|
+
gem.add_development_dependency "minitest"
|
20
29
|
gem.add_development_dependency "rake"
|
21
30
|
gem.add_development_dependency "rack-test"
|
22
31
|
gem.add_development_dependency "sprockets"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
describe Failures do
|
5
|
+
describe '.retry_middleware_class' do
|
6
|
+
it 'returns based on Sidekiq::VERISON' do
|
7
|
+
case Sidekiq::VERSION[0]
|
8
|
+
when '5'
|
9
|
+
assert_equal Failures.retry_middleware_class, Sidekiq::JobRetry
|
10
|
+
when '4'
|
11
|
+
assert_equal Failures.retry_middleware_class, Sidekiq::Middleware::Server::RetryJobs
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/test/middleware_test.rb
CHANGED
@@ -4,9 +4,9 @@ module Sidekiq
|
|
4
4
|
module Failures
|
5
5
|
describe "Middleware" do
|
6
6
|
before do
|
7
|
-
Celluloid.boot
|
8
7
|
$invokes = 0
|
9
8
|
@boss = MiniTest::Mock.new
|
9
|
+
num_options_calls.times { @boss.expect(:options, {:queues => ['default'] }, []) }
|
10
10
|
@processor = ::Sidekiq::Processor.new(@boss)
|
11
11
|
Sidekiq.server_middleware {|chain| chain.add Sidekiq::Failures::Middleware }
|
12
12
|
Sidekiq.redis = REDIS
|
@@ -44,7 +44,7 @@ module Sidekiq
|
|
44
44
|
|
45
45
|
actor = MiniTest::Mock.new
|
46
46
|
actor.expect(:processor_done, nil, [@processor])
|
47
|
-
actor.expect(:real_thread, nil, [nil,
|
47
|
+
actor.expect(:real_thread, nil, [nil, nil])
|
48
48
|
2.times { @boss.expect(:async, actor, []) }
|
49
49
|
|
50
50
|
assert_raises TestException do
|
@@ -62,7 +62,7 @@ module Sidekiq
|
|
62
62
|
|
63
63
|
actor = MiniTest::Mock.new
|
64
64
|
actor.expect(:processor_done, nil, [@processor])
|
65
|
-
actor.expect(:real_thread, nil, [nil,
|
65
|
+
actor.expect(:real_thread, nil, [nil, nil])
|
66
66
|
2.times { @boss.expect(:async, actor, []) }
|
67
67
|
|
68
68
|
assert_raises TestException do
|
@@ -80,8 +80,7 @@ module Sidekiq
|
|
80
80
|
|
81
81
|
actor = MiniTest::Mock.new
|
82
82
|
actor.expect(:processor_done, nil, [@processor])
|
83
|
-
actor.expect(:real_thread, nil, [nil,
|
84
|
-
2.times { @boss.expect(:async, actor, []) }
|
83
|
+
actor.expect(:real_thread, nil, [nil, nil])
|
85
84
|
|
86
85
|
@processor.process(msg)
|
87
86
|
@boss.verify
|
@@ -97,7 +96,7 @@ module Sidekiq
|
|
97
96
|
|
98
97
|
actor = MiniTest::Mock.new
|
99
98
|
actor.expect(:processor_done, nil, [@processor])
|
100
|
-
actor.expect(:real_thread, nil, [nil,
|
99
|
+
actor.expect(:real_thread, nil, [nil, nil])
|
101
100
|
2.times { @boss.expect(:async, actor, []) }
|
102
101
|
|
103
102
|
assert_raises TestException do
|
@@ -117,7 +116,7 @@ module Sidekiq
|
|
117
116
|
|
118
117
|
actor = MiniTest::Mock.new
|
119
118
|
actor.expect(:processor_done, nil, [@processor])
|
120
|
-
actor.expect(:real_thread, nil, [nil,
|
119
|
+
actor.expect(:real_thread, nil, [nil, nil])
|
121
120
|
2.times { @boss.expect(:async, actor, []) }
|
122
121
|
|
123
122
|
assert_raises TestException do
|
@@ -136,7 +135,7 @@ module Sidekiq
|
|
136
135
|
|
137
136
|
actor = MiniTest::Mock.new
|
138
137
|
actor.expect(:processor_done, nil, [@processor])
|
139
|
-
actor.expect(:real_thread, nil, [nil,
|
138
|
+
actor.expect(:real_thread, nil, [nil, nil])
|
140
139
|
2.times { @boss.expect(:async, actor, []) }
|
141
140
|
|
142
141
|
assert_raises TestException do
|
@@ -154,7 +153,7 @@ module Sidekiq
|
|
154
153
|
|
155
154
|
actor = MiniTest::Mock.new
|
156
155
|
actor.expect(:processor_done, nil, [@processor])
|
157
|
-
actor.expect(:real_thread, nil, [nil,
|
156
|
+
actor.expect(:real_thread, nil, [nil, nil])
|
158
157
|
2.times { @boss.expect(:async, actor, []) }
|
159
158
|
|
160
159
|
assert_raises TestException do
|
@@ -172,7 +171,7 @@ module Sidekiq
|
|
172
171
|
|
173
172
|
actor = MiniTest::Mock.new
|
174
173
|
actor.expect(:processor_done, nil, [@processor])
|
175
|
-
actor.expect(:real_thread, nil, [nil,
|
174
|
+
actor.expect(:real_thread, nil, [nil, nil])
|
176
175
|
2.times { @boss.expect(:async, actor, []) }
|
177
176
|
|
178
177
|
assert_raises TestException do
|
@@ -192,7 +191,7 @@ module Sidekiq
|
|
192
191
|
|
193
192
|
actor = MiniTest::Mock.new
|
194
193
|
actor.expect(:processor_done, nil, [@processor])
|
195
|
-
actor.expect(:real_thread, nil, [nil,
|
194
|
+
actor.expect(:real_thread, nil, [nil, nil])
|
196
195
|
2.times { @boss.expect(:async, actor, []) }
|
197
196
|
|
198
197
|
assert_raises TestException do
|
@@ -212,7 +211,7 @@ module Sidekiq
|
|
212
211
|
|
213
212
|
actor = MiniTest::Mock.new
|
214
213
|
actor.expect(:processor_done, nil, [@processor])
|
215
|
-
actor.expect(:real_thread, nil, [nil,
|
214
|
+
actor.expect(:real_thread, nil, [nil, nil])
|
216
215
|
2.times { @boss.expect(:async, actor, []) }
|
217
216
|
|
218
217
|
assert_raises TestException do
|
@@ -233,11 +232,12 @@ module Sidekiq
|
|
233
232
|
|
234
233
|
3.times do
|
235
234
|
boss = MiniTest::Mock.new
|
235
|
+
num_options_calls.times { boss.expect(:options, {:queues => ['default'] }, []) }
|
236
236
|
processor = ::Sidekiq::Processor.new(boss)
|
237
237
|
|
238
238
|
actor = MiniTest::Mock.new
|
239
239
|
actor.expect(:processor_done, nil, [processor])
|
240
|
-
actor.expect(:real_thread, nil, [nil,
|
240
|
+
actor.expect(:real_thread, nil, [nil, nil])
|
241
241
|
2.times { boss.expect(:async, actor, []) }
|
242
242
|
|
243
243
|
assert_raises TestException do
|
@@ -261,7 +261,7 @@ module Sidekiq
|
|
261
261
|
|
262
262
|
actor = MiniTest::Mock.new
|
263
263
|
actor.expect(:processor_done, nil, [@processor])
|
264
|
-
actor.expect(:real_thread, nil, [nil,
|
264
|
+
actor.expect(:real_thread, nil, [nil, nil])
|
265
265
|
@boss.expect(:async, actor, [])
|
266
266
|
|
267
267
|
assert_raises TestException do
|
@@ -278,6 +278,14 @@ module Sidekiq
|
|
278
278
|
def create_work(msg)
|
279
279
|
Sidekiq::BasicFetch::UnitOfWork.new('default', Sidekiq.dump_json(msg))
|
280
280
|
end
|
281
|
+
|
282
|
+
def num_options_calls
|
283
|
+
if Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('5.0.3')
|
284
|
+
3
|
285
|
+
else
|
286
|
+
2
|
287
|
+
end
|
288
|
+
end
|
281
289
|
end
|
282
290
|
end
|
283
291
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
Encoding.default_internal = Encoding::UTF_8
|
1
|
+
$TESTING = true
|
3
2
|
|
4
3
|
require "minitest/autorun"
|
5
4
|
require "minitest/spec"
|
@@ -7,14 +6,13 @@ require "minitest/mock"
|
|
7
6
|
|
8
7
|
require "rack/test"
|
9
8
|
|
10
|
-
require "celluloid"
|
11
9
|
require "sidekiq"
|
10
|
+
require "sidekiq-pro" if ENV['SIDEKIQ_PRO_VERSION']
|
12
11
|
require "sidekiq-failures"
|
13
12
|
require "sidekiq/processor"
|
14
13
|
require "sidekiq/fetch"
|
15
14
|
require "sidekiq/cli"
|
16
15
|
|
17
|
-
Celluloid.logger = nil
|
18
16
|
Sidekiq.logger.level = Logger::ERROR
|
19
17
|
|
20
|
-
REDIS = Sidekiq::RedisConnection.create(:
|
18
|
+
REDIS = Sidekiq::RedisConnection.create(url: "redis://localhost/15")
|
data/test/web_extension_test.rb
CHANGED
@@ -5,11 +5,15 @@ module Sidekiq
|
|
5
5
|
describe "WebExtension" do
|
6
6
|
include Rack::Test::Methods
|
7
7
|
|
8
|
+
TOKEN = SecureRandom.base64(32).freeze
|
9
|
+
|
8
10
|
def app
|
9
11
|
Sidekiq::Web
|
10
12
|
end
|
11
13
|
|
12
14
|
before do
|
15
|
+
env 'rack.session', { csrf: TOKEN }
|
16
|
+
env 'HTTP_X_CSRF_TOKEN', TOKEN
|
13
17
|
Sidekiq.redis = REDIS
|
14
18
|
Sidekiq.redis {|c| c.flushdb }
|
15
19
|
end
|
@@ -18,15 +22,21 @@ module Sidekiq
|
|
18
22
|
get '/'
|
19
23
|
|
20
24
|
last_response.status.must_equal 200
|
21
|
-
last_response.body.must_match
|
22
|
-
last_response.body.must_match
|
25
|
+
last_response.body.must_match(/Sidekiq/)
|
26
|
+
last_response.body.must_match(/Failures/)
|
23
27
|
end
|
24
28
|
|
25
29
|
it 'can display failures page without any failures' do
|
26
30
|
get '/failures'
|
27
31
|
last_response.status.must_equal 200
|
28
|
-
last_response.body.must_match
|
29
|
-
last_response.body.must_match
|
32
|
+
last_response.body.must_match(/Failed Jobs/)
|
33
|
+
last_response.body.must_match(/No failed jobs found/)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'has the reset counter form and action' do
|
37
|
+
get '/failures'
|
38
|
+
last_response.body.must_match(/failures\/all\/reset/)
|
39
|
+
last_response.body.must_match(/Reset Counter/)
|
30
40
|
end
|
31
41
|
|
32
42
|
describe 'when there are failures' do
|
@@ -40,66 +50,61 @@ module Sidekiq
|
|
40
50
|
end
|
41
51
|
|
42
52
|
it 'can display failures page with failures listed' do
|
43
|
-
last_response.body.must_match
|
44
|
-
last_response.body.must_match
|
45
|
-
last_response.body.must_match
|
46
|
-
last_response.body.wont_match
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'has the reset counter form and action' do
|
50
|
-
last_response.body.must_match /failures\/all\/reset/
|
51
|
-
last_response.body.must_match /Reset Counter/
|
53
|
+
last_response.body.must_match(/Failed Jobs/)
|
54
|
+
last_response.body.must_match(/HardWorker/)
|
55
|
+
last_response.body.must_match(/ArgumentError/)
|
56
|
+
last_response.body.wont_match(/No failed jobs found/)
|
52
57
|
end
|
53
58
|
|
54
59
|
it 'can reset counter' do
|
55
60
|
assert_equal failed_count, "1"
|
56
61
|
|
57
|
-
last_response.body.must_match
|
62
|
+
last_response.body.must_match(/HardWorker/)
|
58
63
|
|
59
64
|
post '/failures/all/reset'
|
60
65
|
last_response.status.must_equal 302
|
61
|
-
last_response.location.must_match
|
66
|
+
last_response.location.must_match(/failures$/)
|
62
67
|
|
63
68
|
get '/failures'
|
64
69
|
last_response.status.must_equal 200
|
65
|
-
last_response.body.must_match
|
70
|
+
last_response.body.must_match(/HardWorker/)
|
66
71
|
|
67
72
|
assert_equal failed_count, "0"
|
68
73
|
end
|
69
74
|
|
70
75
|
it 'has the delete all form and action' do
|
71
|
-
last_response.body.must_match
|
72
|
-
last_response.body.must_match
|
76
|
+
last_response.body.must_match(/failures\/all\/delete/)
|
77
|
+
last_response.body.must_match(/Delete All/)
|
73
78
|
end
|
74
79
|
|
75
80
|
it 'can delete all failures' do
|
76
81
|
assert_equal failed_count, "1"
|
77
82
|
|
78
|
-
last_response.body.must_match
|
83
|
+
last_response.body.must_match(/HardWorker/)
|
79
84
|
|
80
85
|
post '/failures/all/delete'
|
81
86
|
last_response.status.must_equal 302
|
82
|
-
last_response.location.must_match
|
87
|
+
last_response.location.must_match(/failures$/)
|
83
88
|
|
84
89
|
get '/failures'
|
85
90
|
last_response.status.must_equal 200
|
86
|
-
last_response.body.must_match
|
91
|
+
last_response.body.must_match(/No failed jobs found/)
|
87
92
|
|
88
93
|
assert_equal failed_count, "1"
|
89
94
|
end
|
90
95
|
|
91
96
|
it 'has the retry all form and action' do
|
92
|
-
last_response.body.must_match
|
93
|
-
last_response.body.must_match
|
97
|
+
last_response.body.must_match(/failures\/all\/retry/)
|
98
|
+
last_response.body.must_match(/Retry All/)
|
94
99
|
end
|
95
100
|
|
96
101
|
it 'can retry all failures' do
|
97
102
|
assert_equal failed_count, "1"
|
98
103
|
|
99
|
-
last_response.body.must_match
|
104
|
+
last_response.body.must_match(/HardWorker/)
|
100
105
|
post '/failures/all/retry'
|
101
106
|
last_response.status.must_equal 302
|
102
|
-
last_response.location.must_match
|
107
|
+
last_response.location.must_match(/failures/)
|
103
108
|
|
104
109
|
get '/failures'
|
105
110
|
last_response.status.must_equal 200
|
@@ -109,29 +114,37 @@ module Sidekiq
|
|
109
114
|
it 'can delete failure from the list' do
|
110
115
|
assert_equal failed_count, "1"
|
111
116
|
|
112
|
-
last_response.body.must_match
|
117
|
+
last_response.body.must_match(/HardWorker/)
|
113
118
|
|
114
119
|
post '/failures', { :key => [failure_score], :delete => 'Delete' }
|
115
120
|
last_response.status.must_equal 302
|
116
|
-
last_response.location.must_match
|
121
|
+
last_response.location.must_match(/failures/)
|
117
122
|
|
118
123
|
get '/failures'
|
119
124
|
last_response.status.must_equal 200
|
120
|
-
last_response.body.must_match
|
125
|
+
last_response.body.must_match(/No failed jobs found/)
|
121
126
|
end
|
122
127
|
|
123
128
|
it 'can retry failure from the list' do
|
124
129
|
assert_equal failed_count, "1"
|
125
130
|
|
126
|
-
last_response.body.must_match
|
131
|
+
last_response.body.must_match(/HardWorker/)
|
127
132
|
|
128
133
|
post '/failures', { :key => [failure_score], :retry => 'Retry Now' }
|
129
134
|
last_response.status.must_equal 302
|
130
|
-
last_response.location.must_match
|
135
|
+
last_response.location.must_match(/failures/)
|
136
|
+
|
137
|
+
get '/failures'
|
138
|
+
last_response.status.must_equal 200
|
139
|
+
last_response.body.must_match(/No failed jobs found/)
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'can handle failures with nil error_message' do
|
143
|
+
create_sample_failure(error_message: nil)
|
131
144
|
|
132
145
|
get '/failures'
|
146
|
+
|
133
147
|
last_response.status.must_equal 200
|
134
|
-
last_response.body.must_match /No failed jobs found/
|
135
148
|
end
|
136
149
|
end
|
137
150
|
|
@@ -146,34 +159,43 @@ module Sidekiq
|
|
146
159
|
end
|
147
160
|
|
148
161
|
it 'can display failure page' do
|
149
|
-
last_response.body.must_match
|
150
|
-
last_response.body.must_match
|
151
|
-
last_response.body.must_match
|
152
|
-
last_response.body.must_match
|
162
|
+
last_response.body.must_match(/Job/)
|
163
|
+
last_response.body.must_match(/HardWorker/)
|
164
|
+
last_response.body.must_match(/ArgumentError/)
|
165
|
+
last_response.body.must_match(/file1/)
|
153
166
|
end
|
154
167
|
|
155
168
|
it 'can delete failure' do
|
156
|
-
last_response.body.must_match
|
169
|
+
last_response.body.must_match(/HardWorker/)
|
157
170
|
|
158
171
|
post "/failures/#{failure_score}", :delete => 'Delete'
|
159
172
|
last_response.status.must_equal 302
|
160
|
-
last_response.location.must_match
|
173
|
+
last_response.location.must_match(/failures/)
|
161
174
|
|
162
175
|
get "/failures/#{failure_score}"
|
163
176
|
last_response.status.must_equal 302
|
164
|
-
last_response.location.must_match
|
177
|
+
last_response.location.must_match(/failures/)
|
165
178
|
end
|
166
179
|
|
167
180
|
it 'can retry failure' do
|
168
|
-
last_response.body.must_match
|
181
|
+
last_response.body.must_match(/HardWorker/)
|
169
182
|
|
170
183
|
post "/failures/#{failure_score}", :retry => 'Retry Now'
|
171
184
|
last_response.status.must_equal 302
|
172
|
-
last_response.location.must_match
|
185
|
+
last_response.location.must_match(/failures/)
|
173
186
|
|
174
187
|
get "/failures/#{failure_score}"
|
175
188
|
last_response.status.must_equal 302
|
176
|
-
last_response.location.must_match
|
189
|
+
last_response.location.must_match(/failures/)
|
190
|
+
end
|
191
|
+
|
192
|
+
if defined? Sidekiq::Pro
|
193
|
+
it 'can filter failure' do
|
194
|
+
create_sample_failure
|
195
|
+
post '/filter/failures', substr: 'new'
|
196
|
+
|
197
|
+
last_response.status.must_equal 200
|
198
|
+
end
|
177
199
|
end
|
178
200
|
end
|
179
201
|
|
@@ -185,11 +207,11 @@ module Sidekiq
|
|
185
207
|
end
|
186
208
|
|
187
209
|
it 'can escape arguments' do
|
188
|
-
last_response.body.must_match
|
210
|
+
last_response.body.must_match(/"<h1>omg</h1>"/)
|
189
211
|
end
|
190
212
|
|
191
213
|
it 'can escape error message' do
|
192
|
-
last_response.body.must_match
|
214
|
+
last_response.body.must_match(/ArgumentError: <p>wow</p>/)
|
193
215
|
end
|
194
216
|
end
|
195
217
|
|
@@ -201,7 +223,7 @@ module Sidekiq
|
|
201
223
|
|
202
224
|
it 'should be successful' do
|
203
225
|
last_response.status.must_equal 200
|
204
|
-
last_response.body.wont_match
|
226
|
+
last_response.body.wont_match(/No failed jobs found/)
|
205
227
|
end
|
206
228
|
end
|
207
229
|
|
@@ -213,7 +235,7 @@ module Sidekiq
|
|
213
235
|
|
214
236
|
it 'should be successful' do
|
215
237
|
last_response.status.must_equal 200
|
216
|
-
last_response.body.wont_match
|
238
|
+
last_response.body.wont_match(/No failed jobs found/)
|
217
239
|
end
|
218
240
|
end
|
219
241
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-failures
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcelo Silveira
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-08-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sidekiq
|
@@ -16,14 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 4.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 4.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,6 +112,8 @@ files:
|
|
98
112
|
- lib/sidekiq/failures.rb
|
99
113
|
- lib/sidekiq/failures/failure_set.rb
|
100
114
|
- lib/sidekiq/failures/locales/en.yml
|
115
|
+
- lib/sidekiq/failures/locales/ja.yml
|
116
|
+
- lib/sidekiq/failures/locales/pt-BR.yml
|
101
117
|
- lib/sidekiq/failures/middleware.rb
|
102
118
|
- lib/sidekiq/failures/sorted_entry.rb
|
103
119
|
- lib/sidekiq/failures/version.rb
|
@@ -105,13 +121,15 @@ files:
|
|
105
121
|
- lib/sidekiq/failures/views/failures.erb
|
106
122
|
- lib/sidekiq/failures/web_extension.rb
|
107
123
|
- sidekiq-failures.gemspec
|
124
|
+
- test/failures_test.rb
|
108
125
|
- test/middleware_test.rb
|
109
126
|
- test/test_helper.rb
|
110
127
|
- test/web_extension_test.rb
|
111
128
|
homepage: https://github.com/mhfs/sidekiq-failures/
|
112
|
-
licenses:
|
129
|
+
licenses:
|
130
|
+
- MIT
|
113
131
|
metadata: {}
|
114
|
-
post_install_message:
|
132
|
+
post_install_message:
|
115
133
|
rdoc_options: []
|
116
134
|
require_paths:
|
117
135
|
- lib
|
@@ -126,13 +144,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
144
|
- !ruby/object:Gem::Version
|
127
145
|
version: '0'
|
128
146
|
requirements: []
|
129
|
-
|
130
|
-
|
131
|
-
signing_key:
|
147
|
+
rubygems_version: 3.2.3
|
148
|
+
signing_key:
|
132
149
|
specification_version: 4
|
133
150
|
summary: Keeps track of Sidekiq failed jobs and adds a tab to the Web UI to let you
|
134
151
|
browse them. Makes use of Sidekiq's custom tabs and middleware chain.
|
135
152
|
test_files:
|
153
|
+
- test/failures_test.rb
|
136
154
|
- test/middleware_test.rb
|
137
155
|
- test/test_helper.rb
|
138
156
|
- test/web_extension_test.rb
|