thrift 0.22.0 → 0.24.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 +4 -4
- data/README.md +235 -17
- data/benchmark/benchmark.rb +23 -8
- data/benchmark/client.rb +50 -6
- data/benchmark/server.rb +46 -7
- data/benchmark/thin_server.rb +2 -0
- data/ext/binary_protocol_accelerated.c +154 -42
- data/ext/bytes.c +14 -0
- data/ext/compact_protocol.c +138 -45
- data/ext/constants.h +12 -0
- data/ext/extconf.rb +17 -8
- data/ext/memory_buffer.c +44 -7
- data/ext/protocol.c +29 -0
- data/ext/protocol.h +35 -0
- data/ext/struct.c +48 -17
- data/ext/thrift_native.c +28 -3
- data/lib/thrift/bytes.rb +70 -100
- data/lib/thrift/client.rb +54 -13
- data/lib/thrift/exceptions.rb +6 -5
- data/lib/thrift/multiplexed_processor.rb +20 -10
- data/lib/thrift/processor.rb +7 -6
- data/lib/thrift/protocol/base_protocol.rb +52 -21
- data/lib/thrift/protocol/binary_protocol.rb +65 -20
- data/lib/thrift/protocol/binary_protocol_accelerated.rb +6 -5
- data/lib/thrift/protocol/compact_protocol.rb +76 -41
- data/lib/thrift/protocol/header_protocol.rb +321 -0
- data/lib/thrift/protocol/json_protocol.rb +44 -27
- data/lib/thrift/protocol/multiplexed_protocol.rb +6 -5
- data/lib/thrift/protocol/protocol_decorator.rb +13 -4
- data/lib/thrift/serializer/deserializer.rb +6 -5
- data/lib/thrift/serializer/serializer.rb +5 -5
- data/lib/thrift/server/base_server.rb +5 -4
- data/lib/thrift/server/mongrel_http_server.rb +7 -6
- data/lib/thrift/server/nonblocking_server.rb +35 -9
- data/lib/thrift/server/simple_server.rb +13 -5
- data/lib/thrift/server/thin_http_server.rb +4 -3
- data/lib/thrift/server/thread_pool_server.rb +7 -6
- data/lib/thrift/server/threaded_server.rb +13 -5
- data/lib/thrift/struct.rb +12 -11
- data/lib/thrift/struct_union.rb +14 -9
- data/lib/thrift/thrift_native.rb +3 -2
- data/lib/thrift/transport/base_server_transport.rb +8 -5
- data/lib/thrift/transport/base_transport.rb +18 -14
- data/lib/thrift/transport/buffered_transport.rb +7 -6
- data/lib/thrift/transport/framed_transport.rb +8 -7
- data/lib/thrift/transport/header_transport.rb +562 -0
- data/lib/thrift/transport/http_client_transport.rb +2 -1
- data/lib/thrift/transport/io_stream_transport.rb +4 -3
- data/lib/thrift/transport/memory_buffer_transport.rb +13 -6
- data/lib/thrift/transport/server_socket.rb +14 -8
- data/lib/thrift/transport/socket.rb +126 -60
- data/lib/thrift/transport/ssl_server_socket.rb +4 -3
- data/lib/thrift/transport/ssl_socket.rb +45 -13
- data/lib/thrift/transport/unix_server_socket.rb +9 -5
- data/lib/thrift/transport/unix_socket.rb +7 -6
- data/lib/thrift/types.rb +10 -6
- data/lib/thrift/union.rb +15 -8
- data/lib/thrift/uuid.rb +50 -0
- data/lib/thrift.rb +4 -1
- data/spec/ThriftSpec.thrift +21 -1
- data/spec/base_protocol_spec.rb +21 -2
- data/spec/base_transport_spec.rb +48 -8
- data/spec/binary_protocol_accelerated_spec.rb +1 -0
- data/spec/binary_protocol_spec.rb +1 -2
- data/spec/binary_protocol_spec_shared.rb +206 -155
- data/spec/bytes_spec.rb +71 -114
- data/spec/client_spec.rb +86 -19
- data/spec/compact_protocol_spec.rb +153 -16
- data/spec/constants_demo_spec.rb +102 -0
- data/spec/exception_spec.rb +1 -1
- data/spec/flat_spec.rb +1 -0
- data/spec/header_protocol_spec.rb +476 -0
- data/spec/header_transport_spec.rb +431 -0
- data/spec/http_client_spec.rb +5 -6
- data/spec/json_protocol_spec.rb +69 -47
- data/spec/multiplexed_processor_spec.rb +75 -0
- data/spec/namespaced_spec.rb +1 -1
- data/spec/nonblocking_server_spec.rb +174 -8
- data/spec/processor_spec.rb +1 -1
- data/spec/recursion_depth_spec.rb +223 -0
- data/spec/serializer_spec.rb +1 -1
- data/spec/server_socket_spec.rb +38 -1
- data/spec/server_spec.rb +60 -9
- data/spec/socket_spec.rb +119 -13
- data/spec/socket_spec_shared.rb +73 -9
- data/spec/spec_helper.rb +2 -1
- data/spec/ssl_server_socket_spec.rb +52 -1
- data/spec/ssl_socket_spec.rb +181 -11
- data/spec/struct_nested_containers_spec.rb +2 -2
- data/spec/struct_spec.rb +114 -9
- data/spec/support/header_protocol_helper.rb +55 -0
- data/spec/thin_http_server_spec.rb +4 -18
- data/spec/types_spec.rb +26 -26
- data/spec/union_spec.rb +70 -11
- data/spec/unix_socket_spec.rb +17 -2
- data/spec/uuid_validation_spec.rb +239 -0
- data/test/fuzz/Makefile +779 -0
- data/test/fuzz/Makefile.am +173 -0
- data/test/fuzz/Makefile.in +775 -0
- data/test/fuzz/README.md +149 -0
- data/test/fuzz/fuzz_common.rb +96 -0
- data/{lib/thrift/core_ext.rb → test/fuzz/fuzz_parse_binary_protocol.rb} +4 -4
- data/{lib/thrift/core_ext/fixnum.rb → test/fuzz/fuzz_parse_binary_protocol_accelerated.rb} +7 -13
- data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +23 -0
- data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_parse_compact_protocol.rb +23 -0
- data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_parse_json_protocol.rb +23 -0
- data/test/fuzz/fuzz_parse_json_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_json_protocol.rb +23 -0
- data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +23 -0
- data/test/fuzz/fuzz_tracer.rb +29 -0
- metadata +105 -70
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# encoding: ascii-8bit
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
#
|
|
3
4
|
# Licensed to the Apache Software Foundation (ASF) under one
|
|
4
5
|
# or more contributor license agreements. See the NOTICE file
|
|
@@ -38,25 +39,24 @@ shared_examples_for 'a binary protocol' do
|
|
|
38
39
|
|
|
39
40
|
it "should make strict_write readable" do
|
|
40
41
|
expect(@prot.strict_write).to eql(true)
|
|
41
|
-
end
|
|
42
|
+
end
|
|
42
43
|
|
|
43
44
|
it "should write the message header" do
|
|
44
45
|
@prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17)
|
|
45
46
|
expect(@trans.read(@trans.available)).to eq([protocol_class.const_get(:VERSION_1) | Thrift::MessageTypes::CALL, "testMessage".size, "testMessage", 17].pack("NNa11N"))
|
|
46
47
|
end
|
|
47
|
-
|
|
48
|
+
|
|
48
49
|
it "should write the message header without version when writes are not strict" do
|
|
49
50
|
@prot = protocol_class.new(@trans, true, false) # no strict write
|
|
50
51
|
@prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17)
|
|
51
52
|
expect(@trans.read(@trans.available)).to eq("\000\000\000\vtestMessage\001\000\000\000\021")
|
|
52
53
|
end
|
|
53
|
-
|
|
54
|
+
|
|
54
55
|
it "should write the message header with a version when writes are strict" do
|
|
55
56
|
@prot = protocol_class.new(@trans) # strict write
|
|
56
57
|
@prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17)
|
|
57
58
|
expect(@trans.read(@trans.available)).to eq("\200\001\000\001\000\000\000\vtestMessage\000\000\000\021")
|
|
58
59
|
end
|
|
59
|
-
|
|
60
60
|
|
|
61
61
|
# message footer is a noop
|
|
62
62
|
|
|
@@ -64,44 +64,44 @@ shared_examples_for 'a binary protocol' do
|
|
|
64
64
|
@prot.write_field_begin('foo', Thrift::Types::DOUBLE, 3)
|
|
65
65
|
expect(@trans.read(@trans.available)).to eq([Thrift::Types::DOUBLE, 3].pack("cn"))
|
|
66
66
|
end
|
|
67
|
-
|
|
67
|
+
|
|
68
68
|
# field footer is a noop
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
it "should write the STOP field" do
|
|
71
71
|
@prot.write_field_stop
|
|
72
72
|
expect(@trans.read(1)).to eq("\000")
|
|
73
73
|
end
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
it "should write the map header" do
|
|
76
76
|
@prot.write_map_begin(Thrift::Types::STRING, Thrift::Types::LIST, 17)
|
|
77
77
|
expect(@trans.read(@trans.available)).to eq([Thrift::Types::STRING, Thrift::Types::LIST, 17].pack("ccN"));
|
|
78
78
|
end
|
|
79
|
-
|
|
79
|
+
|
|
80
80
|
# map footer is a noop
|
|
81
|
-
|
|
81
|
+
|
|
82
82
|
it "should write the list header" do
|
|
83
83
|
@prot.write_list_begin(Thrift::Types::I16, 42)
|
|
84
84
|
expect(@trans.read(@trans.available)).to eq([Thrift::Types::I16, 42].pack("cN"))
|
|
85
85
|
end
|
|
86
|
-
|
|
86
|
+
|
|
87
87
|
# list footer is a noop
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
it "should write the set header" do
|
|
90
90
|
@prot.write_set_begin(Thrift::Types::I16, 42)
|
|
91
91
|
expect(@trans.read(@trans.available)).to eq([Thrift::Types::I16, 42].pack("cN"))
|
|
92
92
|
end
|
|
93
|
-
|
|
93
|
+
|
|
94
94
|
it "should write a bool" do
|
|
95
95
|
@prot.write_bool(true)
|
|
96
96
|
@prot.write_bool(false)
|
|
97
97
|
expect(@trans.read(@trans.available)).to eq("\001\000")
|
|
98
98
|
end
|
|
99
|
-
|
|
99
|
+
|
|
100
100
|
it "should treat a nil bool as false" do
|
|
101
101
|
@prot.write_bool(nil)
|
|
102
102
|
expect(@trans.read(1)).to eq("\000")
|
|
103
103
|
end
|
|
104
|
-
|
|
104
|
+
|
|
105
105
|
it "should write a byte" do
|
|
106
106
|
# byte is small enough, let's check -128..127
|
|
107
107
|
(-128..127).each do |i|
|
|
@@ -110,64 +110,72 @@ shared_examples_for 'a binary protocol' do
|
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
-
it "should
|
|
114
|
-
|
|
115
|
-
@prot.write_byte(i)
|
|
116
|
-
expect(@trans.read(1)).to eq([i].pack('c'))
|
|
113
|
+
it "should reject bytes outside the signed byte range" do
|
|
114
|
+
[-129, 128, 255, 2**65].each do |i|
|
|
115
|
+
expect { @prot.write_byte(i) }.to raise_error(RangeError)
|
|
117
116
|
end
|
|
117
|
+
expect(@trans.available).to eq(0)
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
it "
|
|
121
|
-
expect { @prot.write_byte(
|
|
120
|
+
it "should reject non-integer bytes" do
|
|
121
|
+
expect { @prot.write_byte(1.5) }.to raise_error(TypeError)
|
|
122
122
|
end
|
|
123
|
-
|
|
123
|
+
|
|
124
124
|
it "should error gracefully when trying to write a nil byte" do
|
|
125
|
-
expect { @prot.write_byte(nil) }.to raise_error
|
|
125
|
+
expect { @prot.write_byte(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
|
|
126
126
|
end
|
|
127
|
-
|
|
127
|
+
|
|
128
128
|
it "should write an i16" do
|
|
129
129
|
# try a random scattering of values
|
|
130
130
|
# include the signed i16 minimum/maximum
|
|
131
131
|
[-2**15, -1024, 17, 0, -10000, 1723, 2**15-1].each do |i|
|
|
132
132
|
@prot.write_i16(i)
|
|
133
133
|
end
|
|
134
|
-
|
|
135
|
-
@
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
134
|
+
|
|
135
|
+
expect(@trans.read(@trans.available)).to eq("\200\000\374\000\000\021\000\000\330\360\006\273\177\377")
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "should reject i16 values outside the signed i16 range" do
|
|
139
|
+
[-2**15 - 1, 2**15, 2**65].each do |i|
|
|
140
|
+
expect { @prot.write_i16(i) }.to raise_error(RangeError)
|
|
141
|
+
end
|
|
142
|
+
expect(@trans.available).to eq(0)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "should reject non-integer i16 values" do
|
|
146
|
+
expect { @prot.write_i16(1.5) }.to raise_error(TypeError)
|
|
147
|
+
end
|
|
148
|
+
|
|
143
149
|
it "should error gracefully when trying to write a nil i16" do
|
|
144
|
-
expect { @prot.write_i16(nil) }.to raise_error
|
|
150
|
+
expect { @prot.write_i16(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
|
|
145
151
|
end
|
|
146
|
-
|
|
152
|
+
|
|
147
153
|
it "should write an i32" do
|
|
148
154
|
# try a random scattering of values
|
|
149
155
|
# include the signed i32 minimum/maximum
|
|
150
156
|
[-2**31, -123123, -2532, -3, 0, 2351235, 12331, 2**31-1].each do |i|
|
|
151
157
|
@prot.write_i32(i)
|
|
152
158
|
end
|
|
153
|
-
# try something out of signed range, it should clip
|
|
154
159
|
expect(@trans.read(@trans.available)).to eq("\200\000\000\000" + "\377\376\037\r" + "\377\377\366\034" + "\377\377\377\375" + "\000\000\000\000" + "\000#\340\203" + "\000\0000+" + "\177\377\377\377")
|
|
155
|
-
[2 ** 31
|
|
156
|
-
expect { @prot.write_i32(i) }.to raise_error(RangeError)
|
|
160
|
+
[-2 ** 31 - 1, 2 ** 31, 2 ** 65 + 5].each do |i|
|
|
161
|
+
expect { @prot.write_i32(i) }.to raise_error(RangeError)
|
|
157
162
|
end
|
|
158
163
|
end
|
|
159
|
-
|
|
164
|
+
|
|
165
|
+
it "should reject non-integer i32 values" do
|
|
166
|
+
expect { @prot.write_i32(1.5) }.to raise_error(TypeError)
|
|
167
|
+
end
|
|
168
|
+
|
|
160
169
|
it "should error gracefully when trying to write a nil i32" do
|
|
161
|
-
expect { @prot.write_i32(nil) }.to raise_error
|
|
170
|
+
expect { @prot.write_i32(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
|
|
162
171
|
end
|
|
163
|
-
|
|
172
|
+
|
|
164
173
|
it "should write an i64" do
|
|
165
174
|
# try a random scattering of values
|
|
166
175
|
# try the signed i64 minimum/maximum
|
|
167
176
|
[-2**63, -12356123612323, -23512351, -234, 0, 1231, 2351236, 12361236213, 2**63-1].each do |i|
|
|
168
177
|
@prot.write_i64(i)
|
|
169
178
|
end
|
|
170
|
-
# try something out of signed range, it should clip
|
|
171
179
|
expect(@trans.read(@trans.available)).to eq(["\200\000\000\000\000\000\000\000",
|
|
172
180
|
"\377\377\364\303\035\244+]",
|
|
173
181
|
"\377\377\377\377\376\231:\341",
|
|
@@ -177,100 +185,131 @@ shared_examples_for 'a binary protocol' do
|
|
|
177
185
|
"\000\000\000\000\000#\340\204",
|
|
178
186
|
"\000\000\000\002\340\311~\365",
|
|
179
187
|
"\177\377\377\377\377\377\377\377"].join(""))
|
|
180
|
-
|
|
188
|
+
[-2 ** 63 - 1, 2 ** 63, 2 ** 65 + 5].each do |i|
|
|
189
|
+
expect { @prot.write_i64(i) }.to raise_error(RangeError)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "should reject non-integer i64 values" do
|
|
194
|
+
expect { @prot.write_i64(1.5) }.to raise_error(TypeError)
|
|
181
195
|
end
|
|
182
|
-
|
|
196
|
+
|
|
183
197
|
it "should error gracefully when trying to write a nil i64" do
|
|
184
|
-
expect { @prot.write_i64(nil) }.to raise_error
|
|
198
|
+
expect { @prot.write_i64(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it "should reject out-of-range field ids" do
|
|
202
|
+
expect { @prot.write_field_begin('foo', Thrift::Types::DOUBLE, -2**15 - 1) }.to raise_error(RangeError)
|
|
203
|
+
expect { @prot.write_field_begin('foo', Thrift::Types::DOUBLE, 2**15) }.to raise_error(RangeError)
|
|
185
204
|
end
|
|
186
|
-
|
|
205
|
+
|
|
206
|
+
it "should reject out-of-range container sizes" do
|
|
207
|
+
expect { @prot.write_map_begin(Thrift::Types::STRING, Thrift::Types::LIST, -1) }.to raise_error(RangeError)
|
|
208
|
+
expect { @prot.write_list_begin(Thrift::Types::I16, 2**31) }.to raise_error(RangeError)
|
|
209
|
+
expect { @prot.write_set_begin(Thrift::Types::I16, 2**31) }.to raise_error(RangeError)
|
|
210
|
+
end
|
|
211
|
+
|
|
187
212
|
it "should write a double" do
|
|
188
213
|
# try a random scattering of values, including min/max
|
|
189
|
-
values = [Float::MIN
|
|
214
|
+
values = [Float::MIN, -1231.15325, -123123.23, -23.23515123, 0, 12351.1325, 523.23, Float::MAX]
|
|
190
215
|
values.each do |f|
|
|
191
216
|
@prot.write_double(f)
|
|
192
217
|
expect(@trans.read(@trans.available)).to eq([f].pack("G"))
|
|
193
218
|
end
|
|
194
219
|
end
|
|
195
|
-
|
|
220
|
+
|
|
196
221
|
it "should error gracefully when trying to write a nil double" do
|
|
197
|
-
expect { @prot.write_double(nil) }.to raise_error
|
|
222
|
+
expect { @prot.write_double(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
|
|
198
223
|
end
|
|
199
224
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
end
|
|
225
|
+
it 'should write a string' do
|
|
226
|
+
str = 'abc'
|
|
227
|
+
@prot.write_string(str)
|
|
228
|
+
a = @trans.read(@trans.available)
|
|
229
|
+
expect(a.encoding).to eq(Encoding::BINARY)
|
|
230
|
+
expect(a.unpack('C*')).to eq([0x00, 0x00, 0x00, 0x03, 0x61, 0x62, 0x63])
|
|
231
|
+
end
|
|
208
232
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
233
|
+
it 'should write a string with unicode characters' do
|
|
234
|
+
str = "abc \u20AC \u20AD".encode('UTF-8')
|
|
235
|
+
@prot.write_string(str)
|
|
236
|
+
a = @trans.read(@trans.available)
|
|
237
|
+
expect(a.encoding).to eq(Encoding::BINARY)
|
|
238
|
+
expect(a.unpack('C*')).to eq([0x00, 0x00, 0x00, 0x0B, 0x61, 0x62, 0x63, 0x20,
|
|
239
|
+
0xE2, 0x82, 0xAC, 0x20, 0xE2, 0x82, 0xAD])
|
|
240
|
+
end
|
|
217
241
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
242
|
+
it 'should write should write a string with unicode characters and transcoding' do
|
|
243
|
+
str = "abc \u20AC".encode('ISO-8859-15')
|
|
244
|
+
@prot.write_string(str)
|
|
245
|
+
a = @trans.read(@trans.available)
|
|
246
|
+
expect(a.encoding).to eq(Encoding::BINARY)
|
|
247
|
+
expect(a.unpack('C*')).to eq([0x00, 0x00, 0x00, 0x07, 0x61, 0x62, 0x63, 0x20, 0xE2, 0x82, 0xAC])
|
|
248
|
+
end
|
|
225
249
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
else
|
|
234
|
-
it 'should write a string' do
|
|
235
|
-
str = 'abc'
|
|
236
|
-
@prot.write_string(str)
|
|
237
|
-
a = @trans.read(@trans.available)
|
|
238
|
-
expect(a.unpack('C*')).to eq([0x00, 0x00, 0x00, 0x03, 0x61, 0x62, 0x63])
|
|
239
|
-
end
|
|
250
|
+
it 'should write a binary string' do
|
|
251
|
+
buffer = [0, 1, 2, 3].pack('C*')
|
|
252
|
+
@prot.write_binary(buffer)
|
|
253
|
+
a = @trans.read(@trans.available)
|
|
254
|
+
expect(a.encoding).to eq(Encoding::BINARY)
|
|
255
|
+
expect(a.unpack('C*')).to eq([0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03])
|
|
256
|
+
end
|
|
240
257
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
258
|
+
it 'should write a frozen non-binary string without mutating the input' do
|
|
259
|
+
buffer = "abc \u20AC".encode('UTF-8').freeze
|
|
260
|
+
@prot.write_binary(buffer)
|
|
261
|
+
a = @trans.read(@trans.available)
|
|
262
|
+
expect(buffer.encoding).to eq(Encoding::UTF_8)
|
|
263
|
+
expect(buffer).to be_frozen
|
|
264
|
+
expect(a.encoding).to eq(Encoding::BINARY)
|
|
265
|
+
expect(a.unpack('C*')).to eq([0x00, 0x00, 0x00, 0x07, 0x61, 0x62, 0x63, 0x20, 0xE2, 0x82, 0xAC])
|
|
247
266
|
end
|
|
248
267
|
|
|
249
268
|
it "should error gracefully when trying to write a nil string" do
|
|
250
|
-
expect { @prot.write_string(nil) }.to raise_error
|
|
269
|
+
expect { @prot.write_string(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
it "should error gracefully when trying to write a nil binary" do
|
|
273
|
+
expect { @prot.write_binary(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
it "should write a uuid" do
|
|
277
|
+
@prot.write_uuid("00112233-4455-6677-8899-aabbccddeeff")
|
|
278
|
+
a = @trans.read(@trans.available)
|
|
279
|
+
expect(a.unpack('C*')).to eq([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff])
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
it "should read a uuid" do
|
|
283
|
+
@trans.write([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff].pack('C*'))
|
|
284
|
+
uuid = @prot.read_uuid
|
|
285
|
+
expect(uuid).to eq("00112233-4455-6677-8899-aabbccddeeff")
|
|
251
286
|
end
|
|
252
|
-
|
|
287
|
+
|
|
288
|
+
it "should error gracefully when trying to write an invalid uuid" do
|
|
289
|
+
expect { @prot.write_uuid("invalid") }.to raise_error(Thrift::ProtocolException)
|
|
290
|
+
end
|
|
291
|
+
|
|
253
292
|
it "should write the message header without version when writes are not strict" do
|
|
254
293
|
@prot = protocol_class.new(@trans, true, false) # no strict write
|
|
255
294
|
@prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17)
|
|
256
295
|
expect(@trans.read(@trans.available)).to eq("\000\000\000\vtestMessage\001\000\000\000\021")
|
|
257
296
|
end
|
|
258
|
-
|
|
297
|
+
|
|
259
298
|
it "should write the message header with a version when writes are strict" do
|
|
260
299
|
@prot = protocol_class.new(@trans) # strict write
|
|
261
300
|
@prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17)
|
|
262
301
|
expect(@trans.read(@trans.available)).to eq("\200\001\000\001\000\000\000\vtestMessage\000\000\000\021")
|
|
263
302
|
end
|
|
264
|
-
|
|
303
|
+
|
|
265
304
|
# message footer is a noop
|
|
266
|
-
|
|
305
|
+
|
|
267
306
|
it "should read a field header" do
|
|
268
307
|
@trans.write([Thrift::Types::STRING, 3].pack("cn"))
|
|
269
308
|
expect(@prot.read_field_begin).to eq([nil, Thrift::Types::STRING, 3])
|
|
270
309
|
end
|
|
271
|
-
|
|
310
|
+
|
|
272
311
|
# field footer is a noop
|
|
273
|
-
|
|
312
|
+
|
|
274
313
|
it "should read a stop field" do
|
|
275
314
|
@trans.write([Thrift::Types::STOP].pack("c"));
|
|
276
315
|
expect(@prot.read_field_begin).to eq([nil, Thrift::Types::STOP, 0])
|
|
@@ -280,36 +319,57 @@ shared_examples_for 'a binary protocol' do
|
|
|
280
319
|
@trans.write([Thrift::Types::DOUBLE, Thrift::Types::I64, 42].pack("ccN"))
|
|
281
320
|
expect(@prot.read_map_begin).to eq([Thrift::Types::DOUBLE, Thrift::Types::I64, 42])
|
|
282
321
|
end
|
|
283
|
-
|
|
322
|
+
|
|
323
|
+
it "should reject a negative map size" do
|
|
324
|
+
@trans.write([Thrift::Types::DOUBLE, Thrift::Types::I64, 0xffffffff].pack("ccN"))
|
|
325
|
+
expect { @prot.read_map_begin }.to raise_error(Thrift::ProtocolException, "Negative size") do |e|
|
|
326
|
+
expect(e.type).to eq(Thrift::ProtocolException::NEGATIVE_SIZE)
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
|
|
284
330
|
# map footer is a noop
|
|
285
|
-
|
|
331
|
+
|
|
286
332
|
it "should read a list header" do
|
|
287
333
|
@trans.write([Thrift::Types::STRING, 17].pack("cN"))
|
|
288
334
|
expect(@prot.read_list_begin).to eq([Thrift::Types::STRING, 17])
|
|
289
335
|
end
|
|
290
|
-
|
|
336
|
+
|
|
337
|
+
it "should reject a negative list size" do
|
|
338
|
+
@trans.write([Thrift::Types::STRING, 0xffffffff].pack("cN"))
|
|
339
|
+
expect { @prot.read_list_begin }.to raise_error(Thrift::ProtocolException, "Negative size") do |e|
|
|
340
|
+
expect(e.type).to eq(Thrift::ProtocolException::NEGATIVE_SIZE)
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
291
344
|
# list footer is a noop
|
|
292
|
-
|
|
345
|
+
|
|
293
346
|
it "should read a set header" do
|
|
294
347
|
@trans.write([Thrift::Types::STRING, 17].pack("cN"))
|
|
295
348
|
expect(@prot.read_set_begin).to eq([Thrift::Types::STRING, 17])
|
|
296
349
|
end
|
|
297
|
-
|
|
350
|
+
|
|
351
|
+
it "should reject a negative set size" do
|
|
352
|
+
@trans.write([Thrift::Types::STRING, 0xffffffff].pack("cN"))
|
|
353
|
+
expect { @prot.read_set_begin }.to raise_error(Thrift::ProtocolException, "Negative size") do |e|
|
|
354
|
+
expect(e.type).to eq(Thrift::ProtocolException::NEGATIVE_SIZE)
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
298
358
|
# set footer is a noop
|
|
299
|
-
|
|
359
|
+
|
|
300
360
|
it "should read a bool" do
|
|
301
361
|
@trans.write("\001\000");
|
|
302
362
|
expect(@prot.read_bool).to eq(true)
|
|
303
363
|
expect(@prot.read_bool).to eq(false)
|
|
304
364
|
end
|
|
305
|
-
|
|
365
|
+
|
|
306
366
|
it "should read a byte" do
|
|
307
367
|
[-128, -57, -3, 0, 17, 24, 127].each do |i|
|
|
308
368
|
@trans.write([i].pack("c"))
|
|
309
369
|
expect(@prot.read_byte).to eq(i)
|
|
310
370
|
end
|
|
311
371
|
end
|
|
312
|
-
|
|
372
|
+
|
|
313
373
|
it "should read an i16" do
|
|
314
374
|
# try a scattering of values, including min/max
|
|
315
375
|
[-2**15, -5237, -353, 0, 1527, 2234, 2**15-1].each do |i|
|
|
@@ -317,7 +377,7 @@ shared_examples_for 'a binary protocol' do
|
|
|
317
377
|
expect(@prot.read_i16).to eq(i)
|
|
318
378
|
end
|
|
319
379
|
end
|
|
320
|
-
|
|
380
|
+
|
|
321
381
|
it "should read an i32" do
|
|
322
382
|
# try a scattering of values, including min/max
|
|
323
383
|
[-2**31, -235125, -6236, 0, 2351, 123123, 2**31-1].each do |i|
|
|
@@ -325,7 +385,7 @@ shared_examples_for 'a binary protocol' do
|
|
|
325
385
|
expect(@prot.read_i32).to eq(i)
|
|
326
386
|
end
|
|
327
387
|
end
|
|
328
|
-
|
|
388
|
+
|
|
329
389
|
it "should read an i64" do
|
|
330
390
|
# try a scattering of values, including min/max
|
|
331
391
|
[-2**63, -123512312, -6346, 0, 32, 2346322323, 2**63-1].each do |i|
|
|
@@ -333,7 +393,7 @@ shared_examples_for 'a binary protocol' do
|
|
|
333
393
|
expect(@prot.read_i64).to eq(i)
|
|
334
394
|
end
|
|
335
395
|
end
|
|
336
|
-
|
|
396
|
+
|
|
337
397
|
it "should read a double" do
|
|
338
398
|
# try a random scattering of values, including min/max
|
|
339
399
|
[Float::MIN, -231231.12351, -323.233513, 0, 123.2351235, 2351235.12351235, Float::MAX].each do |f|
|
|
@@ -342,66 +402,57 @@ shared_examples_for 'a binary protocol' do
|
|
|
342
402
|
end
|
|
343
403
|
end
|
|
344
404
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
end
|
|
405
|
+
it 'should read a string' do
|
|
406
|
+
# i32 of value 3, followed by three characters/UTF-8 bytes 'a', 'b', 'c'
|
|
407
|
+
buffer = [0x00, 0x00, 0x00, 0x03, 0x61, 0x62, 0x63].pack('C*')
|
|
408
|
+
@trans.write(buffer)
|
|
409
|
+
a = @prot.read_string
|
|
410
|
+
expect(a).to eq('abc'.encode('UTF-8'))
|
|
411
|
+
expect(a.encoding).to eq(Encoding::UTF_8)
|
|
412
|
+
end
|
|
354
413
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
414
|
+
it 'should read a string containing unicode characters from UTF-8 encoded buffer' do
|
|
415
|
+
# i32 of value 3, followed by one character U+20AC made up of three bytes
|
|
416
|
+
buffer = [0x00, 0x00, 0x00, 0x03, 0xE2, 0x82, 0xAC].pack('C*')
|
|
417
|
+
@trans.write(buffer)
|
|
418
|
+
a = @prot.read_string
|
|
419
|
+
expect(a).to eq("\u20AC".encode('UTF-8'))
|
|
420
|
+
expect(a.encoding).to eq(Encoding::UTF_8)
|
|
421
|
+
end
|
|
363
422
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
else
|
|
372
|
-
it 'should read a string' do
|
|
373
|
-
# i32 of value 3, followed by three characters/UTF-8 bytes 'a', 'b', 'c'
|
|
374
|
-
buffer = [0x00, 0x00, 0x00, 0x03, 0x61, 0x62, 0x63].pack('C*')
|
|
375
|
-
@trans.write(buffer)
|
|
376
|
-
expect(@prot.read_string).to eq('abc')
|
|
377
|
-
end
|
|
423
|
+
it 'should read a binary string' do
|
|
424
|
+
buffer = [0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x02, 0x03].pack('C*')
|
|
425
|
+
@trans.write(buffer)
|
|
426
|
+
a = @prot.read_binary
|
|
427
|
+
expect(a).to eq([0x00, 0x01, 0x02, 0x03].pack('C*'))
|
|
428
|
+
expect(a.encoding).to eq(Encoding::BINARY)
|
|
429
|
+
end
|
|
378
430
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
expect(a).to eq([0x00, 0x01, 0x02, 0x03].pack('C*'))
|
|
431
|
+
it "should reject a negative binary size" do
|
|
432
|
+
@trans.write([0xff, 0xff, 0xff, 0xff].pack('C*'))
|
|
433
|
+
expect { @prot.read_binary }.to raise_error(Thrift::ProtocolException, "Negative size") do |e|
|
|
434
|
+
expect(e.type).to eq(Thrift::ProtocolException::NEGATIVE_SIZE)
|
|
384
435
|
end
|
|
385
436
|
end
|
|
386
437
|
|
|
387
438
|
it "should perform a complete rpc with no args or return" do
|
|
388
439
|
srv_test(
|
|
389
|
-
proc {|client| client.send_voidMethod()},
|
|
390
|
-
proc {|client| expect(client.recv_voidMethod).to eq(nil)}
|
|
440
|
+
proc { |client| client.send_voidMethod() },
|
|
441
|
+
proc { |client| expect(client.recv_voidMethod).to eq(nil) }
|
|
391
442
|
)
|
|
392
443
|
end
|
|
393
444
|
|
|
394
445
|
it "should perform a complete rpc with a primitive return type" do
|
|
395
446
|
srv_test(
|
|
396
|
-
proc {|client| client.send_primitiveMethod()},
|
|
397
|
-
proc {|client| expect(client.recv_primitiveMethod).to eq(1)}
|
|
447
|
+
proc { |client| client.send_primitiveMethod() },
|
|
448
|
+
proc { |client| expect(client.recv_primitiveMethod).to eq(1) }
|
|
398
449
|
)
|
|
399
450
|
end
|
|
400
451
|
|
|
401
452
|
it "should perform a complete rpc with a struct return type" do
|
|
402
453
|
srv_test(
|
|
403
|
-
proc {|client| client.send_structMethod()},
|
|
404
|
-
proc {|client|
|
|
454
|
+
proc { |client| client.send_structMethod() },
|
|
455
|
+
proc { |client|
|
|
405
456
|
result = client.recv_structMethod
|
|
406
457
|
result.set_byte_map = nil
|
|
407
458
|
result.map_byte_map = nil
|
|
@@ -413,7 +464,7 @@ shared_examples_for 'a binary protocol' do
|
|
|
413
464
|
def get_socket_connection
|
|
414
465
|
server = Thrift::ServerSocket.new("localhost", 9090)
|
|
415
466
|
server.listen
|
|
416
|
-
|
|
467
|
+
|
|
417
468
|
clientside = Thrift::Socket.new("localhost", 9090)
|
|
418
469
|
clientside.open
|
|
419
470
|
serverside = server.accept
|
|
@@ -443,14 +494,14 @@ shared_examples_for 'a binary protocol' do
|
|
|
443
494
|
server.close
|
|
444
495
|
end
|
|
445
496
|
|
|
446
|
-
class SrvHandler
|
|
497
|
+
class SrvHandler
|
|
447
498
|
def voidMethod()
|
|
448
499
|
end
|
|
449
|
-
|
|
500
|
+
|
|
450
501
|
def primitiveMethod
|
|
451
502
|
1
|
|
452
503
|
end
|
|
453
|
-
|
|
504
|
+
|
|
454
505
|
def structMethod
|
|
455
506
|
Fixtures::COMPACT_PROTOCOL_TEST_STRUCT
|
|
456
507
|
end
|