blob: dbfa10c939c060a236f404326bdd5c565a18621a [file] [log] [blame]
csharptest71f662c2011-05-20 15:15:34 -05001#region Copyright notice and license
csharptestf1816be2011-05-19 12:01:16 -05002
csharptest71f662c2011-05-20 15:15:34 -05003// Protocol Buffers - Google's data interchange format
4// Copyright 2008 Google Inc. All rights reserved.
5// http://github.com/jskeet/dotnet-protobufs/
6// Original C++/Java/Python code:
7// http://code.google.com/p/protobuf/
8//
9// Redistribution and use in source and binary forms, with or without
10// modification, are permitted provided that the following conditions are
11// met:
12//
13// * Redistributions of source code must retain the above copyright
14// notice, this list of conditions and the following disclaimer.
15// * Redistributions in binary form must reproduce the above
16// copyright notice, this list of conditions and the following disclaimer
17// in the documentation and/or other materials provided with the
18// distribution.
19// * Neither the name of Google Inc. nor the names of its
20// contributors may be used to endorse or promote products derived from
21// this software without specific prior written permission.
22//
23// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35#endregion
36
37using System;
38using Google.ProtocolBuffers.Descriptors;
39using Google.ProtocolBuffers.TestProtos;
40using NUnit.Framework;
41using Rhino.Mocks;
42using Rhino.Mocks.Constraints;
43
44namespace Google.ProtocolBuffers
45{
46 /// <summary>
47 /// Tests for generated service classes.
48 /// TODO(jonskeet): Convert the mocking tests using Rhino.Mocks.
49 /// </summary>
50 [TestFixture]
51 public class ServiceTest
52 {
53 private delegate void Action<T1, T2>(T1 t1, T2 t2);
54
55 private static readonly MethodDescriptor FooDescriptor = TestGenericService.Descriptor.Methods[0];
56 private static readonly MethodDescriptor BarDescriptor = TestGenericService.Descriptor.Methods[1];
57
58 [Test]
59 public void GetRequestPrototype()
60 {
61 TestGenericService service = new TestServiceImpl();
62
63 Assert.AreSame(service.GetRequestPrototype(FooDescriptor), FooRequest.DefaultInstance);
64 Assert.AreSame(service.GetRequestPrototype(BarDescriptor), BarRequest.DefaultInstance);
65 }
66
67 [Test]
68 public void GetResponsePrototype()
69 {
70 TestGenericService service = new TestServiceImpl();
71
72 Assert.AreSame(service.GetResponsePrototype(FooDescriptor), FooResponse.DefaultInstance);
73 Assert.AreSame(service.GetResponsePrototype(BarDescriptor), BarResponse.DefaultInstance);
74 }
75
76 [Test]
77 public void CallMethodFoo()
78 {
79 MockRepository mocks = new MockRepository();
80 FooRequest fooRequest = FooRequest.CreateBuilder().Build();
81 FooResponse fooResponse = FooResponse.CreateBuilder().Build();
82 IRpcController controller = mocks.StrictMock<IRpcController>();
83
84 bool fooCalled = false;
85
86 TestGenericService service = new TestServiceImpl((request, responseAction) =>
87 {
88 Assert.AreSame(fooRequest, request);
89 fooCalled = true;
90 responseAction(fooResponse);
91 }, null, controller);
92
93 bool doneHandlerCalled = false;
94 Action<IMessage> doneHandler = (response =>
95 {
96 Assert.AreSame(fooResponse, response);
97 doneHandlerCalled = true;
98 });
99
100 using (mocks.Record())
101 {
102 // No mock interactions to record
103 }
104
105 service.CallMethod(FooDescriptor, controller, fooRequest, doneHandler);
106
107 Assert.IsTrue(doneHandlerCalled);
108 Assert.IsTrue(fooCalled);
109 mocks.VerifyAll();
110 }
111
112 private delegate void CallFooDelegate(MethodDescriptor descriptor, IRpcController controller,
113 IMessage request, IMessage response, Action<IMessage> doneHandler);
114
115 /// <summary>
116 /// Tests the generated stub handling of Foo. By this stage we're reasonably confident
117 /// that the choice between Foo and Bar is arbitrary, hence the lack of a corresponding Bar
118 /// test.
119 /// </summary>
120 [Test]
121 [Ignore("Crashes Mono - needs further investigation")]
122 public void GeneratedStubFooCall()
123 {
124 FooRequest fooRequest = FooRequest.CreateBuilder().Build();
125 MockRepository mocks = new MockRepository();
126 IRpcChannel mockChannel = mocks.StrictMock<IRpcChannel>();
127 IRpcController mockController = mocks.StrictMock<IRpcController>();
128 TestGenericService service = TestGenericService.CreateStub(mockChannel);
129 Action<FooResponse> doneHandler = mocks.StrictMock<Action<FooResponse>>();
130
131 using (mocks.Record())
132 {
133 // Nasty way of mocking out "the channel calls the done handler".
134 Expect.Call(() => mockChannel.CallMethod(null, null, null, null, null))
135 .IgnoreArguments()
136 .Constraints(Is.Same(FooDescriptor), Is.Same(mockController), Is.Same(fooRequest),
137 Is.Same(FooResponse.DefaultInstance), Is.Anything())
138 .Do((CallFooDelegate) ((p1, p2, p3, response, done) => done(response)));
139 doneHandler(FooResponse.DefaultInstance);
140 }
141
142 service.Foo(mockController, fooRequest, doneHandler);
143
144 mocks.VerifyAll();
145 }
146
147 [Test]
148 public void CallMethodBar()
149 {
150 MockRepository mocks = new MockRepository();
151 BarRequest barRequest = BarRequest.CreateBuilder().Build();
152 BarResponse barResponse = BarResponse.CreateBuilder().Build();
153 IRpcController controller = mocks.StrictMock<IRpcController>();
154
155 bool barCalled = false;
156
157 TestGenericService service = new TestServiceImpl(null, (request, responseAction) =>
158 {
159 Assert.AreSame(barRequest, request);
160 barCalled = true;
161 responseAction(barResponse);
162 }, controller);
163
164 bool doneHandlerCalled = false;
165 Action<IMessage> doneHandler = (response =>
166 {
167 Assert.AreSame(barResponse, response);
168 doneHandlerCalled = true;
169 });
170
171 using (mocks.Record())
172 {
173 // No mock interactions to record
174 }
175
176 service.CallMethod(BarDescriptor, controller, barRequest, doneHandler);
177
178 Assert.IsTrue(doneHandlerCalled);
179 Assert.IsTrue(barCalled);
180 mocks.VerifyAll();
181 }
182
183
184 private class TestServiceImpl : TestGenericService
185 {
186 private readonly Action<FooRequest, Action<FooResponse>> fooHandler;
187 private readonly Action<BarRequest, Action<BarResponse>> barHandler;
188 private readonly IRpcController expectedController;
189
190 internal TestServiceImpl()
191 {
192 }
193
194 internal TestServiceImpl(Action<FooRequest, Action<FooResponse>> fooHandler,
195 Action<BarRequest, Action<BarResponse>> barHandler,
196 IRpcController expectedController)
197 {
198 this.fooHandler = fooHandler;
199 this.barHandler = barHandler;
200 this.expectedController = expectedController;
201 }
202
203 public override void Foo(IRpcController controller, FooRequest request, Action<FooResponse> done)
204 {
205 Assert.AreSame(expectedController, controller);
206 fooHandler(request, done);
207 }
208
209 public override void Bar(IRpcController controller, BarRequest request, Action<BarResponse> done)
210 {
211 Assert.AreSame(expectedController, controller);
212 barHandler(request, done);
213 }
214 }
215 }
216}