sidekiq-failures 0.4.5 → 1.0.2

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: 3cf2e8b86ea584dc2d01d303a8b810a3527da318
4
- data.tar.gz: ea8731360ed096a6f6b885cb3f078a80bb96747e
2
+ SHA256:
3
+ metadata.gz: 19188851daa2c09c4d9fd539cdc5ebf1dba9ef99d8c9ed0e2c9ef3840ed0141e
4
+ data.tar.gz: 16b650f8e29fce5be5b384133914c10bbe95181c963a55cfb0f75f8ddb177091
5
5
  SHA512:
6
- metadata.gz: dd021e8afcbd6a59c8d725d2954f7d45cbb50475b3c342b8e5d00533dd3c72594548d4fdb197e3d5a3cd51d158f000c050da57d353ef294c67bfe7880243dad8
7
- data.tar.gz: 422b175ead022b822ae08838a03365f22e6e4a0a2213ff8f9c2756ed3f41b14c58e9e7f950f32adce8d8f25e440c3a5a8b78753798a4162ddf8626cd9bb2c977
6
+ metadata.gz: 3ed7905bc899029c186d54ea9161b167d6e2477ba4c17da2b19b8f243903f5ae4c1ee2004f17d63b0c57adee458c963c33408724753e37d1442f191b84fe0b3a
7
+ data.tar.gz: 85b87d7dfc6f41e4d4cb1f3b3c0cfcc1f02ed97358c7b0479facc625003ef401bf20669868914715185e242c3bbded6c0262d125e1915ca723304c1629e4adba
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
@@ -0,0 +1,37 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ ruby: [2.6, 2.7, '3.0', 3.1]
16
+ sidekiq: [4.2, 5.2, 6.2]
17
+ services:
18
+ redis:
19
+ image: redis
20
+ options: >-
21
+ --health-cmd "redis-cli ping"
22
+ --health-interval 10s
23
+ --health-timeout 5s
24
+ --health-retries 5
25
+ ports:
26
+ - 6379:6379
27
+ env:
28
+ SIDEKIQ_VERSION: ~> ${{ matrix.sidekiq }}
29
+ steps:
30
+ - uses: actions/checkout@v3
31
+ - name: Set up Ruby
32
+ uses: ruby/setup-ruby@v1
33
+ with:
34
+ bundler-cache: true # 'bundle install' and cache gems
35
+ ruby-version: ${{ matrix.ruby }}
36
+ - name: Run tests
37
+ run: bundle exec rake
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  ## Unreleased
2
2
 
