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.
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