blob: 7b74e58aa4c849d0c271d0ee82122b5e649a35aa [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
Roger Meier3bef8c22012-10-06 06:58:00 +000022{$WARN SYMBOL_PLATFORM OFF}
23
Jens Geyer06045cf2013-03-27 20:26:25 +020024{.$DEFINE RunEndless} // activate to interactively stress-test the server stop routines via Ctrl+C
25
Jake Farrell27274222011-11-10 20:32:44 +000026interface
27
28uses
Roger Meier3bef8c22012-10-06 06:58:00 +000029 Windows, SysUtils,
Jake Farrell27274222011-11-10 20:32:44 +000030 Generics.Collections,
31 Thrift.Console,
32 Thrift.Server,
33 Thrift.Transport,
Roger Meier3bef8c22012-10-06 06:58:00 +000034 Thrift.Transport.Pipes,
Jake Farrell27274222011-11-10 20:32:44 +000035 Thrift.Protocol,
36 Thrift.Protocol.JSON,
37 Thrift.Collections,
38 Thrift.Utils,
39 Thrift.Test,
40 Thrift,
41 TestConstants,
42 Contnrs;
43
44type
45 TTestServer = class
46 public
47 type
48
49 ITestHandler = interface( TThriftTest.Iface )
Roger Meier333bbf32012-01-08 21:51:08 +000050 procedure SetServer( const AServer : IServer );
Jens Geyer06045cf2013-03-27 20:26:25 +020051 procedure TestStop;
Jake Farrell27274222011-11-10 20:32:44 +000052 end;
53
54 TTestHandlerImpl = class( TInterfacedObject, ITestHandler )
55 private
56 FServer : IServer;
57 protected
58 procedure testVoid();
Roger Meier333bbf32012-01-08 21:51:08 +000059 function testString(const thing: string): string;
Jake Farrell7ae13e12011-10-18 14:35:26 +000060 function testByte(thing: ShortInt): ShortInt;
61 function testI32(thing: Integer): Integer;
Roger Meier333bbf32012-01-08 21:51:08 +000062 function testI64(const thing: Int64): Int64;
63 function testDouble(const thing: Double): Double;
64 function testStruct(const thing: IXtruct): IXtruct;
65 function testNest(const thing: IXtruct2): IXtruct2;
66 function testMap(const thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
67 function testStringMap(const thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
68 function testSet(const thing: IHashSet<Integer>): IHashSet<Integer>;
69 function testList(const thing: IThriftList<Integer>): IThriftList<Integer>;
Jake Farrell7ae13e12011-10-18 14:35:26 +000070 function testEnum(thing: TNumberz): TNumberz;
Roger Meier333bbf32012-01-08 21:51:08 +000071 function testTypedef(const thing: Int64): Int64;
Jake Farrell7ae13e12011-10-18 14:35:26 +000072 function testMapMap(hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
Roger Meier333bbf32012-01-08 21:51:08 +000073 function testInsanity(const argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
74 function testMulti(arg0: ShortInt; arg1: Integer; const arg2: Int64; const arg3: IThriftDictionary<SmallInt, string>; arg4: TNumberz; const arg5: Int64): IXtruct;
75 procedure testException(const arg: string);
76 function testMultiException(const arg0: string; const arg1: string): IXtruct;
Jake Farrell7ae13e12011-10-18 14:35:26 +000077 procedure testOneway(secondsToSleep: Integer);
Jake Farrell27274222011-11-10 20:32:44 +000078
Jens Geyer06045cf2013-03-27 20:26:25 +020079 procedure TestStop;
Roger Meier333bbf32012-01-08 21:51:08 +000080 procedure SetServer( const AServer : IServer );
Jake Farrell27274222011-11-10 20:32:44 +000081 end;
82
Jens Geyer06045cf2013-03-27 20:26:25 +020083 class procedure LaunchAnonPipeChild( const app : string; const transport : IAnonymousPipeServerTransport);
Roger Meier333bbf32012-01-08 21:51:08 +000084 class procedure Execute( const args: array of string);
Jake Farrell27274222011-11-10 20:32:44 +000085 end;
86
87implementation
88
Jens Geyer06045cf2013-03-27 20:26:25 +020089
90var g_Handler : TTestServer.ITestHandler = nil;
91
92
93function MyConsoleEventHandler( dwCtrlType : DWORD) : BOOL; stdcall;
94// Note that this Handler procedure is called from another thread
95var handler : TTestServer.ITestHandler;
96begin
97 result := TRUE;
98 try
99 case dwCtrlType of
100 CTRL_C_EVENT : Console.WriteLine( 'Ctrl+C pressed');
101 CTRL_BREAK_EVENT : Console.WriteLine( 'Ctrl+Break pressed');
102 CTRL_CLOSE_EVENT : Console.WriteLine( 'Received CloseTask signal');
103 CTRL_LOGOFF_EVENT : Console.WriteLine( 'Received LogOff signal');
104 CTRL_SHUTDOWN_EVENT : Console.WriteLine( 'Received Shutdown signal');
105 else
106 Console.WriteLine( 'Received console event #'+IntToStr(Integer(dwCtrlType)));
107 end;
108
109 handler := g_Handler;
110 if handler <> nil then handler.TestStop;
111
112 except
113 // catch all
114 end;
115end;
116
117
Jake Farrell27274222011-11-10 20:32:44 +0000118{ TTestServer.TTestHandlerImpl }
119
Roger Meier333bbf32012-01-08 21:51:08 +0000120procedure TTestServer.TTestHandlerImpl.SetServer( const AServer: IServer);
Jake Farrell27274222011-11-10 20:32:44 +0000121begin
122 FServer := AServer;
123end;
124
125function TTestServer.TTestHandlerImpl.testByte(thing: ShortInt): ShortInt;
126begin
127 Console.WriteLine('testByte("' + IntToStr( thing) + '")');
128 Result := thing;
129end;
130
Roger Meier333bbf32012-01-08 21:51:08 +0000131function TTestServer.TTestHandlerImpl.testDouble( const thing: Double): Double;
Jake Farrell27274222011-11-10 20:32:44 +0000132begin
133 Console.WriteLine('testDouble("' + FloatToStr( thing ) + '")');
134 Result := thing;
135end;
136
137function TTestServer.TTestHandlerImpl.testEnum(thing: TNumberz): TNumberz;
138begin
139 Console.WriteLine('testEnum(' + IntToStr( Integer( thing)) + ')');
140 Result := thing;
141end;
142
Roger Meier333bbf32012-01-08 21:51:08 +0000143procedure TTestServer.TTestHandlerImpl.testException(const arg: string);
Jake Farrell27274222011-11-10 20:32:44 +0000144begin
145 Console.WriteLine('testException(' + arg + ')');
146 if ( arg = 'Xception') then
147 begin
Roger Meierbb6de7a2012-05-04 23:35:45 +0000148 raise TXception.Create( 1001, arg);
Jake Farrell27274222011-11-10 20:32:44 +0000149 end;
Roger Meierbb6de7a2012-05-04 23:35:45 +0000150
151 if (arg = 'TException') then
152 begin
153 raise TException.Create('');
154 end;
155
156 // else do not throw anything
Jake Farrell27274222011-11-10 20:32:44 +0000157end;
158
159function TTestServer.TTestHandlerImpl.testI32(thing: Integer): Integer;
160begin
161 Console.WriteLine('testI32("' + IntToStr( thing) + '")');
162 Result := thing;
163end;
164
Roger Meier333bbf32012-01-08 21:51:08 +0000165function TTestServer.TTestHandlerImpl.testI64( const thing: Int64): Int64;
Jake Farrell27274222011-11-10 20:32:44 +0000166begin
167 Console.WriteLine('testI64("' + IntToStr( thing) + '")');
168 Result := thing;
169end;
170
171function TTestServer.TTestHandlerImpl.testInsanity(
Roger Meier333bbf32012-01-08 21:51:08 +0000172 const argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
Jake Farrell27274222011-11-10 20:32:44 +0000173var
174 hello, goodbye : IXtruct;
175 crazy : IInsanity;
176 looney : IInsanity;
177 first_map : IThriftDictionary<TNumberz, IInsanity>;
178 second_map : IThriftDictionary<TNumberz, IInsanity>;
179 insane : IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
180
181begin
182
183 Console.WriteLine('testInsanity()');
184 hello := TXtructImpl.Create;
Roger Meierbb6de7a2012-05-04 23:35:45 +0000185 hello.String_thing := 'Hello2';
Jake Farrell27274222011-11-10 20:32:44 +0000186 hello.Byte_thing := 2;
187 hello.I32_thing := 2;
188 hello.I64_thing := 2;
189
190 goodbye := TXtructImpl.Create;
191 goodbye.String_thing := 'Goodbye4';
192 goodbye.Byte_thing := 4;
193 goodbye.I32_thing := 4;
194 goodbye.I64_thing := 4;
195
196 crazy := TInsanityImpl.Create;
197 crazy.UserMap := TThriftDictionaryImpl<TNumberz, Int64>.Create;
198 crazy.UserMap.AddOrSetValue( TNumberz.EIGHT, 8);
199 crazy.Xtructs := TThriftListImpl<IXtruct>.Create;
200 crazy.Xtructs.Add(goodbye);
201
202 looney := TInsanityImpl.Create;
203 crazy.UserMap.AddOrSetValue( TNumberz.FIVE, 5);
204 crazy.Xtructs.Add(hello);
205
206 first_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
207 second_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
208
Roger Meierbb6de7a2012-05-04 23:35:45 +0000209 first_map.AddOrSetValue( TNumberz.TWO, crazy);
Jake Farrell27274222011-11-10 20:32:44 +0000210 first_map.AddOrSetValue( TNumberz.THREE, crazy);
211
212 second_map.AddOrSetValue( TNumberz.SIX, looney);
213
214 insane := TThriftDictionaryImpl<Int64, IThriftDictionary<TNumberz, IInsanity>>.Create;
215
216 insane.AddOrSetValue( 1, first_map);
217 insane.AddOrSetValue( 2, second_map);
218
219 Result := insane;
220end;
221
222function TTestServer.TTestHandlerImpl.testList(
Roger Meier333bbf32012-01-08 21:51:08 +0000223 const thing: IThriftList<Integer>): IThriftList<Integer>;
Jake Farrell27274222011-11-10 20:32:44 +0000224var
225 first : Boolean;
226 elem : Integer;
227begin
228 Console.Write('testList({');
229 first := True;
230 for elem in thing do
231 begin
232 if first then
233 begin
234 first := False;
235 end else
236 begin
237 Console.Write(', ');
238 end;
239 Console.Write( IntToStr( elem));
240 end;
241 Console.WriteLine('})');
242 Result := thing;
243end;
244
245function TTestServer.TTestHandlerImpl.testMap(
Roger Meier333bbf32012-01-08 21:51:08 +0000246 const thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
Jake Farrell27274222011-11-10 20:32:44 +0000247var
248 first : Boolean;
249 key : Integer;
250begin
251 Console.Write('testMap({');
252 first := True;
253 for key in thing.Keys do
254 begin
255 if (first) then
256 begin
257 first := false;
258 end else
259 begin
260 Console.Write(', ');
261 end;
262 Console.Write(IntToStr(key) + ' => ' + IntToStr( thing[key]));
263 end;
264 Console.WriteLine('})');
265 Result := thing;
266end;
267
268function TTestServer.TTestHandlerImpl.TestMapMap(
269 hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
270var
271 mapmap : IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
272 pos : IThriftDictionary<Integer, Integer>;
273 neg : IThriftDictionary<Integer, Integer>;
274 i : Integer;
275begin
276 Console.WriteLine('testMapMap(' + IntToStr( hello) + ')');
277 mapmap := TThriftDictionaryImpl<Integer, IThriftDictionary<Integer, Integer>>.Create;
278 pos := TThriftDictionaryImpl<Integer, Integer>.Create;
279 neg := TThriftDictionaryImpl<Integer, Integer>.Create;
280
281 for i := 1 to 4 do
282 begin
283 pos.AddOrSetValue( i, i);
284 neg.AddOrSetValue( -i, -i);
285 end;
286
287 mapmap.AddOrSetValue(4, pos);
288 mapmap.AddOrSetValue( -4, neg);
289
290 Result := mapmap;
291end;
292
293function TTestServer.TTestHandlerImpl.testMulti(arg0: ShortInt; arg1: Integer;
Roger Meier333bbf32012-01-08 21:51:08 +0000294 const arg2: Int64; const arg3: IThriftDictionary<SmallInt, string>;
295 arg4: TNumberz; const arg5: Int64): IXtruct;
Jake Farrell27274222011-11-10 20:32:44 +0000296var
297 hello : IXtruct;
298begin
299 Console.WriteLine('testMulti()');
300 hello := TXtructImpl.Create;
301 hello.String_thing := 'Hello2';
302 hello.Byte_thing := arg0;
303 hello.I32_thing := arg1;
304 hello.I64_thing := arg2;
305 Result := hello;
306end;
307
Roger Meier333bbf32012-01-08 21:51:08 +0000308function TTestServer.TTestHandlerImpl.testMultiException( const arg0, arg1: string): IXtruct;
Jake Farrell27274222011-11-10 20:32:44 +0000309var
Jake Farrell27274222011-11-10 20:32:44 +0000310 x2 : TXception2;
311begin
312 Console.WriteLine('testMultiException(' + arg0 + ', ' + arg1 + ')');
313 if ( arg0 = 'Xception') then
314 begin
Jake Farrell343c61d2011-12-09 02:29:56 +0000315 raise TXception.Create( 1001, 'This is an Xception'); // test the new rich CTOR
Jake Farrell27274222011-11-10 20:32:44 +0000316 end else
317 if ( arg0 = 'Xception2') then
318 begin
Jake Farrell343c61d2011-12-09 02:29:56 +0000319 x2 := TXception2.Create; // the old way still works too?
Jake Farrell27274222011-11-10 20:32:44 +0000320 x2.ErrorCode := 2002;
321 x2.Struct_thing := TXtructImpl.Create;
322 x2.Struct_thing.String_thing := 'This is an Xception2';
Jake Farrellac102562011-11-23 14:30:41 +0000323 x2.UpdateMessageProperty;
Jake Farrell27274222011-11-10 20:32:44 +0000324 raise x2;
325 end;
326
327 Result := TXtructImpl.Create;
328 Result.String_thing := arg1;
329end;
330
Roger Meier333bbf32012-01-08 21:51:08 +0000331function TTestServer.TTestHandlerImpl.testNest( const thing: IXtruct2): IXtruct2;
Jake Farrell27274222011-11-10 20:32:44 +0000332var
333 temp : IXtruct;
334begin
335 temp := thing.Struct_thing;
336 Console.WriteLine('testNest({' +
337 IntToStr( thing.Byte_thing) + ', {' +
338 '"' + temp.String_thing + '", ' +
339 IntToStr( temp.Byte_thing) + ', ' +
340 IntToStr( temp.I32_thing) + ', ' +
341 IntToStr( temp.I64_thing) + '}, ' +
342 IntToStr( temp.I32_thing) + '})');
343 Result := thing;
344end;
345
346procedure TTestServer.TTestHandlerImpl.testOneway(secondsToSleep: Integer);
347begin
348 Console.WriteLine('testOneway(' + IntToStr( secondsToSleep )+ '), sleeping...');
349 Sleep(secondsToSleep * 1000);
350 Console.WriteLine('testOneway finished');
351end;
352
353function TTestServer.TTestHandlerImpl.testSet(
Roger Meier333bbf32012-01-08 21:51:08 +0000354 const thing: IHashSet<Integer>):IHashSet<Integer>;
Jake Farrell27274222011-11-10 20:32:44 +0000355var
356 first : Boolean;
357 elem : Integer;
358begin
359 Console.Write('testSet({');
360 first := True;
361
362 for elem in thing do
363 begin
364 if first then
365 begin
366 first := False;
367 end else
368 begin
369 Console.Write( ', ');
370 end;
371 Console.Write( IntToStr( elem));
372 end;
373 Console.WriteLine('})');
374 Result := thing;
375end;
376
377procedure TTestServer.TTestHandlerImpl.testStop;
378begin
379 if FServer <> nil then
380 begin
381 FServer.Stop;
382 end;
383end;
384
Roger Meier333bbf32012-01-08 21:51:08 +0000385function TTestServer.TTestHandlerImpl.testString( const thing: string): string;
Jake Farrell27274222011-11-10 20:32:44 +0000386begin
387 Console.WriteLine('teststring("' + thing + '")');
388 Result := thing;
389end;
390
391function TTestServer.TTestHandlerImpl.testStringMap(
Roger Meier333bbf32012-01-08 21:51:08 +0000392 const thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
Roger Meierbb6de7a2012-05-04 23:35:45 +0000393var
394 first : Boolean;
395 key : string;
Jake Farrell27274222011-11-10 20:32:44 +0000396begin
Roger Meierbb6de7a2012-05-04 23:35:45 +0000397 Console.Write('testStringMap({');
398 first := True;
399 for key in thing.Keys do
400 begin
401 if (first) then
402 begin
403 first := false;
404 end else
405 begin
406 Console.Write(', ');
407 end;
408 Console.Write(key + ' => ' + thing[key]);
409 end;
410 Console.WriteLine('})');
411 Result := thing;
Jake Farrell27274222011-11-10 20:32:44 +0000412end;
413
Roger Meier333bbf32012-01-08 21:51:08 +0000414function TTestServer.TTestHandlerImpl.testTypedef( const thing: Int64): Int64;
Jake Farrell27274222011-11-10 20:32:44 +0000415begin
416 Console.WriteLine('testTypedef(' + IntToStr( thing) + ')');
417 Result := thing;
418end;
419
420procedure TTestServer.TTestHandlerImpl.TestVoid;
421begin
422 Console.WriteLine('testVoid()');
423end;
424
Roger Meier333bbf32012-01-08 21:51:08 +0000425function TTestServer.TTestHandlerImpl.testStruct( const thing: IXtruct): IXtruct;
Jake Farrell27274222011-11-10 20:32:44 +0000426begin
427 Console.WriteLine('testStruct({' +
428 '"' + thing.String_thing + '", ' +
429 IntToStr( thing.Byte_thing) + ', ' +
430 IntToStr( thing.I32_thing) + ', ' +
431 IntToStr( thing.I64_thing));
432 Result := thing;
433end;
434
Roger Meier3bef8c22012-10-06 06:58:00 +0000435
Jake Farrell27274222011-11-10 20:32:44 +0000436{ TTestServer }
437
Roger Meier3bef8c22012-10-06 06:58:00 +0000438
Jens Geyer06045cf2013-03-27 20:26:25 +0200439class procedure TTestServer.LaunchAnonPipeChild( const app : string; const transport : IAnonymousPipeServerTransport);
Roger Meier3bef8c22012-10-06 06:58:00 +0000440//Launch child process and pass R/W anonymous pipe handles on cmd line.
441//This is a simple example and does not include elevation or other
442//advanced features.
443var pi : PROCESS_INFORMATION;
444 si : STARTUPINFO;
445 sArg, sHandles, sCmdLine : string;
446 i : Integer;
447begin
448 GetStartupInfo( si); //set startupinfo for the spawned process
449
450 // preformat handles args
451 sHandles := Format( '%d %d',
452 [ Integer(transport.ClientAnonRead),
453 Integer(transport.ClientAnonWrite)]);
454
455 // pass all settings to client
456 sCmdLine := app;
457 for i := 1 to ParamCount do begin
458 sArg := ParamStr(i);
459
460 // add anonymous handles and quote strings where appropriate
461 if sArg = '-anon'
462 then sArg := sArg +' '+ sHandles
463 else begin
464 if Pos(' ',sArg) > 0
465 then sArg := '"'+sArg+'"';
466 end;;
467
468 sCmdLine := sCmdLine +' '+ sArg;
469 end;
470
471 // spawn the child process
472 Console.WriteLine('Starting client '+sCmdLine);
473 Win32Check( CreateProcess( nil, PChar(sCmdLine), nil,nil,TRUE,0,nil,nil,si,pi));
474
475 CloseHandle( pi.hThread);
476 CloseHandle( pi.hProcess);
477end;
478
479
Roger Meier333bbf32012-01-08 21:51:08 +0000480class procedure TTestServer.Execute( const args: array of string);
Jake Farrell27274222011-11-10 20:32:44 +0000481var
482 UseBufferedSockets : Boolean;
483 UseFramed : Boolean;
484 Port : Integer;
Roger Meier3bef8c22012-10-06 06:58:00 +0000485 AnonPipe : Boolean;
486 sPipeName : string;
Jake Farrell27274222011-11-10 20:32:44 +0000487 testHandler : ITestHandler;
488 testProcessor : IProcessor;
Roger Meier3bef8c22012-10-06 06:58:00 +0000489 ServerTrans : IServerTransport;
Jake Farrell27274222011-11-10 20:32:44 +0000490 ServerEngine : IServer;
Jens Geyer06045cf2013-03-27 20:26:25 +0200491 anonymouspipe : IAnonymousPipeServerTransport;
492 namedpipe : INamedPipeServerTransport;
Jake Farrell27274222011-11-10 20:32:44 +0000493 TransportFactory : ITransportFactory;
494 ProtocolFactory : IProtocolFactory;
495 i : Integer;
496 s : string;
497 protType, p : TKnownProtocol;
Jens Geyer0b20cc82013-03-07 20:47:01 +0100498const
499 // pipe timeouts to be used
500 DEBUG_TIMEOUT = 30 * 1000;
501 RELEASE_TIMEOUT = 0; // server-side default
502 TIMEOUT = RELEASE_TIMEOUT;
Jake Farrell27274222011-11-10 20:32:44 +0000503begin
504 try
505 UseBufferedSockets := False;
506 UseFramed := False;
Roger Meier3bef8c22012-10-06 06:58:00 +0000507 AnonPipe := FALSE;
Jake Farrell27274222011-11-10 20:32:44 +0000508 protType := prot_Binary;
509 Port := 9090;
Roger Meier3bef8c22012-10-06 06:58:00 +0000510 sPipeName := '';
Jake Farrell27274222011-11-10 20:32:44 +0000511
512 i := 0;
513 while ( i < Length(args) ) do begin
514 s := args[i];
515 Inc(i);
516
517 if StrToIntDef( s, -1) > 0 then
518 begin
519 Port := StrToIntDef( s, Port);
Roger Meier3bef8c22012-10-06 06:58:00 +0000520 end
521 else if ( s = 'raw' ) then
Jake Farrell27274222011-11-10 20:32:44 +0000522 begin
523 // as default
Roger Meier3bef8c22012-10-06 06:58:00 +0000524 end
525 else if ( s = 'buffered' ) then
Jake Farrell27274222011-11-10 20:32:44 +0000526 begin
527 UseBufferedSockets := True;
Roger Meier3bef8c22012-10-06 06:58:00 +0000528 end
529 else if ( s = 'framed' ) then
Jake Farrell27274222011-11-10 20:32:44 +0000530 begin
531 UseFramed := True;
Roger Meier3bef8c22012-10-06 06:58:00 +0000532 end
533 else if (s = '-pipe') then
534 begin
535 sPipeName := args[i]; // -pipe <name>
536 Inc( i );
537 end
538 else if (s = '-anon') then
539 begin
540 AnonPipe := TRUE;
541 end
542 else if (s = '-prot') then // -prot JSON|binary
Jake Farrell27274222011-11-10 20:32:44 +0000543 begin
544 s := args[i];
545 Inc( i );
546 for p:= Low(TKnownProtocol) to High(TKnownProtocol) do begin
547 if SameText( s, KNOWN_PROTOCOLS[p]) then begin
548 protType := p;
549 Break;
550 end;
551 end;
552 end else
553 begin
554 // Fall back to the older boolean syntax
555 UseBufferedSockets := StrToBoolDef( args[1], UseBufferedSockets);
556 end
557 end;
558
Roger Meier3bef8c22012-10-06 06:58:00 +0000559
560 Console.WriteLine('Server configuration: ');
561
Jake Farrell27274222011-11-10 20:32:44 +0000562 // create protocol factory, default to BinaryProtocol
563 case protType of
Jens Geyer0b20cc82013-03-07 20:47:01 +0100564 prot_Binary: ProtocolFactory := TBinaryProtocolImpl.TFactory.Create( BINARY_STRICT_READ, BINARY_STRICT_WRITE);
Jake Farrell27274222011-11-10 20:32:44 +0000565 prot_JSON : ProtocolFactory := TJSONProtocolImpl.TFactory.Create;
566 else
567 ASSERT( FALSE); // unhandled case!
Jens Geyer0b20cc82013-03-07 20:47:01 +0100568 ProtocolFactory := TBinaryProtocolImpl.TFactory.Create( BINARY_STRICT_READ, BINARY_STRICT_WRITE);
Jake Farrell27274222011-11-10 20:32:44 +0000569 end;
Roger Meier3bef8c22012-10-06 06:58:00 +0000570 ASSERT( ProtocolFactory <> nil);
571 Console.WriteLine('- '+KNOWN_PROTOCOLS[protType]+' protocol');
Jake Farrell27274222011-11-10 20:32:44 +0000572
Jake Farrell27274222011-11-10 20:32:44 +0000573
Roger Meier3bef8c22012-10-06 06:58:00 +0000574 if sPipeName <> '' then begin
575 Console.WriteLine('- named pipe ('+sPipeName+')');
Jens Geyer06045cf2013-03-27 20:26:25 +0200576 namedpipe := TNamedPipeServerTransportImpl.Create( sPipeName, 4096, PIPE_UNLIMITED_INSTANCES, TIMEOUT);
Roger Meier79655fb2012-10-20 20:59:41 +0000577 servertrans := namedpipe;
Roger Meier3bef8c22012-10-06 06:58:00 +0000578 end
579 else if AnonPipe then begin
580 Console.WriteLine('- anonymous pipes');
Jens Geyer06045cf2013-03-27 20:26:25 +0200581 anonymouspipe := TAnonymousPipeServerTransportImpl.Create;
Roger Meier79655fb2012-10-20 20:59:41 +0000582 servertrans := anonymouspipe;
Roger Meier3bef8c22012-10-06 06:58:00 +0000583 end
584 else begin
585 Console.WriteLine('- sockets (port '+IntToStr(port)+')');
586 if UseBufferedSockets then Console.WriteLine('- buffered sockets');
587 servertrans := TServerSocketImpl.Create( Port, 0, UseBufferedSockets);
588 end;
589 ASSERT( servertrans <> nil);
590
591 if UseFramed then begin
592 Console.WriteLine('- framed transport');
593 TransportFactory := TFramedTransportImpl.TFactory.Create
594 end
595 else begin
596 TransportFactory := TTransportFactoryImpl.Create;
597 end;
598 ASSERT( TransportFactory <> nil);
599
600 testHandler := TTestHandlerImpl.Create;
Jake Farrell27274222011-11-10 20:32:44 +0000601 testProcessor := TThriftTest.TProcessorImpl.Create( testHandler );
Jake Farrell27274222011-11-10 20:32:44 +0000602
603 ServerEngine := TSimpleServer.Create( testProcessor,
Roger Meier3bef8c22012-10-06 06:58:00 +0000604 ServerTrans,
Jake Farrell27274222011-11-10 20:32:44 +0000605 TransportFactory,
606 ProtocolFactory);
607
608 testHandler.SetServer( ServerEngine);
609
Roger Meier3bef8c22012-10-06 06:58:00 +0000610 // start the client now when we have the anon handles, but before the server starts
611 if AnonPipe
Roger Meier79655fb2012-10-20 20:59:41 +0000612 then LaunchAnonPipeChild( ExtractFilePath(ParamStr(0))+'client.exe', anonymouspipe);
Jake Farrell27274222011-11-10 20:32:44 +0000613
Jens Geyer06045cf2013-03-27 20:26:25 +0200614 // install Ctrl+C handler before the server starts
615 g_Handler := testHandler;
616 SetConsoleCtrlHandler( @MyConsoleEventHandler, TRUE);
Roger Meier3bef8c22012-10-06 06:58:00 +0000617
618 Console.WriteLine('');
Jens Geyer06045cf2013-03-27 20:26:25 +0200619 repeat
620 Console.WriteLine('Starting the server ...');
621 serverEngine.Serve;
622 until {$IFDEF RunEndless} FALSE {$ELSE} TRUE {$ENDIF};
623
Jake Farrell27274222011-11-10 20:32:44 +0000624 testHandler.SetServer( nil);
Jens Geyer06045cf2013-03-27 20:26:25 +0200625 g_Handler := nil;
Jake Farrell27274222011-11-10 20:32:44 +0000626
627 except
628 on E: Exception do
629 begin
630 Console.Write( E.Message);
631 end;
632 end;
633 Console.WriteLine( 'done.');
634end;
635
Jens Geyer06045cf2013-03-27 20:26:25 +0200636
Jake Farrell27274222011-11-10 20:32:44 +0000637end.