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
data/spec/bytes_spec.rb CHANGED
@@ -21,140 +21,79 @@
21
21
  require 'spec_helper'
22
22
 
23
23
  describe Thrift::Bytes do
24
- if RUBY_VERSION >= '1.9'
25
- describe '.empty_byte_buffer' do
26
- it 'should create an empty buffer' do
27
- b = Thrift::Bytes.empty_byte_buffer
28
- expect(b.length).to eq(0)
29
- expect(b.encoding).to eq(Encoding::BINARY)
30
- end
31
-
32
- it 'should create an empty buffer of given size' do
33
- b = Thrift::Bytes.empty_byte_buffer 2
34
- expect(b.length).to eq(2)
35
- expect(b.getbyte(0)).to eq(0)
36
- expect(b.getbyte(1)).to eq(0)
37
- expect(b.encoding).to eq(Encoding::BINARY)
38
- end
39
- end
40
-
41
- describe '.force_binary_encoding' do
42
- it 'should change encoding' do
43
- e = 'STRING'.encode('UTF-8')
44
- expect(e.encoding).not_to eq(Encoding::BINARY)
45
- a = Thrift::Bytes.force_binary_encoding e
46
- expect(a.encoding).to eq(Encoding::BINARY)
47
- end
48
- end
49
-
50
- describe '.get_string_byte' do
51
- it 'should get the byte at index' do
52
- s = "\x41\x42"
53
- expect(Thrift::Bytes.get_string_byte(s, 0)).to eq(0x41)
54
- expect(Thrift::Bytes.get_string_byte(s, 1)).to eq(0x42)
55
- end
24
+ describe '.empty_byte_buffer' do
25
+ it 'should create an empty buffer' do
26
+ b = Thrift::Bytes.empty_byte_buffer
27
+ expect(b.length).to eq(0)
28
+ expect(b.encoding).to eq(Encoding::BINARY)
56
29
  end
57
30
 
58
- describe '.set_string_byte' do
59
- it 'should set byte value at index' do
60
- s = "\x41\x42"
61
- Thrift::Bytes.set_string_byte(s, 0, 0x43)
62
- expect(s.getbyte(0)).to eq(0x43)
63
- expect(s).to eq('CB')
64
- end
31
+ it 'should create an empty buffer of given size' do
32
+ b = Thrift::Bytes.empty_byte_buffer 2
33
+ expect(b.length).to eq(2)
34
+ expect(b.getbyte(0)).to eq(0)
35
+ expect(b.getbyte(1)).to eq(0)
36
+ expect(b.encoding).to eq(Encoding::BINARY)
65
37
  end
38
+ end
66
39
 
67
- describe '.convert_to_utf8_byte_buffer' do
68
- it 'should convert UTF-8 String to byte buffer' do
69
- e = "\u20AC".encode('UTF-8') # a string with euro sign character U+20AC
70
- expect(e.length).to eq(1)
71
-
72
- a = Thrift::Bytes.convert_to_utf8_byte_buffer e
73
- expect(a.encoding).to eq(Encoding::BINARY)
74
- expect(a.length).to eq(3)
75
- expect(a.unpack('C*')).to eq([0xE2, 0x82, 0xAC])
76
- end
77
-
78
- it 'should convert ISO-8859-15 String to UTF-8 byte buffer' do
79
- # Assumptions
80
- e = "\u20AC".encode('ISO-8859-15') # a string with euro sign character U+20AC, then converted to ISO-8859-15
81
- expect(e.length).to eq(1)
82
- expect(e.unpack('C*')).to eq([0xA4]) # euro sign is a different code point in ISO-8859-15
83
-
84
- a = Thrift::Bytes.convert_to_utf8_byte_buffer e
85
- expect(a.encoding).to eq(Encoding::BINARY)
86
- expect(a.length).to eq(3)
87
- expect(a.unpack('C*')).to eq([0xE2, 0x82, 0xAC])
88
- end
40
+ describe '.force_binary_encoding' do
41
+ it 'should change encoding' do
42
+ e = 'STRING'.encode('UTF-8')
43
+ expect(e.encoding).not_to eq(Encoding::BINARY)
44
+ a = Thrift::Bytes.force_binary_encoding e
45
+ expect(a.encoding).to eq(Encoding::BINARY)
89
46
  end
