diff -r 000000000000 -r bde4ae8d615e os/ossrv/genericservices/taskscheduler/Test/Robustness/TC_TSCH_ROBUSTNESS.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/ossrv/genericservices/taskscheduler/Test/Robustness/TC_TSCH_ROBUSTNESS.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,583 @@ +// 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: +// + +#include +#include "Thelpers.h" + +#include +#include +#include +#include +#include +#include +#include "TestUtils.h" + +_LIT(KTestName, "Task Scheduler Robustness Test"); +_LIT(KTaskScheduler, "schexe"); + +RTest TheTest(KTestName); + +typedef CArrayFixFlat CTaskInfoArray; +typedef CArrayFixFlat CSchItemRefArray; +typedef CArrayFixFlat CSchConditionArray; + +static RScheduler TheScheduler; +static CTrapCleanup* TheCleanup; +static RFs TheFsSession; + +const TInt KTestKey1 = 1; + +_LIT(KSeparator, "|"); // Invalid filepath char used to separate filenames + +// This function launches the TPropertyDefine process which +// has WriteDeviceData Capabilities enabling it to create the P&S +// variables used by this test. +static void LaunchHelperL(TUid aCategory, TInt aKey, TInt aAttr) + { + _LIT(KConditionHelper, "TPropertyDefine"); + TRequestStatus stat; + RProcess p; + + TBuf<32> args; + args.AppendNum(aCategory.iUid); + args.Append(KSeparator); + args.AppendNum(aKey); + args.Append(KSeparator); + args.AppendNum(aAttr); + + User::LeaveIfError(p.Create(KConditionHelper, args,EOwnerProcess)); + + // Asynchronous logon: completes when process terminates with process exit code + p.Logon(stat); + p.Resume(); + + User::WaitForRequest(stat); + TInt exitReason = p.ExitReason(); + p.Close(); + User::LeaveIfError(exitReason); + } + + +static void CreateTestVariables() + { + LaunchHelperL(KUidSystemCategory, KTestKey1,RProperty::EInt); + } + +static void ResetVariablesL(TInt aKey1Val) + { + User::LeaveIfError(RProperty::Set(KUidSystemCategory, KTestKey1,aKey1Val)); + } + + +// single condition with default time set to 1 year in the future +static TInt CreateScheduleL(TSchedulerItemRef& aRef, + RScheduler& aScheduler, + const TUid& aConditionUID, + TUint aConditionUInt) + { + aRef.iName = _L("Schedule created using CreateScheduleSingle"); + + CSchConditionArray* conditionList = new (ELeave) CSchConditionArray(1); + CleanupStack::PushL(conditionList); + + //create a single condition + TTaskSchedulerCondition condition1; + condition1.iCategory = aConditionUID; + condition1.iKey = aConditionUInt; + condition1.iState = 10; + condition1.iType = TTaskSchedulerCondition::EEquals; + + conditionList->AppendL(condition1); + + //create a persistent schedule + TTime time = SchSvrHelpers::TimeBasedOnOffset(0, 0, 0, 0, 0, 1); //1 year in the future + TInt res = aScheduler.CreatePersistentSchedule(aRef, *conditionList, time); + CleanupStack::PopAndDestroy(); // conditionList + return res; + } + +//Add a single task to a schedule +static TInt AddTaskToScheduleL(const TDesC& aName, + TInt& aNewId, + TInt aScheduleId, + RScheduler& aScheduler) + { + TTaskInfo taskInfo; + taskInfo.iTaskId = aNewId; + taskInfo.iName = aName; + taskInfo.iPriority = 2; + taskInfo.iRepeat = 0; + HBufC* data = _L("the data").AllocLC(); + TInt res = aScheduler.ScheduleTask(taskInfo, *data, aScheduleId); + aNewId = taskInfo.iTaskId; + + CleanupStack::PopAndDestroy(); // data + return res; + } + + +static TInt ScheduleTaskL() + { + //reset the p&s variables before creating the schedule + ResetVariablesL(0); + + //Create a schedule + TSchedulerItemRef ref1; + TheTest.Printf(_L("Create a schedule\n")); + TInt res = CreateScheduleL(ref1, TheScheduler, KUidSystemCategory, KTestKey1); + TEST2(res, KErrNone); + + //Add task to the schedule + TInt task1 = 0; + _LIT(KName1, "Test Task"); + TheTest.Printf(_L("Schedule a task\n")); + + res = AddTaskToScheduleL(KName1, task1, ref1.iHandle, TheScheduler); + TEST2(res, KErrNone); + + return res; + } + +static void ExecuteTaskL() + { + TheTest.Printf(_L("Execute Task\n")); + //Set property causing schedule to be run + User::LeaveIfError(RProperty::Set(KUidSystemCategory, KTestKey1,10)); + + //Pause to wait for the task to be executed + SchSvrHelpers::Pause(TheTest, 2); + + } + +static TInt ScheduleAndExecuteTaskL() + { + TInt res = ScheduleTaskL(); + + ExecuteTaskL(); + + return res; + } + +LOCAL_C void AddTaskFunctionL() + { + RScheduler localScheduler; + // Connect to the server + TInt res = localScheduler.Connect(); + TEST2(res, KErrNone); + //Schedule a task and execute it + //reset the p&s variables before creating the schedule + ResetVariablesL(0); + + //Create a schedule + TSchedulerItemRef ref1; + ref1.iName = _L("Schedule created using CreateScheduleSingle"); + CSchConditionArray* conditionList = new (ELeave) CSchConditionArray(1); + CleanupStack::PushL(conditionList); + + //create a single condition + TTaskSchedulerCondition condition1; + condition1.iCategory = KUidSystemCategory; + condition1.iKey = KTestKey1; + condition1.iState = 10; + condition1.iType = TTaskSchedulerCondition::EEquals; + + conditionList->AppendL(condition1); + + //create a persistent schedule + TTime time = SchSvrHelpers::TimeBasedOnOffset(0, 0, 0, 0, 0, 1); //1 year in the future + res = localScheduler.CreatePersistentSchedule(ref1, *conditionList, time); + CleanupStack::PopAndDestroy(); // conditionList + + //Add task to the schedule + TInt task1 = 0; + _LIT(KName1, "Test Task"); + + TTaskInfo taskInfo; + taskInfo.iTaskId = task1; + taskInfo.iName = KName1; + taskInfo.iPriority = 2; + taskInfo.iRepeat = 0; + HBufC* data = _L("the data").AllocLC(); + + TInt ret = localScheduler.ScheduleTask(taskInfo, *data, ref1.iHandle); + TEST2(ret, 0);//EPanicNotRegistered == 0 + + task1 = taskInfo.iTaskId; + + CleanupStack::PopAndDestroy(); // data + + //Tidying up so next test will be clear. + SchSvrHelpers::DeleteAllSchedulesL(localScheduler); + + localScheduler.Close(); + } + +// Helper function for DEF124488 +LOCAL_C TInt TestPanicThread(TAny*) + { + CTrapCleanup* cleanup = CTrapCleanup::New(); + if(!cleanup) + return KErrNoMemory; + + + TRAPD(err,AddTaskFunctionL()) + TEST2(err,KErrNone); + + delete cleanup; + return KErrNone; + } + +/** +@SYMTestCaseID SYSLIB-SCHSVR-CT-3369 +@SYMTestCaseDesc Test deletion of temporary files with non existent client +@SYMTestPriority High +@SYMTestActions Schedule a task with a client that does not exist. + Ensure that all temporary files are deleted after + schedule excecutes +@SYMTestExpectedResults All temporary files should be deleted by task scheduler +@SYMDEF PDEF101876 +*/ +static void DoTest1L() + { + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-3369 Test handling of non existent client ")); + // Connect to the server + TheTest.Next(_L("===== Connect to Scheduler =====")); + TInt res = TheScheduler.Connect(); + TEST2(res, KErrNone); + + // Register a client with the server - this client does not exist + TheTest.Next(_L("===== Registering Client =====")); + res = SchSvrHelpers::RegisterNonExistentClient(TheScheduler); + TEST2(res, KErrNone); + + //Schedule a task and execute it + ScheduleAndExecuteTaskL(); + + // Check for left task files after scheduled tasks completed + // To access private data cage, uses SchSvrHelplers::CheckTaskFilesL() + TheTest.Next(_L("Now checking no files left when tasks completed")); + TInt err = SchSvrHelpers::CheckTaskFilesL(); + + // If there's any task files left, test fails with error code KErrGeneral + TEST(err == KErrNone); + TheTest.Next(_L("All files deleted as expected...")); + + //Tidying up so next test will be clear. + TheTest.Next(_L("Delete all schedules")); + SchSvrHelpers::DeleteAllSchedulesL(TheScheduler); + + TheScheduler.Close(); + + } + +/** +@SYMTestCaseID SYSLIB-SCHSVR-CT-3370 +@SYMTestCaseDesc Test deletion of temporary files with faulty client +@SYMTestPriority High +@SYMTestActions Schedule a task with a client that panics and does not + release the temporary file handle. + Ensure that all temporary files are deleted after schedule excecutes +@SYMTestExpectedResults All temporary files should be deleted by task scheduler +@SYMDEF PDEF101876 +*/ +static void DoTest2L() + { + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-3370 Test handling of panicing client ")); + + // Connect to the server + TheTest.Next(_L("===== Connect to Scheduler =====")); + TInt res = TheScheduler.Connect(); + TEST2(res, KErrNone); + + // Register a client with the server - this client panics + //after calling RFile::AdoptFromClient + TheTest.Next(_L("===== Registering Client =====")); + res = SchSvrHelpers::RegisterPanicingClient(TheScheduler); + TEST2(res, KErrNone); + + //Schedule a task and execute it - we expect the client to panic + ScheduleAndExecuteTaskL(); + + // Check for left task files after scheduled tasks completed + // To access private data cage, uses SchSvrHelplers::CheckTaskFilesL() + TheTest.Next(_L("Now checking no files left when tasks completed")); + TInt err = SchSvrHelpers::CheckTaskFilesL(); + + // If there's any task files left, test fails with error code KErrGeneral + TEST(err == KErrNone); + + TheTest.Next(_L("All files deleted as expected...")); + + //Tidying up so next test will be clear. + TheTest.Next(_L("Delete all schedules")); + SchSvrHelpers::DeleteAllSchedulesL(TheScheduler); + + TheScheduler.Close(); + } + +/** +@SYMTestCaseID SYSLIB-SCHSVR-CT-3371 +@SYMTestCaseDesc Test deletion of temporary files on task scheduler startup +@SYMTestPriority High +@SYMTestActions Create temporary files in the task schedulers private data cage. + Start the task scheduler and verify that these files are deleted. +@SYMTestExpectedResults All temporary files should be deleted by task scheduler on startup +@SYMDEF PDEF101876 +*/ +static void DoTest3L() + { + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-3371 Test deletion of temporary files on startup ")); + + //Connect to the scheduler + TInt res = TheScheduler.Connect(); + TEST2(res, KErrNone); + + // Kill the server to ensure we restart it when we connect + res = CleanupHelpers::KillProcess(KTaskScheduler); + TEST2(res, KErrNone); + TheScheduler.Close(); + + // Create task files to test cleanup + // To access private data cage, uses SchSvrHelplers::CreateTaskFilesL() + TheTest.Next(_L("Creating dummy task files")); + res = SchSvrHelpers::CreateTaskFilesL(); + + //Restart the scheduler which should clean up temp files on startup + TheTest.Next(_L("===== Connect to Scheduler =====")); + res = TheScheduler.Connect(); + TEST2(res, KErrNone); + + //wait for the server to start up + SchSvrHelpers::Pause(TheTest, 2); + + TheScheduler.Close(); + + // Check for left task files after scheduled tasks completed + // To access private data cage, uses SchSvrHelplers::CheckTaskFilesL() + TheTest.Next(_L("Now checking no files left after task scheduler starts")); + res = SchSvrHelpers::CheckTaskFilesL(); + + TEST2(res, KErrNone); + + TheTest.Next(_L("All files deleted as expected...")); + } + +/** +@SYMTestCaseID SYSLIB-SCHSVR-CT-3402 +@SYMTestCaseDesc Test memory cleanup on Task Scheduler exit +@SYMTestPriority High +@SYMTestActions Start the scheduler and register a client. + Execute a schedule and then terminate the scheduler. + When the scheduler is restarted it should exit as there are no + pending schedules. On exit all allocated memory should be freed +@SYMTestExpectedResults All allocated memory should be freed when the scheduler exits +@SYMDEF DEF102414 +*/ +static void DoTest4L() + { + __UHEAP_MARK; + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-3402 Test memory cleanup on Task Scheduler exit ")); + + // Connect to the server + TheTest.Next(_L("===== Connect to Scheduler =====")); + TInt res = TheScheduler.Connect(); + TEST2(res, KErrNone); + + // Register a client with the server + TheTest.Next(_L("===== Registering Client =====")); + res = SchSvrHelpers::RegisterClientL(TheScheduler); + TEST2(res, KErrNone); + + //Schedule a task and execute it + ScheduleAndExecuteTaskL(); + + // Kill the server + res = CleanupHelpers::KillProcess(KTaskScheduler); + TEST2(res, KErrNone); + + TheScheduler.Close(); + + //Restarting with a registered client and no schedule should + //cause the server to exit. Ther server should free all allocated + //memory. If all memory is not freed, heap check macros within + // the task scheduler code will cause a panic + SchSvrHelpers::LaunchTaskSchedulerL(); + + //wait for the server to exit + SchSvrHelpers::Pause(TheTest, 2); + + //Verify that the server has already exited - there are two valid + //error codes depending on how quickly the process is cleaned up + //KErrDied - Process is dead but hasn't been cleaned up yet by the kernel + //KErrNotFound - Process has been cleaned up + res = CleanupHelpers::KillProcess(KTaskScheduler); + + TEST((res == KErrDied)||(res == KErrNotFound)); + + __UHEAP_MARKEND; + + TheTest.Next(_L("All memory freed...")); + } + + +/** +@SYMTestCaseID SYSLIB-SCHSVR-CT-3412 +@SYMTestCaseDesc Test Task Scheduler startup with pending schedule +@SYMTestPriority High +@SYMTestActions Start the scheduler and register a client. + Create a scheduled task and then terminate the scheduler without executing the task. + When the scheduler is restarted it should not exit as there is a + pending schedule. Verify that the scheduler is still active by executing + the schedule +@SYMTestExpectedResults The task scheduler should not exit and the schedule should execute +@SYMDEF DEF102414 +*/ +static void DoTest5L() + { + __UHEAP_MARK; + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-3412 Test Task Scheduler startup with pending schedule ")); + + // Connect to the server + TheTest.Next(_L("===== Connect to Scheduler =====")); + TInt res = TheScheduler.Connect(); + TEST2(res, KErrNone); + + // Register a client with the server + TheTest.Next(_L("===== Registering Client =====")); + res = SchSvrHelpers::RegisterClientL(TheScheduler); + TEST2(res, KErrNone); + + //Schedule a task + ScheduleTaskL(); + + // Kill the server + res = CleanupHelpers::KillProcess(KTaskScheduler); + TEST2(res, KErrNone); + TheScheduler.Close(); + + TheTest.Next(_L("Create Task notification semaphore")); + //initialise task notification semaphore + STaskSemaphore sem; + sem.CreateL(); + + //Restart the scheduler - task scheduler should not exit as there is a + //pending schedule + res = SchSvrHelpers::LaunchTaskSchedulerL(); + TEST2(res, KErrNone); + + //Execute task and wait for it to run - this would not succeed + //if task scheduler had exited above + ExecuteTaskL(); + TEST2(STaskSemaphore::WaitL(KDefaultTimeout), KErrNone); + + //Kill the process and verify that the scheduler was active + //If the task scheduler isnt active when we try to kill it + //KillProcess would return KErrDied + res = CleanupHelpers::KillProcess(KTaskScheduler); + TEST2(res, KErrNone); + + //close handle to semaphore + sem.Close(); + + __UHEAP_MARKEND; + + } + +/** +@SYMTestCaseID SYSLIB-SCHSVR-CT-4010 +@SYMTestCaseDesc Test that adding a task using an unregistered client panics the client and does not crash the server. +@SYMTestPriority High +@SYMTestActions Schedule a task with a client that has not been registered. +@SYMTestExpectedResults Client should be panicked. +@SYMDEF DEF124488 +*/ +static void DoTest6L() + { + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SCHSVR-CT-4010 Test handling of unregistered client Should Panic Client thread ")); + + RThread testThread; + _LIT(KThreadName, "PanicClientThread"); + + testThread.Create(KThreadName, TestPanicThread, KDefaultStackSize, 0x1000, 0x100000, NULL); + + TRequestStatus requestStatus; + // Request notification when the thread terminates + testThread.Logon(requestStatus); + + TBool justInTime=User::JustInTime(); + User::SetJustInTime(EFalse); + // Let the thread execute + testThread.Resume(); + + // Wait for termination + User::WaitForRequest(requestStatus); + User::SetJustInTime(justInTime); + + TEST2(testThread.ExitReason(), 0); + testThread.Close(); + + } + +static TInt RunTestsL() + { + TheTest.Next(_L("Delete old files")); + SchSvrHelpers::DeleteScheduleFilesL(); + + //create P&S variables for the test + CreateTestVariables(); + + TheTest.Next(_L("Start tests")); + + CActiveScheduler* scheduler = new (ELeave) CActiveScheduler(); + CleanupStack::PushL(scheduler); + CActiveScheduler::Install(scheduler); + + DoTest1L(); + DoTest2L(); + DoTest3L(); + DoTest4L(); + DoTest5L(); + DoTest6L(); + + TheTest.Next(_L("Tidying up")); + CleanupStack::PopAndDestroy(scheduler); + + return KErrNone; + } + +GLDEF_C TInt E32Main() + { + __UHEAP_MARK; + TheTest.Start(_L("TC_TSCH_ROBUSTNESS")); + TheTest.Title(); + TheCleanup = CTrapCleanup::New(); + + //If the previous test fails, SCHSVR.exe may stay in memory. + TRAPD(error,CleanupHelpers::TestCleanupL()); + TEST2(error, KErrNone); + TheTest(TheFsSession.Connect() == KErrNone);; + TRAP(error, RunTestsL()); + TEST2(error, KErrNone); + TRAP(error,CleanupHelpers::TestCleanupL()); + TEST2(error, KErrNone); + delete TheCleanup; + + TheFsSession.Close(); + TheTest.End(); + TheTest.Close(); + __UHEAP_MARKEND; + + return KErrNone; + }