3
+ ## 1.0.2
4
+
5
+ * Pass now required argument to Sidekiq's JobRetry.new (#140 @mcasper)
6
+
7
+ ## 1.0.1
8
+
9
+ * Add license config to the gemspec (#115 @reiz)
10
+ * Guard against failure error_message being `nil` (#122 @mcasper)
11
+ * Fix filtering failures with 0 results on Sidekiq Pro (#125 @substars)
12
+
13
+ ## 1.0.0
14
+
15
+ * WebUI improvements (@bbtfr)
16
+ * Use ActiveJob to display info when available (@dreyks)
17
+ * New locales (@ryohashimoto @gurgelrenan)
18
+ * Sidekiq 4 and higher compatibility (@davekrupinski )
19
+ * Sidekiq 5 fixes (@fidelisrafael)
20
+
3
21
  ## 0.4.5
4
22
 
5
23
  * Limit error message to 500 symbols (@antonzaytsev)
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
@@ -1,4 +1,4 @@
1
- # Sidekiq::Failures [![Build Status](https://secure.travis-ci.org/mhfs/sidekiq-failures.png)](http://travis-ci.org/mhfs/sidekiq-failures)
1
+ # Sidekiq::Failures ![Build Status](https://github.com/mhfs/sidekiq-failures/workflows/CI/badge.svg)
2
2
 
3
3
  Keeps track of Sidekiq failed jobs and adds a tab to the Web UI to let you browse
4
4
  them. Makes use of Sidekiq's custom tabs and middleware chain.
@@ -20,6 +20,8 @@ gem 'sidekiq-failures'
20
20
  Simply having the gem in your Gemfile is enough to get you started. Your failed
21
21
  jobs will be visible via a Failures tab in the Web UI.
22
22
 
23
+ If you have not previously used the Web UI, it is a part of the Sidekiq gem. [See Sidekiq's docs about Web UI here.](https://github.com/mperham/sidekiq/wiki/Monitoring#web-ui)
24
+
23
25
  ## Configuring
24
26
 
25
27
  ### Maximum Tracked Failures
@@ -136,7 +138,7 @@ Sidekiq::Failures.reset_failures
136
138
 
137
139
  ## Dependencies
138
140
 
139
- Depends on Sidekiq >= 2.16.0
141
+ Depends on Sidekiq >= 4.0.0
140
142
 
141
143
  ## Contributing
142
144
 
@@ -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
@@ -0,0 +1,5 @@
1
+ zh-cn:
2
+ FailedJobs: 失败的任务
3
+ FailedAt: 失败时间
4
+ ResetCounter: 重置计数器
5
+ NoFailedJobsFound: 没有发现失败的任务
@@ -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(@config || {})
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.5"
3
+ VERSION = "1.0.2"
4
4
  end
5
5
  end
@@ -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,7 +10,7 @@
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
15
  <%= csrf_tag if respond_to?(:csrf_tag) %>
16
16
  <table class="table table-striped table-bordered table-white">
@@ -21,11 +21,11 @@
21
21
  <input type="checkbox" class="check_all" />
22
22
  </label>
23
23
  </th>
24
- <th style="width: 20%"><%= t('Worker') %></th>
25
- <th style="width: 10%"><%= t('Arguments') %></th>
26
- <th style="width: 10%"><%= t('Queue') %></th>
27
- <th style="width: 10%"><%= t('FailedAt') %></th>
28
- <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>
29
29
  </tr>
30
30
  </thead>
31
31
  <% @failures.each do |entry| %>
@@ -35,17 +35,17 @@
35
35
  <input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' />
36
36
  </label>
37
37
  </td>
38
- <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>
39
39
  <td>
40
- <div class="args"><%= display_args(entry.args) %></div>
40
+ <a href="<%= root_path %>queues/<%= entry.queue %>"><%= entry.queue %></a>
41
41
  </td>
42
+ <td><%= entry.respond_to?(:display_class) ? entry.display_class : entry.klass %></td>
42
43
  <td>
43
- <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>
44
45
  </td>
45
- <td><%= safe_relative_time(entry['failed_at']) %></td>
46
46
  <td style="overflow: auto; padding: 10px;">
47
47
  <a class="backtrace" href="#" onclick="$(this).next().toggle(); return false">
48
- <%= h entry['error_class'] %>: <%= h entry['error_message'].size > 500 ? entry['error_message'][0..500] + '...' : entry['error_message'] %>
48
+ <%= h entry['error_class'] %>: <%= h entry['error_message'].to_s.size > 500 ? entry['error_message'][0..500] + '...' : entry['error_message'] %>
49
49
  </a>
50
50
  <pre style="display: none; background: none; border: 0; width: 100%; max-height: 30em; font-size: 0.8em; white-space: nowrap; overflow: auto;">
51
51
  <%= entry['error_backtrace'].join("<br />") if entry['error_backtrace'] %>
@@ -70,7 +70,7 @@
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.size > 0 && @total_size > @count %>
73
+ <% if @failures.count > 0 && @total_size > @count %>
74
74
  <div class="col-sm-4">
75
75
  <%= erb :_paging, :locals => { :url => "#{root_path}failures" } %>
76
76
  </div>
@@ -81,5 +81,5 @@
81
81
  <% end %>
82
82
  <form action="<%= root_path %>failures/all/reset" method="post">
83
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') %>" />
84
+ <input class="btn btn-danger btn-xs pull-right" type="submit" name="reset" value="<%= t('ResetCounter') %>" data-confirm="<%= t('AreYouSure') %>" />
85
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
@@ -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
@@ -7,16 +7,23 @@ 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
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
13
  gem.name = "sidekiq-failures"
15
14
  gem.require_paths = ["lib"]
16
15
  gem.version = Sidekiq::Failures::VERSION
17
16
 
18
- gem.add_dependency "sidekiq", ">= 2.16.0"
17
+ gem.add_dependency "sidekiq", ">= 4.0.0"
19
18
 
19
+ # Redis 4.X is incompatible with Ruby < 2.3, but the Ruby version constraint
20
+ # wasn't added until 4.1.2, meaning you can get an incompatible version of the
21
+ # redis gem when running Ruby 2.2 without this constraint.
22
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.3.0")
23
+ gem.add_dependency "redis", "< 4.0"
24
+ end
25
+
26
+ gem.add_development_dependency "minitest"
20
27
  gem.add_development_dependency "rake"
21
28
  gem.add_development_dependency "rack-test"
22
29
  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
@@ -1,19 +1,72 @@
1
1
  require "test_helper"
2
2
 
3
+ class SidekiqPre6
4
+ def new_processor(boss)
5
+ num_options_calls.times { boss.expect(:options, {:queues => ['default'] }, []) }
6
+ ::Sidekiq::Processor.new(boss)
7
+ end
8
+
9
+ private
10
+
11
+ def num_options_calls
12
+ if Gem::Version.new(Sidekiq::VERSION) >= Gem::Version.new('5.0.3')
13
+ 3
14
+ else
15
+ 2
16
+ end
17
+ end
18
+ end
19
+
20
+ class SidekiqPre63
21
+ def new_processor(boss)
22
+ opts = {
23
+ queues: ['default'],
24
+ }
25
+ opts[:fetch] = Sidekiq::BasicFetch.new(opts)
26
+ ::Sidekiq::Processor.new(boss, opts)
27
+ end
28
+ end
29
+
30
+ class SidekiqPost63
31
+ def new_processor(boss)
32
+ config = Sidekiq
33
+ config[:queues] = ['default']
34
+ config[:fetch] = Sidekiq::BasicFetch.new(config)
35
+ config[:error_handlers] << Sidekiq.method(:default_error_handler)
36
+ ::Sidekiq::Processor.new(config) { |processor, reason = nil| }
37
+ end
38
+ end
39
+
3
40
  module Sidekiq
4
41
  module Failures
5
42
  describe "Middleware" do
43
+ def new_provider
44
+ version = Gem::Version.new(Sidekiq::VERSION)
45
+ if version >= Gem::Version.new('6.4.0')
46
+ SidekiqPost63
47
+ elsif version >= Gem::Version.new('6.0')
48
+ SidekiqPre63
49
+ else
50
+ SidekiqPre6
51
+ end.new
52
+ end
53
+
6
54
  before do
7
- Celluloid.boot
8
55
  $invokes = 0
9
56
  @boss = MiniTest::Mock.new
10
- @processor = ::Sidekiq::Processor.new(@boss)
57
+ @provider = new_provider
58
+ @processor = @provider.new_processor(@boss)
59
+
11
60
  Sidekiq.server_middleware {|chain| chain.add Sidekiq::Failures::Middleware }
12
61
  Sidekiq.redis = REDIS
13
62
  Sidekiq.redis { |c| c.flushdb }
14
63
  Sidekiq.instance_eval { @failures_default_mode = nil }
15
64
  end
16
65
 
66
+ after do
67
+ @boss.verify
68
+ end
69
+
17
70
  TestException = Class.new(Exception)
18
71
  ShutdownException = Class.new(Sidekiq::Shutdown)
19
72
 
@@ -42,11 +95,6 @@ module Sidekiq
42
95
 
43
96
  assert_equal 0, failures_count
44
97
 
45
- actor = MiniTest::Mock.new
46
- actor.expect(:processor_done, nil, [@processor])
47
- actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
48
- 2.times { @boss.expect(:async, actor, []) }
49
-
50
98
  assert_raises TestException do
51
99
  @processor.process(msg)
52
100
  end
@@ -60,11 +108,6 @@ module Sidekiq
60
108
 
61
109
  assert_equal 0, failures_count
62
110
 
63
- actor = MiniTest::Mock.new
64
- actor.expect(:processor_done, nil, [@processor])
65
- actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
66
- 2.times { @boss.expect(:async, actor, []) }
67
-
68
111
  assert_raises TestException do
69
112
  @processor.process(msg)
70
113
  end
@@ -78,13 +121,7 @@ module Sidekiq
78
121
 
79
122
  assert_equal 0, failures_count
80
123
 
81
- actor = MiniTest::Mock.new
82
- actor.expect(:processor_done, nil, [@processor])
83
- actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
84
- 2.times { @boss.expect(:async, actor, []) }
85
-
86
124
  @processor.process(msg)
87
- @boss.verify
88
125
 
89
126
  assert_equal 0, failures_count
90
127
  assert_equal 1, $invokes
@@ -95,11 +132,6 @@ module Sidekiq
95
132
 
96
133
  assert_equal 0, failures_count
97
134
 
98
- actor = MiniTest::Mock.new
99
- actor.expect(:processor_done, nil, [@processor])
100
- actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
101
- 2.times { @boss.expect(:async, actor, []) }
102
-
103
135
  assert_raises TestException do
104
136
  @processor.process(msg)
105
137
  end
@@ -115,11 +147,6 @@ module Sidekiq
115
147
 
116
148
  assert_equal 0, failures_count
117
149
 
118
- actor = MiniTest::Mock.new
119
- actor.expect(:processor_done, nil, [@processor])
120
- actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
121
- 2.times { @boss.expect(:async, actor, []) }
122
-
123
150
  assert_raises TestException do
124
151
  @processor.process(msg)
125
152
  end
@@ -134,11 +161,6 @@ module Sidekiq
134
161
 
135
162
  assert_equal 0, failures_count
136
163
 
137
- actor = MiniTest::Mock.new
138
- actor.expect(:processor_done, nil, [@processor])
139
- actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
140
- 2.times { @boss.expect(:async, actor, []) }
141
-
142
164
  assert_raises TestException do
143
165
  @processor.process(msg)
144
166
  end
@@ -152,11 +174,6 @@ module Sidekiq
152
174
 
153
175
  assert_equal 0, failures_count
154
176
 
155
- actor = MiniTest::Mock.new
156
- actor.expect(:processor_done, nil, [@processor])
157
- actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
158
- 2.times { @boss.expect(:async, actor, []) }
159
-
160
177
  assert_raises TestException do
161
178
  @processor.process(msg)
162
179
  end
@@ -170,11 +187,6 @@ module Sidekiq
170
187
 
171
188
  assert_equal 0, failures_count
172
189
 
173
- actor = MiniTest::Mock.new
174
- actor.expect(:processor_done, nil, [@processor])
175
- actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
176
- 2.times { @boss.expect(:async, actor, []) }
177
-
178
190
  assert_raises TestException do
179
191
  @processor.process(msg)
180
192
  end
@@ -190,11 +202,6 @@ module Sidekiq
190
202
 
191
203
  assert_equal 0, failures_count
192
204
 
193
- actor = MiniTest::Mock.new
194
- actor.expect(:processor_done, nil, [@processor])
195
- actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
196
- 2.times { @boss.expect(:async, actor, []) }
197
-
198
205
  assert_raises TestException do
199
206
  @processor.process(msg)
200
207
  end
@@ -210,11 +217,6 @@ module Sidekiq
210
217
 
211
218
  assert_equal 0, failures_count
212
219
 
213
- actor = MiniTest::Mock.new
214
- actor.expect(:processor_done, nil, [@processor])
215
- actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
216
- 2.times { @boss.expect(:async, actor, []) }
217
-
218
220
  assert_raises TestException do
219
221
  @processor.process(msg)
220
222
  end
@@ -233,16 +235,13 @@ module Sidekiq
233
235
 
234
236
  3.times do
235
237
  boss = MiniTest::Mock.new
236
- processor = ::Sidekiq::Processor.new(boss)
237
-
238
- actor = MiniTest::Mock.new
239
- actor.expect(:processor_done, nil, [processor])
240
- actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
241
- 2.times { boss.expect(:async, actor, []) }
238
+ processor = @provider.new_processor(boss)
242
239
 
243
240
  assert_raises TestException do
244
241
  processor.process(msg)
245
242
  end
243
+
244
+ boss.verify
246
245
  end
247
246
 
248
247
  assert_equal 2, failures_count
@@ -259,11 +258,6 @@ module Sidekiq
259
258
 
260
259
  assert_equal 0, Sidekiq::Failures.count
261
260
 
262
- actor = MiniTest::Mock.new
263
- actor.expect(:processor_done, nil, [@processor])
264
- actor.expect(:real_thread, nil, [nil, Celluloid::Thread])
265
- @boss.expect(:async, actor, [])
266
-
267
261
  assert_raises TestException do
268
262
  @processor.process(msg)
269
263
  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
@@ -17,22 +21,22 @@ module Sidekiq
17
21
  it 'can display home with failures tab' do
18
22
  get '/'
19
23
 
20
- last_response.status.must_equal 200
21
- last_response.body.must_match /Sidekiq/
22
- last_response.body.must_match /Failures/
24
+ _(last_response.status).must_equal 200
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
- last_response.status.must_equal 200
28
- last_response.body.must_match /Failed Jobs/
29
- last_response.body.must_match /No failed jobs found/
31
+ _(last_response.status).must_equal 200
32
+ _(last_response.body).must_match(/Failed Jobs/)
33
+ _(last_response.body).must_match(/No failed jobs found/)
30
34
  end
31
35
 
32
36
  it 'has the reset counter form and action' do
33
37
  get '/failures'
34
- last_response.body.must_match /failures\/all\/reset/
35
- last_response.body.must_match /Reset Counter/
38
+ _(last_response.body).must_match(/failures\/all\/reset/)
39
+ _(last_response.body).must_match(/Reset Counter/)
36
40
  end
37
41
 
38
42
  describe 'when there are failures' do
@@ -42,97 +46,105 @@ module Sidekiq
42
46
  end
43
47
 
44
48
  it 'should be successful' do
45
- last_response.status.must_equal 200
49
+ _(last_response.status).must_equal 200
46
50
  end
47
51
 
48
52
  it 'can display failures page with failures listed' do
49
- last_response.body.must_match /Failed Jobs/
50
- last_response.body.must_match /HardWorker/
51
- last_response.body.must_match /ArgumentError/
52
- last_response.body.wont_match /No failed jobs found/
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/)
53
57
  end
54
58
 
55
59
  it 'can reset counter' do
56
60
  assert_equal failed_count, "1"
57
61
 
58
- last_response.body.must_match /HardWorker/
62
+ _(last_response.body).must_match(/HardWorker/)
59
63
 
60
64
  post '/failures/all/reset'
61
- last_response.status.must_equal 302
62
- last_response.location.must_match /failures$/
65
+ _(last_response.status).must_equal 302
66
+ _(last_response.location).must_match(/failures$/)
63
67
 
64
68
  get '/failures'
65
- last_response.status.must_equal 200
66
- last_response.body.must_match /HardWorker/
69
+ _(last_response.status).must_equal 200
70
+ _(last_response.body).must_match(/HardWorker/)
67
71
 
68
72
  assert_equal failed_count, "0"
69
73
  end
70
74
 
71
75
  it 'has the delete all form and action' do
72
- last_response.body.must_match /failures\/all\/delete/
73
- last_response.body.must_match /Delete All/
76
+ _(last_response.body).must_match(/failures\/all\/delete/)
77
+ _(last_response.body).must_match(/Delete All/)
74
78
  end
75
79
 
76
80
  it 'can delete all failures' do
77
81
  assert_equal failed_count, "1"
78
82
 
79
- last_response.body.must_match /HardWorker/
83
+ _(last_response.body).must_match(/HardWorker/)
80
84
 
81
85
  post '/failures/all/delete'
82
- last_response.status.must_equal 302
83
- last_response.location.must_match /failures$/
86
+ _(last_response.status).must_equal 302
87
+ _(last_response.location).must_match(/failures$/)
84
88
 
85
89
  get '/failures'
86
- last_response.status.must_equal 200
87
- last_response.body.must_match /No failed jobs found/
90
+ _(last_response.status).must_equal 200
91
+ _(last_response.body).must_match(/No failed jobs found/)
88
92
 
89
93
  assert_equal failed_count, "1"
90
94
  end
91
95
 
92
96
  it 'has the retry all form and action' do
93
- last_response.body.must_match /failures\/all\/retry/
94
- last_response.body.must_match /Retry All/
97
+ _(last_response.body).must_match(/failures\/all\/retry/)
98
+ _(last_response.body).must_match(/Retry All/)
95
99
  end
96
100
 
97
101
  it 'can retry all failures' do
98
102
  assert_equal failed_count, "1"
99
103
 
100
- last_response.body.must_match /HardWorker/
104
+ _(last_response.body).must_match(/HardWorker/)
101
105
  post '/failures/all/retry'
102
- last_response.status.must_equal 302
103
- last_response.location.must_match /failures/
106
+ _(last_response.status).must_equal 302
107
+ _(last_response.location).must_match(/failures/)
104
108
 
105
109
  get '/failures'
106
- last_response.status.must_equal 200
107
- last_response.body.must_match(/No failed jobs found/)
110
+ _(last_response.status).must_equal 200
111
+ _(last_response.body).must_match(/No failed jobs found/)
108
112
  end
109
113
 
110
114
  it 'can delete failure from the list' do
111
115
  assert_equal failed_count, "1"
112
116
 
113
- last_response.body.must_match /HardWorker/
117
+ _(last_response.body).must_match(/HardWorker/)
114
118
 
115
119
  post '/failures', { :key => [failure_score], :delete => 'Delete' }
116
- last_response.status.must_equal 302
117
- last_response.location.must_match /failures/
120
+ _(last_response.status).must_equal 302
121
+ _(last_response.location).must_match(/failures/)
118
122
 
119
123
  get '/failures'
120
- last_response.status.must_equal 200
121
- last_response.body.must_match /No failed jobs found/
124
+ _(last_response.status).must_equal 200
125
+ _(last_response.body).must_match(/No failed jobs found/)
122
126
  end
123
127
 
124
128
  it 'can retry failure from the list' do
125
129
  assert_equal failed_count, "1"
126
130
 
127
- last_response.body.must_match /HardWorker/
131
+ _(last_response.body).must_match(/HardWorker/)
128
132
 
129
133
  post '/failures', { :key => [failure_score], :retry => 'Retry Now' }
130
- last_response.status.must_equal 302
131
- last_response.location.must_match /failures/
134
+ _(last_response.status).must_equal 302
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)
132
144
 
133
145
  get '/failures'
134
- last_response.status.must_equal 200
135
- last_response.body.must_match /No failed jobs found/
146
+
147
+ _(last_response.status).must_equal 200
136
148
  end
137
149
  end
138
150
 
@@ -143,38 +155,47 @@ module Sidekiq
143
155
  end
144
156
 
145
157
  it 'should be successful' do
146
- last_response.status.must_equal 200
158
+ _(last_response.status).must_equal 200
147
159
  end
148
160
 
149
161
  it 'can display failure page' do
150
- last_response.body.must_match /Job/
151
- last_response.body.must_match /HardWorker/
152
- last_response.body.must_match /ArgumentError/
153
- 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/)
154
166
  end
155
167
 
156
168
  it 'can delete failure' do
157
- last_response.body.must_match /HardWorker/
169
+ _(last_response.body).must_match(/HardWorker/)
158
170
 
159
171
  post "/failures/#{failure_score}", :delete => 'Delete'
160
- last_response.status.must_equal 302
161
- last_response.location.must_match /failures/
172
+ _(last_response.status).must_equal 302
173
+ _(last_response.location).must_match(/failures/)
162
174
 
163
175
  get "/failures/#{failure_score}"
164
- last_response.status.must_equal 302
165
- last_response.location.must_match /failures/
176
+ _(last_response.status).must_equal 302
177
+ _(last_response.location).must_match(/failures/)
166
178
  end
167
179
 
168
180
  it 'can retry failure' do
169
- last_response.body.must_match /HardWorker/
181
+ _(last_response.body).must_match(/HardWorker/)
170
182
 
171
183
  post "/failures/#{failure_score}", :retry => 'Retry Now'
172
- last_response.status.must_equal 302
173
- last_response.location.must_match /failures/
184
+ _(last_response.status).must_equal 302
185
+ _(last_response.location).must_match(/failures/)
174
186
 
175
187
  get "/failures/#{failure_score}"
176
- last_response.status.must_equal 302
177
- last_response.location.must_match /failures/
188
+ _(last_response.status).must_equal 302
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
178
199
  end
179
200
  end
180
201
 
@@ -186,11 +207,11 @@ module Sidekiq
186
207
  end
187
208
 
188
209
  it 'can escape arguments' do
189
- 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;/)
190
211
  end
