codeclimate-poseidon 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +14 -0
  5. data/.yardopts +8 -0
  6. data/CHANGES.md +31 -0
  7. data/Gemfile +13 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +72 -0
  10. data/Rakefile +20 -0
  11. data/TODO.md +27 -0
  12. data/examples/consumer.rb +18 -0
  13. data/examples/producer.rb +9 -0
  14. data/lib/poseidon.rb +120 -0
  15. data/lib/poseidon/broker_pool.rb +86 -0
  16. data/lib/poseidon/cluster_metadata.rb +94 -0
  17. data/lib/poseidon/compressed_value.rb +23 -0
  18. data/lib/poseidon/compression.rb +30 -0
  19. data/lib/poseidon/compression/gzip_codec.rb +23 -0
  20. data/lib/poseidon/compression/snappy_codec.rb +29 -0
  21. data/lib/poseidon/connection.rb +169 -0
  22. data/lib/poseidon/fetched_message.rb +37 -0
  23. data/lib/poseidon/message.rb +151 -0
  24. data/lib/poseidon/message_conductor.rb +86 -0
  25. data/lib/poseidon/message_set.rb +80 -0
  26. data/lib/poseidon/message_to_send.rb +33 -0
  27. data/lib/poseidon/messages_for_broker.rb +56 -0
  28. data/lib/poseidon/messages_to_send.rb +47 -0
  29. data/lib/poseidon/messages_to_send_batch.rb +27 -0
  30. data/lib/poseidon/partition_consumer.rb +225 -0
  31. data/lib/poseidon/producer.rb +199 -0
  32. data/lib/poseidon/producer_compression_config.rb +37 -0
  33. data/lib/poseidon/protocol.rb +122 -0
  34. data/lib/poseidon/protocol/protocol_struct.rb +256 -0
  35. data/lib/poseidon/protocol/request_buffer.rb +77 -0
  36. data/lib/poseidon/protocol/response_buffer.rb +72 -0
  37. data/lib/poseidon/sync_producer.rb +161 -0
  38. data/lib/poseidon/topic_metadata.rb +89 -0
  39. data/lib/poseidon/version.rb +4 -0
  40. data/log/.gitkeep +0 -0
  41. data/poseidon.gemspec +27 -0
  42. data/spec/integration/multiple_brokers/consumer_spec.rb +45 -0
  43. data/spec/integration/multiple_brokers/metadata_failures_spec.rb +144 -0
  44. data/spec/integration/multiple_brokers/rebalance_spec.rb +69 -0
  45. data/spec/integration/multiple_brokers/round_robin_spec.rb +41 -0
  46. data/spec/integration/multiple_brokers/spec_helper.rb +60 -0
  47. data/spec/integration/simple/compression_spec.rb +23 -0
  48. data/spec/integration/simple/connection_spec.rb +35 -0
  49. data/spec/integration/simple/multiple_brokers_spec.rb +10 -0
  50. data/spec/integration/simple/simple_producer_and_consumer_spec.rb +121 -0
  51. data/spec/integration/simple/spec_helper.rb +16 -0
  52. data/spec/integration/simple/truncated_messages_spec.rb +46 -0
  53. data/spec/integration/simple/unavailable_broker_spec.rb +72 -0
  54. data/spec/spec_helper.rb +32 -0
  55. data/spec/test_cluster.rb +211 -0
  56. data/spec/unit/broker_pool_spec.rb +98 -0
  57. data/spec/unit/cluster_metadata_spec.rb +46 -0
  58. data/spec/unit/compression/gzip_codec_spec.rb +34 -0
  59. data/spec/unit/compression/snappy_codec_spec.rb +49 -0
  60. data/spec/unit/compression_spec.rb +17 -0
  61. data/spec/unit/connection_spec.rb +4 -0
  62. data/spec/unit/fetched_message_spec.rb +11 -0
  63. data/spec/unit/message_conductor_spec.rb +164 -0
  64. data/spec/unit/message_set_spec.rb +42 -0
  65. data/spec/unit/message_spec.rb +129 -0
  66. data/spec/unit/message_to_send_spec.rb +10 -0
  67. data/spec/unit/messages_for_broker_spec.rb +54 -0
  68. data/spec/unit/messages_to_send_batch_spec.rb +25 -0
  69. data/spec/unit/messages_to_send_spec.rb +63 -0
  70. data/spec/unit/partition_consumer_spec.rb +142 -0
  71. data/spec/unit/producer_compression_config_spec.rb +42 -0
  72. data/spec/unit/producer_spec.rb +51 -0
  73. data/spec/unit/protocol/request_buffer_spec.rb +16 -0
  74. data/spec/unit/protocol_spec.rb +54 -0
  75. data/spec/unit/sync_producer_spec.rb +156 -0
  76. data/spec/unit/topic_metadata_spec.rb +43 -0
  77. metadata +225 -0
