thrift 0.22.0 → 0.23.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 (112) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +175 -17
  3. data/benchmark/benchmark.rb +22 -8
  4. data/benchmark/client.rb +49 -6
  5. data/benchmark/server.rb +45 -7
  6. data/benchmark/thin_server.rb +1 -0
  7. data/ext/binary_protocol_accelerated.c +76 -19
  8. data/ext/compact_protocol.c +80 -15
  9. data/ext/constants.h +12 -0
  10. data/ext/extconf.rb +10 -9
  11. data/ext/memory_buffer.c +7 -7
  12. data/ext/protocol.c +29 -0
  13. data/ext/protocol.h +35 -0
  14. data/ext/struct.c +36 -5
  15. data/ext/thrift_native.c +27 -3
  16. data/lib/thrift/bytes.rb +68 -101
  17. data/lib/thrift/client.rb +61 -9
  18. data/lib/thrift/exceptions.rb +5 -5
  19. data/lib/thrift/multiplexed_processor.rb +6 -6
  20. data/lib/thrift/processor.rb +6 -6
  21. data/lib/thrift/protocol/base_protocol.rb +37 -15
  22. data/lib/thrift/protocol/binary_protocol.rb +25 -9
  23. data/lib/thrift/protocol/binary_protocol_accelerated.rb +5 -5
  24. data/lib/thrift/protocol/compact_protocol.rb +61 -37
  25. data/lib/thrift/protocol/header_protocol.rb +320 -0
  26. data/lib/thrift/protocol/json_protocol.rb +26 -16
  27. data/lib/thrift/protocol/multiplexed_protocol.rb +5 -5
  28. data/lib/thrift/protocol/protocol_decorator.rb +12 -4
  29. data/lib/thrift/serializer/deserializer.rb +5 -5
  30. data/lib/thrift/serializer/serializer.rb +4 -5
  31. data/lib/thrift/server/base_server.rb +4 -4
  32. data/lib/thrift/server/mongrel_http_server.rb +6 -6
  33. data/lib/thrift/server/nonblocking_server.rb +8 -8
  34. data/lib/thrift/server/simple_server.rb +4 -4
  35. data/lib/thrift/server/thin_http_server.rb +3 -3
  36. data/lib/thrift/server/thread_pool_server.rb +6 -6
  37. data/lib/thrift/server/threaded_server.rb +4 -4
  38. data/lib/thrift/struct.rb +11 -11
  39. data/lib/thrift/struct_union.rb +19 -9
  40. data/lib/thrift/thrift_native.rb +1 -1
  41. data/lib/thrift/transport/base_server_transport.rb +5 -5
  42. data/lib/thrift/transport/base_transport.rb +12 -12
  43. data/lib/thrift/transport/buffered_transport.rb +6 -6
  44. data/lib/thrift/transport/framed_transport.rb +7 -7
  45. data/lib/thrift/transport/header_transport.rb +516 -0
  46. data/lib/thrift/transport/http_client_transport.rb +1 -1
  47. data/lib/thrift/transport/io_stream_transport.rb +3 -3
  48. data/lib/thrift/transport/memory_buffer_transport.rb +6 -6
  49. data/lib/thrift/transport/server_socket.rb +8 -5
  50. data/lib/thrift/transport/socket.rb +58 -31
  51. data/lib/thrift/transport/ssl_server_socket.rb +1 -1
  52. data/lib/thrift/transport/ssl_socket.rb +2 -2
  53. data/lib/thrift/transport/unix_server_socket.rb +4 -4
  54. data/lib/thrift/transport/unix_socket.rb +6 -6
  55. data/lib/thrift/types.rb +9 -6
  56. data/lib/thrift/union.rb +14 -8
  57. data/lib/thrift/uuid.rb +49 -0
  58. data/lib/thrift.rb +3 -1
  59. data/spec/ThriftSpec.thrift +5 -1
  60. data/spec/base_protocol_spec.rb +1 -2
  61. data/spec/base_transport_spec.rb +6 -7
  62. data/spec/binary_protocol_spec.rb +0 -2
  63. data/spec/binary_protocol_spec_shared.rb +129 -142
  64. data/spec/bytes_spec.rb +57 -118
  65. data/spec/client_spec.rb +85 -19
  66. data/spec/compact_protocol_spec.rb +54 -16
  67. data/spec/constants_demo_spec.rb +101 -0
  68. data/spec/exception_spec.rb +0 -1
  69. data/spec/header_protocol_spec.rb +475 -0
  70. data/spec/header_transport_spec.rb +386 -0
  71. data/spec/http_client_spec.rb +4 -6
  72. data/spec/json_protocol_spec.rb +47 -47
  73. data/spec/namespaced_spec.rb +0 -1
  74. data/spec/nonblocking_server_spec.rb +102 -4
  75. data/spec/processor_spec.rb +0 -1
  76. data/spec/serializer_spec.rb +0 -1
  77. data/spec/server_socket_spec.rb +1 -1
  78. data/spec/server_spec.rb +8 -9
  79. data/spec/socket_spec.rb +0 -1
  80. data/spec/socket_spec_shared.rb +72 -9
  81. data/spec/spec_helper.rb +1 -1
  82. data/spec/ssl_server_socket_spec.rb +12 -1
  83. data/spec/ssl_socket_spec.rb +10 -1
  84. data/spec/struct_nested_containers_spec.rb +1 -2
  85. data/spec/struct_spec.rb +113 -9
  86. data/spec/support/header_protocol_helper.rb +54 -0
  87. data/spec/thin_http_server_spec.rb +3 -18
  88. data/spec/types_spec.rb +25 -26
  89. data/spec/union_spec.rb +69 -11
  90. data/spec/unix_socket_spec.rb +1 -2
  91. data/spec/uuid_validation_spec.rb +238 -0
  92. data/test/fuzz/Makefile.am +173 -0
  93. data/test/fuzz/README.md +149 -0
  94. data/test/fuzz/fuzz_common.rb +95 -0
  95. data/{lib/thrift/core_ext.rb → test/fuzz/fuzz_parse_binary_protocol.rb} +3 -4
  96. data/{lib/thrift/core_ext/fixnum.rb → test/fuzz/fuzz_parse_binary_protocol_accelerated.rb} +6 -13
  97. data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +22 -0
  98. data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +22 -0
  99. data/test/fuzz/fuzz_parse_compact_protocol.rb +22 -0
  100. data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +22 -0
  101. data/test/fuzz/fuzz_parse_json_protocol.rb +22 -0
  102. data/test/fuzz/fuzz_parse_json_protocol_harness.rb +22 -0
  103. data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +22 -0
  104. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +22 -0
  105. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +22 -0
  106. data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +22 -0
  107. data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +22 -0
  108. data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +22 -0
  109. data/test/fuzz/fuzz_roundtrip_json_protocol.rb +22 -0
  110. data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +22 -0
  111. data/test/fuzz/fuzz_tracer.rb +28 -0
  112. metadata +106 -37
