blob: 6aa2dafe1e5e4bf4ce62626a9932c6d719900e1b [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,
Jens Geyer01640402013-09-25 21:12:21 +020042 TestServerEvents,
Jake Farrell27274222011-11-10 20:32:44 +000043 Contnrs;
44
45type
46 TTestServer = class
47 public
48 type
49
50 ITestHandler = interface( TThriftTest.Iface )
Roger Meier333bbf32012-01-08 21:51:08 +000051 procedure SetServer( const AServer : IServer );
Jens Geyer06045cf2013-03-27 20:26:25 +020052 procedure TestStop;
Jake Farrell27274222011-11-10 20:32:44 +000053 end;
54
55 TTestHandlerImpl = class( TInterfacedObject, ITestHandler )
56 private
57 FServer : IServer;
58 protected
59 procedure testVoid();
Roger Meier333bbf32012-01-08 21:51:08 +000060 function testString(const thing: string): string;
Jake Farrell7ae13e12011-10-18 14:35:26 +000061 function testByte(thing: ShortInt): ShortInt;
62 function testI32(thing: Integer): Integer;
Roger Meier333bbf32012-01-08 21:51:08 +000063 function testI64(const thing: Int64): Int64;
64 function testDouble(const thing: Double): Double;
65 function testStruct(const thing: IXtruct): IXtruct;
66 function testNest(const thing: IXtruct2): IXtruct2;
67 function testMap(const thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
68 function testStringMap(const thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
69 function testSet(const thing: IHashSet<Integer>): IHashSet<Integer>;
70 function testList(const thing: IThriftList<Integer>): IThriftList<Integer>;
Jake Farrell7ae13e12011-10-18 14:35:26 +000071 function testEnum(thing: TNumberz): TNumberz;
Roger Meier333bbf32012-01-08 21:51:08 +000072 function testTypedef(const thing: Int64): Int64;
Jake Farrell7ae13e12011-10-18 14:35:26 +000073 function testMapMap(hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
Roger Meier333bbf32012-01-08 21:51:08 +000074 function testInsanity(const argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
75 function testMulti(arg0: ShortInt; arg1: Integer; const arg2: Int64; const arg3: IThriftDictionary<SmallInt, string>; arg4: TNumberz; const arg5: Int64): IXtruct;
76 procedure testException(const arg: string);
77 function testMultiException(const arg0: string; const arg1: string): IXtruct;
Jake Farrell7ae13e12011-10-18 14:35:26 +000078 procedure testOneway(secondsToSleep: Integer);
Jake Farrell27274222011-11-10 20:32:44 +000079
Jens Geyer06045cf2013-03-27 20:26:25 +020080 procedure TestStop;
Roger Meier333bbf32012-01-08 21:51:08 +000081 procedure SetServer( const AServer : IServer );
Jake Farrell27274222011-11-10 20:32:44 +000082 end;
83
Jens Geyer06045cf2013-03-27 20:26:25 +020084 class procedure LaunchAnonPipeChild( const app : string; const transport : IAnonymousPipeServerTransport);
Roger Meier333bbf32012-01-08 21:51:08 +000085 class procedure Execute( const args: array of string);
Jake Farrell27274222011-11-10 20:32:44 +000086 end;
87
88implementation
89
Jens Geyer06045cf2013-03-27 20:26:25 +020090
91var g_Handler : TTestServer.ITestHandler = nil;
92
93
94function MyConsoleEventHandler( dwCtrlType : DWORD) : BOOL; stdcall;
95// Note that this Handler procedure is called from another thread
96var handler : TTestServer.ITestHandler;
97begin
98 result := TRUE;
99 try
100 case dwCtrlType of
101 CTRL_C_EVENT : Console.WriteLine( 'Ctrl+C pressed');
102 CTRL_BREAK_EVENT : Console.WriteLine( 'Ctrl+Break pressed');
103 CTRL_CLOSE_EVENT : Console.WriteLine( 'Received CloseTask signal');
104 CTRL_LOGOFF_EVENT : Console.WriteLine( 'Received LogOff signal');
105 CTRL_SHUTDOWN_EVENT : Console.WriteLine( 'Received Shutdown signal');
106 else
107 Console.WriteLine( 'Received console event #'+IntToStr(Integer(dwCtrlType)));
108 end;
109
110 handler := g_Handler;
111 if handler <> nil then handler.TestStop;
112
113 except
114 // catch all
115 end;
116end;
117
118
Jake Farrell27274222011-11-10 20:32:44 +0000119{ TTestServer.TTestHandlerImpl }
120
Roger Meier333bbf32012-01-08 21:51:08 +0000121procedure TTestServer.TTestHandlerImpl.SetServer( const AServer: IServer);
Jake Farrell27274222011-11-10 20:32:44 +0000122begin
123 FServer := AServer;
124end;
125
126function TTestServer.TTestHandlerImpl.testByte(thing: ShortInt): ShortInt;
127begin
128 Console.WriteLine('testByte("' + IntToStr( thing) + '")');
129 Result := thing;
130end;
131
Roger Meier333bbf32012-01-08 21:51:08 +0000132function TTestServer.TTestHandlerImpl.testDouble( const thing: Double): Double;
Jake Farrell27274222011-11-10 20:32:44 +0000133begin
134 Console.WriteLine('testDouble("' + FloatToStr( thing ) + '")');
135 Result := thing;
136end;
137
138function TTestServer.TTestHandlerImpl.testEnum(thing: TNumberz): TNumberz;
139begin
140 Console.WriteLine('testEnum(' + IntToStr( Integer( thing)) + ')');
141 Result := thing;
142end;
143
Roger Meier333bbf32012-01-08 21:51:08 +0000144procedure TTestServer.TTestHandlerImpl.testException(const arg: string);
Jake Farrell27274222011-11-10 20:32:44 +0000145begin
146 Console.WriteLine('testException(' + arg + ')');
147 if ( arg = 'Xception') then
148 begin
Roger Meierbb6de7a2012-05-04 23:35:45 +0000149 raise TXception.Create( 1001, arg);
Jake Farrell27274222011-11-10 20:32:44 +0000150 end;
Roger Meierbb6de7a2012-05-04 23:35:45 +0000151
152 if (arg = 'TException') then
153 begin
154 raise TException.Create('');
155 end;
156
157 // else do not throw anything
Jake Farrell27274222011-11-10 20:32:44 +0000158end;
159
160function TTestServer.TTestHandlerImpl.testI32(thing: Integer): Integer;
161begin
162 Console.WriteLine('testI32("' + IntToStr( thing) + '")');
163 Result := thing;
164end;
165
Roger Meier333bbf32012-01-08 21:51:08 +0000166function TTestServer.TTestHandlerImpl.testI64( const thing: Int64): Int64;
Jake Farrell27274222011-11-10 20:32:44 +0000167begin
168 Console.WriteLine('testI64("' + IntToStr( thing) + '")');
169 Result := thing;
170end;
171
172function TTestServer.TTestHandlerImpl.testInsanity(
Roger Meier333bbf32012-01-08 21:51:08 +0000173 const argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
Jake Farrell27274222011-11-10 20:32:44 +0000174var
175 hello, goodbye : IXtruct;
176 crazy : IInsanity;
177 looney : IInsanity;
178 first_map : IThriftDictionary<TNumberz, IInsanity>;
179 second_map : IThriftDictionary<TNumberz, IInsanity>;
180 insane : IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
181
182begin
183
184 Console.WriteLine('testInsanity()');
185 hello := TXtructImpl.Create;
Roger Meierbb6de7a2012-05-04 23:35:45 +0000186 hello.String_thing := 'Hello2';
Jake Farrell27274222011-11-10 20:32:44 +0000187 hello.Byte_thing := 2;
188 hello.I32_thing := 2;
189 hello.I64_thing := 2;
190
191 goodbye := TXtructImpl.Create;
192 goodbye.String_thing := 'Goodbye4';
193 goodbye.Byte_thing := 4;
194 goodbye.I32_thing := 4;
195 goodbye.I64_thing := 4;
196
197 crazy := TInsanityImpl.Create;
198 crazy.UserMap := TThriftDictionaryImpl<TNumberz, Int64>.Create;
199 crazy.UserMap.AddOrSetValue( TNumberz.EIGHT, 8);
200 crazy.Xtructs := TThriftListImpl<IXtruct>.Create;
201 crazy.Xtructs.Add(goodbye);
202
203 looney := TInsanityImpl.Create;
204 crazy.UserMap.AddOrSetValue( TNumberz.FIVE, 5);
205 crazy.Xtructs.Add(hello);
206
207 first_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
208 second_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
209
Roger Meierbb6de7a2012-05-04 23:35:45 +0000210 first_map.AddOrSetValue( TNumberz.TWO, crazy);
Jake Farrell27274222011-11-10 20:32:44 +0000211 first_map.AddOrSetValue( TNumberz.THREE, crazy);
212
213 second_map.AddOrSetValue( TNumberz.SIX, looney);
214
215 insane := TThriftDictionaryImpl<Int64, IThriftDictionary<TNumberz, IInsanity>>.Create;
216
217 insane.AddOrSetValue( 1, first_map);
218 insane.AddOrSetValue( 2, second_map);
219
220 Result := insane;
221end;
222
223function TTestServer.TTestHandlerImpl.testList(
Roger Meier333bbf32012-01-08 21:51:08 +0000224 const thing: IThriftList<Integer>): IThriftList<Integer>;
Jake Farrell27274222011-11-10 20:32:44 +0000225var
226 first : Boolean;
227 elem : Integer;
228begin
229 Console.Write('testList({');
230 first := True;
231 for elem in thing do
232 begin
233 if first then
234 begin
235 first := False;
236 end else
237 begin
238 Console.Write(', ');
239 end;
240 Console.Write( IntToStr( elem));
241 end;
242 Console.WriteLine('})');
243 Result := thing;
244end;
245
246function TTestServer.TTestHandlerImpl.testMap(
Roger Meier333bbf32012-01-08 21:51:08 +0000247 const thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
Jake Farrell27274222011-11-10 20:32:44 +0000248var
249 first : Boolean;
250 key : Integer;
251begin
252 Console.Write('testMap({');
253 first := True;
254 for key in thing.Keys do
255 begin
256 if (first) then
257 begin
258 first := false;
259 end else
260 begin
261 Console.Write(', ');
262 end;
263 Console.Write(IntToStr(key) + ' => ' + IntToStr( thing[key]));
264 end;
265 Console.WriteLine('})');
266 Result := thing;
267end;
268
269function TTestServer.TTestHandlerImpl.TestMapMap(
270 hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
271var
272 mapmap : IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
273 pos : IThriftDictionary<Integer, Integer>;
274 neg : IThriftDictionary<Integer, Integer>;
275 i : Integer;
276begin
277 Console.WriteLine('testMapMap(' + IntToStr( hello) + ')');
278 mapmap := TThriftDictionaryImpl<Integer, IThriftDictionary<Integer, Integer>>.Create;
279 pos := TThriftDictionaryImpl<Integer, Integer>.Create;
280 neg := TThriftDictionaryImpl<Integer, Integer>.Create;
281
282 for i := 1 to 4 do
283 begin
284 pos.AddOrSetValue( i, i);
285 neg.AddOrSetValue( -i, -i);
286 end;
287
288 mapmap.AddOrSetValue(4, pos);
289 mapmap.AddOrSetValue( -4, neg);
290
291 Result := mapmap;
292end;
293
294function TTestServer.TTestHandlerImpl.testMulti(arg0: ShortInt; arg1: Integer;
Roger Meier333bbf32012-01-08 21:51:08 +0000295 const arg2: Int64; const arg3: IThriftDictionary<SmallInt, string>;
296 arg4: TNumberz; const arg5: Int64): IXtruct;
Jake Farrell27274222011-11-10 20:32:44 +0000297var
298 hello : IXtruct;
299begin
300 Console.WriteLine('testMulti()');
301 hello := TXtructImpl.Create;
302 hello.String_thing := 'Hello2';
303 hello.Byte_thing := arg0;
304 hello.I32_thing := arg1;
305 hello.I64_thing := arg2;
306 Result := hello;
307end;
308
Roger Meier333bbf32012-01-08 21:51:08 +0000309function TTestServer.TTestHandlerImpl.testMultiException( const arg0, arg1: string): IXtruct;
Jake Farrell27274222011-11-10 20:32:44 +0000310var
Jake Farrell27274222011-11-10 20:32:44 +0000311 x2 : TXception2;
312begin
313 Console.WriteLine('testMultiException(' + arg0 + ', ' + arg1 + ')');
314 if ( arg0 = 'Xception') then
315 begin
Jake Farrell343c61d2011-12-09 02:29:56 +0000316 raise TXception.Create( 1001, 'This is an Xception'); // test the new rich CTOR
Jake Farrell27274222011-11-10 20:32:44 +0000317 end else
318 if ( arg0 = 'Xception2') then
319 begin
Jake Farrell343c61d2011-12-09 02:29:56 +0000320 x2 := TXception2.Create; // the old way still works too?
Jake Farrell27274222011-11-10 20:32:44 +0000321 x2.ErrorCode := 2002;
322 x2.Struct_thing := TXtructImpl.Create;
323 x2.Struct_thing.String_thing := 'This is an Xception2';
Jake Farrellac102562011-11-23 14:30:41 +0000324 x2.UpdateMessageProperty;
Jake Farrell27274222011-11-10 20:32:44 +0000325 raise x2;
326 end;
327
328 Result := TXtructImpl.Create;
329 Result.String_thing := arg1;
330end;
331
Roger Meier333bbf32012-01-08 21:51:08 +0000332function TTestServer.TTestHandlerImpl.testNest( const thing: IXtruct2): IXtruct2;
Jake Farrell27274222011-11-10 20:32:44 +0000333var
334 temp : IXtruct;
335begin
336 temp := thing.Struct_thing;
337 Console.WriteLine('testNest({' +
338 IntToStr( thing.Byte_thing) + ', {' +
339 '"' + temp.String_thing + '", ' +
340 IntToStr( temp.Byte_thing) + ', ' +
341 IntToStr( temp.I32_thing) + ', ' +
342 IntToStr( temp.I64_thing) + '}, ' +
343 IntToStr( temp.I32_thing) + '})');
344 Result := thing;
345end;
346
347procedure TTestServer.TTestHandlerImpl.testOneway(secondsToSleep: Integer);
348begin
349 Console.WriteLine('testOneway(' + IntToStr( secondsToSleep )+ '), sleeping...');
350 Sleep(secondsToSleep * 1000);
351 Console.WriteLine('testOneway finished');
352end;
353
354function TTestServer.TTestHandlerImpl.testSet(
Roger Meier333bbf32012-01-08 21:51:08 +0000355 const thing: IHashSet<Integer>):IHashSet<Integer>;
Jake Farrell27274222011-11-10 20:32:44 +0000356var
357 first : Boolean;
358 elem : Integer;
359begin
360 Console.Write('testSet({');
361 first := True;
362
363 for elem in thing do
364 begin
365 if first then
366 begin
367 first := False;
368 end else
369 begin
370 Console.Write( ', ');
371 end;
372 Console.Write( IntToStr( elem));
373 end;
374 Console.WriteLine('})');
375 Result := thing;
376end;
377
378procedure TTestServer.TTestHandlerImpl.testStop;
379begin
380 if FServer <> nil then
381 begin
382 FServer.Stop;
383 end;
384end;
385
Roger Meier333bbf32012-01-08 21:51:08 +0000386function TTestServer.TTestHandlerImpl.testString( const thing: string): string;
Jake Farrell27274222011-11-10 20:32:44 +0000387begin
388 Console.WriteLine('teststring("' + thing + '")');
389 Result := thing;
390end;
391
392function TTestServer.TTestHandlerImpl.testStringMap(
Roger Meier333bbf32012-01-08 21:51:08 +0000393 const thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
Roger Meierbb6de7a2012-05-04 23:35:45 +0000394var
395 first : Boolean;
396 key : string;
Jake Farrell27274222011-11-10 20:32:44 +0000397begin
Roger Meierbb6de7a2012-05-04 23:35:45 +0000398 Console.Write('testStringMap({');
399 first := True;
400 for key in thing.Keys do
401 begin
402 if (first) then
403 begin
404 first := false;
405 end else
406 begin
407 Console.Write(', ');
408 end;
409 Console.Write(key + ' => ' + thing[key]);
410 end;
411 Console.WriteLine('})');
412 Result := thing;
Jake Farrell27274222011-11-10 20:32:44 +0000413end;
414
Roger Meier333bbf32012-01-08 21:51:08 +0000415function TTestServer.TTestHandlerImpl.testTypedef( const thing: Int64): Int64;
Jake Farrell27274222011-11-10 20:32:44 +0000416begin
417 Console.WriteLine('testTypedef(' + IntToStr( thing) + ')');
418 Result := thing;
419end;
420
421procedure TTestServer.TTestHandlerImpl.TestVoid;
422begin
423 Console.WriteLine('testVoid()');
424end;
425
Roger Meier333bbf32012-01-08 21:51:08 +0000426function TTestServer.TTestHandlerImpl.testStruct( const thing: IXtruct): IXtruct;
Jake Farrell27274222011-11-10 20:32:44 +0000427begin
428 Console.WriteLine('testStruct({' +
429 '"' + thing.String_thing + '", ' +
430 IntToStr( thing.Byte_thing) + ', ' +
431 IntToStr( thing.I32_thing) + ', ' +
432 IntToStr( thing.I64_thing));
433 Result := thing;
434end;
435
Roger Meier3bef8c22012-10-06 06:58:00 +0000436
Jake Farrell27274222011-11-10 20:32:44 +0000437{ TTestServer }
438
Roger Meier3bef8c22012-10-06 06:58:00 +0000439
Jens Geyer06045cf2013-03-27 20:26:25 +0200440class procedure TTestServer.LaunchAnonPipeChild( const app : string; const transport : IAnonymousPipeServerTransport);
Roger Meier3bef8c22012-10-06 06:58:00 +0000441//Launch child process and pass R/W anonymous pipe handles on cmd line.
442//This is a simple example and does not include elevation or other
443//advanced features.
444var pi : PROCESS_INFORMATION;
445 si : STARTUPINFO;
446 sArg, sHandles, sCmdLine : string;
447 i : Integer;
448begin
449 GetStartupInfo( si); //set startupinfo for the spawned process
450
451 // preformat handles args
452 sHandles := Format( '%d %d',
453 [ Integer(transport.ClientAnonRead),
454 Integer(transport.ClientAnonWrite)]);
455
456 // pass all settings to client
457 sCmdLine := app;
458 for i := 1 to ParamCount do begin
459 sArg := ParamStr(i);
460
461 // add anonymous handles and quote strings where appropriate
462 if sArg = '-anon'
463 then sArg := sArg +' '+ sHandles
464 else begin
465 if Pos(' ',sArg) > 0
466 then sArg := '"'+sArg+'"';
467 end;;
468
469 sCmdLine := sCmdLine +' '+ sArg;
470 end;
471
472 // spawn the child process
473 Console.WriteLine('Starting client '+sCmdLine);
474 Win32Check( CreateProcess( nil, PChar(sCmdLine), nil,nil,TRUE,0,nil,nil,si,pi));
475
476 CloseHandle( pi.hThread);
477 CloseHandle( pi.hProcess);
478end;
479
480
Roger Meier333bbf32012-01-08 21:51:08 +0000481class procedure TTestServer.Execute( const args: array of string);
Jake Farrell27274222011-11-10 20:32:44 +0000482var
483 UseBufferedSockets : Boolean;
484 UseFramed : Boolean;
485 Port : Integer;
Jens Geyer01640402013-09-25 21:12:21 +0200486 AnonPipe, ServerEvents : Boolean;
Roger Meier3bef8c22012-10-06 06:58:00 +0000487 sPipeName : string;
Jake Farrell27274222011-11-10 20:32:44 +0000488 testHandler : ITestHandler;
489 testProcessor : IProcessor;
Roger Meier3bef8c22012-10-06 06:58:00 +0000490 ServerTrans : IServerTransport;
Jake Farrell27274222011-11-10 20:32:44 +0000491 ServerEngine : IServer;
Jens Geyer06045cf2013-03-27 20:26:25 +0200492 anonymouspipe : IAnonymousPipeServerTransport;
493 namedpipe : INamedPipeServerTransport;
Jake Farrell27274222011-11-10 20:32:44 +0000494 TransportFactory : ITransportFactory;
495 ProtocolFactory : IProtocolFactory;
496 i : Integer;
497 s : string;
498 protType, p : TKnownProtocol;
Jens Geyer0b20cc82013-03-07 20:47:01 +0100499const
500 // pipe timeouts to be used
501 DEBUG_TIMEOUT = 30 * 1000;
Jens Geyere9651362014-03-20 22:46:17 +0200502 RELEASE_TIMEOUT = DEFAULT_THRIFT_PIPE_TIMEOUT; // server-side default
Jens Geyer0b20cc82013-03-07 20:47:01 +0100503 TIMEOUT = RELEASE_TIMEOUT;
Jake Farrell27274222011-11-10 20:32:44 +0000504begin
505 try
506 UseBufferedSockets := False;
507 UseFramed := False;
Roger Meier3bef8c22012-10-06 06:58:00 +0000508 AnonPipe := FALSE;
Jens Geyer01640402013-09-25 21:12:21 +0200509 ServerEvents := FALSE;
Jake Farrell27274222011-11-10 20:32:44 +0000510 protType := prot_Binary;
511 Port := 9090;
Roger Meier3bef8c22012-10-06 06:58:00 +0000512 sPipeName := '';
Jake Farrell27274222011-11-10 20:32:44 +0000513
514 i := 0;
515 while ( i < Length(args) ) do begin
516 s := args[i];
517 Inc(i);
518
519 if StrToIntDef( s, -1) > 0 then
520 begin
521 Port := StrToIntDef( s, Port);
Roger Meier3bef8c22012-10-06 06:58:00 +0000522 end
523 else if ( s = 'raw' ) then
Jake Farrell27274222011-11-10 20:32:44 +0000524 begin
525 // as default
Roger Meier3bef8c22012-10-06 06:58:00 +0000526 end
527 else if ( s = 'buffered' ) then
Jake Farrell27274222011-11-10 20:32:44 +0000528 begin
529 UseBufferedSockets := True;
Roger Meier3bef8c22012-10-06 06:58:00 +0000530 end
531 else if ( s = 'framed' ) then
Jake Farrell27274222011-11-10 20:32:44 +0000532 begin
533 UseFramed := True;
Roger Meier3bef8c22012-10-06 06:58:00 +0000534 end
535 else if (s = '-pipe') then
536 begin
537 sPipeName := args[i]; // -pipe <name>
538 Inc( i );
539 end
540 else if (s = '-anon') then
541 begin
542 AnonPipe := TRUE;
543 end
544 else if (s = '-prot') then // -prot JSON|binary
Jake Farrell27274222011-11-10 20:32:44 +0000545 begin
546 s := args[i];
547 Inc( i );
548 for p:= Low(TKnownProtocol) to High(TKnownProtocol) do begin
549 if SameText( s, KNOWN_PROTOCOLS[p]) then begin
550 protType := p;
551 Break;
552 end;
553 end;
Jens Geyer01640402013-09-25 21:12:21 +0200554 end
555 else if ( s = '-events' ) then
Jake Farrell27274222011-11-10 20:32:44 +0000556 begin
Jens Geyer01640402013-09-25 21:12:21 +0200557 ServerEvents := True;
558 end
559 else begin
Jake Farrell27274222011-11-10 20:32:44 +0000560 // Fall back to the older boolean syntax
561 UseBufferedSockets := StrToBoolDef( args[1], UseBufferedSockets);
562 end
563 end;
564
Roger Meier3bef8c22012-10-06 06:58:00 +0000565
566 Console.WriteLine('Server configuration: ');
567
Jake Farrell27274222011-11-10 20:32:44 +0000568 // create protocol factory, default to BinaryProtocol
569 case protType of
Jens Geyer0b20cc82013-03-07 20:47:01 +0100570 prot_Binary: ProtocolFactory := TBinaryProtocolImpl.TFactory.Create( BINARY_STRICT_READ, BINARY_STRICT_WRITE);
Jake Farrell27274222011-11-10 20:32:44 +0000571 prot_JSON : ProtocolFactory := TJSONProtocolImpl.TFactory.Create;
572 else
573 ASSERT( FALSE); // unhandled case!
Jens Geyer0b20cc82013-03-07 20:47:01 +0100574 ProtocolFactory := TBinaryProtocolImpl.TFactory.Create( BINARY_STRICT_READ, BINARY_STRICT_WRITE);
Jake Farrell27274222011-11-10 20:32:44 +0000575 end;
Roger Meier3bef8c22012-10-06 06:58:00 +0000576 ASSERT( ProtocolFactory <> nil);
577 Console.WriteLine('- '+KNOWN_PROTOCOLS[protType]+' protocol');
Jake Farrell27274222011-11-10 20:32:44 +0000578
Jake Farrell27274222011-11-10 20:32:44 +0000579
Roger Meier3bef8c22012-10-06 06:58:00 +0000580 if sPipeName <> '' then begin
581 Console.WriteLine('- named pipe ('+sPipeName+')');
Jens Geyer06045cf2013-03-27 20:26:25 +0200582 namedpipe := TNamedPipeServerTransportImpl.Create( sPipeName, 4096, PIPE_UNLIMITED_INSTANCES, TIMEOUT);
Roger Meier79655fb2012-10-20 20:59:41 +0000583 servertrans := namedpipe;
Roger Meier3bef8c22012-10-06 06:58:00 +0000584 end
585 else if AnonPipe then begin
586 Console.WriteLine('- anonymous pipes');
Jens Geyer06045cf2013-03-27 20:26:25 +0200587 anonymouspipe := TAnonymousPipeServerTransportImpl.Create;
Roger Meier79655fb2012-10-20 20:59:41 +0000588 servertrans := anonymouspipe;
Roger Meier3bef8c22012-10-06 06:58:00 +0000589 end
590 else begin
591 Console.WriteLine('- sockets (port '+IntToStr(port)+')');
592 if UseBufferedSockets then Console.WriteLine('- buffered sockets');
593 servertrans := TServerSocketImpl.Create( Port, 0, UseBufferedSockets);
594 end;
595 ASSERT( servertrans <> nil);
596
597 if UseFramed then begin
598 Console.WriteLine('- framed transport');
599 TransportFactory := TFramedTransportImpl.TFactory.Create
600 end
601 else begin
602 TransportFactory := TTransportFactoryImpl.Create;
603 end;
604 ASSERT( TransportFactory <> nil);
605
606 testHandler := TTestHandlerImpl.Create;
Jake Farrell27274222011-11-10 20:32:44 +0000607 testProcessor := TThriftTest.TProcessorImpl.Create( testHandler );
Jake Farrell27274222011-11-10 20:32:44 +0000608
609 ServerEngine := TSimpleServer.Create( testProcessor,
Roger Meier3bef8c22012-10-06 06:58:00 +0000610 ServerTrans,
Jake Farrell27274222011-11-10 20:32:44 +0000611 TransportFactory,
612 ProtocolFactory);
613
614 testHandler.SetServer( ServerEngine);
615
Jens Geyer01640402013-09-25 21:12:21 +0200616 // test events?
617 if ServerEvents then begin
618 Console.WriteLine('- server events test enabled');
619 ServerEngine.ServerEvents := TServerEventsImpl.Create;
620 end;
621
Roger Meier3bef8c22012-10-06 06:58:00 +0000622 // start the client now when we have the anon handles, but before the server starts
623 if AnonPipe
Roger Meier79655fb2012-10-20 20:59:41 +0000624 then LaunchAnonPipeChild( ExtractFilePath(ParamStr(0))+'client.exe', anonymouspipe);
Jake Farrell27274222011-11-10 20:32:44 +0000625
Jens Geyer06045cf2013-03-27 20:26:25 +0200626 // install Ctrl+C handler before the server starts
627 g_Handler := testHandler;
628 SetConsoleCtrlHandler( @MyConsoleEventHandler, TRUE);
Roger Meier3bef8c22012-10-06 06:58:00 +0000629
630 Console.WriteLine('');
Jens Geyer06045cf2013-03-27 20:26:25 +0200631 repeat
632 Console.WriteLine('Starting the server ...');
633 serverEngine.Serve;
634 until {$IFDEF RunEndless} FALSE {$ELSE} TRUE {$ENDIF};
635
Jake Farrell27274222011-11-10 20:32:44 +0000636 testHandler.SetServer( nil);
Jens Geyer06045cf2013-03-27 20:26:25 +0200637 g_Handler := nil;
Jake Farrell27274222011-11-10 20:32:44 +0000638
639 except
640 on E: Exception do
641 begin
642 Console.Write( E.Message);
643 end;
644 end;
645 Console.WriteLine( 'done.');
646end;
647
Jens Geyer06045cf2013-03-27 20:26:25 +0200648
Jake Farrell27274222011-11-10 20:32:44 +0000649end.