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.
- checksums.yaml +4 -4
- data/README.md +203 -40
- data/ext/binary_protocol_accelerated.c +130 -40
- data/ext/bytes.c +14 -0
- data/ext/compact_protocol.c +184 -91
- data/ext/constants.h +3 -0
- data/ext/extconf.rb +12 -4
- data/ext/macros.h +11 -0
- data/ext/memory_buffer.c +67 -12
- data/ext/struct.c +192 -71
- data/ext/thrift_native.c +7 -0
- data/lib/thrift/bytes.rb +6 -3
- data/lib/thrift/client.rb +31 -33
- data/lib/thrift/exceptions.rb +11 -8
- data/lib/thrift/multiplexed_processor.rb +17 -8
- data/lib/thrift/processor.rb +25 -3
- data/lib/thrift/protocol/base_protocol.rb +66 -31
- data/lib/thrift/protocol/binary_protocol.rb +80 -37
- data/lib/thrift/protocol/binary_protocol_accelerated.rb +7 -2
- data/lib/thrift/protocol/compact_protocol.rb +204 -88
- data/lib/thrift/protocol/header_protocol.rb +15 -3
- data/lib/thrift/protocol/json_protocol.rb +158 -109
- data/lib/thrift/protocol/multiplexed_protocol.rb +3 -3
- data/lib/thrift/protocol/protocol_decorator.rb +6 -2
- data/lib/thrift/serializer/deserializer.rb +1 -0
- data/lib/thrift/serializer/serializer.rb +7 -0
- data/lib/thrift/server/base_server.rb +11 -2
- data/lib/thrift/server/nonblocking_server.rb +69 -20
- data/lib/thrift/server/rack_application.rb +69 -0
- data/lib/thrift/server/simple_server.rb +27 -15
- data/lib/thrift/server/thin_http_server.rb +21 -44
- data/lib/thrift/server/thread_pool_server.rb +21 -17
- data/lib/thrift/server/threaded_server.rb +22 -18
- data/lib/thrift/struct.rb +34 -18
- data/lib/thrift/struct_union.rb +37 -36
- data/lib/thrift/thrift_native.rb +2 -1
- data/lib/thrift/transport/base_server_transport.rb +3 -0
- data/lib/thrift/transport/base_transport.rb +26 -4
- data/lib/thrift/transport/buffered_transport.rb +5 -4
- data/lib/thrift/transport/framed_transport.rb +33 -7
- data/lib/thrift/transport/header_transport.rb +159 -33
- data/lib/thrift/transport/http_client_transport.rb +28 -14
- data/lib/thrift/transport/io_stream_transport.rb +3 -1
- data/lib/thrift/transport/memory_buffer_transport.rb +14 -9
- data/lib/thrift/transport/server_socket.rb +10 -8
- data/lib/thrift/transport/socket.rb +85 -48
- data/lib/thrift/transport/ssl_server_socket.rb +67 -6
- data/lib/thrift/transport/ssl_socket.rb +73 -14
- data/lib/thrift/transport/unix_server_socket.rb +6 -2
- data/lib/thrift/transport/unix_socket.rb +5 -6
- data/lib/thrift/types.rb +23 -22
- data/lib/thrift/union.rb +21 -11
- data/lib/thrift/uuid.rb +9 -8
- data/lib/thrift.rb +40 -39
- metadata +7 -266
- data/benchmark/Benchmark.thrift +0 -24
- data/benchmark/benchmark.rb +0 -285
- data/benchmark/client.rb +0 -117
- data/benchmark/server.rb +0 -120
- data/benchmark/thin_server.rb +0 -45
- data/lib/thrift/server/mongrel_http_server.rb +0 -60
- data/spec/BaseService.thrift +0 -27
- data/spec/ExtendedService.thrift +0 -25
- data/spec/Referenced.thrift +0 -44
- data/spec/ThriftNamespacedSpec.thrift +0 -53
- data/spec/ThriftSpec.thrift +0 -187
- data/spec/base_protocol_spec.rb +0 -224
- data/spec/base_transport_spec.rb +0 -387
- data/spec/binary_protocol_accelerated_spec.rb +0 -46
- data/spec/binary_protocol_spec.rb +0 -72
- data/spec/binary_protocol_spec_shared.rb +0 -445
- data/spec/bytes_spec.rb +0 -99
- data/spec/client_spec.rb +0 -166
- data/spec/compact_protocol_spec.rb +0 -196
- data/spec/constants_demo_spec.rb +0 -101
- data/spec/exception_spec.rb +0 -140
- data/spec/flat_spec.rb +0 -62
- data/spec/header_protocol_spec.rb +0 -475
- data/spec/header_transport_spec.rb +0 -386
- data/spec/http_client_spec.rb +0 -159
- data/spec/json_protocol_spec.rb +0 -552
- data/spec/namespaced_spec.rb +0 -66
- data/spec/nonblocking_server_spec.rb +0 -361
- data/spec/processor_spec.rb +0 -79
- data/spec/serializer_spec.rb +0 -66
- data/spec/server_socket_spec.rb +0 -84
- data/spec/server_spec.rb +0 -186
- data/spec/socket_spec.rb +0 -67
- data/spec/socket_spec_shared.rb +0 -167
- data/spec/spec_helper.rb +0 -69
- data/spec/ssl_server_socket_spec.rb +0 -45
- data/spec/ssl_socket_spec.rb +0 -87
- data/spec/struct_nested_containers_spec.rb +0 -190
- data/spec/struct_spec.rb +0 -397
- data/spec/support/header_protocol_helper.rb +0 -54
- data/spec/thin_http_server_spec.rb +0 -126
- data/spec/types_spec.rb +0 -117
- data/spec/union_spec.rb +0 -272
- data/spec/unix_socket_spec.rb +0 -115
- data/spec/uuid_validation_spec.rb +0 -238
- data/test/fuzz/Makefile.am +0 -173
- data/test/fuzz/README.md +0 -149
- data/test/fuzz/fuzz_common.rb +0 -95
- data/test/fuzz/fuzz_parse_binary_protocol.rb +0 -22
- data/test/fuzz/fuzz_parse_binary_protocol_accelerated.rb +0 -22
- data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +0 -22
- data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +0 -22
- data/test/fuzz/fuzz_parse_compact_protocol.rb +0 -22
- data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +0 -22
- data/test/fuzz/fuzz_parse_json_protocol.rb +0 -22
- data/test/fuzz/fuzz_parse_json_protocol_harness.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_json_protocol.rb +0 -22
- data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +0 -22
- 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
|