@@ -0,0 +1,386 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+ #
19
+
20
+ require 'spec_helper'
21
+ require_relative 'support/header_protocol_helper'
22
+
23
+ describe 'HeaderTransport' do
24
+ include HeaderProtocolHelper
25
+
26
+ describe Thrift::HeaderClientType do
27
+ it "should define client type constants" do
28
+ expect(Thrift::HeaderClientType::HEADERS).to eq(0x00)
29
+ expect(Thrift::HeaderClientType::FRAMED_BINARY).to eq(0x01)
30
+ expect(Thrift::HeaderClientType::UNFRAMED_BINARY).to eq(0x02)
31
+ expect(Thrift::HeaderClientType::FRAMED_COMPACT).to eq(0x03)
32
+ expect(Thrift::HeaderClientType::UNFRAMED_COMPACT).to eq(0x04)
33
+ end
34
+ end
35
+
36
+ describe Thrift::HeaderSubprotocolID do
37
+ it "should define protocol ID constants" do
38
+ expect(Thrift::HeaderSubprotocolID::BINARY).to eq(0x00)
39
+ expect(Thrift::HeaderSubprotocolID::COMPACT).to eq(0x02)
40
+ end
41
+ end
42
+
43
+ describe Thrift::HeaderTransformID do
44
+ it "should define transform ID constants" do
45
+ expect(Thrift::HeaderTransformID::ZLIB).to eq(0x01)
46
+ end
47
+ end
48
+
49
+ describe Thrift::HeaderTransport do
50
+ before(:each) do
51
+ @underlying = Thrift::MemoryBufferTransport.new
52
+ @trans = Thrift::HeaderTransport.new(@underlying)
53
+ end
54
+
55
+ it "should provide a to_s that describes the encapsulation" do
56
+ expect(@trans.to_s).to eq("header(memory)")
57
+ end
58
+
59
+ it "should pass through open?/open/close" do
60
+ mock_transport = double("Transport")
61
+ expect(mock_transport).to receive(:open?).and_return(true)
62
+ expect(mock_transport).to receive(:open).and_return(nil)
63
+ expect(mock_transport).to receive(:close).and_return(nil)
64
+
65
+ trans = Thrift::HeaderTransport.new(mock_transport)
66
+ expect(trans.open?).to be true
67
+ trans.open
68
+ trans.close
69
+ end
70
+
71
+ describe "header management" do
72
+ it "should allow setting and getting headers" do
73
+ @trans.set_header("key1", "value1")
74
+ @trans.set_header("key2", "value2")
75
+ # Headers aren't read until we receive data, so write and read back
76
+ expect(@trans.get_headers).to eq({})
77
+ end
78
+
79
+ it "should clear headers" do
80
+ @trans.set_header("key1", "value1")
81
+ @trans.clear_headers
82
+ # Write and flush to verify headers were cleared
83
+ @trans.write("test")
84
+ @trans.flush
85
+ end
86
+
87
+ it "should add transforms" do
88
+ expect { @trans.add_transform(Thrift::HeaderTransformID::ZLIB) }.not_to raise_error
89
+ end
90
+
91
+ it "should reject unknown transforms" do
92
+ expect { @trans.add_transform(999) }.to raise_error(Thrift::TransportException)
93
+ end
94
+ end
95
+
96
+ describe "write and flush" do
97
+ it "should buffer writes" do
98
+ @trans.write("hello")
99
+ @trans.write(" world")
100
+ expect(@underlying.available).to eq(0)
101
+ end
102
+
103
+ it "should write Header format on flush" do
104
+ @trans.write("test payload")
105
+ @trans.flush
106
+
107
+ # Read back the frame
108
+ data = @underlying.read(@underlying.available)
109
+
110
+ # Should have frame length (4 bytes) + header + payload
111
+ expect(data.bytesize).to be > 16
112
+
113
+ # First 4 bytes are frame length
114
+ frame_size = data[0, 4].unpack('N').first
115
+ expect(frame_size).to eq(data.bytesize - 4)
116
+
117
+ # Next 2 bytes should be header magic
118
+ magic = data[4, 2].unpack('n').first
119
+ expect(magic).to eq(Thrift::HeaderTransport::HEADER_MAGIC)
120
+ end
121
+
122
+ it "should include headers in frame" do
123
+ @trans.set_header("test-key", "test-value")
124
+ @trans.write("payload")
125
+ @trans.flush
126
+
127
+ # Read back and verify it's larger due to headers
128
+ data = @underlying.read(@underlying.available)
129
+ expect(data.bytesize).to be > 30 # Should include header key-value
130
+ end
131
+
132
+ it "should write the configured sequence id into the frame header" do
133
+ @trans.sequence_id = 456
134
+ @trans.write("payload")
135
+ @trans.flush
136
+
137
+ data = @underlying.read(@underlying.available)
138
+ expect(data[8, 4].unpack('N').first).to eq(456)
139
+ end
140
+
141
+ it "should apply ZLIB transform" do
142
+ @trans.add_transform(Thrift::HeaderTransformID::ZLIB)
143
+ original_payload = "a" * 1000 # Compressible data
144
+ @trans.write(original_payload)
145
+ @trans.flush
146
+
147
+ data = @underlying.read(@underlying.available)
148
+ # Compressed frame should be smaller than uncompressed
149
+ expect(data.bytesize).to be < original_payload.bytesize
150
+ end
151
+ end
152
+
153
+ describe "frame size limits" do
154
+ it "should reject payloads larger than max frame size" do
155
+ @trans.set_max_frame_size(4)
156
+ @trans.write("12345")
157
+ expect { @trans.flush }.to raise_error(Thrift::TransportException, /frame that is too large/)
158
+ end
159
+ end
160
+
161
+ describe "read and frame detection" do
162
+ it "should detect Header format" do
163
+ # Write a Header frame
164
+ @trans.write("test data")
165
+ @trans.flush
166
+
167
+ # Reset for reading
168
+ written_data = @underlying.read(@underlying.available)
169
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
170
+ read_trans = Thrift::HeaderTransport.new(read_transport)
171
+
172
+ result = read_trans.read(9)
173
+ expect(result).to eq("test data")
174
+ end
175
+
176
+ it "should detect framed binary protocol" do
177
+ # Create a framed binary message
178
+ payload = [Thrift::BinaryProtocol::VERSION_1 | Thrift::MessageTypes::CALL].pack('N')
179
+ payload << "test"
180
+ frame = [payload.bytesize].pack('N') + payload
181
+
182
+ read_transport = Thrift::MemoryBufferTransport.new(frame)
183
+ read_trans = Thrift::HeaderTransport.new(read_transport)
184
+
185
+ result = read_trans.read(payload.bytesize)
186
+ expect(result).to eq(payload)
187
+ end
188
+
189
+ it "should detect unframed binary protocol" do
190
+ # Create an unframed binary message (version word first)
191
+ message = [Thrift::BinaryProtocol::VERSION_1 | Thrift::MessageTypes::CALL].pack('N')
192
+ message << "test"
193
+
194
+ read_transport = Thrift::MemoryBufferTransport.new(message)
195
+ read_trans = Thrift::HeaderTransport.new(read_transport)
196
+
197
+ result = read_trans.read(message.bytesize)
198
+ expect(result).to eq(message)
199
+ end
200
+
201
+ it "should read headers from Header frame" do
202
+ # Write with headers
203
+ @trans.set_header("request-id", "12345")
204
+ @trans.write("payload")
205
+ @trans.flush
206
+
207
+ # Read back
208
+ written_data = @underlying.read(@underlying.available)
209
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
210
+ read_trans = Thrift::HeaderTransport.new(read_transport)
211
+
212
+ read_trans.read(7)
213
+ headers = read_trans.get_headers
214
+ expect(headers["request-id"]).to eq("12345")
215
+ end
216
+
217
+ it "should decode signed sequence ids from Header frames" do
218
+ @trans.sequence_id = -2147483648
219
+ @trans.write("payload")
220
+ @trans.flush
221
+
222
+ written_data = @underlying.read(@underlying.available)
223
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
224
+ read_trans = Thrift::HeaderTransport.new(read_transport)
225
+
226
+ expect(read_trans.read(7)).to eq("payload")
227
+ expect(read_trans.sequence_id).to eq(-2147483648)
228
+ end
229
+
230
+ it "should decompress ZLIB payload" do
231
+ # Write with ZLIB
232
+ @trans.add_transform(Thrift::HeaderTransformID::ZLIB)
233
+ original = "hello world this is a test"
234
+ @trans.write(original)
235
+ @trans.flush
236
+
237
+ # Read back
238
+ written_data = @underlying.read(@underlying.available)
239
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
240
+ read_trans = Thrift::HeaderTransport.new(read_transport)
241
+
242
+ result = read_trans.read(original.bytesize)
243
+ expect(result).to eq(original)
244
+ end
245
+ end
246
+
247
+ describe "header parsing protections" do
248
+ it "should reject unreasonable header sizes" do
249
+ frame = build_header_frame("", Thrift::Bytes.empty_byte_buffer, header_words: 16_384)
250
+ read_transport = Thrift::MemoryBufferTransport.new(frame)
251
+ read_trans = Thrift::HeaderTransport.new(read_transport)
252
+
253
+ expect { read_trans.read(1) }.to raise_error(Thrift::TransportException, /Header size is unreasonable/)
254
+ end
255
+
256
+ it "should reject header frames that are too small" do
257
+ frame = Thrift::Bytes.empty_byte_buffer
258
+ frame << [9].pack('N')
259
+ frame << [Thrift::HeaderTransport::HEADER_MAGIC].pack('n')
260
+ frame << [0].pack('n')
261
+ frame << [0].pack('N')
262
+ frame << [0].pack('n')
263
+ read_transport = Thrift::MemoryBufferTransport.new(frame)
264
+ read_trans = Thrift::HeaderTransport.new(read_transport)
265
+
266
+ expect { read_trans.read(1) }.to raise_error(Thrift::TransportException, /frame is too small/)
267
+ end
268
+
269
+ it "should reject varints that cross header boundary" do
270
+ header_data = [0x80, 0x80, 0x80, 0x80].pack('C*')
271
+ frame = build_header_frame(header_data)
272
+ read_transport = Thrift::MemoryBufferTransport.new(frame)
273
+ read_trans = Thrift::HeaderTransport.new(read_transport)
274
+
275
+ expect { read_trans.read(1) }.to raise_error(Thrift::TransportException, /header boundary/)
276
+ end
277
+
278
+ it "should reject strings that exceed header boundary" do
279
+ header_data = +""
280
+ header_data << varint32(Thrift::HeaderSubprotocolID::BINARY)
281
+ header_data << varint32(0)
282
+ header_data << varint32(Thrift::HeaderInfoType::KEY_VALUE)
283
+ header_data << varint32(1)
284
+ header_data << varint32(10)
285
+ header_data << "a"
286
+
287
+ frame = build_header_frame(header_data)
288
+ read_transport = Thrift::MemoryBufferTransport.new(frame)
289
+ read_trans = Thrift::HeaderTransport.new(read_transport)
290
+
291
+ expect { read_trans.read(1) }.to raise_error(Thrift::TransportException, /Info header length exceeds header size/)
292
+ end
293
+ end
294
+
295
+ describe "round-trip" do
296
+ it "should handle complete write-read cycle" do
297
+ # Write
298
+ @trans.set_header("trace-id", "abc123")
299
+ @trans.write("hello world")
300
+ @trans.flush
301
+
302
+ # Read
303
+ written_data = @underlying.read(@underlying.available)
304
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
305
+ read_trans = Thrift::HeaderTransport.new(read_transport)
306
+
307
+ result = read_trans.read(11)
308
+ expect(result).to eq("hello world")
309
+ expect(read_trans.get_headers["trace-id"]).to eq("abc123")
310
+ end
311
+
312
+ it "should handle multiple headers" do
313
+ @trans.set_header("header1", "value1")
314
+ @trans.set_header("header2", "value2")
315
+ @trans.set_header("header3", "value3")
316
+ @trans.write("data")
317
+ @trans.flush
318
+
319
+ written_data = @underlying.read(@underlying.available)
320
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
321
+ read_trans = Thrift::HeaderTransport.new(read_transport)
322
+
323
+ read_trans.read(4)
324
+ headers = read_trans.get_headers
325
+ expect(headers["header1"]).to eq("value1")
326
+ expect(headers["header2"]).to eq("value2")
327
+ expect(headers["header3"]).to eq("value3")
328
+ end
329
+
330
+ it "should handle ZLIB compression round-trip" do
331
+ @trans.add_transform(Thrift::HeaderTransformID::ZLIB)
332
+ @trans.set_header("compressed", "true")
333
+ original = "x" * 500
334
+ @trans.write(original)
335
+ @trans.flush
336
+
337
+ written_data = @underlying.read(@underlying.available)
338
+ read_transport = Thrift::MemoryBufferTransport.new(written_data)
339
+ read_trans = Thrift::HeaderTransport.new(read_transport)
340
+
341
+ result = read_trans.read(500)
342
+ expect(result).to eq(original)
343
+ expect(read_trans.get_headers["compressed"]).to eq("true")
344
+ end
345
+ end
346
+
347
+ describe "client type restrictions" do
348
+ it "should reject disallowed client types" do
349
+ # Only allow HEADERS
350
+ allowed = [Thrift::HeaderClientType::HEADERS]
351
+
352
+ # Create framed binary message
353
+ payload = [Thrift::BinaryProtocol::VERSION_1 | Thrift::MessageTypes::CALL].pack('N')
354
+ frame = [payload.bytesize].pack('N') + payload
355
+
356
+ read_transport = Thrift::MemoryBufferTransport.new(frame)
357
+ read_trans = Thrift::HeaderTransport.new(read_transport, allowed)
358
+
359
+ expect { read_trans.read(4) }.to raise_error(Thrift::TransportException)
360
+ end
361
+ end
362
+ end
363
+
364
+ describe Thrift::HeaderTransportFactory do
365
+ it "should wrap transport in HeaderTransport" do
366
+ mock_transport = double("Transport")
367
+ factory = Thrift::HeaderTransportFactory.new
368
+ result = factory.get_transport(mock_transport)
369
+ expect(result).to be_a(Thrift::HeaderTransport)
370
+ end
371
+
372
+ it "should provide a reasonable to_s" do
373
+ expect(Thrift::HeaderTransportFactory.new.to_s).to eq("header")
374
+ end
375
+
376
+ it "should pass allowed_client_types to transport" do
377
+ allowed = [Thrift::HeaderClientType::HEADERS]
378
+ factory = Thrift::HeaderTransportFactory.new(allowed)
379
+
380
+ mock_transport = Thrift::MemoryBufferTransport.new
381
+ result = factory.get_transport(mock_transport)
382
+
383
+ expect(result).to be_a(Thrift::HeaderTransport)
384
+ end
385
+ end
386
+ end
@@ -20,12 +20,11 @@
20
20
  require 'spec_helper'