47
+ end
90
48
 
91
- describe '.convert_to_string' do
92
- it 'should convert UTF-8 byte buffer to a UTF-8 String' do
93
- e = [0xE2, 0x82, 0xAC].pack("C*")
94
- expect(e.encoding).to eq(Encoding::BINARY)
95
- a = Thrift::Bytes.convert_to_string e
96
- expect(a.encoding).to eq(Encoding::UTF_8)
97
- expect(a).to eq("\u20AC")
98
- end
49
+ describe '.get_string_byte' do
50
+ it 'should get the byte at index' do
51
+ s = "\x41\x42"
52
+ expect(Thrift::Bytes.get_string_byte(s, 0)).to eq(0x41)
53
+ expect(Thrift::Bytes.get_string_byte(s, 1)).to eq(0x42)
99
54
  end
55
+ end
100
56
 
101
- else # RUBY_VERSION
102
- describe '.empty_byte_buffer' do
103
- it 'should create an empty buffer' do
104
- b = Thrift::Bytes.empty_byte_buffer
105
- expect(b.length).to eq(0)
106
- end
107
-
108
- it 'should create an empty buffer of given size' do
109
- b = Thrift::Bytes.empty_byte_buffer 2
110
- expect(b.length).to eq(2)
111
- expect(b[0]).to eq(0)
112
- expect(b[1]).to eq(0)
113
- end
57
+ describe '.set_string_byte' do
58
+ it 'should set byte value at index' do
59
+ s = "\x41\x42"
60
+ Thrift::Bytes.set_string_byte(s, 0, 0x43)
61
+ expect(s.getbyte(0)).to eq(0x43)
62
+ expect(s).to eq('CB')
114
63
  end
64
+ end
115
65
 
116
- describe '.force_binary_encoding' do
117
- it 'should be a no-op' do
118
- e = 'STRING'
119
- a = Thrift::Bytes.force_binary_encoding e
120
- expect(a).to eq(e)
121
- expect(a).to be(e)
122
- end
123
- end
66
+ describe '.convert_to_utf8_byte_buffer' do
67
+ it 'should convert UTF-8 String to byte buffer' do
68
+ e = "\u20AC".encode('UTF-8') # a string with euro sign character U+20AC
69
+ expect(e.length).to eq(1)
124
70
 
125
- describe '.get_string_byte' do
126
- it 'should get the byte at index' do
127
- s = "\x41\x42"
128
- expect(Thrift::Bytes.get_string_byte(s, 0)).to eq(0x41)
129
- expect(Thrift::Bytes.get_string_byte(s, 1)).to eq(0x42)
130
- end
71
+ a = Thrift::Bytes.convert_to_utf8_byte_buffer e
72
+ expect(a.encoding).to eq(Encoding::BINARY)
73
+ expect(a.length).to eq(3)
74
+ expect(a.unpack('C*')).to eq([0xE2, 0x82, 0xAC])
131
75
  end
132
76
 
133
- describe '.set_string_byte' do
134
- it 'should set byte value at index' do
135
- s = "\x41\x42"
136
- Thrift::Bytes.set_string_byte(s, 0, 0x43)
137
- expect(s[0]).to eq(0x43)
138
- expect(s).to eq('CB')
139
- end
140
- end
77
+ it 'should convert ISO-8859-15 String to UTF-8 byte buffer' do
78
+ # Assumptions
79
+ e = "\u20AC".encode('ISO-8859-15') # a string with euro sign character U+20AC, then converted to ISO-8859-15
80
+ expect(e.length).to eq(1)
81
+ expect(e.unpack('C*')).to eq([0xA4]) # euro sign is a different code point in ISO-8859-15
141
82
 
142
- describe '.convert_to_utf8_byte_buffer' do
143
- it 'should be a no-op' do
144
- e = 'STRING'
145
- a = Thrift::Bytes.convert_to_utf8_byte_buffer e
146
- expect(a).to eq(e)
147
- expect(a).to be(e)
148
- end
83
+ a = Thrift::Bytes.convert_to_utf8_byte_buffer e
84
+ expect(a.encoding).to eq(Encoding::BINARY)
85
+ expect(a.length).to eq(3)
86
+ expect(a.unpack('C*')).to eq([0xE2, 0x82, 0xAC])
149
87
  end
