diff -r 000000000000 -r bde4ae8d615e os/kernelhwsrv/kerneltest/e32test/pipe/t_pipe.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/kernelhwsrv/kerneltest/e32test/pipe/t_pipe.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,3451 @@ +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "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: +// e32test\pipe\t_pipe.cpp +// Overview: +// Test pipe mechanism +// API Information: +// RPipe +// Details: +// - Create various leagal and illegal pipe and verify that pipe +// functionality works as stated in requirements. +// - Create Named and UnNamed Pipes and verify. +// - Test Pipes communication in multiprocess , multithreaded , single process +// single threaded environment. +// Platforms/Drives/Compatibility: +// All. +// Assumptions/Requirement/Pre-requisites: +// Refer Pipes design and requirement document. +// 1. SGL.GT0314.202 PREQ1460 Design Doc +// 2. SGL.GT0314.203 PREQ1460 Pipe Functional Specification +// Refer Pipe test specification document. +// 1. SGL.GT0314.601 Pipes_Test_Specifications +// Failures and causes: +// Base Port information: +// MMP File: +// t_pipe.mmp +// +// + +/** + @STMTestCaseID KBASE-T_PIPE-0217 + @SYMPREQ PREQ1460 + @SYMREQ REQ6141 + @SYMCR CR0923 + @SYMTestCaseDesc Pipe functional tests + @SYMTestPriority High + @SYMTestActions Tests the functionality of the pipe. Success and failure tests are performed. + @SYMTestExpectedResults Test should pass +*/ + +#define __E32TEST_EXTENSION__ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "RPipe.h" + +LOCAL_D RTest test(_L("t_pipe")); + + +//if the test is to run under the debugger, uncomment the following line + + + +const TInt KHeapSize=0x2000; + + + +// Test Data +_LIT8(KTestData,"Pipe Data To Be Passed"); +_LIT8(KTestData1,"P"); +_LIT8(KTestData2,"Pipe Data To Be Passed"); +_LIT8(KTestData3,"ipe Data To Be Passed"); + + +// Test Pipe Names +_LIT(KPipe1Name,"TestPipe1"); +_LIT(KPipe3Name,"TestPipe3"); + +//Global semaphore name +_LIT(KSemaphoreName,"Semaphore1"); + +// Pipename of max pipe length 80 Charecters. +_LIT(KMaxPipeName,"abcdefghijklmnopqrstabcdefghijklmnopqrstabcdefghijklmnopqrstabcdefghijklmnopqrst"); +// PipeName of max pipe length plus one ,81 charecters +_LIT(KMaxPipeNamePlusOne,"abcdefghijklmnopqrstabcdefghijklmnopqrstabcdefghijklmnopqrstabcdefghijklmnopqrst1"); + +// Thread Name Constants +_LIT(KThread2Name, "thread2"); +_LIT(KThread3Name, "thread3"); +_LIT(KThread4Name, "thread4"); +_LIT(KThread5Name, "thread5"); +_LIT(KReaderThread, "ReaderThread"); +_LIT(KWriterThread, "WriterThread"); +_LIT(KThread8Name, "thread8"); +_LIT(KThread9Name, "thread9"); +_LIT(KThread11Name, "thread11"); + +// Test Process Name Constants +_LIT(KProcessName, "t_pipe2.exe"); + + +// Following class is used to pass thread handle information to different threads. +class TData + { +public: + TData(RPipe* aReadEnd, RPipe *aWriteEnd); + TData(RPipe* aReadEnd, RPipe *aWriteEnd, const TDesC8* aPipeData, TInt aIterations=1); + RPipe* iReadEnd; + RPipe* iWriteEnd; + const TDesC8* iPipeData; + TInt iIterations; + }; + +TData::TData(RPipe* aReadEnd , RPipe *aWriteEnd) + :iReadEnd(aReadEnd),iWriteEnd(aWriteEnd), iPipeData(NULL), iIterations(NULL) + {} + +TData::TData(RPipe* aReadEnd , RPipe *aWriteEnd, const TDesC8* aPipeData, TInt aIterations) + :iReadEnd(aReadEnd),iWriteEnd(aWriteEnd), iPipeData(aPipeData), iIterations(aIterations) + {} + +/** +A utility class for running functions in other threads/processes +*/ +class TTestRemote + { +public: + virtual TInt WaitForExitL()=0; + virtual ~TTestRemote() + {} + + virtual void Rendezvous(TRequestStatus& aStatus) =0; + +protected: + TTestRemote() + {} + + static TInt RunFunctor(TAny* aFunctor) + { + TFunctor& functor = *(TFunctor*)aFunctor; + functor(); + return KErrNone; + } + + TRequestStatus iLogonStatus; + static TInt iCount; + }; +TInt TTestRemote::iCount=0; + +class TTestThread : public TTestRemote + { +public: + TTestThread(const TDesC& aName, TThreadFunction aFn, TAny* aData, TBool aAutoResume=ETrue) + { + Init(aName, aFn, aData, aAutoResume); + } + + /** + Run aFunctor in another thread + */ + TTestThread(const TDesC& aName, TFunctor& aFunctor, TBool aAutoResume=ETrue) + { + Init(aName, RunFunctor, &aFunctor, aAutoResume); + } + + ~TTestThread() + { + //RTest::CloseHandleAndWaitForDestruction(iThread); + iThread.Close(); + } + + void Resume() + { + iThread.Resume(); + } + + /** + If thread exited normally, return its return code + Otherwise, leave with exit reason + */ + virtual TInt WaitForExitL() + { + User::WaitForRequest(iLogonStatus); + const TInt exitType = iThread.ExitType(); + const TInt exitReason = iThread.ExitReason(); + + __ASSERT_ALWAYS(exitType != EExitPending, User::Panic(_L("TTestThread"),0)); + + if(exitType != EExitKill) + User::Leave(exitReason); + + return exitReason; + } + + virtual void Rendezvous(TRequestStatus& aStatus) + { + iThread.Rendezvous(aStatus); + } + +private: + void Init(const TDesC& aName, TThreadFunction aFn, TAny* aData, TBool aAutoResume) + { + TKName name(aName); + name.AppendFormat(_L("-%d"), iCount++); + TInt r=iThread.Create(name, aFn, KDefaultStackSize, KHeapSize, KHeapSize, aData); + User::LeaveIfError(r); + + iThread.Logon(iLogonStatus); + __ASSERT_ALWAYS(iLogonStatus == KRequestPending, User::Panic(_L("TTestThread"),0)); + + if(aAutoResume) + iThread.Resume(); + } + + + + RThread iThread; + }; + + +/** +Non blocking reads, verifying data as expected +*/ +TInt TestThread2(TAny* aData) + { + RTest test(_L("t_pipe_t2")); + + test.Start(_L("Thread 2")); + test.Printf(_L("THREAD 2 called by TestMultiThreadNamedPipes And TestMultiThreadUnNamedPipes\n")); + + TBuf8<50> cPipeReadData; + TInt ret,readsize; + + + + TData& data = *(TData *)aData; // aData will have pipe handles and size. + + + test.Next(_L("PIPE TEST:Thread 2-1 Read 1 byte of data from the pipe : Test for success\n")); + readsize = 1; + + ret = data.iReadEnd->Read(cPipeReadData ,readsize); + test_Equal(readsize, ret); + + + test.Next(_L("PIPE TEST:Thread 2-2 Validate 1 byte received is correct\n")); + ret = cPipeReadData.Compare(KTestData1); + test_KErrNone(ret); + + + test.Next(_L("PIPE TEST:Thread 2-3 Read remaining data from the pipe\n")); + readsize = 21; + ret = data.iReadEnd->Read(cPipeReadData , readsize); + test_Equal(readsize, ret); + + test.Next(_L("PIPE TEST:Thread 2-4 Validate received data\n")); + ret = cPipeReadData.Compare(KTestData3); + test_KErrNone(ret); + + test.End(); + test.Close(); + return KErrNone; + + +} +/**************************************************************************** + This function is used as thread to test Unnamed pipes. + TestMultiThreadUnNamedPipes() will use this function. + TestMultiThreadNamedPipes() will use this function. + @aData : Used to pass the pipe and handle its size information. + + Return Value : TInt + +******************************************************************************/ +TInt TestThread3(TAny* aData) { + + + TInt ret, aWriteSize; + + TBufC8<50> cTestData3(KTestData2); // Test Data + + + + TData& data = *(TData *)aData; // aData will have pipe handles and size. + RTest test(_L("t_pipe_t3")); + + test.Start(_L("Thread 3")); + + test.Printf(_L(" THREAD 3 called by TestMultiThreadNamedPipes And TestMultiThreadUnNamedPipes\n")); + + test.Next(_L("PIPE TEST:Thread 3-1 Call Write blocking and write data\n")); + + // Call Writeblocking function. Write one byte of data. + + aWriteSize = cTestData3.Length(); + ret = data.iWriteEnd->WriteBlocking(cTestData3,aWriteSize); + test_Equal(aWriteSize, ret); + + // Call Writeblocking function. Write aSize bye data. + + // Write data so that pipe get filled. + test.Next(_L("PIPE TEST:Thread 3-2 Write data till pipe is filled up \n")); + ret = data.iWriteEnd->WriteBlocking(cTestData3,aWriteSize); + test_Equal(aWriteSize, ret); + + test.End(); + test.Close(); + return KErrNone; +} +/**************************************************************************** + This function is used as thread to test Unnamed pipes. + TestMultiThreadUnNamedPipes() will use this function. + + @aData : Used to pass the pipe and handle its size information. + + Return Value : TInt + +******************************************************************************/ +//TRequestStatus stat1; +TInt TestThread4(TAny* aData) { + + TData& data = *(TData *)aData; // aData will have pipe handles and size. + TRequestStatus stat1; + TBuf8<150> cPipeReadData; + TInt ret; + RTest test(_L("t_pipe_t4")); + test.Start(_L("Thread 4")); + + RSemaphore sem; // Handle to the global semaphore + ret = sem.OpenGlobal(KSemaphoreName); // Access to the global semaphore identified by its name. + test(ret == KErrNone); + + + + test.Printf(_L("Thread 4:Created by TestNotifyMechanismPipes.\n")); + test.Next(_L("PIPE TEST:Thread 4-1 Register Notify Data available request.\n")); + data.iReadEnd->NotifyDataAvailable(stat1); + test_Equal(KRequestPending, stat1.Int()); + sem.Signal(); //signal to say that we have issued notification request + + test.Next(_L("PIPE TEST:Thread 4-2 Wait till notified for data. Check for Available.\n")); + User::WaitForRequest(stat1); + test ( stat1.Int() == KErrNone); + + test.Next(_L("PIPE TEST:Thread 4-3 Read One byte of data from the pipe.\n")); + sem.Wait(); //wait for signal that 1 byte should be read + ret = data.iReadEnd->Read(cPipeReadData,1); + test (ret == 1); + + test.Next(_L("PIPE TEST:Thread 4-4 Verify data is correct ?.\n")); + test (KErrNone == cPipeReadData.Compare(KTestData1)); + + test.Next(_L("PIPE TEST:Thread 4-5 Read remaining data from the pipe.\n")); + ret = data.iReadEnd->Read(cPipeReadData,21); + test (ret == 21); + + + test.Next(_L("PIPE TEST:Thread 4-6 Verify data is correct ?.\n")); + test (KErrNone == cPipeReadData.Compare(KTestData3)); + + sem.Signal(); //signalling to the main thread to continue its operation + sem.Close(); //closing the handle to the semaphore + test.End(); + test.Close(); + + return KErrNone; + +} + +/**************************************************************************** + This function is used as thread to test Unnamed pipes. + TestWaitMechanismPipes() will use this function. + + @aData : Used to pass the pipe and handle its size information. + + Return Value : TInt + +******************************************************************************/ + +TInt TestThread5(TAny* aData) { + + TData& data = *(TData *)aData; // aData will have pipe handles and size. + TRequestStatus stat1; + TInt ret; + + RTest test(_L("t_pipe_t5")); + + test.Start(_L("Thread 5")); + test.Printf(_L("PIPE TEST:Thread 5:Created by TestWaitMechanismPipes.\n")); + + test.Next(_L("PIPE TEST:Thread 5-1:Register one more request to wait till open to read. It shall not allow\n")); + data.iWriteEnd->Wait(KPipe3Name, stat1); + test (stat1.Int() == KErrInUse); + data.iWriteEnd->WaitForReader(KPipe3Name, stat1); + test (stat1.Int() == KErrInUse); + + + test.Next(_L("PIPE TEST:Thread 5-2:Open Pipe handle to Read.\n")); + ret = data.iReadEnd->Open(KPipe3Name,RPipe::EOpenToRead); + test(ret == KErrNone); + + test.End(); + test.Close(); + return KErrNone; +} + +/** +The reader thread will wait till there is data in the pipe +and then continuously read till it has read the total length +of the pipe. +*/ +TInt ReaderThread(TAny* aData) { +// Read data from Pipe + RTest test(KReaderThread); + test.Title(); + test.Start(_L("Reader Thread")); + + TData& data = *(TData *)aData; + TBuf8<10> pipeReadData; + + const TInt sizeToRead = data.iReadEnd->MaxSize(); //attempt to read everything from pipe + TRequestStatus status(KErrGeneral); + + //do read in loop in case thread is notified before pipe is full + TInt totalDataRead=0; + do + { + data.iReadEnd->NotifyDataAvailable(status); + test.Printf(_L("notify data request status is %d\n"), status.Int()); + if(status==KRequestPending) + User::WaitForRequest(status); + test(status==KErrNone); + test.Printf(_L("ready to read data\n"), status.Int()); + + const TInt sizeRead = data.iReadEnd->Read(pipeReadData, sizeToRead); + test.Printf(_L("Read %d bytes from pipe\n"), sizeRead); + test(sizeRead>0); + totalDataRead+=sizeRead; + } + while(totalDataRead(aData)->iWriteEnd; + RTest test(_L("WriterThread")); + test.Start(_L("WriterThread")); + writeEnd->Flush(); //make sure pipe is empty + const TInt sizeToWrite = writeEnd->MaxSize(); + test.Printf(_L("Writing %d bytes in to pipe\n"), sizeToWrite); + TInt length=writeEnd->WriteBlocking(KTestDataNum1,sizeToWrite); + test(length==sizeToWrite); + test.End(); + test.Close(); + return KErrNone; + } + +/** +The FlusherThread waits till the supplied pipe +is full before flushing it. +*/ +TInt FlusherThread(TAny* aData) + { + TData& data = *(TData *)aData; // aData will have pipe handles and size. + + //wait for pipe to fill, then flush + TRequestStatus status; + const TInt maxSize=data.iReadEnd->MaxSize(); + do + { + data.iReadEnd->NotifyDataAvailable(status); + if(status==KRequestPending) + User::WaitForRequest(status); + if(status!=KErrNone) + return status.Int(); + } while(data.iReadEnd->Size()Flush(); + return KErrNone; + } + +/**************************************************************************** + This function is used as thread to test Unnamed pipes. + TestWaitMechanismPipes() will use this function. + + @aData : Used to pass the pipe and handle its size information. + + Return Value : TInt + +******************************************************************************/ +TInt CloseFlag; + +TInt TestThread9(TAny* aData) { + + TData& data = *(TData *)aData; // aData will have pipe handles and size. + + if (CloseFlag == 1) + data.iReadEnd->Close(); + if (CloseFlag == 0) + data.iWriteEnd->Close(); + + + return 0; + } + +/** +The test will create 2 threads running this function. They will +race to placing the blocking read request. The first +will succeed and wait, the second will write to pipe +*/ +TInt ReadBlockThenWrite(TAny* aData) { + + TData& data = *(TData *)aData; // aData will have pipe handles and size. + TBuf8<10> cReadData; + RTest test(_L("Concurrent blocking read")); + test.Start(_L("Call blocking read on pipe\n")); + + TInt ret = data.iReadEnd->ReadBlocking(cReadData,5); + if(ret == KErrNone) + { + test_KErrNone(cReadData.Compare(KTestDataNum1)); + } + + if(ret == KErrInUse) + { + test.Next(_L("Other thread beat us - write to pipe so it may proceed")); + TInt write = data.iWriteEnd->Write(KTestDataNum,5); + test_Equal(5, write); + } + + test.End(); + test.Close(); + + return ret; +} + +/** +The test will create 2 threads running this function. They will +race to placing the blocking write request. The first +will succeed and wait, the second will read from pipe +*/ +TInt WriteBlockThenRead(TAny* aData) { + + TData& data = *(TData *)aData; // aData will have pipe handles and size. + TBuf8<10> cReadData; + RTest test(_L("Concurrent blocking write")); + test.Start(_L("test writing blocked pipe\n")); + + TInt ret = data.iWriteEnd->WriteBlocking(KTestDataNum,10); + if(ret == KErrInUse) + { + test.Next(_L("The other thread beat us - read from pipe so it may proceed")); + TInt read = data.iReadEnd->Read(cReadData,5); + test_Equal(5, read); + test_KErrNone(cReadData.Compare(KTestDataNum1)); + } + + test.End(); + test.Close(); + + return ret; +} + +/**************************************************************************** + This function is used as thread to test Unnamed pipes. + TestWaitMechanismPipes() will use this function. + + @aData : Used to pass the pipe and handle its size information. + + Return Value : TInt + +******************************************************************************/ + +TInt TestThread11(TAny* aData) { + + TData& data = *(TData *)aData; // aData will have pipe handles and size. + TRequestStatus stat1; + TBufC<50> cPipeName(KPipe3Name); // Descriptor to hold data for Writing. + TInt ret; + RTest test(_L("t_pipe_t11")); + + test.Start(_L("PIPE TEST:Thread 11:Created by TestWaitMechanismPipes.\n")); + + test.Next(_L("PIPE TEST:Thread 11-1:Register one more request to wait till open to read. It shall not allow\n")); + data.iReadEnd->WaitForWriter(cPipeName, stat1); + test_Equal(KErrInUse, stat1.Int()); + + + test.Next(_L("PIPE TEST:Thread 11-2:Open Pipe handle to write.\n")); + ret = data.iWriteEnd->Open(cPipeName,RPipe::EOpenToWrite); + test_KErrNone(ret); + + test.End(); + test.Close(); + return KErrNone; +} + +/**************************************************************************** + This is a function to test Named/UnNamed pipes Performace. + Check the functionality of following library functions + - + - + + + +******************************************************************************/ +/** + - test that WriteBlocking unblocks + - when data is read + - whed date is flushed + - test that notify data available request is completed as data is read + - test that ReadBlocking unblocks + - test that data available notification works + +*/ +void TestBlockingAndNotify() { + + TRequestStatus stat1; + RPipe aReader,aWriter; + TInt aSize,ret; + TBufC8<10> cPipeTestDataNum(KTestDataNum); + + TBuf8<10> cReadData; + + + aSize = 5; + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess, // + EOwnerProcess // + ); + test_KErrNone(ret); + + TData data( &aReader, &aWriter); + + { + TTestThread readerThread(KReaderThread, ReaderThread, &data); + + test.Start(_L("Test that WriteBlock unblocks as data is read from pipe\n")); + ret = aWriter.WriteBlocking(cPipeTestDataNum,10); + test(ret == 10); + test(aWriter.Size()==5); + aWriter.Flush(); + test(aWriter.Size()==0); + + ret = readerThread.WaitForExitL(); + test_KErrNone(ret); + } + + { + TTestThread flusherThread(KThread8Name, FlusherThread, &data); + test.Next(_L("Test that WriteBlock unblocks as data is flushed from read end of pipe\n")); + + ret = aWriter.WriteBlocking(cPipeTestDataNum,10); + test (ret == 10); + ret = flusherThread.WaitForExitL(); + test_KErrNone(ret); + } + + test.Next(_L("Test that NotifyDataAvailable request is completed as data is read from pipe\n")); + + aWriter.NotifySpaceAvailable(aSize,stat1); + test(stat1==KRequestPending); + + { + TTestThread readerThread2(KReaderThread, ReaderThread, &data); + + User::WaitForRequest(stat1); + test(stat1==KErrNone); + + ret = readerThread2.WaitForExitL(); + test_KErrNone(ret); + } + + aReader.Flush(); + + test.Next(_L("PIPE TEST: Test that ReadBlocking unblocks\n")); + { + TTestThread writeThread(KWriterThread, WriterThread, &data); + + ret = aReader.ReadBlocking(cReadData,5); + test(ret == 5); + + ret = writeThread.WaitForExitL(); + test_KErrNone(ret); + } + + test.Next(_L("PIPE TEST: Test NotifyDataAvailable\n")); + aReader.Flush(); + aReader.NotifyDataAvailable(stat1); + test(stat1==KRequestPending); + + { + TTestThread writeThread2(KWriterThread,WriterThread, &data); + + User::WaitForRequest(stat1); + test(stat1==KErrNone); + + aReader.Flush(); + + ret = writeThread2.WaitForExitL(); + test_KErrNone(ret); + } + test.Next(_L("PIPE TEST: Test reading from pipe closed by the writer\n")); + + CloseFlag = 0; // 0 Close Write Handle + //CloseFlag = 1; // 1 Close Read Handle + test.Next(_L("PIPE TEST: TestBlockingAndNotify 10.6\n")); + TTestThread closeThread(KThread9Name, TestThread9, &data); + + ret = closeThread.WaitForExitL(); + test_KErrNone(ret); + + ret = aReader.ReadBlocking(cReadData,5); + test_Equal(KErrNotReady, ret); + + aWriter.Close(); + aReader.Close(); + aSize = 5; + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess, // + EOwnerProcess // + ); + test_KErrNone(ret); + + TData data1(&aReader,&aWriter); + + + //CloseFlag = 0; // 0 Close Write Handle + CloseFlag = 1; // 1 Close Read Handle + test.Printf(_L("PIPE TEST: TestBlockingAndNotify 10.7\n")); + TTestThread closeThread2(KThread9Name, TestThread9, &data1); + ret = aWriter.WriteBlocking(cPipeTestDataNum,10); + test_Equal(KErrNotReady, ret); + + ret = closeThread2.WaitForExitL(); + test_KErrNone(ret); + + aWriter.Close(); + aReader.Close(); + + test.End(); +} + + +/**************************************************************************** + TestPipesPermissionCheck : + This function is used to test Permission and Access related + Errors of Pipes API. + APIs tested are Define , Create , Destroy , Read and Write. + + +******************************************************************************/ +// Different pipes for different capability , VID values. +_LIT(KPipeName2, "PipeWithNoCap"); +_LIT(KPipeName3, "PipeWithNoCapVID"); +_LIT(KPipeName4, "PipeWithRWCap"); +_LIT(KPipeName5, "PipeWithComDDCap"); +_LIT(KPipeName6, "PipeWithRWComDDCap"); +_LIT(KPipeName7, "PipeWithRWComDDCapVID"); +_LIT(KPipeName8, "PipeWithRWRUCap"); + +// Different processes with different capability , VID values. +_LIT(KProcessNoCap, "t_pipe3.exe"); +_LIT(KProcessRCap, "t_pipe5.exe"); + +// My VID and SID +_LIT_VENDOR_ID(MyVID,0x70000001); + +void TestPipesPermissionCheck() { + + RProcess proc; + TInt ret; + + // Define TSecurity objects with different capabilities and VID . + TSecurityPolicy NoCapVID(MyVID,ECapability_None,ECapability_None,ECapability_None); + TSecurityPolicy RWCap(ECapabilityReadDeviceData,ECapabilityWriteDeviceData); + TSecurityPolicy ComDDCap(ECapabilityCommDD); + TSecurityPolicy RWComDDCap(ECapabilityReadDeviceData,ECapabilityCommDD,ECapabilityWriteDeviceData); + TSecurityPolicy RWComDDCapVID(MyVID,ECapabilityCommDD,ECapabilityReadDeviceData,ECapabilityWriteDeviceData); + TSecurityPolicy RWRUCap(ECapabilityReadUserData,ECapabilityReadDeviceData,ECapabilityWriteDeviceData); + + // Define Named pipes with No Cap , combination of Cap and VID + + TInt aSize = 10; + ret = RPipe::Define(KPipeName2, aSize); + test (ret == KErrNone); + ret = RPipe::Define(KPipeName3, aSize,NoCapVID); + test (ret == KErrNone); + ret = RPipe::Define(KPipeName4, aSize,RWCap); + test (ret == KErrNone); + ret = RPipe::Define(KPipeName5, aSize,ComDDCap); + test (ret == KErrNone); + ret = RPipe::Define(KPipeName6, aSize,RWComDDCap); + test (ret == KErrNone); + ret = RPipe::Define(KPipeName7, aSize,RWComDDCapVID); + test (ret == KErrNone); + ret = RPipe::Define(KPipeName8, aSize,RWRUCap); + test (ret == KErrNone); + + //Lets see who can use pipes. Check for Permissions and Access + test.Next(_L("PIPE TEST:8.1 Create Process with No Cap t_pipe3.exe\n")); + ret = proc.Create ( + KProcessNoCap, // Launch t_pipe3.exe process + KNullDesC // No arguments passed to t_pipe3.exe + ); + + if (ret != KErrNone) + { + test.Printf(_L(" ***** t_pipe3.exe could not start ****")); + } + test_KErrNone(ret); + test.Printf(_L("Process Created successfully")); + + TRequestStatus procLogon; + proc.Logon(procLogon); + test(procLogon==KRequestPending); + proc.Resume(); + User::WaitForRequest(procLogon); + proc.Close(); + + // Lets see what happens with Read Capability. + test.Next(_L("PIPE TEST:8.2 Create Process with Read-Write-CommDD Cap t_pipe5.exe\n")); + ret = RPipe::Define(KPipeName2, aSize); + test_KErrNone(ret); + ret = RPipe::Define(KPipeName3, aSize,NoCapVID); + test_KErrNone(ret); + + ret = proc.Create ( + KProcessRCap, // Launch t_pipe3.exe process + KNullDesC // No arguments passed to t_pipe3.exe + ); + + if (ret != KErrNone) + { + test.Printf(_L(" ***** t_pipe5.exe could not start ****")); + } + test_KErrNone(ret); + test.Printf(_L("Process Created successfully")); + proc.Logon(procLogon); + test(procLogon==KRequestPending); + proc.Resume(); + User::WaitForRequest(procLogon); + proc.Close(); + + //the t_pipe5.exe process should destroy most of these + //but we call destroy again to verify this + ret = RPipe::Destroy (KPipeName2); + test_Equal(KErrNotFound, ret); + ret = RPipe::Destroy (KPipeName3); + test_KErrNone(ret); //KPipeName3 is not destroyed by the other process. + ret = RPipe::Destroy (KPipeName4); + test_Equal(KErrNotFound, ret); + ret = RPipe::Destroy (KPipeName5); + test_Equal(KErrNotFound, ret); + ret = RPipe::Destroy (KPipeName6); + test_Equal(KErrNotFound, ret); + ret = RPipe::Destroy (KPipeName7); + test_KErrNone(ret); //t_pipe5.exe does not have permission to delete + ret = RPipe::Destroy (KPipeName8); + test_KErrNone(ret); //t_pipe5.exe does not have permission to delete + + + + return; + +} + +/**************************************************************************** + + TestMiscPipes : + This is a function to test Named/UnNamed pipes for all Misc test cases. + + +******************************************************************************/ + +void TestMiscPipes() { + +_LIT(KInvalidPipeName,"PipeNotExist"); + TInt ret,aSize; + RPipe aReader,aWriter; + TBufC<50> cPipeName(KInvalidPipeName); // Descriptor to hold data for Writing. + TBufC8<50> cPipeTestData2(KTestData2); + + + // Try to create unnamed pipe with Negative size + test.Next(_L("PIPE TEST:9.1 Create Pipe of Negative Size.\n")); + aSize = -1; + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess, // + EOwnerProcess // + ); + test( ret == KErrArgument); + + + // Try to create unnamed pipe with zero size + test.Next(_L("PIPE TEST:9.2 Create Pipe with of Zero size.\n")); + aSize = 0; + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess, // + EOwnerProcess // + ); + test( ret == KErrArgument); + + + // Try to define named pipe with Negative size + test.Next(_L("PIPE TEST:9.3 Define Pipe of Negative size.\n")); + aSize = -1; + ret = RPipe::Define(cPipeName, aSize); + test( ret == KErrArgument); + + + + // Try to define named pipe with Zero size + test.Next(_L("PIPE TEST:9.4 Define Pipe of Zero size.\n")); + aSize = 0; + ret = RPipe::Define(cPipeName, aSize); + test( ret == KErrArgument); + + + // Try to destroy pipe which does not exists + test.Next(_L("PIPE TEST:9.5 Try to destroy named pipe which do not exist.\n")); + ret = RPipe::Destroy (cPipeName); + test (ret == KErrNotFound); + + + // Try to read from pipe with invalid length data to be read + RPipe aReaderUN,aWriterUN; + TBuf8<150> cPipeReadData; + aSize = 10; + ret = RPipe::Create( aSize, + aReaderUN, + aWriterUN, + EOwnerProcess, // + EOwnerProcess // + ); + test (ret == KErrNone ); + + + test.Next(_L("PIPE TEST:9.6 Try calling ReadBlocking using write handle and WriteBlocking using Read handle.\n")); + ret = aWriterUN.ReadBlocking(cPipeReadData, aSize); + test (ret == KErrAccessDenied); + ret = aReaderUN.WriteBlocking(cPipeTestData2,aSize); + test (ret == KErrAccessDenied); + + + + + test.Next(_L("PIPE TEST:9.7 Read negative size data from un-named pipe.\n")); + aSize = -1; + ret = aReaderUN.Read(cPipeReadData, aSize); + test( ret == KErrArgument); + ret = aWriterUN.Write(cPipeTestData2,aSize); + test( ret == KErrArgument); + + + + test.Next(_L("PIPE TEST:9.8 Read/Write zero size data from/to un-named pipe\n")); + aSize = 0; + ret = aReaderUN.Read(cPipeReadData, aSize); + test( ret == KErrNone); + + ret = aWriterUN.Write(cPipeTestData2,aSize); + test( ret == KErrNone); + + + test.Next(_L("PIPE TEST:9.9 Call ReadBlocking and WriteBlocking to Read and Write negative size data.\n")); + // Try to readblocking from pipe with invalid length data to be read + aSize = -1; + ret = aReaderUN.ReadBlocking(cPipeReadData, aSize); + test( ret == KErrArgument); + ret = aWriterUN.WriteBlocking(cPipeTestData2,aSize); + test( ret == KErrArgument); + + test.Next(_L("PIPE TEST:9.10 ReadBlocking/WriteBlocking to read/write zero size data.\n")); + aSize = 0; + ret = aReaderUN.ReadBlocking(cPipeReadData, aSize); + test( ret == KErrArgument); + ret = aWriterUN.WriteBlocking(cPipeTestData2,aSize); + test( ret == KErrArgument); + + + test.Next(_L("PIPE TEST:9.11 Try calling ReadBlocking and WriteBlocking using un opened RPipe handles.\n")); + RPipe aReaderT,aWriterT; + ret = aReaderT.ReadBlocking(cPipeReadData, aSize); + test (ret == KErrBadHandle); + ret = aWriterT.WriteBlocking(cPipeTestData2,aSize); + test (ret == KErrBadHandle); + aReaderUN.Close(); + aWriterUN.Close(); + + + return; +} + +/**************************************************************************** + This is a function to test notify mechanism of pipes. + Check the functionality of following library functions + - Notify...() + + +******************************************************************************/ +void TestWaitMechanismPipes() { + + RPipe aReader,aWriter; // Used to pass to thread. + RPipe aWriter2; + TInt ret; + TBufC<50> cPipeName(KPipe3Name); // Descriptor to hold data for Writing. + TInt aSize; + TRequestStatus stat1; + + aSize = 22 * 10; // Sizeof(KTestData) * 10 + + ret = RPipe::Define( cPipeName,aSize); + ret = aWriter.Open(cPipeName,RPipe::EOpenToWrite); + test (ret == KErrNone); + + + + test.Next(_L("PIPE TEST:7.1 Try calling Wait function on BadPipe name.\n")); + + _LIT(KBadPipeName , "***R$@#$@#%#$%#^.12-."); + aWriter.Wait(KBadPipeName,stat1); + test(stat1.Int() == KErrBadName); + aWriter.WaitForReader(KBadPipeName,stat1); + test(stat1.Int() == KErrBadName); + + + _LIT(KBadPipeName2 , ""); + aWriter.Wait(KBadPipeName2,stat1); + test(stat1.Int() == KErrBadName); + aWriter.WaitForReader(KBadPipeName2,stat1); + test(stat1.Int() == KErrBadName); + + + + test.Next(_L("PIPE TEST:7.2 Try calling Wait function on non existing Pipe\n")); + _LIT(KInvalidPipe , "NotExistingPipe"); + aWriter.Wait(KInvalidPipe,stat1); + test(stat1.Int() == KErrNotFound); + aWriter.WaitForReader(KInvalidPipe,stat1); + test(stat1.Int() == KErrNotFound); + + + test.Next(_L("PIPE TEST:7.3 Try calling Wait function on Pipe name length more than maxlength.\n")); + aWriter.Wait(KMaxPipeNamePlusOne,stat1); + test(stat1.Int() == KErrBadName); + aWriter.WaitForReader(KMaxPipeNamePlusOne,stat1); + test(stat1.Int() == KErrBadName); + + + test.Next(_L("PIPE TEST:7.4 Try calling Wait function from unopened handle.\n")); + aWriter2.Wait(cPipeName, stat1); + test (stat1.Int() == KErrInUse); + aWriter2.WaitForReader(cPipeName, stat1); + test (stat1.Int() == KErrInUse); + + + test.Next(_L("PIPE TEST:7.5 Register a valid Wait Request .\n")); + aWriter.Wait(cPipeName, stat1); + + TData data( &aReader, &aWriter); + + // Create Thread 5 + // Pass TData object with Write and Read handle both + TTestThread thread5(KThread5Name, TestThread5, &data); + User::WaitForRequest(stat1); + + ret = thread5.WaitForExitL(); + test_KErrNone(ret); + + test.Next(_L("PIPE TEST:7.6 After Wait finish check the value of status register.\n")); + test_KErrNone(stat1.Int()); + aWriter.Close(); + aReader.Close(); + ret = aWriter.Open(cPipeName,RPipe::EOpenToWrite); + test_KErrNone(ret); + ret = aReader.Open(cPipeName,RPipe::EOpenToRead); + test_KErrNone(ret); + + test.Next(_L("PIPE TEST:7.7 After Read handle is open , register request to Wait\n")); + + aWriter.Wait(cPipeName, stat1); + test (stat1.Int() == KErrNone); + + test.Next(_L("PIPE TEST:7.8 Check for CancelWait.\n")); + aWriter.Close(); + aReader.Close(); + ret = aWriter.Open(cPipeName,RPipe::EOpenToWrite); + TRequestStatus stat2; + aWriter.Wait(cPipeName, stat1); + aWriter.Wait(cPipeName, stat2); + test(stat2.Int() == KErrInUse); + aWriter.CancelWait(); + test(stat1.Int() == KErrCancel); + test(stat2.Int() == KErrInUse); + aWriter.Wait(cPipeName, stat1); + ret = aReader.Open(cPipeName,RPipe::EOpenToRead); + test(stat1.Int() == KErrNone); + + test.Next(_L("PIPE TEST:7.9 Check Wait and CancelWait from reader end\n")); + aWriter.Close(); + aReader.Close(); + ret = aReader.Open(cPipeName,RPipe::EOpenToRead); + aReader.Wait(cPipeName, stat1); + test (stat1.Int() == KErrAccessDenied); + aReader.CancelWait(); + + + aWriter.Close(); + aReader.Close(); + RPipe::Destroy(cPipeName); + + /*****************Newly added tests for CR 1114 - WaitForReader *********/ + + ret = RPipe::Define( cPipeName,aSize); + ret = aWriter.Open(cPipeName,RPipe::EOpenToWrite); + test (ret == KErrNone); + + + test.Next(_L("PIPE TEST:7.10 Register a valid Wait Request .\n")); + aWriter.WaitForReader(cPipeName, stat1); + test(stat1==KRequestPending); + + // Create Thread 5 + // Pass TData object with Write and Read handle both + { + TTestThread thread5_1(KThread5Name, TestThread5, &data); + User::WaitForRequest(stat1); + + ret = thread5_1.WaitForExitL(); + test_KErrNone(ret); + } + + test.Next(_L("PIPE TEST:7.11 After Wait finish check the value of status register.\n")); + aWriter.Close(); + aReader.Close(); + ret = aWriter.Open(cPipeName,RPipe::EOpenToWrite); + ret = aReader.Open(cPipeName,RPipe::EOpenToRead); + + aReader.WaitForReader(cPipeName, stat1); + test (stat1.Int() == KErrAccessDenied); + + test.Next(_L("PIPE TEST:7.12 After Read handle is open , register request to Wait\n")); + + aWriter.WaitForReader(cPipeName, stat1); + test (stat1.Int() == KErrNone); + + test.Next(_L("PIPE TEST:7.13 Check for CancelWait.\n")); + aWriter.Close(); + aReader.Close(); + ret = aWriter.Open(cPipeName,RPipe::EOpenToWrite); + + aWriter.WaitForReader(cPipeName, stat1); + aWriter.WaitForReader(cPipeName, stat2); + test(stat2.Int() == KErrInUse); + aWriter.CancelWait(); + test(stat1.Int() == KErrCancel); + test(stat2.Int() == KErrInUse); + aWriter.WaitForReader(cPipeName, stat1); + ret = aReader.Open(cPipeName,RPipe::EOpenToRead); + test(stat1.Int() == KErrNone); + + // Release all the resources. + aWriter.Close(); + aReader.Close(); + + // Create Thread 5 + // Pass TData object with Write and Read handle both + + test.Next(_L("PIPE TEST:7.14 Register a valid Wait Request .\n")); + aWriter.WaitForReader(cPipeName, stat1); + + { + TTestThread thread5_2(KThread5Name, TestThread5, &data); + User::WaitForRequest(stat1); + + ret = thread5_2.WaitForExitL(); + test_KErrNone(ret); + } + test.Next(_L("PIPE TEST:7.15 After Wait finish close the handles.\n")); + test (stat1.Int() == KErrNone); + aWriter.Close(); + aReader.Close(); + // Release all the resources. + ret = RPipe::Destroy(cPipeName); + test_KErrNone(ret); + + /*****************Newly added tests for CR 1114 - WaitForWriter *********/ + + ret = RPipe::Define( cPipeName,aSize); + test_KErrNone(ret); + ret = aReader.Open(cPipeName,RPipe::EOpenToRead); + test (ret == KErrNone); + + + // Create Thread 11 + // Pass TData object with Write and Read handle both + + test.Next(_L("PIPE TEST:7.16 Register a valid Wait Request .\n")); + aReader.WaitForWriter(cPipeName, stat1); + test(stat1==KRequestPending); + + { + TTestThread thread11(KThread11Name, TestThread11, &data); + User::WaitForRequest(stat1); + + ret = thread11.WaitForExitL(); + test_KErrNone(ret); + } + + test.Next(_L("PIPE TEST:7.17 After Wait finish check the value of status register.\n")); + aWriter.Close(); + aReader.Close(); + ret = aWriter.Open(cPipeName,RPipe::EOpenToWrite); + test_KErrNone(ret); + ret = aReader.Open(cPipeName,RPipe::EOpenToRead); + test_KErrNone(ret); + + aWriter.WaitForWriter(cPipeName, stat1); + test (stat1.Int() == KErrAccessDenied); + + test.Next(_L("PIPE TEST:7.18 After Write handle is open , register request to Wait\n")); + + aReader.WaitForWriter(cPipeName, stat1); + test (stat1.Int() == KErrNone); + + test.Next(_L("PIPE TEST:7.19 Check for CancelWait.\n")); + aWriter.Close(); + aReader.Close(); + ret = aReader.Open(cPipeName,RPipe::EOpenToRead); + + aReader.WaitForWriter(cPipeName, stat1); + aReader.WaitForWriter(cPipeName, stat2); + test(stat2.Int() == KErrInUse); + aReader.CancelWait(); + test(stat1.Int() == KErrCancel); + test(stat2.Int() == KErrInUse); + aReader.WaitForWriter(cPipeName, stat1); + ret = aWriter.Open(cPipeName,RPipe::EOpenToWrite); + test(stat1.Int() == KErrNone); + + // Release all the resources. + aWriter.Close(); + aReader.Close(); + + // Create Thread 11 + // Pass TData object with Write and Read handle both + + test.Next(_L("PIPE TEST:7.20 Register a valid Wait Request .\n")); + aReader.WaitForWriter(cPipeName, stat1); + + { + TTestThread thread11_2(KThread11Name, TestThread11, &data); + User::WaitForRequest(stat1); + + test.Next(_L("PIPE TEST:7.21 After Wait finish , close the hadles.\n")); + test (stat1.Int() == KErrNone); + ret = thread11_2.WaitForExitL(); + test_KErrNone(ret); + + // Release all the resources. + aWriter.Close(); + aReader.Close(); + } + + ret = RPipe::Destroy(cPipeName); + test_KErrNone(ret); + + /**********************************************************/ + + // Define the pipe. + ret = RPipe::Define( cPipeName,aSize); + test(ret == KErrNone); + + // Wait for Writer. + aReader.WaitForWriter(cPipeName, stat1); + // Try to open read end again. It should not open because WaitForWriter + // will has already opened the Read End of the pipe. + ret = aReader.Open(cPipeName ,RPipe::EOpenToRead ); + test(ret = KErrInUse ); + // Status of the wait request is pending because writer is not opened yet. + test (stat1.Int() == KRequestPending); + + // Wait on Reader. + aWriter.WaitForReader(cPipeName , stat2); + // Reader was already opened so status is KErrNone. + test ( stat2.Int() == KErrNone); + + // Try to open Write end. It should not allow because WaitForReader has + // already opened the write end of the pipe. + ret = aWriter.Open(cPipeName ,RPipe::EOpenToWrite); + test (ret == KErrInUse); + + // Check the status of the WaitForWriter request. It should be KErrNone now. + test (stat1.Int() == KErrNone); + + // Let's check for pipe attributes. + ret = aReader.MaxSize(); + test (ret = aSize); + ret = aWriter.MaxSize(); + test (ret = aSize); + ret = aReader.Size(); + test (ret = aSize); + ret = aWriter.Size(); + test (ret = aSize); + + // Close the Reade handle. + aReader.Close(); + + // Put request to wait for Reader. + aWriter.WaitForReader(cPipeName , stat2); + // It should be pending. + test ( stat2.Int() == KRequestPending); + // Open the reader end of the pipe. It should allow , KErrNone + ret = aReader.Open(cPipeName ,RPipe::EOpenToRead ); + test ( stat2.Int() == KErrNone); + test (ret == KErrNone); + + aReader.Close(); + aWriter.Close(); + ret=RPipe::Destroy(cPipeName); + test_KErrNone(ret); + + return; + + +} + +/**************************************************************************** + This is a function to test notify mechanism of pipes. + Check the functionality of following library functions + - Notify...() + + +******************************************************************************/ +void TestNotifyMechanismPipes() { + // Test NotifyDataAvailable , NotifySpaceAvailable + RSemaphore globalSem; // Handle to a global semaphore. Semaphore is used to maintain synchronisation between thread4 and the main thread + TInt ret; // Return Value variable. + RPipe aReader,aWriter; // Used to pass to thread. + RPipe aReader2,aWriter2; // Used to pass to thread. + + TInt aSize; // Used to pass to thread. + const TBufC<50> cPipeName(KPipe1Name); // Descriptor to hold data for Writing. + + TRequestStatus stat1; + TBuf8<50> cPipeTestData1(KTestData2); + + const TBufC<50> cSemaphoreName(KSemaphoreName); // Descriptor conataining the name of the global semaphore. + + + ret = globalSem.CreateGlobal(cSemaphoreName,0); //create and open a global semaphore with initial count as 0. + test (ret == KErrNone); + + aSize = 22; // Size of KTestData * 10 + + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess, // + EOwnerProcess // + ); + + TData data( &aReader, &aWriter); + + // Create Thread 4 + // Pass TData object with Write and Read handle both + test.Next(_L("PIPE TEST:6.1 Call CancelDataAvailable/CancelSpaceAvailable using unopened RPipe handles.\n")); + ret = aReader2.CancelDataAvailable(); + test ( ret == KErrBadHandle); + ret = aWriter2.CancelSpaceAvailable(); + test (ret == KErrBadHandle); + + test.Next(_L("PIPE TEST:6.2 Call NotifySpaceAvailable with Negative size \n")); + // Call Notfifyspace + TInt tempsize = -1; + aWriter.NotifySpaceAvailable(tempsize, stat1); + test ( stat1.Int() == KErrArgument); + + test.Next(_L("PIPE TEST:6.2a Call NotifySpaceAvailable for space larger than pipe.\n")); + aWriter.NotifySpaceAvailable(aSize+1, stat1); + test_Equal( KErrArgument, stat1.Int()); + + + // Start the thread + { + TTestThread thread4(KThread4Name, TestThread4, &data); + + // Thread 4 + // Call Notifydata available + // Loop for Available + // Read the data and validate + + test.Next(_L("PIPE TEST:6.3 Write data into the pipe , verify return value.\n")); + // Write one byte data into the pipe. + globalSem.Wait(); //wait before writing to ensure that other thread can register Data Available request while pipe is empty. + ret = aWriter.Write(cPipeTestData1,cPipeTestData1.Length()); + test (ret == cPipeTestData1.Length()); + + + test.Next(_L("PIPE TEST:6.4 Call NotifySpaceAvailable with valid parameters \n")); + tempsize = 1; + aWriter.NotifySpaceAvailable(tempsize, stat1); + test(stat1==KRequestPending); + globalSem.Signal(); //signal that thread 4 may go ahead and read 1 byte + + + test.Next(_L("PIPE TEST:6.5 Wait till request says AVAILABLE. Available ?\n")); + User::WaitForRequest(stat1); + test ( stat1.Int() == KErrNone || stat1.Int() == KErrCompletion); + + // Thread 4 + // Notify data available + // Loop for available + // Flush the buffer + // Register two request for Notifydata available + // Register two request for Notifyspace available + // Call Notifydata available using Read handle + // Call Notifydata available using write handle + // return + + + // Check for Error conditions + + // Flush buffer + globalSem.Wait(); // this is waiting for a signal from thread4 + test.Next(_L("PIPE TEST:6.6 Register Notification for space availability. Allows ?\n")); + ret = aWriter.Write(cPipeTestData1,cPipeTestData1.Length()); + ret = aWriter.Write(cPipeTestData1,cPipeTestData1.Length()); + // Register two request for Notifyspace available + + aWriter.NotifySpaceAvailable(tempsize, stat1); + test_Equal(KRequestPending, stat1.Int() ); + test.Next(_L("PIPE TEST:6.7 Register One more Notification for space availability. Allows ?\n")); + TRequestStatus tempstat1; + aWriter.NotifySpaceAvailable(tempsize, tempstat1); + test ( tempstat1.Int() == KErrInUse); + + test.Next(_L("PIPE TEST:6.7a Cancellation of non-outstanding requests must not disrupt oustanding requests\n")); + aWriter.CancelWait(); + aWriter.NotifySpaceAvailable(tempsize, tempstat1); + test_Equal( KErrInUse, tempstat1.Int()); + + test.Next(_L("PIPE TEST:6.8 Cancel all the pending Notifications.\n")); + ret = aWriter.CancelSpaceAvailable(); + test ( ret == KErrNone); + test_Equal(KErrCancel, stat1.Int() ); + + test.Next(_L("PIPE TEST:6.9 Try to cancel some more notifications. It should not allow\n")); + ret = aWriter.CancelSpaceAvailable(); + test ( ret == KErrNone); + + test.Next(_L("PIPE TEST:6.10 Register Notification for Data availability. Allows ?\n")); + // Register two request for Notifydata available + aWriter.Flush(); + aReader.NotifyDataAvailable(stat1); + + test.Next(_L("PIPE TEST:6.11 Register One More Notification for Data availability. Allows ?\n")); + + aReader.NotifyDataAvailable(tempstat1); + test ( ( tempstat1.Int() == KErrInUse) || (tempstat1.Int() == KErrCompletion)); + + test.Next(_L("PIPE TEST:6.12 Cancel all the pending Notifications for Data.\n")); + ret = aReader.CancelDataAvailable(); + test ( ( ret == KErrNone) || (ret == KErrNotFound)); + test (stat1.Int() == KErrCancel); + + test.Next(_L("PIPE TEST:6.13 Try to cancel some more notifications. It should not allow\n")); + ret = aReader.CancelDataAvailable(); + test ( ret == KErrNone); + + test.Next(_L("PIPE TEST:6.14 Try to register Data available notification using Write handle. Should not allow.\n")); + aWriter.NotifyDataAvailable(stat1); + test ( stat1.Int() == KErrAccessDenied); + + test.Next(_L("PIPE TEST:6.15 Try to register Space available notification using Read handle. Should not allow.\n")); + aReader.NotifySpaceAvailable(tempsize, stat1); + test ( stat1.Int() == KErrAccessDenied); + + test.Next(_L("PIPE TEST:6.16 Try to Cancel Data available notification using Write handle. Should not allow.\n")); + ret = aWriter.CancelDataAvailable(); + test ( ret == KErrAccessDenied); + + test.Next(_L("PIPE TEST:6.17 Try to Cancel Space available notification using Write handle. Should not allow.\n")); + ret = aReader.CancelSpaceAvailable(); + test ( ret == KErrAccessDenied); + + // Stop the thread and Close the Thread + ret = thread4.WaitForExitL(); + } + test_KErrNone(ret); + // Close all the pipe handles. + aReader.Close(); + aWriter.Close(); + + + + test.Printf(_L(" TEST NOTIFICATION MECHNISM FOR NAMED PIPES\n")); + + aSize = 22; // Size of KTestData + + test.Next(_L("PIPE TEST:6.18 Create Named pipe and Open Read/Write Handles.\n")); + ret = RPipe::Define( cPipeName,aSize); + test (ret == KErrNone); + ret = aReader.Open(cPipeName,RPipe::EOpenToRead); + test (ret == KErrNone); + ret = aWriter.Open(cPipeName,RPipe::EOpenToWrite); + test (ret == KErrNone); + + + + TData data2( &aReader, &aWriter); + + // Create Thread 4 + // Pass TData object with Write and Read handle both + TTestThread thread4a(KThread4Name, TestThread4, &data2); + + // Thread 4 + // Call Notifydata available + // Loop for Available + // Read the data and validate + + // Write one byte data into the pipe. + test.Next(_L("PIPE TEST:6.19 Write Data and check for return value.\n")); + globalSem.Wait(); //wait before writing to ensure that other thread can register Data Available request while pipe is empty. + ret = aWriter.Write(cPipeTestData1,cPipeTestData1.Length()); + test (ret == cPipeTestData1.Length()); + + test.Next(_L("PIPE TEST:6.20 Register Notification for Space Available.\n")); + // Call Notfifyspace + tempsize = 1; + aWriter.NotifySpaceAvailable(tempsize, stat1); + test(stat1==KRequestPending); + globalSem.Signal(); //signal that thread 4 may go ahead and read byte + + test.Next(_L("PIPE TEST:6.21 Wait till notified for Space Availanle.\n")); + User::WaitForRequest(stat1); + test ( stat1.Int() == KErrNone); + + // Thread 4 + // Read one byte of data + // Thread 4 + // Notify data available + // Loop for available + // Flush the buffer + // Register two request for Notifydata available + // Register two request for Notifyspace available + // Call Notifydata available using Read handle + // Call Notifydata available using write handle + // return + + globalSem.Wait(); //waiting for a signal from thread4. + test.Next(_L("PIPE TEST:6.22 Notify for Space available.\n")); + // Register two request for Notifydata available + ret = aWriter.Write(cPipeTestData1,cPipeTestData1.Length()); + aWriter.NotifySpaceAvailable(tempsize, stat1); + + test.Next(_L("PIPE TEST:6.23 Notify one more notifier for Space available.\n")); + // Register two request for Notifyspace available + TRequestStatus notifyStatus; + aWriter.NotifySpaceAvailable(tempsize, notifyStatus); + test ( notifyStatus.Int() == KErrInUse); + + aWriter.Flush(); + aWriter.NotifySpaceAvailable(tempsize, stat1); + test ( stat1.Int() == KErrNone); + + test.Next(_L("PIPE TEST:6.24 Cancel Notify for Space available.\n")); + ret = aWriter.CancelSpaceAvailable(); + test (( ret == KErrNotFound) ||( ret == KErrNone)); + test.Next(_L("PIPE TEST:6.25 Cancel one more Notify for Space available.\n")); + ret = aWriter.CancelSpaceAvailable(); + test ( ret == KErrNone); + + test.Next(_L("PIPE TEST:6.26 Register Notify for Data available.\n")); + // Register two request for Notifydata available + + aWriter.Flush(); + TRequestStatus stat5,stat6; + aReader.NotifyDataAvailable(stat5); + + test.Next(_L("PIPE TEST:6.27 Register One more Notify for Data available.\n")); + // Register two request for Notifyspace available + aReader.NotifyDataAvailable(notifyStatus); + test ( notifyStatus.Int() == KErrInUse); + test.Next(_L("PIPE TEST:6.28 Cancel Notify for Data available.\n")); + ret = aReader.CancelDataAvailable(); + test ( ret == KErrNone); + test (stat5.Int() == KErrCancel); + + test.Next(_L("PIPE TEST:6.29 Cancel One more Notify for Data available.\n")); + ret = aReader.CancelDataAvailable(); + test ( ret == KErrNone); + + test.Next(_L("PIPE TEST:6.30 Register Notify for Data available using Write handle\n")); + aWriter.NotifyDataAvailable(stat6); + test ( stat6.Int() == KErrAccessDenied); + + test.Next(_L("PIPE TEST:6.31 Register Notify for Space available using Read handle\n")); + aReader.NotifySpaceAvailable(tempsize, stat6); + test ( stat6.Int() == KErrAccessDenied); + + test.Next(_L("PIPE TEST:6.32 Cancel Notify for Data available using Write handle\n")); + ret = aWriter.CancelDataAvailable(); + test ( ret == KErrAccessDenied); + + test.Next(_L("PIPE TEST:6.33 Cancel Notify for Space available using Read handle\n")); + ret = aReader.CancelSpaceAvailable(); + test ( ret == KErrAccessDenied); + + //close the handle to the global semaphore + + globalSem.Close(); + // Stop the thread and Close the Thread + ret = thread4a.WaitForExitL(); + test_KErrNone(ret); + aReader.Close(); + aWriter.Close(); + RPipe::Destroy(cPipeName); + + + return; + + + +} // End TestNotifyMechanismPipes() + +/**************************************************************************** + This is a function to test Named pipes in Mutli process environment. + Check the functionality of following library functions + - Define () + - + + +******************************************************************************/ + + +_LIT8(KTestDataIP, "ABCDEFGHIJ"); + +void TestMultiProcessNamedPipes() { + +_LIT(KPipeName5, "InterProcessPipe1"); + TInt ret; // Return value variable + RProcess proc; // Process Handle + RPipe aWriter; + RPipe aWriterUN,aReaderUN; + const TBufC<150> cPipeName1(KPipeName5); + + TBufC8<150> cPipeWriteData1(KTestDataIP); + TInt aSize; + TRequestStatus stat1; + TBuf8<150> cPipeReadData1; + + aSize = 10; + + // Define Pipe with valid size. + + test.Next(_L("PIPE TEST:5.1 Define Pipe and Create UnNAmed pipe and pass handle to other process.\n")); + ret = RPipe::Define(cPipeName1, aSize); + test_KErrNone(ret); + ret = proc.Create( + KProcessName, // Launch t_pipe2.exe process + KNullDesC // No arguments passed to t_pipe2.exe + ); + + if (ret != KErrNone) { + // Check for process successfully launched + test.Printf(_L("Error : Could not start the process t_pipe2.exe \n")); + } + test_KErrNone(ret); + TRequestStatus procLogon; + proc.Logon(procLogon); + test(procLogon==KRequestPending); + + aSize = 512; + ret = RPipe::Create( aSize, + aReaderUN, + aWriterUN, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess //TOwnerType aTypeW + ); + test_KErrNone(ret); + + ret = aWriterUN.Write(KTestData,22); + test (ret == 22); + ret = aReaderUN.Read(cPipeReadData1,10); + test ( ret == 10); + aWriterUN.Close(); + ret = aReaderUN.Read(cPipeReadData1,6); + test (ret == 6); + aReaderUN.NotifyDataAvailable(stat1); + ret = stat1.Int(); + test (ret == KErrNone); + ret = aReaderUN.ReadBlocking(cPipeReadData1,6); + test (ret == 6); + ret = aReaderUN.Read(cPipeReadData1,1); + test ( ret == KErrNotReady); + ret = aReaderUN.ReadBlocking(cPipeReadData1,1); + test ( ret == KErrNotReady); + aReaderUN.Close(); + + ret = RPipe::Create( aSize, + aReaderUN, + aWriterUN, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess //TOwnerType aTypeW + ); + test_KErrNone(ret); + proc.SetParameter(3,aReaderUN); + aReaderUN.Close(); + ret = aWriterUN.Write(KTestData,22); + test (ret == 22 ); + + proc.Resume(); + + aSize = 10; + test.Next(_L("PIPE TEST:5.2 Open Write handle to Pipe. Wait till Read handle Opened\n")); + ret = aWriter.Open(cPipeName1, RPipe::EOpenToWrite); + test_KErrNone(ret); + aWriter.Wait(cPipeName1,stat1); + User::WaitForRequest(stat1); + test (stat1.Int() == KErrNone); + + test.Next(_L("PIPE TEST:5.3 Write data to Pipe.\n")); + ret = aWriter.Write(cPipeWriteData1,cPipeWriteData1.Length()); + test ( ret == cPipeWriteData1.Length()); + + test.Next(_L("PIPE TEST:5.4 Wait till Space Available in Pipe.\n")); + aWriter.NotifySpaceAvailable(aSize,stat1); + User::WaitForRequest(stat1); + + test.Next(_L("PIPE TEST:5.5 Write the data using WriteBlocking call\n")); + test_Equal(0, aWriter.Size()); + ret = aWriter.WriteBlocking(cPipeWriteData1,cPipeWriteData1.Length()); + test ( ret ==cPipeWriteData1.Length() ); + + User::WaitForRequest(procLogon); + + aWriter.Close(); + ret=RPipe::Destroy(cPipeName1); + test_KErrNone(ret); + + proc.Close(); + aWriterUN.Close(); + aReaderUN.Close(); + return; + +} // End TestMultiProcessNamedPipes () +/**************************************************************************** + This is a function to test Named pipes in Multi threaded environment. + Check the functionality of following library functions + - Define () + - Read() + - Write() + - ReadBlocking() + - WriteBlocking() + + +******************************************************************************/ +// +// Test defining and opening both ends of pipe +// Attempt to readblock from pipe closed at far end (should fail) +// Attemp writeblock to pipe closed at far end +// +// Do some normal reading and writing between threads +// do some blocking read/write between threads +void TestMultiThreadNamedPipes() { + + TInt ret; // Return Value variable. + RPipe aReader,aWriter; // Used to pass to thread. + TInt aSize; // Used to pass to thread. + const TBufC<50> cPipeName(KPipe1Name); // Descriptor to hold data for Writing. + TInt aReadSize; + TBuf8<150> cPipeReadData; + TBufC8<50> cTestData(KTestData); // Test Data + + + + +/////////////////////////////////////////////////////////// +// PART : 1 /// +// Test Read and Write Functionality /// +/////////////////////////////////////////////////////////// + + test.Next(_L("PIPE TEST:4.1 Define Pipe , Open Read and Write Handle.\n")); + aSize = 22; + ret = RPipe::Define( cPipeName,aSize); + test (ret == KErrNone); + + ret = aReader.Open(cPipeName,RPipe::EOpenToRead); + test (ret == KErrNone); + + ret = aWriter.Open(cPipeName,RPipe::EOpenToWrite); + test (ret == KErrNone); + + aWriter.Close(); + + test.Next(_L("PIPE TEST:4.2 ReadBlocking: Check for KErrNotReady.\n")); + aReadSize = 1; + ret = aReader.ReadBlocking(cPipeReadData,aReadSize); + test (ret == KErrNotReady); + + ret = aWriter.Open(cPipeName,RPipe::EOpenToWrite); + test (ret == KErrNone); + + + aReader.Close(); + test.Next(_L("PIPE TEST:4.3 WriteBlocking: Check for KErrNotReady.\n")); + ret = aWriter.WriteBlocking(cTestData,cTestData.Length()); + test (ret == KErrNotReady); + + ret = aReader.Open(cPipeName,RPipe::EOpenToRead); + test (ret == KErrNone); + + + TData data( &aReader, &aWriter); + + + + + // Write data to Pipe using valid handle + test.Next(_L("PIPE TEST:4.4 Write into the pipe and verify return value.\n")); + ret = aWriter.Write(cTestData,cTestData.Length()); + test (ret == cTestData.Length() ); + + + // Keep writing the data into pipe till it overflows + + test.Next(_L("PIPE TEST:4.5 Write into the pipe till it overflows.\n")); + ret = aWriter.Write(cTestData,cTestData.Length()); + test (( ret == KErrOverflow)) ; + + // Start the thread. + TTestThread thread2(KThread2Name, TestThread2, &data); + // Read 1 byte data from pipe + // Validate data + // Read aByte size data + // Validate data + // Thread 2 + // Read aByte size data + // User:: After (10000) + // Keep reading data till zero return + // return + + // Stop the thread and Close the Thread + ret = thread2.WaitForExitL(); + test_KErrNone(ret); + + aReader.Close(); + aWriter.Close(); + ret = RPipe::Destroy(cPipeName); + test_KErrNone(ret); + + +/////////////////////////////////////////////////////////// +// PART : 2 /// +// Test ReadBlocking and WriteBlocking Functionality /// +/////////////////////////////////////////////////////////// + + // Test Read and Write blocking call + + test.Next(_L("PIPE TEST:4.6 Create UnNamed Pipe with valid size.\n")); + + aSize = 22; + ret = RPipe::Define( cPipeName,aSize); + test (ret == KErrNone); + + ret = aReader.Open(cPipeName,RPipe::EOpenToRead); + test (ret == KErrNone); + + ret = aWriter.Open(cPipeName,RPipe::EOpenToWrite); + test (ret == KErrNone); + + // Create TData object to pass Pipe handles. + TData data2( &aReader, &aWriter); + + + // Create Thread ( Note : Thread is in pending state now) + // Flush the data if any in pipe to make sure its empty. + aWriter.Flush(); + + // Start the thread + TTestThread thread3(KThread3Name, TestThread3, &data2); + // Thread 3 + // Write one byte of data + // Write one one byte of data using WriteBlocking call + // Write aByte size data using Writblocking call + + + // Call Readblocking function.Read one byte of data. + test.Next(_L("PIPE TEST:4.7 Flush the buffer and Call ReadBlocking one byte into the pipe.\n")); + aReadSize = 1; + ret = aReader.ReadBlocking(cPipeReadData,aReadSize); + test_Equal(aReadSize, ret); + + test.Next(_L("PIPE TEST:4.8 Verify the data received.\n")); + test ( KErrNone == cPipeReadData.Compare(KTestData1)); + + + test.Next(_L("PIPE TEST:4.9 Call ReadBlocking and read complete data from Pipe. As big as Pipe Size\n")); + // Call Readblocking function.Read aSize bytes of data. + aReadSize = aSize-aReadSize; //read rest of data + ret = aReader.ReadBlocking(cPipeReadData,aReadSize); + test_Equal(aReadSize, ret); + test ( KErrNone == cPipeReadData.Compare(KTestData3)); + + // Thread 3 + // Wait for some time + // Call Readblocking and read 1 byte of data + // Call Readblocking and Read abyte size data + // Call flush buffer + // return + test.Next(_L("PIPE TEST:4.10 Call ReadBlocking and read complete data from Pipe. As big as Pipe Size\n")); + // Call Readblocking function.Read aSize bytes of data. + aReadSize = aSize; + ret = aReader.ReadBlocking(cPipeReadData,aReadSize); + test_Equal(aReadSize, ret); + test ( KErrNone == cPipeReadData.Compare(KTestData2)); + + // Stop the thread and Close the Thread + ret = thread3.WaitForExitL(); + test_KErrNone(ret); + + aReader.Close(); + aWriter.Close(); + ret=RPipe::Destroy(cPipeName); + test_KErrNone(ret); + return ; + +} // End TestMultiThreadNamedPipes () + + +/**************************************************************************** + This is a function to test UnNamed pipes in Multi threaded environment. + Check the functionality of following library functions + - Create() + - Read() + - Write() + - ReadBlocking() + - WriteBlocking() + + +******************************************************************************/ +void TestMultiThreadUnNamedPipes() { + + TInt ret; // Return Value variable. + RPipe aReader,aWriter; // Used to pass to thread. + TInt aSize; // Used to pass to thread. + TBuf8<250> cPipeReadData; + TInt aReadSize; + TBufC8<50> cTestData(KTestData); // Test Data + + +/////////////////////////////////////////////////////////// +// PART : 1 /// +// Test Read and Write Functionality /// +/////////////////////////////////////////////////////////// + + test.Next(_L("PIPE TEST: 3.1 Create Pipe : Check for no erros on Pipe Creation \n")); + ret = 100; + aSize = 22; // Size of KTestData * 10 + + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess ,//TOwnerType aTypeW + EOwnerProcess //TOwnerType aTypeW + ); + + test (ret == KErrNone); + + // Create TData object to pass Pipe handles. + TData data1( &aReader, &aWriter); + + // Create Thread ( Note : Thread is in pending state now) + + // Create test data stream. + test.Next(_L("PIPE TEST: 3.2 Write Function test : Write data into the pipe \n")); + ret = aWriter.Write(cTestData,cTestData.Length()); // Write ""Pipe Data To Be Passed" + test (ret == cTestData.Length()); + + // Keep writing the data into pipe till it overflows + test.Next(_L("PIPE TEST: 3.3 Write Data till the Pipe returns KErrOverFlow\n")); + ret = aWriter.Write(cTestData,cTestData.Length()); + test ( ret == KErrOverflow); + + TTestThread thread2(KThread2Name, TestThread2, &data1); + // Thread2 + // Read 1 byte data from pipe + // Validate data + // Read aByte size data + // Validate data + // Thread 2 + // Read aByte size data + // User:: After (10000) + // Keep reading data till zero return + // return + + // Stop the thread , Close it. + + ret = thread2.WaitForExitL(); + test_KErrNone(ret); + + aReader.Close(); + aWriter.Close(); + + +/////////////////////////////////////////////////////////// +// PART : 2 /// +// Test ReadBlocking and WriteBlocking Functionality /// +/////////////////////////////////////////////////////////// + + + aSize = 22; // Size of KTestData + + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess , //TOwnerType aTypeW + EOwnerProcess //TOwnerType aTypeW + ); + test_KErrNone(ret); + + // Create TData object to pass Pipe handles. + + TData data2(&aReader, &aWriter); + + // Flush the data if any in pipe to make sure its empty. + aWriter.Flush(); + + // Start the thread + TTestThread thread3(KThread3Name, TestThread3, &data2); + // Thread 3 + // Write one byte of data + // Write one one byte of data using WriteBlocking call + // Write aByte size data using Writblocking call + + + // Call Readblocking function.Read one byte of data. + + aReadSize = 1; + test.Next(_L("PIPE TEST: 3.4 : Call readblocking and read one byte of data \n")); + ret = aReader.ReadBlocking(cPipeReadData,aReadSize); + // Call goes to Thread 3 + test_Equal(aReadSize, ret); + + test.Next(_L("PIPE TEST: 3.5 : Validate the data \n")); + test_Equal(0, cPipeReadData.Compare(KTestData1)); + + + // Call Readblocking function.Read aSize bytes of data. + test.Next(_L("PIPE TEST: 3.6 : Read remaining data \n")); + aReadSize = 21; + ret = aReader.ReadBlocking(cPipeReadData,aReadSize); + test_Equal(aReadSize, ret); + test_Equal(0, cPipeReadData.Compare(KTestData3)); + + + test.Next(_L("PIPE TEST: 3.7 : Read complete pipe size data \n")); + aReadSize = 22; + ret = aReader.ReadBlocking(cPipeReadData,aReadSize); + test_Equal(aReadSize, ret); + test_Equal(0, cPipeReadData.Compare(KTestData2)); + + // Wait for thread to end and Close + ret = thread3.WaitForExitL(); + test_KErrNone(ret); + + aReader.Close(); + aWriter.Close(); + + return ; + + +}// End TestMultiThreadUnNamedPipes() + +/**************************************************************************** + This is a function to test Named pipes in Single threaded environment. + Check the functionality of following library functions + - Define () + - + + +******************************************************************************/ + +void TestSingleThreadNamedPipes() + +{ + + + const TBufC<50> cPipeName(KPipe1Name); // Descriptor to hold data for Writing. + TInt aSize, ret; + RPipe testPipe1; + RPipe testPipe2; + RPipe testPipe3; + RPipe testPipe4; + RPipe testPipe5; + const TBufC<100> cPipeNameMax(KMaxPipeName); + const TBufC<100> cPipeNameMaxPlusOne(KMaxPipeNamePlusOne); + + _LIT(KBadName , "***?SFSDFWE?*_-"); + _LIT(KBadName2 , ""); + + test.Next(_L("PIPE TEST: 2.1 Define Function test : Check for No Error\n")); + aSize = 10; + + ret = RPipe::Define(cPipeName , aSize); + test (ret == KErrNone); + + ret = RPipe::Destroy (cPipeName); + test (ret == KErrNone); + + + + test.Next(_L("PIPE TEST: 2.2 Define Function test : Check for Max length \n")); + + aSize = 10; + + ret = RPipe::Define(cPipeNameMax , aSize); + test (ret == KErrNone); + + ret = RPipe::Destroy (cPipeNameMax); + test (ret == KErrNone); + + test.Next(_L("PIPE TEST: 2.3 Define Function test : Check for Max length \n")); + + aSize = 10; + ret = RPipe::Define(cPipeNameMaxPlusOne , aSize); + test (ret == KErrBadName); + ret = RPipe::Destroy (cPipeNameMaxPlusOne); + test (ret == KErrBadName); + + test.Next(_L("PIPE TEST: 2.4 Open Function test : Test Open \n")); + aSize = 10; + ret = RPipe::Define(cPipeName , aSize); + test_KErrNone(ret); + + ret = testPipe1.Open(KBadName,RPipe::EOpenToRead); + test (ret == KErrBadName); + + ret = testPipe1.Open(KBadName2,RPipe::EOpenToRead); + test (ret == KErrBadName); + + ret = testPipe1.Open(cPipeName,RPipe::EOpenToRead); + test (ret == KErrNone); + + ret = testPipe1.Open(cPipeName,RPipe::EOpenToWrite); + test (ret == KErrInUse); + + + + test.Next(_L("PIPE TEST: 2.5 Destroy Function test : Destroy opened pipe error \n")); + ret = RPipe::Destroy (cPipeName); + test (ret == KErrInUse); + + test.Next(_L("PIPE TEST: 2.6 Open Function test : Reopen pipe for reading\n")); + ret = testPipe2.Open(cPipeName,RPipe::EOpenToRead); + test (ret == KErrInUse); + + test.Next(_L("PIPE TEST: 2.7 Open Function test : Bad name test \n")); + ret = testPipe2.Open(cPipeNameMaxPlusOne,RPipe::EOpenToRead); + test (ret == KErrBadName); + + + test.Next(_L("PIPE TEST: 2.8 Open Function test : Write mode test\n")); + + ret = testPipe3.Open(cPipeName,RPipe::EOpenToWrite); + test (ret == KErrNone); + + ret = testPipe3.Open(cPipeName,RPipe::EOpenToRead); + test (ret == KErrInUse); + + test.Next(_L("PIPE TEST: 2.9 Open Function test : Bad name test \n")); + + ret = testPipe4.Open(cPipeNameMaxPlusOne,RPipe::EOpenToWrite); + test (ret == KErrBadName); + + + test.Next(_L("PIPE TEST: 2.10 Open Function test : Reopen for writing \n")); + ret = testPipe4.Open(cPipeName,RPipe::EOpenToWrite); + test (ret == KErrInUse); + + + // Do we have pipes created ? Close and Destroy them ....!! + + testPipe1.Close(); + testPipe2.Close(); + testPipe3.Close(); + testPipe4.Close(); + ret = RPipe::Destroy (cPipeName); + test_KErrNone(ret); + + + + test.Next(_L("PIPE TEST: 2.11a Open Function test : Write But Fail on no Readers mode before pipe defined\n")); + ret = testPipe1.Open(cPipeName,RPipe::EOpenToWriteNamedPipeButFailOnNoReaders); + test_Equal(KErrNotFound,ret); + + test.Next(_L("PIPE TEST: 2.11 Open Function test : Write But Fail on no Readers mode Error test\n")); + ret = RPipe::Define(cPipeName , aSize); + test (ret == KErrNone); + + ret = testPipe1.Open(cPipeName,RPipe::EOpenToWriteNamedPipeButFailOnNoReaders); + test (ret == KErrNotReady); + + + test.Next(_L("PIPE TEST: 2.12 Open Function test : Write But Fail on no Readers mode Success test\n")); + ret = testPipe1.Open(cPipeName,RPipe::EOpenToRead); + test_KErrNone(ret); + ret = testPipe2.Open(cPipeName,RPipe::EOpenToWriteNamedPipeButFailOnNoReaders); + test ( ret == KErrNone); + + + // Do we have pipes created ? Close and Destroy them ....!! + + testPipe1.Close(); + testPipe2.Close(); + testPipe3.Close(); + testPipe4.Close(); + ret = RPipe::Destroy (cPipeName); + test_KErrNone(ret); + + + + test.Next(_L(" 2.13 Define Function test : Check Incorrect Size\n")); + aSize = -1; + ret = RPipe::Define(cPipeName , aSize); + test (ret == KErrArgument); + + + test.Next(_L("PIPE TEST: 2.14 Define Function test : Check Incorrect Size\n")); + aSize = 0x1fffffff; + ret = RPipe::Define(cPipeName , aSize); + test (ret == KErrNoMemory); + + + test.Next(_L("PIPE TEST: 2.15 Size Function test : Size\n")); + aSize = 10; + ret = RPipe::Define(cPipeName , aSize); + + ret = testPipe5.MaxSize(); + test (ret == KErrBadHandle); + + + test.Next(_L("PIPE TEST: 2.16 Size Function test : Size\n")); + aSize = 10; + ret = RPipe::Define(cPipeName , aSize); + testPipe5.Open(cPipeName, RPipe::EOpenToRead); + testPipe4.Open(cPipeName, RPipe::EOpenToWrite); + ret = testPipe5.MaxSize(); + test (ret == aSize); + ret = testPipe4.MaxSize(); + test (ret == aSize); + + + /* Close all the pipes and Destroy*/ + testPipe1.Close(); + testPipe2.Close(); + testPipe3.Close(); + testPipe4.Close(); + testPipe5.Close(); + ret = RPipe::Destroy (cPipeName); + test_KErrNone(ret); + + _LIT(KRedefinePipe , "REDEFINEPIPE"); + + test.Next(_L("PIPE TEST: 2.17 Check for Redefining same pipe name \n")); + ret = RPipe::Define(KRedefinePipe , aSize); + test_KErrNone(ret); + ret = RPipe::Define(KRedefinePipe , aSize); + test (ret == KErrAlreadyExists); + ret = RPipe::Destroy (KRedefinePipe); + test_KErrNone(ret); + + test.Next(_L("PIPE TEST: 2.18 Open Function test : Bad Pipe name\n")); + aSize = 10; + RPipe testPipe6; + ret = testPipe6.Open(cPipeName, RPipe::EOpenToRead); + test (ret == KErrNotFound); + + + const TBufC<50> cPipeNameNull; + test.Next(_L("PIPE TEST: 2.19 Define Function test : Null Pipe name and Bad Pipe name\n")); + aSize = 10; + ret = RPipe::Define(cPipeNameNull , aSize); + test (ret == KErrBadName); + + + ret = RPipe::Define(KBadName , aSize); + test (ret == KErrBadName); + ret = RPipe::Destroy(KBadName); + test (ret == KErrBadName); + + + ret = RPipe::Define(KBadName2 , aSize); + test (ret == KErrBadName); + ret = RPipe::Destroy(KBadName2); + test (ret == KErrBadName); + + + test.Next(_L("PIPE TEST: 2.20 Destroy a pipe while Write end is open\n")); + ret = RPipe::Define(cPipeName , aSize); + + testPipe1.Close(); + ret = testPipe1.Open(cPipeName,RPipe::EOpenToRead); + test (ret == KErrNone); + testPipe2.Close(); + ret = testPipe2.Open(cPipeName,RPipe::EOpenToWrite); + test (ret == KErrNone); + testPipe1.Close(); + ret = RPipe::Destroy (cPipeName); + test (ret == KErrInUse); + + testPipe2.Close(); + ret = RPipe::Destroy (cPipeName); + test (ret == KErrNone); + + testPipe1.Close(); + testPipe2.Close(); + testPipe3.Close(); + testPipe4.Close(); + testPipe5.Close(); + + + _LIT(KPipe1Name,"TestPipeA"); + _LIT(KPipe2Name,"TestPipeB"); + _LIT(KPipe3Name,"TestPipeC"); + _LIT(KPipe4Name,"TestPipeD"); + + test.Next(_L("PIPE TEST: 2.21 Define Four pipes and Destroy in different sequence ( Code Coverage test)\n")); + ret = RPipe::Define(KPipe1Name , aSize); + test (ret == KErrNone); + ret = RPipe::Define(KPipe2Name , aSize); + test (ret == KErrNone); + ret = RPipe::Define(KPipe3Name , aSize); + test (ret == KErrNone); + ret = RPipe::Define(KPipe4Name , aSize); + test (ret == KErrNone); + ret = RPipe::Destroy (KPipe2Name); + test (ret == KErrNone); + ret = RPipe::Destroy (KPipe4Name); + test (ret == KErrNone); + ret = RPipe::Destroy (KPipe1Name); + test (ret == KErrNone); + ret = RPipe::Destroy (KPipe3Name); + test (ret == KErrNone); + + return; + +} // End TestSingleThreadNamedPipes() + +/**************************************************************************** + This is a function to test UnNamed pipes in Single threaded environment. + Check the functionality of following library functions + - Create () + - + + +******************************************************************************/ + +_LIT8(KTxtDataToSend,"*Test data to send**"); + +void TestSingleThreadUnNamedPipes() { + + TInt ret = 1; // Return value test variable. + TInt aSize; + TBufC8<40> wData(KTxtDataToSend); // Descriptor to hold data for Writing. + RPipe aReader,aWriter; + RPipe aReader2,aWriter2; + + + // Following tests will verify all the APIs in single thread + // for all the possible return values. + // This is to verify different paths of API + // not for detail functional verification. + // Create the Pipe and Check for No Errors when Valid parameters are passed. + + test.Next(_L("PIPE TEST:1.1 Create Function test : Check for No Error\n")); + aSize = 10; + + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess //TOwnerType aTypeW + ); + + test (ret == KErrNone); + + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess //TOwnerType aTypeW + ); + + test (ret == KErrInUse); + + aWriter.Close(); + aReader.Close(); + + + // How big pipe we can create ? + + test.Next(_L("PIPE TEST:1.2 Create Function test : Check for No Memory\n")); + + aSize = 0x1BCDEFFF; + + ret = RPipe::Create( aSize, + aReader2, + aWriter2, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess //TOwnerType aTypeW + ); + + test (ret == KErrNoMemory); + + aReader2.Close(); + aWriter2.Close(); + + + test.Next(_L("PIPE TEST:1.3 Create Function test : Check for Reopening pipe\n")); + aSize = 10; + + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess//TOwnerType aTypeW + ); + test_KErrNone(ret); + + + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess//TOwnerType aTypeW + ); + + test (ret == KErrInUse); + + aReader.Close(); + aWriter.Close(); + + + + test.Next(_L("PIPE TEST:1.4 Read/Write Function test : Check for Writing to pipe\n")); + + aSize = 100; + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess//TOwnerType aTypeW + ); + test_KErrNone(ret); + + ret=aWriter.Write(wData , wData.Size()); + test (ret == wData.Size() ); + + ret=aWriter.Write(wData , -1); + test (ret == KErrArgument ); + + + test.Next(_L("PIPE TEST:1.5 Read/Write Function test : Check for Reading from pipe\n")); + + + TBuf8<100> rData ;// Descriptor for reading data from Pipe. + + ret=aReader.Read(rData,wData.Size()); // Length of the data to be read from Pipe + test (ret == wData.Size());// Length of the data read from the Pipe + + + test.Next(_L("PIPE TEST:1.6 Read/Write Function test : Validate data received\n")); + + test (KErrNone == rData.Compare(wData)); + + + test.Next(_L("PIPE TEST:1.7 Read/Write Function test : Check for Reading from pipe\n")); + + ret=aReader.Read(rData,1); + test (ret == 0); + { + + + RPipe aReaderT, aWriterT; + aSize = 20; + ret = RPipe::Create( aSize, + aReaderT, + aWriterT, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess//TOwnerType aTypeW + ); + test_KErrNone(ret); + + ret=aWriterT.Write(wData ,15); + test_Equal(15, ret); + ret = aReaderT.Read(rData,10); + test_Equal(10, ret); + ret=aWriterT.Write(wData ,10); + test_Equal(10, ret); + ret = aReaderT.Read(rData,20); + test (ret ==15); + ret = aReaderT.Read(rData,5); + test_Equal(0, ret); + ret = aReaderT.Read(rData,25); + test_Equal(0, ret); + + aReaderT.Close(); + aWriterT.Close(); + + } + + + test.Next(_L("PIPE TEST:1.8 Read/Write Function test : Check for Wrong RPipe Handle\n")); + + + ret=aWriter.Read(rData,15 );// Length of the data to be read from Pipe + test (ret == KErrAccessDenied ); + + test.Next(_L("PIPE TEST:1.9 Read/Write Function test : Check for Wrong RPipe Handle\n")); + + ret=aReader.Write(rData,rData.Size()); + test (ret == KErrAccessDenied ); + + + test.Next(_L("PIPE TEST:1.10 Read/Write Function test : Check for write overflow\n")); + + ret=aWriter.Write(wData,wData.Size()); + ret=aWriter.Write(wData,wData.Size()); + ret=aWriter.Write(wData,wData.Size()); + ret=aWriter.Write(wData,wData.Size()); + ret=aWriter.Write(wData,wData.Size()); + ret=aWriter.Write(wData,wData.Size()); + test (ret == KErrOverflow ); + + + + test.Next(_L("PIPE TEST:1.11 MaxSize Function test : MaxSize Check \n")); + aSize = 10; + // Just to be on safer side , close pipes if any. + aReader.Close(); + aWriter.Close(); + + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess//TOwnerType aTypeW + ); + test (ret == KErrNone); // This error condition is not defined yet. + ret =aReader.MaxSize(); + test (ret == aSize); + + + test.Next(_L("PIPE TEST:1.12 Size Function test : Size Check \n")); + rData.Zero(); + + ret = aReader.Size(); + test_Equal(0, ret); + + _LIT8(KSizeTestData1,"123456789"); + + ret = aWriter.Write(KSizeTestData1,9); + test_Equal(9, ret); + ret = aReader.Size(); + test_Equal(9, ret); + + ret = aReader.Read(rData,1); + test_Equal(1, ret); + ret = rData.Compare(_L8("1")); + test_KErrNone(ret); + ret = aReader.Size(); + test_Equal(8, ret); + + _LIT8(KSizeTestData2,"ab"); + ret = aWriter.Write(KSizeTestData2,2); + test_Equal(2, ret); + ret = aReader.Size(); + test_Equal(10, ret); + + ret = aWriter.Write(KSizeTestData2,1); + test_Equal(KErrOverflow, ret); + ret = aReader.Size(); + test_Equal(10, ret); + + ret = aReader.Read(rData,9); + test_Equal(9, ret); + ret = rData.Compare(_L8("23456789a")); + test_KErrNone(ret); + ret = aReader.Size(); + test_Equal(1, ret); + + ret = aReader.Read(rData,1); + test_Equal(1, ret); + ret = rData.Compare(_L8("b")); + test_KErrNone(ret); + ret = aReader.Size(); + test_Equal(0, ret); + + ret = aWriter.Size(); + test_Equal(0, ret); + RPipe WrongPipeHandle; + + ret = WrongPipeHandle.Size(); + test ( ret == KErrBadHandle); + + test.Next(_L("PIPE TEST:1.13 Size Function test : Size Function call with Wrong handle \n")); + + + + ret = WrongPipeHandle.MaxSize(); + test (ret == KErrBadHandle); + + aReader.Close(); + aWriter.Close(); + aReader2.Close(); + aWriter2.Close(); + + test.Next(_L("PIPE TEST:1.14 Read Function : KErrNotReady \n")); + aSize = 10; + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess//TOwnerType aTypeW + ); + test (ret == KErrNone); // This error condition is not defined yet. + aWriter.Close(); + ret = aReader.Read(rData,aSize); + test (ret == KErrNotReady); + ret = aReader.Read(rData,110); + test (ret == KErrArgument); + + + test.Next(_L("PIPE TEST:1.15 Check Handle Type function \n")); + aReader.Close(); + aWriter.Close(); + aSize = 10; + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess//TOwnerType aTypeW + ); + test_KErrNone(ret); + + ret = aReader.HandleType(); + test (ret == RPipe::EReadChannel); + + ret = aWriter.HandleType(); + test (ret == RPipe::EWriteChannel); + + + aReader.Close(); + ret = aReader.HandleType(); + test (ret == KErrBadHandle); + + test.Next(_L("PIPE TEST:1.16 Write Function : KErrNotReady \n")); + aSize = 1; + ret = aWriter.Write(wData,aSize); + test (ret == KErrNotReady); + + test.Next(_L("PIPE TEST:1.17 Write Function : Write data more than size of Descriptor \n")); + ret = aWriter.Write(wData,110); + test (ret == KErrArgument); + + + test.Next(_L("PIPE TEST:1.18 Write Function : KErrCompletion \n")); + aWriter.Close(); + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess//TOwnerType aTypeW + ); + test_KErrNone(ret); + ret = aWriter.Write(wData,wData.Size()); + test (ret == KErrOverflow); + + test.Next(_L("PIPE TEST:1.19 Create Function : KErrInUse \n")); + aReader.Close(); + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess//TOwnerType aTypeW + ); + test (ret == KErrInUse); + + aWriter.Close(); + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess//TOwnerType aTypeW + ); + test (ret == KErrNone); + aWriter.Close(); + ret = RPipe::Create( aSize, + aReader, + aWriter, + EOwnerProcess,//TOwnerType aTypeW + EOwnerProcess//TOwnerType aTypeW + ); + test (ret == KErrInUse); + + + + test.Next(_L("PIPE TEST:1.20 Read / Write using un opened handles \n")); + RPipe aReaderT,aWriterT; + + ret = aWriterT.Write(wData,wData.Size()); + test (ret == KErrBadHandle); + ret = aReaderT.Read(rData,aSize); + test (ret == KErrBadHandle); + + + + + // Close all the pipes and return the resources. + aReader.Close(); + aWriter.Close(); + aReader2.Close(); + aWriter2.Close(); + return; + +} // End TestSingleThreadUnNamedPipes() + +/**************************************************************************** + This is a function to test UnNamed pipes and named pipes in Single + threaded environment. + This test ensures that the memory is actually being released when: + RPipe::Close() is called for unnamed pipes and + RPipe::Destroy() is called for named pipes. +******************************************************************************/ +void TestCreateClosePipe() + { + + //unnamed pipes + RPipe readHandle, writeHandle; + const TInt K3MB = 1024*1024*3; + // The loop is run ten times to ensure that if memory allocated while pipe + // creation is not deallocated by close,then creation of pipe will fail with + // KErrNoMemory in the sixth iteration. Default heap size is assumed. + TInt i; + test.Next(_L("PIPE TEST:11.1 Create Function test in a loop : Check for No Error\n")); + for(i=1; i<10; i++) + { + TInt r = RPipe::Create(K3MB, readHandle, writeHandle,EOwnerProcess, EOwnerProcess); + test(KErrNone == r); + readHandle.Close(); + writeHandle.Close(); + } + + //named pipes + _LIT(KPipeName, "testPipe"); + // The loop is run ten times to ensure that if memory allocated while pipe + // creation is not deallocated by destroy,then creation of pipe will fail with + // KErrNoMemory in the sixth iteration. Default heap size is assumed. + test.Next(_L("PIPE TEST:11.2 Define Function test in a loop : Check for No Error\n")); + for(i=1; i<10; i++) + { + TInt r = RPipe::Define(KPipeName,K3MB); + test(KErrNone == r); + r = RPipe::Destroy(KPipeName); + test(KErrNone == r); + } + + }// End TestCreateClosePipe() + + +struct TStressArgs + { + TStressArgs(TInt aIter, TInt aSize) + :iIter(aIter), iSize(aSize) + {} + + const TInt iIter; + const TInt iSize; + }; + +struct TDefDesArgs: public TStressArgs + { + TDefDesArgs(TInt aIter, TInt aSize, const TDesC& aName) + :TStressArgs(aIter,aSize), iName(aName) + {} + const TDesC& iName; + }; + +/** +Repeatedly define and destroy named pipe +*/ +TInt DefineDestroy(TAny* aArgs) + { + const TDefDesArgs args = *static_cast(aArgs); + + for(TInt i=0; i(aData); + + const TInt iter = data.iIterations; + + TInt write=0; + for(TInt i=0; iWriteBlocking(*data.iPipeData, data.iPipeData->Size()); + if(write = iNumBytes) + { + TInt r = iPipe.Write(KTestData, freeSpace); + test_Equal(freeSpace, r); + } + } + + void Cancel() + { + iPipe.CancelSpaceAvailable(); + }; + + TSpaceNotification iFn; + TInt iNumBytes; + }; + +struct CDataNotificationTest : public CNotificationTest + { + typedef void (RTestPipe::*TDataNotification) (TRequestStatus&); + + CDataNotificationTest(RTestPipe& aPipe, TDataNotification aFunc) + :CNotificationTest(aPipe), iFn(aFunc) + {} + + CNotificationTest* Clone() + { + return new CDataNotificationTest(*this); + } + + void RunTest() + { + (iPipe.*iFn)(iStatus); + } + + //make sure we start with an empty pipe + void PreparePipe() + { + iPipe.Flush(); + } + + void Cancel() + { + iPipe.CancelDataAvailable(); + }; + + TDataNotification iFn; + }; + + +void ProcessNotificationTests(RPointerArray& aArray) + { + const TInt count = aArray.Count(); + for(TInt i=0; i < count; i++) + { + for(TInt j=0; j < count; j++) + { + //need copies as objects contain request states + CNotificationTest* testA = aArray[i]->Clone(); + test_NotNull(testA); + CNotificationTest* testB = aArray[j]->Clone(); + test_NotNull(testB); + + testA->PreparePipe(); testB->PreparePipe(); + + TTestThread a(_L("CNotificationTestA"), *testA, EFalse); + TTestThread b(_L("CNotificationTestB"), *testB, EFalse); + + TRequestStatus rendezvousA, rendezvousB; + a.Rendezvous(rendezvousA); + b.Rendezvous(rendezvousB); + + a.Resume(); b.Resume(); + + //wait till after threads have made notification request. + User::WaitForRequest(rendezvousA); + User::WaitForRequest(rendezvousB); + + TInt retA = testA->GetReturn(); TInt retB = testB->GetReturn(); + + //announce that we have read status requests, allowing + //child threads to terminate + RThread::Rendezvous(KErrNone); + + a.WaitForExitL(); + b.WaitForExitL(); + + TBool oneRequestSupported = ((retA == KRequestPending) && (retB == KErrInUse)) + || ((retB == KRequestPending) && (retA == KErrInUse)); + TBool bothSupported = (retA == KRequestPending) && (retB == KRequestPending); + + if(!(oneRequestSupported || bothSupported)) + { + test.Printf(_L("Failure: i=%d, j=%d"), i, j); + test(EFalse); + } + + testA->Cancel(); testB->Cancel(); + delete testA; + delete testB; + } + } + } + +/** +Test abillity of pipe channels to handle multiple notification requests +simultaneously. +*/ +void TestNotifications() + { + RTestPipe readEnd, writeEnd; + + TInt pipeSize = 5; + TInt r = RPipe::Create(pipeSize, readEnd, writeEnd, EOwnerProcess, EOwnerProcess); + test_KErrNone(r); + + test.Next(_L("Test write end requests")); + CSpaceNotificationTest writeBlocking(writeEnd, &RTestPipe::RequestWriteBlocking, pipeSize); + CSpaceNotificationTest spaceAvailable(writeEnd, &RTestPipe::NotifySpaceAvailable, pipeSize); + RPointerArray writeEndTests; + + writeEndTests.AppendL(&writeBlocking); + writeEndTests.AppendL(&spaceAvailable); + + for(TInt i=0; i<10; i++) + { + ProcessNotificationTests(writeEndTests); + } + writeEndTests.Close(); + + test.Next(_L("Test read end requests")); + CDataNotificationTest readBlocking(readEnd, &RTestPipe::RequestReadBlocking); + CDataNotificationTest dataAvailable(readEnd, &RTestPipe::NotifyDataAvailable); + RPointerArray readEndTests; + + readEndTests.AppendL(&readBlocking); + readEndTests.AppendL(&dataAvailable); + + for(TInt j=0; j<10; j++) + { + ProcessNotificationTests(readEndTests); + } + + readEndTests.Close(); + + readEnd.Close(); + writeEnd.Close(); + } + +LOCAL_C void RunTests(void) + { + // Test UnNamed Pipes in Single Thread + test.Next(_L("PIPE TEST: 1.Un Named pipes in Single Thread\n")); + TestSingleThreadUnNamedPipes(); + + // Test Named Pipes in Single Thread + test.Next(_L("PIPE TEST: 2.Named pipes in Single Thread\n")); + TestSingleThreadNamedPipes(); + + // Test UnNamed Pipes in MultiThread + test.Next(_L("PIPE TEST: 3.Un Named pipes in Multi Thread\n")); + TestMultiThreadUnNamedPipes(); + + // Test Named Pipes in MultiThread + test.Next(_L("PIPE TEST: 4.Named pipes in Multi Thread\n")); + TestMultiThreadNamedPipes(); + + // Test Named Pipes in Multi Process + test.Next(_L("PIPE TEST: 5.Named pipes in Multi Process\n")); + TestMultiProcessNamedPipes(); + + // Test Notify mechanism + test.Next(_L("PIPE TEST: 6.Pipes Notify mechanism test\n")); + TestNotifyMechanismPipes(); + + // Test Wait Mechanism + test.Next(_L("PIPE TEST: 7.Pipes Wait mechanism test\n")); + TestWaitMechanismPipes(); + + + // Test Pipes performance + test.Next(_L("PIPE TEST: 8.Pipes Permission test\n")); + TestPipesPermissionCheck (); + + // Misc Pipe tests + test.Next(_L("PIPE TEST: 9.Misc Pipe tests\n")); + TestMiscPipes(); + + // Blocking and Notify method tests. + test.Next(_L("PIPE TEST: 10.Blocking and Notification calls test\n")); + TestBlockingAndNotify(); + + //Creation and closure of a large number of Pipes + test.Next(_L("PIPE TEST: 11. Creation and subsequent closure of a large number of pipes\n")); + TestCreateClosePipe(); + + test.Next(_L("Test concurrent notification requests")); + TestNotifications(); + + test.Next(_L("Repeatedly open a named pipe whilst it's being created and destroyed")); + TestRapidDefineDestroy(); + + test.Next(_L("Check integrity of data after transfer\n")); + TestTransferIntegrity(); + + test.Next(_L("PIPE TEST: Ending test.\n")); + return; + } + +TInt ParseCommandLine() + { + TBuf<20> cmdLine; + //TInt r= cmdLine.Create(User::CommandLineLength()); + //test_KErrNone(r); + User::CommandLine(cmdLine); + TLex lex(cmdLine); + + TPtrC token=lex.NextToken(); + if(token.Length()>0) + { + TInt os=token.Match(_L("-n*")); + if(os==0) + { + if(token.Length()>2) + lex.SkipAndMark(2-lex.TokenLength()); //set mark backwards to after the "-n" + token.Set(lex.NextToken()); + if(token.Length()==0) + return KErrArgument; + + TLex valLex(token); + TInt value; + TInt r=valLex.Val(value); + if(r<0) + return r; + else + return value; + } + else + { + return KErrArgument; + } + } + else + { + const TInt KDefaultRuns=1; + return KDefaultRuns; + } + } + +GLDEF_C TInt E32Main() +// Main entry point for the test. + { + __UHEAP_MARK; + TInt ret = 0; + + test.Start(_L("PIPE TEST: Testing")); + ret = RPipe::Init(); + if ( ret != KErrNone && ret != KErrAlreadyExists) + { + test.Printf(_L("Fail to load RPIPE driver %d\n"),ret); + return KErrNone; + } + TName pddName(RPipe::Name()); + ret = RPipe::Define (KPipe1Name,10); + test_KErrNone(ret); + + User::FreeLogicalDevice(pddName); + ret = RPipe::Define (KPipe1Name,10); + test_Equal(KErrNotFound, ret); + + ret = RPipe::Init(); + if ( ret != KErrNone && ret != KErrAlreadyExists) + { + test.Printf(_L("Fail to load RPIPE driver %d\n"),ret); + return KErrNone; + } + + + TInt runs=ParseCommandLine(); + if(runs>=0) + { + TBool forever=(runs==0); + for(TInt i=0; forever||(i