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 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