88
+ end
150
89
 
151
- describe '.convert_to_string' do
152
- it 'should be a no-op' do
153
- e = 'STRING'
154
- a = Thrift::Bytes.convert_to_string e
155
- expect(a).to eq(e)
156
- expect(a).to be(e)
157
- end
90
+ describe '.convert_to_string' do
91
+ it 'should convert UTF-8 byte buffer to a UTF-8 String' do
92
+ e = [0xE2, 0x82, 0xAC].pack("C*")
93
+ expect(e.encoding).to eq(Encoding::BINARY)
94
+ a = Thrift::Bytes.convert_to_string e
95
+ expect(a.encoding).to eq(Encoding::UTF_8)
96
+ expect(a).to eq("\u20AC")
158
97
  end
159
98
  end
160
99
  end
data/spec/client_spec.rb CHANGED
@@ -20,11 +20,15 @@
20
20
  require 'spec_helper'
21
21
 
22
22
  describe 'Client' do
23
-
24
23
  class ClientSpec
25
24
  include Thrift::Client
26
25
  end
27
26
 
27
+ class EmptyArgs
28
+ def write(_prot)
29
+ end
30
+ end
31
+
28
32
  before(:each) do
29
33
  @prot = double("MockProtocol")
30
34
  @client = ClientSpec.new(@prot)
@@ -53,15 +57,34 @@ describe 'Client' do
53
57
  end
54
58
 
55
59
  it "should increment the sequence id when sending messages" do
56
- pending "it seems sequence ids are completely ignored right now"
57
- @prot.expect(:write_message_begin).with('testMessage', Thrift::MessageTypes::CALL, 0).ordered
58
- @prot.expect(:write_message_begin).with('testMessage2', Thrift::MessageTypes::CALL, 1).ordered
59
- @prot.expect(:write_message_begin).with('testMessage3', Thrift::MessageTypes::CALL, 2).ordered
60
- @prot.stub!(:write_message_end)
61
- @prot.stub!(:trans).and_return double("trans").as_null_object
62
- @client.send_message('testMessage', double("args class").as_null_object)
63
- @client.send_message('testMessage2', double("args class").as_null_object)
64
- @client.send_message('testMessage3', double("args class").as_null_object)
60
+ expect(@prot).to receive(:write_message_begin).with('testMessage', Thrift::MessageTypes::CALL, 0).ordered
61
+ expect(@prot).to receive(:write_message_begin).with('testMessage2', Thrift::MessageTypes::CALL, 1).ordered
62
+ expect(@prot).to receive(:write_message_begin).with('testMessage3', Thrift::MessageTypes::CALL, 2).ordered
63
+ allow(@prot).to receive(:write_message_end)
64
+ allow(@prot).to receive(:trans).and_return(double("trans", :flush => nil))
65
+
66
+ args_class = double("ArgsClass", :new => EmptyArgs.new)
67
+ @client.send_message('testMessage', args_class)
68
+ @client.send_message('testMessage2', args_class)
69
+ @client.send_message('testMessage3', args_class)
70
+ end
71
+
72
+ it "should keep pending reply sequence ids in FIFO order" do
73
+ expect(@prot).to receive(:write_message_begin).with('first', Thrift::MessageTypes::CALL, 0).ordered
74
+ expect(@prot).to receive(:write_message_begin).with('second', Thrift::MessageTypes::CALL, 1).ordered
75
+ allow(@prot).to receive(:write_message_end)
76
+ allow(@prot).to receive(:trans).and_return(double("trans", :flush => nil))
77
+
78
+ args_class = double("ArgsClass", :new => EmptyArgs.new)
79
+ @client.send_message('first', args_class)
80
+ @client.send_message('second', args_class)
81
+
82
+ expect {
83
+ @client.validate_message_begin('first', Thrift::MessageTypes::REPLY, 0, 'first')
84
+ }.not_to raise_error
85
+ expect {
86
+ @client.validate_message_begin('second', Thrift::MessageTypes::REPLY, 1, 'second')
87
+ }.not_to raise_error
65
88
  end
66
89
 
67
90
  it "should receive a test message" do
@@ -73,16 +96,59 @@ describe 'Client' do
73
96
  @client.receive_message(double("MockClass", :new => mock_klass))
