blob: b8b4d725d325cb95d75eb7c9bb8884027ce20d92 [file] [log] [blame]
Jake Farrell27274222011-11-10 20:32:44 +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
20unit TestServer;
21
22interface
23
24uses
25 SysUtils,
26 Generics.Collections,
27 Thrift.Console,
28 Thrift.Server,
29 Thrift.Transport,
30 Thrift.Protocol,
31 Thrift.Protocol.JSON,
32 Thrift.Collections,
33 Thrift.Utils,
34 Thrift.Test,
35 Thrift,
36 TestConstants,
37 Contnrs;
38
39type
40 TTestServer = class
41 public
42 type
43
44 ITestHandler = interface( TThriftTest.Iface )
Roger Meier333bbf32012-01-08 21:51:08 +000045 procedure SetServer( const AServer : IServer );
Jake Farrell27274222011-11-10 20:32:44 +000046 end;
47
48 TTestHandlerImpl = class( TInterfacedObject, ITestHandler )
49 private
50 FServer : IServer;
51 protected
52 procedure testVoid();
Roger Meier333bbf32012-01-08 21:51:08 +000053 function testString(const thing: string): string;
Jake Farrell7ae13e12011-10-18 14:35:26 +000054 function testByte(thing: ShortInt): ShortInt;
55 function testI32(thing: Integer): Integer;
Roger Meier333bbf32012-01-08 21:51:08 +000056 function testI64(const thing: Int64): Int64;
57 function testDouble(const thing: Double): Double;
58 function testStruct(const thing: IXtruct): IXtruct;
59 function testNest(const thing: IXtruct2): IXtruct2;
60 function testMap(const thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
61 function testStringMap(const thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
62 function testSet(const thing: IHashSet<Integer>): IHashSet<Integer>;
63 function testList(const thing: IThriftList<Integer>): IThriftList<Integer>;
Jake Farrell7ae13e12011-10-18 14:35:26 +000064 function testEnum(thing: TNumberz): TNumberz;
Roger Meier333bbf32012-01-08 21:51:08 +000065 function testTypedef(const thing: Int64): Int64;
Jake Farrell7ae13e12011-10-18 14:35:26 +000066 function testMapMap(hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
Roger Meier333bbf32012-01-08 21:51:08 +000067 function testInsanity(const argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
68 function testMulti(arg0: ShortInt; arg1: Integer; const arg2: Int64; const arg3: IThriftDictionary<SmallInt, string>; arg4: TNumberz; const arg5: Int64): IXtruct;
69 procedure testException(const arg: string);
70 function testMultiException(const arg0: string; const arg1: string): IXtruct;
Jake Farrell7ae13e12011-10-18 14:35:26 +000071 procedure testOneway(secondsToSleep: Integer);
Jake Farrell27274222011-11-10 20:32:44 +000072
73 procedure testStop;
74
Roger Meier333bbf32012-01-08 21:51:08 +000075 procedure SetServer( const AServer : IServer );
Jake Farrell27274222011-11-10 20:32:44 +000076 end;
77
Roger Meier333bbf32012-01-08 21:51:08 +000078 class procedure Execute( const args: array of string);
Jake Farrell27274222011-11-10 20:32:44 +000079 end;
80
81implementation
82
83{ TTestServer.TTestHandlerImpl }
84
Roger Meier333bbf32012-01-08 21:51:08 +000085procedure TTestServer.TTestHandlerImpl.SetServer( const AServer: IServer);
Jake Farrell27274222011-11-10 20:32:44 +000086begin
87 FServer := AServer;
88end;
89
90function TTestServer.TTestHandlerImpl.testByte(thing: ShortInt): ShortInt;
91begin
92 Console.WriteLine('testByte("' + IntToStr( thing) + '")');
93 Result := thing;
94end;
95
Roger Meier333bbf32012-01-08 21:51:08 +000096function TTestServer.TTestHandlerImpl.testDouble( const thing: Double): Double;
Jake Farrell27274222011-11-10 20:32:44 +000097begin
98 Console.WriteLine('testDouble("' + FloatToStr( thing ) + '")');
99 Result := thing;
100end;
101
102function TTestServer.TTestHandlerImpl.testEnum(thing: TNumberz): TNumberz;
103begin
104 Console.WriteLine('testEnum(' + IntToStr( Integer( thing)) + ')');
105 Result := thing;
106end;
107
Roger Meier333bbf32012-01-08 21:51:08 +0000108procedure TTestServer.TTestHandlerImpl.testException(const arg: string);
Jake Farrell27274222011-11-10 20:32:44 +0000109begin
110 Console.WriteLine('testException(' + arg + ')');
111 if ( arg = 'Xception') then
112 begin
Jake Farrell343c61d2011-12-09 02:29:56 +0000113 raise TXception.Create( 1001, 'This is an Xception');
Jake Farrell27274222011-11-10 20:32:44 +0000114 end;
115end;
116
117function TTestServer.TTestHandlerImpl.testI32(thing: Integer): Integer;
118begin
119 Console.WriteLine('testI32("' + IntToStr( thing) + '")');
120 Result := thing;
121end;
122
Roger Meier333bbf32012-01-08 21:51:08 +0000123function TTestServer.TTestHandlerImpl.testI64( const thing: Int64): Int64;
Jake Farrell27274222011-11-10 20:32:44 +0000124begin
125 Console.WriteLine('testI64("' + IntToStr( thing) + '")');
126 Result := thing;
127end;
128
129function TTestServer.TTestHandlerImpl.testInsanity(
Roger Meier333bbf32012-01-08 21:51:08 +0000130 const argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
Jake Farrell27274222011-11-10 20:32:44 +0000131var
132 hello, goodbye : IXtruct;
133 crazy : IInsanity;
134 looney : IInsanity;
135 first_map : IThriftDictionary<TNumberz, IInsanity>;
136 second_map : IThriftDictionary<TNumberz, IInsanity>;
137 insane : IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
138
139begin
140
141 Console.WriteLine('testInsanity()');
142 hello := TXtructImpl.Create;
143 hello.String_thing := 'hello';
144 hello.Byte_thing := 2;
145 hello.I32_thing := 2;
146 hello.I64_thing := 2;
147
148 goodbye := TXtructImpl.Create;
149 goodbye.String_thing := 'Goodbye4';
150 goodbye.Byte_thing := 4;
151 goodbye.I32_thing := 4;
152 goodbye.I64_thing := 4;
153
154 crazy := TInsanityImpl.Create;
155 crazy.UserMap := TThriftDictionaryImpl<TNumberz, Int64>.Create;
156 crazy.UserMap.AddOrSetValue( TNumberz.EIGHT, 8);
157 crazy.Xtructs := TThriftListImpl<IXtruct>.Create;
158 crazy.Xtructs.Add(goodbye);
159
160 looney := TInsanityImpl.Create;
161 crazy.UserMap.AddOrSetValue( TNumberz.FIVE, 5);
162 crazy.Xtructs.Add(hello);
163
164 first_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
165 second_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
166
167 first_map.AddOrSetValue( TNumberz.SIX, crazy);
168 first_map.AddOrSetValue( TNumberz.THREE, crazy);
169
170 second_map.AddOrSetValue( TNumberz.SIX, looney);
171
172 insane := TThriftDictionaryImpl<Int64, IThriftDictionary<TNumberz, IInsanity>>.Create;
173
174 insane.AddOrSetValue( 1, first_map);
175 insane.AddOrSetValue( 2, second_map);
176
177 Result := insane;
178end;
179
180function TTestServer.TTestHandlerImpl.testList(
Roger Meier333bbf32012-01-08 21:51:08 +0000181 const thing: IThriftList<Integer>): IThriftList<Integer>;
Jake Farrell27274222011-11-10 20:32:44 +0000182var
183 first : Boolean;
184 elem : Integer;
185begin
186 Console.Write('testList({');
187 first := True;
188 for elem in thing do
189 begin
190 if first then
191 begin
192 first := False;
193 end else
194 begin
195 Console.Write(', ');
196 end;
197 Console.Write( IntToStr( elem));
198 end;
199 Console.WriteLine('})');
200 Result := thing;
201end;
202
203function TTestServer.TTestHandlerImpl.testMap(
Roger Meier333bbf32012-01-08 21:51:08 +0000204 const thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
Jake Farrell27274222011-11-10 20:32:44 +0000205var
206 first : Boolean;
207 key : Integer;
208begin
209 Console.Write('testMap({');
210 first := True;
211 for key in thing.Keys do
212 begin
213 if (first) then
214 begin
215 first := false;
216 end else
217 begin
218 Console.Write(', ');
219 end;
220 Console.Write(IntToStr(key) + ' => ' + IntToStr( thing[key]));
221 end;
222 Console.WriteLine('})');
223 Result := thing;
224end;
225
226function TTestServer.TTestHandlerImpl.TestMapMap(
227 hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
228var
229 mapmap : IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
230 pos : IThriftDictionary<Integer, Integer>;
231 neg : IThriftDictionary<Integer, Integer>;
232 i : Integer;
233begin
234 Console.WriteLine('testMapMap(' + IntToStr( hello) + ')');
235 mapmap := TThriftDictionaryImpl<Integer, IThriftDictionary<Integer, Integer>>.Create;
236 pos := TThriftDictionaryImpl<Integer, Integer>.Create;
237 neg := TThriftDictionaryImpl<Integer, Integer>.Create;
238
239 for i := 1 to 4 do
240 begin
241 pos.AddOrSetValue( i, i);
242 neg.AddOrSetValue( -i, -i);
243 end;
244
245 mapmap.AddOrSetValue(4, pos);
246 mapmap.AddOrSetValue( -4, neg);
247
248 Result := mapmap;
249end;
250
251function TTestServer.TTestHandlerImpl.testMulti(arg0: ShortInt; arg1: Integer;
Roger Meier333bbf32012-01-08 21:51:08 +0000252 const arg2: Int64; const arg3: IThriftDictionary<SmallInt, string>;
253 arg4: TNumberz; const arg5: Int64): IXtruct;
Jake Farrell27274222011-11-10 20:32:44 +0000254var
255 hello : IXtruct;
256begin
257 Console.WriteLine('testMulti()');
258 hello := TXtructImpl.Create;
259 hello.String_thing := 'Hello2';
260 hello.Byte_thing := arg0;
261 hello.I32_thing := arg1;
262 hello.I64_thing := arg2;
263 Result := hello;
264end;
265
Roger Meier333bbf32012-01-08 21:51:08 +0000266function TTestServer.TTestHandlerImpl.testMultiException( const arg0, arg1: string): IXtruct;
Jake Farrell27274222011-11-10 20:32:44 +0000267var
Jake Farrell27274222011-11-10 20:32:44 +0000268 x2 : TXception2;
269begin
270 Console.WriteLine('testMultiException(' + arg0 + ', ' + arg1 + ')');
271 if ( arg0 = 'Xception') then
272 begin
Jake Farrell343c61d2011-12-09 02:29:56 +0000273 raise TXception.Create( 1001, 'This is an Xception'); // test the new rich CTOR
Jake Farrell27274222011-11-10 20:32:44 +0000274 end else
275 if ( arg0 = 'Xception2') then
276 begin
Jake Farrell343c61d2011-12-09 02:29:56 +0000277 x2 := TXception2.Create; // the old way still works too?
Jake Farrell27274222011-11-10 20:32:44 +0000278 x2.ErrorCode := 2002;
279 x2.Struct_thing := TXtructImpl.Create;
280 x2.Struct_thing.String_thing := 'This is an Xception2';
Jake Farrellac102562011-11-23 14:30:41 +0000281 x2.UpdateMessageProperty;
Jake Farrell27274222011-11-10 20:32:44 +0000282 raise x2;
283 end;
284
285 Result := TXtructImpl.Create;
286 Result.String_thing := arg1;
287end;
288
Roger Meier333bbf32012-01-08 21:51:08 +0000289function TTestServer.TTestHandlerImpl.testNest( const thing: IXtruct2): IXtruct2;
Jake Farrell27274222011-11-10 20:32:44 +0000290var
291 temp : IXtruct;
292begin
293 temp := thing.Struct_thing;
294 Console.WriteLine('testNest({' +
295 IntToStr( thing.Byte_thing) + ', {' +
296 '"' + temp.String_thing + '", ' +
297 IntToStr( temp.Byte_thing) + ', ' +
298 IntToStr( temp.I32_thing) + ', ' +
299 IntToStr( temp.I64_thing) + '}, ' +
300 IntToStr( temp.I32_thing) + '})');
301 Result := thing;
302end;
303
304procedure TTestServer.TTestHandlerImpl.testOneway(secondsToSleep: Integer);
305begin
306 Console.WriteLine('testOneway(' + IntToStr( secondsToSleep )+ '), sleeping...');
307 Sleep(secondsToSleep * 1000);
308 Console.WriteLine('testOneway finished');
309end;
310
311function TTestServer.TTestHandlerImpl.testSet(
Roger Meier333bbf32012-01-08 21:51:08 +0000312 const thing: IHashSet<Integer>):IHashSet<Integer>;
Jake Farrell27274222011-11-10 20:32:44 +0000313var
314 first : Boolean;
315 elem : Integer;
316begin
317 Console.Write('testSet({');
318 first := True;
319
320 for elem in thing do
321 begin
322 if first then
323 begin
324 first := False;
325 end else
326 begin
327 Console.Write( ', ');
328 end;
329 Console.Write( IntToStr( elem));
330 end;
331 Console.WriteLine('})');
332 Result := thing;
333end;
334
335procedure TTestServer.TTestHandlerImpl.testStop;
336begin
337 if FServer <> nil then
338 begin
339 FServer.Stop;
340 end;
341end;
342
Roger Meier333bbf32012-01-08 21:51:08 +0000343function TTestServer.TTestHandlerImpl.testString( const thing: string): string;
Jake Farrell27274222011-11-10 20:32:44 +0000344begin
345 Console.WriteLine('teststring("' + thing + '")');
346 Result := thing;
347end;
348
349function TTestServer.TTestHandlerImpl.testStringMap(
Roger Meier333bbf32012-01-08 21:51:08 +0000350 const thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
Jake Farrell27274222011-11-10 20:32:44 +0000351begin
352
353end;
354
Roger Meier333bbf32012-01-08 21:51:08 +0000355function TTestServer.TTestHandlerImpl.testTypedef( const thing: Int64): Int64;
Jake Farrell27274222011-11-10 20:32:44 +0000356begin
357 Console.WriteLine('testTypedef(' + IntToStr( thing) + ')');
358 Result := thing;
359end;
360
361procedure TTestServer.TTestHandlerImpl.TestVoid;
362begin
363 Console.WriteLine('testVoid()');
364end;
365
Roger Meier333bbf32012-01-08 21:51:08 +0000366function TTestServer.TTestHandlerImpl.testStruct( const thing: IXtruct): IXtruct;
Jake Farrell27274222011-11-10 20:32:44 +0000367begin
368 Console.WriteLine('testStruct({' +
369 '"' + thing.String_thing + '", ' +
370 IntToStr( thing.Byte_thing) + ', ' +
371 IntToStr( thing.I32_thing) + ', ' +
372 IntToStr( thing.I64_thing));
373 Result := thing;
374end;
375
376{ TTestServer }
377
Roger Meier333bbf32012-01-08 21:51:08 +0000378class procedure TTestServer.Execute( const args: array of string);
Jake Farrell27274222011-11-10 20:32:44 +0000379var
380 UseBufferedSockets : Boolean;
381 UseFramed : Boolean;
382 Port : Integer;
383 testHandler : ITestHandler;
384 testProcessor : IProcessor;
385 ServerSocket : IServerTransport;
386 ServerEngine : IServer;
387 TransportFactory : ITransportFactory;
388 ProtocolFactory : IProtocolFactory;
389 i : Integer;
390 s : string;
391 protType, p : TKnownProtocol;
392begin
393 try
394 UseBufferedSockets := False;
395 UseFramed := False;
396 protType := prot_Binary;
397 Port := 9090;
398
399 i := 0;
400 while ( i < Length(args) ) do begin
401 s := args[i];
402 Inc(i);
403
404 if StrToIntDef( s, -1) > 0 then
405 begin
406 Port := StrToIntDef( s, Port);
407 end else
408 if ( s = 'raw' ) then
409 begin
410 // as default
411 end else
412 if ( s = 'buffered' ) then
413 begin
414 UseBufferedSockets := True;
415 end else
416 if ( s = 'framed' ) then
417 begin
418 UseFramed := True;
419 end else
420 if (s = '-prot') then // -prot JSON|binary
421 begin
422 s := args[i];
423 Inc( i );
424 for p:= Low(TKnownProtocol) to High(TKnownProtocol) do begin
425 if SameText( s, KNOWN_PROTOCOLS[p]) then begin
426 protType := p;
427 Break;
428 end;
429 end;
430 end else
431 begin
432 // Fall back to the older boolean syntax
433 UseBufferedSockets := StrToBoolDef( args[1], UseBufferedSockets);
434 end
435 end;
436
437 // create protocol factory, default to BinaryProtocol
438 case protType of
439 prot_Binary: ProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
440 prot_JSON : ProtocolFactory := TJSONProtocolImpl.TFactory.Create;
441 else
442 ASSERT( FALSE); // unhandled case!
443 ProtocolFactory := TBinaryProtocolImpl.TFactory.Create;
444 end;
445
446 testHandler := TTestHandlerImpl.Create;
447
448 testProcessor := TThriftTest.TProcessorImpl.Create( testHandler );
449 ServerSocket := TServerSocketImpl.Create( Port, 0, UseBufferedSockets );
450
451 if UseFramed
452 then TransportFactory := TFramedTransportImpl.TFactory.Create
453 else TransportFactory := TTransportFactoryImpl.Create;
454
455 ServerEngine := TSimpleServer.Create( testProcessor,
456 ServerSocket,
457 TransportFactory,
458 ProtocolFactory);
459
460 testHandler.SetServer( ServerEngine);
461
462 Console.WriteLine('Starting the server on port ' + IntToStr( Port) +
463 IfValue(UseBufferedSockets, ' with buffered socket', '') +
464 IfValue(useFramed, ' with framed transport', '') +
465 ' using '+KNOWN_PROTOCOLS[protType]+' protocol' +
466 '...');
467
468 serverEngine.Serve;
469 testHandler.SetServer( nil);
470
471 except
472 on E: Exception do
473 begin
474 Console.Write( E.Message);
475 end;
476 end;
477 Console.WriteLine( 'done.');
478end;
479
480end.