-
Notifications
You must be signed in to change notification settings - Fork 43
/
consumer_spec.rb
146 lines (125 loc) · 5.83 KB
/
consumer_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require File.dirname(__FILE__) + '/spec_helper'
describe Consumer do
before(:each) do
@mocked_socket = mock(TCPSocket)
TCPSocket.stub!(:new).and_return(@mocked_socket) # don't use a real socket
@consumer = Consumer.new(:offset => 0)
end
describe "Kafka Consumer" do
it "should have a Kafka::RequestType::FETCH" do
Kafka::RequestType::FETCH.should eql(1)
@consumer.should respond_to(:request_type)
end
it "should have a topic and a partition" do
@consumer.should respond_to(:topic)
@consumer.should respond_to(:partition)
end
it "should have a polling option, and a default value" do
Consumer::DEFAULT_POLLING_INTERVAL.should eql(2)
@consumer.should respond_to(:polling)
@consumer.polling.should eql(2)
end
it "should set a topic and partition on initialize" do
@consumer = Consumer.new({ :host => "localhost", :port => 9092, :topic => "testing" })
@consumer.topic.should eql("testing")
@consumer.partition.should eql(0)
@consumer = Consumer.new({ :topic => "testing", :partition => 3 })
@consumer.partition.should eql(3)
end
it "should set default host and port if none is specified" do
@consumer = Consumer.new
@consumer.host.should eql("localhost")
@consumer.port.should eql(9092)
end
it "should not have a default offset but be able to set it" do
@consumer = Consumer.new
@consumer.offset.should be_nil
@consumer = Consumer.new({ :offset => 1111 })
@consumer.offset.should eql(1111)
end
it "should have a max size" do
Consumer::MAX_SIZE.should eql(1048576)
@consumer.max_size.should eql(1048576)
end
it "should return the size of the request" do
@consumer.topic = "someothertopicname"
@consumer.encoded_request_size.should eql([38].pack("N"))
end
it "should encode a request to consume" do
bytes = [Kafka::RequestType::FETCH].pack("n") + ["test".length].pack("n") + "test" + [0].pack("N") + [0].pack("q").reverse + [Kafka::Consumer::MAX_SIZE].pack("N")
@consumer.encode_request(Kafka::RequestType::FETCH, "test", 0, 0, Kafka::Consumer::MAX_SIZE).should eql(bytes)
end
it "should read the response data" do
bytes = [0].pack("n") + [1120192889].pack("N") + "ale"
@mocked_socket.should_receive(:read).and_return([9].pack("N"))
@mocked_socket.should_receive(:read).with(9).and_return(bytes)
@consumer.read_data_response.should eql(bytes[2,7])
end
it "should send a consumer request" do
@consumer.stub!(:encoded_request_size).and_return(666)
@consumer.stub!(:encode_request).and_return("someencodedrequest")
@consumer.should_receive(:write).with("someencodedrequest").exactly(:once).and_return(true)
@consumer.should_receive(:write).with(666).exactly(:once).and_return(true)
@consumer.send_consume_request.should eql(true)
end
it "should consume messages" do
@consumer.should_receive(:send_consume_request).and_return(true)
@consumer.should_receive(:read_data_response).and_return("")
@consumer.consume.should eql([])
end
it "should loop and execute a block with the consumed messages" do
@consumer.stub!(:consume).and_return([mock(Kafka::Message)])
messages = []
messages.should_receive(:<<).exactly(:once).and_return([])
@consumer.loop do |message|
messages << message
break # we don't wanna loop forever on the test
end
end
it "should loop (every N seconds, configurable on polling attribute), and execute a block with the consumed messages" do
@consumer = Consumer.new({ :polling => 1 })
@consumer.stub!(:consume).and_return([mock(Kafka::Message)])
messages = []
messages.should_receive(:<<).exactly(:twice).and_return([])
executed_times = 0
@consumer.loop do |message|
messages << message
executed_times += 1
break if executed_times >= 2 # we don't wanna loop forever on the test, only 2 seconds
end
executed_times.should eql(2)
end
it "should fetch initial offset if no offset is given" do
@consumer = Consumer.new
@consumer.should_receive(:fetch_latest_offset).exactly(:once).and_return(1000)
@consumer.should_receive(:send_consume_request).and_return(true)
@consumer.should_receive(:read_data_response).and_return("")
@consumer.consume
@consumer.offset.should eql(1000)
end
it "should encode an offset request" do
bytes = [Kafka::RequestType::OFFSETS].pack("n") + ["test".length].pack("n") + "test" + [0].pack("N") + [-1].pack("q").reverse + [Kafka::Consumer::MAX_OFFSETS].pack("N")
@consumer.encode_request(Kafka::RequestType::OFFSETS, "test", 0, -1, Kafka::Consumer::MAX_OFFSETS).should eql(bytes)
end
it "should parse an offsets response" do
bytes = [0].pack("n") + [1].pack('N') + [21346].pack('q').reverse
@mocked_socket.should_receive(:read).and_return([14].pack("N"))
@mocked_socket.should_receive(:read).and_return(bytes)
@consumer.read_offsets_response.should eql(21346)
end
end
end