191
212
 
192
213
  it 'can escape error message' do
193
- 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;/)
194
215
  end
195
216
  end
196
217
 
@@ -201,8 +222,8 @@ module Sidekiq
201
222
  end
202
223
 
203
224
  it 'should be successful' do
204
- last_response.status.must_equal 200
205
- last_response.body.wont_match /No failed jobs found/
225
+ _(last_response.status).must_equal 200
226
+ _(last_response.body).wont_match(/No failed jobs found/)
206
227
  end
207
228
  end
208
229
 
@@ -213,8 +234,8 @@ module Sidekiq
213
234
  end
214
235
 
215
236
  it 'should be successful' do
216
- last_response.status.must_equal 200
217
- last_response.body.wont_match /No failed jobs found/
237
+ _(last_response.status).must_equal 200
238
+ _(last_response.body).wont_match(/No failed jobs found/)
218
239
  end
219
240
  end
220
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.5
4
+ version: 1.0.2
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: 2015-07-21 00:00:00.000000000 Z
11
+ date: 2022-07-28 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
@@ -87,8 +101,9 @@ executables: []
87
101
  extensions: []
88
102
  extra_rdoc_files: []
89
103
  files:
104
+ - ".github/dependabot.yml"
105
+ - ".github/workflows/ci.yml"
90
106
  - ".gitignore"
