thrift 0.24.0 → 0.25.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.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +107 -4
  3. data/ext/binary_protocol_accelerated.c +52 -17
  4. data/ext/compact_protocol.c +135 -70
  5. data/ext/constants.h +3 -0
  6. data/ext/extconf.rb +4 -4
  7. data/ext/macros.h +11 -0
  8. data/ext/memory_buffer.c +35 -17
  9. data/ext/struct.c +185 -64
  10. data/ext/thrift_native.c +6 -0
  11. data/lib/thrift/bytes.rb +2 -2
  12. data/lib/thrift/client.rb +31 -22
  13. data/lib/thrift/exceptions.rb +10 -8
  14. data/lib/thrift/multiplexed_processor.rb +5 -6
  15. data/lib/thrift/processor.rb +24 -3
  16. data/lib/thrift/protocol/base_protocol.rb +53 -27
  17. data/lib/thrift/protocol/binary_protocol.rb +54 -40
  18. data/lib/thrift/protocol/binary_protocol_accelerated.rb +6 -2
  19. data/lib/thrift/protocol/compact_protocol.rb +193 -88
  20. data/lib/thrift/protocol/header_protocol.rb +14 -3
  21. data/lib/thrift/protocol/json_protocol.rb +146 -104
  22. data/lib/thrift/protocol/multiplexed_protocol.rb +2 -3
  23. data/lib/thrift/protocol/protocol_decorator.rb +5 -2
  24. data/lib/thrift/serializer/serializer.rb +6 -0
  25. data/lib/thrift/server/base_server.rb +10 -2
  26. data/lib/thrift/server/nonblocking_server.rb +49 -26
  27. data/lib/thrift/server/rack_application.rb +69 -0
  28. data/lib/thrift/server/simple_server.rb +27 -23
  29. data/lib/thrift/server/thin_http_server.rb +20 -44
  30. data/lib/thrift/server/thread_pool_server.rb +20 -17
  31. data/lib/thrift/server/threaded_server.rb +22 -26
  32. data/lib/thrift/struct.rb +33 -18
  33. data/lib/thrift/struct_union.rb +36 -30
  34. data/lib/thrift/transport/base_transport.rb +23 -5
  35. data/lib/thrift/transport/buffered_transport.rb +4 -4
  36. data/lib/thrift/transport/framed_transport.rb +32 -7
  37. data/lib/thrift/transport/header_transport.rb +130 -50
  38. data/lib/thrift/transport/http_client_transport.rb +27 -14
  39. data/lib/thrift/transport/io_stream_transport.rb +2 -1
  40. data/lib/thrift/transport/memory_buffer_transport.rb +8 -10
  41. data/lib/thrift/transport/server_socket.rb +4 -5
  42. data/lib/thrift/transport/socket.rb +20 -22
  43. data/lib/thrift/transport/ssl_server_socket.rb +64 -4
  44. data/lib/thrift/transport/ssl_socket.rb +32 -5
  45. data/lib/thrift/transport/unix_server_socket.rb +1 -1
  46. data/lib/thrift/transport/unix_socket.rb +4 -6
  47. data/lib/thrift/types.rb +22 -22
  48. data/lib/thrift/union.rb +20 -11
  49. data/lib/thrift/uuid.rb +8 -8
  50. data/lib/thrift.rb +39 -39
  51. metadata +5 -230
  52. data/benchmark/Benchmark.thrift +0 -24
  53. data/benchmark/benchmark.rb +0 -286
  54. data/benchmark/client.rb +0 -118
  55. data/benchmark/server.rb +0 -121
  56. data/benchmark/thin_server.rb +0 -46
  57. data/lib/thrift/server/mongrel_http_server.rb +0 -61
  58. data/spec/BaseService.thrift +0 -27
  59. data/spec/ExtendedService.thrift +0 -25
  60. data/spec/Referenced.thrift +0 -44
  61. data/spec/ThriftNamespacedSpec.thrift +0 -53
  62. data/spec/ThriftSpec.thrift +0 -203
  63. data/spec/base_protocol_spec.rb +0 -244
  64. data/spec/base_transport_spec.rb +0 -428
  65. data/spec/binary_protocol_accelerated_spec.rb +0 -47
  66. data/spec/binary_protocol_spec.rb +0 -73
  67. data/spec/binary_protocol_spec_shared.rb +0 -509
  68. data/spec/bytes_spec.rb +0 -117
  69. data/spec/client_spec.rb +0 -167
  70. data/spec/compact_protocol_spec.rb +0 -295
  71. data/spec/constants_demo_spec.rb +0 -102
  72. data/spec/exception_spec.rb +0 -141
  73. data/spec/flat_spec.rb +0 -63
  74. data/spec/header_protocol_spec.rb +0 -476
  75. data/spec/header_transport_spec.rb +0 -431
  76. data/spec/http_client_spec.rb +0 -160
  77. data/spec/json_protocol_spec.rb +0 -574
  78. data/spec/multiplexed_processor_spec.rb +0 -75
  79. data/spec/namespaced_spec.rb +0 -67
  80. data/spec/nonblocking_server_spec.rb +0 -429
  81. data/spec/processor_spec.rb +0 -80
  82. data/spec/recursion_depth_spec.rb +0 -223
  83. data/spec/serializer_spec.rb +0 -67
  84. data/spec/server_socket_spec.rb +0 -121
  85. data/spec/server_spec.rb +0 -238
  86. data/spec/socket_spec.rb +0 -174
  87. data/spec/socket_spec_shared.rb +0 -168
  88. data/spec/spec_helper.rb +0 -70
  89. data/spec/ssl_server_socket_spec.rb +0 -85
  90. data/spec/ssl_socket_spec.rb +0 -248
  91. data/spec/struct_nested_containers_spec.rb +0 -191
  92. data/spec/struct_spec.rb +0 -398
  93. data/spec/support/header_protocol_helper.rb +0 -55
  94. data/spec/thin_http_server_spec.rb +0 -127
  95. data/spec/types_spec.rb +0 -118
  96. data/spec/union_spec.rb +0 -273
  97. data/spec/unix_socket_spec.rb +0 -131
  98. data/spec/uuid_validation_spec.rb +0 -239
  99. data/test/fuzz/Makefile +0 -779
  100. data/test/fuzz/Makefile.am +0 -173
  101. data/test/fuzz/Makefile.in +0 -775
  102. data/test/fuzz/README.md +0 -149
  103. data/test/fuzz/fuzz_common.rb +0 -96
  104. data/test/fuzz/fuzz_parse_binary_protocol.rb +0 -23
  105. data/test/fuzz/fuzz_parse_binary_protocol_accelerated.rb +0 -23
  106. data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +0 -23
  107. data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +0 -23
  108. data/test/fuzz/fuzz_parse_compact_protocol.rb +0 -23
  109. data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +0 -23
  110. data/test/fuzz/fuzz_parse_json_protocol.rb +0 -23
  111. data/test/fuzz/fuzz_parse_json_protocol_harness.rb +0 -23
  112. data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +0 -23
  113. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +0 -23
  114. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +0 -23
  115. data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +0 -23
  116. data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +0 -23
  117. data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +0 -23
  118. data/test/fuzz/fuzz_roundtrip_json_protocol.rb +0 -23
  119. data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +0 -23
  120. data/test/fuzz/fuzz_tracer.rb +0 -29
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
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
-
21
- require 'spec_helper'
22
- require File.expand_path("#{File.dirname(__FILE__)}/binary_protocol_spec_shared")
23
-
24
- if defined? Thrift::BinaryProtocolAccelerated
25
-
26
- describe 'BinaryProtocolAccelerated' do
27
- # since BinaryProtocolAccelerated should be directly equivalent to
28
- # BinaryProtocol, we don't need any custom specs!
29
- it_should_behave_like 'a binary protocol'
30
-
31
- def protocol_class
32
- Thrift::BinaryProtocolAccelerated
33
- end
34
-
35
- describe Thrift::BinaryProtocolAcceleratedFactory do
36
- it "should create a BinaryProtocolAccelerated" do
37
- expect(Thrift::BinaryProtocolAcceleratedFactory.new.get_protocol(double("MockTransport"))).to be_instance_of(Thrift::BinaryProtocolAccelerated)
38
- end
39
-
40
- it "should provide a reasonable to_s" do
41
- expect(Thrift::BinaryProtocolAcceleratedFactory.new.to_s).to eq("binary-accel")
42
- end
43
- end
44
- end
45
- else
46
- puts "skipping BinaryProtocolAccelerated spec because it is not defined."
47
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
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
-
21
- require 'spec_helper'
22
- require File.expand_path("#{File.dirname(__FILE__)}/binary_protocol_spec_shared")
23
-
24
- describe 'BinaryProtocol' do
25
- it_should_behave_like 'a binary protocol'
26
-
27
- def protocol_class
28
- Thrift::BinaryProtocol
29
- end
30
-
31
- describe Thrift::BinaryProtocol do
32
- before(:each) do
33
- @trans = Thrift::MemoryBufferTransport.new
34
- @prot = protocol_class.new(@trans)
35
- end
36
-
37
- it "should read a message header" do
38
- @trans.write([protocol_class.const_get(:VERSION_1) | Thrift::MessageTypes::REPLY].pack('N'))
39
- @trans.write([42].pack('N'))
40
- expect(@prot).to receive(:read_string).and_return('testMessage')
41
- expect(@prot.read_message_begin).to eq(['testMessage', Thrift::MessageTypes::REPLY, 42])
42
- end
43
-
44
- it "should raise an exception if the message header has the wrong version" do
45
- expect(@prot).to receive(:read_i32).and_return(-1)
46
- expect { @prot.read_message_begin }.to raise_error(Thrift::ProtocolException, 'Missing version identifier') do |e|
47
- e.type == Thrift::ProtocolException::BAD_VERSION
48
- end
49
- end
50
-
51
- it "should raise an exception if the message header does not exist and strict_read is enabled" do
52
- expect(@prot).to receive(:read_i32).and_return(42)
53
- expect(@prot).to receive(:strict_read).and_return(true)
54
- expect { @prot.read_message_begin }.to raise_error(Thrift::ProtocolException, 'No version identifier, old protocol client?') do |e|
55
- e.type == Thrift::ProtocolException::BAD_VERSION
56
- end
57
- end
58
-
59
- it "should provide a reasonable to_s" do
60
- expect(@prot.to_s).to eq("binary(memory)")
61
- end
62
- end
63
-
64
- describe Thrift::BinaryProtocolFactory do
65
- it "should create a BinaryProtocol" do
66
- expect(Thrift::BinaryProtocolFactory.new.get_protocol(double("MockTransport"))).to be_instance_of(Thrift::BinaryProtocol)
67
- end
68
-
69
- it "should provide a reasonable to_s" do
70
- expect(Thrift::BinaryProtocolFactory.new.to_s).to eq("binary")
71
- end
72
- end
73
- end
@@ -1,509 +0,0 @@
1
- # encoding: ascii-8bit
2
- # frozen_string_literal: true
3
- #
4
- # Licensed to the Apache Software Foundation (ASF) under one
5
- # or more contributor license agreements. See the NOTICE file
6
- # distributed with this work for additional information
7
- # regarding copyright ownership. The ASF licenses this file
8
- # to you under the Apache License, Version 2.0 (the
9
- # "License"); you may not use this file except in compliance
10
- # with the License. You may obtain a copy of the License at
11
- #
12
- # http://www.apache.org/licenses/LICENSE-2.0
13
- #
14
- # Unless required by applicable law or agreed to in writing,
15
- # software distributed under the License is distributed on an
16
- # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17
- # KIND, either express or implied. See the License for the
18
- # specific language governing permissions and limitations
19
- # under the License.
20
- #
21
-
22
- require 'spec_helper'
23
-
24
- shared_examples_for 'a binary protocol' do
25
- before(:each) do
26
- @trans = Thrift::MemoryBufferTransport.new
27
- @prot = protocol_class.new(@trans)
28
- end
29
-
30
- it "should define the proper VERSION_1, VERSION_MASK AND TYPE_MASK" do
31
- expect(protocol_class.const_get(:VERSION_MASK)).to eq(0xffff0000)
32
- expect(protocol_class.const_get(:VERSION_1)).to eq(0x80010000)
33
- expect(protocol_class.const_get(:TYPE_MASK)).to eq(0x000000ff)
34
- end
35
-
36
- it "should make strict_read readable" do
37
- expect(@prot.strict_read).to eql(true)
38
- end
39
-
40
- it "should make strict_write readable" do
41
- expect(@prot.strict_write).to eql(true)
42
- end
43
-
44
- it "should write the message header" do
45
- @prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17)
46
- expect(@trans.read(@trans.available)).to eq([protocol_class.const_get(:VERSION_1) | Thrift::MessageTypes::CALL, "testMessage".size, "testMessage", 17].pack("NNa11N"))
47
- end
48
-
49
- it "should write the message header without version when writes are not strict" do
50
- @prot = protocol_class.new(@trans, true, false) # no strict write
51
- @prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17)
52
- expect(@trans.read(@trans.available)).to eq("\000\000\000\vtestMessage\001\000\000\000\021")
53
- end
54
-
55
- it "should write the message header with a version when writes are strict" do
56
- @prot = protocol_class.new(@trans) # strict write
57
- @prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17)
58
- expect(@trans.read(@trans.available)).to eq("\200\001\000\001\000\000\000\vtestMessage\000\000\000\021")
59
- end
60
-
61
- # message footer is a noop
62
-
63
- it "should write the field header" do
64
- @prot.write_field_begin('foo', Thrift::Types::DOUBLE, 3)
65
- expect(@trans.read(@trans.available)).to eq([Thrift::Types::DOUBLE, 3].pack("cn"))
66
- end
67
-
68
- # field footer is a noop
69
-
70
- it "should write the STOP field" do
71
- @prot.write_field_stop
72
- expect(@trans.read(1)).to eq("\000")
73
- end
74
-
75
- it "should write the map header" do
76
- @prot.write_map_begin(Thrift::Types::STRING, Thrift::Types::LIST, 17)
77
- expect(@trans.read(@trans.available)).to eq([Thrift::Types::STRING, Thrift::Types::LIST, 17].pack("ccN"));
78
- end
79
-
80
- # map footer is a noop
81
-
82
- it "should write the list header" do
83
- @prot.write_list_begin(Thrift::Types::I16, 42)
84
- expect(@trans.read(@trans.available)).to eq([Thrift::Types::I16, 42].pack("cN"))
85
- end
86
-
87
- # list footer is a noop
88
-
89
- it "should write the set header" do
90
- @prot.write_set_begin(Thrift::Types::I16, 42)
91
- expect(@trans.read(@trans.available)).to eq([Thrift::Types::I16, 42].pack("cN"))
92
- end
93
-
94
- it "should write a bool" do
95
- @prot.write_bool(true)
96
- @prot.write_bool(false)
97
- expect(@trans.read(@trans.available)).to eq("\001\000")
98
- end
99
-
100
- it "should treat a nil bool as false" do
101
- @prot.write_bool(nil)
102
- expect(@trans.read(1)).to eq("\000")
103
- end
104
-
105
- it "should write a byte" do
106
- # byte is small enough, let's check -128..127
107
- (-128..127).each do |i|
108
- @prot.write_byte(i)
109
- expect(@trans.read(1)).to eq([i].pack('c'))
110
- end
111
- end
112
-
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)
116
- end
117
- expect(@trans.available).to eq(0)
118
- end
119
-
120
- it "should reject non-integer bytes" do
121
- expect { @prot.write_byte(1.5) }.to raise_error(TypeError)
122
- end
123
-
124
- it "should error gracefully when trying to write a nil byte" do
125
- expect { @prot.write_byte(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
126
- end
127
-
128
- it "should write an i16" do
129
- # try a random scattering of values
130
- # include the signed i16 minimum/maximum
131
- [-2**15, -1024, 17, 0, -10000, 1723, 2**15-1].each do |i|
132
- @prot.write_i16(i)
133
- end
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
-
149
- it "should error gracefully when trying to write a nil i16" do
150
- expect { @prot.write_i16(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
151
- end
152
-
153
- it "should write an i32" do
154
- # try a random scattering of values
155
- # include the signed i32 minimum/maximum
156
- [-2**31, -123123, -2532, -3, 0, 2351235, 12331, 2**31-1].each do |i|
157
- @prot.write_i32(i)
158
- end
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")
160
- [-2 ** 31 - 1, 2 ** 31, 2 ** 65 + 5].each do |i|
161
- expect { @prot.write_i32(i) }.to raise_error(RangeError)
162
- end
163
- end
164
-
165
- it "should reject non-integer i32 values" do
166
- expect { @prot.write_i32(1.5) }.to raise_error(TypeError)
167
- end
168
-
169
- it "should error gracefully when trying to write a nil i32" do
170
- expect { @prot.write_i32(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
171
- end
172
-
173
- it "should write an i64" do
174
- # try a random scattering of values
175
- # try the signed i64 minimum/maximum
176
- [-2**63, -12356123612323, -23512351, -234, 0, 1231, 2351236, 12361236213, 2**63-1].each do |i|
177
- @prot.write_i64(i)
178
- end
179
- expect(@trans.read(@trans.available)).to eq(["\200\000\000\000\000\000\000\000",
180
- "\377\377\364\303\035\244+]",
181
- "\377\377\377\377\376\231:\341",
182
- "\377\377\377\377\377\377\377\026",
183
- "\000\000\000\000\000\000\000\000",
184
- "\000\000\000\000\000\000\004\317",
185
- "\000\000\000\000\000#\340\204",
186
- "\000\000\000\002\340\311~\365",
187
- "\177\377\377\377\377\377\377\377"].join(""))
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)
195
- end
196
-
197
- it "should error gracefully when trying to write a nil i64" do
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)
204
- end
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
-
212
- it "should write a double" do
213
- # try a random scattering of values, including min/max
214
- values = [Float::MIN, -1231.15325, -123123.23, -23.23515123, 0, 12351.1325, 523.23, Float::MAX]
215
- values.each do |f|
216
- @prot.write_double(f)
217
- expect(@trans.read(@trans.available)).to eq([f].pack("G"))
218
- end
219
- end
220
-
221
- it "should error gracefully when trying to write a nil double" do
222
- expect { @prot.write_double(nil) }.to raise_error(StandardError, 'nil argument not allowed!')
223
- end
224
-
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
232
-
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
241
-
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
249
-
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
257
-
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])
266
- end
267
-
268
- it "should error gracefully when trying to write a nil string" do
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")
286
- end
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
-
292
- it "should write the message header without version when writes are not strict" do
293
- @prot = protocol_class.new(@trans, true, false) # no strict write
294
- @prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17)
295
- expect(@trans.read(@trans.available)).to eq("\000\000\000\vtestMessage\001\000\000\000\021")
296
- end
297
-
298
- it "should write the message header with a version when writes are strict" do
299
- @prot = protocol_class.new(@trans) # strict write
300
- @prot.write_message_begin('testMessage', Thrift::MessageTypes::CALL, 17)
301
- expect(@trans.read(@trans.available)).to eq("\200\001\000\001\000\000\000\vtestMessage\000\000\000\021")
302
- end
303
-
304
- # message footer is a noop
305
-
306
- it "should read a field header" do
307
- @trans.write([Thrift::Types::STRING, 3].pack("cn"))
308
- expect(@prot.read_field_begin).to eq([nil, Thrift::Types::STRING, 3])
309
- end
310
-
311
- # field footer is a noop
312
-
313
- it "should read a stop field" do
314
- @trans.write([Thrift::Types::STOP].pack("c"));
315
- expect(@prot.read_field_begin).to eq([nil, Thrift::Types::STOP, 0])
316
- end
317
-
318
- it "should read a map header" do
319
- @trans.write([Thrift::Types::DOUBLE, Thrift::Types::I64, 42].pack("ccN"))
320
- expect(@prot.read_map_begin).to eq([Thrift::Types::DOUBLE, Thrift::Types::I64, 42])
321
- end
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
-
330
- # map footer is a noop
331
-
332
- it "should read a list header" do
333
- @trans.write([Thrift::Types::STRING, 17].pack("cN"))
334
- expect(@prot.read_list_begin).to eq([Thrift::Types::STRING, 17])
335
- end
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
-
344
- # list footer is a noop
345
-
346
- it "should read a set header" do
347
- @trans.write([Thrift::Types::STRING, 17].pack("cN"))
348
- expect(@prot.read_set_begin).to eq([Thrift::Types::STRING, 17])
349
- end
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
-
358
- # set footer is a noop
359
-
360
- it "should read a bool" do
361
- @trans.write("\001\000");
362
- expect(@prot.read_bool).to eq(true)
363
- expect(@prot.read_bool).to eq(false)
364
- end
365
-
366
- it "should read a byte" do
367
- [-128, -57, -3, 0, 17, 24, 127].each do |i|
368
- @trans.write([i].pack("c"))
369
- expect(@prot.read_byte).to eq(i)
370
- end
371
- end
372
-
373
- it "should read an i16" do
374
- # try a scattering of values, including min/max
375
- [-2**15, -5237, -353, 0, 1527, 2234, 2**15-1].each do |i|
376
- @trans.write([i].pack("n"));
377
- expect(@prot.read_i16).to eq(i)
378
- end
379
- end
380
-
381
- it "should read an i32" do
382
- # try a scattering of values, including min/max
383
- [-2**31, -235125, -6236, 0, 2351, 123123, 2**31-1].each do |i|
384
- @trans.write([i].pack("N"))
385
- expect(@prot.read_i32).to eq(i)
386
- end
387
- end
388
-
389
- it "should read an i64" do
390
- # try a scattering of values, including min/max
391
- [-2**63, -123512312, -6346, 0, 32, 2346322323, 2**63-1].each do |i|
392
- @trans.write([i >> 32, i & 0xFFFFFFFF].pack("NN"))
393
- expect(@prot.read_i64).to eq(i)
394
- end
395
- end
396
-
397
- it "should read a double" do
398
- # try a random scattering of values, including min/max
399
- [Float::MIN, -231231.12351, -323.233513, 0, 123.2351235, 2351235.12351235, Float::MAX].each do |f|
400
- @trans.write([f].pack("G"));
401
- expect(@prot.read_double).to eq(f)
402
- end
403
- end
404
-
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
413
-
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
422
-
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
430
-
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)
435
- end
436
- end
437
-
438
- it "should perform a complete rpc with no args or return" do
439
- srv_test(
440
- proc { |client| client.send_voidMethod() },
441
- proc { |client| expect(client.recv_voidMethod).to eq(nil) }
442
- )
443
- end
444
-
445
- it "should perform a complete rpc with a primitive return type" do
446
- srv_test(
447
- proc { |client| client.send_primitiveMethod() },
448
- proc { |client| expect(client.recv_primitiveMethod).to eq(1) }
449
- )
450
- end
451
-
452
- it "should perform a complete rpc with a struct return type" do
453
- srv_test(
454
- proc { |client| client.send_structMethod() },
455
- proc { |client|
456
- result = client.recv_structMethod
457
- result.set_byte_map = nil
458
- result.map_byte_map = nil
459
- expect(result).to eq(Fixtures::COMPACT_PROTOCOL_TEST_STRUCT)
460
- }
461
- )
462
- end
463
-
464
- def get_socket_connection
465
- server = Thrift::ServerSocket.new("localhost", 9090)
466
- server.listen
467
-
468
- clientside = Thrift::Socket.new("localhost", 9090)
469
- clientside.open
470
- serverside = server.accept
471
- [clientside, serverside, server]
472
- end
473
-
474
- def srv_test(firstblock, secondblock)
475
- clientside, serverside, server = get_socket_connection
476
-
477
- clientproto = protocol_class.new(clientside)
478
- serverproto = protocol_class.new(serverside)
479
-
480
- processor = Thrift::Test::Srv::Processor.new(SrvHandler.new)
481
-
482
- client = Thrift::Test::Srv::Client.new(clientproto, clientproto)
483
-
484
- # first block
485
- firstblock.call(client)
486
-
487
- processor.process(serverproto, serverproto)
488
-
489
- # second block
490
- secondblock.call(client)
491
- ensure
492
- clientside.close
493
- serverside.close
494
- server.close
495
- end
496
-
497
- class SrvHandler
498
- def voidMethod()
499
- end
500
-
501
- def primitiveMethod
502
- 1
503
- end
504
-
505
- def structMethod
506
- Fixtures::COMPACT_PROTOCOL_TEST_STRUCT
507
- end
508
- end
509
- end