unit IdTestCmdTCPServer; { session from known non-indy smtp: ----------------------------------------- 220 mail.example.com ESMTP ? 500 5.5.1 Command unrecognized: "?" ----------------------------------------- non-indy pop3 ----------------------------------------- +OK DBMAIL pop3 server ready to rock ? -ERR your command does not compute ----------------------------------------- current indy cmdserver functionality: ----------------------------------------- 200 Test Greeting ? 400-Unknown Command 400 ? ----------------------------------------- } interface uses IdCmdTCPServer, IdCommandHandlers, IdContext, IdGlobal, IdIOHandlerStack, IdLogDebug, IdTCPClient, IdTCPConnection, IdTest, IdSys; type TIdTestCmdTCPServer = class(TIdTest) private //use a basic tcpclient to ensure isolate errors to the server component FClient: TIdTCPClient; FServer: TIdCmdTCPServer; procedure CommandTEST(ASender: TIdCommand); procedure CommandError(ASender: TIdCommand); procedure GetGreeting; protected procedure SetUp;override; procedure TearDown;override; published procedure TestCompleteCommand; procedure TestResultCode; procedure TestServerException; procedure TestUnknownCommand; end; EIdTestException = class(Exception); implementation const cTestCommand='TEST'; cTestResponse='TestResponse'; cTestCode=202; cNotTestCode=203; cErrorCommand='CAUSEERROR'; cErrorResponse='My Error Message'; cUnknownCommand='UNKNOWN'; cTestPort=20202; cGreetingText = 'Test Greeting'; procedure TIdTestCmdTCPServer.CommandError(ASender: TIdCommand); begin raise EIdTestException.Create(cErrorResponse); end; procedure TIdTestCmdTCPServer.CommandTEST(ASender: TIdCommand); begin ASender.Reply.SetReply(cTestCode,cTestResponse); end; procedure TIdTestCmdTCPServer.SetUp; var aCommand:TIdCommandHandler; begin inherited; FServer:= TIdCmdTCPServer.Create(nil); FServer.DefaultPort:=cTestPort; FServer.HelpReply.Code := '111'; FServer.Greeting.Code := '200'; FServer.Greeting.Text.Text := cGreetingText; Assert(FServer.Greeting.NumericCode<>0); aCommand:=FServer.CommandHandlers.Add; aCommand.Command := cTestCommand; aCommand.OnCommand := CommandTEST; aCommand:=FServer.CommandHandlers.Add; aCommand.Command := cErrorCommand; aCommand.OnCommand := CommandError; //uncomment to test using external telnet app //Sleep(5*60*1000); //setup client FClient:= TIdTCPClient.Create(nil); FClient.Port:=cTestPort; FClient.Host:='127.0.0.1'; FClient.ReadTimeout:=1000; FClient.ConnectTimeout:=1000; //start FServer.Active:=True; FClient.Connect; GetGreeting; end; procedure TIdTestCmdTCPServer.TearDown; begin Sys.FreeAndNil(FClient); Sys.FreeAndNil(FServer); inherited; end; procedure TIdTestCmdTCPServer.TestCompleteCommand; //check that commands are only processed after EOL is sent var aStr:string; begin FClient.IOHandler.Write('TE'); aStr:=FClient.IOHandler.Readln; Assert(aStr = '',aStr); FClient.IOHandler.Write('ST' + EOL); Assert(FClient.GetResponse(cTestCode) = cTestCode); Assert(FClient.LastCmdResult.Text.Text = cTestResponse + EOL); end; procedure TIdTestCmdTCPServer.GetGreeting; //greeting is sent by server immediately after connect //already read in setup var aResponse:integer; aStr:string; begin aResponse:=FClient.GetResponse(200); Assert(aResponse = 200); aStr := FClient.LastCmdResult.Text.Text; Assert(aStr = cGreetingText+EOL, aStr); end; procedure TIdTestCmdTCPServer.TestResultCode; //check unexpected resultcode raises error //TEST doesnt return 203, so this should fail var aExpected:Boolean; begin try FClient.SendCmd(cTestCommand,[cNotTestCode]); aExpected:=False; except aExpected:=True; end; Assert(aExpected); //SendCmd function result invalid here due to exception raised Assert(FClient.LastCmdResult.NumericCode=cTestCode); end; procedure TIdTestCmdTCPServer.TestServerException; //check exception on server sent to client ok. //exceptions should be response 500 //possible to get actual server-side exception class? var aResponse: integer; aStr:string; begin FClient.IOHandler.WriteLn(cErrorCommand); aResponse:=FClient.GetResponse(500); aStr:=FClient.LastCmdResult.Text.Text; Assert(aResponse=500); Assert(aStr=cErrorResponse+EOL); end; procedure TIdTestCmdTCPServer.TestUnknownCommand; //check that unknown command is handled correctly //see TIdCmdTCPServer.CreateReplyUnknownCommand var aResponse:integer; aStr:string; begin aResponse:=FClient.SendCmd(cUnknownCommand); Assert(aResponse=400); aStr:=FClient.LastCmdResult.Text.Text; Assert(aStr='Unknown Command'+EOL+cUnknownCommand+EOL); end; initialization TIdTest.RegisterTest(TIdTestCmdTCPServer); end.