@@ -0,0 +1,144 @@
1
+ require 'integration/multiple_brokers/spec_helper'
2
+
3
+ # Created because you can't use a block form for receive with and_call_original
4
+ # https://github.com/rspec/rspec-mocks/issues/774
5
+ RSpec::Matchers.define :a_broker_id_of do |id|
6
+ match { |actual| actual.broker_id == id }
7
+ end
8
+
9
+ RSpec::Matchers.define :a_broker_id_not do |id|
10
+ match { |actual| actual.broker_id != id }
11
+ end
12
+
13
+ RSpec::Matchers.define :needing_metadata do |val|
14
+ match { |actual| actual.send(:needs_metadata?) == val }
15
+ end
16
+
17
+ RSpec.describe "handling failures", :type => :request do
18
+ include_context "a multiple broker cluster"
19
+
20
+ describe "metadata failures" do
21
+ before(:each) do
22
+ @messages_to_send = [
23
+ MessageToSend.new("topic1", "hello"),
24
+ MessageToSend.new("topic2", "hello")
25
+ ]
26
+ end
27
+
28
+ describe "unable to connect to brokers" do
29
+ before(:each) do
30
+ @p = Producer.new(["localhost:1092","localhost:1093","localhost:1094"], "producer")
31
+ end
32
+
33
+ it "triggers callback failures for both topics" do
34
+ expect {
35
+ @p.send_messages(@messages_to_send)
36
+ }.to raise_error(Poseidon::Errors::UnableToFetchMetadata)
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "unknown topic" do
42
+ it "receives error callback" do
43
+ pending "need a way to turn off auto-topic creation just for this test"
44
+ @p = Producer.new(["localhost:9092","localhost:9093","localhost:9094"], "producer")
45
+
46
+ expect {
47
+ @p.send_messages([MessageToSend.new("imnothere", "hello")])
48
+ }.to raise_error(Poseidon::Errors::UnableToFetchMetadata)
49
+ end
50
+ end
51
+
52
+ describe "leader node loss" do
53
+ let(:topic) { "testing" }
54
+ let(:kafka_partitions) { 1 }
55
+
56
+ it "is still able to send messages" do
57
+ @p = Producer.new(["localhost:9092","localhost:9093","localhost:9094"], "producer", :required_acks => 1)
58
+
59
+ # Send one to force topic creation
60
+ expect(@p.send_messages([MessageToSend.new(topic, "hello")])).to be_truthy
61
+
62
+ @producer = @p.instance_variable_get(:@producer)
63
+ @cluster_metadata = @producer.instance_variable_get(:@cluster_metadata)
64
+ topic_metadata = @cluster_metadata.metadata_for_topics([topic])[topic]
65
+
66
+ expect(topic_metadata.available_partitions.length).to be(kafka_partitions)
67
+
68
+ # Now, lets kill the topic leader
69
+ leader = topic_metadata.available_partitions.first.leader
70
+ broker = $tc.brokers[topic_metadata.available_partitions.first.leader]
71
+ expect(broker.id).to be(leader)
72
+
73
+ broker.without_process do
74
+ expect(@cluster_metadata.metadata_for_topics([topic])[topic].available_partitions.first.leader).to be(leader)
75
+ expect(@producer.send(:refresh_interval_elapsed?)).to be_falsy
76
+
77
+ # Setup expectations that the consumer updates its info
78
+ expect(@producer).to receive(:ensure_metadata_available_for_topics).with(needing_metadata(false)).ordered.and_call_original
79
+ expect(@producer).to receive(:send_to_broker).with(a_broker_id_of(leader)).ordered.and_call_original
80
+
81
+ expect(@producer).to receive(:reset_metadata).ordered.and_call_original
82
+ expect(@producer).to receive(:ensure_metadata_available_for_topics).ordered.and_call_original
83
+ expect(@producer).to receive(:send_to_broker).with(a_broker_id_not(leader)).ordered.and_call_original
84
+
85
+ expect(@p.send_messages([MessageToSend.new(topic, "hello")])).to be_truthy
86
+ end
87
+ end
88
+ end
89
+
90
+ describe "partition replica loss" do
91
+ let(:topic) { "testing" }
92
+ let(:kafka_partitions) { 1 }
93
+
94
+ it "refreshes metadata correctly" do
95
+ @p = Producer.new(["localhost:9092","localhost:9093","localhost:9094"], "producer", :required_acks => 1)
96
+
97
+ # Send one to force topic creation
98
+ expect(@p.send_messages([MessageToSend.new(topic, "hello")])).to be_truthy
99
+
100
+ @producer = @p.instance_variable_get(:@producer)
101
+ @cluster_metadata = @producer.instance_variable_get(:@cluster_metadata)
102
+ topic_metadata = @cluster_metadata.metadata_for_topics([topic])[topic]
103
+
104
+ expect(topic_metadata.available_partitions.length).to be(kafka_partitions)
105
+ expect(topic_metadata.available_partitions.first.error).to be(0)
106
+
107
+ # Now, lets kill the topic leader
108
+ partition_metadata = topic_metadata.available_partitions.first
109
+ expect(partition_metadata.replicas.length).to be(2)
110
+ leader = partition_metadata.leader
111
+ replica = (partition_metadata.replicas - [leader]).first
112
+
113
+ broker = $tc.brokers[replica]
114
+ expect(broker.id).to_not be(partition_metadata.leader)
115
+ expect(broker.id).to be(replica)
116
+
117
+ broker.without_process do
118
+ expect(@cluster_metadata.metadata_for_topics([topic])[topic].available_partitions.first.replicas).to include(replica)
119
+ expect(@producer.send(:refresh_interval_elapsed?)).to be_falsy
120
+
121
+ Timecop.travel(@producer.metadata_refresh_interval_ms) do
122
+ expect(@producer.send(:refresh_interval_elapsed?)).to be_truthy
123
+
124
+ # Setup expectations that the consumer updates its info
125
+ expect(@producer).to receive(:refresh_metadata).with(Set.new([topic])).ordered.and_call_original
126
+ expect(@producer).to receive(:ensure_metadata_available_for_topics).with(needing_metadata(false)).ordered.and_call_original
127
+ expect(@producer).to receive(:send_to_broker).with(a_broker_id_of(partition_metadata.leader)).ordered.and_call_original
128
+
129
+ # Make sure we don't error out
130
+ expect(@producer).to_not receive(:reset_metadata)
131
+
132
+ expect(@p.send_messages([MessageToSend.new(topic, "hello")])).to be_truthy
133
+
134
+ # Check the valid metadata
135
+ updated_topic_metadata = @cluster_metadata.metadata_for_topics([topic])[topic]
136
+ expect(updated_topic_metadata.available_partitions.length).to be(kafka_partitions)
137
+ expect(updated_topic_metadata.available_partitions.first.leader).to be(leader)
138
+ expect(updated_topic_metadata.available_partitions.first.replicas).to eq([leader])
139
+ expect(updated_topic_metadata.available_partitions.first.error).to be(9)
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,69 @@
1
+ require 'integration/multiple_brokers/spec_helper'
2
+
3
+ RSpec.describe "producer handles rebalancing", :type => :request do
4
+ include_context "a multiple broker cluster"
5
+
6
+ before(:each) do
7
+ # autocreate the topic by asking for information about it
8
+ @c = Connection.new("localhost", 9093, "metadata_fetcher", 10_000)
9
+ @c.topic_metadata(["failure_spec"])
10
+ sleep 1
11
+ end
12
+
13
+ def current_leadership_mapping(c)
14
+ metadata = c.topic_metadata(["failure_spec"])
15
+ topic_metadata = metadata.topics.find { |t| t.name == "failure_spec" }
16
+ (0..2).map { |p| topic_metadata.partition_leader(p) }
17
+ end
18
+
19
+ it "produces a bunch of messages and consumes all without error" do
20
+ @p = Producer.new(["localhost:9092","localhost:9093","localhost:9094"], "test",
21
+ :required_acks => -1)
22
+
23
+ 1.upto(25) do |n|
24
+ @p.send_messages([MessageToSend.new("failure_spec", n.to_s)])
25
+ end
26
+
27
+ # The goal here is to have the producer attempt to send messages
28
+ # to a broker which is no longer the leader for the partition.
29
+ #
30
+ # We accomplish this by turning off a broker which causes leadership
31
+ # to failover. Then we turn that broker back on and begin sending
32
+ # messages. While sending messages, the kafka cluster should rebalance
33
+ # the partitions causing leadership to switch back to the original
34
+ # broker in the midst of messages being sent.
35
+ #
36
+ # We compare leadership before and after the message sending period
37
+ # to make sure we were successful.
38
+ $tc.stop_first_broker
39
+ sleep 30
40
+ SPEC_LOGGER.info "Pre start #{current_leadership_mapping(@c).inspect}"
41
+ $tc.start_first_broker
42
+
43
+ pre_send_leadership = current_leadership_mapping(@c)
44
+ SPEC_LOGGER.info "Pre send #{pre_send_leadership.inspect}"
45
+ 26.upto(50) do |n|
46
+ sleep 0.5
47
+ @p.send_messages([MessageToSend.new("failure_spec", n.to_s)])
48
+ end
49
+ post_send_leadership = current_leadership_mapping(@c)
50
+ SPEC_LOGGER.info "Post send #{post_send_leadership.inspect}"
51
+
52
+ expect(pre_send_leadership).to_not eq(post_send_leadership)
53
+
54
+ messages = []
55
+ 0.upto(2) do |partition|
56
+ consumer = PartitionConsumer.consumer_for_partition("consumer_failure_spect",
57
+ ["localhost:9092","localhost:9093","localhost:9094"],
58
+ "failure_spec",
59
+ partition,
60
+ :earliest_offset)
61
+ while (fetched = consumer.fetch).any?
62
+ messages.push(*fetched)
63
+ end
64
+ end
65
+
66
+ expect(messages.size).to eq(50)
67
+ expect(messages.map { |m| m.value.to_i }.sort).to eq((1..50).to_a)
68
+ end
69
+ end
@@ -0,0 +1,41 @@
1
+ require 'integration/multiple_brokers/spec_helper'
2
+
3
+ RSpec.describe "round robin sending", :type => :request do
4
+ include_context "a multiple broker cluster"
5
+
6
+ describe "with small message batches" do
7
+ it "evenly distributes messages across brokers" do
8
+ c = Connection.new("localhost", 9092, "metadata_fetcher", 10_000)
9
+ md = c.topic_metadata(["test"])
10
+ sleep 1
11
+ md = c.topic_metadata(["test"])
12
+
13
+ test_topic = md.topics.first
14
+
15
+ consumers = test_topic.send(:partitions).map do |partition|
16
+ leader_id = partition.leader
17
+ broker = md.brokers.find { |b| b.id == leader_id }
18
+ PartitionConsumer.new("test_consumer_#{partition.id}", broker.host,
19
+ broker.port, "test", partition.id, -1)
20
+ end
21
+
22
+ # Update offsets to current position before adding test messages
23
+ consumers.each do |c|
24
+ c.fetch
25
+ end
26
+
27
+ @p = Producer.new(["localhost:9092","localhost:9093","localhost:9094"], "test",
28
+ :required_acks => 1)
29
+ 24.times do
30
+ @p.send_messages([MessageToSend.new("test", "hello")])
31
+ end
32
+
33
+ sleep 5
34
+
35
+ consumers.each do |c|
36
+ messages = c.fetch
37
+ expect(messages.size).to eq(8)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ require 'test_cluster'
4
+
5
+ class ThreeBrokerCluster
6
+ attr_reader :brokers, :zookeeper
7
+
8
+ def initialize(partitions, properties = {})
9
+ @zookeeper = ZookeeperRunner.new
10
+ @brokers = (9092..9094).map { |port| BrokerRunner.new(port - 9092, port,
11
+ partitions,
12
+ 2,
13
+ properties) }
14
+ end
15
+
16
+ def start
17
+ @zookeeper.start
18
+ @brokers.each(&:start)
19
+ sleep 5
20
+ end
21
+
22
+ def stop
23
+ SPEC_LOGGER.info "Stopping three broker cluster"
24
+ SPEC_LOGGER.info "Stopping brokers"
25
+ @brokers.each(&:stop)
26
+ sleep 5
27
+
28
+ SPEC_LOGGER.info "Stopping ZK"
29
+ @zookeeper.stop
30
+ sleep 5
31
+ end
32
+
33
+ def stop_first_broker
34
+ SPEC_LOGGER.info "Stopping first broker"
35
+ @brokers.first.stop
36
+ sleep 5
37
+ end
38
+
39
+ def start_first_broker
40
+ SPEC_LOGGER.info "Starting first broker"
41
+ @brokers.first.start
42
+ end
43
+ end
44
+
45
+ RSpec.shared_context "a multiple broker cluster" do
46
+ let(:kafka_partitions) { 3 }
47
+
48
+ before(:each) do
49
+ JavaRunner.remove_tmp
50
+ JavaRunner.set_kafka_path!
51
+ $tc = ThreeBrokerCluster.new(kafka_partitions)
52
+ $tc.start
53
+ SPEC_LOGGER.info "Waiting on cluster"
54
+ sleep 10 # wait for cluster to come up
55
+ end
56
+
57
+ after(:each) do
58
+ $tc.stop if $tc
59
+ end
60
+ end
@@ -0,0 +1,23 @@
1
+ require 'integration/simple/spec_helper'
2
+
3
+ RSpec.describe "compression", :type => :request do
4
+ include_context "a single broker cluster"
5
+
6
+ it "roundtrips" do
7
+ i = rand(1000)
8
+
9
+ @consumer = PartitionConsumer.new("test_consumer", "localhost", 9092,
10
+ "test12", 0, -2)
11
+
12
+ @producer = Producer.new(["localhost:9092"],
13
+ "test_client",
14
+ :type => :sync,
15
+ :compression_codec => :gzip)
16
+ messages = [MessageToSend.new("test12", "Hello World: #{i}")]
17
+
18
+ expect(@producer.send_messages(messages)).to eq(true)
19
+ sleep 1
20
+ messages = @consumer.fetch
21
+ expect(messages.last.value).to eq("Hello World: #{i}")
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ require 'integration/simple/spec_helper'
2
+
3
+ include Protocol
4
+ RSpec.describe Connection, :type => :request do
5
+ include_context "a single broker cluster"
6
+
7
+ before(:each) do
8
+ @connection = Connection.new("localhost", 9092, "test", 10_000)
9
+ end
10
+
11
+ it 'sends and parses topic metadata requests' do
12
+ @connection.topic_metadata(["test2"])
13
+ end
14
+
15
+ it 'sends and parsers produce requests' do
16
+ message = MessageStruct.new(0, 0, nil, "hello")
17
+ message_with_offset = MessageWithOffsetStruct.new(0, message)
18
+ message_set = MessageSetStruct.new([message_with_offset])
19
+ messages_for_partitions = [MessagesForPartition.new(0,message_set)]
20
+ messages_for_topics = [MessagesForTopic.new("test2",messages_for_partitions)]
21
+ @connection.produce(1, 10_000, messages_for_topics)
22
+ end
23
+
24
+ it 'sends and parsers fetch requests' do
25
+ partition_fetches = [PartitionFetch.new(0,0,1024*1024)]
26
+ topic_fetches = [TopicFetch.new("test2", partition_fetches)]
27
+ @connection.fetch(1000, 0, topic_fetches)
28
+ end
29
+
30
+ it 'sends and parsers offset requests' do
31
+ partition_offset_requests = [PartitionOffsetRequest.new(0,-1,1000)]
32
+ offset_topic_requests = [TopicOffsetRequest.new("test2", partition_offset_requests)]
33
+ @connection.offset(offset_topic_requests)
34
+ end
35
+ end
@@ -0,0 +1,10 @@
1
+ require 'integration/simple/spec_helper'
2
+
3
+ RSpec.describe "three brokers in cluster", :type => :request do
4
+ include_context "a single broker cluster"
5
+
6
+ describe "sending batches of 1 message" do
7
+ it "sends messages to all brokers" do
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,121 @@
1
+ require 'integration/simple/spec_helper'
2
+
3
+ RSpec.describe "simple producer and consumer", :type => :request do
4
+ include_context "a single broker cluster"
5
+
6
+ describe "writing and consuming one topic" do
7
+ it "fetches produced messages" do
8
+ @producer = Producer.new(["localhost:9092"],
9
+ "test_client",
10
+ :type => :sync)
11
+
12
+
13
+ messages = [MessageToSend.new("topic_simple_producer_and_consumer", "Hello World")]
14
+ expect(@producer.send_messages(messages)).to eq(true)
15
+
16
+ @consumer = PartitionConsumer.new("test_consumer", "localhost", 9092,
17
+ "topic_simple_producer_and_consumer", 0, -2)
18
+ messages = @consumer.fetch
19
+ expect(messages.last.value).to eq("Hello World")
20
+
21
+ @producer.close
22
+ end
23
+
24
+ it "fetches only messages since the last offset" do
25
+ @producer = Producer.new(["localhost:9092"],
26
+ "test_client",
27
+ :type => :sync,
28
+ :required_acks => 1)
29
+
30
+ @consumer = PartitionConsumer.new("test_consumer", "localhost", 9092,
31
+ "topic_simple_producer_and_consumer", 0, -1)
32
+
33
+ # Read up to the end of the current messages (if there are any)
34
+ begin
35
+ @consumer.fetch
36
+ rescue Errors::UnknownTopicOrPartition
37
+ end
38
+
39
+ # First Batch
40
+ messages = [MessageToSend.new("topic_simple_producer_and_consumer", "Hello World")]
41
+ expect(@producer.send_messages(messages)).to eq(true)
42
+
43
+ messages = @consumer.fetch
44
+ expect(messages.last.value).to eq("Hello World")
45
+
46
+ # Second Batch
47
+ messages = [MessageToSend.new("topic_simple_producer_and_consumer", "Hello World Again")]
48
+ expect(@producer.send_messages(messages)).to eq(true)
49
+
50
+ messages = @consumer.fetch
51
+ expect(messages.map(&:value)).to eq(["Hello World Again"])
52
+
53
+ # Empty Batch
54
+ messages = @consumer.fetch
55
+ expect(messages.empty?).to eq(true)
56
+ end
57
+
58
+ it "waits for messages" do
59
+ # Create topic
60
+ @c = Connection.new("localhost", 9092, "metadata_fetcher", 10_000)
61
+ @c.topic_metadata(["simple_wait_test"])
62
+
63
+ sleep 5
64
+ @consumer = PartitionConsumer.new("test_consumer", "localhost", 9092,
65
+ "simple_wait_test", 0, :earliest_offset,
66
+ :max_wait_ms => 2500)
67
+
68
+ require 'benchmark'
69
+ n = Benchmark.realtime do
70
+ @consumer.fetch
71
+ end
72
+ expect(n).to be_within(0.25).of(2.5)
73
+ end
74
+
75
+ # Not sure what's going on here, will revisit.
76
+ =begin
77
+ it "fetches larger messages with a larger max bytes size" do
78
+ @producer = Producer.new(["localhost:9092"],
79
+ "test_client",
80
+ :type => :sync,
81
+ :required_acks => 1)
82
+
83
+ @consumer = PartitionConsumer.new("test_consumer", "localhost", 9092,
84
+ "topic_simple_producer_and_consumer", 0, -2)
85
+
86
+ messages = []
87
+ 2000.times do
88
+ messages << MessageToSend.new("topic_simple_producer_and_consumer",'KcjNyFBtqfSbpwjjcGKckMKLUCWz83IVcp21C8FQzs8JJKKTTrc4OLxSjLpYc5z7fsncX59te2cBn0sWDRaYmRuZyttRMLMHvXrM5o3QReKPIYUKzVCFahC4cb3Ivcbb5ZuS98Ohnb7Io42Bz9FucXwwGkQyFhJwyn3nD3BYs5r8TZM8Q76CGR2kTH1rjnFeB7J3hrRKukztxCrDY3smrQE1bbVR80IF3yWlhzkdfv3cpfwnD0TKadtt21sFJANFmORAJ0HKs6Z2262hcBQyF7WcWypC2RoLWVgKVQxbouVUP7yV6YYOAQEevYrl9sOB0Yi6h1mS8fTBUmRTmWLqyl8KzwbnbQvmCvgnX26F5JEzIoXsVaoDT2ks5eep9RyE1zm5yPtbYVmd2Sz7t5ru0wj6YiAmbF7Xgiw2l4VpNOxG0Ec6rFxXRXs0bahyBd2YtxpGyZBeruIK1RAN4n0t97xVXgZG5CGoVhL1oRDxw2pTbwEO1cvwHiiYXpXSqaxF7G9kiiPsQt24Vu7chXrJT7Xqv4RIg1aOT5Os5JVlISaJCmx8ZLtbC3OjAdGtF1ZkDuUeQHHohqeKh0qBJjw7Rv1oSDwcM0MRazjF36jijpYg26Qml9lSEnGYIFLQWHVDWKqqhl2GIntjxDXn1IyI')
89
+ end
90
+ expect(@producer.send_messages(messages)).to eq(true)
91
+
92
+ messages = @consumer.fetch
93
+ expect(messages.length).to be > 2
94
+
95
+ @consumer = PartitionConsumer.new("test_consumer", "localhost", 9092,
96
+ "topic_simple_producer_and_consumer", 0, -2)
97
+ messages = @consumer.fetch(:max_bytes => 1400000)
98
+ expect(messages.length).to be > 2
99
+ end
100
+ =end
101
+ end
102
+
103
+ describe "broker that becomes unavailable" do
104
+ it "fails the fetch" do
105
+ @producer = Producer.new(["localhost:9092"],
106
+ "test_client",
107
+ :type => :sync)
108
+
109
+
110
+ messages = [MessageToSend.new("topic_simple_producer_and_consumer", "Hello World")]
111
+ expect(@producer.send_messages(messages)).to eq(true)
112
+
113
+ @consumer = PartitionConsumer.new("test_consumer", "localhost", 9092,
114
+ "topic_simple_producer_and_consumer", 0, -2)
115
+
116
+ $tc.broker.without_process do
117
+ expect { @consumer.fetch }.to raise_error(Connection::ConnectionFailedError)
118
+ end
119
+ end
120
+ end
121
+ end