shoryuken 6.2.1 → 7.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.
Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/push.yml +36 -0
  3. data/.github/workflows/specs.yml +49 -44
  4. data/.github/workflows/verify-action-pins.yml +16 -0
  5. data/.gitignore +4 -1
  6. data/.rspec +3 -1
  7. data/.rubocop.yml +6 -1
  8. data/.ruby-version +1 -0
  9. data/.yard-lint.yml +279 -0
  10. data/CHANGELOG.md +308 -139
  11. data/Gemfile +1 -8
  12. data/Gemfile.lint +9 -0
  13. data/Gemfile.lint.lock +69 -0
  14. data/README.md +16 -33
  15. data/Rakefile +6 -10
  16. data/bin/clean_sqs +52 -0
  17. data/bin/cli/base.rb +22 -2
  18. data/bin/cli/sqs.rb +74 -7
  19. data/bin/integrations +275 -0
  20. data/bin/scenario +154 -0
  21. data/bin/shoryuken +3 -2
  22. data/docker-compose.yml +6 -0
  23. data/lib/{shoryuken/extensions/active_job_extensions.rb → active_job/extensions.rb} +20 -6
  24. data/lib/active_job/queue_adapters/shoryuken_adapter.rb +208 -0
  25. data/lib/active_job/queue_adapters/shoryuken_concurrent_send_adapter.rb +78 -0
  26. data/lib/shoryuken/active_job/current_attributes.rb +139 -0
  27. data/lib/shoryuken/active_job/job_wrapper.rb +28 -0
  28. data/lib/shoryuken/body_parser.rb +11 -1
  29. data/lib/shoryuken/client.rb +16 -0
  30. data/lib/shoryuken/default_exception_handler.rb +11 -0
  31. data/lib/shoryuken/default_worker_registry.rb +39 -11
  32. data/lib/shoryuken/environment_loader.rb +85 -15
  33. data/lib/shoryuken/errors.rb +36 -0
  34. data/lib/shoryuken/fetcher.rb +41 -3
  35. data/lib/shoryuken/helpers/atomic_boolean.rb +58 -0
  36. data/lib/shoryuken/helpers/atomic_counter.rb +104 -0
  37. data/lib/shoryuken/helpers/atomic_hash.rb +182 -0
  38. data/lib/shoryuken/helpers/hash_utils.rb +56 -0
  39. data/lib/shoryuken/helpers/string_utils.rb +65 -0
  40. data/lib/shoryuken/helpers/timer_task.rb +80 -0
  41. data/lib/shoryuken/inline_message.rb +22 -0
  42. data/lib/shoryuken/launcher.rb +55 -0
  43. data/lib/shoryuken/logging/base.rb +26 -0
  44. data/lib/shoryuken/logging/pretty.rb +25 -0
  45. data/lib/shoryuken/logging/without_timestamp.rb +25 -0
  46. data/lib/shoryuken/logging.rb +43 -15
  47. data/lib/shoryuken/manager.rb +84 -5
  48. data/lib/shoryuken/message.rb +116 -1
  49. data/lib/shoryuken/middleware/chain.rb +141 -43
  50. data/lib/shoryuken/middleware/entry.rb +30 -0
  51. data/lib/shoryuken/middleware/server/active_record.rb +10 -0
  52. data/lib/shoryuken/middleware/server/auto_delete.rb +12 -0
  53. data/lib/shoryuken/middleware/server/auto_extend_visibility.rb +37 -11
  54. data/lib/shoryuken/middleware/server/exponential_backoff_retry.rb +34 -3
  55. data/lib/shoryuken/middleware/server/non_retryable_exception.rb +95 -0
  56. data/lib/shoryuken/middleware/server/timing.rb +13 -0
  57. data/lib/shoryuken/options.rb +154 -13
  58. data/lib/shoryuken/polling/base_strategy.rb +127 -0
  59. data/lib/shoryuken/polling/queue_configuration.rb +103 -0
  60. data/lib/shoryuken/polling/strict_priority.rb +41 -0
  61. data/lib/shoryuken/polling/weighted_round_robin.rb +44 -0
  62. data/lib/shoryuken/processor.rb +37 -3
  63. data/lib/shoryuken/queue.rb +99 -8
  64. data/lib/shoryuken/runner.rb +54 -16
  65. data/lib/shoryuken/util.rb +32 -7
  66. data/lib/shoryuken/version.rb +4 -1
  67. data/lib/shoryuken/worker/default_executor.rb +23 -1
  68. data/lib/shoryuken/worker/inline_executor.rb +33 -2
  69. data/lib/shoryuken/worker.rb +224 -0
  70. data/lib/shoryuken/worker_registry.rb +35 -0
  71. data/lib/shoryuken.rb +27 -38
  72. data/renovate.json +62 -0
  73. data/shoryuken.gemspec +8 -4
  74. data/spec/integration/.rspec +1 -0
  75. data/spec/integration/active_job/adapter_configuration/configuration_spec.rb +26 -0
  76. data/spec/integration/active_job/bulk_enqueue/bulk_enqueue_spec.rb +53 -0
  77. data/spec/integration/active_job/current_attributes/bulk_enqueue_spec.rb +50 -0
  78. data/spec/integration/active_job/current_attributes/complex_types_spec.rb +55 -0
  79. data/spec/integration/active_job/current_attributes/empty_context_spec.rb +41 -0
  80. data/spec/integration/active_job/current_attributes/full_context_spec.rb +63 -0
  81. data/spec/integration/active_job/current_attributes/partial_context_spec.rb +57 -0
  82. data/spec/integration/active_job/custom_attributes/number_attributes_spec.rb +37 -0
  83. data/spec/integration/active_job/custom_attributes/string_attributes_spec.rb +39 -0
  84. data/spec/integration/active_job/error_handling/job_wrapper_spec.rb +53 -0
  85. data/spec/integration/active_job/fifo_and_attributes/deduplication_spec.rb +86 -0
  86. data/spec/integration/active_job/keyword_arguments/keyword_arguments_spec.rb +63 -0
  87. data/spec/integration/active_job/retry/discard_on_spec.rb +43 -0
  88. data/spec/integration/active_job/retry/retry_on_spec.rb +36 -0
  89. data/spec/integration/active_job/roundtrip/roundtrip_spec.rb +52 -0
  90. data/spec/integration/active_job/scheduled/scheduled_spec.rb +76 -0
  91. data/spec/integration/active_record_middleware/active_record_middleware_spec.rb +84 -0
  92. data/spec/integration/auto_delete/auto_delete_spec.rb +53 -0
  93. data/spec/integration/auto_extend_visibility/auto_extend_visibility_spec.rb +57 -0
  94. data/spec/integration/aws_config/aws_config_spec.rb +59 -0
  95. data/spec/integration/batch_processing/batch_processing_spec.rb +37 -0
  96. data/spec/integration/body_parser/json_parser_spec.rb +45 -0
  97. data/spec/integration/body_parser/proc_parser_spec.rb +54 -0
  98. data/spec/integration/body_parser/text_parser_spec.rb +43 -0
  99. data/spec/integration/concurrent_processing/concurrent_processing_spec.rb +45 -0
  100. data/spec/integration/custom_group_polling_strategy/custom_group_polling_strategy_spec.rb +87 -0
  101. data/spec/integration/dead_letter_queue/dead_letter_queue_spec.rb +91 -0
  102. data/spec/integration/exception_handlers/exception_handlers_spec.rb +69 -0
  103. data/spec/integration/exponential_backoff/exponential_backoff_spec.rb +67 -0
  104. data/spec/integration/fifo_ordering/fifo_ordering_spec.rb +44 -0
  105. data/spec/integration/large_payloads/large_payloads_spec.rb +30 -0
  106. data/spec/integration/launcher/launcher_spec.rb +40 -0
  107. data/spec/integration/message_attributes/message_attributes_spec.rb +54 -0
  108. data/spec/integration/message_operations/message_operations_spec.rb +59 -0
  109. data/spec/integration/middleware_chain/empty_chain_spec.rb +11 -0
  110. data/spec/integration/middleware_chain/execution_order_spec.rb +33 -0
  111. data/spec/integration/middleware_chain/removal_spec.rb +31 -0
  112. data/spec/integration/middleware_chain/short_circuit_spec.rb +40 -0
  113. data/spec/integration/non_retryable_exception/non_retryable_exception_spec.rb +149 -0
  114. data/spec/integration/polling_strategies/polling_strategies_spec.rb +46 -0
  115. data/spec/integration/queue_operations/queue_operations_spec.rb +84 -0
  116. data/spec/integration/rails/rails_72/Gemfile +6 -0
  117. data/spec/integration/rails/rails_72/activejob_adapter_spec.rb +98 -0
  118. data/spec/integration/rails/rails_80/Gemfile +6 -0
  119. data/spec/integration/rails/rails_80/activejob_adapter_spec.rb +98 -0
  120. data/spec/integration/rails/rails_80/continuation_spec.rb +79 -0
  121. data/spec/integration/rails/rails_81/Gemfile +6 -0
  122. data/spec/integration/rails/rails_81/activejob_adapter_spec.rb +98 -0
  123. data/spec/integration/rails/rails_81/continuation_spec.rb +79 -0
  124. data/spec/integration/retry_behavior/retry_behavior_spec.rb +45 -0
  125. data/spec/integration/spec_helper.rb +7 -0
  126. data/spec/integration/strict_priority_polling/strict_priority_polling_spec.rb +58 -0
  127. data/spec/integration/visibility_timeout/visibility_timeout_spec.rb +37 -0
  128. data/spec/integration/worker_enqueueing/worker_enqueueing_spec.rb +60 -0
  129. data/spec/integration/worker_groups/worker_groups_spec.rb +79 -0
  130. data/spec/integration/worker_lifecycle/worker_lifecycle_spec.rb +33 -0
  131. data/spec/integrations_helper.rb +243 -0
  132. data/spec/lib/active_job/extensions_spec.rb +225 -0
  133. data/spec/lib/active_job/queue_adapters/shoryuken_adapter_spec.rb +29 -0
  134. data/spec/{shoryuken/extensions/active_job_concurrent_send_adapter_spec.rb → lib/active_job/queue_adapters/shoryuken_concurrent_send_adapter_spec.rb} +5 -4
  135. data/spec/{shoryuken/extensions/active_job_wrapper_spec.rb → lib/shoryuken/active_job/job_wrapper_spec.rb} +6 -5
  136. data/spec/{shoryuken → lib/shoryuken}/body_parser_spec.rb +2 -4
  137. data/spec/{shoryuken → lib/shoryuken}/client_spec.rb +1 -1
  138. data/spec/{shoryuken → lib/shoryuken}/default_exception_handler_spec.rb +9 -10
  139. data/spec/{shoryuken → lib/shoryuken}/default_worker_registry_spec.rb +1 -2
  140. data/spec/{shoryuken → lib/shoryuken}/environment_loader_spec.rb +10 -9
  141. data/spec/{shoryuken → lib/shoryuken}/fetcher_spec.rb +23 -26
  142. data/spec/lib/shoryuken/helpers/atomic_boolean_spec.rb +196 -0
  143. data/spec/lib/shoryuken/helpers/atomic_counter_spec.rb +177 -0
  144. data/spec/lib/shoryuken/helpers/atomic_hash_spec.rb +307 -0
  145. data/spec/lib/shoryuken/helpers/hash_utils_spec.rb +145 -0
  146. data/spec/lib/shoryuken/helpers/string_utils_spec.rb +124 -0
  147. data/spec/lib/shoryuken/helpers/timer_task_spec.rb +298 -0
  148. data/spec/lib/shoryuken/helpers_integration_spec.rb +96 -0
  149. data/spec/lib/shoryuken/inline_message_spec.rb +196 -0
  150. data/spec/{shoryuken → lib/shoryuken}/launcher_spec.rb +23 -2
  151. data/spec/lib/shoryuken/logging_spec.rb +242 -0
  152. data/spec/{shoryuken → lib/shoryuken}/manager_spec.rb +1 -2
  153. data/spec/lib/shoryuken/message_spec.rb +109 -0
  154. data/spec/{shoryuken → lib/shoryuken}/middleware/chain_spec.rb +1 -1
  155. data/spec/lib/shoryuken/middleware/entry_spec.rb +68 -0
  156. data/spec/lib/shoryuken/middleware/server/active_record_spec.rb +133 -0
  157. data/spec/{shoryuken → lib/shoryuken}/middleware/server/auto_delete_spec.rb +1 -1
  158. data/spec/{shoryuken → lib/shoryuken}/middleware/server/auto_extend_visibility_spec.rb +51 -1
  159. data/spec/{shoryuken → lib/shoryuken}/middleware/server/exponential_backoff_retry_spec.rb +1 -1
  160. data/spec/lib/shoryuken/middleware/server/non_retryable_exception_spec.rb +214 -0
  161. data/spec/{shoryuken → lib/shoryuken}/middleware/server/timing_spec.rb +1 -1
  162. data/spec/{shoryuken → lib/shoryuken}/options_spec.rb +49 -6
  163. data/spec/lib/shoryuken/polling/base_strategy_spec.rb +280 -0
  164. data/spec/lib/shoryuken/polling/queue_configuration_spec.rb +195 -0
  165. data/spec/{shoryuken → lib/shoryuken}/polling/strict_priority_spec.rb +1 -1
  166. data/spec/{shoryuken → lib/shoryuken}/polling/weighted_round_robin_spec.rb +1 -1
  167. data/spec/{shoryuken → lib/shoryuken}/processor_spec.rb +1 -1
  168. data/spec/{shoryuken → lib/shoryuken}/queue_spec.rb +2 -3
  169. data/spec/{shoryuken → lib/shoryuken}/runner_spec.rb +1 -3
  170. data/spec/{shoryuken → lib/shoryuken}/util_spec.rb +2 -2
  171. data/spec/lib/shoryuken/version_spec.rb +17 -0
  172. data/spec/{shoryuken → lib/shoryuken}/worker/default_executor_spec.rb +1 -1
  173. data/spec/lib/shoryuken/worker/inline_executor_spec.rb +105 -0
  174. data/spec/lib/shoryuken/worker_registry_spec.rb +63 -0
  175. data/spec/{shoryuken → lib/shoryuken}/worker_spec.rb +15 -11
  176. data/spec/{shoryuken_spec.rb → lib/shoryuken_spec.rb} +1 -1
  177. data/spec/shared_examples_for_active_job.rb +40 -15
  178. data/spec/spec_helper.rb +48 -2
  179. metadata +295 -101
  180. data/.codeclimate.yml +0 -20
  181. data/.devcontainer/Dockerfile +0 -17
  182. data/.devcontainer/base.Dockerfile +0 -43
  183. data/.devcontainer/devcontainer.json +0 -35
  184. data/.github/FUNDING.yml +0 -12
  185. data/.github/dependabot.yml +0 -6
  186. data/.github/workflows/stale.yml +0 -20
  187. data/.reek.yml +0 -5
  188. data/Appraisals +0 -42
  189. data/gemfiles/.gitignore +0 -1
  190. data/gemfiles/aws_sdk_core_2.gemfile +0 -21
  191. data/gemfiles/rails_4_2.gemfile +0 -20
  192. data/gemfiles/rails_5_2.gemfile +0 -21
  193. data/gemfiles/rails_6_0.gemfile +0 -21
  194. data/gemfiles/rails_6_1.gemfile +0 -21
  195. data/gemfiles/rails_7_0.gemfile +0 -22
  196. data/lib/shoryuken/core_ext.rb +0 -69
  197. data/lib/shoryuken/extensions/active_job_adapter.rb +0 -103
  198. data/lib/shoryuken/extensions/active_job_concurrent_send_adapter.rb +0 -50
  199. data/lib/shoryuken/polling/base.rb +0 -67
  200. data/shoryuken.jpg +0 -0
  201. data/spec/integration/launcher_spec.rb +0 -128
  202. data/spec/shoryuken/core_ext_spec.rb +0 -40
  203. data/spec/shoryuken/extensions/active_job_adapter_spec.rb +0 -7
  204. data/spec/shoryuken/extensions/active_job_base_spec.rb +0 -84
  205. data/spec/shoryuken/worker/inline_executor_spec.rb +0 -49