21
21
 
22
22
  describe 'Thrift::HTTPClientTransport' do
23
-
24
23
  describe Thrift::HTTPClientTransport do
25
24
  before(:each) do
26
25
  @client = Thrift::HTTPClientTransport.new("http://my.domain.com/path/to/service?param=value")
27
26
  end
28
-
27
+
29
28
  it "should provide a reasonable to_s" do
30
29
  @client.to_s == "http://my.domain.com/path/to/service?param=value"
31
30
  end
@@ -84,7 +83,7 @@ describe 'Thrift::HTTPClientTransport' do
84
83
  end
85
84
  end
86
85
 
87
- @client.flush rescue
86
+ @client.flush rescue
88
87
  expect(@client.instance_variable_get(:@outbuf)).to eq(Thrift::Bytes.empty_byte_buffer)
89
88
  end
90
89
 
@@ -105,7 +104,6 @@ describe 'Thrift::HTTPClientTransport' do
105
104
 
106
105
  expect { @client.flush }.to raise_error(Thrift::TransportException)
107
106
  end
108
-
109
107
  end
110
108
 
111
109
  describe 'ssl enabled' do
@@ -124,7 +122,7 @@ describe 'Thrift::HTTPClientTransport' do
124
122
  expect(http).to receive(:use_ssl=).with(true)