74
97
  end
75
98
 
76
- it "should handle received exceptions" do
77
- expect(@prot).to receive(:read_message_begin).and_return [nil, Thrift::MessageTypes::EXCEPTION, 0]
99
+ it "should raise BAD_SEQUENCE_ID for mismatched replies" do
100
+ @client.instance_variable_set(:@pending_seqids, [0])
101
+
102
+ expect {
103
+ @client.validate_message_begin('testMessage', Thrift::MessageTypes::REPLY, 1, 'testMessage')
104
+ }.to raise_error(Thrift::ApplicationException) { |error|
105
+ expect(error.type).to eq(Thrift::ApplicationException::BAD_SEQUENCE_ID)
106
+ }
107
+ end
108
+
109
+ it "should raise WRONG_METHOD_NAME for unexpected replies" do
110
+ @client.instance_variable_set(:@pending_seqids, [0])
111
+
112
+ expect {
113
+ @client.validate_message_begin('otherMessage', Thrift::MessageTypes::REPLY, 0, 'testMessage')
114
+ }.to raise_error(Thrift::ApplicationException) { |error|
115
+ expect(error.type).to eq(Thrift::ApplicationException::WRONG_METHOD_NAME)
116
+ }
117
+ end
118
+
119
+ it "should raise INVALID_MESSAGE_TYPE for non-reply messages" do
120
+ @client.instance_variable_set(:@pending_seqids, [0])
121
+
122
+ expect {
123
+ @client.validate_message_begin('testMessage', Thrift::MessageTypes::CALL, 0, 'testMessage')
124
+ }.to raise_error(Thrift::ApplicationException) { |error|
125
+ expect(error.type).to eq(Thrift::ApplicationException::INVALID_MESSAGE_TYPE)
126
+ }
127
+ end
128
+
129
+ it "should raise received application exceptions" do
78
130
  expect(@prot).to receive(:read_message_end)
79
- expect(Thrift::ApplicationException).to receive(:new) do
80
- StandardError.new.tap do |mock_exc|
81
- expect(mock_exc).to receive(:read).with(@prot)
82
- end
83
- end
84
- fname, mtype, sqeid = @client.receive_message_begin()
85
- expect { @client.handle_exception(mtype) }.to raise_error(StandardError)
131
+ server_exception = Thrift::ApplicationException.new(Thrift::ApplicationException::UNKNOWN, "boom")
132
+ expect(server_exception).to receive(:read).with(@prot)
133
+ expect(Thrift::ApplicationException).to receive(:new).and_return(server_exception)
134
+ @client.instance_variable_set(:@pending_seqids, [0])
135
+
136
+ expect {
137
+ @client.validate_message_begin('testMessage', Thrift::MessageTypes::EXCEPTION, 0, 'testMessage')
138
+ }.to raise_error(Thrift::ApplicationException, "boom")
139
+ expect(@client.instance_variable_get(:@pending_seqids)).to be_empty
140
+ end
141
+
142
+ it "should roll sequence ids across the signed int32 boundary" do
143
+ expect(@prot).to receive(:write_message_begin).with('testMessage', Thrift::MessageTypes::CALL, Thrift::Client::MAX_SEQUENCE_ID).ordered
144
+ expect(@prot).to receive(:write_message_begin).with('testMessage2', Thrift::MessageTypes::CALL, Thrift::Client::MIN_SEQUENCE_ID).ordered
145
+ allow(@prot).to receive(:write_message_end)
146
+ allow(@prot).to receive(:trans).and_return(double("trans", :flush => nil))
147
+
148
+ @client.instance_variable_set(:@seqid, Thrift::Client::MAX_SEQUENCE_ID)
149
+ args_class = double("ArgsClass", :new => EmptyArgs.new)
150
+ @client.send_message('testMessage', args_class)
151
+ @client.send_message('testMessage2', args_class)
86
152
  end
87
153
 
88
154
  it "should close the transport if an error occurs while sending a message" do
@@ -23,22 +23,22 @@ require 'spec_helper'
23
23
  describe Thrift::CompactProtocol do
