sessionm-thrift 0.8.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/CHANGELOG +1 -0
  2. data/README +43 -0
  3. data/benchmark/Benchmark.thrift +24 -0
  4. data/benchmark/benchmark.rb +271 -0
  5. data/benchmark/client.rb +74 -0
  6. data/benchmark/server.rb +82 -0
  7. data/benchmark/thin_server.rb +44 -0
  8. data/ext/binary_protocol_accelerated.c +441 -0
  9. data/ext/binary_protocol_accelerated.h +20 -0
  10. data/ext/compact_protocol.c +618 -0
  11. data/ext/compact_protocol.h +20 -0
  12. data/ext/constants.h +96 -0
  13. data/ext/extconf.rb +30 -0
  14. data/ext/macros.h +41 -0
  15. data/ext/memory_buffer.c +131 -0
  16. data/ext/memory_buffer.h +20 -0
  17. data/ext/protocol.c +185 -0
  18. data/ext/protocol.h +20 -0
  19. data/ext/strlcpy.c +41 -0
  20. data/ext/strlcpy.h +30 -0
  21. data/ext/struct.c +691 -0
  22. data/ext/struct.h +25 -0
  23. data/ext/thrift_native.c +196 -0
  24. data/lib/thrift.rb +64 -0
  25. data/lib/thrift/client.rb +62 -0
  26. data/lib/thrift/core_ext.rb +23 -0
  27. data/lib/thrift/core_ext/fixnum.rb +29 -0
  28. data/lib/thrift/exceptions.rb +84 -0
  29. data/lib/thrift/processor.rb +57 -0
  30. data/lib/thrift/protocol/base_protocol.rb +290 -0
  31. data/lib/thrift/protocol/binary_protocol.rb +229 -0
  32. data/lib/thrift/protocol/binary_protocol_accelerated.rb +39 -0
  33. data/lib/thrift/protocol/compact_protocol.rb +426 -0
  34. data/lib/thrift/serializer/deserializer.rb +33 -0
  35. data/lib/thrift/serializer/serializer.rb +34 -0
  36. data/lib/thrift/server/base_server.rb +31 -0
  37. data/lib/thrift/server/mongrel_http_server.rb +58 -0
  38. data/lib/thrift/server/nonblocking_server.rb +305 -0
  39. data/lib/thrift/server/simple_server.rb +43 -0
  40. data/lib/thrift/server/thread_pool_server.rb +75 -0
  41. data/lib/thrift/server/threaded_server.rb +47 -0
  42. data/lib/thrift/struct.rb +237 -0
  43. data/lib/thrift/struct_union.rb +192 -0
  44. data/lib/thrift/thrift_native.rb +24 -0
  45. data/lib/thrift/transport/base_server_transport.rb +37 -0
  46. data/lib/thrift/transport/base_transport.rb +107 -0
  47. data/lib/thrift/transport/buffered_transport.rb +108 -0
  48. data/lib/thrift/transport/framed_transport.rb +116 -0
  49. data/lib/thrift/transport/http_client_transport.rb +51 -0
  50. data/lib/thrift/transport/io_stream_transport.rb +39 -0
  51. data/lib/thrift/transport/memory_buffer_transport.rb +125 -0
  52. data/lib/thrift/transport/server_socket.rb +63 -0
  53. data/lib/thrift/transport/socket.rb +137 -0
  54. data/lib/thrift/transport/unix_server_socket.rb +60 -0
  55. data/lib/thrift/transport/unix_socket.rb +40 -0
  56. data/lib/thrift/types.rb +101 -0
  57. data/lib/thrift/union.rb +179 -0
  58. data/spec/ThriftSpec.thrift +132 -0
  59. data/spec/base_protocol_spec.rb +160 -0
  60. data/spec/base_transport_spec.rb +351 -0
  61. data/spec/binary_protocol_accelerated_spec.rb +46 -0
  62. data/spec/binary_protocol_spec.rb +61 -0
  63. data/spec/binary_protocol_spec_shared.rb +375 -0
  64. data/spec/client_spec.rb +100 -0
  65. data/spec/compact_protocol_spec.rb +144 -0
  66. data/spec/exception_spec.rb +142 -0
  67. data/spec/http_client_spec.rb +64 -0
  68. data/spec/mongrel_http_server_spec.rb +117 -0
  69. data/spec/nonblocking_server_spec.rb +265 -0
  70. data/spec/processor_spec.rb +83 -0
  71. data/spec/serializer_spec.rb +69 -0
  72. data/spec/server_socket_spec.rb +80 -0
  73. data/spec/server_spec.rb +159 -0
  74. data/spec/socket_spec.rb +61 -0
  75. data/spec/socket_spec_shared.rb +104 -0
  76. data/spec/spec_helper.rb +58 -0
  77. data/spec/struct_spec.rb +295 -0
  78. data/spec/types_spec.rb +116 -0
  79. data/spec/union_spec.rb +193 -0
  80. data/spec/unix_socket_spec.rb +108 -0
  81. metadata +247 -0