125
123
  expect(http).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
126
124
  expect(http).to receive(:post).with(@service_path, "test",
127
- "Content-Type" => "application/x-thrift") do
125
+ {"Content-Type" => "application/x-thrift"}) do
128
126
  double("Net::HTTPOK").tap do |response|
129
127
  expect(response).to receive(:body).and_return "data"
130
128
  expect(response).to receive(:code).and_return "200"
@@ -146,7 +144,7 @@ describe 'Thrift::HTTPClientTransport' do
146
144
  expect(http).to receive(:use_ssl=).with(true)
147
145
  expect(http).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
148
146
  expect(http).to receive(:post).with(@service_path, "test",
149
- "Content-Type" => "application/x-thrift") do
147
+ {"Content-Type" => "application/x-thrift"}) do
150
148
  double("Net::HTTPOK").tap do |response|
151
149
  expect(response).to receive(:body).and_return "data"
152
150
  expect(response).to receive(:code).and_return "200"
@@ -21,7 +21,6 @@
21
21
  require 'spec_helper'
22
22
 
23
23
  describe 'JsonProtocol' do
24
-
25
24
  describe Thrift::JsonProtocol do
26
25
  before(:each) do
27
26
  @trans = Thrift::MemoryBufferTransport.new
@@ -221,25 +220,18 @@ describe 'JsonProtocol' do
221
220
  expect(@trans.read(@trans.available)).to eq("\"-Infinity\"")
