karafka-testing 2.5.4 → 2.5.6
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 +4 -4
- data/.github/workflows/ci.yml +81 -43
- data/.github/workflows/push.yml +3 -3
- data/.github/workflows/trigger-wiki-refresh.yml +1 -1
- data/.github/workflows/verify-action-pins.yml +1 -1
- data/.gitignore +1 -0
- data/.rubocop.yml +32 -0
- data/.ruby-version +1 -1
- data/.yard-lint.yml +275 -0
- data/CHANGELOG.md +12 -4
- data/Gemfile +10 -3
- data/Gemfile.lint +14 -0
- data/Gemfile.lint.lock +108 -0
- data/Gemfile.lock +56 -19
- data/Rakefile +12 -2
- data/karafka-testing.gemspec +22 -22
- data/lib/karafka/testing/minitest/helpers.rb +90 -23
- data/lib/karafka/testing/minitest/proxy.rb +11 -6
- data/lib/karafka/testing/rspec/helpers.rb +113 -24
- data/lib/karafka/testing/rspec/proxy.rb +11 -6
- data/lib/karafka/testing/version.rb +1 -1
- data/lib/karafka/testing.rb +3 -3
- data/lib/karafka-testing.rb +1 -1
- data/package-lock.json +331 -0
- data/package.json +9 -0
- data/renovate.json +16 -3
- metadata +8 -5
- data/.coditsu/ci.yml +0 -3
- data/.diffend.yml +0 -3
- data/.rspec +0 -1
data/Gemfile.lint.lock
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: https://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
ast (2.4.3)
|
|
5
|
+
json (2.18.0)
|
|
6
|
+
language_server-protocol (3.17.0.5)
|
|
7
|
+
lint_roller (1.1.0)
|
|
8
|
+
parallel (1.27.0)
|
|
9
|
+
parser (3.3.10.1)
|
|
10
|
+
ast (~> 2.4.1)
|
|
11
|
+
racc
|
|
12
|
+
prism (1.8.0)
|
|
13
|
+
racc (1.8.1)
|
|
14
|
+
rainbow (3.1.1)
|
|
15
|
+
regexp_parser (2.11.3)
|
|
16
|
+
rubocop (1.82.1)
|
|
17
|
+
json (~> 2.3)
|
|
18
|
+
language_server-protocol (~> 3.17.0.2)
|
|
19
|
+
lint_roller (~> 1.1.0)
|
|
20
|
+
parallel (~> 1.10)
|
|
21
|
+
parser (>= 3.3.0.2)
|
|
22
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
23
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
24
|
+
rubocop-ast (>= 1.48.0, < 2.0)
|
|
25
|
+
ruby-progressbar (~> 1.7)
|
|
26
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
27
|
+
rubocop-ast (1.49.0)
|
|
28
|
+
parser (>= 3.3.7.2)
|
|
29
|
+
prism (~> 1.7)
|
|
30
|
+
rubocop-minitest (0.39.1)
|
|
31
|
+
lint_roller (~> 1.1)
|
|
32
|
+
rubocop (>= 1.75.0, < 2.0)
|
|
33
|
+
rubocop-ast (>= 1.38.0, < 2.0)
|
|
34
|
+
rubocop-performance (1.26.1)
|
|
35
|
+
lint_roller (~> 1.1)
|
|
36
|
+
rubocop (>= 1.75.0, < 2.0)
|
|
37
|
+
rubocop-ast (>= 1.47.1, < 2.0)
|
|
38
|
+
rubocop-thread_safety (0.7.3)
|
|
39
|
+
lint_roller (~> 1.1)
|
|
40
|
+
rubocop (~> 1.72, >= 1.72.1)
|
|
41
|
+
rubocop-ast (>= 1.44.0, < 2.0)
|
|
42
|
+
ruby-progressbar (1.13.0)
|
|
43
|
+
standard (1.53.0)
|
|
44
|
+
language_server-protocol (~> 3.17.0.2)
|
|
45
|
+
lint_roller (~> 1.0)
|
|
46
|
+
rubocop (~> 1.82.0)
|
|
47
|
+
standard-custom (~> 1.0.0)
|
|
48
|
+
standard-performance (~> 1.8)
|
|
49
|
+
standard-custom (1.0.2)
|
|
50
|
+
lint_roller (~> 1.0)
|
|
51
|
+
rubocop (~> 1.50)
|
|
52
|
+
standard-minitest (1.0.0)
|
|
53
|
+
lint_roller (~> 1.0)
|
|
54
|
+
rubocop-minitest
|
|
55
|
+
standard-performance (1.9.0)
|
|
56
|
+
lint_roller (~> 1.1)
|
|
57
|
+
rubocop-performance (~> 1.26.0)
|
|
58
|
+
unicode-display_width (3.2.0)
|
|
59
|
+
unicode-emoji (~> 4.1)
|
|
60
|
+
unicode-emoji (4.2.0)
|
|
61
|
+
yard (0.9.38)
|
|
62
|
+
yard-lint (1.4.0)
|
|
63
|
+
yard (~> 0.9)
|
|
64
|
+
zeitwerk (~> 2.6)
|
|
65
|
+
zeitwerk (2.7.4)
|
|
66
|
+
|
|
67
|
+
PLATFORMS
|
|
68
|
+
ruby
|
|
69
|
+
x86_64-linux
|
|
70
|
+
|
|
71
|
+
DEPENDENCIES
|
|
72
|
+
rubocop-minitest
|
|
73
|
+
rubocop-performance
|
|
74
|
+
rubocop-thread_safety
|
|
75
|
+
standard
|
|
76
|
+
standard-minitest
|
|
77
|
+
standard-performance
|
|
78
|
+
yard-lint
|
|
79
|
+
|
|
80
|
+
CHECKSUMS
|
|
81
|
+
ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
|
|
82
|
+
json (2.18.0) sha256=b10506aee4183f5cf49e0efc48073d7b75843ce3782c68dbeb763351c08fd505
|
|
83
|
+
language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
|
|
84
|
+
lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
|
|
85
|
+
parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130
|
|
86
|
+
parser (3.3.10.1) sha256=06f6a725d2cd91e5e7f2b7c32ba143631e1f7c8ae2fb918fc4cebec187e6a688
|
|
87
|
+
prism (1.8.0) sha256=84453a16ef5530ea62c5f03ec16b52a459575ad4e7b9c2b360fd8ce2c39c1254
|
|
88
|
+
racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
|
|
89
|
+
rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
|
|
90
|
+
regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4
|
|
91
|
+
rubocop (1.82.1) sha256=09f1a6a654a960eda767aebea33e47603080f8e9c9a3f019bf9b94c9cab5e273
|
|
92
|
+
rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd
|
|
93
|
+
rubocop-minitest (0.39.1) sha256=998398d6da4026d297f0f9bf709a1eac5f2b6947c24431f94af08138510cf7ed
|
|
94
|
+
rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834
|
|
95
|
+
rubocop-thread_safety (0.7.3) sha256=067cdd52fbf5deffc18995437e45b5194236eaff4f71de3375a1f6052e48f431
|
|
96
|
+
ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
|
|
97
|
+
standard (1.53.0) sha256=f3c9493385db7079d0abce6f7582f553122156997b81258cd361d3480eeacf9c
|
|
98
|
+
standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b
|
|
99
|
+
standard-minitest (1.0.0) sha256=450caa86a64a6e6f6f186cc88601dbb49b6cfaa3b0dce77a73b50ba8cdc15b2a
|
|
100
|
+
standard-performance (1.9.0) sha256=49483d31be448292951d80e5e67cdcb576c2502103c7b40aec6f1b6e9c88e3f2
|
|
101
|
+
unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42
|
|
102
|
+
unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f
|
|
103
|
+
yard (0.9.38) sha256=721fb82afb10532aa49860655f6cc2eaa7130889df291b052e1e6b268283010f
|
|
104
|
+
yard-lint (1.4.0) sha256=7dd88fbb08fd77cb840bea899d58812817b36d92291b5693dd0eeb3af9f91f0f
|
|
105
|
+
zeitwerk (2.7.4) sha256=2bef90f356bdafe9a6c2bd32bcd804f83a4f9b8bc27f3600fff051eb3edcec8b
|
|
106
|
+
|
|
107
|
+
BUNDLED WITH
|
|
108
|
+
4.0.3
|
data/Gemfile.lock
CHANGED
|
@@ -1,46 +1,77 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
karafka-testing (2.5.
|
|
4
|
+
karafka-testing (2.5.6)
|
|
5
5
|
karafka (>= 2.5.0, < 2.6.0)
|
|
6
6
|
waterdrop (>= 2.8.0)
|
|
7
7
|
|
|
8
8
|
GEM
|
|
9
9
|
remote: https://rubygems.org/
|
|
10
10
|
specs:
|
|
11
|
-
base64 (0.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
base64 (0.3.0)
|
|
12
|
+
diff-lcs (1.6.2)
|
|
13
|
+
docile (1.4.1)
|
|
14
|
+
drb (2.2.3)
|
|
15
|
+
ffi (1.17.3)
|
|
16
|
+
ffi (1.17.3-x86_64-linux-gnu)
|
|
17
|
+
json (2.19.2)
|
|
18
|
+
karafka (2.5.1)
|
|
16
19
|
base64 (~> 0.2)
|
|
17
|
-
karafka-core (>= 2.5.
|
|
18
|
-
karafka-rdkafka (>= 0.
|
|
19
|
-
waterdrop (>= 2.8.
|
|
20
|
+
karafka-core (>= 2.5.6, < 2.6.0)
|
|
21
|
+
karafka-rdkafka (>= 0.22.0)
|
|
22
|
+
waterdrop (>= 2.8.9, < 3.0.0)
|
|
20
23
|
zeitwerk (~> 2.3)
|
|
21
|
-
karafka-core (2.5.
|
|
24
|
+
karafka-core (2.5.10)
|
|
22
25
|
karafka-rdkafka (>= 0.20.0)
|
|
23
26
|
logger (>= 1.6.0)
|
|
24
|
-
karafka-rdkafka (0.
|
|
25
|
-
ffi (~> 1.
|
|
27
|
+
karafka-rdkafka (0.24.0)
|
|
28
|
+
ffi (~> 1.17.1)
|
|
26
29
|
json (> 2.0)
|
|
27
30
|
logger
|
|
28
31
|
mini_portile2 (~> 2.6)
|
|
29
32
|
rake (> 12)
|
|
30
|
-
karafka-rdkafka (0.
|
|
31
|
-
ffi (~> 1.
|
|
33
|
+
karafka-rdkafka (0.24.0-x86_64-linux-gnu)
|
|
34
|
+
ffi (~> 1.17.1)
|
|
32
35
|
json (> 2.0)
|
|
33
36
|
logger
|
|
34
37
|
mini_portile2 (~> 2.6)
|
|
35
38
|
rake (> 12)
|
|
36
39
|
logger (1.7.0)
|
|
37
|
-
mini_portile2 (2.8.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
mini_portile2 (2.8.9)
|
|
41
|
+
minitest (6.0.2)
|
|
42
|
+
drb (~> 2.0)
|
|
43
|
+
prism (~> 1.5)
|
|
44
|
+
mocha (3.1.0)
|
|
45
|
+
ruby2_keywords (>= 0.0.5)
|
|
46
|
+
ostruct (0.6.3)
|
|
47
|
+
prism (1.9.0)
|
|
48
|
+
rake (13.3.1)
|
|
49
|
+
rspec (3.13.2)
|
|
50
|
+
rspec-core (~> 3.13.0)
|
|
51
|
+
rspec-expectations (~> 3.13.0)
|
|
52
|
+
rspec-mocks (~> 3.13.0)
|
|
53
|
+
rspec-core (3.13.6)
|
|
54
|
+
rspec-support (~> 3.13.0)
|
|
55
|
+
rspec-expectations (3.13.5)
|
|
56
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
57
|
+
rspec-support (~> 3.13.0)
|
|
58
|
+
rspec-mocks (3.13.7)
|
|
59
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
60
|
+
rspec-support (~> 3.13.0)
|
|
61
|
+
rspec-support (3.13.6)
|
|
62
|
+
ruby2_keywords (0.0.5)
|
|
63
|
+
simplecov (0.22.0)
|
|
64
|
+
docile (~> 1.1)
|
|
65
|
+
simplecov-html (~> 0.11)
|
|
66
|
+
simplecov_json_formatter (~> 0.1)
|
|
67
|
+
simplecov-html (0.13.2)
|
|
68
|
+
simplecov_json_formatter (0.1.4)
|
|
69
|
+
warning (1.5.0)
|
|
70
|
+
waterdrop (2.8.12)
|
|
40
71
|
karafka-core (>= 2.4.9, < 3.0.0)
|
|
41
|
-
karafka-rdkafka (>= 0.
|
|
72
|
+
karafka-rdkafka (>= 0.20.0)
|
|
42
73
|
zeitwerk (~> 2.3)
|
|
43
|
-
zeitwerk (2.
|
|
74
|
+
zeitwerk (2.7.3)
|
|
44
75
|
|
|
45
76
|
PLATFORMS
|
|
46
77
|
ruby
|
|
@@ -48,6 +79,12 @@ PLATFORMS
|
|
|
48
79
|
|
|
49
80
|
DEPENDENCIES
|
|
50
81
|
karafka-testing!
|
|
82
|
+
minitest
|
|
83
|
+
mocha
|
|
84
|
+
ostruct
|
|
85
|
+
rspec
|
|
86
|
+
simplecov
|
|
87
|
+
warning
|
|
51
88
|
|
|
52
89
|
BUNDLED WITH
|
|
53
90
|
2.6.3
|
data/Rakefile
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "bundler/gem_tasks"
|
|
5
|
+
|
|
6
|
+
require "rake/testtask"
|
|
7
|
+
|
|
8
|
+
Rake::TestTask.new(:test) do |t|
|
|
9
|
+
t.libs << "test"
|
|
10
|
+
t.test_files = FileList["test/test_helper.rb", "test/**/*_test.rb"]
|
|
11
|
+
.exclude("test/integration/**/*")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
task default: :test
|
data/karafka-testing.gemspec
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
lib = File.expand_path(
|
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
|
|
6
|
-
require
|
|
6
|
+
require "karafka/testing/version"
|
|
7
7
|
|
|
8
8
|
Gem::Specification.new do |spec|
|
|
9
|
-
spec.name
|
|
10
|
-
spec.platform
|
|
11
|
-
spec.version
|
|
12
|
-
spec.authors
|
|
13
|
-
spec.email
|
|
14
|
-
spec.summary
|
|
15
|
-
spec.description
|
|
16
|
-
spec.homepage
|
|
17
|
-
spec.license
|
|
18
|
-
spec.files
|
|
19
|
-
spec.executables
|
|
9
|
+
spec.name = "karafka-testing"
|
|
10
|
+
spec.platform = Gem::Platform::RUBY
|
|
11
|
+
spec.version = Karafka::Testing::VERSION
|
|
12
|
+
spec.authors = ["Maciej Mensfeld"]
|
|
13
|
+
spec.email = %w[contact@karafka.io]
|
|
14
|
+
spec.summary = "Library which provides helpers for easier Karafka consumers tests"
|
|
15
|
+
spec.description = "Library which provides helpers for easier Karafka consumers tests"
|
|
16
|
+
spec.homepage = "https://karafka.io"
|
|
17
|
+
spec.license = "MIT"
|
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test)/}) }
|
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
20
20
|
spec.require_paths = %w[lib]
|
|
21
21
|
|
|
22
|
-
spec.add_dependency
|
|
23
|
-
spec.add_dependency
|
|
22
|
+
spec.add_dependency "karafka", ">= 2.5.0", "< 2.6.0"
|
|
23
|
+
spec.add_dependency "waterdrop", ">= 2.8.0"
|
|
24
24
|
|
|
25
|
-
spec.required_ruby_version =
|
|
25
|
+
spec.required_ruby_version = ">= 3.2.0"
|
|
26
26
|
|
|
27
27
|
spec.metadata = {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
"homepage_uri" => "https://karafka.io",
|
|
29
|
+
"changelog_uri" => "https://karafka.io/docs/Changelog-Karafka-Testing",
|
|
30
|
+
"bug_tracker_uri" => "https://github.com/karafka/karafka-testing/issues",
|
|
31
|
+
"source_code_uri" => "https://github.com/karafka/karafka-testing",
|
|
32
|
+
"documentation_uri" => "https://karafka.io/docs",
|
|
33
|
+
"rubygems_mfa_required" => "true"
|
|
34
34
|
}
|
|
35
35
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
3
|
+
require "karafka/testing"
|
|
4
|
+
require "karafka/testing/errors"
|
|
5
|
+
require "karafka/testing/helpers"
|
|
6
|
+
require "karafka/testing/spec_consumer_client"
|
|
7
|
+
require "karafka/testing/spec_producer_client"
|
|
8
|
+
require "karafka/testing/minitest/proxy"
|
|
9
9
|
|
|
10
10
|
module Karafka
|
|
11
11
|
module Testing
|
|
@@ -42,14 +42,23 @@ module Karafka
|
|
|
42
42
|
Karafka.producer.stubs(:client).returns(@_karafka_producer_client)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
if base.to_s ==
|
|
45
|
+
if base.to_s == "Minitest::Spec"
|
|
46
46
|
base.class_eval do
|
|
47
47
|
before(&eval_flow)
|
|
48
48
|
end
|
|
49
|
-
|
|
49
|
+
elsif base.respond_to?(:setup) && base.method(:setup).arity != 0
|
|
50
50
|
base.class_eval do
|
|
51
51
|
setup(&eval_flow)
|
|
52
52
|
end
|
|
53
|
+
else
|
|
54
|
+
setup_mod = Module.new do
|
|
55
|
+
define_method(:setup) do
|
|
56
|
+
instance_exec(&eval_flow)
|
|
57
|
+
super()
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
base.prepend(setup_mod)
|
|
53
62
|
end
|
|
54
63
|
end
|
|
55
64
|
end
|
|
@@ -89,11 +98,13 @@ module Karafka
|
|
|
89
98
|
# @example Send a json message to consumer and simulate, that it is partition 6
|
|
90
99
|
# @karafka.produce({ 'hello' => 'world' }.to_json, 'partition' => 6)
|
|
91
100
|
def _karafka_add_message_to_consumer_if_needed(message)
|
|
92
|
-
consumer_obj = if
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
101
|
+
consumer_obj = if message[:consumer_group]
|
|
102
|
+
_karafka_find_consumer_for_message(message)
|
|
103
|
+
elsif defined?(@consumer)
|
|
104
|
+
@consumer
|
|
105
|
+
else
|
|
106
|
+
_karafka_find_consumer_for_message(message)
|
|
107
|
+
end
|
|
97
108
|
# Consumer needs to be defined in order to pass messages to it
|
|
98
109
|
return unless defined?(consumer_obj)
|
|
99
110
|
# We're interested in adding message to consumer only when it is a Karafka consumer
|
|
@@ -103,6 +114,9 @@ module Karafka
|
|
|
103
114
|
# We target to the consumer only messages that were produced to it, since specs may also
|
|
104
115
|
# produce other messages targeting other topics
|
|
105
116
|
return unless message[:topic] == consumer_obj.topic.name
|
|
117
|
+
# If consumer_group is explicitly specified, verify it matches
|
|
118
|
+
return if message[:consumer_group] &&
|
|
119
|
+
message[:consumer_group].to_s != consumer_obj.topic.consumer_group.name
|
|
106
120
|
|
|
107
121
|
# Build message metadata and copy any metadata that would come from the message
|
|
108
122
|
metadata = _karafka_message_metadata_defaults(consumer_obj)
|
|
@@ -137,21 +151,30 @@ module Karafka
|
|
|
137
151
|
|
|
138
152
|
# Produces message with a given payload to the consumer matching topic
|
|
139
153
|
# @param payload [String] payload we want to dispatch
|
|
140
|
-
# @param metadata [Hash] any metadata we want to dispatch alongside the payload
|
|
154
|
+
# @param metadata [Hash] any metadata we want to dispatch alongside the payload.
|
|
155
|
+
# Supports an `offset` key to set a custom offset for the message (otherwise
|
|
156
|
+
# offsets auto-increment from 0).
|
|
141
157
|
def _karafka_produce(payload, metadata = {})
|
|
158
|
+
# Extract offset before passing to WaterDrop since it is not a valid
|
|
159
|
+
# WaterDrop message attribute (Kafka assigns offsets, not producers)
|
|
160
|
+
@_karafka_next_offset = metadata.delete(:offset)
|
|
161
|
+
|
|
142
162
|
topic = if metadata[:topic]
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
163
|
+
metadata[:topic]
|
|
164
|
+
elsif defined?(@consumer)
|
|
165
|
+
@consumer.topic.name
|
|
166
|
+
else
|
|
167
|
+
last_consumer = @_karafka_consumer_mappings&.values&.last
|
|
168
|
+
last_consumer&.topic&.name
|
|
169
|
+
end
|
|
149
170
|
Karafka.producer.produce_sync(
|
|
150
171
|
{
|
|
151
172
|
topic: topic,
|
|
152
173
|
payload: payload
|
|
153
174
|
}.merge(metadata)
|
|
154
175
|
)
|
|
176
|
+
ensure
|
|
177
|
+
@_karafka_next_offset = nil
|
|
155
178
|
end
|
|
156
179
|
|
|
157
180
|
# @return [Array<Hash>] messages that were produced
|
|
@@ -165,8 +188,52 @@ module Karafka
|
|
|
165
188
|
@_karafka_consumer_messages
|
|
166
189
|
end
|
|
167
190
|
|
|
191
|
+
# Produces message to a specific consumer instance
|
|
192
|
+
# Use when testing multiple consumers for the same topic
|
|
193
|
+
#
|
|
194
|
+
# @param consumer_instance [Object] the consumer to produce to
|
|
195
|
+
# @param payload [String] message content (usually serialized JSON) to deliver to the
|
|
196
|
+
# consumer
|
|
197
|
+
# @param metadata [Hash] any metadata to dispatch alongside the payload
|
|
198
|
+
#
|
|
199
|
+
# @example Produce to specific consumer when multiple exist for same topic
|
|
200
|
+
# consumer1 = @karafka.consumer_for(:events, :analytics_group)
|
|
201
|
+
# consumer2 = @karafka.consumer_for(:events, :notifications_group)
|
|
202
|
+
# @karafka.produce_to(consumer1, { 'event' => 'click' }.to_json)
|
|
203
|
+
def _karafka_produce_to(consumer_instance, payload, metadata = {})
|
|
204
|
+
_karafka_produce(
|
|
205
|
+
payload,
|
|
206
|
+
metadata.merge(
|
|
207
|
+
topic: consumer_instance.topic.name,
|
|
208
|
+
consumer_group: consumer_instance.topic.consumer_group.name
|
|
209
|
+
)
|
|
210
|
+
)
|
|
211
|
+
end
|
|
212
|
+
|
|
168
213
|
private
|
|
169
214
|
|
|
215
|
+
# Finds a consumer for the given message with backward-compatible fallback
|
|
216
|
+
# @param message [Hash] the message being routed
|
|
217
|
+
# @return [Object, nil] the consumer instance or nil
|
|
218
|
+
def _karafka_find_consumer_for_message(message)
|
|
219
|
+
return nil unless @_karafka_consumer_mappings
|
|
220
|
+
|
|
221
|
+
topic_name = message[:topic]
|
|
222
|
+
consumer_group = message[:consumer_group]
|
|
223
|
+
|
|
224
|
+
if consumer_group
|
|
225
|
+
# Explicit consumer group - find by composite key pattern
|
|
226
|
+
@_karafka_consumer_mappings.values.find do |c|
|
|
227
|
+
c.topic.name == topic_name && c.topic.consumer_group.name == consumer_group.to_s
|
|
228
|
+
end
|
|
229
|
+
else
|
|
230
|
+
# No consumer group specified - find all consumers for this topic
|
|
231
|
+
matching = @_karafka_consumer_mappings.values.select { |c| c.topic.name == topic_name }
|
|
232
|
+
# If exactly one consumer matches, use it (backward compatible)
|
|
233
|
+
(matching.size == 1) ? matching.first : nil
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
170
237
|
# @param consumer_obj [Karafka::BaseConsumer] consumer reference
|
|
171
238
|
# @return [Hash] message default options
|
|
172
239
|
def _karafka_message_metadata_defaults(consumer_obj)
|
|
@@ -175,7 +242,7 @@ module Karafka
|
|
|
175
242
|
timestamp: Time.now,
|
|
176
243
|
raw_headers: {},
|
|
177
244
|
raw_key: nil,
|
|
178
|
-
offset: @_karafka_consumer_messages.size,
|
|
245
|
+
offset: @_karafka_next_offset.nil? ? @_karafka_consumer_messages.size : @_karafka_next_offset,
|
|
179
246
|
partition: 0,
|
|
180
247
|
received_at: Time.now,
|
|
181
248
|
topic: consumer_obj.topic.name
|
|
@@ -200,10 +267,10 @@ module Karafka
|
|
|
200
267
|
@consumer.coordinator = coordinators.find_or_create(topic.name, 0)
|
|
201
268
|
@consumer.coordinator.seek_offset = 0
|
|
202
269
|
# Indicate usage as for tests no direct enqueuing happens
|
|
203
|
-
@consumer.instance_variable_set(
|
|
270
|
+
@consumer.instance_variable_set(:@used, true)
|
|
204
271
|
expansions = processing_cfg.expansions_selector.find(topic)
|
|
205
272
|
expansions.each { |expansion| @consumer.singleton_class.include(expansion) }
|
|
206
|
-
@_karafka_consumer_mappings[topic.
|
|
273
|
+
@_karafka_consumer_mappings[topic.id] = @consumer
|
|
207
274
|
@consumer
|
|
208
275
|
end
|
|
209
276
|
end
|
|
@@ -11,14 +11,19 @@ module Karafka
|
|
|
11
11
|
@minitest_example = minitest_example
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
#
|
|
15
|
-
def consumer_for(*
|
|
16
|
-
@minitest_example._karafka_consumer_for(*
|
|
14
|
+
# Forwards all arguments to `#_karafka_consumer_for`
|
|
15
|
+
def consumer_for(*)
|
|
16
|
+
@minitest_example._karafka_consumer_for(*)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
#
|
|
20
|
-
def produce(*
|
|
21
|
-
@minitest_example._karafka_produce(*
|
|
19
|
+
# Forwards all arguments to `#_karafka_produce`
|
|
20
|
+
def produce(*)
|
|
21
|
+
@minitest_example._karafka_produce(*)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Forwards all arguments to `#_karafka_produce_to`
|
|
25
|
+
def produce_to(*)
|
|
26
|
+
@minitest_example._karafka_produce_to(*)
|
|
22
27
|
end
|
|
23
28
|
|
|
24
29
|
# @return [Array<Hash>] messages produced via `Karafka#producer`
|