thrift 0.9.2.0 → 0.14.0
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/ext/binary_protocol_accelerated.c +12 -12
- data/ext/struct.c +5 -1
- data/lib/thrift.rb +8 -4
- data/lib/thrift/multiplexed_processor.rb +76 -0
- data/lib/thrift/processor.rb +24 -6
- data/lib/thrift/protocol/base_protocol.rb +11 -3
- data/lib/thrift/protocol/binary_protocol.rb +8 -1
- data/lib/thrift/protocol/binary_protocol_accelerated.rb +8 -0
- data/lib/thrift/protocol/compact_protocol.rb +8 -0
- data/lib/thrift/protocol/json_protocol.rb +21 -4
- data/lib/thrift/protocol/multiplexed_protocol.rb +44 -0
- data/lib/thrift/protocol/protocol_decorator.rb +194 -0
- data/lib/thrift/server/base_server.rb +8 -2
- data/lib/thrift/server/simple_server.rb +5 -1
- data/lib/thrift/server/thread_pool_server.rb +5 -1
- data/lib/thrift/server/threaded_server.rb +5 -1
- data/lib/thrift/transport/base_server_transport.rb +1 -1
- data/lib/thrift/transport/base_transport.rb +8 -0
- data/lib/thrift/transport/buffered_transport.rb +9 -1
- data/lib/thrift/transport/framed_transport.rb +9 -1
- data/lib/thrift/transport/http_client_transport.rb +7 -0
- data/lib/thrift/transport/io_stream_transport.rb +4 -1
- data/lib/thrift/transport/memory_buffer_transport.rb +4 -0
- data/lib/thrift/transport/server_socket.rb +6 -1
- data/lib/thrift/transport/socket.rb +21 -17
- data/lib/thrift/transport/ssl_server_socket.rb +41 -0
- data/lib/thrift/transport/ssl_socket.rb +51 -0
- data/lib/thrift/transport/unix_server_socket.rb +5 -1
- data/lib/thrift/transport/unix_socket.rb +5 -1
- data/lib/thrift/union.rb +3 -6
- data/spec/BaseService.thrift +27 -0
- data/spec/ExtendedService.thrift +25 -0
- data/spec/base_protocol_spec.rb +79 -71
- data/spec/base_transport_spec.rb +155 -117
- data/spec/binary_protocol_accelerated_spec.rb +6 -2
- data/spec/binary_protocol_spec.rb +16 -8
- data/spec/binary_protocol_spec_shared.rb +75 -72
- data/spec/bytes_spec.rb +38 -38
- data/spec/client_spec.rb +41 -42
- data/spec/compact_protocol_spec.rb +32 -17
- data/spec/exception_spec.rb +54 -54
- data/spec/flat_spec.rb +62 -0
- data/spec/http_client_spec.rb +74 -33
- data/spec/json_protocol_spec.rb +170 -131
- data/spec/namespaced_spec.rb +10 -5
- data/spec/nonblocking_server_spec.rb +16 -16
- data/spec/processor_spec.rb +26 -26
- data/spec/serializer_spec.rb +20 -20
- data/spec/server_socket_spec.rb +27 -22
- data/spec/server_spec.rb +91 -51
- data/spec/socket_spec.rb +23 -16
- data/spec/socket_spec_shared.rb +31 -31
- data/spec/spec_helper.rb +4 -1
- data/spec/ssl_server_socket_spec.rb +34 -0
- data/spec/ssl_socket_spec.rb +78 -0
- data/spec/struct_nested_containers_spec.rb +24 -24
- data/spec/struct_spec.rb +120 -120
- data/spec/thin_http_server_spec.rb +18 -18
- data/spec/types_spec.rb +56 -53
- data/spec/union_spec.rb +51 -40
- data/spec/unix_socket_spec.rb +43 -34
- metadata +191 -143
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
#
|
3
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
4
|
+
# or more contributor license agreements. See the NOTICE file
|
5
|
+
# distributed with this work for additional information
|
6
|
+
# regarding copyright ownership. The ASF licenses this file
|
7
|
+
# to you under the Apache License, Version 2.0 (the
|
8
|
+
# "License"); you may not use this file except in compliance
|
9
|
+
# with the License. You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing,
|
14
|
+
# software distributed under the License is distributed on an
|
15
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
16
|
+
# KIND, either express or implied. See the License for the
|
17
|
+
# specific language governing permissions and limitations
|
18
|
+
# under the License.
|
19
|
+
|
20
|
+
module Thrift
|
21
|
+
class SSLSocket < Socket
|
22
|
+
def initialize(host='localhost', port=9090, timeout=nil, ssl_context=nil)
|
23
|
+
super(host, port, timeout)
|
24
|
+
@ssl_context = ssl_context
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_accessor :ssl_context
|
28
|
+
|
29
|
+
def open
|
30
|
+
socket = super
|
31
|
+
@handle = OpenSSL::SSL::SSLSocket.new(socket, @ssl_context)
|
32
|
+
begin
|
33
|
+
@handle.connect_nonblock
|
34
|
+
@handle.post_connection_check(@host)
|
35
|
+
@handle
|
36
|
+
rescue IO::WaitReadable
|
37
|
+
IO.select([ @handle ], nil, nil, @timeout)
|
38
|
+
retry
|
39
|
+
rescue IO::WaitWritable
|
40
|
+
IO.select(nil, [ @handle ], nil, @timeout)
|
41
|
+
retry
|
42
|
+
rescue StandardError => e
|
43
|
+
raise TransportException.new(TransportException::NOT_OPEN, "Could not connect to #{@desc}: #{e}")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
"ssl(#{super.to_s})"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/thrift/union.rb
CHANGED
@@ -87,12 +87,9 @@ module Thrift
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def ==(other)
|
90
|
-
other
|
91
|
-
end
|
92
|
-
|
93
|
-
def eql?(other)
|
94
|
-
self.class == other.class && self == other
|
90
|
+
other.equal?(self) || other.instance_of?(self.class) && @setfield == other.get_set_field && @value == other.get_value
|
95
91
|
end
|
92
|
+
alias_method :eql?, :==
|
96
93
|
|
97
94
|
def hash
|
98
95
|
[self.class.name, @setfield, @value].hash
|
@@ -176,4 +173,4 @@ module Thrift
|
|
176
173
|
end
|
177
174
|
end
|
178
175
|
end
|
179
|
-
end
|
176
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
namespace rb Base
|
20
|
+
|
21
|
+
struct Hello {
|
22
|
+
1: string greeting = "hello world"
|
23
|
+
}
|
24
|
+
|
25
|
+
service BaseService {
|
26
|
+
Hello greeting(1:bool english)
|
27
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Licensed to the Apache Software Foundation (ASF) under one
|
2
|
+
# or more contributor license agreements. See the NOTICE file
|
3
|
+
# distributed with this work for additional information
|
4
|
+
# regarding copyright ownership. The ASF licenses this file
|
5
|
+
# to you under the Apache License, Version 2.0 (the
|
6
|
+
# "License"); you may not use this file except in compliance
|
7
|
+
# with the License. You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
namespace rb Extended
|
20
|
+
|
21
|
+
include "BaseService.thrift"
|
22
|
+
|
23
|
+
service ExtendedService extends BaseService.BaseService {
|
24
|
+
void ping()
|
25
|
+
}
|
data/spec/base_protocol_spec.rb
CHANGED
@@ -22,41 +22,46 @@ require 'spec_helper'
|
|
22
22
|
describe 'BaseProtocol' do
|
23
23
|
|
24
24
|
before(:each) do
|
25
|
-
@trans =
|
25
|
+
@trans = double("MockTransport")
|
26
26
|
@prot = Thrift::BaseProtocol.new(@trans)
|
27
27
|
end
|
28
28
|
|
29
29
|
describe Thrift::BaseProtocol do
|
30
30
|
# most of the methods are stubs, so we can ignore them
|
31
31
|
|
32
|
+
it "should provide a reasonable to_s" do
|
33
|
+
expect(@trans).to receive(:to_s).once.and_return("trans")
|
34
|
+
expect(@prot.to_s).to eq("trans")
|
35
|
+
end
|
36
|
+
|
32
37
|
it "should make trans accessible" do
|
33
|
-
@prot.trans.
|
38
|
+
expect(@prot.trans).to eql(@trans)
|
34
39
|
end
|
35
40
|
|
36
41
|
it 'should write out a field nicely (deprecated write_field signature)' do
|
37
|
-
@prot.
|
38
|
-
@prot.
|
39
|
-
@prot.
|
42
|
+
expect(@prot).to receive(:write_field_begin).with('field', 'type', 'fid').ordered
|
43
|
+
expect(@prot).to receive(:write_type).with({:name => 'field', :type => 'type'}, 'value').ordered
|
44
|
+
expect(@prot).to receive(:write_field_end).ordered
|
40
45
|
@prot.write_field('field', 'type', 'fid', 'value')
|
41
46
|
end
|
42
47
|
|
43
48
|
it 'should write out a field nicely' do
|
44
|
-
@prot.
|
45
|
-
@prot.
|
46
|
-
@prot.
|
49
|
+
expect(@prot).to receive(:write_field_begin).with('field', 'type', 'fid').ordered
|
50
|
+
expect(@prot).to receive(:write_type).with({:name => 'field', :type => 'type', :binary => false}, 'value').ordered
|
51
|
+
expect(@prot).to receive(:write_field_end).ordered
|
47
52
|
@prot.write_field({:name => 'field', :type => 'type', :binary => false}, 'fid', 'value')
|
48
53
|
end
|
49
54
|
|
50
55
|
it 'should write out the different types (deprecated write_type signature)' do
|
51
|
-
@prot.
|
52
|
-
@prot.
|
53
|
-
@prot.
|
54
|
-
@prot.
|
55
|
-
@prot.
|
56
|
-
@prot.
|
57
|
-
@prot.
|
58
|
-
struct =
|
59
|
-
struct.
|
56
|
+
expect(@prot).to receive(:write_bool).with('bool').ordered
|
57
|
+
expect(@prot).to receive(:write_byte).with('byte').ordered
|
58
|
+
expect(@prot).to receive(:write_double).with('double').ordered
|
59
|
+
expect(@prot).to receive(:write_i16).with('i16').ordered
|
60
|
+
expect(@prot).to receive(:write_i32).with('i32').ordered
|
61
|
+
expect(@prot).to receive(:write_i64).with('i64').ordered
|
62
|
+
expect(@prot).to receive(:write_string).with('string').ordered
|
63
|
+
struct = double('Struct')
|
64
|
+
expect(struct).to receive(:write).with(@prot).ordered
|
60
65
|
@prot.write_type(Thrift::Types::BOOL, 'bool')
|
61
66
|
@prot.write_type(Thrift::Types::BYTE, 'byte')
|
62
67
|
@prot.write_type(Thrift::Types::DOUBLE, 'double')
|
@@ -72,16 +77,16 @@ describe 'BaseProtocol' do
|
|
72
77
|
end
|
73
78
|
|
74
79
|
it 'should write out the different types' do
|
75
|
-
@prot.
|
76
|
-
@prot.
|
77
|
-
@prot.
|
78
|
-
@prot.
|
79
|
-
@prot.
|
80
|
-
@prot.
|
81
|
-
@prot.
|
82
|
-
@prot.
|
83
|
-
struct =
|
84
|
-
struct.
|
80
|
+
expect(@prot).to receive(:write_bool).with('bool').ordered
|
81
|
+
expect(@prot).to receive(:write_byte).with('byte').ordered
|
82
|
+
expect(@prot).to receive(:write_double).with('double').ordered
|
83
|
+
expect(@prot).to receive(:write_i16).with('i16').ordered
|
84
|
+
expect(@prot).to receive(:write_i32).with('i32').ordered
|
85
|
+
expect(@prot).to receive(:write_i64).with('i64').ordered
|
86
|
+
expect(@prot).to receive(:write_string).with('string').ordered
|
87
|
+
expect(@prot).to receive(:write_binary).with('binary').ordered
|
88
|
+
struct = double('Struct')
|
89
|
+
expect(struct).to receive(:write).with(@prot).ordered
|
85
90
|
@prot.write_type({:type => Thrift::Types::BOOL}, 'bool')
|
86
91
|
@prot.write_type({:type => Thrift::Types::BYTE}, 'byte')
|
87
92
|
@prot.write_type({:type => Thrift::Types::DOUBLE}, 'double')
|
@@ -98,13 +103,13 @@ describe 'BaseProtocol' do
|
|
98
103
|
end
|
99
104
|
|
100
105
|
it 'should read the different types (deprecated read_type signature)' do
|
101
|
-
@prot.
|
102
|
-
@prot.
|
103
|
-
@prot.
|
104
|
-
@prot.
|
105
|
-
@prot.
|
106
|
-
@prot.
|
107
|
-
@prot.
|
106
|
+
expect(@prot).to receive(:read_bool).ordered
|
107
|
+
expect(@prot).to receive(:read_byte).ordered
|
108
|
+
expect(@prot).to receive(:read_i16).ordered
|
109
|
+
expect(@prot).to receive(:read_i32).ordered
|
110
|
+
expect(@prot).to receive(:read_i64).ordered
|
111
|
+
expect(@prot).to receive(:read_double).ordered
|
112
|
+
expect(@prot).to receive(:read_string).ordered
|
108
113
|
@prot.read_type(Thrift::Types::BOOL)
|
109
114
|
@prot.read_type(Thrift::Types::BYTE)
|
110
115
|
@prot.read_type(Thrift::Types::I16)
|
@@ -120,14 +125,14 @@ describe 'BaseProtocol' do
|
|
120
125
|
end
|
121
126
|
|
122
127
|
it 'should read the different types' do
|
123
|
-
@prot.
|
124
|
-
@prot.
|
125
|
-
@prot.
|
126
|
-
@prot.
|
127
|
-
@prot.
|
128
|
-
@prot.
|
129
|
-
@prot.
|
130
|
-
@prot.
|
128
|
+
expect(@prot).to receive(:read_bool).ordered
|
129
|
+
expect(@prot).to receive(:read_byte).ordered
|
130
|
+
expect(@prot).to receive(:read_i16).ordered
|
131
|
+
expect(@prot).to receive(:read_i32).ordered
|
132
|
+
expect(@prot).to receive(:read_i64).ordered
|
133
|
+
expect(@prot).to receive(:read_double).ordered
|
134
|
+
expect(@prot).to receive(:read_string).ordered
|
135
|
+
expect(@prot).to receive(:read_binary).ordered
|
131
136
|
@prot.read_type({:type => Thrift::Types::BOOL})
|
132
137
|
@prot.read_type({:type => Thrift::Types::BYTE})
|
133
138
|
@prot.read_type({:type => Thrift::Types::I16})
|
@@ -144,13 +149,13 @@ describe 'BaseProtocol' do
|
|
144
149
|
end
|
145
150
|
|
146
151
|
it "should skip the basic types" do
|
147
|
-
@prot.
|
148
|
-
@prot.
|
149
|
-
@prot.
|
150
|
-
@prot.
|
151
|
-
@prot.
|
152
|
-
@prot.
|
153
|
-
@prot.
|
152
|
+
expect(@prot).to receive(:read_bool).ordered
|
153
|
+
expect(@prot).to receive(:read_byte).ordered
|
154
|
+
expect(@prot).to receive(:read_i16).ordered
|
155
|
+
expect(@prot).to receive(:read_i32).ordered
|
156
|
+
expect(@prot).to receive(:read_i64).ordered
|
157
|
+
expect(@prot).to receive(:read_double).ordered
|
158
|
+
expect(@prot).to receive(:read_string).ordered
|
154
159
|
@prot.skip(Thrift::Types::BOOL)
|
155
160
|
@prot.skip(Thrift::Types::BYTE)
|
156
161
|
@prot.skip(Thrift::Types::I16)
|
@@ -158,52 +163,51 @@ describe 'BaseProtocol' do
|
|
158
163
|
@prot.skip(Thrift::Types::I64)
|
159
164
|
@prot.skip(Thrift::Types::DOUBLE)
|
160
165
|
@prot.skip(Thrift::Types::STRING)
|
161
|
-
@prot.skip(Thrift::Types::STOP) # should do absolutely nothing
|
162
166
|
end
|
163
167
|
|
164
168
|
it "should skip structs" do
|
165
169
|
real_skip = @prot.method(:skip)
|
166
|
-
@prot.
|
167
|
-
@prot.
|
170
|
+
expect(@prot).to receive(:read_struct_begin).ordered
|
171
|
+
expect(@prot).to receive(:read_field_begin).exactly(4).times.and_return(
|
168
172
|
['field 1', Thrift::Types::STRING, 1],
|
169
173
|
['field 2', Thrift::Types::I32, 2],
|
170
174
|
['field 3', Thrift::Types::MAP, 3],
|
171
175
|
[nil, Thrift::Types::STOP, 0]
|
172
176
|
)
|
173
|
-
@prot.
|
174
|
-
@prot.
|
175
|
-
@prot.
|
176
|
-
@prot.
|
177
|
+
expect(@prot).to receive(:read_field_end).exactly(3).times
|
178
|
+
expect(@prot).to receive(:read_string).exactly(3).times
|
179
|
+
expect(@prot).to receive(:read_i32).ordered
|
180
|
+
expect(@prot).to receive(:read_map_begin).ordered.and_return([Thrift::Types::STRING, Thrift::Types::STRING, 1])
|
177
181
|
# @prot.should_receive(:read_string).exactly(2).times
|
178
|
-
@prot.
|
179
|
-
@prot.
|
182
|
+
expect(@prot).to receive(:read_map_end).ordered
|
183
|
+
expect(@prot).to receive(:read_struct_end).ordered
|
180
184
|
real_skip.call(Thrift::Types::STRUCT)
|
181
185
|
end
|
182
186
|
|
183
187
|
it "should skip maps" do
|
184
188
|
real_skip = @prot.method(:skip)
|
185
|
-
@prot.
|
186
|
-
@prot.
|
187
|
-
@prot.
|
188
|
-
@prot.
|
189
|
-
@prot.
|
190
|
-
@prot.
|
189
|
+
expect(@prot).to receive(:read_map_begin).ordered.and_return([Thrift::Types::STRING, Thrift::Types::STRUCT, 1])
|
190
|
+
expect(@prot).to receive(:read_string).ordered
|
191
|
+
expect(@prot).to receive(:read_struct_begin).ordered.and_return(["some_struct"])
|
192
|
+
expect(@prot).to receive(:read_field_begin).ordered.and_return([nil, Thrift::Types::STOP, nil]);
|
193
|
+
expect(@prot).to receive(:read_struct_end).ordered
|
194
|
+
expect(@prot).to receive(:read_map_end).ordered
|
191
195
|
real_skip.call(Thrift::Types::MAP)
|
192
196
|
end
|
193
197
|
|
194
198
|
it "should skip sets" do
|
195
199
|
real_skip = @prot.method(:skip)
|
196
|
-
@prot.
|
197
|
-
@prot.
|
198
|
-
@prot.
|
200
|
+
expect(@prot).to receive(:read_set_begin).ordered.and_return([Thrift::Types::I64, 9])
|
201
|
+
expect(@prot).to receive(:read_i64).ordered.exactly(9).times
|
202
|
+
expect(@prot).to receive(:read_set_end)
|
199
203
|
real_skip.call(Thrift::Types::SET)
|
200
204
|
end
|
201
205
|
|
202
206
|
it "should skip lists" do
|
203
207
|
real_skip = @prot.method(:skip)
|
204
|
-
@prot.
|
205
|
-
@prot.
|
206
|
-
@prot.
|
208
|
+
expect(@prot).to receive(:read_list_begin).ordered.and_return([Thrift::Types::DOUBLE, 11])
|
209
|
+
expect(@prot).to receive(:read_double).ordered.exactly(11).times
|
210
|
+
expect(@prot).to receive(:read_list_end)
|
207
211
|
real_skip.call(Thrift::Types::LIST)
|
208
212
|
end
|
209
213
|
end
|
@@ -211,7 +215,11 @@ describe 'BaseProtocol' do
|
|
211
215
|
describe Thrift::BaseProtocolFactory do
|
212
216
|
it "should raise NotImplementedError" do
|
213
217
|
# returning nil since Protocol is just an abstract class
|
214
|
-
|
218
|
+
expect {Thrift::BaseProtocolFactory.new.get_protocol(double("MockTransport"))}.to raise_error(NotImplementedError)
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should provide a reasonable to_s" do
|
222
|
+
expect(Thrift::BaseProtocolFactory.new.to_s).to eq("base")
|
215
223
|
end
|
216
224
|
end
|
217
225
|
end
|
data/spec/base_transport_spec.rb
CHANGED
@@ -24,105 +24,119 @@ describe 'BaseTransport' do
|
|
24
24
|
describe Thrift::TransportException do
|
25
25
|
it "should make type accessible" do
|
26
26
|
exc = Thrift::TransportException.new(Thrift::TransportException::ALREADY_OPEN, "msg")
|
27
|
-
exc.type.
|
28
|
-
exc.message.
|
27
|
+
expect(exc.type).to eq(Thrift::TransportException::ALREADY_OPEN)
|
28
|
+
expect(exc.message).to eq("msg")
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
describe Thrift::BaseTransport do
|
33
33
|
it "should read the specified size" do
|
34
34
|
transport = Thrift::BaseTransport.new
|
35
|
-
transport.
|
36
|
-
transport.
|
37
|
-
transport.
|
38
|
-
transport.read_all(40).
|
35
|
+
expect(transport).to receive(:read).with(40).ordered.and_return("10 letters")
|
36
|
+
expect(transport).to receive(:read).with(30).ordered.and_return("fifteen letters")
|
37
|
+
expect(transport).to receive(:read).with(15).ordered.and_return("more characters")
|
38
|
+
expect(transport.read_all(40)).to eq("10 lettersfifteen lettersmore characters")
|
39
39
|
end
|
40
40
|
|
41
41
|
it "should stub out the rest of the methods" do
|
42
42
|
# can't test for stubbiness, so just make sure they're defined
|
43
43
|
[:open?, :open, :close, :read, :write, :flush].each do |sym|
|
44
|
-
Thrift::BaseTransport.method_defined?(sym).
|
44
|
+
expect(Thrift::BaseTransport.method_defined?(sym)).to be_truthy
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
it "should alias << to write" do
|
49
|
-
Thrift::BaseTransport.instance_method(:<<).
|
49
|
+
expect(Thrift::BaseTransport.instance_method(:<<)).to eq(Thrift::BaseTransport.instance_method(:write))
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should provide a reasonable to_s" do
|
53
|
+
expect(Thrift::BaseTransport.new.to_s).to eq("base")
|
50
54
|
end
|
51
55
|
end
|
52
56
|
|
53
57
|
describe Thrift::BaseServerTransport do
|
54
58
|
it "should stub out its methods" do
|
55
59
|
[:listen, :accept, :close].each do |sym|
|
56
|
-
Thrift::BaseServerTransport.method_defined?(sym).
|
60
|
+
expect(Thrift::BaseServerTransport.method_defined?(sym)).to be_truthy
|
57
61
|
end
|
58
62
|
end
|
59
63
|
end
|
60
64
|
|
61
65
|
describe Thrift::BaseTransportFactory do
|
62
66
|
it "should return the transport it's given" do
|
63
|
-
transport =
|
64
|
-
Thrift::BaseTransportFactory.new.get_transport(transport).
|
67
|
+
transport = double("Transport")
|
68
|
+
expect(Thrift::BaseTransportFactory.new.get_transport(transport)).to eql(transport)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should provide a reasonable to_s" do
|
72
|
+
expect(Thrift::BaseTransportFactory.new.to_s).to eq("base")
|
65
73
|
end
|
66
74
|
end
|
67
75
|
|
68
76
|
describe Thrift::BufferedTransport do
|
77
|
+
it "should provide a to_s that describes the encapsulation" do
|
78
|
+
trans = double("Transport")
|
79
|
+
expect(trans).to receive(:to_s).and_return("mock")
|
80
|
+
expect(Thrift::BufferedTransport.new(trans).to_s).to eq("buffered(mock)")
|
81
|
+
end
|
82
|
+
|
69
83
|
it "should pass through everything but write/flush/read" do
|
70
|
-
trans =
|
71
|
-
trans.
|
72
|
-
trans.
|
73
|
-
trans.
|
74
|
-
trans.
|
84
|
+
trans = double("Transport")
|
85
|
+
expect(trans).to receive(:open?).ordered.and_return("+ open?")
|
86
|
+
expect(trans).to receive(:open).ordered.and_return("+ open")
|
87
|
+
expect(trans).to receive(:flush).ordered # from the close
|
88
|
+
expect(trans).to receive(:close).ordered.and_return("+ close")
|
75
89
|
btrans = Thrift::BufferedTransport.new(trans)
|
76
|
-
btrans.open
|
77
|
-
btrans.open.
|
78
|
-
btrans.close.
|
90
|
+
expect(btrans.open?).to eq("+ open?")
|
91
|
+
expect(btrans.open).to eq("+ open")
|
92
|
+
expect(btrans.close).to eq("+ close")
|
79
93
|
end
|
80
94
|
|
81
95
|
it "should buffer reads in chunks of #{Thrift::BufferedTransport::DEFAULT_BUFFER}" do
|
82
|
-
trans =
|
83
|
-
trans.
|
96
|
+
trans = double("Transport")
|
97
|
+
expect(trans).to receive(:read).with(Thrift::BufferedTransport::DEFAULT_BUFFER).and_return("lorum ipsum dolor emet")
|
84
98
|
btrans = Thrift::BufferedTransport.new(trans)
|
85
|
-
btrans.read(6).
|
86
|
-
btrans.read(6).
|
87
|
-
btrans.read(6).
|
88
|
-
btrans.read(6).
|
99
|
+
expect(btrans.read(6)).to eq("lorum ")
|
100
|
+
expect(btrans.read(6)).to eq("ipsum ")
|
101
|
+
expect(btrans.read(6)).to eq("dolor ")
|
102
|
+
expect(btrans.read(6)).to eq("emet")
|
89
103
|
end
|
90
104
|
|
91
105
|
it "should buffer writes and send them on flush" do
|
92
|
-
trans =
|
106
|
+
trans = double("Transport")
|
93
107
|
btrans = Thrift::BufferedTransport.new(trans)
|
94
108
|
btrans.write("one/")
|
95
109
|
btrans.write("two/")
|
96
110
|
btrans.write("three/")
|
97
|
-
trans.
|
98
|
-
trans.
|
111
|
+
expect(trans).to receive(:write).with("one/two/three/").ordered
|
112
|
+
expect(trans).to receive(:flush).ordered
|
99
113
|
btrans.flush
|
100
114
|
end
|
101
115
|
|
102
116
|
it "should only send buffered data once" do
|
103
|
-
trans =
|
117
|
+
trans = double("Transport")
|
104
118
|
btrans = Thrift::BufferedTransport.new(trans)
|
105
119
|
btrans.write("one/")
|
106
120
|
btrans.write("two/")
|
107
121
|
btrans.write("three/")
|
108
|
-
trans.
|
109
|
-
trans.
|
122
|
+
expect(trans).to receive(:write).with("one/two/three/")
|
123
|
+
allow(trans).to receive(:flush)
|
110
124
|
btrans.flush
|
111
125
|
# Nothing to flush with no data
|
112
126
|
btrans.flush
|
113
127
|
end
|
114
128
|
|
115
129
|
it "should flush on close" do
|
116
|
-
trans =
|
117
|
-
trans.
|
130
|
+
trans = double("Transport")
|
131
|
+
expect(trans).to receive(:close)
|
118
132
|
btrans = Thrift::BufferedTransport.new(trans)
|
119
|
-
btrans.
|
133
|
+
expect(btrans).to receive(:flush)
|
120
134
|
btrans.close
|
121
135
|
end
|
122
136
|
|
123
137
|
it "should not write to socket if there's no data" do
|
124
|
-
trans =
|
125
|
-
trans.
|
138
|
+
trans = double("Transport")
|
139
|
+
expect(trans).to receive(:flush)
|
126
140
|
btrans = Thrift::BufferedTransport.new(trans)
|
127
141
|
btrans.flush
|
128
142
|
end
|
@@ -130,80 +144,90 @@ describe 'BaseTransport' do
|
|
130
144
|
|
131
145
|
describe Thrift::BufferedTransportFactory do
|
132
146
|
it "should wrap the given transport in a BufferedTransport" do
|
133
|
-
trans =
|
134
|
-
btrans =
|
135
|
-
Thrift::BufferedTransport.
|
136
|
-
Thrift::BufferedTransportFactory.new.get_transport(trans).
|
147
|
+
trans = double("Transport")
|
148
|
+
btrans = double("BufferedTransport")
|
149
|
+
expect(Thrift::BufferedTransport).to receive(:new).with(trans).and_return(btrans)
|
150
|
+
expect(Thrift::BufferedTransportFactory.new.get_transport(trans)).to eq(btrans)
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should provide a reasonable to_s" do
|
154
|
+
expect(Thrift::BufferedTransportFactory.new.to_s).to eq("buffered")
|
137
155
|
end
|
138
156
|
end
|
139
157
|
|
140
158
|
describe Thrift::FramedTransport do
|
141
159
|
before(:each) do
|
142
|
-
@trans =
|
160
|
+
@trans = double("Transport")
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should provide a to_s that describes the encapsulation" do
|
164
|
+
trans = double("Transport")
|
165
|
+
expect(trans).to receive(:to_s).and_return("mock")
|
166
|
+
expect(Thrift::FramedTransport.new(trans).to_s).to eq("framed(mock)")
|
143
167
|
end
|
144
168
|
|
145
169
|
it "should pass through open?/open/close" do
|
146
170
|
ftrans = Thrift::FramedTransport.new(@trans)
|
147
|
-
@trans.
|
148
|
-
@trans.
|
149
|
-
@trans.
|
150
|
-
ftrans.open
|
151
|
-
ftrans.open.
|
152
|
-
ftrans.close.
|
171
|
+
expect(@trans).to receive(:open?).ordered.and_return("+ open?")
|
172
|
+
expect(@trans).to receive(:open).ordered.and_return("+ open")
|
173
|
+
expect(@trans).to receive(:close).ordered.and_return("+ close")
|
174
|
+
expect(ftrans.open?).to eq("+ open?")
|
175
|
+
expect(ftrans.open).to eq("+ open")
|
176
|
+
expect(ftrans.close).to eq("+ close")
|
153
177
|
end
|
154
178
|
|
155
179
|
it "should pass through read when read is turned off" do
|
156
180
|
ftrans = Thrift::FramedTransport.new(@trans, false, true)
|
157
|
-
@trans.
|
158
|
-
ftrans.read(17).
|
181
|
+
expect(@trans).to receive(:read).with(17).ordered.and_return("+ read")
|
182
|
+
expect(ftrans.read(17)).to eq("+ read")
|
159
183
|
end
|
160
184
|
|
161
185
|
it "should pass through write/flush when write is turned off" do
|
162
186
|
ftrans = Thrift::FramedTransport.new(@trans, true, false)
|
163
|
-
@trans.
|
164
|
-
@trans.
|
165
|
-
ftrans.write("foo").
|
166
|
-
ftrans.flush.
|
187
|
+
expect(@trans).to receive(:write).with("foo").ordered.and_return("+ write")
|
188
|
+
expect(@trans).to receive(:flush).ordered.and_return("+ flush")
|
189
|
+
expect(ftrans.write("foo")).to eq("+ write")
|
190
|
+
expect(ftrans.flush).to eq("+ flush")
|
167
191
|
end
|
168
192
|
|
169
193
|
it "should return a full frame if asked for >= the frame's length" do
|
170
194
|
frame = "this is a frame"
|
171
|
-
@trans.
|
172
|
-
@trans.
|
173
|
-
Thrift::FramedTransport.new(@trans).read(frame.length + 10).
|
195
|
+
expect(@trans).to receive(:read_all).with(4).and_return("\000\000\000\017")
|
196
|
+
expect(@trans).to receive(:read_all).with(frame.length).and_return(frame)
|
197
|
+
expect(Thrift::FramedTransport.new(@trans).read(frame.length + 10)).to eq(frame)
|
174
198
|
end
|
175
199
|
|
176
200
|
it "should return slices of the frame when asked for < the frame's length" do
|
177
201
|
frame = "this is a frame"
|
178
|
-
@trans.
|
179
|
-
@trans.
|
202
|
+
expect(@trans).to receive(:read_all).with(4).and_return("\000\000\000\017")
|
203
|
+
expect(@trans).to receive(:read_all).with(frame.length).and_return(frame)
|
180
204
|
ftrans = Thrift::FramedTransport.new(@trans)
|
181
|
-
ftrans.read(4).
|
182
|
-
ftrans.read(4).
|
183
|
-
ftrans.read(16).
|
205
|
+
expect(ftrans.read(4)).to eq("this")
|
206
|
+
expect(ftrans.read(4)).to eq(" is ")
|
207
|
+
expect(ftrans.read(16)).to eq("a frame")
|
184
208
|
end
|
185
209
|
|
186
210
|
it "should return nothing if asked for <= 0" do
|
187
|
-
Thrift::FramedTransport.new(@trans).read(-2).
|
211
|
+
expect(Thrift::FramedTransport.new(@trans).read(-2)).to eq("")
|
188
212
|
end
|
189
213
|
|
190
214
|
it "should pull a new frame when the first is exhausted" do
|
191
215
|
frame = "this is a frame"
|
192
216
|
frame2 = "yet another frame"
|
193
|
-
@trans.
|
194
|
-
@trans.
|
195
|
-
@trans.
|
217
|
+
expect(@trans).to receive(:read_all).with(4).and_return("\000\000\000\017", "\000\000\000\021")
|
218
|
+
expect(@trans).to receive(:read_all).with(frame.length).and_return(frame)
|
219
|
+
expect(@trans).to receive(:read_all).with(frame2.length).and_return(frame2)
|
196
220
|
ftrans = Thrift::FramedTransport.new(@trans)
|
197
|
-
ftrans.read(4).
|
198
|
-
ftrans.read(8).
|
199
|
-
ftrans.read(6).
|
200
|
-
ftrans.read(4).
|
201
|
-
ftrans.read(16).
|
221
|
+
expect(ftrans.read(4)).to eq("this")
|
222
|
+
expect(ftrans.read(8)).to eq(" is a fr")
|
223
|
+
expect(ftrans.read(6)).to eq("ame")
|
224
|
+
expect(ftrans.read(4)).to eq("yet ")
|
225
|
+
expect(ftrans.read(16)).to eq("another frame")
|
202
226
|
end
|
203
227
|
|
204
228
|
it "should buffer writes" do
|
205
229
|
ftrans = Thrift::FramedTransport.new(@trans)
|
206
|
-
@trans.
|
230
|
+
expect(@trans).not_to receive(:write)
|
207
231
|
ftrans.write("foo")
|
208
232
|
ftrans.write("bar")
|
209
233
|
ftrans.write("this is a frame")
|
@@ -213,15 +237,15 @@ describe 'BaseTransport' do
|
|
213
237
|
ftrans = Thrift::FramedTransport.new(@trans)
|
214
238
|
ftrans.write("foobar", 3)
|
215
239
|
ftrans.write("barfoo", 1)
|
216
|
-
@trans.
|
217
|
-
@trans.
|
240
|
+
allow(@trans).to receive(:flush)
|
241
|
+
expect(@trans).to receive(:write).with("\000\000\000\004foob")
|
218
242
|
ftrans.flush
|
219
243
|
end
|
220
244
|
|
221
245
|
it "should flush frames with a 4-byte header" do
|
222
246
|
ftrans = Thrift::FramedTransport.new(@trans)
|
223
|
-
@trans.
|
224
|
-
@trans.
|
247
|
+
expect(@trans).to receive(:write).with("\000\000\000\035one/two/three/this is a frame").ordered
|
248
|
+
expect(@trans).to receive(:flush).ordered
|
225
249
|
ftrans.write("one/")
|
226
250
|
ftrans.write("two/")
|
227
251
|
ftrans.write("three/")
|
@@ -231,22 +255,26 @@ describe 'BaseTransport' do
|
|
231
255
|
|
232
256
|
it "should not flush the same buffered data twice" do
|
233
257
|
ftrans = Thrift::FramedTransport.new(@trans)
|
234
|
-
@trans.
|
235
|
-
@trans.
|
258
|
+
expect(@trans).to receive(:write).with("\000\000\000\007foo/bar")
|
259
|
+
allow(@trans).to receive(:flush)
|
236
260
|
ftrans.write("foo")
|
237
261
|
ftrans.write("/bar")
|
238
262
|
ftrans.flush
|
239
|
-
@trans.
|
263
|
+
expect(@trans).to receive(:write).with("\000\000\000\000")
|
240
264
|
ftrans.flush
|
241
265
|
end
|
242
266
|
end
|
243
267
|
|
244
268
|
describe Thrift::FramedTransportFactory do
|
245
269
|
it "should wrap the given transport in a FramedTransport" do
|
246
|
-
trans =
|
247
|
-
Thrift::FramedTransport.
|
270
|
+
trans = double("Transport")
|
271
|
+
expect(Thrift::FramedTransport).to receive(:new).with(trans)
|
248
272
|
Thrift::FramedTransportFactory.new.get_transport(trans)
|
249
273
|
end
|
274
|
+
|
275
|
+
it "should provide a reasonable to_s" do
|
276
|
+
expect(Thrift::FramedTransportFactory.new.to_s).to eq("framed")
|
277
|
+
end
|
250
278
|
end
|
251
279
|
|
252
280
|
describe Thrift::MemoryBufferTransport do
|
@@ -254,96 +282,106 @@ describe 'BaseTransport' do
|
|
254
282
|
@buffer = Thrift::MemoryBufferTransport.new
|
255
283
|
end
|
256
284
|
|
285
|
+
it "should provide a reasonable to_s" do
|
286
|
+
expect(@buffer.to_s).to eq("memory")
|
287
|
+
end
|
288
|
+
|
257
289
|
it "should accept a buffer on input and use it directly" do
|
258
290
|
s = "this is a test"
|
259
291
|
@buffer = Thrift::MemoryBufferTransport.new(s)
|
260
|
-
@buffer.read(4).
|
292
|
+
expect(@buffer.read(4)).to eq("this")
|
261
293
|
s.slice!(-4..-1)
|
262
|
-
@buffer.read(@buffer.available).
|
294
|
+
expect(@buffer.read(@buffer.available)).to eq(" is a ")
|
263
295
|
end
|
264
296
|
|
265
297
|
it "should always remain open" do
|
266
|
-
@buffer.
|
298
|
+
expect(@buffer).to be_open
|
267
299
|
@buffer.close
|
268
|
-
@buffer.
|
300
|
+
expect(@buffer).to be_open
|
269
301
|
end
|
270
302
|
|
271
303
|
it "should respond to peek and available" do
|
272
304
|
@buffer.write "some data"
|
273
|
-
@buffer.peek.
|
274
|
-
@buffer.available.
|
305
|
+
expect(@buffer.peek).to be_truthy
|
306
|
+
expect(@buffer.available).to eq(9)
|
275
307
|
@buffer.read(4)
|
276
|
-
@buffer.peek.
|
277
|
-
@buffer.available.
|
308
|
+
expect(@buffer.peek).to be_truthy
|
309
|
+
expect(@buffer.available).to eq(5)
|
278
310
|
@buffer.read(5)
|
279
|
-
@buffer.peek.
|
280
|
-
@buffer.available.
|
311
|
+
expect(@buffer.peek).to be_falsey
|
312
|
+
expect(@buffer.available).to eq(0)
|
281
313
|
end
|
282
314
|
|
283
315
|
it "should be able to reset the buffer" do
|
284
316
|
@buffer.write "test data"
|
285
317
|
@buffer.reset_buffer("foobar")
|
286
|
-
@buffer.available.
|
287
|
-
@buffer.read(@buffer.available).
|
318
|
+
expect(@buffer.available).to eq(6)
|
319
|
+
expect(@buffer.read(@buffer.available)).to eq("foobar")
|
288
320
|
@buffer.reset_buffer
|
289
|
-
@buffer.available.
|
321
|
+
expect(@buffer.available).to eq(0)
|
290
322
|
end
|
291
323
|
|
292
324
|
it "should copy the given string when resetting the buffer" do
|
293
325
|
s = "this is a test"
|
294
326
|
@buffer.reset_buffer(s)
|
295
|
-
@buffer.available.
|
327
|
+
expect(@buffer.available).to eq(14)
|
296
328
|
@buffer.read(10)
|
297
|
-
@buffer.available.
|
298
|
-
s.
|
329
|
+
expect(@buffer.available).to eq(4)
|
330
|
+
expect(s).to eq("this is a test")
|
299
331
|
end
|
300
332
|
|
301
333
|
it "should return from read what was given in write" do
|
302
334
|
@buffer.write "test data"
|
303
|
-
@buffer.read(4).
|
304
|
-
@buffer.read(@buffer.available).
|
335
|
+
expect(@buffer.read(4)).to eq("test")
|
336
|
+
expect(@buffer.read(@buffer.available)).to eq(" data")
|
305
337
|
@buffer.write "foo"
|
306
338
|
@buffer.write " bar"
|
307
|
-
@buffer.read(@buffer.available).
|
339
|
+
expect(@buffer.read(@buffer.available)).to eq("foo bar")
|
308
340
|
end
|
309
341
|
|
310
342
|
it "should throw an EOFError when there isn't enough data in the buffer" do
|
311
343
|
@buffer.reset_buffer("")
|
312
|
-
|
344
|
+
expect{@buffer.read(1)}.to raise_error(EOFError)
|
313
345
|
|
314
346
|
@buffer.reset_buffer("1234")
|
315
|
-
|
347
|
+
expect{@buffer.read(5)}.to raise_error(EOFError)
|
316
348
|
end
|
317
349
|
end
|
318
350
|
|
319
351
|
describe Thrift::IOStreamTransport do
|
320
352
|
before(:each) do
|
321
|
-
@input =
|
322
|
-
@output =
|
353
|
+
@input = double("Input", :closed? => false)
|
354
|
+
@output = double("Output", :closed? => false)
|
323
355
|
@trans = Thrift::IOStreamTransport.new(@input, @output)
|
324
356
|
end
|
325
357
|
|
358
|
+
it "should provide a reasonable to_s" do
|
359
|
+
expect(@input).to receive(:to_s).and_return("mock_input")
|
360
|
+
expect(@output).to receive(:to_s).and_return("mock_output")
|
361
|
+
expect(@trans.to_s).to eq("iostream(input=mock_input,output=mock_output)")
|
362
|
+
end
|
363
|
+
|
326
364
|
it "should be open as long as both input or output are open" do
|
327
|
-
@trans.
|
328
|
-
@input.
|
329
|
-
@trans.
|
330
|
-
@input.
|
331
|
-
@output.
|
332
|
-
@trans.
|
333
|
-
@input.
|
334
|
-
@trans.
|
365
|
+
expect(@trans).to be_open
|
366
|
+
allow(@input).to receive(:closed?).and_return(true)
|
367
|
+
expect(@trans).to be_open
|
368
|
+
allow(@input).to receive(:closed?).and_return(false)
|
369
|
+
allow(@output).to receive(:closed?).and_return(true)
|
370
|
+
expect(@trans).to be_open
|
371
|
+
allow(@input).to receive(:closed?).and_return(true)
|
372
|
+
expect(@trans).not_to be_open
|
335
373
|
end
|
336
374
|
|
337
375
|
it "should pass through read/write to input/output" do
|
338
|
-
@input.
|
339
|
-
@output.
|
340
|
-
@trans.read(17).
|
341
|
-
@trans.write("foobar").
|
376
|
+
expect(@input).to receive(:read).with(17).and_return("+ read")
|
377
|
+
expect(@output).to receive(:write).with("foobar").and_return("+ write")
|
378
|
+
expect(@trans.read(17)).to eq("+ read")
|
379
|
+
expect(@trans.write("foobar")).to eq("+ write")
|
342
380
|
end
|
343
381
|
|
344
382
|
it "should close both input and output when closed" do
|
345
|
-
@input.
|
346
|
-
@output.
|
383
|
+
expect(@input).to receive(:close)
|
384
|
+
expect(@output).to receive(:close)
|
347
385
|
@trans.close
|
348
386
|
end
|
349
387
|
end
|