222
221
  end
223
222
 
224
- if RUBY_VERSION >= '1.9'
225
- it 'should write string' do
226
- @prot.write_string('this is a test string')
227
- a = @trans.read(@trans.available)
228
- expect(a).to eq('"this is a test string"'.force_encoding(Encoding::BINARY))
229
- expect(a.encoding).to eq(Encoding::BINARY)
230
- end
223
+ it 'should write string' do
224
+ @prot.write_string('this is a test string')
225
+ a = @trans.read(@trans.available)
226
+ expect(a).to eq('"this is a test string"'.force_encoding(Encoding::BINARY))
227
+ expect(a.encoding).to eq(Encoding::BINARY)
228
+ end
231
229
 
232
- it 'should write string with unicode characters' do
233
- @prot.write_string("this is a test string with unicode characters: \u20AC \u20AD")
234
- a = @trans.read(@trans.available)
235
- expect(a).to eq("\"this is a test string with unicode characters: \u20AC \u20AD\"".force_encoding(Encoding::BINARY))
236
- expect(a.encoding).to eq(Encoding::BINARY)
237
- end
238
- else
239
- it 'should write string' do
240
- @prot.write_string('this is a test string')
241
- expect(@trans.read(@trans.available)).to eq('"this is a test string"')
242
- end
230
+ it 'should write string with unicode characters' do
231
+ @prot.write_string("this is a test string with unicode characters: \u20AC \u20AD")
232
+ a = @trans.read(@trans.available)
233
+ expect(a).to eq("\"this is a test string with unicode characters: \u20AC \u20AD\"".force_encoding(Encoding::BINARY))
234
+ expect(a.encoding).to eq(Encoding::BINARY)
243
235
  end