@@ -0,0 +1,225 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'active_job'
5
+
6
+ # Skip this spec if ActiveSupport is not available, as the extensions require it
7
+ if defined?(ActiveSupport)
8
+ require 'active_job/extensions'
9
+
10
+ RSpec.describe Shoryuken::ActiveJob do
11
+ describe Shoryuken::ActiveJob::SQSSendMessageParametersAccessor do
12
+ let(:job_class) do
13
+ Class.new do
14
+ include Shoryuken::ActiveJob::SQSSendMessageParametersAccessor
15
+ end
16
+ end
17
+
18
+ let(:job_instance) { job_class.new }
19
+
20
+ describe 'included behavior' do
21
+ it 'adds sqs_send_message_parameters accessor' do
22
+ expect(job_instance).to respond_to(:sqs_send_message_parameters)
23
+ expect(job_instance).to respond_to(:sqs_send_message_parameters=)
24
+ end
25
+
26
+ it 'allows setting and getting sqs_send_message_parameters' do
27
+ params = { message_group_id: 'group1', message_deduplication_id: 'dedup1' }
28
+ job_instance.sqs_send_message_parameters = params
29
+ expect(job_instance.sqs_send_message_parameters).to eq(params)
30
+ end
31
+ end
32
+ end
33
+
34
+ describe Shoryuken::ActiveJob::SQSSendMessageParametersSupport do
35
+ let(:base_class) do
36
+ Class.new do
37
+ attr_accessor :sqs_send_message_parameters
38
+
39
+ def initialize(*arguments)
40
+ # Mock ActiveJob::Base initialization
41
+ end
42
+
43
+ def enqueue(options = {})
44
+ # Mock ActiveJob::Base enqueue method that returns remaining options
45
+ options
46
+ end
47
+ end
48
+ end
49
+
50
+ let(:job_class) do
51
+ Class.new(base_class) do
52
+ prepend Shoryuken::ActiveJob::SQSSendMessageParametersSupport
53
+ end
54
+ end
55
+
56
+ describe '#initialize' do
57
+ it 'initializes sqs_send_message_parameters to empty hash' do
58
+ job = job_class.new('arg1', 'arg2')
59
+ expect(job.sqs_send_message_parameters).to eq({})
60
+ end
61
+
62
+ it 'calls super with the provided arguments' do
63
+ expect_any_instance_of(base_class).to receive(:initialize).with('arg1', 'arg2')
64
+ job_class.new('arg1', 'arg2')
65
+ end
66
+
67
+ it 'handles ruby2_keywords compatibility' do
68
+ # Test that ruby2_keywords is called if available
69
+ if respond_to?(:ruby2_keywords, true)
70
+ expect(job_class.method(:new)).to respond_to(:ruby2_keywords) if RUBY_VERSION >= '2.7'
71
+ end
72
+ end
73
+
74
+ # Regression test for https://github.com/ruby-shoryuken/shoryuken/issues/961
75
+ # ActiveJob with keyword arguments was broken in Shoryuken 7.0 because
76
+ # the SQSSendMessageParametersSupport module's initialize method did not
77
+ # properly forward keyword arguments using ruby2_keywords.
78
+ context 'with keyword arguments' do
79
+ let(:base_class_with_kwargs) do
80
+ Class.new do
81
+ attr_accessor :sqs_send_message_parameters
82
+ attr_reader :received_name, :received_count, :received_enabled
83
+
84
+ def initialize(name:, count:, enabled: false)
85
+ @received_name = name
86
+ @received_count = count
87
+ @received_enabled = enabled
88
+ end
89
+ end
90
+ end
91
+
92
+ let(:job_class_with_kwargs) do
93
+ Class.new(base_class_with_kwargs) do
94
+ prepend Shoryuken::ActiveJob::SQSSendMessageParametersSupport
95
+ end
96
+ end
97
+
98
+ it 'properly forwards keyword arguments to the base class' do
99
+ job = job_class_with_kwargs.new(name: 'test_name', count: 42, enabled: true)
100
+
101
+ expect(job.received_name).to eq('test_name')
102
+ expect(job.received_count).to eq(42)
103
+ expect(job.received_enabled).to eq(true)
104
+ expect(job.sqs_send_message_parameters).to eq({})
105
+ end
106
+
107
+ it 'properly forwards keyword arguments with default values' do
108
+ job = job_class_with_kwargs.new(name: 'another_test', count: 10)
109
+
110
+ expect(job.received_name).to eq('another_test')
111
+ expect(job.received_count).to eq(10)
112
+ expect(job.received_enabled).to eq(false)
113
+ expect(job.sqs_send_message_parameters).to eq({})
114
+ end
115
+ end
116
+
117
+ # Regression test for https://github.com/ruby-shoryuken/shoryuken/issues/961
118
+ # Test with a mix of positional and keyword arguments
119
+ context 'with mixed positional and keyword arguments' do
120
+ let(:base_class_mixed) do
121
+ Class.new do
122
+ attr_accessor :sqs_send_message_parameters
123
+ attr_reader :received_id, :received_data, :received_options
124
+
125
+ def initialize(id, data, options: {})
126
+ @received_id = id
127
+ @received_data = data
128
+ @received_options = options
129
+ end
130
+ end
131
+ end
132
+
133
+ let(:job_class_mixed) do
134
+ Class.new(base_class_mixed) do
135
+ prepend Shoryuken::ActiveJob::SQSSendMessageParametersSupport
136
+ end
137
+ end
138
+
139
+ it 'properly forwards mixed arguments to the base class' do
140
+ job = job_class_mixed.new('job_id', { key: 'value' }, options: { retry: true })
141
+
142
+ expect(job.received_id).to eq('job_id')
143
+ expect(job.received_data).to eq({ key: 'value' })
144
+ expect(job.received_options).to eq({ retry: true })
145
+ expect(job.sqs_send_message_parameters).to eq({})
146
+ end
147
+ end
148
+ end
149
+
150
+ describe '#enqueue' do
151
+ let(:job_instance) { job_class.new }
152
+
153
+ it 'extracts SQS-specific options and merges them into sqs_send_message_parameters' do
154
+ options = {
155
+ wait: 5 * 60, # 5 minutes in seconds
156
+ message_attributes: { 'type' => 'important' },
157
+ message_system_attributes: { 'source' => 'api' },
158
+ message_deduplication_id: 'dedup123',
159
+ message_group_id: 'group456',
160
+ other_option: 'value'
161
+ }
162
+
163
+ remaining_options = job_instance.enqueue(options)
164
+
165
+ expect(job_instance.sqs_send_message_parameters).to eq({
166
+ message_attributes: { 'type' => 'important' },
167
+ message_system_attributes: { 'source' => 'api' },
168
+ message_deduplication_id: 'dedup123',
169
+ message_group_id: 'group456'
170
+ })
171
+
172
+ expect(remaining_options).to eq({
173
+ wait: 300,
174
+ other_option: 'value'
175
+ })
176
+ end
177
+
178
+ it 'handles empty options gracefully' do
179
+ remaining_options = job_instance.enqueue({})
180
+ expect(job_instance.sqs_send_message_parameters).to eq({})
181
+ expect(remaining_options).to eq({})
182
+ end
183
+
184
+ it 'merges new SQS options with existing ones' do
185
+ job_instance.sqs_send_message_parameters = { message_group_id: 'existing_group' }
186
+
187
+ options = { message_deduplication_id: 'new_dedup' }
188
+ job_instance.enqueue(options)
189
+
190
+ expect(job_instance.sqs_send_message_parameters).to eq({
191
+ message_group_id: 'existing_group',
192
+ message_deduplication_id: 'new_dedup'
193
+ })
194
+ end
195
+
196
+ it 'overwrites existing SQS options when the same key is provided' do
197
+ job_instance.sqs_send_message_parameters = { message_group_id: 'old_group' }
198
+
199
+ options = { message_group_id: 'new_group' }
200
+ job_instance.enqueue(options)
201
+
202
+ expect(job_instance.sqs_send_message_parameters).to eq({
203
+ message_group_id: 'new_group'
204
+ })
205
+ end
206
+ end
207
+ end
208
+
209
+ describe 'module constants' do
210
+ it 'defines SQSSendMessageParametersAccessor' do
211
+ expect(Shoryuken::ActiveJob::SQSSendMessageParametersAccessor).to be_a(Module)
212
+ end
213
+
214
+ it 'defines SQSSendMessageParametersSupport' do
215
+ expect(Shoryuken::ActiveJob::SQSSendMessageParametersSupport).to be_a(Module)
216
+ end
217
+ end
218
+ end
219
+ else
220
+ RSpec.describe 'Shoryuken::ActiveJob (skipped - ActiveSupport not available)' do
221
+ it 'skips tests when ActiveSupport is not available' do
222
+ skip('ActiveSupport not available in test environment')
223
+ end
224
+ end
225
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'shared_examples_for_active_job'
4
+ require 'active_job/queue_adapters/shoryuken_adapter'
5
+ require 'active_support/core_ext/numeric/time'
6
+
7
+ RSpec.describe ActiveJob::QueueAdapters::ShoryukenAdapter do
8
+ include_examples 'active_job_adapters'
9
+
10
+ describe '#enqueue_after_transaction_commit?' do
11
+ it 'returns true to support Rails 7.2+ transaction commit behavior' do
12
+ adapter = described_class.new
13
+ expect(adapter.enqueue_after_transaction_commit?).to eq(true)
14
+ end
15
+ end
16
+
17
+ describe '.instance' do
18
+ it 'returns the same instance (singleton pattern)' do
19
+ instance1 = described_class.instance
20
+ instance2 = described_class.instance
21
+ expect(instance1).to be(instance2)
22
+ end
23
+
24
+ it 'returns a ShoryukenAdapter instance' do
25
+ expect(described_class.instance).to be_a(described_class)
26
+ end
27
+ end
28
+
29
+ end
@@ -1,7 +1,8 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
2
3
  require 'shared_examples_for_active_job'