@@ -0,0 +1,144 @@
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 File.expand_path("#{File.dirname(__FILE__)}/spec_helper")
21
+
22
+ describe Thrift::CompactProtocol do
23
+ TESTS = {
24
+ :byte => (-127..127).to_a,
25
+ :i16 => (0..14).map {|shift| [1 << shift, -(1 << shift)]}.flatten.sort,
26
+ :i32 => (0..30).map {|shift| [1 << shift, -(1 << shift)]}.flatten.sort,
27
+ :i64 => (0..62).map {|shift| [1 << shift, -(1 << shift)]}.flatten.sort,
28
+ :string => ["", "1", "short", "fourteen123456", "fifteen12345678", "1" * 127, "1" * 3000],
29
+ :binary => ["", "\001", "\001" * 5, "\001" * 14, "\001" * 15, "\001" * 127, "\001" * 3000],
30
+ :double => [0.0, 1.0, -1.0, 1.1, -1.1, 10000000.1, 1.0/0.0, -1.0/0.0],
31
+ :bool => [true, false]
32
+ }
33
+
34
+ it "should encode and decode naked primitives correctly" do
35
+ TESTS.each_pair do |primitive_type, test_values|
36
+ test_values.each do |value|
37
+ # puts "testing #{value}" if primitive_type == :i64
38
+ trans = Thrift::MemoryBufferTransport.new
39
+ proto = Thrift::CompactProtocol.new(trans)
40
+
41
+ proto.send(writer(primitive_type), value)
42
+ # puts "buf: #{trans.inspect_buffer}" if primitive_type == :i64
43
+ read_back = proto.send(reader(primitive_type))
44
+ read_back.should == value
45
+ end
46
+ end
47
+ end
48
+
49
+ it "should encode and decode primitives in fields correctly" do
50
+ TESTS.each_pair do |primitive_type, test_values|
51
+ final_primitive_type = primitive_type == :binary ? :string : primitive_type
52
+ thrift_type = Thrift::Types.const_get(final_primitive_type.to_s.upcase)
53
+ # puts primitive_type
54
+ test_values.each do |value|
55
+ trans = Thrift::MemoryBufferTransport.new
56
+ proto = Thrift::CompactProtocol.new(trans)
57
+
58
+ proto.write_field_begin(nil, thrift_type, 15)
59
+ proto.send(writer(primitive_type), value)
60
+ proto.write_field_end
61
+
62
+ proto = Thrift::CompactProtocol.new(trans)
63
+ name, type, id = proto.read_field_begin
64
+ type.should == thrift_type
65
+ id.should == 15
66
+ read_back = proto.send(reader(primitive_type))
67
+ read_back.should == value
68
+ proto.read_field_end
69
+ end
70
+ end
71
+ end
72
+
73
+ it "should encode and decode a monster struct correctly" do
74
+ trans = Thrift::MemoryBufferTransport.new
75
+ proto = Thrift::CompactProtocol.new(trans)
76
+
77
+ struct = CompactProtoTestStruct.new
78
+ # sets and maps don't hash well... not sure what to do here.
79
+ struct.write(proto)
80
+
81
+ struct2 = CompactProtoTestStruct.new
82
+ struct2.read(proto)
83
+ struct2.should == struct
84
+ end
85
+
86
+ it "should make method calls correctly" do
87
+ client_out_trans = Thrift::MemoryBufferTransport.new
88
+ client_out_proto = Thrift::CompactProtocol.new(client_out_trans)
89
+
90
+ client_in_trans = Thrift::MemoryBufferTransport.new
91
+ client_in_proto = Thrift::CompactProtocol.new(client_in_trans)
92
+
93
+ processor = Srv::Processor.new(JankyHandler.new)
94
+
95
+ client = Srv::Client.new(client_in_proto, client_out_proto)
96
+ client.send_Janky(1)
97
+ # puts client_out_trans.inspect_buffer
98
+ processor.process(client_out_proto, client_in_proto)
99
+ client.recv_Janky.should == 2
100
+ end
101
+
102
+ it "should deal with fields following fields that have non-delta ids" do
103
+ brcp = BreaksRubyCompactProtocol.new(
104
+ :field1 => "blah",
105
+ :field2 => BigFieldIdStruct.new(
106
+ :field1 => "string1",
107
+ :field2 => "string2"),
108
+ :field3 => 3)
109
+ ser = Thrift::Serializer.new(Thrift::CompactProtocolFactory.new)
110
+ bytes = ser.serialize(brcp)
111
+
112
+ deser = Thrift::Deserializer.new(Thrift::CompactProtocolFactory.new)
113
+ brcp2 = BreaksRubyCompactProtocol.new
114
+ deser.deserialize(brcp2, bytes)
115
+ brcp2.should == brcp
116
+ end
117
+
118
+ it "should deserialize an empty map to an empty hash" do
119
+ struct = SingleMapTestStruct.new(:i32_map => {})
120
+ ser = Thrift::Serializer.new(Thrift::CompactProtocolFactory.new)
121
+ bytes = ser.serialize(struct)
122
+
123
+ deser = Thrift::Deserializer.new(Thrift::CompactProtocolFactory.new)
124
+ struct2 = SingleMapTestStruct.new
125
+ deser.deserialize(struct2, bytes)
126
+ struct.should == struct2
127
+ end
128
+
129
+ class JankyHandler
130
+ def Janky(i32arg)
131
+ i32arg * 2
132
+ end
133
+ end
134
+
135
+ def writer(sym)
136
+ sym = sym == :binary ? :string : sym
137
+ "write_#{sym.to_s}"
138
+ end
139
+
140
+ def reader(sym)
141
+ sym = sym == :binary ? :string : sym
142
+ "read_#{sym.to_s}"
143
+ end
144
+ end
@@ -0,0 +1,142 @@
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 File.expand_path("#{File.dirname(__FILE__)}/spec_helper")
21
+
22
+ class ThriftExceptionSpec < Spec::ExampleGroup
23
+ include Thrift
24
+
25
+ describe Exception do
26
+ it "should have an accessible message" do
27
+ e = Exception.new("test message")
28
+ e.message.should == "test message"
29
+ end
30
+ end
31
+
32
+ describe ApplicationException do
33
+ it "should inherit from Thrift::Exception" do
34
+ ApplicationException.superclass.should == Exception
35
+ end
36
+
37
+ it "should have an accessible type and message" do
38
+ e = ApplicationException.new
39
+ e.type.should == ApplicationException::UNKNOWN
40
+ e.message.should be_nil
41
+ e = ApplicationException.new(ApplicationException::UNKNOWN_METHOD, "test message")
42
+ e.type.should == ApplicationException::UNKNOWN_METHOD
43
+ e.message.should == "test message"
44
+ end
45
+
46
+ it "should read a struct off of a protocol" do
47
+ prot = mock("MockProtocol")
48
+ prot.should_receive(:read_struct_begin).ordered
49
+ prot.should_receive(:read_field_begin).exactly(3).times.and_return(
50
+ ["message", Types::STRING, 1],
51
+ ["type", Types::I32, 2],
52
+ [nil, Types::STOP, 0]
53
+ )
54
+ prot.should_receive(:read_string).ordered.and_return "test message"
55
+ prot.should_receive(:read_i32).ordered.and_return ApplicationException::BAD_SEQUENCE_ID
56
+ prot.should_receive(:read_field_end).exactly(2).times
57
+ prot.should_receive(:read_struct_end).ordered
58
+
59
+ e = ApplicationException.new
60
+ e.read(prot)
61
+ e.message.should == "test message"
62
+ e.type.should == ApplicationException::BAD_SEQUENCE_ID
63
+ end
64
+
65
+ it "should skip bad fields when reading a struct" do
66
+ prot = mock("MockProtocol")
67
+ prot.should_receive(:read_struct_begin).ordered
68
+ prot.should_receive(:read_field_begin).exactly(5).times.and_return(
69
+ ["type", Types::I32, 2],
70
+ ["type", Types::STRING, 2],
71
+ ["message", Types::MAP, 1],
72
+ ["message", Types::STRING, 3],
73
+ [nil, Types::STOP, 0]
74
+ )
75
+ prot.should_receive(:read_i32).and_return ApplicationException::INVALID_MESSAGE_TYPE
76
+ prot.should_receive(:skip).with(Types::STRING).twice
77
+ prot.should_receive(:skip).with(Types::MAP)
78
+ prot.should_receive(:read_field_end).exactly(4).times
79
+ prot.should_receive(:read_struct_end).ordered
80
+
81
+ e = ApplicationException.new
82
+ e.read(prot)
83
+ e.message.should be_nil
84
+ e.type.should == ApplicationException::INVALID_MESSAGE_TYPE
85
+ end
86
+
87
+ it "should write a Thrift::ApplicationException struct to the oprot" do
88
+ prot = mock("MockProtocol")
89
+ prot.should_receive(:write_struct_begin).with("Thrift::ApplicationException").ordered
90
+ prot.should_receive(:write_field_begin).with("message", Types::STRING, 1).ordered
91
+ prot.should_receive(:write_string).with("test message").ordered
92
+ prot.should_receive(:write_field_begin).with("type", Types::I32, 2).ordered
93
+ prot.should_receive(:write_i32).with(ApplicationException::UNKNOWN_METHOD).ordered
94
+ prot.should_receive(:write_field_end).twice
95
+ prot.should_receive(:write_field_stop).ordered
96
+ prot.should_receive(:write_struct_end).ordered
97
+
98
+ e = ApplicationException.new(ApplicationException::UNKNOWN_METHOD, "test message")
99
+ e.write(prot)
100
+ end
101
+
102
+ it "should skip nil fields when writing to the oprot" do
103
+ prot = mock("MockProtocol")
104
+ prot.should_receive(:write_struct_begin).with("Thrift::ApplicationException").ordered
105
+ prot.should_receive(:write_field_begin).with("message", Types::STRING, 1).ordered
106
+ prot.should_receive(:write_string).with("test message").ordered
107
+ prot.should_receive(:write_field_end).ordered
108
+ prot.should_receive(:write_field_stop).ordered
109
+ prot.should_receive(:write_struct_end).ordered
110
+
111
+ e = ApplicationException.new(nil, "test message")
112
+ e.write(prot)
113
+
114
+ prot = mock("MockProtocol")
115
+ prot.should_receive(:write_struct_begin).with("Thrift::ApplicationException").ordered
116
+ prot.should_receive(:write_field_begin).with("type", Types::I32, 2).ordered
117
+ prot.should_receive(:write_i32).with(ApplicationException::BAD_SEQUENCE_ID).ordered
118
+ prot.should_receive(:write_field_end).ordered
119
+ prot.should_receive(:write_field_stop).ordered
120
+ prot.should_receive(:write_struct_end).ordered
121
+
122
+ e = ApplicationException.new(ApplicationException::BAD_SEQUENCE_ID)
123
+ e.write(prot)
124
+
125
+ prot = mock("MockProtocol")
126
+ prot.should_receive(:write_struct_begin).with("Thrift::ApplicationException").ordered
127
+ prot.should_receive(:write_field_stop).ordered
128
+ prot.should_receive(:write_struct_end).ordered
129
+
130
+ e = ApplicationException.new(nil)
131
+ e.write(prot)
132
+ end
133
+ end
134
+
135
+ describe ProtocolException do
136
+ it "should have an accessible type" do
137
+ prot = ProtocolException.new(ProtocolException::SIZE_LIMIT, "message")
138
+ prot.type.should == ProtocolException::SIZE_LIMIT
139
+ prot.message.should == "message"
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,64 @@
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 File.expand_path("#{File.dirname(__FILE__)}/spec_helper")
21
+
22
+ class ThriftHTTPClientTransportSpec < Spec::ExampleGroup
23
+ include Thrift
24
+
25
+ describe HTTPClientTransport do
26
+ before(:each) do
27
+ @client = HTTPClientTransport.new("http://my.domain.com/path/to/service?param=value")
28
+ end
29
+
30
+ it "should always be open" do
31
+ @client.should be_open
32
+ @client.close
33
+ @client.should be_open
34
+ end
35
+
36
+ it "should post via HTTP and return the results" do
37
+ @client.write "a test"
38
+ @client.write " frame"
39
+ Net::HTTP.should_receive(:new).with("my.domain.com", 80).and_return do
40
+ mock("Net::HTTP").tee do |http|
41
+ http.should_receive(:use_ssl=).with(false)
42
+ http.should_receive(:post).with("/path/to/service?param=value", "a test frame", {"Content-Type"=>"application/x-thrift"}).and_return([nil, "data"])
43
+ end
44
+ end
45
+ @client.flush
46
+ @client.read(10).should == "data"
47
+ end
48
+
49
+ it "should send custom headers if defined" do
50
+ @client.write "test"
51
+ custom_headers = {"Cookie" => "Foo"}
52
+ headers = {"Content-Type"=>"application/x-thrift"}.merge(custom_headers)
53
+
54
+ @client.add_headers(custom_headers)
55
+ Net::HTTP.should_receive(:new).with("my.domain.com", 80).and_return do
56
+ mock("Net::HTTP").tee do |http|
57
+ http.should_receive(:use_ssl=).with(false)
58
+ http.should_receive(:post).with("/path/to/service?param=value", "test", headers).and_return([nil, "data"])
59
+ end
60
+ end
61
+ @client.flush
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,117 @@
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 File.expand_path("#{File.dirname(__FILE__)}/spec_helper")
21
+ require 'thrift/server/mongrel_http_server'
22
+
23
+ class ThriftHTTPServerSpec < Spec::ExampleGroup
24
+ include Thrift
25
+
26
+ Handler = MongrelHTTPServer::Handler
27
+
28
+ describe MongrelHTTPServer do
29
+ it "should have appropriate defaults" do
30
+ mock_factory = mock("BinaryProtocolFactory")
31
+ mock_proc = mock("Processor")
32
+ BinaryProtocolFactory.should_receive(:new).and_return(mock_factory)
33
+ Mongrel::HttpServer.should_receive(:new).with("0.0.0.0", 80).and_return do
34
+ mock("Mongrel::HttpServer").tee do |mock|
35
+ handler = mock("Handler")
36
+ Handler.should_receive(:new).with(mock_proc, mock_factory).and_return(handler)
37
+ mock.should_receive(:register).with("/", handler)
38
+ end
39
+ end
40
+ MongrelHTTPServer.new(mock_proc)
41
+ end
42
+
43
+ it "should understand :ip, :port, :path, and :protocol_factory" do
44
+ mock_proc = mock("Processor")
45
+ mock_factory = mock("ProtocolFactory")
46
+ Mongrel::HttpServer.should_receive(:new).with("1.2.3.4", 1234).and_return do
47
+ mock("Mongrel::HttpServer").tee do |mock|
48
+ handler = mock("Handler")
49
+ Handler.should_receive(:new).with(mock_proc, mock_factory).and_return(handler)
50
+ mock.should_receive(:register).with("/foo", handler)
51
+ end
52
+ end
53
+ MongrelHTTPServer.new(mock_proc, :ip => "1.2.3.4", :port => 1234, :path => "foo",
54
+ :protocol_factory => mock_factory)
55
+ end
56
+
57
+ it "should serve using Mongrel::HttpServer" do
58
+ BinaryProtocolFactory.stub!(:new)
59
+ Mongrel::HttpServer.should_receive(:new).and_return do
60
+ mock("Mongrel::HttpServer").tee do |mock|
61
+ Handler.stub!(:new)
62
+ mock.stub!(:register)
63
+ mock.should_receive(:run).and_return do
64
+ mock("Mongrel::HttpServer.run").tee do |runner|
65
+ runner.should_receive(:join)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ MongrelHTTPServer.new(nil).serve
71
+ end
72
+ end
73
+
74
+ describe MongrelHTTPServer::Handler do
75
+ before(:each) do
76
+ @processor = mock("Processor")
77
+ @factory = mock("ProtocolFactory")
78
+ @handler = Handler.new(@processor, @factory)
79
+ end
80
+
81
+ it "should return 404 for non-POST requests" do
82
+ request = mock("request", :params => {"REQUEST_METHOD" => "GET"})
83
+ response = mock("response")
84
+ response.should_receive(:start).with(404)
85
+ response.should_not_receive(:start).with(200)
86
+ @handler.process(request, response)
87
+ end
88
+
89
+ it "should serve using application/x-thrift" do
90
+ request = mock("request", :params => {"REQUEST_METHOD" => "POST"}, :body => nil)
91
+ response = mock("response")
92
+ head = mock("head")
93
+ head.should_receive(:[]=).with("Content-Type", "application/x-thrift")
94
+ IOStreamTransport.stub!(:new)
95
+ @factory.stub!(:get_protocol)
96
+ @processor.stub!(:process)
97
+ response.should_receive(:start).with(200).and_yield(head, nil)
98
+ @handler.process(request, response)
99
+ end
100
+
101
+ it "should use the IOStreamTransport" do
102
+ body = mock("body")
103
+ request = mock("request", :params => {"REQUEST_METHOD" => "POST"}, :body => body)
104
+ response = mock("response")
105
+ head = mock("head")
106
+ head.stub!(:[]=)
107
+ out = mock("out")
108
+ protocol = mock("protocol")
109
+ transport = mock("transport")
110
+ IOStreamTransport.should_receive(:new).with(body, out).and_return(transport)
111
+ @factory.should_receive(:get_protocol).with(transport).and_return(protocol)
112
+ @processor.should_receive(:process).with(protocol, protocol)
113
+ response.should_receive(:start).with(200).and_yield(head, out)
114
+ @handler.process(request, response)
115
+ end
116
+ end
117
+ end