244
236
 
245
237
  it "should write binary" do
@@ -252,9 +244,14 @@ describe 'JsonProtocol' do
252
244
  expect(@trans.read(@trans.available)).to eq("\"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==\"")
253
245
  end
254
246
 
247
+ it "should write a uuid" do
248
+ @prot.write_uuid("00112233-4455-6677-8899-aabbccddeeff")
249
+ expect(@trans.read(@trans.available)).to eq("\"00112233-4455-6677-8899-aabbccddeeff\"")
250
+ end
251
+
255
252
  it "should get type name for type id" do
256
- expect {@prot.get_type_name_for_type_id(Thrift::Types::STOP)}.to raise_error(NotImplementedError)
257
- expect {@prot.get_type_name_for_type_id(Thrift::Types::VOID)}.to raise_error(NotImplementedError)
253
+ expect { @prot.get_type_name_for_type_id(Thrift::Types::STOP) }.to raise_error(NotImplementedError)
254
+ expect { @prot.get_type_name_for_type_id(Thrift::Types::VOID) }.to raise_error(NotImplementedError)
258
255
  expect(@prot.get_type_name_for_type_id(Thrift::Types::BOOL)).to eq("tf")
259
256
  expect(@prot.get_type_name_for_type_id(Thrift::Types::BYTE)).to eq("i8")