3
- require 'shoryuken/extensions/active_job_adapter'
4
- require 'shoryuken/extensions/active_job_concurrent_send_adapter'
4
+ require 'active_job/queue_adapters/shoryuken_adapter'
5
+ require 'active_job/queue_adapters/shoryuken_concurrent_send_adapter'
5
6
 
6
7
  RSpec.describe ActiveJob::QueueAdapters::ShoryukenConcurrentSendAdapter do
7
8
  include_examples 'active_job_adapters'
@@ -36,4 +37,4 @@ RSpec.describe ActiveJob::QueueAdapters::ShoryukenConcurrentSendAdapter do
36
37
  subject.enqueue(job, options)
37
38
  end
38
39
  end
39
- end
40
+ end
@@ -1,9 +1,10 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
2
3
  require 'active_job'
3
- require 'shoryuken/extensions/active_job_extensions'
4
- require 'shoryuken/extensions/active_job_adapter'
4
+ require 'active_job/extensions'
5
+ require 'active_job/queue_adapters/shoryuken_adapter'
5
6
 
6
- RSpec.describe ActiveJob::QueueAdapters::ShoryukenAdapter::JobWrapper do
7
+ RSpec.describe Shoryuken::ActiveJob::JobWrapper do
7
8
  subject { described_class.new }
