sidekiq-failures 0.4.3 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: dbf773e3881e5c3f66679dc77ce221997c58442d
4
- data.tar.gz: 8fde6abd64a06cd529e7bf523a8f018c68cd9900
2
+ SHA256:
3
+ metadata.gz: 411bc0eb000e29f27b3d5afd27e39719c693df17ce7b08baace66e42f4b8c402
4
+ data.tar.gz: 88174d41395b3953bf089590775e8e34725c4f47109a379727df08c4331ad8d8
5
5
  SHA512:
6
- metadata.gz: 61dc54a740b82bd9317bec3240468dcd9fdb30663cc2eea05c2368fb117c307e5eeb2979388309177fd7c5a1bec692997e041675d6bba5d11265e95d8492a069
7
- data.tar.gz: 58fca490bba04d832220c1ee1689cb19adfb6a0b457d76fbd79f82b1171ace187990cd47147f3ac8c081bcf36453bb1aa0d858b923bdb2f91058048b27984050
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.9.3
6
- - jruby-19mode
7
- - 2.0.0
8
- - 2.1
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="~> 2.16"
12
- - SIDEKIQ_VERSION="~> 2.17"
13
- - SIDEKIQ_VERSION="~> 3.0"
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.9.3
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
@@ -136,7 +136,7 @@ Sidekiq::Failures.reset_failures
136
136
 
137
137
  ## Dependencies
138
138
 
139
- Depends on Sidekiq >= 2.16.0
139
+ Depends on Sidekiq >= 4.0.0
140
140
 
141
141
  ## Contributing
142
142
 
@@ -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
- return 1000 if @failures_max_count.nil?
51
-
52
- @failures_max_count
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::Middleware::Server::RetryJobs,
84
+ chain.insert_before Sidekiq::Failures.retry_middleware_class,
71
85
  Sidekiq::Failures::Middleware
72
86
  end
73
87
  end
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+ ja:
3
+ FailedJobs: 失敗したジョブ
4
+ FailedAt: 失敗した日時
5
+ ResetCounter: カウンターをリセット
6
+ NoFailedJobsFound: 失敗したジョブはありません
@@ -0,0 +1,5 @@
1
+ pt-BR:
2
+ FailedJobs: Processos Falhos
3
+ FailedAt: Falhou em
4
+ ResetCounter: Resetar contador
5
+ NoFailedJobsFound: Nenhum Processo falho encontrado
@@ -80,11 +80,12 @@ module Sidekiq
80
80
  end
81
81
 
82
82
  def retry_middleware
83
- @retry_middleware ||= Sidekiq::Middleware::Server::RetryJobs.new
83
+ @retry_middleware ||=
84
+ Sidekiq::Failures.retry_middleware_class.new
84
85
  end
85
86
 
86
87
  def default_max_retries
87
- Sidekiq::Middleware::Server::RetryJobs::DEFAULT_MAX_RETRY_ATTEMPTS
88
+ Sidekiq::Failures.retry_middleware_class::DEFAULT_MAX_RETRY_ATTEMPTS
88
89
  end
89
90
 
90
91
  def hostname
@@ -1,5 +1,5 @@
1
1
  module Sidekiq
2
2
  module Failures
3
- VERSION = "0.4.3"
3
+ VERSION = "1.0.1"
4
4
  end
5
5
  end
@@ -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.size > 0 && @total_size > @count %>
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.size > 0 %>
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 style="width: 20%"><%= t('Worker') %></th>
24
- <th style="width: 10%"><%= t('Arguments') %></th>
25
- <th style="width: 10%"><%= t('Queue') %></th>
26
- <th style="width: 10%"><%= t('FailedAt') %></th>
27
- <th style="width: 50%"><%= t('Error') %></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.klass %></a></td>
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
- <div class="args"><%= display_args(entry.args) %></div>
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
- <a href="<%= root_path %>queues/<%= entry.queue %>"><%= entry.queue %></a>
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
@@ -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", ">= 2.16.0"
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
@@ -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, Celluloid::Thread])
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, Celluloid::Thread])
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, Celluloid::Thread])
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, Celluloid::Thread])
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, Celluloid::Thread])
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, Celluloid::Thread])
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, Celluloid::Thread])
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, Celluloid::Thread])
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, Celluloid::Thread])
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, Celluloid::Thread])
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, Celluloid::Thread])
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, Celluloid::Thread])
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
- Encoding.default_external = Encoding::UTF_8
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(:url => "redis://localhost/15", :namespace => 'sidekiq_failures_test')
18
+ REDIS = Sidekiq::RedisConnection.create(url: "redis://localhost/15")
@@ -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 /Sidekiq/
22
- last_response.body.must_match /Failures/
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 /Failed Jobs/
29
- last_response.body.must_match /No failed jobs found/
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 /Failed Jobs/
44
- last_response.body.must_match /HardWorker/
45
- last_response.body.must_match /ArgumentError/
46
- last_response.body.wont_match /No failed jobs found/
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 /HardWorker/
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 /failures$/
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 /HardWorker/
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 /failures\/all\/delete/
72
- last_response.body.must_match /Delete All/
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 /HardWorker/
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 /failures$/
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 /No failed jobs found/
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 /failures\/all\/retry/
93
- last_response.body.must_match /Retry All/
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 /HardWorker/
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 /failures/
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 /HardWorker/
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 /failures/
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 /No failed jobs found/
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 /HardWorker/
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 /failures/
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 /Job/
150
- last_response.body.must_match /HardWorker/
151
- last_response.body.must_match /ArgumentError/
152
- last_response.body.must_match /file1/
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 /HardWorker/
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 /failures/
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 /failures/
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 /HardWorker/
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 /failures/
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 /failures/
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 /&quot;&lt;h1&gt;omg&lt;&#x2F;h1&gt;&quot;/
210
+ last_response.body.must_match(/&quot;&lt;h1&gt;omg&lt;&#x2F;h1&gt;&quot;/)
189
211
  end
190
212
 
191
213
  it 'can escape error message' do
192
- last_response.body.must_match /ArgumentError: &lt;p&gt;wow&lt;&#x2F;p&gt;/
214
+ last_response.body.must_match(/ArgumentError: &lt;p&gt;wow&lt;&#x2F;p&gt;/)
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 /No failed jobs found/
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 /No failed jobs found/
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.3
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: 2014-06-30 00:00:00.000000000 Z
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: 2.16.0
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: 2.16.0
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
- rubyforge_project:
130
- rubygems_version: 2.2.2
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