codeclimate-poseidon 0.0.8
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 +7 -0
- data/.gitignore +21 -0
- data/.rspec +2 -0
- data/.travis.yml +14 -0
- data/.yardopts +8 -0
- data/CHANGES.md +31 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +72 -0
- data/Rakefile +20 -0
- data/TODO.md +27 -0
- data/examples/consumer.rb +18 -0
- data/examples/producer.rb +9 -0
- data/lib/poseidon.rb +120 -0
- data/lib/poseidon/broker_pool.rb +86 -0
- data/lib/poseidon/cluster_metadata.rb +94 -0
- data/lib/poseidon/compressed_value.rb +23 -0
- data/lib/poseidon/compression.rb +30 -0
- data/lib/poseidon/compression/gzip_codec.rb +23 -0
- data/lib/poseidon/compression/snappy_codec.rb +29 -0
- data/lib/poseidon/connection.rb +169 -0
- data/lib/poseidon/fetched_message.rb +37 -0
- data/lib/poseidon/message.rb +151 -0
- data/lib/poseidon/message_conductor.rb +86 -0
- data/lib/poseidon/message_set.rb +80 -0
- data/lib/poseidon/message_to_send.rb +33 -0
- data/lib/poseidon/messages_for_broker.rb +56 -0
- data/lib/poseidon/messages_to_send.rb +47 -0
- data/lib/poseidon/messages_to_send_batch.rb +27 -0
- data/lib/poseidon/partition_consumer.rb +225 -0
- data/lib/poseidon/producer.rb +199 -0
- data/lib/poseidon/producer_compression_config.rb +37 -0
- data/lib/poseidon/protocol.rb +122 -0
- data/lib/poseidon/protocol/protocol_struct.rb +256 -0
- data/lib/poseidon/protocol/request_buffer.rb +77 -0
- data/lib/poseidon/protocol/response_buffer.rb +72 -0
- data/lib/poseidon/sync_producer.rb +161 -0
- data/lib/poseidon/topic_metadata.rb +89 -0
- data/lib/poseidon/version.rb +4 -0
- data/log/.gitkeep +0 -0
- data/poseidon.gemspec +27 -0
- data/spec/integration/multiple_brokers/consumer_spec.rb +45 -0
- data/spec/integration/multiple_brokers/metadata_failures_spec.rb +144 -0
- data/spec/integration/multiple_brokers/rebalance_spec.rb +69 -0
- data/spec/integration/multiple_brokers/round_robin_spec.rb +41 -0
- data/spec/integration/multiple_brokers/spec_helper.rb +60 -0
- data/spec/integration/simple/compression_spec.rb +23 -0
- data/spec/integration/simple/connection_spec.rb +35 -0
- data/spec/integration/simple/multiple_brokers_spec.rb +10 -0
- data/spec/integration/simple/simple_producer_and_consumer_spec.rb +121 -0
- data/spec/integration/simple/spec_helper.rb +16 -0
- data/spec/integration/simple/truncated_messages_spec.rb +46 -0
- data/spec/integration/simple/unavailable_broker_spec.rb +72 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/test_cluster.rb +211 -0
- data/spec/unit/broker_pool_spec.rb +98 -0
- data/spec/unit/cluster_metadata_spec.rb +46 -0
- data/spec/unit/compression/gzip_codec_spec.rb +34 -0
- data/spec/unit/compression/snappy_codec_spec.rb +49 -0
- data/spec/unit/compression_spec.rb +17 -0
- data/spec/unit/connection_spec.rb +4 -0
- data/spec/unit/fetched_message_spec.rb +11 -0
- data/spec/unit/message_conductor_spec.rb +164 -0
- data/spec/unit/message_set_spec.rb +42 -0
- data/spec/unit/message_spec.rb +129 -0
- data/spec/unit/message_to_send_spec.rb +10 -0
- data/spec/unit/messages_for_broker_spec.rb +54 -0
- data/spec/unit/messages_to_send_batch_spec.rb +25 -0
- data/spec/unit/messages_to_send_spec.rb +63 -0
- data/spec/unit/partition_consumer_spec.rb +142 -0
- data/spec/unit/producer_compression_config_spec.rb +42 -0
- data/spec/unit/producer_spec.rb +51 -0
- data/spec/unit/protocol/request_buffer_spec.rb +16 -0
- data/spec/unit/protocol_spec.rb +54 -0
- data/spec/unit/sync_producer_spec.rb +156 -0
- data/spec/unit/topic_metadata_spec.rb +43 -0
- metadata +225 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe MessageToSend do
|
4
|
+
it "provides access to topic,value,key" do
|
5
|
+
mts = MessageToSend.new("hello_topic", "Hello World", "key")
|
6
|
+
expect(mts.topic).to eq("hello_topic")
|
7
|
+
expect(mts.value).to eq("Hello World")
|
8
|
+
expect(mts.key).to eq("key")
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe MessagesForBroker do
|
4
|
+
context "twos message one to broker 0, partition 0, another to partition 1" do
|
5
|
+
before(:each) do
|
6
|
+
@messages = [ Message.new(:topic => "topic1",:value => "hi0"),
|
7
|
+
Message.new(:topic => "topic1",:value => "hi1")]
|
8
|
+
|
9
|
+
@compression_config = double('compression_config',
|
10
|
+
:compression_codec_for_topic => nil)
|
11
|
+
|
12
|
+
@mfb = MessagesForBroker.new(0)
|
13
|
+
@mfb.add(@messages[0], 0)
|
14
|
+
@mfb.add(@messages[1], 1)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "provides the messages" do
|
18
|
+
expect(@mfb.messages.to_set).to eq(@messages.to_set)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "is has a broker_id of 0" do
|
22
|
+
expect(@mfb.broker_id).to eq(0)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "builds the protocol object correctly" do
|
26
|
+
protocol_object = @mfb.build_protocol_objects(@compression_config)
|
27
|
+
|
28
|
+
messages_for_topics = [
|
29
|
+
MessagesForTopic.new("topic1",
|
30
|
+
[
|
31
|
+
MessagesForPartition.new(0, MessageSet.new([@messages[0]])),
|
32
|
+
MessagesForPartition.new(1, MessageSet.new([@messages[1]])),
|
33
|
+
])
|
34
|
+
]
|
35
|
+
expect(protocol_object).to eq(messages_for_topics)
|
36
|
+
end
|
37
|
+
|
38
|
+
context "and topic is compressed" do
|
39
|
+
it "builds the protocol object correctly" do
|
40
|
+
allow(@compression_config).to receive_messages(:compression_codec_for_topic => Compression::GzipCodec)
|
41
|
+
protocol_object = @mfb.build_protocol_objects(@compression_config)
|
42
|
+
|
43
|
+
messages_for_topics = [
|
44
|
+
MessagesForTopic.new("topic1",
|
45
|
+
[
|
46
|
+
MessagesForPartition.new(0, MessageSet.new([@messages[0]]).compress(Compression::GzipCodec)),
|
47
|
+
MessagesForPartition.new(1, MessageSet.new([@messages[1]]).compress(Compression::GzipCodec)),
|
48
|
+
])
|
49
|
+
]
|
50
|
+
expect(protocol_object).to eq(messages_for_topics)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe MessagesToSendBatch do
|
4
|
+
context "messages sent to two different brokers" do
|
5
|
+
before(:each) do
|
6
|
+
message_conductor = double('message_conductor')
|
7
|
+
allow(message_conductor).to receive(:destination).and_return([0,0],[1,1])
|
8
|
+
|
9
|
+
@messages = [
|
10
|
+
Message.new(:topic => "topic1", :value => "hi"),
|
11
|
+
Message.new(:topic => "topic1", :value => "hi")
|
12
|
+
]
|
13
|
+
@batch = MessagesToSendBatch.new(@messages, message_conductor)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "returns a couple messages brokers" do
|
17
|
+
expect(@batch.messages_for_brokers.size).to eq(2)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "has all messages in the returned message brokers" do
|
21
|
+
messages = @batch.messages_for_brokers.map(&:messages).flatten
|
22
|
+
expect(messages.to_set).to eq(@messages.to_set)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe MessagesToSend do
|
4
|
+
before(:each) do
|
5
|
+
@messages = []
|
6
|
+
@messages << Message.new(:topic => "test1", :value => "hi")
|
7
|
+
@messages << Message.new(:topic => "test2", :value => "hi")
|
8
|
+
@messages << Message.new(:topic => "test2", :value => "hi")
|
9
|
+
|
10
|
+
|
11
|
+
@cluster_metadata = double('cluster_metdata').as_null_object
|
12
|
+
@mts = MessagesToSend.new(@messages, @cluster_metadata)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "needing metadata" do
|
16
|
+
it "returns set of topics" do
|
17
|
+
expect(@mts.topic_set).to eq(Set.new(["test1","test2"]))
|
18
|
+
end
|
19
|
+
|
20
|
+
it "asks ClusterMetadata about having metadata" do
|
21
|
+
allow(@cluster_metadata).to receive(:have_metadata_for_topics?).and_return(true)
|
22
|
+
|
23
|
+
expect(@mts.needs_metadata?).to eq(false)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "sending" do
|
28
|
+
before(:each) do
|
29
|
+
@mfb = double('mfb', :messages => @messages)
|
30
|
+
@messages_for_brokers = [@mfb]
|
31
|
+
|
32
|
+
@mtsb = double('messages_to_send_batch').as_null_object
|
33
|
+
allow(@mtsb).to receive(:messages_for_brokers).and_return(@messages_for_brokers)
|
34
|
+
|
35
|
+
allow(MessagesToSendBatch).to receive(:new).and_return(@mtsb)
|
36
|
+
end
|
37
|
+
|
38
|
+
context "is successful" do
|
39
|
+
before(:each) do
|
40
|
+
@mts.messages_for_brokers(nil).each do |mfb|
|
41
|
+
@mts.successfully_sent(mfb.messages)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "successfully sends all" do
|
46
|
+
expect(@mts.pending_messages?).to eq(false)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "is not successful" do
|
51
|
+
before(:each) do
|
52
|
+
@mts.messages_for_brokers(nil).each do |mfb|
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "does not send all" do
|
57
|
+
@mts.messages_for_brokers(nil).each do |mfb|
|
58
|
+
end
|
59
|
+
expect(@mts.pending_messages?).to eq(true)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe PartitionConsumer do
|
4
|
+
before(:each) do
|
5
|
+
@connection = double('connection')
|
6
|
+
allow(Connection).to receive(:new).and_return(@connection)
|
7
|
+
|
8
|
+
offset = Protocol::Offset.new(100)
|
9
|
+
partition_offsets = [Protocol::PartitionOffset.new(0, 0, [offset])]
|
10
|
+
@offset_response = [Protocol::TopicOffsetResponse.new("test_topic", partition_offsets)]
|
11
|
+
allow(@connection).to receive(:offset).and_return(@offset_response)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "creation" do
|
15
|
+
context "when passed unknown options" do
|
16
|
+
it "raises an ArgumentError" do
|
17
|
+
expect { PartitionConsumer.new("test_client", "localhost", 9092, "test_topic", 0, :earliest_offset, :unknown => true) }.to raise_error(ArgumentError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when passed an unknown offset" do
|
22
|
+
it "raises an ArgumentError" do
|
23
|
+
expect { PartitionConsumer.new("test_client", "localhost", 9092, "test_topic", 0, :coolest_offset) }.to raise_error(ArgumentError)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "next offset" do
|
29
|
+
context "when offset is not set" do
|
30
|
+
it "resolves offset if it's not set" do
|
31
|
+
expect(@connection).to receive(:offset).and_return(@offset_response)
|
32
|
+
pc = PartitionConsumer.new("test_client", "localhost", 9092, "test_topic",
|
33
|
+
0, :earliest_offset)
|
34
|
+
|
35
|
+
pc.next_offset
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns resolved offset" do
|
39
|
+
pc = PartitionConsumer.new("test_client", "localhost", 9092, "test_topic",
|
40
|
+
0, :earliest_offset)
|
41
|
+
expect(pc.next_offset).to eq(100)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when offset is set" do
|
46
|
+
it "does not resolve it" do
|
47
|
+
pc = PartitionConsumer.new("test_client", "localhost", 9092, "test_topic",
|
48
|
+
0, 200)
|
49
|
+
pc.next_offset
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when call returns an error" do
|
54
|
+
it "is raised" do
|
55
|
+
allow(@offset_response.first.partition_offsets.first).to receive(:error).and_return(2)
|
56
|
+
pc = PartitionConsumer.new("test_client", "localhost", 9092, "test_topic",
|
57
|
+
0, :earliest_offset)
|
58
|
+
|
59
|
+
expect { pc.next_offset }.to raise_error(Errors::InvalidMessage)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when no offset exists" do
|
64
|
+
it "sets offset to 0" do
|
65
|
+
pc = PartitionConsumer.new("test_client", "localhost", 9092, "test_topic",
|
66
|
+
0, :earliest_offset)
|
67
|
+
|
68
|
+
allow(@offset_response.first.partition_offsets.first).to receive(:offsets).and_return([])
|
69
|
+
expect(pc.next_offset).to eq(0)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "when offset negative" do
|
74
|
+
it "resolves offset to one " do
|
75
|
+
pc = PartitionConsumer.new("test_client", "localhost", 9092, "test_topic",
|
76
|
+
0, -10)
|
77
|
+
expect(pc.next_offset).to eq(90)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "fetching messages" do
|
83
|
+
before(:each) do
|
84
|
+
message_set = MessageSet.new
|
85
|
+
message_set << Message.new(:value => "value", :key => "key", :offset => 90)
|
86
|
+
partition_fetch_response = Protocol::PartitionFetchResponse.new(0, 0, 100, message_set)
|
87
|
+
topic_fetch_response = Protocol::TopicFetchResponse.new('test_topic',
|
88
|
+
[partition_fetch_response])
|
89
|
+
@response = Protocol::FetchResponse.new(double('common'), [topic_fetch_response])
|
90
|
+
|
91
|
+
allow(@connection).to receive(:fetch).and_return(@response)
|
92
|
+
@pc = PartitionConsumer.new("test_client", "localhost", 9092, "test_topic", 0, :earliest_offset)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "returns FetchedMessage objects" do
|
96
|
+
expect(@pc.fetch.first.class).to eq(FetchedMessage)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "uses object defaults" do
|
100
|
+
expect(@connection).to receive(:fetch).with(10_000, 1, anything)
|
101
|
+
@pc.fetch
|
102
|
+
end
|
103
|
+
|
104
|
+
context "when options are passed" do
|
105
|
+
it "overrides object defaults" do
|
106
|
+
expect(@connection).to receive(:fetch).with(20_000, 1, anything)
|
107
|
+
@pc = PartitionConsumer.new("test_client", "localhost", 9092, "test_topic", 0, :earliest_offset, :max_wait_ms => 20_000)
|
108
|
+
|
109
|
+
@pc.fetch
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "when negative offset beyond beginning of partition is passed" do
|
114
|
+
it "starts from the earliest offset" do
|
115
|
+
@pc = PartitionConsumer.new("test_client", "localhost", 9092, "test_topic", 0, -10000)
|
116
|
+
pfr = @response.topic_fetch_responses.first.partition_fetch_responses.first
|
117
|
+
allow(pfr).to receive(:error).and_return(1, 1, 0)
|
118
|
+
|
119
|
+
@pc.fetch
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "when call returns an error" do
|
124
|
+
it "is raised" do
|
125
|
+
pfr = @response.topic_fetch_responses.first.partition_fetch_responses.first
|
126
|
+
allow(pfr).to receive(:error).and_return(2)
|
127
|
+
|
128
|
+
expect { @pc.fetch }.to raise_error(Errors::InvalidMessage)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
it "sets the highwater mark" do
|
133
|
+
@pc.fetch
|
134
|
+
expect(@pc.highwater_mark).to eq(100)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "sets the latest offset" do
|
138
|
+
@pc.fetch
|
139
|
+
expect(@pc.next_offset).to eq(91)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ProducerCompressionConfig do
|
4
|
+
describe "creation" do
|
5
|
+
it "raises ArgumentError when codec is unknown" do
|
6
|
+
expect { ProducerCompressionConfig.new(:ripple, nil) }.to raise_error(ArgumentError)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
context "no codec set" do
|
11
|
+
it "compresses no topics" do
|
12
|
+
pcc = ProducerCompressionConfig.new(nil,nil)
|
13
|
+
expect(pcc.compression_codec_for_topic("test")).to eq(false)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "none compression codec" do
|
18
|
+
it "compresses no topics" do
|
19
|
+
pcc = ProducerCompressionConfig.new(:none,nil)
|
20
|
+
expect(pcc.compression_codec_for_topic("test")).to eq(false)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "compression codec no topics specified" do
|
25
|
+
it "compresses any topic" do
|
26
|
+
pcc = ProducerCompressionConfig.new(:gzip,nil)
|
27
|
+
expect(pcc.compression_codec_for_topic("test")).to eq(Compression::GzipCodec)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "compression codec set, but only compress 'compressed' topic" do
|
32
|
+
it "compresses 'compressed' topic" do
|
33
|
+
pcc = ProducerCompressionConfig.new(:gzip, ["compressed"])
|
34
|
+
expect(pcc.compression_codec_for_topic("compressed")).to eq(Compression::GzipCodec)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "does not compresses 'test' topic" do
|
38
|
+
pcc = ProducerCompressionConfig.new(:gzip, ["compressed"])
|
39
|
+
expect(pcc.compression_codec_for_topic("test")).to eq(false)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Producer do
|
4
|
+
it "requires brokers and client_id" do
|
5
|
+
expect { Producer.new }.to raise_error
|
6
|
+
end
|
7
|
+
|
8
|
+
it "raises ArgumentError on unknown arguments" do
|
9
|
+
expect { Producer.new([],"client_id", :unknown => true) }.to raise_error(ArgumentError)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "raises ArgumentError unless brokers is an enumerable" do
|
13
|
+
expect { Producer.new("host:port","client_id") }.to raise_error(ArgumentError)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "raises ProducerShutdown if we try to send to a shutdown producer" do
|
17
|
+
p = Producer.new(["host:port"],"client_id")
|
18
|
+
p.close
|
19
|
+
expect { p.send_messages([]) }.to raise_error(Errors::ProducerShutdownError)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "accepts all options" do
|
23
|
+
expect { Producer.new([],"client_id", Producer::OPTION_DEFAULTS.dup) }.not_to raise_error
|
24
|
+
end
|
25
|
+
|
26
|
+
it "accepts socket_timeout_ms option" do
|
27
|
+
expect { Producer.new([],"client_id", socket_timeout_ms: 10_000) }.not_to raise_error
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "sending messages" do
|
31
|
+
before(:each) do
|
32
|
+
@sync_producer = double('sync_producer').as_null_object
|
33
|
+
allow(SyncProducer).to receive(:new).and_return(@sync_producer)
|
34
|
+
|
35
|
+
@producer = Producer.new([], "client_id", :type => :sync)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "turns MessagesToSend into Message objects" do
|
39
|
+
expect(@sync_producer).to receive(:send_messages).with(an_instance_of(Array)) do |array|
|
40
|
+
array.each { |obj| expect(obj).to be_an_instance_of(Message) }
|
41
|
+
end
|
42
|
+
|
43
|
+
m = MessageToSend.new("topic", "value")
|
44
|
+
@producer.send_messages([m])
|
45
|
+
end
|
46
|
+
|
47
|
+
it "raises an ArgumentError if you try to send a single message" do
|
48
|
+
expect { @producer.send_messages(MessageToSend.new("topic", "value")) }.to raise_error(ArgumentError)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
include Protocol
|
5
|
+
|
6
|
+
RSpec.describe RequestBuffer do
|
7
|
+
subject(:buffer) { Poseidon::Protocol::RequestBuffer.new }
|
8
|
+
|
9
|
+
it 'appends UTF-8 strings' do
|
10
|
+
expect do
|
11
|
+
str = 'hello ümlaut'
|
12
|
+
buffer.append(str)
|
13
|
+
buffer.append(str.force_encoding(Encoding::BINARY))
|
14
|
+
end.to_not raise_error
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
include Protocol
|
3
|
+
RSpec.describe RequestCommon do
|
4
|
+
it "roundtrips" do
|
5
|
+
rc = RequestCommon.new(0,1,2,"client_id")
|
6
|
+
|
7
|
+
req_buffer = RequestBuffer.new
|
8
|
+
rc.write(req_buffer)
|
9
|
+
|
10
|
+
resp_buffer = ResponseBuffer.new(req_buffer.to_s)
|
11
|
+
rc_roundtrip = RequestCommon.read(resp_buffer)
|
12
|
+
|
13
|
+
expect(rc).to eq(rc_roundtrip)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec.describe MetadataRequest do
|
18
|
+
it "roundtrips" do
|
19
|
+
rc = RequestCommon.new(0,1,2,"client_id")
|
20
|
+
mr = MetadataRequest.new(rc, ["topic1","topic2"])
|
21
|
+
|
22
|
+
req_buffer = RequestBuffer.new
|
23
|
+
mr.write(req_buffer)
|
24
|
+
|
25
|
+
resp_buffer = ResponseBuffer.new(req_buffer.to_s)
|
26
|
+
mr_roundtrip = MetadataRequest.read(resp_buffer)
|
27
|
+
|
28
|
+
expect(mr).to eq(mr_roundtrip)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
RSpec.describe "objects with errors" do
|
33
|
+
it "returns objects that have errors" do
|
34
|
+
message_set = MessageSet.new
|
35
|
+
message_set << Message.new(:value => "value", :key => "key")
|
36
|
+
partition_fetch_response = PartitionFetchResponse.new(0, 5, 100, message_set)
|
37
|
+
topic_fetch_response = TopicFetchResponse.new('test_topic',
|
38
|
+
[partition_fetch_response])
|
39
|
+
response = FetchResponse.new(double('common'), [topic_fetch_response])
|
40
|
+
|
41
|
+
expect(response.objects_with_errors).to eq([partition_fetch_response])
|
42
|
+
end
|
43
|
+
|
44
|
+
it "raises error when asked" do
|
45
|
+
message_set = MessageSet.new
|
46
|
+
message_set << Message.new(:value => "value", :key => "key")
|
47
|
+
partition_fetch_response = PartitionFetchResponse.new(0, 5, 100, message_set)
|
48
|
+
topic_fetch_response = TopicFetchResponse.new('test_topic',
|
49
|
+
[partition_fetch_response])
|
50
|
+
response = FetchResponse.new(double('common'), [topic_fetch_response])
|
51
|
+
|
52
|
+
expect { response.raise_error_if_one_exists }.to raise_error
|
53
|
+
end
|
54
|
+
end
|