8
9
 
9
10
  describe '#perform' do
@@ -17,4 +18,4 @@ RSpec.describe ActiveJob::QueueAdapters::ShoryukenAdapter::JobWrapper do
17
18
  subject.perform sqs_msg, job_hash
18
19
  end
19
20
  end
20
- end
21
+ end
@@ -1,5 +1,4 @@
1
- require 'spec_helper'
2
- require 'shoryuken/body_parser'
1
+ # frozen_string_literal: true
3
2
 
4
3
  RSpec.describe Shoryuken::BodyParser do
5
4
  let(:sqs_msg) { double }
@@ -69,8 +68,7 @@ RSpec.describe Shoryuken::BodyParser do
69
68
  end
70
69
 
71
70
  specify do
72
- expect { described_class.parse(TestWorker, sqs_msg) }
73
- .to raise_error(JSON::ParserError, /unexpected token at 'invalid JSON'/)
71
+ expect { described_class.parse(TestWorker, sqs_msg) }.to raise_error(JSON::ParserError)
74
72
  end
75
73
  end
76
74
 
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe Shoryuken::Client do
4
4
  let(:credentials) { Aws::Credentials.new('access_key_id', 'secret_access_key') }
@@ -1,12 +1,11 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Metrics/BlockLength
4
3
  RSpec.describe Shoryuken::DefaultExceptionHandler do