24
24
  TESTS = {
25
25
  :byte => (-127..127).to_a,
26
- :i16 => (0..14).map {|shift| [1 << shift, -(1 << shift)]}.flatten.sort,
27
- :i32 => (0..30).map {|shift| [1 << shift, -(1 << shift)]}.flatten.sort,
28
- :i64 => (0..62).map {|shift| [1 << shift, -(1 << shift)]}.flatten.sort,
26
+ :i16 => (0..14).map { |shift| [1 << shift, -(1 << shift)] }.flatten.sort,
27
+ :i32 => (0..30).map { |shift| [1 << shift, -(1 << shift)] }.flatten.sort,
28
+ :i64 => (0..62).map { |shift| [1 << shift, -(1 << shift)] }.flatten.sort,
29
29
  :string => ["", "1", "short", "fourteen123456", "fifteen12345678", "unicode characters: \u20AC \u20AD", "1" * 127, "1" * 3000],
30
30
  :binary => ["", "\001", "\001" * 5, "\001" * 14, "\001" * 15, "\001" * 127, "\001" * 3000],
31
31
  :double => [0.0, 1.0, -1.0, 1.1, -1.1, 10000000.1, 1.0/0.0, -1.0/0.0],
32
32
  :bool => [true, false]
33
33
  }
34
-
34
+
35
35
  it "should encode and decode naked primitives correctly" do
36
36
  TESTS.each_pair do |primitive_type, test_values|
37
37
  test_values.each do |value|
38
38
  # puts "testing #{value}" if primitive_type == :i64
39
39
  trans = Thrift::MemoryBufferTransport.new
40
40
  proto = Thrift::CompactProtocol.new(trans)
41
-
41
+
42
42
  proto.send(writer(primitive_type), value)
43
43
  # puts "buf: #{trans.inspect_buffer}" if primitive_type == :i64
44
44
  read_back = proto.send(reader(primitive_type))
@@ -46,7 +46,7 @@ describe Thrift::CompactProtocol do
46
46
  end
47
47
  end
48
48
  end
49
-
49
+
50
50
  it "should encode and decode primitives in fields correctly" do
51
51
  TESTS.each_pair do |primitive_type, test_values|
52
52
  final_primitive_type = primitive_type == :binary ? :string : primitive_type
@@ -71,6 +71,30 @@ describe Thrift::CompactProtocol do
71
71
  end
72
72
  end
73
73
 
74
+ it "should write a uuid" do
75
+ trans = Thrift::MemoryBufferTransport.new
76
+ proto = Thrift::CompactProtocol.new(trans)
77
+
78
+ proto.write_uuid("00112233-4455-6677-8899-aabbccddeeff")
79
+ a = trans.read(trans.available)
80
+ expect(a.unpack('C*')).to eq([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff])
81
+ end
82
+
83
+ it "should read a uuid" do
84
+ trans = Thrift::MemoryBufferTransport.new
85
+ proto = Thrift::CompactProtocol.new(trans)
86
+
87
+ trans.write([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff].pack('C*'))
88
+ uuid = proto.read_uuid
89
+ expect(uuid).to eq("00112233-4455-6677-8899-aabbccddeeff")
90
+ end
91
+
92
+ it "should error gracefully when trying to write an invalid uuid" do
93
+ trans = Thrift::MemoryBufferTransport.new
94
+ proto = Thrift::CompactProtocol.new(trans)
95
+ expect { proto.write_uuid("invalid") }.to raise_error(Thrift::ProtocolException)
96
+ end
97
+
74
98
  it "should encode and decode a monster struct correctly" do
75
99
  trans = Thrift::MemoryBufferTransport.new
76
100
  proto = Thrift::CompactProtocol.new(trans)
@@ -80,7 +104,7 @@ describe Thrift::CompactProtocol do
80
104
  struct.write(proto)
81
105
 
82
106
  struct2 = Thrift::Test::CompactProtoTestStruct.new
83
- struct2.read(proto)
107
+ struct2.read(proto)
84
108
  expect(struct2).to eq(struct)
85
109
  end
86
110
 
@@ -99,13 +123,27 @@ describe Thrift::CompactProtocol do
99
123
  processor.process(client_out_proto, client_in_proto)
100
124
  expect(client.recv_Janky).to eq(2)
101
125
  end
