thrift 0.23.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 +203 -40
  3. data/ext/binary_protocol_accelerated.c +130 -40
  4. data/ext/bytes.c +14 -0
  5. data/ext/compact_protocol.c +184 -91
  6. data/ext/constants.h +3 -0
  7. data/ext/extconf.rb +12 -4
  8. data/ext/macros.h +11 -0
  9. data/ext/memory_buffer.c +67 -12
  10. data/ext/struct.c +192 -71
  11. data/ext/thrift_native.c +7 -0
  12. data/lib/thrift/bytes.rb +6 -3
  13. data/lib/thrift/client.rb +31 -33
  14. data/lib/thrift/exceptions.rb +11 -8
  15. data/lib/thrift/multiplexed_processor.rb +17 -8
  16. data/lib/thrift/processor.rb +25 -3
  17. data/lib/thrift/protocol/base_protocol.rb +66 -31
  18. data/lib/thrift/protocol/binary_protocol.rb +80 -37
  19. data/lib/thrift/protocol/binary_protocol_accelerated.rb +7 -2
  20. data/lib/thrift/protocol/compact_protocol.rb +204 -88
  21. data/lib/thrift/protocol/header_protocol.rb +15 -3
  22. data/lib/thrift/protocol/json_protocol.rb +158 -109
  23. data/lib/thrift/protocol/multiplexed_protocol.rb +3 -3
  24. data/lib/thrift/protocol/protocol_decorator.rb +6 -2
  25. data/lib/thrift/serializer/deserializer.rb +1 -0
  26. data/lib/thrift/serializer/serializer.rb +7 -0
  27. data/lib/thrift/server/base_server.rb +11 -2
  28. data/lib/thrift/server/nonblocking_server.rb +69 -20
  29. data/lib/thrift/server/rack_application.rb +69 -0
  30. data/lib/thrift/server/simple_server.rb +27 -15
  31. data/lib/thrift/server/thin_http_server.rb +21 -44
  32. data/lib/thrift/server/thread_pool_server.rb +21 -17
  33. data/lib/thrift/server/threaded_server.rb +22 -18
  34. data/lib/thrift/struct.rb +34 -18
  35. data/lib/thrift/struct_union.rb +37 -36
  36. data/lib/thrift/thrift_native.rb +2 -1
  37. data/lib/thrift/transport/base_server_transport.rb +3 -0
  38. data/lib/thrift/transport/base_transport.rb +26 -4
  39. data/lib/thrift/transport/buffered_transport.rb +5 -4
  40. data/lib/thrift/transport/framed_transport.rb +33 -7
  41. data/lib/thrift/transport/header_transport.rb +159 -33
  42. data/lib/thrift/transport/http_client_transport.rb +28 -14
  43. data/lib/thrift/transport/io_stream_transport.rb +3 -1
  44. data/lib/thrift/transport/memory_buffer_transport.rb +14 -9
  45. data/lib/thrift/transport/server_socket.rb +10 -8
  46. data/lib/thrift/transport/socket.rb +85 -48
  47. data/lib/thrift/transport/ssl_server_socket.rb +67 -6
  48. data/lib/thrift/transport/ssl_socket.rb +73 -14
  49. data/lib/thrift/transport/unix_server_socket.rb +6 -2
  50. data/lib/thrift/transport/unix_socket.rb +5 -6
  51. data/lib/thrift/types.rb +23 -22
  52. data/lib/thrift/union.rb +21 -11
  53. data/lib/thrift/uuid.rb +9 -8
  54. data/lib/thrift.rb +40 -39
  55. metadata +7 -266
  56. data/benchmark/Benchmark.thrift +0 -24
  57. data/benchmark/benchmark.rb +0 -285
  58. data/benchmark/client.rb +0 -117
  59. data/benchmark/server.rb +0 -120
  60. data/benchmark/thin_server.rb +0 -45
  61. data/lib/thrift/server/mongrel_http_server.rb +0 -60
  62. data/spec/BaseService.thrift +0 -27
  63. data/spec/ExtendedService.thrift +0 -25
  64. data/spec/Referenced.thrift +0 -44
  65. data/spec/ThriftNamespacedSpec.thrift +0 -53
  66. data/spec/ThriftSpec.thrift +0 -187
  67. data/spec/base_protocol_spec.rb +0 -224
  68. data/spec/base_transport_spec.rb +0 -387
  69. data/spec/binary_protocol_accelerated_spec.rb +0 -46
  70. data/spec/binary_protocol_spec.rb +0 -72
  71. data/spec/binary_protocol_spec_shared.rb +0 -445
  72. data/spec/bytes_spec.rb +0 -99
  73. data/spec/client_spec.rb +0 -166
  74. data/spec/compact_protocol_spec.rb +0 -196
  75. data/spec/constants_demo_spec.rb +0 -101
  76. data/spec/exception_spec.rb +0 -140
  77. data/spec/flat_spec.rb +0 -62
  78. data/spec/header_protocol_spec.rb +0 -475
  79. data/spec/header_transport_spec.rb +0 -386
  80. data/spec/http_client_spec.rb +0 -159
  81. data/spec/json_protocol_spec.rb +0 -552
  82. data/spec/namespaced_spec.rb +0 -66
  83. data/spec/nonblocking_server_spec.rb +0 -361
  84. data/spec/processor_spec.rb +0 -79
  85. data/spec/serializer_spec.rb +0 -66
  86. data/spec/server_socket_spec.rb +0 -84
  87. data/spec/server_spec.rb +0 -186
  88. data/spec/socket_spec.rb +0 -67
  89. data/spec/socket_spec_shared.rb +0 -167
  90. data/spec/spec_helper.rb +0 -69
  91. data/spec/ssl_server_socket_spec.rb +0 -45
  92. data/spec/ssl_socket_spec.rb +0 -87
  93. data/spec/struct_nested_containers_spec.rb +0 -190
  94. data/spec/struct_spec.rb +0 -397
  95. data/spec/support/header_protocol_helper.rb +0 -54
  96. data/spec/thin_http_server_spec.rb +0 -126
  97. data/spec/types_spec.rb +0 -117
  98. data/spec/union_spec.rb +0 -272
  99. data/spec/unix_socket_spec.rb +0 -115
  100. data/spec/uuid_validation_spec.rb +0 -238
  101. data/test/fuzz/Makefile.am +0 -173
  102. data/test/fuzz/README.md +0 -149
  103. data/test/fuzz/fuzz_common.rb +0 -95
  104. data/test/fuzz/fuzz_parse_binary_protocol.rb +0 -22
  105. data/test/fuzz/fuzz_parse_binary_protocol_accelerated.rb +0 -22
  106. data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +0 -22
  107. data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +0 -22
  108. data/test/fuzz/fuzz_parse_compact_protocol.rb +0 -22
  109. data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +0 -22
  110. data/test/fuzz/fuzz_parse_json_protocol.rb +0 -22
  111. data/test/fuzz/fuzz_parse_json_protocol_harness.rb +0 -22
  112. data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +0 -22
  113. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +0 -22
  114. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +0 -22
  115. data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +0 -22
  116. data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +0 -22
  117. data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +0 -22
  118. data/test/fuzz/fuzz_roundtrip_json_protocol.rb +0 -22
  119. data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +0 -22
  120. data/test/fuzz/fuzz_tracer.rb +0 -28
