diff -r 000000000000 -r dfb7c4ff071f serialserver/packetloopbackcsy/src/LoopbackTestStep.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/serialserver/packetloopbackcsy/src/LoopbackTestStep.cpp Thu Dec 17 09:22:25 2009 +0200 @@ -0,0 +1,985 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Tests for packet loopback CSY +// +// + +/** + @file +*/ + +#include +#include +#include +#include + +#include + +#include "LoopbackTestStep.h" +#include "LoopbackConfig.h" + +_LIT(KCsyName,"PKTLOOPBACK"); +_LIT(KPortName1,"PKTLOOPBACK::501"); +const TUint KPortUnitNum1 = 501; +_LIT(KPortName2,"PKTLOOPBACK::502"); +const TUint KPortUnitNum2 = 502; +_LIT(KPortName3,"PKTLOOPBACK::503"); +_LIT(KPortName4,"PKTLOOPBACK::504"); +_LIT8(KWriteBuf1,"1Packet data1"); +_LIT8(KWriteBuf2,"2Packet data2"); +_LIT8(KWriteBuf3,"3Packet data3"); +_LIT8(KWriteBuf4,"4Packet data4"); + +const TUint KConfiguredPortDelayMicroseconds = 100000; +const TUint KConfiguredPortLongDelayMicroseconds = 1000000; + +const TUint KTooSmallBufferSize = 4; +const TUint KRegularBufferSize = 64; +const TUint KHugeBufferSize = 10000; + +const TUint KLoopackConfigTestNumber1 = 1; +const TUint KLoopackConfigTestNumber2 = 2; +const TUint KLoopackConfigTestNumber3 = 3; +const TUint KLoopackConfigTestNumber4 = 4; +const TUint KLoopackConfigTestNumber5 = 5; +const TUint KLoopackConfigTestNumber6 = 6; +const TUint KLoopackConfigTestNumber7 = 7; +const TUint KLoopackConfigTestNumber8 = 8; +const TUint KLoopackConfigTestNumber9 = 9; +const TUint KLoopackConfigTestNumber10 = 10; +const TUint KLoopackConfigTestNumber11 = 11; +const TUint KLoopackConfigTestNumber12 = 12; +const TUint KLoopackConfigTestNumber13 = 13; + +CLoopbackTestStepBase::CLoopbackTestStepBase(TInt aTestNumber) + { + iTestNumber = aTestNumber; + } + +CLoopbackTestStepBase::~CLoopbackTestStepBase() + { + iCommPort1.Close(); + iCommPort2.Close(); + iCommPort3.Close(); + iCommPort4.Close(); + iCommServer.Close(); + } + +void CLoopbackTestStepBase::SetTestNumber(TInt aTestNumber) + { + TInt dummy; + TInt ret = RProperty::Get(KUidPSPacketLoopbackCsyCategory, KPSLoopbackCsyTestNumber, dummy); + if(ret == KErrNotFound) + { + RProperty::Define(KUidPSPacketLoopbackCsyCategory, KPSLoopbackCsyTestNumber, + KPSLoopbackCsyTestNumberKeyType); + } + ret = RProperty::Set(KUidPSPacketLoopbackCsyCategory, KPSLoopbackCsyTestNumber, aTestNumber); + } + +void CLoopbackTestStepBase::SetFlowControl(TUint aUnit, TBool aFlowControlOn) + { + TInt dummy; + TInt ret = RProperty::Get(KUidPSCsyFlowControlCategory, aUnit, dummy); + if(ret == KErrNotFound) + { + RProperty::Define(KUidPSCsyFlowControlCategory, aUnit, KPSLoopbackCsyFlowControlOnKeyType); + } + ret = RProperty::Set(KUidPSCsyFlowControlCategory, aUnit, aFlowControlOn); + } + +void CLoopbackTestStepBase::SetReadResult(TUint aUnit, TInt aReadResult) + { + TInt dummy; + TInt ret = RProperty::Get(KUidPSCsyReadResultCategory, aUnit, dummy); + if(ret == KErrNotFound) + { + RProperty::Define(KUidPSCsyReadResultCategory, aUnit, KUidPSCsyReadResultCategoryKeyType); + } + ret = RProperty::Set(KUidPSCsyReadResultCategory, aUnit, aReadResult); + } + +void CLoopbackTestStepBase::SetWriteResult(TUint aUnit, TInt aWriteResult) + { + TInt dummy; + TInt ret = RProperty::Get(KUidPSCsyWriteResultCategory, aUnit, dummy); + if(ret == KErrNotFound) + { + RProperty::Define(KUidPSCsyWriteResultCategory, aUnit, KUidPSCsyWriteResultCategoryKeyType); + } + ret = RProperty::Set(KUidPSCsyWriteResultCategory, aUnit, aWriteResult); + } + +TVerdict CLoopbackTestStepBase::doTestStepPreambleL() + { + __UHEAP_MARK; + SetTestNumber(iTestNumber); + + TestErrorCodeL( iCommServer.Connect(), _L("Connect to comm server") ); + TestErrorCodeL( iCommServer.LoadCommModule(KCsyName), _L("Loading comm module") ); + + return TestStepResult(); + } + +TVerdict CLoopbackTestStepBase::doTestStepPostambleL() + { + User::LeaveIfError(KErrNone); // To prevent LeaveScan warning + + iCommPort1.Close(); + iCommPort2.Close(); + iCommPort3.Close(); + iCommPort4.Close(); + iCommServer.Close(); + + __UHEAP_MARKEND; + return EPass; + } + +void CLoopbackTestStepBase::TestErrorCodeL(TInt aErrCode, const TDesC& aMessage) + { + TestErrorCodeL(aErrCode, KErrNone, aMessage); + } + +void CLoopbackTestStepBase::TestErrorCodeL(TInt aErrCode, TInt aExpectedErrCode, const TDesC& aMessage) + { + if(aExpectedErrCode == aErrCode) + { + INFO_PRINTF3(_L("[%S]. err[%d], as expected. OK."), &aMessage, aErrCode); + } + else + { + ERR_PRINTF5(_L("Failed: [%S]. err[%d], expected [%d]. Leaving with [%d])."), &aMessage, aErrCode, aExpectedErrCode, aErrCode); + User::Leave(aErrCode); + } + } + +void CLoopbackTestStepBase::TestBooleanTrueL(TInt aBool, const TDesC& aMessage) + { + if(aBool) + { + INFO_PRINTF2(_L("[%S] is true, as expected. OK."), &aMessage); + } + else + { + ERR_PRINTF2(_L("Failed: [%S] is false. Leaving with KErrGeneral)."), &aMessage); + User::Leave(KErrGeneral); + } + } + +void CLoopbackTestStepBase::TestErrorCodeAndDescriptorL(TInt aErrCode, TInt aExpectedErrCode, const TDesC8& aDesC, const TDesC8& aExpectedDesC, const TDesC& aMessage) + { + if ( (aExpectedErrCode == aErrCode) && (aDesC.Compare(aExpectedDesC) == 0) ) + { + INFO_PRINTF4(_L("[%S]. err[%d], and string [%S] as expected. OK."), &aMessage, aErrCode, &aExpectedDesC); + } + else if (aExpectedErrCode == aErrCode) + { + ERR_PRINTF5(_L("Failed: [%S]. err[%d], expected [%d]. Leaving with [%d])."), &aMessage, aErrCode, aExpectedErrCode, aErrCode); + User::Leave(aErrCode); + } + else + { + ERR_PRINTF4(_L("Failed: [%S]. String [%S] received, expected [%S]. Leaving with KErrGeneral."), &aMessage, &aDesC, &aExpectedDesC); + User::Leave(KErrGeneral); + } + } + +void CLoopbackTestStepBase::TestErrorCodeAndDescriptorL(TInt aErrCode, const TDesC8& aDesC, const TDesC8& aExpectedDesC, const TDesC& aMessage) + { + TestErrorCodeAndDescriptorL(aErrCode, KErrNone, aDesC, aExpectedDesC, aMessage); + } + +CLoopbackTestStep1::~CLoopbackTestStep1() + { + } + +CLoopbackTestStep1::CLoopbackTestStep1() : CLoopbackTestStepBase(KLoopackConfigTestNumber1) + { + // Call base class method to set up the human readable name for logging + SetTestStepName(KLoopbackTestStep1); + } + +TVerdict CLoopbackTestStep1::doTestStepL() +/** +Test that two different sets of loopback ports can read/write to their corresponding loopback port +The test's ini file is configured to have commPort1 and commPort2 as loopback ports, and +commPort3 and commPort4 as loopback ports +*/ + { + // open the 4 ports + TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") ); + TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") ); + TestErrorCodeL( iCommPort3.Open(iCommServer, KPortName3, ECommExclusive, ECommRoleDCE), _L("Opening comm port 3") ); + TestErrorCodeL( iCommPort4.Open(iCommServer, KPortName4, ECommExclusive, ECommRoleDCE), _L("Opening comm port 4") ); + + // There are a total of 4 writes (one to and from each port) + // 2 of the reads occur before the write and 2 after + + // Issue the two reads before the writes + TRequestStatus readStatus1, readStatus2; + TBuf8 readBuf1; + TBuf8 readBuf2; + iCommPort1.ReadOneOrMore(readStatus1, readBuf1); + iCommPort2.ReadOneOrMore(readStatus2, readBuf2); + + // Issue the writes on each port + TRequestStatus writeStatus1, writeStatus2, writeStatus3, writeStatus4; + iCommPort1.Write(writeStatus1, KWriteBuf1); + iCommPort2.Write(writeStatus2, KWriteBuf2); + iCommPort3.Write(writeStatus3, KWriteBuf3); + iCommPort4.Write(writeStatus4, KWriteBuf4); + + User::WaitForRequest(writeStatus1); + TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1")); + User::WaitForRequest(writeStatus2); + TestErrorCodeL(writeStatus2.Int(), _L("Writing to comm port 2")); + User::WaitForRequest(writeStatus3); + TestErrorCodeL(writeStatus3.Int(), _L("Writing to comm port 3")); + User::WaitForRequest(writeStatus4); + TestErrorCodeL(writeStatus4.Int(), _L("Writing to comm port 4")); + + // Check that the first 2 reads completed successfully + User::WaitForRequest(readStatus1); + TestErrorCodeAndDescriptorL(readStatus1.Int(), readBuf1, KWriteBuf2, _L("Read from comm port 1")); + User::WaitForRequest(readStatus2); + TestErrorCodeAndDescriptorL(readStatus2.Int(), readBuf2, KWriteBuf1, _L("Read from comm port 2")); + + // Issue the 2 reads after the writes and make sure they complete successfully + TRequestStatus readStatus3, readStatus4; + TBuf8 readBuf3; + TBuf8 readBuf4; + + iCommPort3.ReadOneOrMore(readStatus3, readBuf3); + User::WaitForRequest(readStatus3); + TestErrorCodeAndDescriptorL(readStatus3.Int(), readBuf3, KWriteBuf4, _L("Read from comm port 3")); + + iCommPort4.ReadOneOrMore(readStatus4, readBuf4); + User::WaitForRequest(readStatus4); + TestErrorCodeAndDescriptorL(readStatus4.Int(), readBuf4, KWriteBuf3, _L("Read from comm port 4")); + + return TestStepResult(); + } + +CLoopbackTestStep2::~CLoopbackTestStep2() + { + } + +CLoopbackTestStep2::CLoopbackTestStep2() : CLoopbackTestStepBase(KLoopackConfigTestNumber2) + { + // Call base class method to set up the human readable name for logging + SetTestStepName(KLoopbackTestStep2); + } + +TVerdict CLoopbackTestStep2::doTestStepL() +/** +Test that writes are successfully queued and sent. +The 2 ports opened are configured as loopback ports in the ini file +*/ + { + TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") ); + TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") ); + + // Issue 2 writes immediately one after the other in each direction + TRequestStatus writeStatus1, writeStatus2, writeStatus3, writeStatus4; + iCommPort1.Write(writeStatus1, KWriteBuf1); + iCommPort1.Write(writeStatus2, KWriteBuf2); + + iCommPort2.Write(writeStatus3, KWriteBuf3); + iCommPort2.Write(writeStatus4, KWriteBuf4); + + TBool writesSuccessful = EFalse; + User::WaitForRequest(writeStatus1); + User::WaitForRequest(writeStatus2); + User::WaitForRequest(writeStatus3); + User::WaitForRequest(writeStatus4); + if (writeStatus1 == KErrNone && writeStatus2 == KErrNone && + writeStatus3 == KErrNone && writeStatus4 == KErrNone) + { + writesSuccessful = ETrue; + } + TestBooleanTrueL(writesSuccessful, _L("Writing to comm ports successful")); + + // Issue the reads + TRequestStatus readStatus1, readStatus2, readStatus3, readStatus4; + TBuf8 readBuf1, readBuf2, readBuf3, readBuf4; + iCommPort2.ReadOneOrMore(readStatus1, readBuf1); + User::WaitForRequest(readStatus1); + iCommPort2.ReadOneOrMore(readStatus2, readBuf2); + User::WaitForRequest(readStatus2); + iCommPort1.ReadOneOrMore(readStatus3, readBuf3); + iCommPort1.ReadOneOrMore(readStatus4, readBuf4); + User::WaitForRequest(readStatus4); + User::WaitForRequest(readStatus3); + + // Make sure the requests are all successful + TestBooleanTrueL(readStatus1 == KErrNone && readStatus2 == KErrNone && + readStatus3 == KErrNone && readStatus4 == KErrNone, + _L("Check that reading from comm ports returned no errors")); + TestBooleanTrueL(readBuf1.Compare(KWriteBuf1) == 0 && readBuf2.Compare(KWriteBuf2) == 0 && + readBuf3.Compare(KWriteBuf3) == 0 || readBuf4.Compare(KWriteBuf4) == 0, + _L("Check that correct values were read from comm ports")); + + return TestStepResult(); + } + +CLoopbackTestStep3::~CLoopbackTestStep3() + { + } + +CLoopbackTestStep3::CLoopbackTestStep3() : CLoopbackTestStepBase(KLoopackConfigTestNumber3) + { + // Call base class method to set up the human readable name for logging + SetTestStepName(KLoopbackTestStep3); + } + +TVerdict CLoopbackTestStep3::doTestStepL() +/** +Test the 3 different orders in which read/write operations can occur as follows: + 1. The read is issued, then the write is issued, then the data is sent across the port + 2. The write is issued, then the read is issued, then the data is sent across the port + 3. The write is issued, then the data is sent across the port, then the read is issued +*/ + { + TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") ); + TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") ); + + TRequestStatus readStatus1, readStatus2; + TBuf8 readBuf1, readBuf2; + TRequestStatus writeStatus1; + + // 1. The read is issued, then the write is issued, then the data is sent across the port + + // fist issue the read + iCommPort1.ReadOneOrMore(readStatus1, readBuf1); + + // second issue the write + iCommPort2.Write(writeStatus1, KWriteBuf1); + User::WaitForRequest(writeStatus1); + TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1")); + + User::WaitForRequest(readStatus1); + TestErrorCodeAndDescriptorL(readStatus1.Int(), readBuf1, KWriteBuf1, _L("Read from comm port 1")); + + // 2. The write is issued, then the read is issued, then the data is sent across the port + + // first issue the write + iCommPort1.Write(writeStatus1, KWriteBuf2); + User::WaitForRequest(writeStatus1); + TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1")); + + // second issue the read before the data has the chance to be sent across the port + iCommPort2.ReadOneOrMore(readStatus2, readBuf2); + User::WaitForRequest(readStatus2); + TestErrorCodeAndDescriptorL(readStatus2.Int(), readBuf2, KWriteBuf2, _L("Read from comm port 2")); + + // 3. The write is issued, then the data is sent across the port, then the read is issued + + // first issue the write + iCommPort1.Write(writeStatus1, KWriteBuf2); + User::WaitForRequest(writeStatus1); + TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1")); + // second wait until the data has the chance to be sent across the port (this delay is configured + // to be 0.1s in the ini file, so we wait a bit longer) + User::After(2*KConfiguredPortDelayMicroseconds); + + // third the read is issued + iCommPort2.ReadOneOrMore(readStatus2, readBuf2); + User::WaitForRequest(readStatus2); + TestErrorCodeAndDescriptorL(readStatus2.Int(), readBuf2, KWriteBuf2, _L("Read from comm port 2")); + + return TestStepResult(); + } + +CLoopbackTestStep4::~CLoopbackTestStep4() + { + } + +CLoopbackTestStep4::CLoopbackTestStep4() : CLoopbackTestStepBase(KLoopackConfigTestNumber4) + { + // Call base class method to set up the human readable name for logging + SetTestStepName(KLoopbackTestStep4); + } + +TVerdict CLoopbackTestStep4::doTestStepL() +/** +Test reading/writing to an un-opened port, or a port whose loopback port is un-opened +*/ + { + TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") ); + + TRequestStatus readStatus; + TBuf8 readBuf; + TRequestStatus writeStatus; + + // issue read request before port is opened + iCommPort1.ReadOneOrMore(readStatus, readBuf); + // iCommPort2's loopback port is not yet opened, so write should fail + iCommPort1.Write(writeStatus, KWriteBuf1); + User::WaitForRequest(writeStatus); + TestErrorCodeL(writeStatus.Int(), KErrNotReady, _L("Writing to comm port 1 before port 2 is opened")); + + TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") ); + + iCommPort2.Write(writeStatus, KWriteBuf2); + User::WaitForRequest(writeStatus); + + // now wait for read request which should complete from before iCommPort2 was opened + User::WaitForRequest(readStatus); + + TestErrorCodeL(writeStatus.Int(), _L("Writing to comm port 1 after port 2 is opened")); + TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf2, _L("Read from comm port 2")); + + iCommPort2.Close(); + + // iCommPort1 is now closed, so both write should fail + iCommPort1.Write(writeStatus, KWriteBuf1); + User::WaitForRequest(writeStatus); + TestErrorCodeL(writeStatus.Int(), KErrNotReady, _L("Writing to comm port 1 after port 2 is closed")); + + return TestStepResult(); + } + +CLoopbackTestStep5::~CLoopbackTestStep5() + { + } + +CLoopbackTestStep5::CLoopbackTestStep5() : CLoopbackTestStepBase(KLoopackConfigTestNumber5) + { + // Call base class method to set up the human readable name for logging + SetTestStepName(KLoopbackTestStep5); + } + +TVerdict CLoopbackTestStep5::doTestStepL() +/** +Test filling up the read and write queues +In this test, the read and write queues are set to be 1 entry in size +*/ + { + INFO_PRINTF1(_L("Starting Loopback test step 5")); + + TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") ); + TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") ); + + TRequestStatus readStatus1; + TBuf8 readBuf1; + TRequestStatus writeStatus1, writeStatus2; + + // Issue 2 writes immediately after each other. Since the queue is only set to 1 entry + // it will be full after the first write, so the second should return with KErrOverflow + iCommPort2.Write(writeStatus1, KWriteBuf1); + User::WaitForRequest(writeStatus1); + TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 2")); + + iCommPort2.Write(writeStatus2, KWriteBuf2); + User::WaitForRequest(writeStatus2); + TestErrorCodeL(writeStatus2.Int(), KErrOverflow, _L("Writing to comm port 2")); + + // wait until the data has the chance to be sent across the port (this delay is configured + // to be 1s in the ini file, so we wait a bit longer) + User::After(2*KConfiguredPortLongDelayMicroseconds); + + // After this delay, the buffer should have been 'sent' to the read queue of the loopback port + // Again, issue 2 writes immediately after each other, the first one filling up the queue + // meaning the second will return with KErrOverflow + iCommPort2.Write(writeStatus2, KWriteBuf2); + User::WaitForRequest(writeStatus2); + TestErrorCodeL(writeStatus2.Int(), _L("Writing to comm port 2")); + + iCommPort2.Write(writeStatus2, KWriteBuf2); + User::WaitForRequest(writeStatus2); + TestErrorCodeL(writeStatus2.Int(), KErrOverflow, _L("Writing to comm port 2")); + + // Wait for the amount of time it should take for the data to cross the port. + // After the delay the buffer should not be sent because the read buffer on the loopback port is full + User::After(2*KConfiguredPortLongDelayMicroseconds); + + iCommPort2.Write(writeStatus2, KWriteBuf2); + User::WaitForRequest(writeStatus2); + TestErrorCodeL(writeStatus2.Int(), KErrOverflow, _L("Writing to comm port 2")); + + // Issue reads for the 2 writes that have been sent successfully + // Since the second read has not yet been sent across the port, it should take more than the + // time configured to send a buffer + + // Get the time before the reads + TTime beforeTime; + beforeTime.UniversalTime(); + + iCommPort1.ReadOneOrMore(readStatus1, readBuf1); + User::WaitForRequest(readStatus1); + TestErrorCodeAndDescriptorL(readStatus1.Int(), readBuf1, KWriteBuf1, _L("Read from comm port 1")); + + iCommPort1.ReadOneOrMore(readStatus1, readBuf1); + User::WaitForRequest(readStatus1); + + // Get the time after the read + TTime afterTime; + afterTime.UniversalTime(); + + // Make sure the read was successful + TestErrorCodeAndDescriptorL(readStatus1.Int(), readBuf1, KWriteBuf2, _L("Read from comm port 1")); + + // Make sure the read took at least the amount of time as the configured delay + // We need a long time-out here because the resolution of the timer may cause it to expire prematurely + const TTimeIntervalMicroSeconds delayTime((TInt)(0.5*KConfiguredPortLongDelayMicroseconds)); + TTime netTime = afterTime - delayTime; + TestBooleanTrueL(netTime > beforeTime, _L("Check there was a delay writing to the port")); + + return TestStepResult(); + } + +CLoopbackTestStep6::~CLoopbackTestStep6() + { + } + +CLoopbackTestStep6::CLoopbackTestStep6() : CLoopbackTestStepBase(KLoopackConfigTestNumber6) + { + // Call base class method to set up the human readable name for logging + SetTestStepName(KLoopbackTestStep6); + } + +TVerdict CLoopbackTestStep6::doTestStepL() +/** +Test reading an entry with too small a read buffer +*/ + { + INFO_PRINTF1(_L("Starting Loopback test step 6")); + + TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") ); + TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") ); + + TRequestStatus readStatus1; + TBuf8 smallReadBuf; + TBuf8 largeEnoughReadBuf1; + TRequestStatus writeStatus2; + + iCommPort2.Write(writeStatus2, KWriteBuf1); + User::WaitForRequest(writeStatus2); + TestErrorCodeL(writeStatus2.Int(), _L("Writing to comm port 1")); + + // Issue read that should fail from too small of a buffer + iCommPort1.ReadOneOrMore(readStatus1, smallReadBuf); + User::WaitForRequest(readStatus1); + TestErrorCodeL(readStatus1.Int(), KErrOverflow, _L("Check that read fails becuase too small buffer supplied")); + + // Issue read that should succeed + iCommPort1.ReadOneOrMore(readStatus1, largeEnoughReadBuf1); + User::WaitForRequest(readStatus1); + TestErrorCodeAndDescriptorL(readStatus1.Int(), largeEnoughReadBuf1, KWriteBuf1, _L("Read from comm port 1")); + + return TestStepResult(); + } + +CLoopbackTestStep7::~CLoopbackTestStep7() + { + } + +CLoopbackTestStep7::CLoopbackTestStep7() : CLoopbackTestStepBase(KLoopackConfigTestNumber7) + { + // Call base class method to set up the human readable name for logging + SetTestStepName(KLoopbackTestStep7); + } + +TVerdict CLoopbackTestStep7::doTestStepL() +/** +Test issuing write with too large of a buffer +*/ + { + TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") ); + TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") ); + + // Create the large buffer + HBufC8 *hugeHeapDescriptor = HBufC8::NewLC(KHugeBufferSize); + TPtr8 hugeDescriptor = hugeHeapDescriptor->Des(); + hugeDescriptor.AppendFill('a', KHugeBufferSize); + + // Issue the write with the buffer that is too large + TRequestStatus writeStatus1, readStatus1; + iCommPort2.Write(writeStatus1, hugeDescriptor); + User::WaitForRequest(writeStatus1); + TestErrorCodeL(writeStatus1.Int(), KErrArgument, _L("Writing to comm port 1")); + + // Make sure write still works with normal sized buffer + iCommPort2.Write(writeStatus1, KWriteBuf1); + User::WaitForRequest(writeStatus1); + TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1")); + + TBuf8 readBuf; + iCommPort1.ReadOneOrMore(readStatus1, readBuf); + User::WaitForRequest(readStatus1); + if (readStatus1 != KErrNone) + { + INFO_PRINTF1(_L("Failed read")); + SetTestStepResult(EFail); + } + + CleanupStack::PopAndDestroy(hugeHeapDescriptor); + + return TestStepResult(); + } + +CLoopbackTestStep8::~CLoopbackTestStep8() + { + } + +CLoopbackTestStep8::CLoopbackTestStep8() : CLoopbackTestStepBase(KLoopackConfigTestNumber8) + { + // Call base class method to set up the human readable name for logging + SetTestStepName(KLoopbackTestStep8); + } + +TVerdict CLoopbackTestStep8::doTestStepL() +/** +Test wrapping around the queue by issuing more writes than the queue size (configured to 2 in the ini file) +*/ + { + TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") ); + TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") ); + + TRequestStatus writeStatus, readStatus; + iCommPort2.Write(writeStatus, KWriteBuf1); + User::WaitForRequest(writeStatus); + TestErrorCodeL(writeStatus.Int(), _L("Writing to comm port 1")); + + iCommPort2.Write(writeStatus, KWriteBuf2); + User::WaitForRequest(writeStatus); + TestErrorCodeL(writeStatus.Int(), _L("Writing to comm port 1")); + + TBuf8 readBuf; + iCommPort1.ReadOneOrMore(readStatus, readBuf); + User::WaitForRequest(readStatus); + TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf1, _L("Read from comm port 1")); + + iCommPort2.Write(writeStatus, KWriteBuf3); + User::WaitForRequest(writeStatus); + TestErrorCodeL(writeStatus.Int(), _L("Writing to comm port 1")); + + iCommPort1.ReadOneOrMore(readStatus, readBuf); + User::WaitForRequest(readStatus); + TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf2, _L("Read from comm port 1")); + + iCommPort1.ReadOneOrMore(readStatus, readBuf); + User::WaitForRequest(readStatus); + TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf3, _L("Read from comm port 1")); + + return TestStepResult(); + } + +CLoopbackTestStep9::~CLoopbackTestStep9() + { + } + +CLoopbackTestStep9::CLoopbackTestStep9() : CLoopbackTestStepBase(KLoopackConfigTestNumber9) + { + // Call base class method to set up the human readable name for logging + SetTestStepName(KLoopbackTestStep9); + } + +TVerdict CLoopbackTestStep9::doTestStepL() +/** +Test read cancel +*/ + { + TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") ); + TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") ); + + TRequestStatus writeStatus, readStatus; + iCommPort1.Write(writeStatus, KWriteBuf1); + User::WaitForRequest(writeStatus); + TestErrorCodeL(writeStatus.Int(), _L("Writing to comm port 1")); + + TBuf8 readBuf; + iCommPort2.ReadOneOrMore(readStatus, readBuf); + // Cancel the buffer before it has the chance to complete + iCommPort2.ReadCancel(); + User::WaitForRequest(readStatus); + TestErrorCodeL(readStatus.Int(), KErrCancel, _L("Check that cancelled request returns KErrCancel")); + + // Make sure the read still works + iCommPort2.ReadOneOrMore(readStatus, readBuf); + User::WaitForRequest(readStatus); + TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf1, _L("Read from comm port 1")); + + return TestStepResult(); + } + +CLoopbackTestStep10::~CLoopbackTestStep10() + { + } + +CLoopbackTestStep10::CLoopbackTestStep10() : CLoopbackTestStepBase(KLoopackConfigTestNumber10) + { + // Call base class method to set up the human readable name for logging + SetTestStepName(KLoopbackTestStep10); + } + +TVerdict CLoopbackTestStep10::doTestStepL() +/** +Test flow control +*/ + { + TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") ); + TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") ); + + TRequestStatus writeStatus1; + iCommPort1.Write(writeStatus1, KWriteBuf1); + SetFlowControl(KPortUnitNum1, ETrue); + SetFlowControl(KPortUnitNum2, ETrue); + User::WaitForRequest(writeStatus1); + TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1")); + + TRequestStatus timerStatus, readStatus; + TBuf8 readBuf; + iCommPort2.ReadOneOrMore(readStatus, readBuf); + + RTimer timer; + timer.CreateLocal(); + timer.After(timerStatus, 3*KConfiguredPortDelayMicroseconds); + + User::WaitForRequest(readStatus, timerStatus); + + SetFlowControl(KPortUnitNum1, EFalse); + SetFlowControl(KPortUnitNum2, EFalse); + TestBooleanTrueL(timerStatus == KErrNone && readStatus != KErrNone, _L("Check that setting flow control causes read to be stopped")); + + User::WaitForRequest(readStatus); + TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf1, _L("Read from comm port 1")); + + return TestStepResult(); + } + +CLoopbackTestStep11::~CLoopbackTestStep11() + { + } + +CLoopbackTestStep11::CLoopbackTestStep11() : CLoopbackTestStepBase(KLoopackConfigTestNumber11) + { + // Call base class method to set up the human readable name for logging + SetTestStepName(KLoopbackTestStep11); + } + +TVerdict CLoopbackTestStep11::doTestStepL() +/** +Test setting read result +*/ + { + TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") ); + TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") ); + + TRequestStatus writeStatus1; + iCommPort1.Write(writeStatus1, KWriteBuf1); + User::WaitForRequest(writeStatus1); + TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1")); + + TRequestStatus readStatus; + TBuf8 readBuf; + iCommPort2.ReadOneOrMore(readStatus, readBuf); + + SetReadResult(KPortUnitNum2, KErrNotFound); + + User::WaitForRequest(readStatus); + + // Make sure everything still works + SetReadResult(KPortUnitNum2, KErrNone); + TestErrorCodeL(readStatus.Int(), KErrNotFound, _L("Check that SetReadResult causes Read to return error")); + + iCommPort1.Write(writeStatus1, KWriteBuf2); + User::WaitForRequest(writeStatus1); + TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1")); + + iCommPort2.ReadOneOrMore(readStatus, readBuf); + User::WaitForRequest(readStatus); + TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf2, _L("Read from comm port 1")); + + // Now test failing a write + SetWriteResult(KPortUnitNum2, KErrNotFound); + iCommPort2.Write(writeStatus1, KWriteBuf3); + User::WaitForRequest(writeStatus1); + SetWriteResult(KPortUnitNum2, KErrNone); + TestErrorCodeL(writeStatus1.Int(), KErrNotFound, _L("Check that SetWriteResult causes Write to return error")); + + // Make sure we can't read this + TRequestStatus timerStatus; + RTimer timer; + timer.CreateLocal(); + iCommPort1.ReadOneOrMore(readStatus, readBuf); + timer.After(timerStatus, 3*KConfiguredPortDelayMicroseconds); + + User::WaitForRequest(readStatus, timerStatus); + TestBooleanTrueL(timerStatus == KErrNone && readStatus != KErrNone, _L("Write that was configured to fail completed successfully")); + + return TestStepResult(); + } + +CLoopbackTestStep12::~CLoopbackTestStep12() + { + } + +CLoopbackTestStep12::CLoopbackTestStep12() : CLoopbackTestStepBase(KLoopackConfigTestNumber12) + { + // Call base class method to set up the human readable name for logging + SetTestStepName(KLoopbackTestStep12); + } + +_LIT8(KWriteBuf,"12345"); +_LIT8(KDoubleWriteBuf,"1234512345"); +_LIT8(KWriteBufTabTerminator,"12345\t"); +_LIT8(KWriteBufNewlineTerminator,"12345\n"); +_LIT8(KWriteBufTabThenNewlineTerminator,"12345\t12345\n12345"); +_LIT8(KWriteBufNewlineThenTabTerminator,"12345\n12345\t12345"); +const TInt KWriteBufSegmentSize = 5; + +TVerdict CLoopbackTestStep12::doTestStepL() +/** +Test setting read result +*/ + { + TRequestStatus readStatus; + TBuf8 readBuf; + TRequestStatus writeStatus1; + + TCommConfig commConfigBuf; + TCommConfigV01& commConfig = commConfigBuf(); + commConfig.iTerminator[0] = '\t'; + commConfig.iTerminator[1] = '\n'; + commConfig.iTerminatorCount = 2; + + TestErrorCodeL( iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE), _L("Opening comm port 1") ); + TestErrorCodeL( iCommPort1.SetConfig(commConfigBuf), _L("Opening comm port 1") ); + TestErrorCodeL( iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE), _L("Opening comm port 2") ); + TestErrorCodeL( iCommPort2.SetConfig(commConfigBuf), _L("Opening comm port 2") ); + + // reads and writes are same size + iCommPort1.Write(writeStatus1, KWriteBuf); + User::WaitForRequest(writeStatus1); + TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1")); + + iCommPort2.ReadOneOrMore(readStatus, readBuf); + User::WaitForRequest(readStatus); + TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf, KWriteBuf, _L("Read from comm port 1")); + + + // test ReadOneOrMore + iCommPort1.Write(writeStatus1, KWriteBufTabThenNewlineTerminator); + User::WaitForRequest(writeStatus1); + TestErrorCodeL(writeStatus1.Int(), _L("Writing to comm port 1")); + + TBuf8 readBuf2; + iCommPort2.ReadOneOrMore(readStatus, readBuf2); + User::WaitForRequest(readStatus); + if (readBuf2.Compare(KWriteBufTabTerminator) != 0 || readStatus != KErrNone) + { + INFO_PRINTF1(_L("Failed write")); + SetTestStepResult(EFail); + } + + iCommPort2.ReadOneOrMore(readStatus, readBuf2); + User::WaitForRequest(readStatus); + TestErrorCodeL(readStatus.Int(), _L("Error in read status")); + TestErrorCodeL(readBuf2.Compare(KWriteBufNewlineTerminator), _L("Incorrect buffer received")); + + iCommPort2.ReadOneOrMore(readStatus, readBuf2); + User::WaitForRequest(readStatus); + if (readBuf2.Compare(KWriteBuf) != 0 || readStatus != KErrNone) + { + INFO_PRINTF1(_L("Failed write")); + SetTestStepResult(EFail); + } + + iCommPort1.Write(writeStatus1, KWriteBufNewlineThenTabTerminator); + User::WaitForRequest(writeStatus1); + TestErrorCodeL(writeStatus1.Int(), _L("Failed write")); + + iCommPort2.ReadOneOrMore(readStatus, readBuf2); + User::WaitForRequest(readStatus); + TestBooleanTrueL(readBuf2.Compare(KWriteBufNewlineTerminator) == 0 && readStatus == KErrNone, _L("Failed read")); + + iCommPort2.ReadOneOrMore(readStatus, readBuf2); + User::WaitForRequest(readStatus); + TestBooleanTrueL(readBuf2.Compare(KWriteBufTabTerminator) == 0 && readStatus == KErrNone, _L("Failed read")); + + iCommPort2.ReadOneOrMore(readStatus, readBuf2); + User::WaitForRequest(readStatus); + TestBooleanTrueL(readBuf2.Compare(KWriteBuf) == 0 || readStatus == KErrNone, _L("Failed read")); + + return TestStepResult(); + } + +CLoopbackTestStep13::~CLoopbackTestStep13() + { + } + +CLoopbackTestStep13::CLoopbackTestStep13() : CLoopbackTestStepBase(KLoopackConfigTestNumber13) + { + // Call base class method to set up the human readable name for logging + SetTestStepName(KLoopbackTestStep13); + } + +TVerdict CLoopbackTestStep13::doTestStepL() +/** +Test setting read result +*/ + { + TRequestStatus readStatus; + TRequestStatus writeStatus; + + TCommConfig commConfigBuf; + TCommConfigV01& commConfig = commConfigBuf(); + commConfig.iTerminator[0] = '\t'; + commConfig.iTerminator[1] = '\n'; + commConfig.iTerminatorCount = 2; + + TInt err = iCommPort1.Open(iCommServer, KPortName1, ECommExclusive, ECommRoleDCE); + err = iCommPort1.SetConfig(commConfigBuf); + TestErrorCodeL(err, _L("Failed loading port")); + + err = iCommPort2.Open(iCommServer, KPortName2, ECommExclusive, ECommRoleDCE); + err = iCommPort2.SetConfig(commConfigBuf); + TestErrorCodeL(err, _L("Failed loading port")); + + // make sure Read works + iCommPort1.Write(writeStatus, KWriteBufNewlineThenTabTerminator); + User::WaitForRequest(writeStatus); + TestErrorCodeL(writeStatus.Int(), _L("Write failed")); + + TBuf8 readBuf2; + iCommPort2.Read(readStatus, readBuf2); + User::WaitForRequest(readStatus); + TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf2, KWriteBufNewlineTerminator, _L("Read from comm port 1")); + + iCommPort2.Read(readStatus, readBuf2); + User::WaitForRequest(readStatus); + TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf2, KWriteBufTabTerminator, _L("Read from comm port 1")); + + TRequestStatus timerStatus; + TBuf8<2*KWriteBufSegmentSize> readBuf4; + iCommPort2.Read(readStatus, readBuf4); + + RTimer timer; + timer.CreateLocal(); + timer.After(timerStatus, 10*KConfiguredPortDelayMicroseconds); + + User::WaitForRequest(readStatus, timerStatus); + TestBooleanTrueL(timerStatus == KErrNone && readStatus != KErrNone, _L("Check that read didn't complete")); + + iCommPort1.Write(writeStatus, KWriteBuf); + User::WaitForRequest(writeStatus); + TestErrorCodeL(writeStatus.Int(), _L("Failed write")); + + User::WaitForRequest(readStatus); + TestErrorCodeAndDescriptorL(readStatus.Int(), readBuf4, KDoubleWriteBuf, _L("Read from comm port 1")); + + return TestStepResult(); + } +