serialserver/packetloopbackcsy/src/LoopbackTestStep.cpp
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Tests for packet loopback CSY
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 #include <e32property.h>
       
    23 #include <c32comm.h>
       
    24 #include <e32def.h>
       
    25 #include <e32base.h>
       
    26 
       
    27 #include <test/testexecutelog.h>
       
    28 
       
    29 #include "LoopbackTestStep.h"
       
    30 #include "LoopbackConfig.h"
       
    31 
       
    32 _LIT(KCsyName,"PKTLOOPBACK");
       
    33 _LIT(KPortName1,"PKTLOOPBACK::501");
       
    34 const TUint KPortUnitNum1 = 501;
       
    35 _LIT(KPortName2,"PKTLOOPBACK::502");
       
    36 const TUint KPortUnitNum2 = 502;
       
    37 _LIT(KPortName3,"PKTLOOPBACK::503");
       
    38 _LIT(KPortName4,"PKTLOOPBACK::504");
       
    39 _LIT8(KWriteBuf1,"1Packet data1");
       
    40 _LIT8(KWriteBuf2,"2Packet data2");
       
    41 _LIT8(KWriteBuf3,"3Packet data3");
       
    42 _LIT8(KWriteBuf4,"4Packet data4");
       
    43 
       
    44 const TUint KConfiguredPortDelayMicroseconds = 100000;
       
    45 const TUint KConfiguredPortLongDelayMicroseconds = 1000000;
       
    46 
       
    47 const TUint KTooSmallBufferSize = 4;
       
    48 const TUint KRegularBufferSize = 64;
       
    49 const TUint KHugeBufferSize = 10000;
       
    50 
       
    51 const TUint KLoopackConfigTestNumber1 = 1;
       
    52 const TUint KLoopackConfigTestNumber2 = 2;
       
    53 const TUint KLoopackConfigTestNumber3 = 3;
       
    54 const TUint KLoopackConfigTestNumber4 = 4;
       
    55 const TUint KLoopackConfigTestNumber5 = 5;
       
    56 const TUint KLoopackConfigTestNumber6 = 6;
       
    57 const TUint KLoopackConfigTestNumber7 = 7;
       
    58 const TUint KLoopackConfigTestNumber8 = 8;
       
    59 const TUint KLoopackConfigTestNumber9 = 9;
       
    60 const TUint KLoopackConfigTestNumber10 = 10;
       
    61 const TUint KLoopackConfigTestNumber11 = 11;
       
    62 const TUint KLoopackConfigTestNumber12 = 12;
       
    63 const TUint KLoopackConfigTestNumber13 = 13;
       
    64 
       
    65 CLoopbackTestStepBase::CLoopbackTestStepBase(TInt aTestNumber)
       
    66 	{
       
    67 	iTestNumber = aTestNumber;
       
    68 	}
       
    69 
       
    70 CLoopbackTestStepBase::~CLoopbackTestStepBase()
       
    71 	{
       
    72 	iCommPort1.Close();
       
    73 	iCommPort2.Close();
       
    74 	iCommPort3.Close();
       
    75 	iCommPort4.Close();
       
    76 	iCommServer.Close();
       
    77 	}
       
    78 
       
    79 void CLoopbackTestStepBase::SetTestNumber(TInt aTestNumber)
       
    80   	{
       
    81   	TInt dummy;
       
    82 	TInt ret = RProperty::Get(KUidPSPacketLoopbackCsyCategory, KPSLoopbackCsyTestNumber, dummy);
       
    83 	if(ret == KErrNotFound)
       
    84 		{
       
    85 		RProperty::Define(KUidPSPacketLoopbackCsyCategory, KPSLoopbackCsyTestNumber, 
       
    86 							KPSLoopbackCsyTestNumberKeyType);
       
    87 		}		
       
    88 	ret = RProperty::Set(KUidPSPacketLoopbackCsyCategory, KPSLoopbackCsyTestNumber, aTestNumber);
       
    89   	}
       
    90 
       
    91 void CLoopbackTestStepBase::SetFlowControl(TUint aUnit, TBool aFlowControlOn)
       
    92   	{
       
    93   	TInt dummy;
       
    94 	TInt ret = RProperty::Get(KUidPSCsyFlowControlCategory, aUnit, dummy);
       
    95 	if(ret == KErrNotFound)
       
    96 		{
       
    97 		RProperty::Define(KUidPSCsyFlowControlCategory, aUnit, KPSLoopbackCsyFlowControlOnKeyType);
       
    98 		}
       
    99 	ret = RProperty::Set(KUidPSCsyFlowControlCategory, aUnit, aFlowControlOn);
       
   100   	}
       
   101 
       
   102 void CLoopbackTestStepBase::SetReadResult(TUint aUnit, TInt aReadResult)
       
   103   	{
       
   104   	TInt dummy;
       
   105 	TInt ret = RProperty::Get(KUidPSCsyReadResultCategory, aUnit, dummy);
       
   106 	if(ret == KErrNotFound)
       
   107 		{
       
   108 		RProperty::Define(KUidPSCsyReadResultCategory, aUnit, KUidPSCsyReadResultCategoryKeyType);
       
   109 		}
       
   110 	ret = RProperty::Set(KUidPSCsyReadResultCategory, aUnit, aReadResult);
       
   111   	}
       
   112 
       
   113 void CLoopbackTestStepBase::SetWriteResult(TUint aUnit, TInt aWriteResult)
       
   114   	{
       
   115   	TInt dummy;
       
   116 	TInt ret = RProperty::Get(KUidPSCsyWriteResultCategory, aUnit, dummy);
       
   117 	if(ret == KErrNotFound)
       
   118 		{
       
   119 		RProperty::Define(KUidPSCsyWriteResultCategory, aUnit, KUidPSCsyWriteResultCategoryKeyType);
       
   120 		}
       
   121 	ret = RProperty::Set(KUidPSCsyWriteResultCategory, aUnit, aWriteResult);
       
   122   	}
       
   123 
       
   124 TVerdict CLoopbackTestStepBase::doTestStepPreambleL()
       
   125 	{
       
   126 	__UHEAP_MARK;
       
   127 	SetTestNumber(iTestNumber);
       
   128 
       
   129 	TestErrorCodeL( iCommServer.Connect(), _L("Connect to comm server") );
       
   130 	TestErrorCodeL( iCommServer.LoadCommModule(KCsyName), _L("Loading comm module") );
       
   131 
       
   132 	return TestStepResult();
       
   133 	}
       
   134 	
       
   135 TVerdict CLoopbackTestStepBase::doTestStepPostambleL()
       
   136 	{
       
   137 	User::LeaveIfError(KErrNone);	// To prevent LeaveScan warning
       
   138 
       
   139 	iCommPort1.Close();
       
   140 	iCommPort2.Close();
       
   141 	iCommPort3.Close();
       
   142 	iCommPort4.Close();
       
   143 	iCommServer.Close();
       
   144 
       
   145 	__UHEAP_MARKEND;
       
   146 	return EPass;
       
   147 	}
       
   148 	
       
   149 void CLoopbackTestStepBase::TestErrorCodeL(TInt aErrCode, const TDesC& aMessage)
       
   150 	{	
       
   151 	TestErrorCodeL(aErrCode, KErrNone, aMessage);
       
   152 	}
       
   153 
       
   154 void CLoopbackTestStepBase::TestErrorCodeL(TInt aErrCode, TInt aExpectedErrCode, const TDesC& aMessage)
       
   155 	{	
       
   156 	if(aExpectedErrCode == aErrCode)
       
   157 		{
       
   158 		INFO_PRINTF3(_L("[%S]. err[%d], as expected. OK."), &aMessage, aErrCode);
       
   159 		}
       
   160 	else
       
   161 		{
       
   162 		ERR_PRINTF5(_L("Failed: [%S]. err[%d], expected [%d]. Leaving with [%d])."), &aMessage, aErrCode, aExpectedErrCode, aErrCode);
       
   163 		User::Leave(aErrCode);
       
   164 		}
       
   165 	}
       
   166 
       
   167 void CLoopbackTestStepBase::TestBooleanTrueL(TInt aBool, const TDesC& aMessage)
       
   168 	{	
       
   169 	if(aBool)
       
   170 		{
       
   171 		INFO_PRINTF2(_L("[%S] is true, as expected. OK."), &aMessage);
       
   172 		}
       
   173 	else
       
   174 		{
       
   175 		ERR_PRINTF2(_L("Failed: [%S] is false. Leaving with KErrGeneral)."), &aMessage);
       
   176 		User::Leave(KErrGeneral);
       
   177 		}
       
   178 	}
       
   179 
       
   180 void CLoopbackTestStepBase::TestErrorCodeAndDescriptorL(TInt aErrCode, TInt aExpectedErrCode, const TDesC8& aDesC, const TDesC8& aExpectedDesC, const TDesC& aMessage)
       
   181 	{
       
   182 	if ( (aExpectedErrCode == aErrCode) && (aDesC.Compare(aExpectedDesC) == 0) )
       
   183 		{
       
   184 		INFO_PRINTF4(_L("[%S]. err[%d], and string [%S] as expected. OK."), &aMessage, aErrCode, &aExpectedDesC);
       
   185 		}
       
   186 	else if (aExpectedErrCode == aErrCode)
       
   187 		{
       
   188 		ERR_PRINTF5(_L("Failed: [%S]. err[%d], expected [%d]. Leaving with [%d])."), &aMessage, aErrCode, aExpectedErrCode, aErrCode);
       
   189 		User::Leave(aErrCode);
       
   190 		}
       
   191 	else
       
   192 		{
       
   193 		ERR_PRINTF4(_L("Failed: [%S]. String [%S] received, expected [%S]. Leaving with KErrGeneral."), &aMessage, &aDesC, &aExpectedDesC);
       
   194 		User::Leave(KErrGeneral);
       
   195 		}
       
   196 	}
       
   197 	
       
   198 void CLoopbackTestStepBase::TestErrorCodeAndDescriptorL(TInt aErrCode, const TDesC8& aDesC, const TDesC8& aExpectedDesC, const TDesC& aMessage)
       
   199 	{
       
   200 	TestErrorCodeAndDescriptorL(aErrCode, KErrNone, aDesC, aExpectedDesC, aMessage);
       
   201 	}
       
   202 	
       
   203 CLoopbackTestStep1::~CLoopbackTestStep1()
       
   204 	{
       
   205 	}
       
   206 
       
   207 CLoopbackTestStep1::CLoopbackTestStep1() : CLoopbackTestStepBase(KLoopackConfigTestNumber1)
       
   208 	{
       
   209 	// Call base class method to set up the human readable name for logging
       
   210 	SetTestStepName(KLoopbackTestStep1);
       
   211 	}
       
   212 	
       
   213 TVerdict CLoopbackTestStep1::doTestStepL()
       
   214 /**
       
   215 Test that two different sets of loopback ports can read/write to their corresponding loopback port
       
   216 The test's ini file is configured to have commPort1 and commPort2 as loopback ports, and 
       
   217 commPort3 and commPort4 as loopback ports
       
   218 */
       
   219 	{
       
   220 	// open the 4 ports
       
   221 	TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") );
       
   222 	TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") );
       
   223 	TestErrorCodeL( iCommPort3.Open(iCommServer, KPortName3, ECommExclusive, ECommRoleDCE), _L("Opening comm port 3") );
       
   224 	TestErrorCodeL( iCommPort4.Open(iCommServer, KPortName4, ECommExclusive, ECommRoleDCE), _L("Opening comm port 4") );
       
   225 
       
   226 	// There are a total of 4 writes (one to and from each port)
       
   227 	// 2 of the reads occur before the write and 2 after
       
   228 	
       
   229 	// Issue the two reads before the writes
       
   230 	TRequestStatus readStatus1, readStatus2;
       
   231 	TBuf8<KRegularBufferSize> readBuf1;
       
   232 	TBuf8<KRegularBufferSize> readBuf2;
       
   233 	iCommPort1.ReadOneOrMore(readStatus1, readBuf1);
       
   234 	iCommPort2.ReadOneOrMore(readStatus2, readBuf2);
       
   235 	
       
   236 	// Issue the writes on each port
       
   237 	TRequestStatus writeStatus1, writeStatus2, writeStatus3, writeStatus4;
       
   238 	iCommPort1.Write(writeStatus1, KWriteBuf1);
       
   239 	iCommPort2.Write(writeStatus2, KWriteBuf2);
       
   240 	iCommPort3.Write(writeStatus3, KWriteBuf3);
       
   241 	iCommPort4.Write(writeStatus4, KWriteBuf4);
       
   242 
       
   243 	User::WaitForRequest(writeStatus1);
       
   244 	TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1"));
       
   245 	User::WaitForRequest(writeStatus2);
       
   246 	TestErrorCodeL(writeStatus2.Int(), _L("Writing to comm port 2"));
       
   247 	User::WaitForRequest(writeStatus3);
       
   248 	TestErrorCodeL(writeStatus3.Int(), _L("Writing to comm port 3"));
       
   249 	User::WaitForRequest(writeStatus4);
       
   250 	TestErrorCodeL(writeStatus4.Int(), _L("Writing to comm port 4"));
       
   251 
       
   252 	// Check that the first 2 reads completed successfully
       
   253 	User::WaitForRequest(readStatus1);
       
   254 	TestErrorCodeAndDescriptorL(readStatus1.Int(), readBuf1, KWriteBuf2, _L("Read from comm port 1"));
       
   255 	User::WaitForRequest(readStatus2);
       
   256 	TestErrorCodeAndDescriptorL(readStatus2.Int(), readBuf2, KWriteBuf1, _L("Read from comm port 2"));
       
   257 
       
   258 	// Issue the 2 reads after the writes and make sure they complete successfully
       
   259 	TRequestStatus readStatus3, readStatus4;
       
   260 	TBuf8<KRegularBufferSize> readBuf3;
       
   261 	TBuf8<KRegularBufferSize> readBuf4;
       
   262 
       
   263 	iCommPort3.ReadOneOrMore(readStatus3, readBuf3);
       
   264 	User::WaitForRequest(readStatus3);
       
   265 	TestErrorCodeAndDescriptorL(readStatus3.Int(), readBuf3, KWriteBuf4, _L("Read from comm port 3"));
       
   266 
       
   267 	iCommPort4.ReadOneOrMore(readStatus4, readBuf4);
       
   268 	User::WaitForRequest(readStatus4);
       
   269 	TestErrorCodeAndDescriptorL(readStatus4.Int(), readBuf4, KWriteBuf3, _L("Read from comm port 4"));
       
   270 
       
   271 	return TestStepResult();
       
   272 	}
       
   273 
       
   274 CLoopbackTestStep2::~CLoopbackTestStep2()
       
   275 	{
       
   276 	}
       
   277 
       
   278 CLoopbackTestStep2::CLoopbackTestStep2() : CLoopbackTestStepBase(KLoopackConfigTestNumber2)
       
   279 	{
       
   280 	// Call base class method to set up the human readable name for logging
       
   281 	SetTestStepName(KLoopbackTestStep2);
       
   282 	}
       
   283 	
       
   284 TVerdict CLoopbackTestStep2::doTestStepL()
       
   285 /**
       
   286 Test that writes are successfully queued and sent.
       
   287 The 2 ports opened are configured as loopback ports in the ini file
       
   288 */
       
   289 	{
       
   290 	TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") );
       
   291 	TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") );
       
   292 		
       
   293 	// Issue 2 writes immediately one after the other in each direction
       
   294 	TRequestStatus writeStatus1, writeStatus2, writeStatus3, writeStatus4;
       
   295 	iCommPort1.Write(writeStatus1, KWriteBuf1);
       
   296 	iCommPort1.Write(writeStatus2, KWriteBuf2);
       
   297 	
       
   298 	iCommPort2.Write(writeStatus3, KWriteBuf3);
       
   299 	iCommPort2.Write(writeStatus4, KWriteBuf4);
       
   300 	
       
   301 	TBool writesSuccessful = EFalse;
       
   302 	User::WaitForRequest(writeStatus1);
       
   303 	User::WaitForRequest(writeStatus2);
       
   304 	User::WaitForRequest(writeStatus3);
       
   305 	User::WaitForRequest(writeStatus4);
       
   306 	if (writeStatus1 == KErrNone && writeStatus2 == KErrNone && 
       
   307 		writeStatus3 == KErrNone && writeStatus4 == KErrNone)
       
   308 		{
       
   309 		writesSuccessful = ETrue;
       
   310 		}
       
   311 	TestBooleanTrueL(writesSuccessful, _L("Writing to comm ports successful"));
       
   312 
       
   313 	// Issue the reads
       
   314 	TRequestStatus readStatus1, readStatus2, readStatus3, readStatus4;
       
   315 	TBuf8<KRegularBufferSize> readBuf1, readBuf2, readBuf3, readBuf4;
       
   316 	iCommPort2.ReadOneOrMore(readStatus1, readBuf1);
       
   317 	User::WaitForRequest(readStatus1);
       
   318 	iCommPort2.ReadOneOrMore(readStatus2, readBuf2);
       
   319 	User::WaitForRequest(readStatus2);
       
   320 	iCommPort1.ReadOneOrMore(readStatus3, readBuf3);
       
   321 	iCommPort1.ReadOneOrMore(readStatus4, readBuf4);
       
   322 	User::WaitForRequest(readStatus4);
       
   323 	User::WaitForRequest(readStatus3);
       
   324 
       
   325 	// Make sure the requests are all successful
       
   326 	TestBooleanTrueL(readStatus1 == KErrNone && readStatus2 == KErrNone && 
       
   327 					 readStatus3 == KErrNone && readStatus4 == KErrNone,
       
   328 					 _L("Check that reading from comm ports returned no errors"));
       
   329 	TestBooleanTrueL(readBuf1.Compare(KWriteBuf1) == 0 && readBuf2.Compare(KWriteBuf2) == 0 &&
       
   330 					 readBuf3.Compare(KWriteBuf3) == 0 || readBuf4.Compare(KWriteBuf4) == 0,
       
   331 					 _L("Check that correct values were read from comm ports"));
       
   332 
       
   333 	return TestStepResult();
       
   334 	}
       
   335 
       
   336 CLoopbackTestStep3::~CLoopbackTestStep3()
       
   337 	{
       
   338 	}
       
   339 
       
   340 CLoopbackTestStep3::CLoopbackTestStep3() : CLoopbackTestStepBase(KLoopackConfigTestNumber3)
       
   341 	{
       
   342 	// Call base class method to set up the human readable name for logging
       
   343 	SetTestStepName(KLoopbackTestStep3);
       
   344 	}
       
   345 	
       
   346 TVerdict CLoopbackTestStep3::doTestStepL()
       
   347 /**
       
   348 Test the 3 different orders in which read/write operations can occur as follows:
       
   349 	1. The read is issued, then the write is issued, then the data is sent across the port
       
   350 	2. The write is issued, then the read is issued, then the data is sent across the port
       
   351 	3. The write is issued, then the data is sent across the port, then the read is issued
       
   352 */
       
   353 	{
       
   354 	TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") );
       
   355 	TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") );
       
   356 
       
   357 	TRequestStatus readStatus1, readStatus2;
       
   358 	TBuf8<KRegularBufferSize> readBuf1, readBuf2;
       
   359 	TRequestStatus writeStatus1;
       
   360 
       
   361 	// 1. The read is issued, then the write is issued, then the data is sent across the port
       
   362 	
       
   363 	// fist issue the read
       
   364 	iCommPort1.ReadOneOrMore(readStatus1, readBuf1);
       
   365 
       
   366 	// second issue the write
       
   367 	iCommPort2.Write(writeStatus1, KWriteBuf1);
       
   368 	User::WaitForRequest(writeStatus1);
       
   369 	TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1"));
       
   370 		
       
   371 	User::WaitForRequest(readStatus1);
       
   372 	TestErrorCodeAndDescriptorL(readStatus1.Int(), readBuf1, KWriteBuf1, _L("Read from comm port 1"));
       
   373 
       
   374 	// 2. The write is issued, then the read is issued, then the data is sent across the port
       
   375 	
       
   376 	// first issue the write
       
   377 	iCommPort1.Write(writeStatus1, KWriteBuf2);
       
   378 	User::WaitForRequest(writeStatus1);
       
   379 	TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1"));
       
   380 		
       
   381 	// second issue the read before the data has the chance to be sent across the port
       
   382 	iCommPort2.ReadOneOrMore(readStatus2, readBuf2);
       
   383 	User::WaitForRequest(readStatus2);
       
   384 	TestErrorCodeAndDescriptorL(readStatus2.Int(), readBuf2, KWriteBuf2, _L("Read from comm port 2"));
       
   385 		
       
   386 	// 3. The write is issued, then the data is sent across the port, then the read is issued
       
   387 	
       
   388 	// first issue the write
       
   389 	iCommPort1.Write(writeStatus1, KWriteBuf2);
       
   390 	User::WaitForRequest(writeStatus1);
       
   391 	TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1"));
       
   392 	// second wait until the data has the chance to be sent across the port (this delay is configured
       
   393 	// to be 0.1s in the ini file, so we wait a bit longer)
       
   394 	User::After(2*KConfiguredPortDelayMicroseconds);
       
   395 		
       
   396 	// third the read is issued
       
   397 	iCommPort2.ReadOneOrMore(readStatus2, readBuf2);
       
   398 	User::WaitForRequest(readStatus2);
       
   399 	TestErrorCodeAndDescriptorL(readStatus2.Int(), readBuf2, KWriteBuf2, _L("Read from comm port 2"));
       
   400 		
       
   401 	return TestStepResult();
       
   402 	}
       
   403 
       
   404 CLoopbackTestStep4::~CLoopbackTestStep4()
       
   405 	{
       
   406 	}
       
   407 
       
   408 CLoopbackTestStep4::CLoopbackTestStep4() : CLoopbackTestStepBase(KLoopackConfigTestNumber4)
       
   409 	{
       
   410 	// Call base class method to set up the human readable name for logging
       
   411 	SetTestStepName(KLoopbackTestStep4);
       
   412 	}
       
   413 	
       
   414 TVerdict CLoopbackTestStep4::doTestStepL()
       
   415 /**
       
   416 Test reading/writing to an un-opened port, or a port whose loopback port is un-opened
       
   417 */
       
   418 	{
       
   419 	TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") );
       
   420 
       
   421 	TRequestStatus readStatus;
       
   422 	TBuf8<KRegularBufferSize> readBuf;
       
   423 	TRequestStatus writeStatus;
       
   424 
       
   425 	// issue read request before port is opened
       
   426 	iCommPort1.ReadOneOrMore(readStatus, readBuf);
       
   427 	// iCommPort2's loopback port is not yet opened, so write should fail
       
   428 	iCommPort1.Write(writeStatus, KWriteBuf1);
       
   429 	User::WaitForRequest(writeStatus);
       
   430 	TestErrorCodeL(writeStatus.Int(), KErrNotReady, _L("Writing to comm port 1 before port 2 is opened"));
       
   431 		
       
   432 	TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") );
       
   433 
       
   434 	iCommPort2.Write(writeStatus, KWriteBuf2);
       
   435 	User::WaitForRequest(writeStatus);
       
   436 
       
   437 	// now wait for read request which should complete from before iCommPort2 was opened
       
   438 	User::WaitForRequest(readStatus);
       
   439 
       
   440 	TestErrorCodeL(writeStatus.Int(), _L("Writing to comm port 1 after port 2 is opened"));
       
   441 	TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf2, _L("Read from comm port 2"));
       
   442 		
       
   443 	iCommPort2.Close();
       
   444 
       
   445 	// iCommPort1 is now closed, so both write should fail
       
   446 	iCommPort1.Write(writeStatus, KWriteBuf1);
       
   447 	User::WaitForRequest(writeStatus);
       
   448 	TestErrorCodeL(writeStatus.Int(), KErrNotReady, _L("Writing to comm port 1 after port 2 is closed"));
       
   449 		
       
   450 	return TestStepResult();
       
   451 	}
       
   452 
       
   453 CLoopbackTestStep5::~CLoopbackTestStep5()
       
   454 	{
       
   455 	}
       
   456 
       
   457 CLoopbackTestStep5::CLoopbackTestStep5() : CLoopbackTestStepBase(KLoopackConfigTestNumber5)
       
   458 	{
       
   459 	// Call base class method to set up the human readable name for logging
       
   460 	SetTestStepName(KLoopbackTestStep5);
       
   461 	}
       
   462 	
       
   463 TVerdict CLoopbackTestStep5::doTestStepL()
       
   464 /**
       
   465 Test filling up the read and write queues
       
   466 In this test, the read and write queues are set to be 1 entry in size
       
   467 */
       
   468 	{
       
   469 	INFO_PRINTF1(_L("Starting Loopback test step 5"));
       
   470 
       
   471 	TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") );
       
   472 	TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") );
       
   473 
       
   474 	TRequestStatus readStatus1;
       
   475 	TBuf8<KRegularBufferSize> readBuf1;
       
   476 	TRequestStatus writeStatus1, writeStatus2;
       
   477 
       
   478 	// Issue 2 writes immediately after each other. Since the queue is only set to 1 entry
       
   479 	// it will be full after the first write, so the second should return with KErrOverflow
       
   480 	iCommPort2.Write(writeStatus1, KWriteBuf1);
       
   481 	User::WaitForRequest(writeStatus1);
       
   482 	TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 2"));
       
   483 		
       
   484 	iCommPort2.Write(writeStatus2, KWriteBuf2);
       
   485 	User::WaitForRequest(writeStatus2);
       
   486 	TestErrorCodeL(writeStatus2.Int(), KErrOverflow, _L("Writing to comm port 2"));
       
   487 		
       
   488 	// wait until the data has the chance to be sent across the port (this delay is configured
       
   489 	// to be 1s in the ini file, so we wait a bit longer)
       
   490 	User::After(2*KConfiguredPortLongDelayMicroseconds);
       
   491 		
       
   492 	// After this delay, the buffer should have been 'sent' to the read queue of the loopback port
       
   493 	// Again, issue 2 writes immediately after each other, the first one filling up the queue
       
   494 	// meaning the second will return with KErrOverflow
       
   495 	iCommPort2.Write(writeStatus2, KWriteBuf2);
       
   496 	User::WaitForRequest(writeStatus2);
       
   497 	TestErrorCodeL(writeStatus2.Int(), _L("Writing to comm port 2"));
       
   498 		
       
   499 	iCommPort2.Write(writeStatus2, KWriteBuf2);
       
   500 	User::WaitForRequest(writeStatus2);
       
   501 	TestErrorCodeL(writeStatus2.Int(), KErrOverflow, _L("Writing to comm port 2"));
       
   502 		
       
   503 	// Wait for the amount of time it should take for the data to cross the port.
       
   504 	// After the delay the buffer should not be sent because the read buffer on the loopback port is full
       
   505 	User::After(2*KConfiguredPortLongDelayMicroseconds);
       
   506 		
       
   507 	iCommPort2.Write(writeStatus2, KWriteBuf2);
       
   508 	User::WaitForRequest(writeStatus2);
       
   509 	TestErrorCodeL(writeStatus2.Int(), KErrOverflow, _L("Writing to comm port 2"));
       
   510 		
       
   511 	// Issue reads for the 2 writes that have been sent successfully
       
   512 	// Since the second read has not yet been sent across the port, it should take more than the 
       
   513 	// time configured to send a buffer 
       
   514 
       
   515 	// Get the time before the reads
       
   516 	TTime beforeTime;
       
   517 	beforeTime.UniversalTime();
       
   518 	
       
   519 	iCommPort1.ReadOneOrMore(readStatus1, readBuf1);
       
   520 	User::WaitForRequest(readStatus1);
       
   521 	TestErrorCodeAndDescriptorL(readStatus1.Int(), readBuf1, KWriteBuf1, _L("Read from comm port 1"));
       
   522 
       
   523 	iCommPort1.ReadOneOrMore(readStatus1, readBuf1);
       
   524 	User::WaitForRequest(readStatus1);
       
   525 
       
   526 	// Get the time after the read
       
   527 	TTime afterTime;
       
   528 	afterTime.UniversalTime();
       
   529 
       
   530 	// Make sure the read was successful
       
   531 	TestErrorCodeAndDescriptorL(readStatus1.Int(), readBuf1, KWriteBuf2, _L("Read from comm port 1"));
       
   532 	
       
   533 	// Make sure the read took at least the amount of time as the configured delay
       
   534 	// We need a long time-out here because the resolution of the timer may cause it to expire prematurely
       
   535 	const TTimeIntervalMicroSeconds delayTime((TInt)(0.5*KConfiguredPortLongDelayMicroseconds));
       
   536 	TTime netTime = afterTime - delayTime;
       
   537 	TestBooleanTrueL(netTime > beforeTime, _L("Check there was a delay writing to the port"));
       
   538 	
       
   539 	return TestStepResult();
       
   540 	}
       
   541 
       
   542 CLoopbackTestStep6::~CLoopbackTestStep6()
       
   543 	{
       
   544 	}
       
   545 
       
   546 CLoopbackTestStep6::CLoopbackTestStep6() : CLoopbackTestStepBase(KLoopackConfigTestNumber6)
       
   547 	{
       
   548 	// Call base class method to set up the human readable name for logging
       
   549 	SetTestStepName(KLoopbackTestStep6);
       
   550 	}
       
   551 	
       
   552 TVerdict CLoopbackTestStep6::doTestStepL()
       
   553 /**
       
   554 Test reading an entry with too small a read buffer
       
   555 */
       
   556 	{
       
   557 	INFO_PRINTF1(_L("Starting Loopback test step 6"));
       
   558 
       
   559 	TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") );
       
   560 	TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") );
       
   561 	
       
   562 	TRequestStatus readStatus1;
       
   563 	TBuf8<KTooSmallBufferSize> smallReadBuf;
       
   564 	TBuf8<KRegularBufferSize> largeEnoughReadBuf1;
       
   565 	TRequestStatus writeStatus2;
       
   566 
       
   567 	iCommPort2.Write(writeStatus2, KWriteBuf1);
       
   568 	User::WaitForRequest(writeStatus2);
       
   569 	TestErrorCodeL(writeStatus2.Int(), _L("Writing to comm port 1"));
       
   570 		
       
   571 	// Issue read that should fail from too small of a buffer
       
   572 	iCommPort1.ReadOneOrMore(readStatus1, smallReadBuf);
       
   573 	User::WaitForRequest(readStatus1);
       
   574 	TestErrorCodeL(readStatus1.Int(), KErrOverflow, _L("Check that read fails becuase too small buffer supplied"));
       
   575 
       
   576 	// Issue read that should succeed
       
   577 	iCommPort1.ReadOneOrMore(readStatus1, largeEnoughReadBuf1);
       
   578 	User::WaitForRequest(readStatus1);
       
   579 	TestErrorCodeAndDescriptorL(readStatus1.Int(), largeEnoughReadBuf1, KWriteBuf1, _L("Read from comm port 1"));
       
   580 
       
   581 	return TestStepResult();
       
   582 	}
       
   583 
       
   584 CLoopbackTestStep7::~CLoopbackTestStep7()
       
   585 	{
       
   586 	}
       
   587 
       
   588 CLoopbackTestStep7::CLoopbackTestStep7() : CLoopbackTestStepBase(KLoopackConfigTestNumber7)
       
   589 	{
       
   590 	// Call base class method to set up the human readable name for logging
       
   591 	SetTestStepName(KLoopbackTestStep7);
       
   592 	}
       
   593 	
       
   594 TVerdict CLoopbackTestStep7::doTestStepL()
       
   595 /**
       
   596 Test issuing write with too large of a buffer
       
   597 */
       
   598 	{
       
   599 	TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") );
       
   600 	TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") );
       
   601 	
       
   602 	// Create the large buffer
       
   603 	HBufC8 *hugeHeapDescriptor = HBufC8::NewLC(KHugeBufferSize);
       
   604 	TPtr8 hugeDescriptor = hugeHeapDescriptor->Des();
       
   605 	hugeDescriptor.AppendFill('a', KHugeBufferSize);
       
   606 	
       
   607 	// Issue the write with the buffer that is too large
       
   608 	TRequestStatus writeStatus1, readStatus1;
       
   609 	iCommPort2.Write(writeStatus1, hugeDescriptor);
       
   610 	User::WaitForRequest(writeStatus1);
       
   611 	TestErrorCodeL(writeStatus1.Int(), KErrArgument, _L("Writing to comm port 1"));
       
   612 
       
   613 	// Make sure write still works with normal sized buffer
       
   614 	iCommPort2.Write(writeStatus1, KWriteBuf1);
       
   615 	User::WaitForRequest(writeStatus1);
       
   616 	TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1"));
       
   617 		
       
   618 	TBuf8<KRegularBufferSize> readBuf;
       
   619 	iCommPort1.ReadOneOrMore(readStatus1, readBuf);
       
   620 	User::WaitForRequest(readStatus1);
       
   621 	if (readStatus1 != KErrNone)
       
   622 		{
       
   623 		INFO_PRINTF1(_L("Failed read"));
       
   624 		SetTestStepResult(EFail);
       
   625 		}
       
   626 
       
   627 	CleanupStack::PopAndDestroy(hugeHeapDescriptor);
       
   628 
       
   629 	return TestStepResult();
       
   630 	}
       
   631 
       
   632 CLoopbackTestStep8::~CLoopbackTestStep8()
       
   633 	{
       
   634 	}
       
   635 
       
   636 CLoopbackTestStep8::CLoopbackTestStep8() : CLoopbackTestStepBase(KLoopackConfigTestNumber8)
       
   637 	{
       
   638 	// Call base class method to set up the human readable name for logging
       
   639 	SetTestStepName(KLoopbackTestStep8);
       
   640 	}
       
   641 	
       
   642 TVerdict CLoopbackTestStep8::doTestStepL()
       
   643 /**
       
   644 Test wrapping around the queue by issuing more writes than the queue size (configured to 2 in the ini file)
       
   645 */
       
   646 	{
       
   647 	TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") );
       
   648 	TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") );
       
   649 	
       
   650 	TRequestStatus writeStatus, readStatus;
       
   651 	iCommPort2.Write(writeStatus, KWriteBuf1);
       
   652 	User::WaitForRequest(writeStatus);
       
   653 	TestErrorCodeL(writeStatus.Int(), _L("Writing to comm port 1"));
       
   654 
       
   655 	iCommPort2.Write(writeStatus, KWriteBuf2);
       
   656 	User::WaitForRequest(writeStatus);
       
   657 	TestErrorCodeL(writeStatus.Int(), _L("Writing to comm port 1"));
       
   658 		
       
   659 	TBuf8<KRegularBufferSize> readBuf;
       
   660 	iCommPort1.ReadOneOrMore(readStatus, readBuf);
       
   661 	User::WaitForRequest(readStatus);
       
   662 	TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf1, _L("Read from comm port 1"));
       
   663 
       
   664 	iCommPort2.Write(writeStatus, KWriteBuf3);
       
   665 	User::WaitForRequest(writeStatus);
       
   666 	TestErrorCodeL(writeStatus.Int(), _L("Writing to comm port 1"));
       
   667 		
       
   668 	iCommPort1.ReadOneOrMore(readStatus, readBuf);
       
   669 	User::WaitForRequest(readStatus);
       
   670 	TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf2, _L("Read from comm port 1"));
       
   671 
       
   672 	iCommPort1.ReadOneOrMore(readStatus, readBuf);
       
   673 	User::WaitForRequest(readStatus);
       
   674 	TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf3, _L("Read from comm port 1"));
       
   675 
       
   676 	return TestStepResult();
       
   677 	}
       
   678 
       
   679 CLoopbackTestStep9::~CLoopbackTestStep9()
       
   680 	{
       
   681 	}
       
   682 
       
   683 CLoopbackTestStep9::CLoopbackTestStep9() : CLoopbackTestStepBase(KLoopackConfigTestNumber9)
       
   684 	{
       
   685 	// Call base class method to set up the human readable name for logging
       
   686 	SetTestStepName(KLoopbackTestStep9);
       
   687 	}
       
   688 	
       
   689 TVerdict CLoopbackTestStep9::doTestStepL()
       
   690 /**
       
   691 Test read cancel
       
   692 */
       
   693 	{
       
   694 	TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") );
       
   695 	TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") );
       
   696 	
       
   697 	TRequestStatus writeStatus, readStatus;
       
   698 	iCommPort1.Write(writeStatus, KWriteBuf1);
       
   699 	User::WaitForRequest(writeStatus);
       
   700 	TestErrorCodeL(writeStatus.Int(), _L("Writing to comm port 1"));
       
   701 
       
   702 	TBuf8<KRegularBufferSize> readBuf;
       
   703 	iCommPort2.ReadOneOrMore(readStatus, readBuf);
       
   704 	// Cancel the buffer before it has the chance to complete
       
   705 	iCommPort2.ReadCancel();
       
   706 	User::WaitForRequest(readStatus);
       
   707 	TestErrorCodeL(readStatus.Int(), KErrCancel, _L("Check that cancelled request returns KErrCancel"));
       
   708 	
       
   709 	// Make sure the read still works
       
   710 	iCommPort2.ReadOneOrMore(readStatus, readBuf);
       
   711 	User::WaitForRequest(readStatus);
       
   712 	TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf1, _L("Read from comm port 1"));
       
   713 
       
   714 	return TestStepResult();
       
   715 	}
       
   716 
       
   717 CLoopbackTestStep10::~CLoopbackTestStep10()
       
   718 	{
       
   719 	}
       
   720 
       
   721 CLoopbackTestStep10::CLoopbackTestStep10() : CLoopbackTestStepBase(KLoopackConfigTestNumber10)
       
   722 	{
       
   723 	// Call base class method to set up the human readable name for logging
       
   724 	SetTestStepName(KLoopbackTestStep10);
       
   725 	}
       
   726 	
       
   727 TVerdict CLoopbackTestStep10::doTestStepL()
       
   728 /**
       
   729 Test flow control
       
   730 */
       
   731 	{
       
   732 	TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") );
       
   733 	TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") );
       
   734 	
       
   735 	TRequestStatus writeStatus1;
       
   736 	iCommPort1.Write(writeStatus1, KWriteBuf1);
       
   737 	SetFlowControl(KPortUnitNum1, ETrue);
       
   738 	SetFlowControl(KPortUnitNum2, ETrue);
       
   739 	User::WaitForRequest(writeStatus1);
       
   740 	TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1"));
       
   741 
       
   742 	TRequestStatus timerStatus, readStatus;
       
   743 	TBuf8<KRegularBufferSize> readBuf;
       
   744 	iCommPort2.ReadOneOrMore(readStatus, readBuf);
       
   745 
       
   746 	RTimer timer;
       
   747 	timer.CreateLocal();
       
   748 	timer.After(timerStatus, 3*KConfiguredPortDelayMicroseconds);
       
   749 	
       
   750 	User::WaitForRequest(readStatus, timerStatus);
       
   751 	
       
   752 	SetFlowControl(KPortUnitNum1, EFalse);
       
   753 	SetFlowControl(KPortUnitNum2, EFalse);
       
   754 	TestBooleanTrueL(timerStatus == KErrNone && readStatus != KErrNone, _L("Check that setting flow control causes read to be stopped"));
       
   755 
       
   756 	User::WaitForRequest(readStatus);
       
   757 	TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf1, _L("Read from comm port 1"));
       
   758 
       
   759 	return TestStepResult();
       
   760 	}
       
   761 
       
   762 CLoopbackTestStep11::~CLoopbackTestStep11()
       
   763 	{
       
   764 	}
       
   765 
       
   766 CLoopbackTestStep11::CLoopbackTestStep11() : CLoopbackTestStepBase(KLoopackConfigTestNumber11)
       
   767 	{
       
   768 	// Call base class method to set up the human readable name for logging
       
   769 	SetTestStepName(KLoopbackTestStep11);
       
   770 	}
       
   771 	
       
   772 TVerdict CLoopbackTestStep11::doTestStepL()
       
   773 /**
       
   774 Test setting read result
       
   775 */
       
   776 	{
       
   777 	TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") );
       
   778 	TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") );
       
   779 	
       
   780 	TRequestStatus writeStatus1;
       
   781 	iCommPort1.Write(writeStatus1, KWriteBuf1);
       
   782 	User::WaitForRequest(writeStatus1);
       
   783 	TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1"));
       
   784 
       
   785 	TRequestStatus readStatus;
       
   786 	TBuf8<KRegularBufferSize> readBuf;
       
   787 	iCommPort2.ReadOneOrMore(readStatus, readBuf);
       
   788 
       
   789 	SetReadResult(KPortUnitNum2, KErrNotFound);
       
   790 
       
   791 	User::WaitForRequest(readStatus);
       
   792 	
       
   793 	// Make sure everything still works
       
   794 	SetReadResult(KPortUnitNum2, KErrNone);
       
   795 	TestErrorCodeL(readStatus.Int(), KErrNotFound, _L("Check that SetReadResult causes Read to return error"));
       
   796 
       
   797 	iCommPort1.Write(writeStatus1, KWriteBuf2);
       
   798 	User::WaitForRequest(writeStatus1);
       
   799 	TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1"));
       
   800 
       
   801 	iCommPort2.ReadOneOrMore(readStatus, readBuf);
       
   802 	User::WaitForRequest(readStatus);
       
   803 	TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf2, _L("Read from comm port 1"));
       
   804 
       
   805 	// Now test failing a write
       
   806 	SetWriteResult(KPortUnitNum2, KErrNotFound);
       
   807 	iCommPort2.Write(writeStatus1, KWriteBuf3);
       
   808 	User::WaitForRequest(writeStatus1);
       
   809 	SetWriteResult(KPortUnitNum2, KErrNone);
       
   810 	TestErrorCodeL(writeStatus1.Int(), KErrNotFound, _L("Check that SetWriteResult causes Write to return error"));
       
   811 
       
   812 	// Make sure we can't read this
       
   813 	TRequestStatus timerStatus;
       
   814 	RTimer timer;
       
   815 	timer.CreateLocal();
       
   816 	iCommPort1.ReadOneOrMore(readStatus, readBuf);
       
   817 	timer.After(timerStatus, 3*KConfiguredPortDelayMicroseconds);
       
   818 	
       
   819 	User::WaitForRequest(readStatus, timerStatus);
       
   820 	TestBooleanTrueL(timerStatus == KErrNone && readStatus != KErrNone, _L("Write that was configured to fail completed successfully"));
       
   821 	
       
   822 	return TestStepResult();
       
   823 	}
       
   824 
       
   825 CLoopbackTestStep12::~CLoopbackTestStep12()
       
   826 	{
       
   827 	}
       
   828 
       
   829 CLoopbackTestStep12::CLoopbackTestStep12() : CLoopbackTestStepBase(KLoopackConfigTestNumber12)
       
   830 	{
       
   831 	// Call base class method to set up the human readable name for logging
       
   832 	SetTestStepName(KLoopbackTestStep12);
       
   833 	}
       
   834 	
       
   835 _LIT8(KWriteBuf,"12345");
       
   836 _LIT8(KDoubleWriteBuf,"1234512345");
       
   837 _LIT8(KWriteBufTabTerminator,"12345\t");
       
   838 _LIT8(KWriteBufNewlineTerminator,"12345\n");
       
   839 _LIT8(KWriteBufTabThenNewlineTerminator,"12345\t12345\n12345");
       
   840 _LIT8(KWriteBufNewlineThenTabTerminator,"12345\n12345\t12345");
       
   841 const TInt KWriteBufSegmentSize = 5;
       
   842 
       
   843 TVerdict CLoopbackTestStep12::doTestStepL()
       
   844 /**
       
   845 Test setting read result
       
   846 */
       
   847 	{
       
   848 	TRequestStatus readStatus;
       
   849 	TBuf8<KWriteBufSegmentSize> readBuf;
       
   850 	TRequestStatus writeStatus1;
       
   851 
       
   852 	TCommConfig commConfigBuf;
       
   853 	TCommConfigV01& commConfig = commConfigBuf();
       
   854 	commConfig.iTerminator[0] = '\t';
       
   855 	commConfig.iTerminator[1] = '\n';
       
   856 	commConfig.iTerminatorCount = 2;
       
   857 	
       
   858 	TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") );
       
   859 	TestErrorCodeL( iCommPort1.SetConfig(commConfigBuf), _L("Opening comm port 1") );
       
   860 	TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") );
       
   861 	TestErrorCodeL( iCommPort2.SetConfig(commConfigBuf), _L("Opening comm port 2") );
       
   862 		
       
   863 	// reads and writes are same size
       
   864 	iCommPort1.Write(writeStatus1, KWriteBuf);
       
   865 	User::WaitForRequest(writeStatus1);
       
   866 	TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1"));
       
   867 
       
   868 	iCommPort2.ReadOneOrMore(readStatus, readBuf);
       
   869 	User::WaitForRequest(readStatus);
       
   870 	TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf, _L("Read from comm port 1"));
       
   871 	
       
   872 
       
   873 	// test ReadOneOrMore
       
   874 	iCommPort1.Write(writeStatus1, KWriteBufTabThenNewlineTerminator);
       
   875 	User::WaitForRequest(writeStatus1);
       
   876 	TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1"));
       
   877 
       
   878 	TBuf8<KRegularBufferSize> readBuf2;
       
   879 	iCommPort2.ReadOneOrMore(readStatus, readBuf2);
       
   880 	User::WaitForRequest(readStatus);
       
   881 	if (readBuf2.Compare(KWriteBufTabTerminator) != 0 || readStatus != KErrNone)
       
   882 		{
       
   883 		INFO_PRINTF1(_L("Failed write"));
       
   884 		SetTestStepResult(EFail);
       
   885 		}
       
   886 	
       
   887 	iCommPort2.ReadOneOrMore(readStatus, readBuf2);
       
   888 	User::WaitForRequest(readStatus);
       
   889 	TestErrorCodeL(readStatus.Int(), _L("Error in read status"));
       
   890 	TestErrorCodeL(readBuf2.Compare(KWriteBufNewlineTerminator), _L("Incorrect buffer received"));
       
   891 	
       
   892 	iCommPort2.ReadOneOrMore(readStatus, readBuf2);
       
   893 	User::WaitForRequest(readStatus);
       
   894 	if (readBuf2.Compare(KWriteBuf) != 0 || readStatus != KErrNone)
       
   895 		{
       
   896 		INFO_PRINTF1(_L("Failed write"));
       
   897 		SetTestStepResult(EFail);
       
   898 		}
       
   899 	
       
   900 	iCommPort1.Write(writeStatus1, KWriteBufNewlineThenTabTerminator);
       
   901 	User::WaitForRequest(writeStatus1);
       
   902 	TestErrorCodeL(writeStatus1.Int(), _L("Failed write"));
       
   903 
       
   904 	iCommPort2.ReadOneOrMore(readStatus, readBuf2);
       
   905 	User::WaitForRequest(readStatus);
       
   906 	TestBooleanTrueL(readBuf2.Compare(KWriteBufNewlineTerminator) == 0 && readStatus == KErrNone, _L("Failed read"));
       
   907 	
       
   908 	iCommPort2.ReadOneOrMore(readStatus, readBuf2);
       
   909 	User::WaitForRequest(readStatus);
       
   910 	TestBooleanTrueL(readBuf2.Compare(KWriteBufTabTerminator) == 0 && readStatus == KErrNone, _L("Failed read"));
       
   911 	
       
   912 	iCommPort2.ReadOneOrMore(readStatus, readBuf2);
       
   913 	User::WaitForRequest(readStatus);
       
   914 	TestBooleanTrueL(readBuf2.Compare(KWriteBuf) == 0 || readStatus == KErrNone, _L("Failed read"));
       
   915 
       
   916 	return TestStepResult();
       
   917 	}
       
   918 
       
   919 CLoopbackTestStep13::~CLoopbackTestStep13()
       
   920 	{
       
   921 	}
       
   922 
       
   923 CLoopbackTestStep13::CLoopbackTestStep13() : CLoopbackTestStepBase(KLoopackConfigTestNumber13)
       
   924 	{
       
   925 	// Call base class method to set up the human readable name for logging
       
   926 	SetTestStepName(KLoopbackTestStep13);
       
   927 	}
       
   928 	
       
   929 TVerdict CLoopbackTestStep13::doTestStepL()
       
   930 /**
       
   931 Test setting read result
       
   932 */
       
   933 	{
       
   934 	TRequestStatus readStatus;
       
   935 	TRequestStatus writeStatus;
       
   936 
       
   937 	TCommConfig commConfigBuf;
       
   938 	TCommConfigV01& commConfig = commConfigBuf();
       
   939 	commConfig.iTerminator[0] = '\t';
       
   940 	commConfig.iTerminator[1] = '\n';
       
   941 	commConfig.iTerminatorCount = 2;
       
   942 	
       
   943 	TInt err = iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE);
       
   944 	err = iCommPort1.SetConfig(commConfigBuf);
       
   945 	TestErrorCodeL(err, _L("Failed loading port"));
       
   946 		
       
   947 	err = iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE);
       
   948 	err = iCommPort2.SetConfig(commConfigBuf);
       
   949 	TestErrorCodeL(err, _L("Failed loading port"));
       
   950 	
       
   951 	// make sure Read works
       
   952 	iCommPort1.Write(writeStatus, KWriteBufNewlineThenTabTerminator);
       
   953 	User::WaitForRequest(writeStatus);
       
   954 	TestErrorCodeL(writeStatus.Int(), _L("Write failed"));
       
   955 
       
   956 	TBuf8<KRegularBufferSize> readBuf2;
       
   957 	iCommPort2.Read(readStatus, readBuf2);
       
   958 	User::WaitForRequest(readStatus);
       
   959 	TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf2, KWriteBufNewlineTerminator, _L("Read from comm port 1"));
       
   960 	
       
   961 	iCommPort2.Read(readStatus, readBuf2);
       
   962 	User::WaitForRequest(readStatus);
       
   963 	TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf2, KWriteBufTabTerminator, _L("Read from comm port 1"));
       
   964 	
       
   965 	TRequestStatus timerStatus;
       
   966 	TBuf8<2*KWriteBufSegmentSize> readBuf4;
       
   967 	iCommPort2.Read(readStatus, readBuf4);
       
   968 
       
   969 	RTimer timer;
       
   970 	timer.CreateLocal();
       
   971 	timer.After(timerStatus, 10*KConfiguredPortDelayMicroseconds);
       
   972 
       
   973 	User::WaitForRequest(readStatus, timerStatus);
       
   974 	TestBooleanTrueL(timerStatus == KErrNone && readStatus != KErrNone, _L("Check that read didn't complete"));
       
   975 	
       
   976 	iCommPort1.Write(writeStatus, KWriteBuf);
       
   977 	User::WaitForRequest(writeStatus);
       
   978 	TestErrorCodeL(writeStatus.Int(), _L("Failed write"));
       
   979 
       
   980 	User::WaitForRequest(readStatus);
       
   981 	TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf4, KDoubleWriteBuf, _L("Read from comm port 1"));
       
   982 
       
   983 	return TestStepResult();
       
   984 	}
       
   985