260
257
  expect(@prot.get_type_name_for_type_id(Thrift::Types::DOUBLE)).to eq("dbl")
@@ -269,7 +266,7 @@ describe 'JsonProtocol' do
269
266
  end
270
267
 
271
268
  it "should get type id for type name" do
272
- expect {@prot.get_type_id_for_type_name("pp")}.to raise_error(NotImplementedError)
269
+ expect { @prot.get_type_id_for_type_name("pp") }.to raise_error(NotImplementedError)
273
270
  expect(@prot.get_type_id_for_type_name("tf")).to eq(Thrift::Types::BOOL)
274
271
  expect(@prot.get_type_id_for_type_name("i8")).to eq(Thrift::Types::BYTE)
275
272
  expect(@prot.get_type_id_for_type_name("dbl")).to eq(Thrift::Types::DOUBLE)
@@ -285,7 +282,7 @@ describe 'JsonProtocol' do
285
282
 
286
283
  it "should read json syntax char" do
287
284
  @trans.write('F')
288
- expect {@prot.read_json_syntax_char('G')}.to raise_error(Thrift::ProtocolException)
285
+ expect { @prot.read_json_syntax_char('G') }.to raise_error(Thrift::ProtocolException)
289
286
  @trans.write('H')
290
287
  @prot.read_json_syntax_char('H')
291
288
  end
@@ -321,7 +318,7 @@ describe 'JsonProtocol' do
321
318
 
322
319
  it "should read json string" do
323
320
  @trans.write("\"\\P")
324
- expect {@prot.read_json_string(false)}.to raise_error(Thrift::ProtocolException)
321
+ expect { @prot.read_json_string(false) }.to raise_error(Thrift::ProtocolException)
325
322
 
326
323
  @trans.write("\"this is a test string\"")
327
324
  expect(@prot.read_json_string).to eq("this is a test string")
@@ -358,7 +355,7 @@ describe 'JsonProtocol' do
358
355
 
359
356
  it "should read json integer" do
360
357
  @trans.write("1.45\"\"")
361
- expect {@prot.read_json_integer}.to raise_error(Thrift::ProtocolException)
358
+ expect { @prot.read_json_integer }.to raise_error(Thrift::ProtocolException)
362
359
  @prot.read_string
