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