102
-
126
+
127
+ it "should round-trip wrapped negative seqids in message headers" do
128
+ trans = Thrift::MemoryBufferTransport.new
129
+ writer = Thrift::CompactProtocol.new(trans)
130
+
131
+ writer.write_message_begin("test", Thrift::MessageTypes::CALL, -2147483648)
132
+ writer.write_message_end
133
+
134
+ reader = Thrift::CompactProtocol.new(trans)
135
+ name, type, seqid = reader.read_message_begin
136
+ expect(name).to eq("test")
137
+ expect(type).to eq(Thrift::MessageTypes::CALL)
138
+ expect(seqid).to eq(-2147483648)
139
+ end
140
+
103
141
  it "should deal with fields following fields that have non-delta ids" do
104
142
  brcp = Thrift::Test::BreaksRubyCompactProtocol.new(
105
- :field1 => "blah",
143
+ :field1 => "blah",
106
144
  :field2 => Thrift::Test::BigFieldIdStruct.new(
107
- :field1 => "string1",
108
- :field2 => "string2"),
145
+ :field1 => "string1",
146
+ :field2 => "string2"),
109
147
  :field3 => 3)
110
148
  ser = Thrift::Serializer.new(Thrift::CompactProtocolFactory.new)
111
149
  bytes = ser.serialize(brcp)
@@ -115,7 +153,7 @@ describe Thrift::CompactProtocol do
115
153
  deser.deserialize(brcp2, bytes)
116
154
  expect(brcp2).to eq(brcp)
117
155
  end
118
-
156
+
119
157
  it "should deserialize an empty map to an empty hash" do
120
158
  struct = Thrift::Test::SingleMapTestStruct.new(:i32_map => {})
121
159
  ser = Thrift::Serializer.new(Thrift::CompactProtocolFactory.new)
@@ -126,22 +164,22 @@ describe Thrift::CompactProtocol do
126
164
  deser.deserialize(struct2, bytes)
127
165
  expect(struct).to eq(struct2)
128
166
  end
129
-
167
+
130
168
  it "should provide a reasonable to_s" do
131
169
  trans = Thrift::MemoryBufferTransport.new
132
170
  expect(Thrift::CompactProtocol.new(trans).to_s).to eq("compact(memory)")
133
171
  end
134
-
172
+
135
173
  class JankyHandler
136
174
  def Janky(i32arg)
137
175
  i32arg * 2
138
176
  end
139
177
  end
140
-
178
+
141
179
  def writer(sym)
142
180
  "write_#{sym.to_s}"
143
181
  end
144
-
182
+
145
183
  def reader(sym)
146
184
  "read_#{sym.to_s}"
147
185
  end