5
4
  class CustomErrorHandler
6
5
  extend Shoryuken::Util
7
6
 
8
7
  def self.call(_ex, queue, _msg)
9
- logger.error("#{queue.to_s} failed to process the message")
8
+ logger.error("#{queue} failed to process the message")
10
9
  end
11
10
  end
12
11
 
@@ -38,31 +37,31 @@ RSpec.describe Shoryuken::DefaultExceptionHandler do
38
37
 
39
38
  subject { Shoryuken::Processor.new(queue, sqs_msg) }
40
39
 
41
- context "with default handler" do
40
+ context 'with default handler' do
42
41
  before do
43
42
  Shoryuken.exception_handlers = described_class
44
43
  end
45
44
 
46
- it "logs an error message" do
45
+ it 'logs an error message' do
47
46
  expect(Shoryuken::Logging.logger).to receive(:error).twice
48
47
 
49
- allow_any_instance_of(TestWorker).to receive(:perform).and_raise(StandardError, "error")
48
+ allow_any_instance_of(TestWorker).to receive(:perform).and_raise(StandardError, 'error')
50
49
  allow(sqs_msg).to receive(:body)
51
50
 
52
51
  expect { subject.process }.to raise_error(StandardError)
53
52
  end
54
53
  end
55
54
 
56
- context "with custom handler" do
55
+ context 'with custom handler' do
57
56
  before do