363
360
 
364
361
  @trans.write("1453T")
@@ -367,11 +364,11 @@ describe 'JsonProtocol' do
367
364
 
368
365
  it "should read json double" do
369
366
  @trans.write("1.45e3e01\"\"")
370
- expect {@prot.read_json_double}.to raise_error(Thrift::ProtocolException)
367
+ expect { @prot.read_json_double }.to raise_error(Thrift::ProtocolException)
371
368
  @prot.read_string
372
369
 
373
370
  @trans.write("\"1.453e01\"")
374
- expect {@prot.read_json_double}.to raise_error(Thrift::ProtocolException)
371
+ expect { @prot.read_json_double }.to raise_error(Thrift::ProtocolException)
375
372
 
376
373
  @trans.write("1.453e01\"\"")
377
374
  expect(@prot.read_json_double).to eq(14.53)
@@ -409,7 +406,7 @@ describe 'JsonProtocol' do
409
406
 
410
407
  it "should read_message_begin" do
411
408
  @trans.write("[2,")
412
- expect {@prot.read_message_begin}.to raise_error(Thrift::ProtocolException)
409
+ expect { @prot.read_message_begin }.to raise_error(Thrift::ProtocolException)
413
410
 
414
411
  @trans.write("[1,\"name\",12,32\"\"")
415
412
  expect(@prot.read_message_begin).to eq(["name", 12, 32])
@@ -504,25 +501,18 @@ describe 'JsonProtocol' do
504
501
  expect(@prot.read_double).to eq(12.23)
505
502
  end
506
503
 
507
- if RUBY_VERSION >= '1.9'
508
- it 'should read string' do
509
- @trans.write('"this is a test string"'.force_encoding(Encoding::BINARY))
510
- a = @prot.read_string
511
- expect(a).to eq('this is a test string')
512
- expect(a.encoding).to eq(Encoding::UTF_8)
513
- end
504
+ it 'should read string' do
505
+ @trans.write('"this is a test string"'.force_encoding(Encoding::BINARY))
506
+ a = @prot.read_string
507
+ expect(a).to eq('this is a test string')
508
+ expect(a.encoding).to eq(Encoding::UTF_8)
509
+ end
514
510
 
515
- it 'should read string with unicode characters' do
516
- @trans.write('"this is a test string with unicode characters: \u20AC \u20AD"'.force_encoding(Encoding::BINARY))
517
- a = @prot.read_string
518
- expect(a).to eq("this is a test string with unicode characters: \u20AC \u20AD")
519
- expect(a.encoding).to eq(Encoding::UTF_8)
520
- end
521
- else
522
- it 'should read string' do
523
- @trans.write('"this is a test string"')
524
- expect(@prot.read_string).to eq('this is a test string')
525
- end
511
+ it 'should read string with unicode characters' do
512
+ @trans.write('"this is a test string with unicode characters: \u20AC \u20AD"'.force_encoding(Encoding::BINARY))
513
+ a = @prot.read_string
514
+ expect(a).to eq("this is a test string with unicode characters: \u20AC \u20AD")
515
+ expect(a.encoding).to eq(Encoding::UTF_8)
526
516
  end
527
517
 
528
518
  it "should read binary" do
@@ -534,7 +524,17 @@ describe 'JsonProtocol' do
534
524
  @trans.write("\"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==\"")
535
525
  expect(@prot.read_binary.bytes.to_a).to eq((0...256).to_a)
536
526
  end
537
-
527
+
528
+ it "should read a uuid" do
529
+ @trans.write("\"00112233-4455-6677-8899-aabbccddeeff\"")
530
+ expect(@prot.read_uuid).to eq("00112233-4455-6677-8899-aabbccddeeff")
531
+ end
532
+
533
+ it "should normalize uppercase uuid on read" do
534
+ @trans.write("\"00112233-4455-6677-8899-AABBCCDDEEFF\"")
535
+ expect(@prot.read_uuid).to eq("00112233-4455-6677-8899-aabbccddeeff")
536
+ end
537
+
538
538
  it "should provide a reasonable to_s" do
539
539
  expect(@prot.to_s).to eq("json(memory)")
540
540
  end
@@ -63,5 +63,4 @@ describe 'namespaced generation' do
63
63
  it "extended a service" do
64
64
  require "extended/extended_service"
65
65
  end
66
-
67
66
  end