karafka-rdkafka 0.20.0.rc3-x86_64-linux-gnu

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 (99) hide show
  1. checksums.yaml +7 -0
  2. data/.github/CODEOWNERS +3 -0
  3. data/.github/FUNDING.yml +1 -0
  4. data/.github/workflows/ci_linux_x86_64_gnu.yml +248 -0
  5. data/.github/workflows/ci_macos_arm64.yml +301 -0
  6. data/.github/workflows/push_linux_x86_64_gnu.yml +60 -0
  7. data/.github/workflows/push_ruby.yml +37 -0
  8. data/.github/workflows/verify-action-pins.yml +16 -0
  9. data/.gitignore +15 -0
  10. data/.rspec +2 -0
  11. data/.ruby-gemset +1 -0
  12. data/.ruby-version +1 -0
  13. data/.yardopts +2 -0
  14. data/CHANGELOG.md +323 -0
  15. data/Gemfile +5 -0
  16. data/MIT-LICENSE +22 -0
  17. data/README.md +177 -0
  18. data/Rakefile +96 -0
  19. data/docker-compose.yml +25 -0
  20. data/ext/README.md +19 -0
  21. data/ext/Rakefile +131 -0
  22. data/ext/build_common.sh +361 -0
  23. data/ext/build_linux_x86_64_gnu.sh +306 -0
  24. data/ext/build_macos_arm64.sh +550 -0
  25. data/ext/librdkafka.so +0 -0
  26. data/karafka-rdkafka.gemspec +61 -0
  27. data/lib/rdkafka/abstract_handle.rb +116 -0
  28. data/lib/rdkafka/admin/acl_binding_result.rb +51 -0
  29. data/lib/rdkafka/admin/config_binding_result.rb +30 -0
  30. data/lib/rdkafka/admin/config_resource_binding_result.rb +18 -0
  31. data/lib/rdkafka/admin/create_acl_handle.rb +28 -0
  32. data/lib/rdkafka/admin/create_acl_report.rb +24 -0
  33. data/lib/rdkafka/admin/create_partitions_handle.rb +30 -0
  34. data/lib/rdkafka/admin/create_partitions_report.rb +6 -0
  35. data/lib/rdkafka/admin/create_topic_handle.rb +32 -0
  36. data/lib/rdkafka/admin/create_topic_report.rb +24 -0
  37. data/lib/rdkafka/admin/delete_acl_handle.rb +30 -0
  38. data/lib/rdkafka/admin/delete_acl_report.rb +23 -0
  39. data/lib/rdkafka/admin/delete_groups_handle.rb +28 -0
  40. data/lib/rdkafka/admin/delete_groups_report.rb +24 -0
  41. data/lib/rdkafka/admin/delete_topic_handle.rb +32 -0
  42. data/lib/rdkafka/admin/delete_topic_report.rb +24 -0
  43. data/lib/rdkafka/admin/describe_acl_handle.rb +30 -0
  44. data/lib/rdkafka/admin/describe_acl_report.rb +24 -0
  45. data/lib/rdkafka/admin/describe_configs_handle.rb +33 -0
  46. data/lib/rdkafka/admin/describe_configs_report.rb +48 -0
  47. data/lib/rdkafka/admin/incremental_alter_configs_handle.rb +33 -0
  48. data/lib/rdkafka/admin/incremental_alter_configs_report.rb +48 -0
  49. data/lib/rdkafka/admin.rb +832 -0
  50. data/lib/rdkafka/bindings.rb +582 -0
  51. data/lib/rdkafka/callbacks.rb +415 -0
  52. data/lib/rdkafka/config.rb +398 -0
  53. data/lib/rdkafka/consumer/headers.rb +79 -0
  54. data/lib/rdkafka/consumer/message.rb +86 -0
  55. data/lib/rdkafka/consumer/partition.rb +57 -0
  56. data/lib/rdkafka/consumer/topic_partition_list.rb +190 -0
  57. data/lib/rdkafka/consumer.rb +663 -0
  58. data/lib/rdkafka/error.rb +201 -0
  59. data/lib/rdkafka/helpers/oauth.rb +58 -0
  60. data/lib/rdkafka/helpers/time.rb +14 -0
  61. data/lib/rdkafka/metadata.rb +115 -0
  62. data/lib/rdkafka/native_kafka.rb +139 -0
  63. data/lib/rdkafka/producer/delivery_handle.rb +48 -0
  64. data/lib/rdkafka/producer/delivery_report.rb +45 -0
  65. data/lib/rdkafka/producer/partitions_count_cache.rb +216 -0
  66. data/lib/rdkafka/producer.rb +492 -0
  67. data/lib/rdkafka/version.rb +7 -0
  68. data/lib/rdkafka.rb +54 -0
  69. data/renovate.json +92 -0
  70. data/spec/rdkafka/abstract_handle_spec.rb +117 -0
  71. data/spec/rdkafka/admin/create_acl_handle_spec.rb +56 -0
  72. data/spec/rdkafka/admin/create_acl_report_spec.rb +18 -0
  73. data/spec/rdkafka/admin/create_topic_handle_spec.rb +54 -0
  74. data/spec/rdkafka/admin/create_topic_report_spec.rb +16 -0
  75. data/spec/rdkafka/admin/delete_acl_handle_spec.rb +85 -0
  76. data/spec/rdkafka/admin/delete_acl_report_spec.rb +72 -0
  77. data/spec/rdkafka/admin/delete_topic_handle_spec.rb +54 -0
  78. data/spec/rdkafka/admin/delete_topic_report_spec.rb +16 -0
  79. data/spec/rdkafka/admin/describe_acl_handle_spec.rb +85 -0
  80. data/spec/rdkafka/admin/describe_acl_report_spec.rb +73 -0
  81. data/spec/rdkafka/admin_spec.rb +769 -0
  82. data/spec/rdkafka/bindings_spec.rb +222 -0
  83. data/spec/rdkafka/callbacks_spec.rb +20 -0
  84. data/spec/rdkafka/config_spec.rb +258 -0
  85. data/spec/rdkafka/consumer/headers_spec.rb +73 -0
  86. data/spec/rdkafka/consumer/message_spec.rb +139 -0
  87. data/spec/rdkafka/consumer/partition_spec.rb +57 -0
  88. data/spec/rdkafka/consumer/topic_partition_list_spec.rb +248 -0
  89. data/spec/rdkafka/consumer_spec.rb +1299 -0
  90. data/spec/rdkafka/error_spec.rb +95 -0
  91. data/spec/rdkafka/metadata_spec.rb +79 -0
  92. data/spec/rdkafka/native_kafka_spec.rb +130 -0
  93. data/spec/rdkafka/producer/delivery_handle_spec.rb +60 -0
  94. data/spec/rdkafka/producer/delivery_report_spec.rb +25 -0
  95. data/spec/rdkafka/producer/partitions_count_cache_spec.rb +359 -0
  96. data/spec/rdkafka/producer/partitions_count_spec.rb +359 -0
  97. data/spec/rdkafka/producer_spec.rb +1234 -0
  98. data/spec/spec_helper.rb +181 -0
  99. metadata +244 -0
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rdkafka
4
+ VERSION = "0.20.0.rc3"
5
+ LIBRDKAFKA_VERSION = "2.8.0"
6
+ LIBRDKAFKA_SOURCE_SHA256 = "5bd1c46f63265f31c6bfcedcde78703f77d28238eadf23821c2b43fc30be3e25"
7
+ end
data/lib/rdkafka.rb ADDED
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "logger"
4
+ require "objspace"
5
+ require "ffi"
6
+ require "json"
7
+
8
+ require "rdkafka/version"
9
+ require "rdkafka/helpers/time"
10
+ require "rdkafka/helpers/oauth"
11
+ require "rdkafka/abstract_handle"
12
+ require "rdkafka/admin"
13
+ require "rdkafka/admin/create_topic_handle"
14
+ require "rdkafka/admin/create_topic_report"
15
+ require "rdkafka/admin/delete_groups_handle"
16
+ require "rdkafka/admin/delete_groups_report"
17
+ require "rdkafka/admin/delete_topic_handle"
18
+ require "rdkafka/admin/delete_topic_report"
19
+ require "rdkafka/admin/create_partitions_handle"
20
+ require "rdkafka/admin/create_partitions_report"
21
+ require "rdkafka/admin/create_acl_handle"
22
+ require "rdkafka/admin/create_acl_report"
23
+ require "rdkafka/admin/delete_acl_handle"
24
+ require "rdkafka/admin/delete_acl_report"
25
+ require "rdkafka/admin/describe_acl_handle"
26
+ require "rdkafka/admin/describe_acl_report"
27
+ require "rdkafka/admin/describe_configs_handle"
28
+ require "rdkafka/admin/describe_configs_report"
29
+ require "rdkafka/admin/incremental_alter_configs_handle"
30
+ require "rdkafka/admin/incremental_alter_configs_report"
31
+ require "rdkafka/admin/acl_binding_result"
32
+ require "rdkafka/admin/config_binding_result"
33
+ require "rdkafka/admin/config_resource_binding_result"
34
+ require "rdkafka/bindings"
35
+ require "rdkafka/callbacks"
36
+ require "rdkafka/config"
37
+ require "rdkafka/consumer"
38
+ require "rdkafka/consumer/headers"
39
+ require "rdkafka/consumer/message"
40
+ require "rdkafka/consumer/partition"
41
+ require "rdkafka/consumer/topic_partition_list"
42
+ require "rdkafka/error"
43
+ require "rdkafka/metadata"
44
+ require "rdkafka/native_kafka"
45
+ require "rdkafka/producer/partitions_count_cache"
46
+ require "rdkafka/producer"
47
+ require "rdkafka/producer/delivery_handle"
48
+ require "rdkafka/producer/delivery_report"
49
+
50
+ # Main Rdkafka namespace of this gem
51
+ module Rdkafka
52
+ end
53
+
54
+ Rdkafka::Bindings.rd_kafka_global_init
data/renovate.json ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": [
4
+ "config:recommended"
5
+ ],
6
+ "github-actions": {
7
+ "enabled": true,
8
+ "pinDigests": true
9
+ },
10
+ "packageRules": [
11
+ {
12
+ "matchManagers": [
13
+ "github-actions"
14
+ ],
15
+ "minimumReleaseAge": "7 days"
16
+ }
17
+ ],
18
+ "customManagers": [
19
+ {
20
+ "customType": "regex",
21
+ "managerFilePatterns": [
22
+ "/^ext/build_common\\.sh$/"
23
+ ],
24
+ "matchStrings": [
25
+ "readonly OPENSSL_VERSION=\"(?<currentValue>.*)\""
26
+ ],
27
+ "depNameTemplate": "openssl/openssl",
28
+ "datasourceTemplate": "github-releases",
29
+ "extractVersionTemplate": "^OpenSSL_(?<version>.*)$"
30
+ },
31
+ {
32
+ "customType": "regex",
33
+ "managerFilePatterns": [
34
+ "/^ext/build_common\\.sh$/"
35
+ ],
36
+ "matchStrings": [
37
+ "readonly CYRUS_SASL_VERSION=\"(?<currentValue>.*)\""
38
+ ],
39
+ "depNameTemplate": "cyrusimap/cyrus-sasl",
40
+ "datasourceTemplate": "github-releases",
41
+ "extractVersionTemplate": "^cyrus-sasl-(?<version>.*)$"
42
+ },
43
+ {
44
+ "customType": "regex",
45
+ "managerFilePatterns": [
46
+ "/^ext/build_common\\.sh$/"
47
+ ],
48
+ "matchStrings": [
49
+ "readonly ZLIB_VERSION=\"(?<currentValue>.*)\""
50
+ ],
51
+ "depNameTemplate": "madler/zlib",
52
+ "datasourceTemplate": "github-releases",
53
+ "extractVersionTemplate": "^v(?<version>.*)$"
54
+ },
55
+ {
56
+ "customType": "regex",
57
+ "managerFilePatterns": [
58
+ "/^ext/build_common\\.sh$/"
59
+ ],
60
+ "matchStrings": [
61
+ "readonly ZSTD_VERSION=\"(?<currentValue>.*)\""
62
+ ],
63
+ "depNameTemplate": "facebook/zstd",
64
+ "datasourceTemplate": "github-releases",
65
+ "extractVersionTemplate": "^v(?<version>.*)$"
66
+ },
67
+ {
68
+ "customType": "regex",
69
+ "managerFilePatterns": [
70
+ "/^ext/build_common\\.sh$/"
71
+ ],
72
+ "matchStrings": [
73
+ "readonly KRB5_VERSION=\"(?<currentValue>.*)\""
74
+ ],
75
+ "depNameTemplate": "krb5/krb5",
76
+ "datasourceTemplate": "github-releases",
77
+ "extractVersionTemplate": "^krb5-(?<version>.*)$"
78
+ },
79
+ {
80
+ "customType": "regex",
81
+ "managerFilePatterns": [
82
+ "/^ext/build_common\\.sh$/"
83
+ ],
84
+ "matchStrings": [
85
+ "readonly LIBRDKAFKA_VERSION=\"(?<currentValue>.*)\""
86
+ ],
87
+ "depNameTemplate": "confluentinc/librdkafka",
88
+ "datasourceTemplate": "github-releases",
89
+ "extractVersionTemplate": "^v(?<version>.*)$"
90
+ }
91
+ ]
92
+ }
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Rdkafka::AbstractHandle do
4
+ let(:response) { 0 }
5
+ let(:result) { -1 }
6
+
7
+ context "A subclass that does not implement the required methods" do
8
+
9
+ class BadTestHandle < Rdkafka::AbstractHandle
10
+ layout :pending, :bool,
11
+ :response, :int
12
+ end
13
+
14
+ it "raises an exception if operation_name is called" do
15
+ expect {
16
+ BadTestHandle.new.operation_name
17
+ }.to raise_exception(RuntimeError, /Must be implemented by subclass!/)
18
+ end
19
+
20
+ it "raises an exception if create_result is called" do
21
+ expect {
22
+ BadTestHandle.new.create_result
23
+ }.to raise_exception(RuntimeError, /Must be implemented by subclass!/)
24
+ end
25
+ end
26
+
27
+ class TestHandle < Rdkafka::AbstractHandle
28
+ layout :pending, :bool,
29
+ :response, :int,
30
+ :result, :int
31
+
32
+ def operation_name
33
+ "test_operation"
34
+ end
35
+
36
+ def create_result
37
+ self[:result]
38
+ end
39
+ end
40
+
41
+ subject do
42
+ TestHandle.new.tap do |handle|
43
+ handle[:pending] = pending_handle
44
+ handle[:response] = response
45
+ handle[:result] = result
46
+ end
47
+ end
48
+
49
+ describe ".register and .remove" do
50
+ let(:pending_handle) { true }
51
+
52
+ it "should register and remove a delivery handle" do
53
+ Rdkafka::AbstractHandle.register(subject)
54
+ removed = Rdkafka::AbstractHandle.remove(subject.to_ptr.address)
55
+ expect(removed).to eq subject
56
+ expect(Rdkafka::AbstractHandle::REGISTRY).to be_empty
57
+ end
58
+ end
59
+
60
+ describe "#pending?" do
61
+ context "when true" do
62
+ let(:pending_handle) { true }
63
+
64
+ it "should be true" do
65
+ expect(subject.pending?).to be true
66
+ end
67
+ end
68
+
69
+ context "when not true" do
70
+ let(:pending_handle) { false }
71
+
72
+ it "should be false" do
73
+ expect(subject.pending?).to be false
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "#wait" do
79
+ context 'when pending_handle true' do
80
+ let(:pending_handle) { true }
81
+
82
+ it "should wait until the timeout and then raise an error" do
83
+ expect {
84
+ subject.wait(max_wait_timeout: 0.1)
85
+ }.to raise_error Rdkafka::AbstractHandle::WaitTimeoutError, /test_operation/
86
+ end
87
+ end
88
+
89
+ context 'when pending_handle false' do
90
+ let(:pending_handle) { false }
91
+
92
+ context "without error" do
93
+ let(:result) { 1 }
94
+
95
+ it "should return a result" do
96
+ wait_result = subject.wait
97
+ expect(wait_result).to eq(result)
98
+ end
99
+
100
+ it "should wait without a timeout" do
101
+ wait_result = subject.wait(max_wait_timeout: nil)
102
+ expect(wait_result).to eq(result)
103
+ end
104
+ end
105
+
106
+ context "with error" do
107
+ let(:response) { 20 }
108
+
109
+ it "should raise an rdkafka error" do
110
+ expect {
111
+ subject.wait
112
+ }.to raise_error Rdkafka::RdkafkaError
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Rdkafka::Admin::CreateAclHandle do
6
+ # If create acl was successful there is no error object
7
+ # the error code is set to RD_KAFKA_RESP_ERR_NO_ERRORa
8
+ # https://github.com/confluentinc/librdkafka/blob/1f9f245ac409f50f724695c628c7a0d54a763b9a/src/rdkafka_error.c#L169
9
+ let(:response) { Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR }
10
+
11
+ subject do
12
+ Rdkafka::Admin::CreateAclHandle.new.tap do |handle|
13
+ handle[:pending] = pending_handle
14
+ handle[:response] = response
15
+ # If create acl was successful there is no error object and the error_string is set to ""
16
+ # https://github.com/confluentinc/librdkafka/blob/1f9f245ac409f50f724695c628c7a0d54a763b9a/src/rdkafka_error.c#L178
17
+ handle[:response_string] = FFI::MemoryPointer.from_string("")
18
+ end
19
+ end
20
+
21
+ describe "#wait" do
22
+ let(:pending_handle) { true }
23
+
24
+ it "should wait until the timeout and then raise an error" do
25
+ expect {
26
+ subject.wait(max_wait_timeout: 0.1)
27
+ }.to raise_error Rdkafka::Admin::CreateAclHandle::WaitTimeoutError, /create acl/
28
+ end
29
+
30
+ context "when not pending anymore and no error" do
31
+ let(:pending_handle) { false }
32
+
33
+ it "should return a create acl report" do
34
+ report = subject.wait
35
+
36
+ expect(report.rdkafka_response_string).to eq("")
37
+ end
38
+
39
+ it "should wait without a timeout" do
40
+ report = subject.wait(max_wait_timeout: nil)
41
+
42
+ expect(report.rdkafka_response_string).to eq("")
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "#raise_error" do
48
+ let(:pending_handle) { false }
49
+
50
+ it "should raise the appropriate error" do
51
+ expect {
52
+ subject.raise_error
53
+ }.to raise_exception(Rdkafka::RdkafkaError, /Success \(no_error\)/)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Rdkafka::Admin::CreateAclReport do
6
+ subject { Rdkafka::Admin::CreateAclReport.new(
7
+ rdkafka_response: Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR,
8
+ rdkafka_response_string: FFI::MemoryPointer.from_string("")
9
+ )}
10
+
11
+ it "should get RD_KAFKA_RESP_ERR_NO_ERROR " do
12
+ expect(subject.rdkafka_response).to eq(0)
13
+ end
14
+
15
+ it "should get empty string" do
16
+ expect(subject.rdkafka_response_string).to eq("")
17
+ end
18
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Rdkafka::Admin::CreateTopicHandle do
4
+ let(:response) { 0 }
5
+
6
+ subject do
7
+ Rdkafka::Admin::CreateTopicHandle.new.tap do |handle|
8
+ handle[:pending] = pending_handle
9
+ handle[:response] = response
10
+ handle[:error_string] = FFI::Pointer::NULL
11
+ handle[:result_name] = FFI::MemoryPointer.from_string("my-test-topic")
12
+ end
13
+ end
14
+
15
+ describe "#wait" do
16
+ let(:pending_handle) { true }
17
+
18
+ it "should wait until the timeout and then raise an error" do
19
+ expect {
20
+ subject.wait(max_wait_timeout: 0.1)
21
+ }.to raise_error Rdkafka::Admin::CreateTopicHandle::WaitTimeoutError, /create topic/
22
+ end
23
+
24
+ context "when not pending anymore and no error" do
25
+ let(:pending_handle) { false }
26
+
27
+ it "should return a create topic report" do
28
+ report = subject.wait
29
+
30
+ expect(report.error_string).to eq(nil)
31
+ expect(report.result_name).to eq("my-test-topic")
32
+ end
33
+
34
+ it "should wait without a timeout" do
35
+ report = subject.wait(max_wait_timeout: nil)
36
+
37
+ expect(report.error_string).to eq(nil)
38
+ expect(report.result_name).to eq("my-test-topic")
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "#raise_error" do
44
+ let(:pending_handle) { false }
45
+
46
+ before { subject[:response] = -1 }
47
+
48
+ it "should raise the appropriate error when there is an error" do
49
+ expect {
50
+ subject.raise_error
51
+ }.to raise_exception(Rdkafka::RdkafkaError, /Unknown broker error \(unknown\)/)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Rdkafka::Admin::CreateTopicReport do
4
+ subject { Rdkafka::Admin::CreateTopicReport.new(
5
+ FFI::MemoryPointer.from_string("error string"),
6
+ FFI::MemoryPointer.from_string("result name")
7
+ )}
8
+
9
+ it "should get the error string" do
10
+ expect(subject.error_string).to eq("error string")
11
+ end
12
+
13
+ it "should get the result name" do
14
+ expect(subject.result_name).to eq("result name")
15
+ end
16
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Rdkafka::Admin::DeleteAclHandle do
6
+ let(:response) { Rdkafka::Bindings::RD_KAFKA_RESP_ERR_NO_ERROR }
7
+ let(:resource_name) {"acl-test-topic"}
8
+ let(:resource_type) {Rdkafka::Bindings::RD_KAFKA_RESOURCE_TOPIC}
9
+ let(:resource_pattern_type) {Rdkafka::Bindings::RD_KAFKA_RESOURCE_PATTERN_LITERAL}
10
+ let(:principal) {"User:anonymous"}
11
+ let(:host) {"*"}
12
+ let(:operation) {Rdkafka::Bindings::RD_KAFKA_ACL_OPERATION_READ}
13
+ let(:permission_type) {Rdkafka::Bindings::RD_KAFKA_ACL_PERMISSION_TYPE_ALLOW}
14
+ let(:delete_acl_ptr) {FFI::Pointer::NULL}
15
+
16
+ subject do
17
+ error_buffer = FFI::MemoryPointer.from_string(" " * 256)
18
+ delete_acl_ptr = Rdkafka::Bindings.rd_kafka_AclBinding_new(
19
+ resource_type,
20
+ FFI::MemoryPointer.from_string(resource_name),
21
+ resource_pattern_type,
22
+ FFI::MemoryPointer.from_string(principal),
23
+ FFI::MemoryPointer.from_string(host),
24
+ operation,
25
+ permission_type,
26
+ error_buffer,
27
+ 256
28
+ )
29
+ if delete_acl_ptr.null?
30
+ raise Rdkafka::Config::ConfigError.new(error_buffer.read_string)
31
+ end
32
+ pointer_array = [delete_acl_ptr]
33
+ delete_acls_array_ptr = FFI::MemoryPointer.new(:pointer)
34
+ delete_acls_array_ptr.write_array_of_pointer(pointer_array)
35
+ Rdkafka::Admin::DeleteAclHandle.new.tap do |handle|
36
+ handle[:pending] = pending_handle
37
+ handle[:response] = response
38
+ handle[:response_string] = FFI::MemoryPointer.from_string("")
39
+ handle[:matching_acls] = delete_acls_array_ptr
40
+ handle[:matching_acls_count] = 1
41
+ end
42
+ end
43
+
44
+ after do
45
+ if delete_acl_ptr != FFI::Pointer::NULL
46
+ Rdkafka::Bindings.rd_kafka_AclBinding_destroy(delete_acl_ptr)
47
+ end
48
+ end
49
+
50
+ describe "#wait" do
51
+ let(:pending_handle) { true }
52
+
53
+ it "should wait until the timeout and then raise an error" do
54
+ expect {
55
+ subject.wait(max_wait_timeout: 0.1)
56
+ }.to raise_error Rdkafka::Admin::DeleteAclHandle::WaitTimeoutError, /delete acl/
57
+ end
58
+
59
+ context "when not pending anymore and no error" do
60
+ let(:pending_handle) { false }
61
+
62
+ it "should return a delete acl report" do
63
+ report = subject.wait
64
+
65
+ expect(report.deleted_acls.length).to eq(1)
66
+ end
67
+
68
+ it "should wait without a timeout" do
69
+ report = subject.wait(max_wait_timeout: nil)
70
+
71
+ expect(report.deleted_acls[0].matching_acl_resource_name).to eq(resource_name)
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "#raise_error" do
77
+ let(:pending_handle) { false }
78
+
79
+ it "should raise the appropriate error" do
80
+ expect {
81
+ subject.raise_error
82
+ }.to raise_exception(Rdkafka::RdkafkaError, /Success \(no_error\)/)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Rdkafka::Admin::DeleteAclReport do
6
+
7
+ let(:resource_name) {"acl-test-topic"}
8
+ let(:resource_type) {Rdkafka::Bindings::RD_KAFKA_RESOURCE_TOPIC}
9
+ let(:resource_pattern_type) {Rdkafka::Bindings::RD_KAFKA_RESOURCE_PATTERN_LITERAL}
10
+ let(:principal) {"User:anonymous"}
11
+ let(:host) {"*"}
12
+ let(:operation) {Rdkafka::Bindings::RD_KAFKA_ACL_OPERATION_READ}
13
+ let(:permission_type) {Rdkafka::Bindings::RD_KAFKA_ACL_PERMISSION_TYPE_ALLOW}
14
+ let(:delete_acl_ptr) {FFI::Pointer::NULL}
15
+
16
+ subject do
17
+ error_buffer = FFI::MemoryPointer.from_string(" " * 256)
18
+ delete_acl_ptr = Rdkafka::Bindings.rd_kafka_AclBinding_new(
19
+ resource_type,
20
+ FFI::MemoryPointer.from_string(resource_name),
21
+ resource_pattern_type,
22
+ FFI::MemoryPointer.from_string(principal),
23
+ FFI::MemoryPointer.from_string(host),
24
+ operation,
25
+ permission_type,
26
+ error_buffer,
27
+ 256
28
+ )
29
+ if delete_acl_ptr.null?
30
+ raise Rdkafka::Config::ConfigError.new(error_buffer.read_string)
31
+ end
32
+ pointer_array = [delete_acl_ptr]
33
+ delete_acls_array_ptr = FFI::MemoryPointer.new(:pointer)
34
+ delete_acls_array_ptr.write_array_of_pointer(pointer_array)
35
+ Rdkafka::Admin::DeleteAclReport.new(matching_acls: delete_acls_array_ptr, matching_acls_count: 1)
36
+ end
37
+
38
+ after do
39
+ if delete_acl_ptr != FFI::Pointer::NULL
40
+ Rdkafka::Bindings.rd_kafka_AclBinding_destroy(delete_acl_ptr)
41
+ end
42
+ end
43
+
44
+ it "should get deleted acl resource type as Rdkafka::Bindings::RD_KAFKA_RESOURCE_TOPIC" do
45
+ expect(subject.deleted_acls[0].matching_acl_resource_type).to eq(Rdkafka::Bindings::RD_KAFKA_RESOURCE_TOPIC)
46
+ end
47
+
48
+ it "should get deleted acl resource name as acl-test-topic" do
49
+ expect(subject.deleted_acls[0].matching_acl_resource_name).to eq(resource_name)
50
+ end
51
+
52
+ it "should get deleted acl resource pattern type as Rdkafka::Bindings::RD_KAFKA_RESOURCE_PATTERN_LITERAL" do
53
+ expect(subject.deleted_acls[0].matching_acl_resource_pattern_type).to eq(Rdkafka::Bindings::RD_KAFKA_RESOURCE_PATTERN_LITERAL)
54
+ expect(subject.deleted_acls[0].matching_acl_pattern_type).to eq(Rdkafka::Bindings::RD_KAFKA_RESOURCE_PATTERN_LITERAL)
55
+ end
56
+
57
+ it "should get deleted acl principal as User:anonymous" do
58
+ expect(subject.deleted_acls[0].matching_acl_principal).to eq("User:anonymous")
59
+ end
60
+
61
+ it "should get deleted acl host as * " do
62
+ expect(subject.deleted_acls[0].matching_acl_host).to eq("*")
63
+ end
64
+
65
+ it "should get deleted acl operation as Rdkafka::Bindings::RD_KAFKA_ACL_OPERATION_READ" do
66
+ expect(subject.deleted_acls[0].matching_acl_operation).to eq(Rdkafka::Bindings::RD_KAFKA_ACL_OPERATION_READ)
67
+ end
68
+
69
+ it "should get deleted acl permission_type as Rdkafka::Bindings::RD_KAFKA_ACL_PERMISSION_TYPE_ALLOW" do
70
+ expect(subject.deleted_acls[0].matching_acl_permission_type).to eq(Rdkafka::Bindings::RD_KAFKA_ACL_PERMISSION_TYPE_ALLOW)
71
+ end
72
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Rdkafka::Admin::DeleteTopicHandle do
4
+ let(:response) { 0 }
5
+
6
+ subject do
7
+ Rdkafka::Admin::DeleteTopicHandle.new.tap do |handle|
8
+ handle[:pending] = pending_handle
9
+ handle[:response] = response
10
+ handle[:error_string] = FFI::Pointer::NULL
11
+ handle[:result_name] = FFI::MemoryPointer.from_string("my-test-topic")
12
+ end
13
+ end
14
+
15
+ describe "#wait" do
16
+ let(:pending_handle) { true }
17
+
18
+ it "should wait until the timeout and then raise an error" do
19
+ expect {
20
+ subject.wait(max_wait_timeout: 0.1)
21
+ }.to raise_error Rdkafka::Admin::DeleteTopicHandle::WaitTimeoutError, /delete topic/
22
+ end
23
+
24
+ context "when not pending anymore and no error" do
25
+ let(:pending_handle) { false }
26
+
27
+ it "should return a delete topic report" do
28
+ report = subject.wait
29
+
30
+ expect(report.error_string).to eq(nil)
31
+ expect(report.result_name).to eq("my-test-topic")
32
+ end
33
+
34
+ it "should wait without a timeout" do
35
+ report = subject.wait(max_wait_timeout: nil)
36
+
37
+ expect(report.error_string).to eq(nil)
38
+ expect(report.result_name).to eq("my-test-topic")
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "#raise_error" do
44
+ let(:pending_handle) { false }
45
+
46
+ before { subject[:response] = -1 }
47
+
48
+ it "should raise the appropriate error" do
49
+ expect {
50
+ subject.raise_error
51
+ }.to raise_exception(Rdkafka::RdkafkaError, /Unknown broker error \(unknown\)/)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Rdkafka::Admin::DeleteTopicReport do
4
+ subject { Rdkafka::Admin::DeleteTopicReport.new(
5
+ FFI::MemoryPointer.from_string("error string"),
6
+ FFI::MemoryPointer.from_string("result name")
7
+ )}
8
+
9
+ it "should get the error string" do
10
+ expect(subject.error_string).to eq("error string")
11
+ end
12
+
13
+ it "should get the result name" do
14
+ expect(subject.result_name).to eq("result name")
15
+ end
16
+ end