58
57
  Shoryuken.exception_handlers = [described_class, CustomErrorHandler]
59
58
  end
60
59
 
61
- it "logs default and custom error messages" do
60
+ it 'logs default and custom error messages' do
62
61
  expect(Shoryuken::Logging.logger).to receive(:error).twice
63
- expect(Shoryuken::Logging.logger).to receive(:error).with("default failed to process the message").once
62
+ expect(Shoryuken::Logging.logger).to receive(:error).with('default failed to process the message').once
64
63
 
65
- allow_any_instance_of(TestWorker).to receive(:perform).and_raise(StandardError, "error")
64
+ allow_any_instance_of(TestWorker).to receive(:perform).and_raise(StandardError, 'error')
66
65
  allow(sqs_msg).to receive(:body)
67
66
 
68
67
  expect { subject.process }.to raise_error(StandardError)
@@ -1,6 +1,5 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Metrics/BlockLength
4
3
  RSpec.describe Shoryuken::DefaultWorkerRegistry do
5
4
  class RegistryTestWorker
6
5
  include Shoryuken::Worker
@@ -1,4 +1,5 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
2
3
  require 'active_job'
3
4
 
4
5
  RSpec.describe Shoryuken::EnvironmentLoader do
@@ -23,7 +24,7 @@ RSpec.describe Shoryuken::EnvironmentLoader do
23
24
  context "when given queues don't exist" do
