thrift 0.24.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +107 -4
  3. data/ext/binary_protocol_accelerated.c +52 -17
  4. data/ext/compact_protocol.c +135 -70
  5. data/ext/constants.h +3 -0
  6. data/ext/extconf.rb +4 -4
  7. data/ext/macros.h +11 -0
  8. data/ext/memory_buffer.c +35 -17
  9. data/ext/struct.c +185 -64
  10. data/ext/thrift_native.c +6 -0
  11. data/lib/thrift/bytes.rb +2 -2
  12. data/lib/thrift/client.rb +31 -22
  13. data/lib/thrift/exceptions.rb +10 -8
  14. data/lib/thrift/multiplexed_processor.rb +5 -6
  15. data/lib/thrift/processor.rb +24 -3
  16. data/lib/thrift/protocol/base_protocol.rb +53 -27
  17. data/lib/thrift/protocol/binary_protocol.rb +54 -40
  18. data/lib/thrift/protocol/binary_protocol_accelerated.rb +6 -2
  19. data/lib/thrift/protocol/compact_protocol.rb +193 -88
  20. data/lib/thrift/protocol/header_protocol.rb +14 -3
  21. data/lib/thrift/protocol/json_protocol.rb +146 -104
  22. data/lib/thrift/protocol/multiplexed_protocol.rb +2 -3
  23. data/lib/thrift/protocol/protocol_decorator.rb +5 -2
  24. data/lib/thrift/serializer/serializer.rb +6 -0
  25. data/lib/thrift/server/base_server.rb +10 -2
  26. data/lib/thrift/server/nonblocking_server.rb +49 -26
  27. data/lib/thrift/server/rack_application.rb +69 -0
  28. data/lib/thrift/server/simple_server.rb +27 -23
  29. data/lib/thrift/server/thin_http_server.rb +20 -44
  30. data/lib/thrift/server/thread_pool_server.rb +20 -17
  31. data/lib/thrift/server/threaded_server.rb +22 -26
  32. data/lib/thrift/struct.rb +33 -18
  33. data/lib/thrift/struct_union.rb +36 -30
  34. data/lib/thrift/transport/base_transport.rb +23 -5
  35. data/lib/thrift/transport/buffered_transport.rb +4 -4
  36. data/lib/thrift/transport/framed_transport.rb +32 -7
  37. data/lib/thrift/transport/header_transport.rb +130 -50
  38. data/lib/thrift/transport/http_client_transport.rb +27 -14
  39. data/lib/thrift/transport/io_stream_transport.rb +2 -1
  40. data/lib/thrift/transport/memory_buffer_transport.rb +8 -10
  41. data/lib/thrift/transport/server_socket.rb +4 -5
  42. data/lib/thrift/transport/socket.rb +20 -22
  43. data/lib/thrift/transport/ssl_server_socket.rb +64 -4
  44. data/lib/thrift/transport/ssl_socket.rb +32 -5
  45. data/lib/thrift/transport/unix_server_socket.rb +1 -1
  46. data/lib/thrift/transport/unix_socket.rb +4 -6
  47. data/lib/thrift/types.rb +22 -22
  48. data/lib/thrift/union.rb +20 -11
  49. data/lib/thrift/uuid.rb +8 -8
  50. data/lib/thrift.rb +39 -39
  51. metadata +5 -230
  52. data/benchmark/Benchmark.thrift +0 -24
  53. data/benchmark/benchmark.rb +0 -286
  54. data/benchmark/client.rb +0 -118
  55. data/benchmark/server.rb +0 -121
  56. data/benchmark/thin_server.rb +0 -46
  57. data/lib/thrift/server/mongrel_http_server.rb +0 -61
  58. data/spec/BaseService.thrift +0 -27
  59. data/spec/ExtendedService.thrift +0 -25
  60. data/spec/Referenced.thrift +0 -44
  61. data/spec/ThriftNamespacedSpec.thrift +0 -53
  62. data/spec/ThriftSpec.thrift +0 -203
  63. data/spec/base_protocol_spec.rb +0 -244
  64. data/spec/base_transport_spec.rb +0 -428
  65. data/spec/binary_protocol_accelerated_spec.rb +0 -47
  66. data/spec/binary_protocol_spec.rb +0 -73
  67. data/spec/binary_protocol_spec_shared.rb +0 -509
  68. data/spec/bytes_spec.rb +0 -117
  69. data/spec/client_spec.rb +0 -167
  70. data/spec/compact_protocol_spec.rb +0 -295
  71. data/spec/constants_demo_spec.rb +0 -102
  72. data/spec/exception_spec.rb +0 -141
  73. data/spec/flat_spec.rb +0 -63
  74. data/spec/header_protocol_spec.rb +0 -476
  75. data/spec/header_transport_spec.rb +0 -431
  76. data/spec/http_client_spec.rb +0 -160
  77. data/spec/json_protocol_spec.rb +0 -574
  78. data/spec/multiplexed_processor_spec.rb +0 -75
  79. data/spec/namespaced_spec.rb +0 -67
  80. data/spec/nonblocking_server_spec.rb +0 -429
  81. data/spec/processor_spec.rb +0 -80
  82. data/spec/recursion_depth_spec.rb +0 -223
  83. data/spec/serializer_spec.rb +0 -67
  84. data/spec/server_socket_spec.rb +0 -121
  85. data/spec/server_spec.rb +0 -238
  86. data/spec/socket_spec.rb +0 -174
  87. data/spec/socket_spec_shared.rb +0 -168
  88. data/spec/spec_helper.rb +0 -70
  89. data/spec/ssl_server_socket_spec.rb +0 -85
  90. data/spec/ssl_socket_spec.rb +0 -248
  91. data/spec/struct_nested_containers_spec.rb +0 -191
  92. data/spec/struct_spec.rb +0 -398
  93. data/spec/support/header_protocol_helper.rb +0 -55
  94. data/spec/thin_http_server_spec.rb +0 -127
  95. data/spec/types_spec.rb +0 -118
  96. data/spec/union_spec.rb +0 -273
  97. data/spec/unix_socket_spec.rb +0 -131
  98. data/spec/uuid_validation_spec.rb +0 -239
  99. data/test/fuzz/Makefile +0 -779
  100. data/test/fuzz/Makefile.am +0 -173
  101. data/test/fuzz/Makefile.in +0 -775
  102. data/test/fuzz/README.md +0 -149
  103. data/test/fuzz/fuzz_common.rb +0 -96
  104. data/test/fuzz/fuzz_parse_binary_protocol.rb +0 -23
  105. data/test/fuzz/fuzz_parse_binary_protocol_accelerated.rb +0 -23
  106. data/test/fuzz/fuzz_parse_binary_protocol_accelerated_harness.rb +0 -23
  107. data/test/fuzz/fuzz_parse_binary_protocol_harness.rb +0 -23
  108. data/test/fuzz/fuzz_parse_compact_protocol.rb +0 -23
  109. data/test/fuzz/fuzz_parse_compact_protocol_harness.rb +0 -23
  110. data/test/fuzz/fuzz_parse_json_protocol.rb +0 -23
  111. data/test/fuzz/fuzz_parse_json_protocol_harness.rb +0 -23
  112. data/test/fuzz/fuzz_roundtrip_binary_protocol.rb +0 -23
  113. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated.rb +0 -23
  114. data/test/fuzz/fuzz_roundtrip_binary_protocol_accelerated_harness.rb +0 -23
  115. data/test/fuzz/fuzz_roundtrip_binary_protocol_harness.rb +0 -23
  116. data/test/fuzz/fuzz_roundtrip_compact_protocol.rb +0 -23
  117. data/test/fuzz/fuzz_roundtrip_compact_protocol_harness.rb +0 -23
  118. data/test/fuzz/fuzz_roundtrip_json_protocol.rb +0 -23
  119. data/test/fuzz/fuzz_roundtrip_json_protocol_harness.rb +0 -23
  120. data/test/fuzz/fuzz_tracer.rb +0 -29
