diff -r 000000000000 -r 4e1aa6a622a0 sysstatemgmt/systemstatemgr/test/tss/src/tss_appstartmultiple.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysstatemgmt/systemstatemgr/test/tss/src/tss_appstartmultiple.cpp Tue Feb 02 00:53:00 2010 +0200 @@ -0,0 +1,860 @@ +// Copyright (c) 2007-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: +// Old Test CaseID APPFWK-SSS-0004 +// New Test CaseID DEVSRVS-SSMA-STARTSAFE-0004 +// +// + +/** + @file + @test + @internalComponent - Internal Symbian test code +*/ + + +#include "tss_appstartmultiple.h" + + +const TInt KSsTestAppStartTimeout = 3000; // ms +const TInt KInduceTimeoutFailWaitTime = 300; //ms +const TInt KTestMultiRetries = 5; // for a successful start this value must exceed KDontRvCount (declared in ssmtestapprvafterretry.h) + + + +TVerdict CSsTestStepAppStartMultiple::doTestStepL() + { + __UHEAP_MARK; + + TRAPD(err, DoTestMultiAppAsyncL()); + TEST(err == KErrNone); + INFO_PRINTF2(_L("DoTestMultiAppAsyncL completed with err = %d"), err); + + TRAP(err, DoTestMultiAppWithTimeoutAsyncL()); + TEST(err == KErrNone); + INFO_PRINTF2(_L("DoTestMultiAppWithTimeoutAsyncL completed with err = %d"), err); + + TRAP(err, DoTestMultiAppAllTimeoutAsyncL()); + TEST(err == KErrNone); + INFO_PRINTF2(_L("DoTestMultiAppAllTimeoutAsyncL completed with err = %d"), err); + + TRAP(err, DoTestMultiAppIncludingRetryAsyncL()); + TEST(err == KErrNone); + INFO_PRINTF2(_L("DoTestMultiAppIncludingRetryAsyncL completed with err = %d"), err); + + TRAP(err, DoTestMultiProcAsyncL()); + TEST(err == KErrNone); + INFO_PRINTF2(_L("DoTestMultiProcAsyncL completed with err = %d"), err); + + TRAP(err, DoTestMultiProcWithTimeoutAsyncL()); + TEST(err == KErrNone); + INFO_PRINTF2(_L("DoTestMultiProcWithTimeoutAsyncL completed with err = %d"), err); + + TRAP(err, DoTestMultiProcAllTimeoutAsyncL()); + TEST(err == KErrNone); + INFO_PRINTF2(_L("DoTestMultiProcAllTimeoutAsyncL completed with err = %d"), err); + + TRAP(err, DoTestMultiProcIncludingRetryAsyncL()); + TEST(err == KErrNone); + INFO_PRINTF2(_L("DoTestMultiProcIncludingRetryAsyncL completed with err = %d"), err); + + __UHEAP_MARKEND; + return TestStepResult(); + } + + + +// +// START AS APPS +// +/** + Concurrently starts four instances of ssmtestappgood.exe + There is no timeout specified, therefore no instances of CTimeoutWaiter are constructed. + */ +void CSsTestStepAppStartMultiple::DoTestMultiAppAsyncL() + { + + INFO_PRINTF1( _L("\n\n Performing Multiple App-Start Async test---no timeout") ); + + CSsmStartupProperties* startupProperties_0 = CSsmStartupProperties::NewL(); + CleanupStack::PushL( startupProperties_0 ); + + // Slightly cheeky. Use the same startup properties for each call + startupProperties_0->SetFileParamsL( KTestAppGood, KNullDesC ); + startupProperties_0->SetCommandTypeL( ESsmCmdStartApp ); + startupProperties_0->SetExecutionBehaviour( ESsmWaitForSignal ); + + RProcess process_0; + CleanupClosePushL( process_0 ); + RProcess process_1; + CleanupClosePushL( process_1 ); + RProcess process_2; + CleanupClosePushL( process_2 ); + RProcess process_3; + CleanupClosePushL( process_3 ); + + TInt id_0 = 0; + TInt id_1 = 0; + TInt id_2 = 0; + TInt id_3 = 0; + + CStartAcknowledge* ack_0 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_0 ); + CStartAcknowledge* ack_1 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_1 ); + CStartAcknowledge* ack_2 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_2 ); + CStartAcknowledge* ack_3 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_3 ); + + CSsmStartSafe* ss = CSsmStartSafe::NewLC(); + // Use this timeout AO. Therefore not making assumptions about the order of completions. + CAsPauseStopper* pauseStopper = new(ELeave) CAsPauseStopper( KSsAsStopperNominalTimeout * 2); + CleanupStack::PushL( pauseStopper ); + + ss->Start(*startupProperties_0, process_0, ack_0->iStatus, id_0); + ss->Start(*startupProperties_0, process_1, ack_1->iStatus, id_1); + ss->Start(*startupProperties_0, process_2, ack_2->iStatus, id_2); + ss->Start(*startupProperties_0, process_3, ack_3->iStatus, id_3); + + INFO_PRINTF5( _L("id_0 to id_3 have the values %d %d %d %d "), id_0, id_1, id_2, id_3 ); + //Process are started using Wait for start execution behaviour, + //Start method always sets TRequestStatus to KRequestPending. + if( (KRequestPending == ack_0->iStatus.Int()) && (KRequestPending == ack_1->iStatus.Int()) && (KRequestPending == ack_2->iStatus.Int()) && (KRequestPending == ack_3->iStatus.Int()) ) + { + CActiveScheduler::Start(); + + TBuf buf( process_0.FileName() ); + INFO_PRINTF2( _L("process_0 filename %S"), &buf ); + + buf.Copy( process_1.FileName() ); + INFO_PRINTF2( _L("process_1 filename %S"), &buf ); + + buf.Copy( process_2.FileName() ); + INFO_PRINTF2( _L("process_2 filename %S"), &buf ); + + buf.Copy( process_3.FileName() ); + INFO_PRINTF2( _L("process_3 filename %S"), &buf ); + + + INFO_PRINTF5( _L("Test apps rv'd with the values %d %d %d %d "), ack_0->iStatus.Int(), ack_1->iStatus.Int(), ack_2->iStatus.Int(), ack_3->iStatus.Int() ); + INFO_PRINTF5( _L("Anticipated values were %d %d %d %d "), KErrNone, KErrNone, KErrNone, KErrNone ); + + TEST( ack_0->iStatus == KErrNone ); + TEST( ack_1->iStatus == KErrNone ); + TEST( ack_2->iStatus == KErrNone ); + TEST( ack_3->iStatus == KErrNone ); + } + + CleanupStack::PopAndDestroy( 11, startupProperties_0 ); + + TEST( 4 == FindAndKill(KTestAppGood) ); + } + + + +/** + Concurrently starts four instances of ssmtestappgood.exe + A timeout value is specified which ensures that intances of CTimeoutWaiter are created + */ +void CSsTestStepAppStartMultiple::DoTestMultiAppWithTimeoutAsyncL() + { + + INFO_PRINTF1( _L("\n\n Performing Multiple App-Start Async test---*with* timeout") ); + + CSsmStartupProperties* startupProperties_0 = CSsmStartupProperties::NewL(); + CleanupStack::PushL( startupProperties_0 ); + + // Slightly cheeky. Use the same startup properties for each call + // Timeout is specified, therefore there are instances of CTimeoutWaiter constructed. + startupProperties_0->SetFileParamsL( KTestAppGood, KNullDesC ); + startupProperties_0->SetCommandTypeL( ESsmCmdStartApp ); + startupProperties_0->SetExecutionBehaviour( ESsmWaitForSignal ); + startupProperties_0->SetTimeout( KSsTestAppStartTimeout ); + + RProcess process_0; + CleanupClosePushL( process_0 ); + RProcess process_1; + CleanupClosePushL( process_1 ); + RProcess process_2; + CleanupClosePushL( process_2 ); + RProcess process_3; + CleanupClosePushL( process_3 ); + + TInt id_0 = 0; + TInt id_1 = 0; + TInt id_2 = 0; + TInt id_3 = 0; + + CStartAcknowledge* ack_0 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_0 ); + CStartAcknowledge* ack_1 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_1 ); + CStartAcknowledge* ack_2 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_2 ); + CStartAcknowledge* ack_3 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_3 ); + + + // Use this timeout AO. Therefore not making assumptions about the order of completions. + CAsPauseStopper* pauseStopper = new(ELeave) CAsPauseStopper( KSsAsStopperNominalTimeout * 5 ); + CleanupStack::PushL( pauseStopper ); + + CSsmStartSafe* ss = CSsmStartSafe::NewLC(); + ss->Start(*startupProperties_0, process_0, ack_0->iStatus, id_0); + ss->Start(*startupProperties_0, process_1, ack_1->iStatus, id_1); + ss->Start(*startupProperties_0, process_2, ack_2->iStatus, id_2); + ss->Start(*startupProperties_0, process_3, ack_3->iStatus, id_3); + + INFO_PRINTF5( _L("id_0 to id_3 have the values %d %d %d %d "), id_0, id_1, id_2, id_3 ); + //Process are started using Wait for start execution behaviour, + //Start method always sets TRequestStatus to KRequestPending. + if( (KRequestPending == ack_0->iStatus.Int()) && (KRequestPending == ack_1->iStatus.Int()) && (KRequestPending == ack_2->iStatus.Int()) && (KRequestPending == ack_3->iStatus.Int()) ) + { + CActiveScheduler::Start(); + + TBuf buf( process_0.FileName() ); + INFO_PRINTF2( _L("process_0 filename %S"), &buf ); + + buf.Copy( process_1.FileName() ); + INFO_PRINTF2( _L("process_1 filename %S"), &buf ); + + buf.Copy( process_2.FileName() ); + INFO_PRINTF2( _L("process_2 filename %S"), &buf ); + + buf.Copy( process_3.FileName() ); + INFO_PRINTF2( _L("process_3 filename %S"), &buf ); + + + INFO_PRINTF5( _L("Test apps rv'd with the values %d %d %d %d "), ack_0->iStatus.Int(), ack_1->iStatus.Int(), ack_2->iStatus.Int(), ack_3->iStatus.Int() ); + INFO_PRINTF5( _L("Anticipated values were %d %d %d %d "), KErrNone, KErrNone, KErrNone, KErrNone ); + + TEST( ack_0->iStatus == KErrNone ); + TEST( ack_1->iStatus == KErrNone ); + TEST( ack_2->iStatus == KErrNone ); + TEST( ack_3->iStatus == KErrNone ); + } + + CleanupStack::PopAndDestroy( 11, startupProperties_0 ); + + TEST( 4 == FindAndKill(KTestAppGood) ); + } + + + +/** + Concurrently starts four instances of ssmtestappnorv.exe + All of these timeout (naturalment) + */ +void CSsTestStepAppStartMultiple::DoTestMultiAppAllTimeoutAsyncL() + { + + INFO_PRINTF1( _L("\n\n Performing Multiple App-Start Async test---ALL timeout") ); + + CSsmStartupProperties* startupProperties_0 = CSsmStartupProperties::NewL(); + CleanupStack::PushL( startupProperties_0 ); + + // Slightly cheeky. Use the same startup properties for each call + // Timeout is specified, therefore there are instances of CTimeoutWaiter constructed. + startupProperties_0->SetFileParamsL( KTestAppNoRv, KNullDesC ); + startupProperties_0->SetCommandTypeL( ESsmCmdStartApp ); + startupProperties_0->SetExecutionBehaviour( ESsmWaitForSignal ); + startupProperties_0->SetTimeout( KInduceTimeoutFailWaitTime ); + + RProcess process_0; + CleanupClosePushL( process_0 ); + RProcess process_1; + CleanupClosePushL( process_1 ); + RProcess process_2; + CleanupClosePushL( process_2 ); + RProcess process_3; + CleanupClosePushL( process_3 ); + + TInt id_0 = 0; + TInt id_1 = 0; + TInt id_2 = 0; + TInt id_3 = 0; + + CStartAcknowledge* ack_0 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_0 ); + CStartAcknowledge* ack_1 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_1 ); + CStartAcknowledge* ack_2 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_2 ); + CStartAcknowledge* ack_3 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_3 ); + + CSsmStartSafe* ss = CSsmStartSafe::NewLC(); + + // Use this timeout AO. Therefore not making assumptions about the order of completions. + CAsPauseStopper* pauseStopper = new(ELeave) CAsPauseStopper( KSsAsStopperNominalTimeout * 5 ); + CleanupStack::PushL( pauseStopper ); + + ss->Start(*startupProperties_0, process_0, ack_0->iStatus, id_0); + ss->Start(*startupProperties_0, process_1, ack_1->iStatus, id_1); + ss->Start(*startupProperties_0, process_2, ack_2->iStatus, id_2); + ss->Start(*startupProperties_0, process_3, ack_3->iStatus, id_3); + + INFO_PRINTF5( _L("id_0 to id_3 have the values %d %d %d %d "), id_0, id_1, id_2, id_3 ); + //Process are started using Wait for start execution behaviour, + //Start method always sets TRequestStatus to KRequestPending. + if( (KRequestPending == ack_0->iStatus.Int()) && (KRequestPending == ack_1->iStatus.Int()) && (KRequestPending == ack_2->iStatus.Int()) && (KRequestPending == ack_3->iStatus.Int()) ) + { + CActiveScheduler::Start(); + + INFO_PRINTF5( _L("Test apps rv'd with the values %d %d %d %d "), ack_0->iStatus.Int(), ack_1->iStatus.Int(), ack_2->iStatus.Int(), ack_3->iStatus.Int() ); + INFO_PRINTF5( _L("Anticipated values were %d %d %d %d "), KErrTimedOut, KErrTimedOut, KErrTimedOut, KErrTimedOut ); + + TEST( ack_0->iStatus == KErrTimedOut ); + TEST( ack_1->iStatus == KErrTimedOut ); + TEST( ack_2->iStatus == KErrTimedOut ); + TEST( ack_3->iStatus == KErrTimedOut ); + } + + CleanupStack::PopAndDestroy( 11, startupProperties_0 ); + + TEST( 0 == FindAndKill(KTestAppNoRv) ); + } + + +/** + This test starts three instances of ssmtestappgood.exe and one of ssmtestapprvafterretry.exe.The latter + fails to rv 1 + the number of retries specified in the dat file (written here and deleted by the app) + Rv is eventually successful + */ +void CSsTestStepAppStartMultiple::DoTestMultiAppIncludingRetryAsyncL() + { + INFO_PRINTF1( _L("\n\n Performing Multiple App-Start Async test---Inc one Retry") ); + + // + // Write the retry number to a file to be read, updated + // and eventually deleted by the test-app. + RFs fs; + CleanupClosePushL( fs ); + + RFileWriteStream writeStream; + CleanupClosePushL( writeStream ); + + User::LeaveIfError(fs.Connect()); + User::LeaveIfError(writeStream.Replace(fs, KDontRvCountFile, EFileWrite)); + + writeStream.WriteInt8L( KDontRvCount ); // KDontRvCount is declared in ssmtestapprvafterretry.h + writeStream.CommitL(); + + CleanupStack::PopAndDestroy( 2, &fs ); + // + + + + CSsmStartupProperties* startupProperties_0 = CSsmStartupProperties::NewL(); + CleanupStack::PushL( startupProperties_0 ); + + // Timeout is specified, therefore there are instances of CTimeoutWaiter constructed. + startupProperties_0->SetFileParamsL( KTestAppGood, KNullDesC ); + startupProperties_0->SetCommandTypeL( ESsmCmdStartApp ); + startupProperties_0->SetExecutionBehaviour( ESsmWaitForSignal ); + startupProperties_0->SetRetries( KTestMultiRetries ); + startupProperties_0->SetTimeout( KSsTestAppStartTimeout ); + + CSsmStartupProperties* startupProperties_1 = CSsmStartupProperties::NewL(); + CleanupStack::PushL( startupProperties_1 ); + // The app that rv's after some retries (specified in c:\dontrvcount.dat + startupProperties_1->SetFileParamsL( KTestAppRvAfterRetry, KNullDesC ); + startupProperties_1->SetCommandTypeL( ESsmCmdStartApp ); + startupProperties_1->SetExecutionBehaviour( ESsmWaitForSignal ); + startupProperties_1->SetRetries( KTestMultiRetries ); + // Each retry in the test app takes 2ms, so delay for 5 retries is given as 18ms. + startupProperties_1->SetTimeout( KSsTestAppStartTimeout * 6); //18000ms because KTestAppRvAfterRetry takes 2ms delay for each retry + + RProcess process_0; + CleanupClosePushL( process_0 ); + RProcess process_1; + CleanupClosePushL( process_1 ); + RProcess process_2; + CleanupClosePushL( process_2 ); + RProcess process_3; + CleanupClosePushL( process_3 ); + + TInt id_0 = 0; + TInt id_1 = 0; + TInt id_2 = 0; + TInt id_3 = 0; + + CStartAcknowledge* ack_0 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_0 ); + CStartAcknowledge* ack_1 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_1 ); + CStartAcknowledge* ack_2 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_2 ); + CStartAcknowledge* ack_3 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_3 ); + + CSsmStartSafe* ss = CSsmStartSafe::NewLC(); + // Use this timeout AO. Therefore not making assumptions about the order of completions. + CAsPauseStopper* pauseStopper = new(ELeave) CAsPauseStopper( KSsAsStopperNominalTimeout * 10 ); + CleanupStack::PushL( pauseStopper ); + + ss->Start(*startupProperties_0, process_0, ack_0->iStatus, id_0); + ss->Start(*startupProperties_0, process_1, ack_1->iStatus, id_1); + ss->Start(*startupProperties_0, process_2, ack_2->iStatus, id_2); + ss->Start(*startupProperties_1, process_3, ack_3->iStatus, id_3); // The problematic app. Starts after the retries-count file is depleted + + INFO_PRINTF5( _L("id_0 to id_3 have the values %d %d %d %d "), id_0, id_1, id_2, id_3 ); + //Process are started using Wait for start execution behaviour, + //Start method always sets TRequestStatus to KRequestPending. + if( (KRequestPending == ack_0->iStatus.Int()) && (KRequestPending == ack_1->iStatus.Int()) && (KRequestPending == ack_2->iStatus.Int()) && (KRequestPending == ack_3->iStatus.Int()) ) + { + CActiveScheduler::Start(); + + TBuf buf( process_0.FileName() ); + INFO_PRINTF2( _L("process_0 filename %S"), &buf ); + + buf.Copy( process_1.FileName() ); + INFO_PRINTF2( _L("process_1 filename %S"), &buf ); + + buf.Copy( process_2.FileName() ); + INFO_PRINTF2( _L("process_2 filename %S"), &buf ); + + buf.Copy( process_3.FileName() ); + INFO_PRINTF2( _L("process_3 filename %S"), &buf ); + + + INFO_PRINTF5( _L("Test apps rv'd with the values %d %d %d %d "), ack_0->iStatus.Int(), ack_1->iStatus.Int(), ack_2->iStatus.Int(), ack_3->iStatus.Int() ); + INFO_PRINTF5( _L("Anticipated values were %d %d %d %d "), KErrNone, KErrNone, KErrNone, KErrNone ); + + TEST( ack_0->iStatus == KErrNone ); + TEST( ack_1->iStatus == KErrNone ); + TEST( ack_2->iStatus == KErrNone ); + TEST( ack_3->iStatus == KErrNone ); + } + + CleanupStack::PopAndDestroy( 12, startupProperties_0 ); + + TEST( 1 == FindAndKill(KTestAppRvAfterRetry) ); + TEST( 3 == FindAndKill(KTestAppGood) ); + } + + + + +// +// START AS PROCESSES +// + +/** + Concurrently starts four instances of ssmtestappgood.exe as processes + */ +void CSsTestStepAppStartMultiple::DoTestMultiProcAsyncL() + { + + INFO_PRINTF1( _L("\n\n Performing Multiple Process-Start Async test---no timeout") ); + + CSsmStartupProperties* startupProperties_0 = CSsmStartupProperties::NewL(); + CleanupStack::PushL( startupProperties_0 ); + + // Slightly cheeky. Use the same startup properties for each call + // No timeout specified, therefore there is no instance of CTimeoutWaiter constructed. + startupProperties_0->SetFileParamsL( KTestAppGood, KNullDesC ); + startupProperties_0->SetCommandTypeL( ESsmCmdStartProcess ); + startupProperties_0->SetExecutionBehaviour( ESsmWaitForSignal ); + + RProcess process_0; + CleanupClosePushL( process_0 ); + RProcess process_1; + CleanupClosePushL( process_1 ); + RProcess process_2; + CleanupClosePushL( process_2 ); + RProcess process_3; + CleanupClosePushL( process_3 ); + + TInt id_0 = 0; + TInt id_1 = 0; + TInt id_2 = 0; + TInt id_3 = 0; + + CStartAcknowledge* ack_0 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_0 ); + CStartAcknowledge* ack_1 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_1 ); + CStartAcknowledge* ack_2 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_2 ); + CStartAcknowledge* ack_3 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_3 ); + + CSsmStartSafe* ss = CSsmStartSafe::NewLC(); + // Use this timeout AO. Therefore not making assumptions about the order of completions. + CAsPauseStopper* pauseStopper = new(ELeave) CAsPauseStopper( KSsAsStopperNominalTimeout * 2 ); + CleanupStack::PushL( pauseStopper ); + + ss->Start(*startupProperties_0, process_0, ack_0->iStatus, id_0); + ss->Start(*startupProperties_0, process_1, ack_1->iStatus, id_1); + ss->Start(*startupProperties_0, process_2, ack_2->iStatus, id_2); + ss->Start(*startupProperties_0, process_3, ack_3->iStatus, id_3); + + INFO_PRINTF5( _L("id_0 to id_3 have the values %d %d %d %d "), id_0, id_1, id_2, id_3 ); + //Process are started using Wait for start execution behaviour, + //Start method always sets TRequestStatus to KRequestPending. + if( (KRequestPending == ack_0->iStatus.Int()) && (KRequestPending == ack_1->iStatus.Int()) && (KRequestPending == ack_2->iStatus.Int()) && (KRequestPending == ack_3->iStatus.Int()) ) + { + CActiveScheduler::Start(); + + TBuf buf( process_0.FileName() ); + INFO_PRINTF2( _L("process_0 filename %S"), &buf ); + + buf.Copy( process_1.FileName() ); + INFO_PRINTF2( _L("process_1 filename %S"), &buf ); + + buf.Copy( process_2.FileName() ); + INFO_PRINTF2( _L("process_2 filename %S"), &buf ); + + buf.Copy( process_3.FileName() ); + INFO_PRINTF2( _L("process_3 filename %S"), &buf ); + + + INFO_PRINTF5( _L("Test apps rv'd with the values %d %d %d %d "), ack_0->iStatus.Int(), ack_1->iStatus.Int(), ack_2->iStatus.Int(), ack_3->iStatus.Int() ); + INFO_PRINTF5( _L("Anticipated values were %d %d %d %d "), KErrNone, KErrNone, KErrNone, KErrNone ); + + TEST( ack_0->iStatus == KErrNone ); + TEST( ack_1->iStatus == KErrNone ); + TEST( ack_2->iStatus == KErrNone ); + TEST( ack_3->iStatus == KErrNone ); + } + + CleanupStack::PopAndDestroy( 11, startupProperties_0 ); + + TEST( 4 == FindAndKill(KTestAppGood) ); + } + + + +/** + Concurrently starts four instances of ssmtestappgood.exe as processes + A timeout value is specified which ensures that intances of CTimeoutWaiter are created + */ +void CSsTestStepAppStartMultiple::DoTestMultiProcWithTimeoutAsyncL() + { + + INFO_PRINTF1( _L("\n\n Performing Multiple Process-Start Async test---*with* timeout") ); + + CSsmStartupProperties* startupProperties_0 = CSsmStartupProperties::NewL(); + CleanupStack::PushL( startupProperties_0 ); + + // Slightly cheeky. Use the same startup properties for each call + // Timeout is specified, therefore there are instances of CTimeoutWaiter constructed. + startupProperties_0->SetFileParamsL( KTestAppGood, KNullDesC ); + startupProperties_0->SetCommandTypeL( ESsmCmdStartProcess ); + startupProperties_0->SetExecutionBehaviour( ESsmWaitForSignal ); + startupProperties_0->SetTimeout( KSsTestAppStartTimeout ); + + RProcess process_0; + CleanupClosePushL( process_0 ); + RProcess process_1; + CleanupClosePushL( process_1 ); + RProcess process_2; + CleanupClosePushL( process_2 ); + RProcess process_3; + CleanupClosePushL( process_3 ); + + TInt id_0 = 0; + TInt id_1 = 0; + TInt id_2 = 0; + TInt id_3 = 0; + + CStartAcknowledge* ack_0 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_0 ); + CStartAcknowledge* ack_1 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_1 ); + CStartAcknowledge* ack_2 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_2 ); + CStartAcknowledge* ack_3 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_3 ); + + CSsmStartSafe* ss = CSsmStartSafe::NewLC(); + // Use this timeout AO. Therefore not making assumptions about the order of completions. + CAsPauseStopper* pauseStopper = new(ELeave) CAsPauseStopper( KSsAsStopperNominalTimeout * 5 ); + CleanupStack::PushL( pauseStopper ); + + ss->Start(*startupProperties_0, process_0, ack_0->iStatus, id_0); + ss->Start(*startupProperties_0, process_1, ack_1->iStatus, id_1); + ss->Start(*startupProperties_0, process_2, ack_2->iStatus, id_2); + ss->Start(*startupProperties_0, process_3, ack_3->iStatus, id_3); + + INFO_PRINTF5( _L("id_0 to id_3 have the values %d %d %d %d "), id_0, id_1, id_2, id_3 ); + //Process are started using Wait for start execution behaviour, + //Start method always sets TRequestStatus to KRequestPending. + if( (KRequestPending == ack_0->iStatus.Int()) && (KRequestPending == ack_1->iStatus.Int()) && (KRequestPending == ack_2->iStatus.Int()) && (KRequestPending == ack_3->iStatus.Int()) ) + { + CActiveScheduler::Start(); + + TBuf buf( process_0.FileName() ); + INFO_PRINTF2( _L("process_0 filename %S"), &buf ); + + buf.Copy( process_1.FileName() ); + INFO_PRINTF2( _L("process_1 filename %S"), &buf ); + + buf.Copy( process_2.FileName() ); + INFO_PRINTF2( _L("process_2 filename %S"), &buf ); + + buf.Copy( process_3.FileName() ); + INFO_PRINTF2( _L("process_3 filename %S"), &buf ); + + + INFO_PRINTF5( _L("Test apps rv'd with the values %d %d %d %d "), ack_0->iStatus.Int(), ack_1->iStatus.Int(), ack_2->iStatus.Int(), ack_3->iStatus.Int() ); + INFO_PRINTF5( _L("Anticipated values were %d %d %d %d "), KErrNone, KErrNone, KErrNone, KErrNone ); + + TEST( ack_0->iStatus == KErrNone ); + TEST( ack_1->iStatus == KErrNone ); + TEST( ack_2->iStatus == KErrNone ); + TEST( ack_3->iStatus == KErrNone ); + } + + CleanupStack::PopAndDestroy( 11, startupProperties_0 ); + + TEST( 4 == FindAndKill(KTestAppGood) ); + } + + + +/** + Concurrently starts four instances of ssmtestappnorv.exe as processes + All of these timeout (naturalment) + */ +void CSsTestStepAppStartMultiple::DoTestMultiProcAllTimeoutAsyncL() + { + + INFO_PRINTF1( _L("\n\n Performing Multiple App-as-Process-Start Async test---ALL timeout") ); + + CSsmStartupProperties* startupProperties_0 = CSsmStartupProperties::NewL(); + CleanupStack::PushL( startupProperties_0 ); + + // Slightly cheeky. Use the same startup properties for each call + startupProperties_0->SetFileParamsL( KTestAppNoRv, KNullDesC ); + startupProperties_0->SetCommandTypeL( ESsmCmdStartProcess ); + startupProperties_0->SetExecutionBehaviour( ESsmWaitForSignal ); + startupProperties_0->SetTimeout( KInduceTimeoutFailWaitTime ); + + + RProcess process_0; + CleanupClosePushL( process_0 ); + RProcess process_1; + CleanupClosePushL( process_1 ); + RProcess process_2; + CleanupClosePushL( process_2 ); + RProcess process_3; + CleanupClosePushL( process_3 ); + + TInt id_0 = 0; + TInt id_1 = 0; + TInt id_2 = 0; + TInt id_3 = 0; + + CStartAcknowledge* ack_0 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_0 ); + CStartAcknowledge* ack_1 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_1 ); + CStartAcknowledge* ack_2 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_2 ); + CStartAcknowledge* ack_3 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_3 ); + + CSsmStartSafe* ss = CSsmStartSafe::NewLC(); + // Use this timeout AO. Therefore not making assumptions about the order of completions. + CAsPauseStopper* pauseStopper = new(ELeave) CAsPauseStopper( KSsAsStopperNominalTimeout * 5 ); + CleanupStack::PushL( pauseStopper ); + + ss->Start(*startupProperties_0, process_0, ack_0->iStatus, id_0); + ss->Start(*startupProperties_0, process_1, ack_1->iStatus, id_1); + ss->Start(*startupProperties_0, process_2, ack_2->iStatus, id_2); + ss->Start(*startupProperties_0, process_3, ack_3->iStatus, id_3); + + INFO_PRINTF5( _L("id_0 to id_3 have the values %d %d %d %d "), id_0, id_1, id_2, id_3 ); + //Process are started using Wait for start execution behaviour, + //Start method always sets TRequestStatus to KRequestPending. + if( (KRequestPending == ack_0->iStatus.Int()) && (KRequestPending == ack_1->iStatus.Int()) && (KRequestPending == ack_2->iStatus.Int()) && (KRequestPending == ack_3->iStatus.Int()) ) + { + CActiveScheduler::Start(); + + INFO_PRINTF5( _L("Test apps rv'd with the values %d %d %d %d "), ack_0->iStatus.Int(), ack_1->iStatus.Int(), ack_2->iStatus.Int(), ack_3->iStatus.Int() ); + INFO_PRINTF5( _L("Anticipated values were %d %d %d %d "), KErrTimedOut, KErrTimedOut, KErrTimedOut, KErrTimedOut ); + + TEST( ack_0->iStatus == KErrTimedOut ); + TEST( ack_1->iStatus == KErrTimedOut ); + TEST( ack_2->iStatus == KErrTimedOut ); + TEST( ack_3->iStatus == KErrTimedOut ); + } + + CleanupStack::PopAndDestroy( 11, startupProperties_0 ); + + TEST( 0 == FindAndKill(KTestAppNoRv) ); + } + + + +/** + This test starts three instances of ssmtestappgood.exe and one of ssmtestapprvafterretry.exe as processes.The latter + fails to rv 1 + the number of retries specified in the dat file (written here and deleted by the app) + Rv is eventually successful + */ +void CSsTestStepAppStartMultiple::DoTestMultiProcIncludingRetryAsyncL() + { + INFO_PRINTF1( _L("\n\n Performing Multiple Slow App-As-Process-Start Async test---ALL Retry") ); + + // + // Write the retry number to a file to be read, updated + // and eventually deleted by the test-app. + RFs fs; + CleanupClosePushL( fs ); + + RFileWriteStream writeStream; + CleanupClosePushL( writeStream ); + + User::LeaveIfError(fs.Connect()); + User::LeaveIfError(writeStream.Replace(fs, KDontRvCountFile, EFileWrite)); + + writeStream.WriteInt8L( KDontRvCount ); // KDontRvCount is declared in ssmtestapprvafterretry.h + writeStream.CommitL(); + + CleanupStack::PopAndDestroy( 2, &fs ); + // + + + + CSsmStartupProperties* startupProperties_0 = CSsmStartupProperties::NewL(); + CleanupStack::PushL( startupProperties_0 ); + + // Timeout is specified, therefore there are instances of CTimeoutWaiter constructed. + startupProperties_0->SetFileParamsL( KTestAppGood, KNullDesC ); + startupProperties_0->SetCommandTypeL( ESsmCmdStartProcess ); + startupProperties_0->SetExecutionBehaviour( ESsmWaitForSignal ); + startupProperties_0->SetRetries( KTestMultiRetries ); + startupProperties_0->SetTimeout( KSsTestAppStartTimeout ); + + CSsmStartupProperties* startupProperties_1 = CSsmStartupProperties::NewL(); + CleanupStack::PushL( startupProperties_1 ); + // The app that rv's after some retries (specified in c:\dontrvcount.dat + startupProperties_1->SetFileParamsL( KTestAppRvAfterRetry, KNullDesC ); + startupProperties_1->SetCommandTypeL( ESsmCmdStartProcess ); + startupProperties_1->SetExecutionBehaviour( ESsmWaitForSignal ); + startupProperties_1->SetRetries( KTestMultiRetries ); + startupProperties_1->SetTimeout( KSsTestAppStartTimeout * 6); //18000ms because KTestAppRvAfterRetry takes 2ms delay for each retry + + RProcess process_0; + CleanupClosePushL( process_0 ); + RProcess process_1; + CleanupClosePushL( process_1 ); + RProcess process_2; + CleanupClosePushL( process_2 ); + RProcess process_3; + CleanupClosePushL( process_3 ); + + TInt id_0 = 0; + TInt id_1 = 0; + TInt id_2 = 0; + TInt id_3 = 0; + + CStartAcknowledge* ack_0 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_0 ); + CStartAcknowledge* ack_1 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_1 ); + CStartAcknowledge* ack_2 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_2 ); + CStartAcknowledge* ack_3 = new(ELeave) CStartAcknowledge( this ); + CleanupStack::PushL( ack_3 ); + + CSsmStartSafe* ss = CSsmStartSafe::NewLC(); + // Use this timeout AO. Therefore not making assumptions about the order of completions. + CAsPauseStopper* pauseStopper = new(ELeave) CAsPauseStopper( KSsAsStopperNominalTimeout * 10 ); + CleanupStack::PushL( pauseStopper ); + + ss->Start(*startupProperties_0, process_0, ack_0->iStatus, id_0); + ss->Start(*startupProperties_0, process_1, ack_1->iStatus, id_1); + ss->Start(*startupProperties_0, process_2, ack_2->iStatus, id_2); + ss->Start(*startupProperties_1, process_3, ack_3->iStatus, id_3); // The problematic app. Starts after the retries-count file is depleted + + INFO_PRINTF5( _L("id_0 to id_3 have the values %d %d %d %d "), id_0, id_1, id_2, id_3 ); + //Process are started using Wait for start execution behaviour, + //Start method always sets TRequestStatus to KRequestPending. + if( (KRequestPending == ack_0->iStatus.Int()) && (KRequestPending == ack_1->iStatus.Int()) && (KRequestPending == ack_2->iStatus.Int()) && (KRequestPending == ack_3->iStatus.Int()) ) + { + CActiveScheduler::Start(); + + TBuf buf( process_0.FileName() ); + INFO_PRINTF2( _L("process_0 filename %S"), &buf ); + + buf.Copy( process_1.FileName() ); + INFO_PRINTF2( _L("process_1 filename %S"), &buf ); + + buf.Copy( process_2.FileName() ); + INFO_PRINTF2( _L("process_2 filename %S"), &buf ); + + buf.Copy( process_3.FileName() ); + INFO_PRINTF2( _L("process_3 filename %S"), &buf ); + + + INFO_PRINTF5( _L("Test apps rv'd with the values %d %d %d %d "), ack_0->iStatus.Int(), ack_1->iStatus.Int(), ack_2->iStatus.Int(), ack_3->iStatus.Int() ); + INFO_PRINTF5( _L("Anticipated values were %d %d %d %d "), KErrNone, KErrNone, KErrNone, KErrNone ); + + TEST( ack_0->iStatus == KErrNone ); + TEST( ack_1->iStatus == KErrNone ); + TEST( ack_2->iStatus == KErrNone ); + TEST( ack_3->iStatus == KErrNone ); + } + + CleanupStack::PopAndDestroy( 12, startupProperties_0 ); + + TEST( 1 == FindAndKill(KTestAppRvAfterRetry) ); + TEST( 3 == FindAndKill(KTestAppGood) ); + } + + + +TVerdict CSsTestStepAppStartMultiple::doTestStepPreambleL() + { + iActiveScheduler = new(ELeave) CActiveScheduler; + CActiveScheduler::Install( iActiveScheduler ); + + return CTestStep::doTestStepPreambleL(); + } + + + +/** */ +TVerdict CSsTestStepAppStartMultiple::doTestStepPostambleL() + { + return CTestStep::doTestStepPostambleL(); + } + + +/** + From MSsTestAsyncNotifier +*/ +void CSsTestStepAppStartMultiple::SsTestNotify( TInt aNotify ) + { + // This method is called if CSsmStartSafe's start method leaves in void CTestAndStopper::DoStartsL(). + INFO_PRINTF2( _L("*** App rv'd with %d"), aNotify ); + } + + + +CSsTestStepAppStartMultiple::CSsTestStepAppStartMultiple() + { + SetTestStepName( KCTestCaseAppStartMultiple ); + } + + + +CSsTestStepAppStartMultiple::~CSsTestStepAppStartMultiple() + { + delete iActiveScheduler; + } +