24
25
  specify do
25
26
  expect { subject.load }.to raise_error(
26
- ArgumentError,
27
+ Shoryuken::Errors::QueueNotFoundError,
27
28
  <<-MSG.gsub(/^\s+/, '')
28
29
  The specified queue(s) stubbed_queue do not exist.
29
30
  Try 'shoryuken sqs create QUEUE-NAME' for creating a queue with default settings.
@@ -63,7 +64,7 @@ RSpec.describe Shoryuken::EnvironmentLoader do
63
64
  end
64
65
 
65
66
  specify do
66
- Shoryuken.options[:queues] = ['queue1', 'queue2'] # default queues
67
+ Shoryuken.options[:queues] = %w[queue1 queue2] # default queues
67
68
  Shoryuken.options[:groups] = [['custom', { queues: ['queue3'], delay: 25 }]]
68
69
  subject.load
69
70
 
@@ -124,11 +125,11 @@ RSpec.describe Shoryuken::EnvironmentLoader do
124
125
  end
125
126
  end
126
127
 
127
- describe "#setup_options" do
128
- let(:cli_queues) { { "queue1" => 10, "queue2" => 20 } }
129
- let(:config_queues) { [["queue1", 8], ["queue2", 4]] }
128
+ describe '#setup_options' do
129
+ let(:cli_queues) { { 'queue1' => 10, 'queue2' => 20 } }
130
+ let(:config_queues) { [['queue1', 8], ['queue2', 4]] }
130
131
 
131
- context "when given queues through config and CLI" do
132
+ context 'when given queues through config and CLI' do
132
133
  specify do
133
134
  allow_any_instance_of(Shoryuken::EnvironmentLoader).to receive(:config_file_options).and_return({ queues: config_queues })
134
135
  Shoryuken::EnvironmentLoader.setup_options(queues: cli_queues)
@@ -136,7 +137,7 @@ RSpec.describe Shoryuken::EnvironmentLoader do
136
137
  end
137
138
  end
138
139
 
139
- context "when given queues through config only" do
140
+ context 'when given queues through config only' do
140
141
  specify do
141
142
  allow_any_instance_of(Shoryuken::EnvironmentLoader).to receive(:config_file_options).and_return({ queues: config_queues })
142
143
  Shoryuken::EnvironmentLoader.setup_options({})
@@ -144,7 +145,7 @@ RSpec.describe Shoryuken::EnvironmentLoader do
144
145
  end
145
146
  end
146
147
 
147
- context "when given queues through CLI only" do
148
+ context 'when given queues through CLI only' do
148
149
  specify do
149
150
  Shoryuken::EnvironmentLoader.setup_options(queues: cli_queues)
150
151
  expect(Shoryuken.options[:queues]).to eq(cli_queues)
@@ -1,8 +1,5 @@
1
- require 'spec_helper'
2
- require 'shoryuken/manager'
3
- require 'shoryuken/fetcher'
1
+ # frozen_string_literal: true
4
2
 
5
- # rubocop:disable Metrics/BlockLength
6
3
  RSpec.describe Shoryuken::Fetcher do
7
4
  let(:queue) { instance_double('Shoryuken::Queue', fifo?: false) }
8
5
  let(:queue_name) { 'default' }
@@ -29,17 +26,17 @@ RSpec.describe Shoryuken::Fetcher do
29
26
  Shoryuken.sqs_client_receive_message_opts[group] = { wait_time_seconds: 10 }
30
27
 
31
28
  expect(queue).to receive(:receive_messages).with({
32
- wait_time_seconds: 10,
33
- max_number_of_messages: limit,
34
- message_attribute_names: ['All'],
35
- attribute_names: ['All']
36
- }).and_return([])
29
+ wait_time_seconds: 10,
30
+ max_number_of_messages: limit,
31
+ message_attribute_names: ['All'],
32
+ attribute_names: ['All']
33
+ }).and_return([])
37
34
 