@@ -1,223 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- # Licensed to the Apache Software Foundation (ASF) under one
4
- # or more contributor license agreements. See the NOTICE file
5
- # distributed with this work for additional information
6
- # regarding copyright ownership. The ASF licenses this file
7
- # to you under the Apache License, Version 2.0 (the
8
- # "License"); you may not use this file except in compliance
9
- # with the License. You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing,
14
- # software distributed under the License is distributed on an
15
- # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
- # KIND, either express or implied. See the License for the
17
- # specific language governing permissions and limitations
18
- # under the License.
19
- #
20
-
21
- require 'spec_helper'
22
-
23
- # Round-trip test for struct/union/exception recursion depth, driving the
24
- # *generated* read/write path (Thrift::Struct#read/#write,
25
- # Thrift::Union#read/#write) over RecTree / RecUnion / RecError from
26
- # ThriftSpec.thrift; a linear chain is one struct level deeper per node, so a
27
- # chain of N nodes reaches depth N.
28
- #
29
- # NOTE: the Ruby library does not enforce a recursion-depth limit yet
30
- # (THRIFT-6045). The round-trip / within-limit examples are active; the
31
- # limit-enforcement (over-limit) examples are `pending` and will start passing
32
- # once the limit is implemented, at which point RSpec flags them to be enabled.
33
- describe 'recursion depth limit' do
34
- # The intended struct/union nesting limit. The Ruby library does not enforce a
35
- # recursion-depth limit yet (THRIFT-6045); the limit-enforcement examples below
36
- # are therefore `pending` until it is implemented. 64 matches the limit other
37
- # Thrift libraries use.
38
- RECURSION_LIMIT = 64
39
-
40
- # Attached to the pending (over-limit) examples.
41
- PENDING_REASON = 'recursion-depth limit not implemented in the Ruby library yet (THRIFT-6045)'
42
-
43
- def binary_protocol
44
- Thrift::BinaryProtocol.new(Thrift::MemoryBufferTransport.new)
45
- end
46
-
47
- # A linearly nested RecTree that is `depth` struct levels deep.
48
- def struct_chain(depth)
49
- node = SpecNamespace::RecTree.new(item: depth, children: [])
50
- node.children = [struct_chain(depth - 1)] if depth > 1
51
- node
52
- end
53
-
54
- def tree_depth(node)
55
- n = 0
56
- until node.nil?
57
- n += 1
58
- break if node.children.nil? || node.children.empty?
59
- node = node.children.first
60
- end
61
- n
62
- end
63
-
64
- # A linearly nested RecUnion that is `depth` levels deep (each union holds the
65
- # next; the innermost holds a scalar leaf).
66
- def union_chain(depth)
67
- if depth > 1
68
- SpecNamespace::RecUnion.new(children: [union_chain(depth - 1)])
69
- else
70
- SpecNamespace::RecUnion.new(leaf: 0)
71
- end
72
- end
73
-
74
- # A linearly nested RecError exception that is `depth` struct levels deep.
75
- # Exceptions read/write through the same generated path as structs, so
76
- # tree_depth applies to the decoded chain too.
77
- def error_chain(depth)
78
- node = SpecNamespace::RecError.new(leaf: depth, children: [])
79
- node.children = [error_chain(depth - 1)] if depth > 1
80
- node
81
- end
82
-
83
- # Emit, via raw protocol calls (which carry no depth guard), the wire image of
84
- # a RecTree chain `depth` levels deep. This lets the read tests feed an
85
- # over-limit payload that the guarded writer would itself refuse to produce.
86
- def write_raw_tree(oprot, depth)
87
- oprot.write_struct_begin('RecTree')
88
- oprot.write_field_begin('children', Thrift::Types::LIST, 1)
89
- oprot.write_list_begin(Thrift::Types::STRUCT, depth > 1 ? 1 : 0)
90
- write_raw_tree(oprot, depth - 1) if depth > 1
91
- oprot.write_list_end
92
- oprot.write_field_end
93
- oprot.write_field_begin('item', Thrift::Types::I16, 2)
94
- oprot.write_i16(depth)
95
- oprot.write_field_end
96
- oprot.write_field_stop
97
- oprot.write_struct_end
98
- end
99
-
100
- # Same as write_raw_tree but for the RecError exception (leaf is i32 here).
101
- def write_raw_error(oprot, depth)
102
- oprot.write_struct_begin('RecError')
103
- oprot.write_field_begin('children', Thrift::Types::LIST, 1)
104
- oprot.write_list_begin(Thrift::Types::STRUCT, depth > 1 ? 1 : 0)
105
- write_raw_error(oprot, depth - 1) if depth > 1
106
- oprot.write_list_end
107
- oprot.write_field_end
108
- oprot.write_field_begin('leaf', Thrift::Types::I32, 2)
109
- oprot.write_i32(depth)
110
- oprot.write_field_end
111
- oprot.write_field_stop
112
- oprot.write_struct_end
113
- end
114
-
115
- def expect_depth_limit
116
- expect { yield }.to raise_error(Thrift::ProtocolException) { |e|
117
- expect(e.type).to eq(Thrift::ProtocolException::DEPTH_LIMIT)
118
- }
119
- end
120
-
121
- describe 'structs' do
122
- it 'round-trips a chain at the limit' do
123
- prot = binary_protocol
124
- struct_chain(RECURSION_LIMIT).write(prot)
125
- result = SpecNamespace::RecTree.new
126
- result.read(prot)
127
- expect(tree_depth(result)).to eq(RECURSION_LIMIT)
128
- end
129
-
130
- it 'rejects writing a chain past the limit' do
131
- pending PENDING_REASON
132
- expect_depth_limit { struct_chain(RECURSION_LIMIT + 1).write(binary_protocol) }
133
- end
134
-
135
- it 'rejects reading a payload past the limit' do
136
- pending PENDING_REASON
137
- prot = binary_protocol
138
- write_raw_tree(prot, RECURSION_LIMIT + 1)
139
- expect_depth_limit { SpecNamespace::RecTree.new.read(prot) }
140
- end
141
-
142
- it 'round-trips a wide shallow tree (counter unwinds per sibling)' do
143
- width = RECURSION_LIMIT * 3
144
- prot = binary_protocol
145
- root = SpecNamespace::RecTree.new(
146
- item: 0,
147
- children: (1..width).map { |i| SpecNamespace::RecTree.new(item: i, children: []) }
148
- )
149
- root.write(prot)
150
- result = SpecNamespace::RecTree.new
151
- result.read(prot)
152
- expect(result.children.size).to eq(width)
153
- end
154
- end
155
-
156
- describe 'unions' do
157
- it 'round-trips a chain at the limit' do
158
- prot = binary_protocol
159
- union_chain(RECURSION_LIMIT).write(prot)
160
- expect { SpecNamespace::RecUnion.new.read(prot) }.not_to raise_error
161
- end
162
-
163
- it 'rejects writing a chain past the limit' do
164
- pending PENDING_REASON
165
- expect_depth_limit { union_chain(RECURSION_LIMIT + 1).write(binary_protocol) }
166
- end
167
- end
168
-
169
- describe 'exceptions' do
170
- it 'round-trips a chain at the limit' do
171
- prot = binary_protocol
172
- error_chain(RECURSION_LIMIT).write(prot)
173
- result = SpecNamespace::RecError.new
174
- result.read(prot)
175
- expect(tree_depth(result)).to eq(RECURSION_LIMIT)
176
- end
177
-
178
- it 'rejects writing a chain past the limit' do
179
- pending PENDING_REASON
180
- expect_depth_limit { error_chain(RECURSION_LIMIT + 1).write(binary_protocol) }
181
- end
182
-
183
- it 'rejects reading a payload past the limit' do
184
- pending PENDING_REASON
185
- prot = binary_protocol
186
- write_raw_error(prot, RECURSION_LIMIT + 1)
187
- expect_depth_limit { SpecNamespace::RecError.new.read(prot) }
188
- end
189
- end
190
-
191
- describe 'protocol decorators' do
192
- # A struct written through a decorator must still be bounded and must not
193
- # crash: decorators (MultiplexedProtocol via ProtocolDecorator) do not chain
194
- # BaseProtocol#initialize, so the depth counter starts unset on that object.
195
- it 'round-trips a struct through a MultiplexedProtocol' do
196
- mprot = Thrift::MultiplexedProtocol.new(binary_protocol, 'svc')
197
- struct_chain(3).write(mprot)
198
- result = SpecNamespace::RecTree.new
199
- result.read(mprot)
200
- expect(tree_depth(result)).to eq(3)
201
- end
202
- end
203
-
204
- # Only present when the native (thrift_native) extension is loaded, which
205
- # also makes Thrift::Struct#read/#write the native implementations -- the path
206
- # that must enforce the limit in C, not just in pure Ruby.
207
- if defined? Thrift::BinaryProtocolAccelerated
208
- describe 'accelerated binary protocol' do
209
- it 'rejects writing a chain past the limit' do
210
- pending PENDING_REASON
211
- prot = Thrift::BinaryProtocolAccelerated.new(Thrift::MemoryBufferTransport.new)
212
- expect_depth_limit { struct_chain(RECURSION_LIMIT + 1).write(prot) }
213
- end
214
-
215
- it 'rejects reading a payload past the limit' do
216
- pending PENDING_REASON
217
- prot = Thrift::BinaryProtocolAccelerated.new(Thrift::MemoryBufferTransport.new)
218
- write_raw_tree(prot, RECURSION_LIMIT + 1)
219
- expect_depth_limit { SpecNamespace::RecTree.new.read(prot) }
220
- end
221
- end
222
- end
223
- end
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- # Licensed to the Apache Software Foundation (ASF) under one
4
- # or more contributor license agreements. See the NOTICE file
5
- # distributed with this work for additional information
6
- # regarding copyright ownership. The ASF licenses this file
7
- # to you under the Apache License, Version 2.0 (the
8
- # "License"); you may not use this file except in compliance
9
- # with the License. You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing,
14
- # software distributed under the License is distributed on an
15
- # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
- # KIND, either express or implied. See the License for the
17
- # specific language governing permissions and limitations
18
- # under the License.
19
- #
20
-
21
- require 'spec_helper'
22
-
23
- describe 'Serializer' do
24
- describe Thrift::Serializer do
25
- it "should serialize structs to binary by default" do
26
- serializer = Thrift::Serializer.new(Thrift::BinaryProtocolAcceleratedFactory.new)
27
- data = serializer.serialize(SpecNamespace::Hello.new(:greeting => "'Ello guv'nor!"))
28
- expect(data).to eq("\x0B\x00\x01\x00\x00\x00\x0E'Ello guv'nor!\x00")
29
- end
30
-
31
- it "should serialize structs to the given protocol" do
32
- protocol = Thrift::BaseProtocol.new(double("transport"))
33
- expect(protocol).to receive(:write_struct_begin).with("SpecNamespace::Hello")
34
- expect(protocol).to receive(:write_field_begin).with("greeting", Thrift::Types::STRING, 1)
35
- expect(protocol).to receive(:write_string).with("Good day")
36
- expect(protocol).to receive(:write_field_end)
37
- expect(protocol).to receive(:write_field_stop)
38
- expect(protocol).to receive(:write_struct_end)
39
- protocol_factory = double("ProtocolFactory")
40
- allow(protocol_factory).to receive(:get_protocol).and_return(protocol)
41
- serializer = Thrift::Serializer.new(protocol_factory)
42
- serializer.serialize(SpecNamespace::Hello.new(:greeting => "Good day"))
43
- end
44
- end
45
-
46
- describe Thrift::Deserializer do
47
- it "should deserialize structs from binary by default" do
48
- deserializer = Thrift::Deserializer.new
49
- data = "\x0B\x00\x01\x00\x00\x00\x0E'Ello guv'nor!\x00"
50
- expect(deserializer.deserialize(SpecNamespace::Hello.new, data)).to eq(SpecNamespace::Hello.new(:greeting => "'Ello guv'nor!"))
51
- end
52
-
53
- it "should deserialize structs from the given protocol" do
54
- protocol = Thrift::BaseProtocol.new(double("transport"))
55
- expect(protocol).to receive(:read_struct_begin).and_return("SpecNamespace::Hello")
56
- expect(protocol).to receive(:read_field_begin).and_return(["greeting", Thrift::Types::STRING, 1],
57
- [nil, Thrift::Types::STOP, 0])
58
- expect(protocol).to receive(:read_string).and_return("Good day")
59
- expect(protocol).to receive(:read_field_end)
60
- expect(protocol).to receive(:read_struct_end)
61
- protocol_factory = double("ProtocolFactory")
62
- allow(protocol_factory).to receive(:get_protocol).and_return(protocol)
63
- deserializer = Thrift::Deserializer.new(protocol_factory)
64
- expect(deserializer.deserialize(SpecNamespace::Hello.new, "")).to eq(SpecNamespace::Hello.new(:greeting => "Good day"))
65
- end
66
- end
67
- end
@@ -1,121 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- # Licensed to the Apache Software Foundation (ASF) under one
4
- # or more contributor license agreements. See the NOTICE file
5
- # distributed with this work for additional information
6
- # regarding copyright ownership. The ASF licenses this file
7
- # to you under the Apache License, Version 2.0 (the
8
- # "License"); you may not use this file except in compliance
9
- # with the License. You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing,
14
- # software distributed under the License is distributed on an
15
- # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
- # KIND, either express or implied. See the License for the
17
- # specific language governing permissions and limitations
18
- # under the License.
19
- #
20
-
21
- require 'spec_helper'
22
- require File.expand_path("#{File.dirname(__FILE__)}/socket_spec_shared")
23
-
24
- describe 'Thrift::ServerSocket' do
25
- describe Thrift::ServerSocket do
26
- before(:each) do
27
- @socket = Thrift::ServerSocket.new(1234)
28
- end
29
-
30
- it "should create a handle when calling listen" do
31
- expect(TCPServer).to receive(:new).with(nil, 1234)
32
- @socket.listen
33
- end
34
-
35
- it "should accept an optional host argument" do
36
- @socket = Thrift::ServerSocket.new('localhost', 1234)
37
- expect(TCPServer).to receive(:new).with('localhost', 1234)
38
- @socket.to_s == "server(localhost:1234)"
39
- @socket.listen
40
- end
41
-
42
- it "should create a Thrift::Socket to wrap accepted sockets" do
43
- handle = double("TCPServer")
44
- expect(TCPServer).to receive(:new).with(nil, 1234).and_return(handle)
45
- @socket.listen
46
- sock = double("sock")
47
- expect(sock).to receive(:setsockopt).with(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
48
- expect(handle).to receive(:accept).and_return(sock)
49
- trans = double("Socket")
50
- expect(Thrift::Socket).to receive(:new).and_return(trans)
51
- expect(trans).to receive(:timeout=).with(Thrift::BaseServerTransport::DEFAULT_CLIENT_TIMEOUT)
52
- expect(trans).to receive(:handle=).with(sock)
53
- expect(@socket.accept).to eq(trans)
54
- end
55
-
56
- it "should default accepted sockets to a finite client timeout" do
57
- expect(@socket.client_timeout).to eq(5)
58
- end
59
-
60
- it "should accept a custom client timeout" do
61
- @socket = Thrift::ServerSocket.new(1234, client_timeout: 2.5)
62
- expect(@socket.client_timeout).to eq(2.5)
63
- end
64
-
65
- it "should allow blocking accepted sockets with nil or zero client timeout" do
66
- expect(Thrift::ServerSocket.new(1234, client_timeout: nil).client_timeout).to be_nil
67
- expect(Thrift::ServerSocket.new(1234, client_timeout: 0).client_timeout).to eq(0)
68
- end
69
-
70
- it "should use the accepted socket timeout for writes" do
71
- handle = double("TCPServer")
72
- allow(TCPServer).to receive(:new).with(nil, 1234).and_return(handle)
73
- @socket.listen
74
-
75
- sock = double("sock", :closed? => false)
76
- allow(sock).to receive(:setsockopt)
77
- allow(handle).to receive(:accept).and_return(sock)
78
-
79
- transport = @socket.accept
80
- expect(transport.timeout).to eq(Thrift::BaseServerTransport::DEFAULT_CLIENT_TIMEOUT)
81
-
82
- expect(sock).to receive(:write_nonblock).with("test data").and_raise(IO::EAGAINWaitWritable)
83
- expect(Process).to receive(:clock_gettime).with(Process::CLOCK_MONOTONIC).and_return(100.0, 100.0, 105.1)
84
- expect(IO).to receive(:select).with(nil, [sock], nil, 5.0).and_return(nil)
85
-
86
- expect { transport.write("test data") }.to raise_error(Thrift::TransportException) do |e|
87
- expect(e.type).to eq(Thrift::TransportException::TIMED_OUT)
88
- end
89
- end
90
-
91
- it "should close the handle when closed" do
92
- handle = double("TCPServer", :closed? => false)
93
- expect(TCPServer).to receive(:new).with(nil, 1234).and_return(handle)
94
- @socket.listen
95
- expect(handle).to receive(:close)
96
- @socket.close
97
- end
98
-
99
- it "should return nil when accepting if there is no handle" do
100
- expect(@socket.accept).to be_nil
101
- end
102
-
103
- it "should return true for closed? when appropriate" do
104
- handle = double("TCPServer", :closed? => false)
105
- allow(TCPServer).to receive(:new).and_return(handle)
106
- @socket.listen
107
- expect(@socket).not_to be_closed
108
- allow(handle).to receive(:close)
109
- @socket.close
110
- expect(@socket).to be_closed
111
- @socket.listen
112
- expect(@socket).not_to be_closed
113
- allow(handle).to receive(:closed?).and_return(true)
114
- expect(@socket).to be_closed
115
- end
116
-
117
- it "should provide a reasonable to_s" do
118
- expect(@socket.to_s).to eq("socket(:1234)")
119
- end
120
- end
121
- end
data/spec/server_spec.rb DELETED
@@ -1,238 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- # Licensed to the Apache Software Foundation (ASF) under one
4
- # or more contributor license agreements. See the NOTICE file
5
- # distributed with this work for additional information
6
- # regarding copyright ownership. The ASF licenses this file
7
- # to you under the Apache License, Version 2.0 (the
8
- # "License"); you may not use this file except in compliance
9
- # with the License. You may obtain a copy of the License at
10
- #
11
- # http://www.apache.org/licenses/LICENSE-2.0
12
- #
13
- # Unless required by applicable law or agreed to in writing,
14
- # software distributed under the License is distributed on an
15
- # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
- # KIND, either express or implied. See the License for the
17
- # specific language governing permissions and limitations
18
- # under the License.
19
- #
20
- require 'spec_helper'
21
- require 'openssl'
22
-
23
- describe 'Server' do
24
- describe Thrift::BaseServer do
25
- before(:each) do
26
- @processor = double("Processor")
27
- @serverTrans = double("ServerTransport")
28
- @trans = double("BaseTransport")
29
- @prot = double("BaseProtocol")
30
- @server = described_class.new(@processor, @serverTrans, @trans, @prot)
31
- end
32
-
33
- it "should default to BaseTransportFactory and BinaryProtocolFactory when not specified" do
34
- @server = Thrift::BaseServer.new(double("Processor"), double("BaseServerTransport"))
35
- expect(@server.instance_variable_get(:'@transport_factory')).to be_an_instance_of(Thrift::BaseTransportFactory)
36
- expect(@server.instance_variable_get(:'@protocol_factory')).to be_an_instance_of(Thrift::BinaryProtocolFactory)
37
- end
38
-
39
- it "should not serve" do
40
- expect { @server.serve() }.to raise_error(NotImplementedError)
41
- end
42
-
43
- it "should provide a reasonable to_s" do
44
- expect(@serverTrans).to receive(:to_s).once.and_return("serverTrans")
45
- expect(@trans).to receive(:to_s).once.and_return("trans")
46
- expect(@prot).to receive(:to_s).once.and_return("prot")
47
- expect(@server.to_s).to eq("server(prot(trans(serverTrans)))")
48
- end
49
- end
50
-
51
- describe Thrift::SimpleServer do
52
- before(:each) do
53
- @processor = double("Processor")
54
- @serverTrans = double("ServerTransport")
55
- @trans = double("BaseTransport")
56
- @prot = double("BaseProtocol")
57
- @client = double("Client")
58
- @server = described_class.new(@processor, @serverTrans, @trans, @prot)
59
- end
60
-
61
- it "should provide a reasonable to_s" do
62
- expect(@serverTrans).to receive(:to_s).once.and_return("serverTrans")
63
- expect(@trans).to receive(:to_s).once.and_return("trans")
64
- expect(@prot).to receive(:to_s).once.and_return("prot")
65
- expect(@server.to_s).to eq("simple(server(prot(trans(serverTrans))))")
66
- end
67
-
68
- it "should serve in the main thread" do
69
- expect(@serverTrans).to receive(:listen).ordered
70
- expect(@serverTrans).to receive(:accept).exactly(3).times.and_return(@client)
71
- expect(@trans).to receive(:get_transport).exactly(3).times.with(@client).and_return(@trans)
72
- expect(@prot).to receive(:get_protocol).exactly(3).times.with(@trans).and_return(@prot)
73
- x = 0
74
- expect(@processor).to receive(:process).exactly(3).times.with(@prot, @prot) do
75
- case (x += 1)
76
- when 1 then raise Thrift::TransportException
77
- when 2 then raise Thrift::ProtocolException
78
- when 3 then throw :stop
79
- end
80
- end
81
- expect(@trans).to receive(:close).exactly(3).times
82
- expect(@serverTrans).to receive(:close).ordered
83
- expect { @server.serve }.to throw_symbol(:stop)
84
- end
85
-
86
- it "should continue serving after accept raises Errno::ECONNRESET" do
87
- expect(@serverTrans).to receive(:listen).ordered
88
- expect(@serverTrans).to receive(:accept).ordered.and_raise(Errno::ECONNRESET)
89
- expect(@serverTrans).to receive(:accept).ordered.and_return(@client)
90
- expect(@trans).to receive(:get_transport).once.with(@client).and_return(@trans)
91
- expect(@prot).to receive(:get_protocol).once.with(@trans).and_return(@prot)
92
- expect(@processor).to receive(:process).once.with(@prot, @prot) { throw :stop }
93
- expect(@trans).to receive(:close).once
94
- expect(@serverTrans).to receive(:close).ordered
95
- expect { @server.serve }.to throw_symbol(:stop)
96
- end
97
-
98
- it "should continue serving after accept raises OpenSSL::SSL::SSLError" do
99
- expect(@serverTrans).to receive(:listen).ordered
100
- expect(@serverTrans).to receive(:accept).ordered.and_raise(OpenSSL::SSL::SSLError)
101
- expect(@serverTrans).to receive(:accept).ordered.and_return(@client)
102
- expect(@trans).to receive(:get_transport).once.with(@client).and_return(@trans)
103
- expect(@prot).to receive(:get_protocol).once.with(@trans).and_return(@prot)
104
- expect(@processor).to receive(:process).once.with(@prot, @prot) { throw :stop }
105
- expect(@trans).to receive(:close).once
106
- expect(@serverTrans).to receive(:close).ordered
107
- expect { @server.serve }.to throw_symbol(:stop)
108
- end
109
- end
110
-
111
- describe Thrift::ThreadedServer do
112
- before(:each) do
113
- @processor = double("Processor")
114
- @serverTrans = double("ServerTransport")
115
- @trans = double("BaseTransport")
116
- @prot = double("BaseProtocol")
117
- @client = double("Client")
118
- @server = described_class.new(@processor, @serverTrans, @trans, @prot)
119
- end
120
-
121
- it "should provide a reasonable to_s" do
122
- expect(@serverTrans).to receive(:to_s).once.and_return("serverTrans")
123
- expect(@trans).to receive(:to_s).once.and_return("trans")
124
- expect(@prot).to receive(:to_s).once.and_return("prot")
125
- expect(@server.to_s).to eq("threaded(server(prot(trans(serverTrans))))")
126
- end
127
-
128
- it "should serve using threads" do
129
- expect(@serverTrans).to receive(:listen).ordered
130
- expect(@serverTrans).to receive(:accept).exactly(3).times.and_return(@client)
131
- expect(@trans).to receive(:get_transport).exactly(3).times.with(@client).and_return(@trans)
132
- expect(@prot).to receive(:get_protocol).exactly(3).times.with(@trans).and_return(@prot)
133
- expect(Thread).to receive(:new).with(@prot, @trans).exactly(3).times.and_yield(@prot, @trans)
134
- x = 0
135
- expect(@processor).to receive(:process).exactly(3).times.with(@prot, @prot) do
136
- case (x += 1)
137
- when 1 then raise Thrift::TransportException
138
- when 2 then raise Thrift::ProtocolException
139
- when 3 then throw :stop
140
- end
141
- end
142
- expect(@trans).to receive(:close).exactly(3).times
143
- expect(@serverTrans).to receive(:close).ordered
144
- expect { @server.serve }.to throw_symbol(:stop)
145
- end
146
-
147
- it "should continue serving after accept raises Errno::ECONNRESET" do
148
- expect(@serverTrans).to receive(:listen).ordered
149
- expect(@serverTrans).to receive(:accept).ordered.and_raise(Errno::ECONNRESET)
150
- expect(@serverTrans).to receive(:accept).ordered.and_return(@client)
151
- expect(@trans).to receive(:get_transport).once.with(@client).and_return(@trans)
152
- expect(@prot).to receive(:get_protocol).once.with(@trans).and_return(@prot)
153
- expect(Thread).to receive(:new).with(@prot, @trans).once.and_yield(@prot, @trans)
154
- expect(@processor).to receive(:process).once.with(@prot, @prot) { throw :stop }
155
- expect(@trans).to receive(:close).once
156
- expect(@serverTrans).to receive(:close).ordered
157
- expect { @server.serve }.to throw_symbol(:stop)
158
- end
159
-
160
- it "should continue serving after accept raises OpenSSL::SSL::SSLError" do
161
- expect(@serverTrans).to receive(:listen).ordered
162
- expect(@serverTrans).to receive(:accept).ordered.and_raise(OpenSSL::SSL::SSLError)
163
- expect(@serverTrans).to receive(:accept).ordered.and_return(@client)
164
- expect(@trans).to receive(:get_transport).once.with(@client).and_return(@trans)
165
- expect(@prot).to receive(:get_protocol).once.with(@trans).and_return(@prot)
166
- expect(Thread).to receive(:new).with(@prot, @trans).once.and_yield(@prot, @trans)
167
- expect(@processor).to receive(:process).once.with(@prot, @prot) { throw :stop }
168
- expect(@trans).to receive(:close).once
169
- expect(@serverTrans).to receive(:close).ordered
170
- expect { @server.serve }.to throw_symbol(:stop)
171
- end
172
- end
173
-
174
- describe Thrift::ThreadPoolServer do
175
- before(:each) do
176
- @processor = double("Processor")
177
- @server_trans = double("ServerTransport")
178
- @trans = double("BaseTransport")
179
- @prot = double("BaseProtocol")
180
- @client = double("Client")
181
- @server = described_class.new(@processor, @server_trans, @trans, @prot)
182
- sleep(0.15)
183
- end
184
-
185
- it "should provide a reasonable to_s" do
186
- expect(@server_trans).to receive(:to_s).once.and_return("server_trans")
187
- expect(@trans).to receive(:to_s).once.and_return("trans")
188
- expect(@prot).to receive(:to_s).once.and_return("prot")
189
- expect(@server.to_s).to eq("threadpool(server(prot(trans(server_trans))))")
190
- end
191
-
192
- it "should serve inside a thread" do
193
- exception_q = @server.instance_variable_get(:@exception_q)
194
- expect_any_instance_of(described_class).to receive(:serve) do
195
- exception_q.push(StandardError.new('ERROR'))
196
- end
197
- expect { @server.rescuable_serve }.to(raise_error('ERROR'))
198
- sleep(0.15)
199
- end
200
-
201
- it "should avoid running the server twice when retrying rescuable_serve" do
202
- exception_q = @server.instance_variable_get(:@exception_q)
203
- expect_any_instance_of(described_class).to receive(:serve) do
204
- exception_q.push(StandardError.new('ERROR1'))
205
- exception_q.push(StandardError.new('ERROR2'))
206
- end
207
- expect { @server.rescuable_serve }.to(raise_error('ERROR1'))
208
- expect { @server.rescuable_serve }.to(raise_error('ERROR2'))
209
- end
210
-
211
- it "should serve using a thread pool" do
212
- thread_q = double("SizedQueue")
213
- exception_q = double("Queue")
214
- @server.instance_variable_set(:@thread_q, thread_q)
215
- @server.instance_variable_set(:@exception_q, exception_q)
216
- expect(@server_trans).to receive(:listen).ordered
217
- expect(thread_q).to receive(:push).with(:token)
218
- expect(thread_q).to receive(:pop)
219
- expect(Thread).to receive(:new).and_yield
220
- expect(@server_trans).to receive(:accept).exactly(3).times.and_return(@client)
221
- expect(@trans).to receive(:get_transport).exactly(3).times.and_return(@trans)
222
- expect(@prot).to receive(:get_protocol).exactly(3).times.and_return(@prot)
223
- x = 0
224
- error = RuntimeError.new("Stopped")
225
- expect(@processor).to receive(:process).exactly(3).times.with(@prot, @prot) do
226
- case (x += 1)
227
- when 1 then raise Thrift::TransportException
228
- when 2 then raise Thrift::ProtocolException
229
- when 3 then raise error
230
- end
231
- end
232
- expect(@trans).to receive(:close).exactly(3).times
233
- expect(exception_q).to receive(:push).with(error).and_throw(:stop)
234
- expect(@server_trans).to receive(:close)
235
- expect { @server.serve }.to(throw_symbol(:stop))
236
- end
237
- end
238
- end