sl@0: // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include "T_backupSrv.h" sl@0: LOCAL_D RTest MainTest(_L(" T_BackupSrv.cpp")); sl@0: sl@0: _LIT(KFileName1, "FileName1"); sl@0: _LIT(KFileName2, "FileName2"); sl@0: _LIT(KFileName3, "FileName3"); sl@0: _LIT(KFileName4, "FileName4"); sl@0: sl@0: // Nasty global convenience function sl@0: LOCAL_D void LogThread() sl@0: { sl@0: TBuf<150> buf((RThread().Name())); sl@0: RDebug::Print(_L("*** Currently in thread : ")); sl@0: RDebug::Print(buf); sl@0: } sl@0: sl@0: // sl@0: // class CBackupOperationObserver sl@0: // sl@0: CBackupOperationObserver* CBackupOperationObserver::NewL(TInt aObserverNumber) sl@0: { sl@0: LogThread(); sl@0: RDebug::Print(_L("CBackupOperationObserver::NewL")); sl@0: sl@0: CBackupOperationObserver* self = new (ELeave) CBackupOperationObserver(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aObserverNumber); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: CBackupOperationObserver::CBackupOperationObserver() sl@0: : CActive(0) sl@0: { ; } sl@0: sl@0: CBackupOperationObserver::~CBackupOperationObserver() sl@0: { sl@0: LogThread(); sl@0: RDebug::Print(_L("CBackupOperationObserver::~CBackupOperationObserver")); sl@0: sl@0: iBackupSession->DeRegisterBackupOperationObserver(*this); sl@0: delete iBackupSession; sl@0: sl@0: delete iLocalRTest; sl@0: } sl@0: sl@0: void CBackupOperationObserver::ConstructL(TInt aObserverNumber) sl@0: { sl@0: // Set up the AO callback sl@0: CActiveScheduler::Add(this); sl@0: SetActive(); sl@0: iStatus = KRequestPending; sl@0: sl@0: // Create a new session for this backup notification observer sl@0: iBackupSession = CBaBackupSessionWrapper::NewL(); sl@0: iBackupSession->RegisterBackupOperationObserverL(*this); sl@0: iObserverNumber = aObserverNumber; sl@0: iLocalRTest = new (ELeave) RTest(_L("BackupOperationObserver")); sl@0: } sl@0: sl@0: void CBackupOperationObserver::HandleBackupOperationEventL(const TBackupOperationAttributes& aBackupOperationAttributes) sl@0: { sl@0: LogThread(); sl@0: RDebug::Print(_L("CBackupOperationObserver::HandleBackupOperationEventL")); sl@0: sl@0: TBuf<150> buf; sl@0: buf.Format(_L("Backup observer number %d received a notification of operation type %d and file lock type: %d\n"),iObserverNumber, aBackupOperationAttributes.iOperation, aBackupOperationAttributes.iFileFlag); sl@0: RDebug::Print(buf); sl@0: } sl@0: sl@0: void CBackupOperationObserver::DoCancel() sl@0: { ; } sl@0: sl@0: void CBackupOperationObserver::RunL() sl@0: { sl@0: // Okay - we're back in the right thread! sl@0: LogThread(); sl@0: RDebug::Print(_L("CBackupOperationObserver::RunL")); sl@0: sl@0: // Finished with this object sl@0: delete this; sl@0: sl@0: // And the active scheduler in this thread sl@0: CActiveScheduler::Current()->Stop(); sl@0: sl@0: } sl@0: sl@0: void CBackupOperationObserver::Kill(RThread* aThread) sl@0: { sl@0: LogThread(); sl@0: RDebug::Print(_L("CBackupFileObserver::Kill")); sl@0: sl@0: // Trigger the Active Object locally - in a different thread! sl@0: TRequestStatus* tempStatus=(&iStatus); sl@0: aThread->RequestComplete(tempStatus, KErrNone); sl@0: } sl@0: sl@0: // sl@0: // class CBackupFileObserver sl@0: // sl@0: sl@0: CBackupFileObserver::CBackupFileObserver() sl@0: : CActive(0) sl@0: { ; } sl@0: sl@0: void CBackupFileObserver::ConstructL(TInt aFileObserverNumber) sl@0: { sl@0: // Set up the AO callback sl@0: CActiveScheduler::Add(this); sl@0: SetActive(); sl@0: iStatus = KRequestPending; sl@0: sl@0: // Create a new session for this file lock observer sl@0: iBackupSession = CBaBackupSessionWrapper::NewL(); sl@0: iFileObserverNumber = aFileObserverNumber; sl@0: iFileLocksChanged = 0; sl@0: iFileLockState = ELocked; sl@0: iLocalRTest = new (ELeave) RTest(_L("BackupFileObserver")); sl@0: } sl@0: sl@0: CBackupFileObserver* CBackupFileObserver::NewL(TInt aFileObserverNumber) sl@0: { sl@0: LogThread(); sl@0: RDebug::Print(_L("CBackupFileObserver::NewL")); sl@0: sl@0: CBackupFileObserver* self=new(ELeave) CBackupFileObserver(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aFileObserverNumber); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: CBackupFileObserver::~CBackupFileObserver() sl@0: { sl@0: LogThread(); sl@0: RDebug::Print(_L("CBackupFileObserver::~CBackupFileObserver")); sl@0: sl@0: delete iBackupSession; sl@0: sl@0: delete iLocalRTest; sl@0: } sl@0: sl@0: void CBackupFileObserver::AddFileL(TInt aFileNumber) sl@0: { sl@0: LogThread(); sl@0: RDebug::Print(_L("CBackupFileObserver::AddFileL")); sl@0: sl@0: // We base the filename of the number of thread in the RArray sl@0: iFileName.Format(_L("FileName%d"), aFileNumber); sl@0: sl@0: iBackupSession->RegisterFileL(iFileName,*this); sl@0: } sl@0: sl@0: TInt CBackupFileObserver::GetFileLocksChanged() sl@0: { sl@0: return iFileLocksChanged; sl@0: } sl@0: sl@0: void CBackupFileObserver::ZeroFileLocksChanged() sl@0: { sl@0: iFileLocksChanged = 0; sl@0: } sl@0: sl@0: void CBackupFileObserver::SetDelay(TBool aDelay) sl@0: { sl@0: iDelay = aDelay; sl@0: } sl@0: sl@0: void CBackupFileObserver::ChangeFileLockL(const TDesC& aFileName,TFileLockFlags aFlags) sl@0: { sl@0: LogThread(); sl@0: RDebug::Print(_L("BackupFileObserver::ChangeFileLockL")); sl@0: sl@0: // Keep a count of how many release notifications there have been sl@0: if (aFlags != MBackupObserver::ETakeLock) sl@0: { sl@0: iFileLocksChanged++; sl@0: } sl@0: sl@0: // If delay is set then insert wait now sl@0: if (iDelay && (!(aFileName.Compare(KFileName1)))) sl@0: { sl@0: User::After(10000000); sl@0: } sl@0: sl@0: // Check this file is the one for this observer - if not fail test; sl@0: if (iFileName.Compare(aFileName)) sl@0: { sl@0: RDebug::Print(_L("\nReceived notification for non-registered file!")); sl@0: (*iLocalRTest)(EFalse); sl@0: } sl@0: sl@0: // Update the local file lock array sl@0: CBackupFileObserver::TFileLock flag = (CBackupFileObserver::TFileLock) aFlags; sl@0: iFileLockState = flag; sl@0: sl@0: // Test output sl@0: TBuf<150> buf; sl@0: buf.Format(_L("File backup observer number %d was notified for file %S of file lock type: %d\n"),iFileObserverNumber, &aFileName, flag); sl@0: RDebug::Print(buf); sl@0: } sl@0: sl@0: void CBackupFileObserver::DoCancel() sl@0: { ; } sl@0: sl@0: void CBackupFileObserver::RunL() sl@0: { sl@0: // Okay - we're back in the right thread! sl@0: LogThread(); sl@0: RDebug::Print(_L("CBackupFileObserver::RunL")); sl@0: sl@0: // Finished with this object sl@0: delete this; sl@0: sl@0: // And the active scheduler in this thread sl@0: CActiveScheduler::Current()->Stop(); sl@0: sl@0: } sl@0: sl@0: void CBackupFileObserver::Kill(RThread* aThread) sl@0: { sl@0: LogThread(); sl@0: RDebug::Print(_L("CBackupFileObserver::Kill")); sl@0: sl@0: // Trigger the Active Object locally - in a different thread! sl@0: TRequestStatus* tempStatus=(&iStatus); sl@0: aThread->RequestComplete(tempStatus, KErrNone); sl@0: } sl@0: sl@0: // sl@0: // class CBackupTestsStateMachine sl@0: // sl@0: sl@0: CBackupTestsStateMachine* CBackupTestsStateMachine::NewL() sl@0: { sl@0: CBackupTestsStateMachine* self = new (ELeave) CBackupTestsStateMachine(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: CBackupTestsStateMachine::CBackupTestsStateMachine() sl@0: : CActive(0) sl@0: { ; } sl@0: sl@0: void CBackupTestsStateMachine::ConstructL() sl@0: { sl@0: // Set up the RTest for this thread and display we're started sl@0: iLocalRTest = new (ELeave) RTest(_L("T_BACKUP_SRV")); sl@0: iLocalRTest->Title(); sl@0: sl@0: // Set the ititial state sl@0: iState = EStateMachineStart; sl@0: sl@0: // Zero the EndBackupRecursionCount (see below) sl@0: iEndBackupRecursionCount = 0; sl@0: sl@0: // Add this to the Active Scheduler and set us active sl@0: CActiveScheduler::Add(this); sl@0: SetActive(); sl@0: sl@0: // Create the backup "command" session sl@0: iBackupSession = CBaBackupSessionWrapper::NewL(); sl@0: sl@0: // Set up the mutex sl@0: iMutex.CreateLocal(); sl@0: } sl@0: sl@0: // Observers need to have their own thread sl@0: void CBackupTestsStateMachine::CreateObserversThreadsL() sl@0: { sl@0: RDebug::Print(_L("Starting observers threads")); sl@0: sl@0: TInt i; sl@0: TBuf<30> newThreadNames; sl@0: TInt error; sl@0: for (i = 0; i<4 ; i++) sl@0: { sl@0: // Backup observer sl@0: iBackupObserverThreads.AppendL(new (ELeave) RThread); sl@0: newThreadNames.Format(_L("Backup Observer Thread %d"), i+1); sl@0: error = iBackupObserverThreads[i]->Create(newThreadNames, CBackupTestsStateMachine::BackupObserversThreadStartL, 0x2000, NULL, (TAny*)this); sl@0: (*iLocalRTest)(error==KErrNone); sl@0: iBackupObserverThreads[i]->Resume(); sl@0: sl@0: // File observer sl@0: iFileObserverThreads.AppendL(new (ELeave) RThread); sl@0: newThreadNames.Format(_L("File Observer Thread %d"), i+1); sl@0: error = iFileObserverThreads[i]->Create(newThreadNames, CBackupTestsStateMachine::FileObserversThreadStartL, 0x2000, NULL, (TAny*)this); sl@0: sl@0: (*iLocalRTest)(error==KErrNone); sl@0: iFileObserverThreads[i]->Resume(); sl@0: sl@0: // Brief delay to let the observer threads get started sl@0: User::After(1000000); sl@0: } sl@0: sl@0: } sl@0: sl@0: // Static starting function for the backup observers threads sl@0: TInt CBackupTestsStateMachine::BackupObserversThreadStartL(TAny* aPtr) sl@0: { sl@0: // Create the Cleanup Stack and Active Scheduler for this thread sl@0: sl@0: CTrapCleanup* theTrapCleanup = CTrapCleanup::New(); sl@0: CActiveScheduler *activeScheduler = new CActiveScheduler; sl@0: CActiveScheduler::Install(activeScheduler); sl@0: sl@0: // Create the observer instances sl@0: CBackupTestsStateMachine* objectPtr = static_cast(aPtr); sl@0: TRAPD(error, objectPtr->CreateBackupObserverInstanceL()); sl@0: User::LeaveIfError(error); sl@0: sl@0: // Go to Active Scheduler main loop for this thread sl@0: CActiveScheduler::Start(); sl@0: sl@0: // And we're done sl@0: delete activeScheduler; sl@0: delete theTrapCleanup; sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: // Static starting function for the file observers threads sl@0: TInt CBackupTestsStateMachine::FileObserversThreadStartL(TAny* aPtr) sl@0: { sl@0: // Create the Cleanup Stack and Active Scheduler for this thread sl@0: CTrapCleanup* theTrapCleanup = CTrapCleanup::New(); sl@0: CActiveScheduler* activeScheduler = new CActiveScheduler; sl@0: CActiveScheduler::Install(activeScheduler); sl@0: sl@0: // Create the observer instances sl@0: CBackupTestsStateMachine* objectPtr = static_cast(aPtr); sl@0: TRAPD(error, objectPtr->CreateFileObserverInstanceL()); sl@0: User::LeaveIfError(error); sl@0: sl@0: // Go to Active Scheduler main loop for this thread sl@0: CActiveScheduler::Start(); sl@0: sl@0: // And we're done sl@0: delete activeScheduler; sl@0: delete theTrapCleanup; sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: void CBackupTestsStateMachine::CreateBackupObserverInstanceL() sl@0: { sl@0: iMutex.Wait(); sl@0: sl@0: TInt count = iBackupObserverThreads.Count(); sl@0: sl@0: // Create the new object instance (one object per thread) sl@0: // We base the thread number of the number of thread in the RArray sl@0: CBackupOperationObserver* newObserver = CBackupOperationObserver::NewL(count); sl@0: iBackupObservers.AppendL(newObserver); sl@0: sl@0: iMutex.Signal(); sl@0: } sl@0: sl@0: void CBackupTestsStateMachine::CreateFileObserverInstanceL() sl@0: { sl@0: iMutex.Wait(); sl@0: sl@0: TInt count = iBackupFileObservers.Count(); sl@0: sl@0: // Create the new object instance (one object per thread) sl@0: CBackupFileObserver* newObserver = CBackupFileObserver::NewL(count + 1); sl@0: iBackupFileObservers.AppendL(newObserver); sl@0: sl@0: // Register the file for this thread / instance sl@0: iBackupFileObservers[count]->AddFileL(count + 1); sl@0: sl@0: iMutex.Signal(); sl@0: } sl@0: sl@0: // State Machine destructor sl@0: CBackupTestsStateMachine::~CBackupTestsStateMachine() sl@0: { sl@0: // Close our session into the backup server sl@0: delete iBackupSession; sl@0: sl@0: // Delete all the observers (only 3 of each of by this point) sl@0: TInt i; sl@0: sl@0: for (i = 0; i<3 ; i++) sl@0: { sl@0: iBackupObservers[i]->Kill(iBackupObserverThreads[i]); sl@0: iBackupFileObservers[i]->Kill(iFileObserverThreads[i]); sl@0: User::After(50000000); sl@0: } sl@0: iBackupObservers.Close(); sl@0: iBackupFileObservers.Close(); sl@0: sl@0: // Kill the observer threads sl@0: for (i = 0; i<3 ; i++) sl@0: sl@0: { sl@0: iBackupObserverThreads[i]->Kill(KErrNone); sl@0: delete iBackupObserverThreads[i]; sl@0: iFileObserverThreads[i]->Kill(KErrNone); sl@0: delete iFileObserverThreads[i]; sl@0: } sl@0: iBackupObserverThreads.Close(); sl@0: iFileObserverThreads.Close(); sl@0: sl@0: // Display we're finished sl@0: iLocalRTest->Close(); sl@0: delete iLocalRTest; sl@0: sl@0: // Cancel this is it's active sl@0: if (IsActive()) sl@0: { sl@0: Cancel(); sl@0: } sl@0: } sl@0: sl@0: // Common starting function for all test-related calls to CloseAll sl@0: void CBackupTestsStateMachine::CloseAllStartL(StateMachineState aNextState, MBackupObserver::TFileLockFlags aFlag) sl@0: { sl@0: StartBackupL(); sl@0: iState = aNextState; sl@0: iBackupSession->CloseAll(aFlag, iStatus); sl@0: } sl@0: sl@0: // Common ending function for all test-related calls to CloseAll sl@0: void CBackupTestsStateMachine::CloseAllEndL(StateMachineState aNextState, TInt aExpectedNotifications) sl@0: { sl@0: iState = aNextState; sl@0: SignalEndBackupL(); sl@0: EndBackup(aExpectedNotifications, ETrue); sl@0: iLocalRTest->End(); sl@0: Complete(); sl@0: } sl@0: sl@0: // State machine call back - get here by calls to Complete and returns for asynchronous server calls sl@0: void CBackupTestsStateMachine::RunL() sl@0: { sl@0: switch(iState) sl@0: { sl@0: case EStateMachineStart: sl@0: // Create observers threads sl@0: CreateObserversThreadsL(); sl@0: iState = ECloseAllNormalReadOnly; sl@0: Complete(); sl@0: break; sl@0: case ECloseAllNormalReadOnly: sl@0: iLocalRTest->Start(_L("\nCloseAllFiles normal ReadOnly\n")); sl@0: CloseAllStartL(ECloseAllNormalReadOnlyReturned, MBackupObserver::EReleaseLockReadOnly); sl@0: break; sl@0: case ECloseAllNormalReadOnlyReturned: sl@0: CloseAllEndL(ECloseAllNormalNoAccess, 4); sl@0: break; sl@0: case ECloseAllNormalNoAccess: sl@0: iLocalRTest->Start(_L("\nCloseAllFiles normal NoAccess\n")); sl@0: CloseAllStartL(ECloseAllNormalNoAccessReturned, MBackupObserver::EReleaseLockNoAccess); sl@0: break; sl@0: case ECloseAllNormalNoAccessReturned: sl@0: CloseAllEndL(ECloseAllDelayReadOnly, 4); sl@0: break; sl@0: case ECloseAllDelayReadOnly: sl@0: iLocalRTest->Start(_L("\nCloseAllFiles delay ReadOnly\n")); sl@0: iBackupFileObservers[0]->SetDelay(ETrue); sl@0: CloseAllStartL(ECloseAllDelayReadOnlyReturned, MBackupObserver::EReleaseLockReadOnly); sl@0: break; sl@0: case ECloseAllDelayReadOnlyReturned: sl@0: iBackupFileObservers[0]->SetDelay(EFalse); sl@0: CloseAllEndL(ECloseAllDelayNoAccess, 4); sl@0: // Nice long wait for the timer to expire in the other thread sl@0: User::After(10000000); sl@0: break; sl@0: case ECloseAllDelayNoAccess: sl@0: iLocalRTest->Start(_L("\nCloseAllFiles delay NoAccess\n")); sl@0: iBackupFileObservers[0]->SetDelay(ETrue); sl@0: CloseAllStartL(ECloseAllDelayNoAccessReturned, MBackupObserver::EReleaseLockNoAccess); sl@0: break; sl@0: case ECloseAllDelayNoAccessReturned: sl@0: iBackupFileObservers[0]->SetDelay(EFalse); sl@0: CloseAllEndL(ECloseAllDropFileSession, 4); sl@0: // Nice long wait for the timer to expire in the other thread sl@0: User::After(10000000); sl@0: break; sl@0: case ECloseAllDropFileSession: sl@0: iLocalRTest->Start(_L("\nCloseAllFiles dropping file session\n")); sl@0: // Drop one of the file registration / observer sessions sl@0: iBackupFileObservers[0]->Kill(iFileObserverThreads[0]); sl@0: // Nice long wait for the observer to be killed in the other thread sl@0: User::After(10000000); sl@0: // Remove it from the list sl@0: iBackupFileObservers.Remove(0); sl@0: // Kill the thread sl@0: iFileObserverThreads[0]->Kill(KErrNone); sl@0: delete iFileObserverThreads[0]; sl@0: iFileObserverThreads.Remove(0); sl@0: // All done - start this sub-test sl@0: CloseAllStartL(ECloseAllDropFileSessionReturned, MBackupObserver::EReleaseLockReadOnly); sl@0: break; sl@0: case ECloseAllDropFileSessionReturned: sl@0: CloseAllEndL(ECloseAllDropBackupObserverSession, 3); sl@0: break; sl@0: case ECloseAllDropBackupObserverSession: sl@0: iLocalRTest->Start(_L("\nCloseAllFiles dropping backup session\n")); sl@0: // Drop one of the backup observer sessions sl@0: iBackupObservers[0]->Kill(iBackupObserverThreads[0]); sl@0: // Nice long wait for the observer to be killed in the other thread sl@0: User::After(10000000); sl@0: // Remove it from the list sl@0: iBackupObservers.Remove(0); sl@0: // Kill the thread sl@0: iBackupObserverThreads[0]->Kill(KErrNone); sl@0: delete iBackupObserverThreads[0]; sl@0: iBackupObserverThreads.Remove(0); sl@0: // All done - start this sub-test sl@0: CloseAllStartL(ECloseAllDropBackupObserverSessionReturned, MBackupObserver::EReleaseLockReadOnly); sl@0: break; sl@0: case ECloseAllDropBackupObserverSessionReturned: sl@0: CloseAllEndL(ESingleFileTests, 3); sl@0: break; sl@0: case ESingleFileTests: sl@0: iLocalRTest->Start(_L("\nSingle file lock tests\n")); sl@0: StartBackupL(); sl@0: SingleFileLockTestsL(); sl@0: SignalEndBackupL(); sl@0: // Can call EndBackup synchronously here as nothing in SingleFileLockTests is asynchronous sl@0: EndBackup(3, EFalse); sl@0: iLocalRTest->End(); sl@0: iState = ENoBackupSessionSingleFileTests; sl@0: Complete(); sl@0: break; sl@0: // Required to cover the situation when the backup server is used purely for message signalling sl@0: // For example in the LogEng compnent sl@0: case ENoBackupSessionSingleFileTests: sl@0: iLocalRTest->Start(_L("\nNo backup session single file lock tests\n")); sl@0: SingleFileLockTestsL(); sl@0: // Can call EndBackup synchronously here as nothing in SingleFileLockTests is asynchronous sl@0: EndBackup(3, EFalse); sl@0: iLocalRTest->End(); sl@0: iState = EStateMachineEnd; sl@0: Complete(); sl@0: break; sl@0: case EStateMachineEnd: sl@0: RDebug::Print(_L("\nEnd of state machine\n")); sl@0: End(); sl@0: break; sl@0: default: sl@0: RDebug::Print(_L("\nCBackupTestsStateMachine::RunL problem")); sl@0: break; sl@0: } sl@0: if (!IsActive()) sl@0: { sl@0: SetActive(); sl@0: } sl@0: } sl@0: sl@0: void CBackupTestsStateMachine::DoCancel() sl@0: { sl@0: Complete(); sl@0: } sl@0: sl@0: void CBackupTestsStateMachine::RunError() sl@0: { ; } sl@0: sl@0: // Common function to start a backup sl@0: void CBackupTestsStateMachine::StartBackupL() sl@0: { sl@0: TBackupOperationAttributes attribs; sl@0: attribs.iFileFlag=MBackupObserver::EReleaseLockNoAccess; sl@0: attribs.iOperation=MBackupOperationObserver::EStart; sl@0: iBackupSession->NotifyBackupOperationL(attribs); sl@0: RDebug::Print(_L("\nStarting backup\n")); sl@0: } sl@0: sl@0: void CBackupTestsStateMachine::SignalEndBackupL() sl@0: { sl@0: // Tell the server the backup is over sl@0: TBackupOperationAttributes attribs; sl@0: attribs.iFileFlag=MBackupObserver::EReleaseLockNoAccess; sl@0: attribs.iOperation=MBackupOperationObserver::EEnd; sl@0: iBackupSession->NotifyBackupOperationL(attribs); sl@0: } sl@0: sl@0: // This function works in two ways. If oneTimeOnly is ETrue then all file lock sl@0: // change notifications must have been received before this function is called. sl@0: // If oneTimeOnly is EFalse this function recursively calls itself (a finate number sl@0: // of times) until all notifications have arrived (this happens with single file testing) sl@0: void CBackupTestsStateMachine::EndBackup(TInt aFileLockChangesExpected, TBool oneTimeOnly) sl@0: { sl@0: // Get the total notification count so far sl@0: TInt numberOfObservers = iBackupFileObservers.Count(); sl@0: TInt totalNotificationCount = 0; sl@0: for (TInt i=0; iGetFileLocksChanged(); sl@0: } sl@0: if (aFileLockChangesExpected == totalNotificationCount) sl@0: { sl@0: // Reset the recursion count sl@0: iEndBackupRecursionCount = 0; sl@0: sl@0: // Zero the notification counts in the file lock observers sl@0: for (TInt i = 0 ; iZeroFileLocksChanged(); sl@0: } sl@0: sl@0: // Debug output sl@0: TBuf<100> buf; sl@0: buf.Format(_L("\nBackup finished sucsessfully on recusion count %d of EndBackup\n"), iEndBackupRecursionCount); sl@0: RDebug::Print(buf); sl@0: } sl@0: else if (oneTimeOnly) sl@0: { sl@0: // No second chances - fail here sl@0: (*iLocalRTest)(EFalse); sl@0: } sl@0: else sl@0: { sl@0: // Give it 5 more seconds (in 10 .5 second iterations) for the notifications to arrive sl@0: User::After(500000); sl@0: // 5 seconds is more than enough (timeouts in server should have gone off by now anyway) sl@0: iEndBackupRecursionCount++; sl@0: if (iEndBackupRecursionCount > 10) sl@0: { sl@0: (*iLocalRTest)(EFalse); sl@0: } sl@0: // Recursively calling isn't great but it needs to leave the function so the AO can run sl@0: EndBackup(aFileLockChangesExpected, EFalse); sl@0: } sl@0: sl@0: } sl@0: sl@0: void CBackupTestsStateMachine::Complete() sl@0: { sl@0: // Trigger the Active Object locally sl@0: TRequestStatus* tempStatus=(&iStatus); sl@0: User::RequestComplete(tempStatus, KErrNone); sl@0: } sl@0: sl@0: void CBackupTestsStateMachine::Start() sl@0: { sl@0: // Time to start testing sl@0: RDebug::Print(_L("\nCBackupTestsStateMachine::Start")); sl@0: Complete(); sl@0: } sl@0: sl@0: void CBackupTestsStateMachine::End() sl@0: { sl@0: // We're done testing - kill the Active Scheduler sl@0: RDebug::Print(_L("\nAll test complete\n")); sl@0: Cancel(); sl@0: CActiveScheduler::Current()->Stop(); sl@0: } sl@0: sl@0: void CBackupTestsStateMachine::SingleFileLockTestsL() sl@0: { sl@0: TFileName file; sl@0: sl@0: // File 1 sl@0: file.Copy(KFileName1); sl@0: iLocalRTest->Next(file); sl@0: sl@0: iBackupSession->CloseFileL(KFileName1, MBackupObserver::EReleaseLockReadOnly); sl@0: iBackupSession->RestartFile(file); sl@0: sl@0: // iBackupSession->CloseFileL(KFileName1, MBackupObserver::EReleaseLockNoAccess); sl@0: // iBackupSession->RestartFile(file); sl@0: sl@0: // File 2 sl@0: file.Copy(KFileName2); sl@0: iLocalRTest->Next(file); sl@0: sl@0: iBackupSession->CloseFileL(KFileName2, MBackupObserver::EReleaseLockReadOnly); sl@0: iBackupSession->RestartFile(file); sl@0: sl@0: // iBackupSession->CloseFileL(KFileName2, MBackupObserver::EReleaseLockNoAccess); sl@0: // iBackupSession->RestartFile(file); sl@0: sl@0: // File 3 sl@0: file.Copy(KFileName3); sl@0: iLocalRTest->Next(file); sl@0: sl@0: iBackupSession->CloseFileL(KFileName3, MBackupObserver::EReleaseLockReadOnly); sl@0: iBackupSession->RestartFile(file); sl@0: sl@0: // iBackupSession->CloseFileL(KFileName3, MBackupObserver::EReleaseLockNoAccess); sl@0: // iBackupSession->RestartFile(file); sl@0: sl@0: // File 3 sl@0: file.Copy(KFileName4); sl@0: iLocalRTest->Next(file); sl@0: sl@0: iBackupSession->CloseFileL(KFileName4, MBackupObserver::EReleaseLockReadOnly); sl@0: iBackupSession->RestartFile(file); sl@0: sl@0: // iBackupSession->CloseFileL(KFileName4, MBackupObserver::EReleaseLockNoAccess); sl@0: // iBackupSession->RestartFile(file); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-BAFL-CT-0467 sl@0: @SYMTestCaseDesc Tests the functionality of CBaBackupSessionWrapper class sl@0: @SYMTestPriority High sl@0: @SYMTestActions Tests for the enabling backup of files sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_D void StartTestsL() sl@0: { sl@0: // For the sake of logging let's start off by renaming the main "command" thread sl@0: RThread().RenameMe(_L("Main thread")); sl@0: sl@0: // Create state machine sl@0: CBackupTestsStateMachine* stateMachine = CBackupTestsStateMachine::NewL(); sl@0: sl@0: // Kick it off sl@0: stateMachine->Start(); sl@0: sl@0: // Start the Active Scheduler sl@0: CActiveScheduler::Start(); sl@0: sl@0: // Clean up the state machine sl@0: delete stateMachine; sl@0: } sl@0: sl@0: TInt E32Main() sl@0: { sl@0: MainTest.Title(); sl@0: MainTest.Start(_L(" @SYMTestCaseID:SYSLIB-BAFL-CT-0467 Loading Device")); sl@0: sl@0: __UHEAP_MARK; sl@0: sl@0: CTrapCleanup* theTrapCleanup=CTrapCleanup::New(); sl@0: CActiveScheduler *activeScheduler=new CActiveScheduler; sl@0: CActiveScheduler::Install(activeScheduler); sl@0: sl@0: TRAPD(error, StartTestsL()); sl@0: User::LeaveIfError(error); sl@0: sl@0: delete activeScheduler; sl@0: delete theTrapCleanup; sl@0: sl@0: __UHEAP_MARKEND; sl@0: sl@0: MainTest.End(); sl@0: sl@0: sl@0: return(KErrNone); sl@0: }