38
35
  subject.fetch(queue_config, limit)
39
36
  end
40
37
 
41
38
  it 'logs debug only' do
42
- # See https://github.com/phstc/shoryuken/issues/435
39
+ # See https://github.com/ruby-shoryuken/shoryuken/issues/435
43
40
  logger = double 'logger'
44
41
 
45
42
  allow(subject).to receive(:logger).and_return(logger)
@@ -63,10 +60,10 @@ RSpec.describe Shoryuken::Fetcher do
63
60
  Shoryuken.sqs_client_receive_message_opts[queue_name] = { max_number_of_messages: 1 }
64
61
 
65
62
  expect(queue).to receive(:receive_messages).with({
66
- max_number_of_messages: 1,
67
- message_attribute_names: ['All'],
68
- attribute_names: ['All']
69
- }).and_return([])
63
+ max_number_of_messages: 1,
64
+ message_attribute_names: ['All'],
65
+ attribute_names: ['All']
66
+ }).and_return([])
70
67
 
71
68
  subject.fetch(queue_config, limit)
72
69
  end
@@ -79,10 +76,10 @@ RSpec.describe Shoryuken::Fetcher do
79
76
  Shoryuken.sqs_client_receive_message_opts[queue_name] = { max_number_of_messages: 20 }
80
77
 
81
78
  expect(queue).to receive(:receive_messages).with({
82
- max_number_of_messages: limit,
83
- message_attribute_names: ['All'],
84
- attribute_names: ['All']
85
- }).and_return([])
79
+ max_number_of_messages: limit,
80
+ message_attribute_names: ['All'],
81
+ attribute_names: ['All']
82
+ }).and_return([])
86
83
 
87
84
  subject.fetch(queue_config, limit)
88
85
  end
@@ -94,8 +91,8 @@ RSpec.describe Shoryuken::Fetcher do
94
91
  specify do
95
92
  allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
96
93
  expect(queue).to receive(:receive_messages).with({
97
- max_number_of_messages: described_class::FETCH_LIMIT, attribute_names: ['All'], message_attribute_names: ['All']
98
- }).and_return([])
94
+ max_number_of_messages: described_class::FETCH_LIMIT, attribute_names: ['All'], message_attribute_names: ['All']
95
+ }).and_return([])
99
96
 
100
97
  subject.fetch(queue_config, limit)
101
98
  end
@@ -106,26 +103,26 @@ RSpec.describe Shoryuken::Fetcher do
106
103
  let(:queue) { instance_double('Shoryuken::Queue', fifo?: true, name: queue_name) }
107
104
 
108
105
  it 'polls one message at a time' do
109
- # see https://github.com/phstc/shoryuken/pull/530
106
+ # see https://github.com/ruby-shoryuken/shoryuken/pull/530
110
107
 
111
108
  allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
112
109
  expect(queue).to receive(:receive_messages).with({
113
- max_number_of_messages: 1, attribute_names: ['All'], message_attribute_names: ['All']
114
- }).and_return([])
110
+ max_number_of_messages: 1, attribute_names: ['All'], message_attribute_names: ['All']
111
+ }).and_return([])
115
112
 
116
113
  subject.fetch(queue_config, limit)
117
114
  end
118
115
 
119
116
  context 'with batch=true' do
120
117
  it 'polls the provided limit' do
121
- # see https://github.com/phstc/shoryuken/pull/530
118
+ # see https://github.com/ruby-shoryuken/shoryuken/pull/530
122
119
 
123
120
  allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
124
121
  allow(Shoryuken.worker_registry).to receive(:batch_receive_messages?).with(queue.name).and_return(true)
125
122
 
126
123
  expect(queue).to receive(:receive_messages).with({
127
- max_number_of_messages: limit, attribute_names: ['All'], message_attribute_names: ['All']
128
- }).and_return([])
124
+ max_number_of_messages: limit, attribute_names: ['All'], message_attribute_names: ['All']
125
+ }).and_return([])
129
126
 
130
127
  subject.fetch(queue_config, limit)
131
128
  end