@@ -0,0 +1,101 @@
1
+ # encoding: UTF-8
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
+
23
+ $:.unshift File.join(File.dirname(__FILE__), *%w[gen-rb/constants_demo])
24
+ require 'constants_demo_constants'
25
+
26
+ describe 'ConstantsDemo' do
27
+ it 'should have correct integer constants' do
28
+ expect(ConstantsDemo::MyInt).to eq(3)
29
+ expect(ConstantsDemo::Hex_const).to eq(0x0001F)
30
+ expect(ConstantsDemo::Negative_hex_constant).to eq(-0x0001F)
31
+ expect(ConstantsDemo::GEN_ME).to eq(-3523553)
32
+ end
33
+
34
+ it 'should have correct double constants' do
35
+ expect(ConstantsDemo::GEn_DUB).to eq(325.532)
36
+ expect(ConstantsDemo::GEn_DU).to eq(85.2355)
37
+ expect(ConstantsDemo::E10).to eq(1e+10)
38
+ expect(ConstantsDemo::E11).to eq(-1e+10)
39
+ end
40
+
41
+ it 'should have correct string constants' do
42
+ expect(ConstantsDemo::GEN_STRING).to eq("asldkjasfd")
43
+ end
44
+
45
+ it 'should have correct uuid constants' do
46
+ expect(ConstantsDemo::GEN_UUID).to eq("00000000-4444-CCCC-ffff-0123456789ab")
47
+ expect(ConstantsDemo::GEN_GUID).to eq("00112233-4455-6677-8899-aaBBccDDeeFF")
48
+ expect(ConstantsDemo::MY_UUID).to eq("00000000-4444-CCCC-ffff-0123456789ab")
49
+ expect(ConstantsDemo::MY_GUID).to eq("00112233-4455-6677-8899-aaBBccDDeeFF")
50
+ end
51
+
52
+ it 'should have correct list constants' do
53
+ expect(ConstantsDemo::GEN_LIST).to be_a(Array)
54
+ expect(ConstantsDemo::GEN_LIST).to eq([235235, 23598352, 3253523])
55
+ end
56
+
57
+ it 'should have correct map constants' do
58
+ expect(ConstantsDemo::GEN_MAP).to be_a(Hash)
59
+ expect(ConstantsDemo::GEN_MAP[35532]).to eq(233)
60
+ expect(ConstantsDemo::GEN_MAP[43523]).to eq(853)
61
+
62
+ expect(ConstantsDemo::GEN_MAP2).to be_a(Hash)
63
+ expect(ConstantsDemo::GEN_MAP2["hello"]).to eq(233)
64
+ expect(ConstantsDemo::GEN_MAP2["lkj98d"]).to eq(853)
65
+ expect(ConstantsDemo::GEN_MAP2['lkjsdf']).to eq(98325)
66
+
67
+ expect(ConstantsDemo::GEN_MAPMAP).to be_a(Hash)
68
+ expect(ConstantsDemo::GEN_MAPMAP[235]).to be_a(Hash)
69
+ expect(ConstantsDemo::GEN_MAPMAP[235][532]).to eq(53255)
70
+ expect(ConstantsDemo::GEN_MAPMAP[235][235]).to eq(235)
71
+ end
72
+
73
+ it 'should have correct set constants' do
74
+ expect(ConstantsDemo::GEN_SET).to be_a(Set)
75
+ expect(ConstantsDemo::GEN_SET.size).to eq(2)
76
+ expect(ConstantsDemo::GEN_SET.include?(235)).to be true # added twice, but this is a set
77
+ expect(ConstantsDemo::GEN_SET.include?(53235)).to be true
78
+
79
+ expect(ConstantsDemo::GUID_SET).to be_a(Set)
80
+ expect(ConstantsDemo::GUID_SET.size).to eq(2)
81
+ expect(ConstantsDemo::GUID_SET.include?("00112233-4455-6677-8899-aaBBccDDeeFF")).to be true
82
+ expect(ConstantsDemo::GUID_SET.include?("00000000-4444-CCCC-ffff-0123456789ab")).to be true
83
+ end
84
+
85
+ it 'should have correct struct constants' do
86
+ expect(ConstantsDemo::GEN_THING).to be_a(Thrift::Struct)
87
+ expect(ConstantsDemo::GEN_THING.hello).to eq(325)
88
+ expect(ConstantsDemo::GEN_THING.goodbye).to eq(325352)
89
+ expect(ConstantsDemo::GEN_THING.id).to eq("00112233-4455-6677-8899-aaBBccDDeeFF")
90
+ expect(ConstantsDemo::GEN_THING.my_id).to eq("00000000-4444-CCCC-ffff-0123456789ab")
91
+ expect(ConstantsDemo::GEN_THING.my_optional_id).to eq("00000000-4444-CCCC-ffff-0123456789ab")
92
+
93
+ expect(ConstantsDemo::GEN_WHAT).to be_a(Hash)
94
+ expect(ConstantsDemo::GEN_WHAT[35]).to be_a(Thrift::Struct)
95
+ expect(ConstantsDemo::GEN_WHAT[35].hello).to eq(325)
96
+ expect(ConstantsDemo::GEN_WHAT[35].goodbye).to eq(325352)
97
+ expect(ConstantsDemo::GEN_WHAT[35].id).to eq("00000000-4444-CCCC-ffff-0123456789ab")
98
+ expect(ConstantsDemo::GEN_WHAT[35].my_id).to eq("00000000-4444-CCCC-ffff-0123456789ab")
99
+ expect(ConstantsDemo::GEN_WHAT[35].my_optional_id).to eq("00000000-4444-CCCC-ffff-0123456789ab")
100
+ end
101
+ end
@@ -20,7 +20,6 @@
20
20
  require 'spec_helper'
21
21
 
22
22
  describe 'Exception' do
23
-
24
23
  describe Thrift::Exception do
25
24
  it "should have an accessible message" do
26
25
  e = Thrift::Exception.new("test message")