91
- - ".travis.yml"
92
107
  - CHANGELOG.md
93
108
  - Gemfile
94
109
  - LICENSE
@@ -98,6 +113,9 @@ files:
98
113
  - lib/sidekiq/failures.rb
99
114
  - lib/sidekiq/failures/failure_set.rb
100
115
  - lib/sidekiq/failures/locales/en.yml
116
+ - lib/sidekiq/failures/locales/ja.yml
117
+ - lib/sidekiq/failures/locales/pt-BR.yml
118
+ - lib/sidekiq/failures/locales/zh-cn.yml
101
119
  - lib/sidekiq/failures/middleware.rb
102
120
  - lib/sidekiq/failures/sorted_entry.rb
103
121
  - lib/sidekiq/failures/version.rb
@@ -105,13 +123,15 @@ files:
105
123
  - lib/sidekiq/failures/views/failures.erb
106
124
  - lib/sidekiq/failures/web_extension.rb
107
125
  - sidekiq-failures.gemspec
126
+ - test/failures_test.rb
108
127
  - test/middleware_test.rb
109
128
  - test/test_helper.rb
110
129
  - test/web_extension_test.rb
111
130
  homepage: https://github.com/mhfs/sidekiq-failures/
112
- licenses: []
131
+ licenses:
132
+ - MIT
113
133
  metadata: {}
