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