blob: a6339562af54e1e1a2128be3e8fd05005da50ad0 [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001#
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#
Jake Farrell89414582011-11-10 00:53:17 +000019require File.expand_path("#{File.dirname(__FILE__)}/spec_helper")
Kevin Clarkccc86582008-06-18 01:09:00 +000020
21class ThriftServerSpec < Spec::ExampleGroup
22 include Thrift
23
Bryan Duxburyd1d15422009-04-04 00:58:03 +000024 describe BaseServer do
25 it "should default to BaseTransportFactory and BinaryProtocolFactory when not specified" do
26 server = BaseServer.new(mock("Processor"), mock("BaseServerTransport"))
27 server.instance_variable_get(:'@transport_factory').should be_an_instance_of(BaseTransportFactory)
28 server.instance_variable_get(:'@protocol_factory').should be_an_instance_of(BinaryProtocolFactory)
Kevin Clarkccc86582008-06-18 01:09:00 +000029 end
30
31 # serve is a noop, so can't test that
32 end
33
34 shared_examples_for "servers" do
35 before(:each) do
36 @processor = mock("Processor")
37 @serverTrans = mock("ServerTransport")
Bryan Duxburyd1d15422009-04-04 00:58:03 +000038 @trans = mock("BaseTransport")
39 @prot = mock("BaseProtocol")
Kevin Clarkccc86582008-06-18 01:09:00 +000040 @client = mock("Client")
41 @server = server_type.new(@processor, @serverTrans, @trans, @prot)
42 end
43 end
44
45 describe SimpleServer do
46 it_should_behave_like "servers"
47
48 def server_type
49 SimpleServer
50 end
51
52 it "should serve in the main thread" do
53 @serverTrans.should_receive(:listen).ordered
54 @serverTrans.should_receive(:accept).exactly(3).times.and_return(@client)
55 @trans.should_receive(:get_transport).exactly(3).times.with(@client).and_return(@trans)
56 @prot.should_receive(:get_protocol).exactly(3).times.with(@trans).and_return(@prot)
57 x = 0
58 @processor.should_receive(:process).exactly(3).times.with(@prot, @prot).and_return do
59 case (x += 1)
Bryan Duxburye3ab50d2009-03-25 21:06:53 +000060 when 1 then raise Thrift::TransportException
61 when 2 then raise Thrift::ProtocolException
62 when 3 then throw :stop
Kevin Clarkccc86582008-06-18 01:09:00 +000063 end
64 end
65 @trans.should_receive(:close).exactly(3).times
66 @serverTrans.should_receive(:close).ordered
67 lambda { @server.serve }.should throw_symbol(:stop)
68 end
69 end
70
71 describe ThreadedServer do
72 it_should_behave_like "servers"
73
74 def server_type
75 ThreadedServer
76 end
77
78 it "should serve using threads" do
79 @serverTrans.should_receive(:listen).ordered
80 @serverTrans.should_receive(:accept).exactly(3).times.and_return(@client)
81 @trans.should_receive(:get_transport).exactly(3).times.with(@client).and_return(@trans)
82 @prot.should_receive(:get_protocol).exactly(3).times.with(@trans).and_return(@prot)
83 Thread.should_receive(:new).with(@prot, @trans).exactly(3).times.and_yield(@prot, @trans)
84 x = 0
85 @processor.should_receive(:process).exactly(3).times.with(@prot, @prot).and_return do
86 case (x += 1)
Bryan Duxburye3ab50d2009-03-25 21:06:53 +000087 when 1 then raise Thrift::TransportException
88 when 2 then raise Thrift::ProtocolException
89 when 3 then throw :stop
Kevin Clarkccc86582008-06-18 01:09:00 +000090 end
91 end
92 @trans.should_receive(:close).exactly(3).times
93 @serverTrans.should_receive(:close).ordered
94 lambda { @server.serve }.should throw_symbol(:stop)
95 end
96 end
97
98 describe ThreadPoolServer do
99 it_should_behave_like "servers"
100
101 def server_type
102 # put this stuff here so it runs before the server is created
103 @threadQ = mock("SizedQueue")
104 SizedQueue.should_receive(:new).with(20).and_return(@threadQ)
105 @excQ = mock("Queue")
106 Queue.should_receive(:new).and_return(@excQ)
107 ThreadPoolServer
108 end
109
110 it "should set up the queues" do
111 @server.instance_variable_get(:'@thread_q').should be(@threadQ)
112 @server.instance_variable_get(:'@exception_q').should be(@excQ)
113 end
114
115 it "should serve inside a thread" do
116 Thread.should_receive(:new).and_return do |block|
117 @server.should_receive(:serve)
118 block.call
119 @server.rspec_verify
120 end
121 @excQ.should_receive(:pop).and_throw(:popped)
122 lambda { @server.rescuable_serve }.should throw_symbol(:popped)
123 end
124
125 it "should avoid running the server twice when retrying rescuable_serve" do
126 Thread.should_receive(:new).and_return do |block|
127 @server.should_receive(:serve)
128 block.call
129 @server.rspec_verify
130 end
131 @excQ.should_receive(:pop).twice.and_throw(:popped)
132 lambda { @server.rescuable_serve }.should throw_symbol(:popped)
133 lambda { @server.rescuable_serve }.should throw_symbol(:popped)
134 end
135
136 it "should serve using a thread pool" do
137 @serverTrans.should_receive(:listen).ordered
138 @threadQ.should_receive(:push).with(:token)
139 @threadQ.should_receive(:pop)
140 Thread.should_receive(:new).and_yield
141 @serverTrans.should_receive(:accept).exactly(3).times.and_return(@client)
142 @trans.should_receive(:get_transport).exactly(3).times.and_return(@trans)
143 @prot.should_receive(:get_protocol).exactly(3).times.and_return(@prot)
144 x = 0
145 error = RuntimeError.new("Stopped")
146 @processor.should_receive(:process).exactly(3).times.with(@prot, @prot).and_return do
147 case (x += 1)
Bryan Duxburye3ab50d2009-03-25 21:06:53 +0000148 when 1 then raise Thrift::TransportException
149 when 2 then raise Thrift::ProtocolException
150 when 3 then raise error
Kevin Clarkccc86582008-06-18 01:09:00 +0000151 end
152 end
153 @trans.should_receive(:close).exactly(3).times
154 @excQ.should_receive(:push).with(error).and_throw(:stop)
155 @serverTrans.should_receive(:close)
156 lambda { @server.serve }.should throw_symbol(:stop)
157 end
158 end
159end