114
- post_install_message:
134
+ post_install_message:
115
135
  rdoc_options: []
116
136
  require_paths:
117
137
  - lib
@@ -126,13 +146,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
146
  - !ruby/object:Gem::Version
127
147
  version: '0'
128
148
  requirements: []
129
- rubyforge_project:
130
- rubygems_version: 2.4.5
131
- signing_key:
149
+ rubygems_version: 3.3.7
150
+ signing_key:
132
151
  specification_version: 4
133
152
  summary: Keeps track of Sidekiq failed jobs and adds a tab to the Web UI to let you
134
153
  browse them. Makes use of Sidekiq's custom tabs and middleware chain.
135
- test_files:
136
- - test/middleware_test.rb
137
- - test/test_helper.rb
138
- - test/web_extension_test.rb
154
+ test_files: []
data/.travis.yml DELETED
@@ -1,18 +0,0 @@
1
- language: ruby
2
- services:
3
- - redis-server
4
- rvm:
5
- - 1.9.3
6
- - jruby-19mode
7
- - 2.0.0
8
- - 2.1
9
- env:
10
- matrix:
11
- - SIDEKIQ_VERSION="~> 2.16"
12
- - SIDEKIQ_VERSION="~> 2.17"
13
- - SIDEKIQ_VERSION="~> 3.0"
14
- - SIDEKIQ_VERSION="~> 3.1"
15
- matrix:
16
- allow_failures:
17
- - rvm: 1.9.3
18
- - rvm: jruby-19mode