@@ -1,190 +0,0 @@
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
-
22
- describe 'StructNestedContainers' do
23
- def with_type_checking
24
- saved_type_checking, Thrift.type_checking = Thrift.type_checking, true
25
- begin
26
- yield
27
- ensure
28
- Thrift.type_checking = saved_type_checking
29
- end
30
- end
31
-
32
- describe Thrift::Struct do
33
- # Nested container tests, see THRIFT-369.
34
- it "should support nested lists inside lists" do
35
- with_type_checking do
36
- a, b = SpecNamespace::NestedListInList.new, SpecNamespace::NestedListInList.new
37
- [a, b].each do |thrift_struct|
38
- thrift_struct.value = [ [1, 2, 3], [2, 3, 4] ]
39
- thrift_struct.validate
40
- end
41
- expect(a).to eq(b)
42
- b.value.push [3, 4, 5]
43
- expect(a).not_to eq(b)
44
- end
45
- end
46
-
47
- it "should support nested lists inside sets" do
48
- with_type_checking do
49
- a, b = SpecNamespace::NestedListInSet.new, SpecNamespace::NestedListInSet.new
50
- [a, b].each do |thrift_struct|
51
- thrift_struct.value = [ [1, 2, 3], [2, 3, 4] ].to_set
52
- thrift_struct.validate
53
- end
54
- expect(a).to eq(b)
55
- b.value.add [3, 4, 5]
56
- expect(a).not_to eq(b)
57
- end
58
- end
59
-
60
- it "should support nested lists in map keys" do
61
- with_type_checking do
62
- a, b = SpecNamespace::NestedListInMapKey.new, SpecNamespace::NestedListInMapKey.new
63
- [a, b].each do |thrift_struct|
64
- thrift_struct.value = { [1, 2, 3] => 1, [2, 3, 4] => 2 }
65
- thrift_struct.validate
66
- end
67
- expect(a).to eq(b)
68
- b.value[[3, 4, 5]] = 3
69
- expect(a).not_to eq(b)
70
- end
71
- end
72
-
73
- it "should support nested lists in map values" do
74
- with_type_checking do
75
- a, b = SpecNamespace::NestedListInMapValue.new, SpecNamespace::NestedListInMapValue.new
76
- [a, b].each do |thrift_struct|
77
- thrift_struct.value = { 1 => [1, 2, 3], 2 => [2, 3, 4] }
78
- thrift_struct.validate
79
- end
80
- expect(a).to eq(b)
81
- b.value[3] = [3, 4, 5]
82
- expect(a).not_to eq(b)
83
- end
84
- end
85
-
86
- it "should support nested sets inside lists" do
87
- with_type_checking do
88
- a, b = SpecNamespace::NestedSetInList.new, SpecNamespace::NestedSetInList.new
89
- [a, b].each do |thrift_struct|
90
- thrift_struct.value = [ [1, 2, 3].to_set, [2, 3, 4].to_set ]
91
- thrift_struct.validate
92
- end
93
- expect(a).to eq(b)
94
- b.value.push([3, 4, 5].to_set)
95
- expect(a).not_to eq(b)
96
- end
97
- end
98
-
99
- it "should support nested sets inside sets" do
100
- with_type_checking do
101
- a, b = SpecNamespace::NestedSetInSet.new, SpecNamespace::NestedSetInSet.new
102
- [a, b].each do |thrift_struct|
103
- thrift_struct.value = [ [1, 2, 3].to_set, [2, 3, 4].to_set ].to_set
104
- thrift_struct.validate
105
- end
106
- expect(a).to eq(b)
107
- b.value.add([3, 4, 5].to_set)
108
- expect(a).not_to eq(b)
109
- end
110
- end
111
-
112
- it "should support nested sets in map keys" do
113
- with_type_checking do
114
- a, b = SpecNamespace::NestedSetInMapKey.new, SpecNamespace::NestedSetInMapKey.new
115
- [a, b].each do |thrift_struct|
116
- thrift_struct.value = { [1, 2, 3].to_set => 1, [2, 3, 4].to_set => 2 }
117
- thrift_struct.validate
118
- end
119
- expect(a).to eq(b)
120
- b.value[[3, 4, 5].to_set] = 3
121
- expect(a).not_to eq(b)
122
- end
123
- end
124
-
125
- it "should support nested sets in map values" do
126
- with_type_checking do
127
- a, b = SpecNamespace::NestedSetInMapValue.new, SpecNamespace::NestedSetInMapValue.new
128
- [a, b].each do |thrift_struct|
129
- thrift_struct.value = { 1 => [1, 2, 3].to_set, 2 => [2, 3, 4].to_set }
130
- thrift_struct.validate
131
- end
132
- expect(a).to eq(b)
133
- b.value[3] = [3, 4, 5].to_set
134
- expect(a).not_to eq(b)
135
- end
136
- end
137
-
138
- it "should support nested maps inside lists" do
139
- with_type_checking do
140
- a, b = SpecNamespace::NestedMapInList.new, SpecNamespace::NestedMapInList.new
141
- [a, b].each do |thrift_struct|
142
- thrift_struct.value = [ {1 => 2, 3 => 4}, {2 => 3, 4 => 5} ]
143
- thrift_struct.validate
144
- end
145
- expect(a).to eq(b)
146
- b.value.push({ 3 => 4, 5 => 6 })
147
- expect(a).not_to eq(b)
148
- end
149
- end
150
-
151
- it "should support nested maps inside sets" do
152
- with_type_checking do
153
- a, b = SpecNamespace::NestedMapInSet.new, SpecNamespace::NestedMapInSet.new
154
- [a, b].each do |thrift_struct|
155
- thrift_struct.value = [ {1 => 2, 3 => 4}, {2 => 3, 4 => 5} ].to_set
156
- thrift_struct.validate
157
- end
158
- expect(a).to eq(b)
159
- b.value.add({ 3 => 4, 5 => 6 })
160
- expect(a).not_to eq(b)
161
- end
162
- end
163
-
164
- it "should support nested maps in map keys" do
165
- with_type_checking do
166
- a, b = SpecNamespace::NestedMapInMapKey.new, SpecNamespace::NestedMapInMapKey.new
167
- [a, b].each do |thrift_struct|
168
- thrift_struct.value = { { 1 => 2, 3 => 4} => 1, {2 => 3, 4 => 5} => 2 }
169
- thrift_struct.validate
170
- end
171
- expect(a).to eq(b)
172
- b.value[{3 => 4, 5 => 6}] = 3
173
- expect(a).not_to eq(b)
174
- end
175
- end
176
-
177
- it "should support nested maps in map values" do
178
- with_type_checking do
179
- a, b = SpecNamespace::NestedMapInMapValue.new, SpecNamespace::NestedMapInMapValue.new
180
- [a, b].each do |thrift_struct|
181
- thrift_struct.value = { 1 => { 1 => 2, 3 => 4}, 2 => {2 => 3, 4 => 5} }
182
- thrift_struct.validate
183
- end
184
- expect(a).to eq(b)
185
- b.value[3] = { 3 => 4, 5 => 6 }
186
- expect(a).not_to eq(b)
187
- end
188
- end
189
- end
190
- end
data/spec/struct_spec.rb DELETED
@@ -1,397 +0,0 @@
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
-
22
- describe 'Struct' do
23
- describe Thrift::Struct do
24
- it "should iterate over all fields properly" do
25
- fields = {}
26
- SpecNamespace::Foo.new.each_field { |fid, field_info| fields[fid] = field_info }
27
- expect(fields).to eq(SpecNamespace::Foo::FIELDS)
28
- end
29
-
30
- it "should initialize all fields to defaults" do
31
- validate_default_arguments(SpecNamespace::Foo.new)
32
- end
33
-
34
- it "should initialize all fields to defaults and accept a block argument" do
35
- SpecNamespace::Foo.new do |f|
36
- validate_default_arguments(f)
37
- end
38
- end
39
-
40
- def validate_default_arguments(object)
41
- expect(object.simple).to eq(53)
42
- expect(object.words).to eq("words")
43
- expect(object.hello).to eq(SpecNamespace::Hello.new(:greeting => 'hello, world!'))
44
- expect(object.ints).to eq([1, 2, 2, 3])
45
- expect(object.complex).to be_nil
46
- expect(object.shorts).to eq(Set.new([5, 17, 239]))
47
- end
48
-
49
- it "should not share default values between instances" do
50
- begin
51
- struct = SpecNamespace::Foo.new
52
- struct.ints << 17
53
- expect(SpecNamespace::Foo.new.ints).to eq([1, 2, 2, 3])
54
- ensure
55
- # ensure no leakage to other tests
56
- SpecNamespace::Foo::FIELDS[4][:default] = [1, 2, 2, 3]
57
- end
58
- end
59
-
60
- it "should properly initialize boolean values" do
61
- struct = SpecNamespace::BoolStruct.new(:yesno => false)
62
- expect(struct.yesno).to be_falsey
63
- end
64
-
65
- it "should have proper == semantics" do
66
- expect(SpecNamespace::Foo.new).not_to eq(SpecNamespace::Hello.new)
67
- expect(SpecNamespace::Foo.new).to eq(SpecNamespace::Foo.new)
68
- expect(SpecNamespace::Foo.new(:simple => 52)).not_to eq(SpecNamespace::Foo.new)
69
- end
70
-
71
- it "should print enum value names in inspect" do
72
- expect(SpecNamespace::StructWithSomeEnum.new(:some_enum => SpecNamespace::SomeEnum::ONE).inspect).to eq("<SpecNamespace::StructWithSomeEnum some_enum:ONE (0)>")
73
-
74
- expect(SpecNamespace::StructWithEnumMap.new(:my_map => {SpecNamespace::SomeEnum::ONE => [SpecNamespace::SomeEnum::TWO]}).inspect).to eq("<SpecNamespace::StructWithEnumMap my_map:{ONE (0): [TWO (1)]}>")
75
- end
76
-
77
- it "should pretty print binary fields" do
78
- expect(SpecNamespace::Foo2.new(:my_binary => "\001\002\003").inspect).to eq("<SpecNamespace::Foo2 my_binary:010203>")
79
- end
80
-
81
- it "should offer field? methods" do
82
- expect(SpecNamespace::Foo.new.opt_string?).to be_falsey
83
- expect(SpecNamespace::Foo.new(:simple => 52).simple?).to be_truthy
84
- expect(SpecNamespace::Foo.new(:my_bool => false).my_bool?).to be_truthy
85
- expect(SpecNamespace::Foo.new(:my_bool => true).my_bool?).to be_truthy
86
- end
87
-
88
- it "should be comparable" do
89
- s1 = SpecNamespace::StructWithSomeEnum.new(:some_enum => SpecNamespace::SomeEnum::ONE)
90
- s2 = SpecNamespace::StructWithSomeEnum.new(:some_enum => SpecNamespace::SomeEnum::TWO)
91
-
92
- expect(s1 <=> s2).to eq(-1)
93
- expect(s2 <=> s1).to eq(1)
94
- expect(s1 <=> s1).to eq(0)
95
- expect(s1 <=> SpecNamespace::StructWithSomeEnum.new()).to eq(-1)
96
- end
97
-
98
- it "should read itself off the wire" do
99
- struct = SpecNamespace::Foo.new
100
- prot = Thrift::BaseProtocol.new(double("transport"))
101
- expect(prot).to receive(:read_struct_begin).twice
102
- expect(prot).to receive(:read_struct_end).twice
103
- expect(prot).to receive(:read_field_begin).and_return(
104
- ['complex', Thrift::Types::MAP, 5], # Foo
105
- ['words', Thrift::Types::STRING, 2], # Foo
106
- ['hello', Thrift::Types::STRUCT, 3], # Foo
107
- ['greeting', Thrift::Types::STRING, 1], # Hello
108
- [nil, Thrift::Types::STOP, 0], # Hello
109
- ['simple', Thrift::Types::I32, 1], # Foo
110
- ['ints', Thrift::Types::LIST, 4], # Foo
111
- ['shorts', Thrift::Types::SET, 6], # Foo
112
- [nil, Thrift::Types::STOP, 0] # Hello
113
- )
114
- expect(prot).to receive(:read_field_end).exactly(7).times
115
- expect(prot).to receive(:read_map_begin).and_return(
116
- [Thrift::Types::I32, Thrift::Types::MAP, 2], # complex
117
- [Thrift::Types::STRING, Thrift::Types::DOUBLE, 2], # complex/1/value
118
- [Thrift::Types::STRING, Thrift::Types::DOUBLE, 1] # complex/2/value
119
- )
120
- expect(prot).to receive(:read_map_end).exactly(3).times
121
- expect(prot).to receive(:read_list_begin).and_return([Thrift::Types::I32, 4])
122
- expect(prot).to receive(:read_list_end)
123
- expect(prot).to receive(:read_set_begin).and_return([Thrift::Types::I16, 2])
124
- expect(prot).to receive(:read_set_end)
125
- expect(prot).to receive(:read_i32).and_return(
126
- 1, 14, # complex keys
127
- 42, # simple
128
- 4, 23, 4, 29 # ints
129
- )
130
- expect(prot).to receive(:read_string).and_return("pi", "e", "feigenbaum", "apple banana", "what's up?")
131
- expect(prot).to receive(:read_double).and_return(Math::PI, Math::E, 4.669201609)
132
- expect(prot).to receive(:read_i16).and_return(2, 3)
133
- expect(prot).not_to receive(:skip)
134
- struct.read(prot)
135
-
136
- expect(struct.simple).to eq(42)
137
- expect(struct.complex).to eq({1 => {"pi" => Math::PI, "e" => Math::E}, 14 => {"feigenbaum" => 4.669201609}})
138
- expect(struct.hello).to eq(SpecNamespace::Hello.new(:greeting => "what's up?"))
139
- expect(struct.words).to eq("apple banana")
140
- expect(struct.ints).to eq([4, 23, 4, 29])
141
- expect(struct.shorts).to eq(Set.new([3, 2]))
142
- end
143
-
144
- it "rejects negative container sizes while reading" do
145
- struct = SpecNamespace::Foo.new
146
- prot = Thrift::BaseProtocol.new(double("transport"))
147
-
148
- expect(prot).to receive(:read_list_begin).and_return([Thrift::Types::I32, -1])
149
-
150
- expect {
151
- struct.send(:read_field, prot, SpecNamespace::Foo::FIELDS[4])
152
- }.to raise_error(Thrift::ProtocolException, "Negative size") { |error|
153
- expect(error.type).to eq(Thrift::ProtocolException::NEGATIVE_SIZE)
154
- }
155
- end
156
-
157
- it "does not preallocate arrays from declared list sizes" do
158
- struct = SpecNamespace::Foo.new
159
- prot = Thrift::BaseProtocol.new(double("transport"))
160
- declared_size = 1 << 30
161
- sentinel = RuntimeError.new("stop after first element")
162
-
163
- expect(prot).to receive(:read_list_begin).and_return([Thrift::Types::I32, declared_size])
164
- expect(prot).to receive(:read_i32).and_raise(sentinel)
165
- expect(Array).not_to receive(:new).with(declared_size)
166
-
167
- expect {
168
- struct.send(:read_field, prot, SpecNamespace::Foo::FIELDS[4])
169
- }.to raise_error(sentinel)
170
- end
171
-
172
- it "should serialize false boolean fields correctly" do
173
- b = SpecNamespace::BoolStruct.new(:yesno => false)
174
- prot = Thrift::BinaryProtocol.new(Thrift::MemoryBufferTransport.new)
175
- expect(prot).to receive(:write_bool).with(false)
176
- b.write(prot)
177
- end
178
-
179
- it "should skip unexpected fields in structs and use default values" do
180
- struct = SpecNamespace::Foo.new
181
- prot = Thrift::BaseProtocol.new(double("transport"))
182
- expect(prot).to receive(:read_struct_begin)
183
- expect(prot).to receive(:read_struct_end)
184
- expect(prot).to receive(:read_field_begin).and_return(
185
- ['simple', Thrift::Types::I32, 1],
186
- ['complex', Thrift::Types::STRUCT, 5],
187
- ['thinz', Thrift::Types::MAP, 7],
188
- ['foobar', Thrift::Types::I32, 3],
189
- ['words', Thrift::Types::STRING, 2],
190
- [nil, Thrift::Types::STOP, 0]
191
- )
192
- expect(prot).to receive(:read_field_end).exactly(5).times
193
- expect(prot).to receive(:read_i32).and_return(42)
194
- expect(prot).to receive(:read_string).and_return("foobar")
195
- expect(prot).to receive(:skip).with(Thrift::Types::STRUCT)
196
- expect(prot).to receive(:skip).with(Thrift::Types::MAP)
197
- # prot.should_receive(:read_map_begin).and_return([Thrift::Types::I32, Thrift::Types::I32, 0])
198
- # prot.should_receive(:read_map_end)
199
- expect(prot).to receive(:skip).with(Thrift::Types::I32)
200
- struct.read(prot)
201
-
202
- expect(struct.simple).to eq(42)
203
- expect(struct.complex).to be_nil
204
- expect(struct.words).to eq("foobar")
205
- expect(struct.hello).to eq(SpecNamespace::Hello.new(:greeting => 'hello, world!'))
206
- expect(struct.ints).to eq([1, 2, 2, 3])
207
- expect(struct.shorts).to eq(Set.new([5, 17, 239]))
208
- end
209
-
210
- it "should write itself to the wire" do
211
- prot = Thrift::BaseProtocol.new(double("transport")) # mock("Protocol")
212
- expect(prot).to receive(:write_struct_begin).with("SpecNamespace::Foo")
213
- expect(prot).to receive(:write_struct_begin).with("SpecNamespace::Hello")
214
- expect(prot).to receive(:write_struct_end).twice
215
- expect(prot).to receive(:write_field_begin).with('ints', Thrift::Types::LIST, 4)
216
- expect(prot).to receive(:write_i32).with(1)
217
- expect(prot).to receive(:write_i32).with(2).twice
218
- expect(prot).to receive(:write_i32).with(3)
219
- expect(prot).to receive(:write_field_begin).with('complex', Thrift::Types::MAP, 5)
220
- expect(prot).to receive(:write_i32).with(5)
221
- expect(prot).to receive(:write_string).with('foo')
222
- expect(prot).to receive(:write_double).with(1.23)
223
- expect(prot).to receive(:write_field_begin).with('shorts', Thrift::Types::SET, 6)
224
- expect(prot).to receive(:write_i16).with(5)
225
- expect(prot).to receive(:write_i16).with(17)
226
- expect(prot).to receive(:write_i16).with(239)
227
- expect(prot).to receive(:write_field_stop).twice
228
- expect(prot).to receive(:write_field_end).exactly(6).times
229
- expect(prot).to receive(:write_field_begin).with('simple', Thrift::Types::I32, 1)
230
- expect(prot).to receive(:write_i32).with(53)
231
- expect(prot).to receive(:write_field_begin).with('hello', Thrift::Types::STRUCT, 3)
232
- expect(prot).to receive(:write_field_begin).with('greeting', Thrift::Types::STRING, 1)
233
- expect(prot).to receive(:write_string).with('hello, world!')
234
- expect(prot).to receive(:write_map_begin).with(Thrift::Types::I32, Thrift::Types::MAP, 1)
235
- expect(prot).to receive(:write_map_begin).with(Thrift::Types::STRING, Thrift::Types::DOUBLE, 1)
236
- expect(prot).to receive(:write_map_end).twice
237
- expect(prot).to receive(:write_list_begin).with(Thrift::Types::I32, 4)
238
- expect(prot).to receive(:write_list_end)
239
- expect(prot).to receive(:write_set_begin).with(Thrift::Types::I16, 3)
240
- expect(prot).to receive(:write_set_end)
241
-
242
- struct = SpecNamespace::Foo.new
243
- struct.words = nil
244
- struct.complex = {5 => {"foo" => 1.23}}
245
- struct.write(prot)
246
- end
247
-
248
- it "should raise an exception if presented with an unknown container" do
249
- # yeah this is silly, but I'm going for code coverage here
250
- struct = SpecNamespace::Foo.new
251
- expect { struct.send :write_container, nil, nil, {:type => "foo"} }.to raise_error(StandardError, "Not a container type: foo")
252
- end
253
-
254
- it "should support optional type-checking in Thrift::Struct.new" do
255
- Thrift.type_checking = true
256
- begin
257
- expect { SpecNamespace::Hello.new(:greeting => 3) }.to raise_error(Thrift::TypeError, "Expected Types::STRING, received Integer for field greeting")
258
- ensure
259
- Thrift.type_checking = false
260
- end
261
- expect { SpecNamespace::Hello.new(:greeting => 3) }.not_to raise_error
262
- end
263
-
264
- it "should support optional type-checking in field accessors" do
265
- Thrift.type_checking = true
266
- begin
267
- hello = SpecNamespace::Hello.new
268
- expect { hello.greeting = 3 }.to raise_error(Thrift::TypeError, "Expected Types::STRING, received Integer for field greeting")
269
- ensure
270
- Thrift.type_checking = false
271
- end
272
- expect { hello.greeting = 3 }.not_to raise_error
273
- end
274
-
275
- it "should raise an exception when unknown types are given to Thrift::Struct.new" do
276
- expect { SpecNamespace::Hello.new(:fish => 'salmon') }.to raise_error(Exception, "Unknown key given to SpecNamespace::Hello.new: fish")
277
- end
278
-
279
- it "should support `raise Xception, 'message'` for Exception structs" do
280
- begin
281
- raise SpecNamespace::Xception, "something happened"
282
- rescue Thrift::Exception => e
283
- expect(e.message).to eq("something happened")
284
- expect(e.code).to eq(1)
285
- # ensure it gets serialized properly, this is the really important part
286
- prot = Thrift::BaseProtocol.new(double("trans"))
287
- expect(prot).to receive(:write_struct_begin).with("SpecNamespace::Xception")
288
- expect(prot).to receive(:write_struct_end)
289
- expect(prot).to receive(:write_field_begin).with('message', Thrift::Types::STRING, 1)
290
- expect(prot).to receive(:write_string).with("something happened")
291
- expect(prot).to receive(:write_field_begin).with('code', Thrift::Types::I32, 2)
292
- expect(prot).to receive(:write_i32).with(1)
293
- expect(prot).to receive(:write_field_stop)
294
- expect(prot).to receive(:write_field_end).twice
295
-
296
- e.write(prot)
297
- end
298
- end
299
-
300
- it "should support the regular initializer for exception structs" do
301
- begin
302
- raise SpecNamespace::Xception, :message => "something happened", :code => 5
303
- rescue Thrift::Exception => e
304
- expect(e.message).to eq("something happened")
305
- expect(e.code).to eq(5)
306
- prot = Thrift::BaseProtocol.new(double("trans"))
307
- expect(prot).to receive(:write_struct_begin).with("SpecNamespace::Xception")
308
- expect(prot).to receive(:write_struct_end)
309
- expect(prot).to receive(:write_field_begin).with('message', Thrift::Types::STRING, 1)
310
- expect(prot).to receive(:write_string).with("something happened")
311
- expect(prot).to receive(:write_field_begin).with('code', Thrift::Types::I32, 2)
312
- expect(prot).to receive(:write_i32).with(5)
313
- expect(prot).to receive(:write_field_stop)
314
- expect(prot).to receive(:write_field_end).twice
315
-
316
- e.write(prot)
317
- end
318
- end
319
-
320
- it "should handle UUID fields in structs" do
321
- struct = SpecNamespace::Foo.new(
322
- simple: 42,
323
- words: 'test',
324
- opt_uuid: '550e8400-e29b-41d4-a716-446655440000'
325
- )
326
-
327
- trans = Thrift::MemoryBufferTransport.new
328
- prot = Thrift::BinaryProtocol.new(trans)
329
-
330
- struct.write(prot)
331
-
332
- result = SpecNamespace::Foo.new
333
- result.read(prot)
334
-
335
- expect(result.simple).to eq(42)
336
- expect(result.words).to eq('test')
337
- expect(result.opt_uuid).to eq('550e8400-e29b-41d4-a716-446655440000')
338
- end
339
-
340
- it "should handle optional UUID fields when unset" do
341
- struct = SpecNamespace::Foo.new(simple: 42, words: 'test')
342
- expect(struct.opt_uuid).to be_nil
343
- expect(struct.opt_uuid?).to be_falsey
344
- end
345
-
346
- it "should handle list of UUIDs in SimpleList" do
347
- uuids = ['550e8400-e29b-41d4-a716-446655440000', '6ba7b810-9dad-11d1-80b4-00c04fd430c8']
348
- struct = SpecNamespace::SimpleList.new(uuids: uuids)
349
-
350
- trans = Thrift::MemoryBufferTransport.new
351
- prot = Thrift::CompactProtocol.new(trans)
352
-
353
- struct.write(prot)
354
-
355
- result = SpecNamespace::SimpleList.new
356
- result.read(prot)
357
-
358
- expect(result.uuids).to eq(uuids)
359
- end
360
-
361
- it "should normalize UUID case to lowercase" do
362
- struct = SpecNamespace::Foo.new(opt_uuid: '550E8400-E29B-41D4-A716-446655440000')
363
-
364
- trans = Thrift::MemoryBufferTransport.new
365
- prot = Thrift::BinaryProtocol.new(trans)
366
-
367
- struct.write(prot)
368
-
369
- result = SpecNamespace::Foo.new
370
- result.read(prot)
371
-
372
- expect(result.opt_uuid).to eq('550e8400-e29b-41d4-a716-446655440000')
373
- end
374
-
375
- it "should handle UUID alongside other types in SimpleList" do
376
- struct = SpecNamespace::SimpleList.new(
377
- bools: [true, false],
378
- i32s: [1, 2, 3],
379
- strings: ['hello', 'world'],
380
- uuids: ['550e8400-e29b-41d4-a716-446655440000', '00000000-0000-0000-0000-000000000000']
381
- )
382
-
383
- trans = Thrift::MemoryBufferTransport.new
384
- prot = Thrift::BinaryProtocol.new(trans)
385
-
386
- struct.write(prot)
387
-
388
- result = SpecNamespace::SimpleList.new
389
- result.read(prot)
390
-
391
- expect(result.bools).to eq([true, false])
392
- expect(result.i32s).to eq([1, 2, 3])
393
- expect(result.strings).to eq(['hello', 'world'])
394
- expect(result.uuids).to eq(['550e8400-e29b-41d4-a716-446655440000', '00000000-0000-0000-0000-000000000000'])
395
- end
396
- end
397
- end
@@ -1,54 +0,0 @@
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
- module HeaderProtocolHelper
21
- def varint32(n)
22
- bytes = []
23
- loop do
24
- if (n & ~0x7f) == 0
25
- bytes << n
26
- break
27
- else
28
- bytes << ((n & 0x7f) | 0x80)
29
- n >>= 7
30
- end
31
- end
32
- bytes.pack('C*')
33
- end
34
-
35
- def build_header_frame(header_data, payload = Thrift::Bytes.empty_byte_buffer, header_words: nil)
36
- header_data = Thrift::Bytes.force_binary_encoding(header_data)
37
- if header_words.nil?
38
- padding = (4 - (header_data.bytesize % 4)) % 4
39
- header_data += "\x00" * padding
40
- header_words = header_data.bytesize / 4
41
- end
42
-
43
- frame_size = 2 + 2 + 4 + 2 + header_data.bytesize + payload.bytesize
44
- frame = Thrift::Bytes.empty_byte_buffer
45
- frame << [frame_size].pack('N')
46
- frame << [Thrift::HeaderTransport::HEADER_MAGIC].pack('n')
47
- frame << [0].pack('n')
48
- frame << [0].pack('N')
49
- frame << [header_words].pack('n')
50
- frame << header_data
51
- frame << payload
52
- frame
53
- end
54
- end