|
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <e32debug.h> |
|
17 #include <e32test.h> |
|
18 #include <babackup.h> |
|
19 #include "T_backupSrv.h" |
|
20 LOCAL_D RTest MainTest(_L(" T_BackupSrv.cpp")); |
|
21 |
|
22 _LIT(KFileName1, "FileName1"); |
|
23 _LIT(KFileName2, "FileName2"); |
|
24 _LIT(KFileName3, "FileName3"); |
|
25 _LIT(KFileName4, "FileName4"); |
|
26 |
|
27 // Nasty global convenience function |
|
28 LOCAL_D void LogThread() |
|
29 { |
|
30 TBuf<150> buf((RThread().Name())); |
|
31 RDebug::Print(_L("*** Currently in thread : ")); |
|
32 RDebug::Print(buf); |
|
33 } |
|
34 |
|
35 // |
|
36 // class CBackupOperationObserver |
|
37 // |
|
38 CBackupOperationObserver* CBackupOperationObserver::NewL(TInt aObserverNumber) |
|
39 { |
|
40 LogThread(); |
|
41 RDebug::Print(_L("CBackupOperationObserver::NewL")); |
|
42 |
|
43 CBackupOperationObserver* self = new (ELeave) CBackupOperationObserver(); |
|
44 CleanupStack::PushL(self); |
|
45 self->ConstructL(aObserverNumber); |
|
46 CleanupStack::Pop(); |
|
47 return self; |
|
48 } |
|
49 |
|
50 CBackupOperationObserver::CBackupOperationObserver() |
|
51 : CActive(0) |
|
52 { ; } |
|
53 |
|
54 CBackupOperationObserver::~CBackupOperationObserver() |
|
55 { |
|
56 LogThread(); |
|
57 RDebug::Print(_L("CBackupOperationObserver::~CBackupOperationObserver")); |
|
58 |
|
59 iBackupSession->DeRegisterBackupOperationObserver(*this); |
|
60 delete iBackupSession; |
|
61 |
|
62 delete iLocalRTest; |
|
63 } |
|
64 |
|
65 void CBackupOperationObserver::ConstructL(TInt aObserverNumber) |
|
66 { |
|
67 // Set up the AO callback |
|
68 CActiveScheduler::Add(this); |
|
69 SetActive(); |
|
70 iStatus = KRequestPending; |
|
71 |
|
72 // Create a new session for this backup notification observer |
|
73 iBackupSession = CBaBackupSessionWrapper::NewL(); |
|
74 iBackupSession->RegisterBackupOperationObserverL(*this); |
|
75 iObserverNumber = aObserverNumber; |
|
76 iLocalRTest = new (ELeave) RTest(_L("BackupOperationObserver")); |
|
77 } |
|
78 |
|
79 void CBackupOperationObserver::HandleBackupOperationEventL(const TBackupOperationAttributes& aBackupOperationAttributes) |
|
80 { |
|
81 LogThread(); |
|
82 RDebug::Print(_L("CBackupOperationObserver::HandleBackupOperationEventL")); |
|
83 |
|
84 TBuf<150> buf; |
|
85 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); |
|
86 RDebug::Print(buf); |
|
87 } |
|
88 |
|
89 void CBackupOperationObserver::DoCancel() |
|
90 { ; } |
|
91 |
|
92 void CBackupOperationObserver::RunL() |
|
93 { |
|
94 // Okay - we're back in the right thread! |
|
95 LogThread(); |
|
96 RDebug::Print(_L("CBackupOperationObserver::RunL")); |
|
97 |
|
98 // Finished with this object |
|
99 delete this; |
|
100 |
|
101 // And the active scheduler in this thread |
|
102 CActiveScheduler::Current()->Stop(); |
|
103 |
|
104 } |
|
105 |
|
106 void CBackupOperationObserver::Kill(RThread* aThread) |
|
107 { |
|
108 LogThread(); |
|
109 RDebug::Print(_L("CBackupFileObserver::Kill")); |
|
110 |
|
111 // Trigger the Active Object locally - in a different thread! |
|
112 TRequestStatus* tempStatus=(&iStatus); |
|
113 aThread->RequestComplete(tempStatus, KErrNone); |
|
114 } |
|
115 |
|
116 // |
|
117 // class CBackupFileObserver |
|
118 // |
|
119 |
|
120 CBackupFileObserver::CBackupFileObserver() |
|
121 : CActive(0) |
|
122 { ; } |
|
123 |
|
124 void CBackupFileObserver::ConstructL(TInt aFileObserverNumber) |
|
125 { |
|
126 // Set up the AO callback |
|
127 CActiveScheduler::Add(this); |
|
128 SetActive(); |
|
129 iStatus = KRequestPending; |
|
130 |
|
131 // Create a new session for this file lock observer |
|
132 iBackupSession = CBaBackupSessionWrapper::NewL(); |
|
133 iFileObserverNumber = aFileObserverNumber; |
|
134 iFileLocksChanged = 0; |
|
135 iFileLockState = ELocked; |
|
136 iLocalRTest = new (ELeave) RTest(_L("BackupFileObserver")); |
|
137 } |
|
138 |
|
139 CBackupFileObserver* CBackupFileObserver::NewL(TInt aFileObserverNumber) |
|
140 { |
|
141 LogThread(); |
|
142 RDebug::Print(_L("CBackupFileObserver::NewL")); |
|
143 |
|
144 CBackupFileObserver* self=new(ELeave) CBackupFileObserver(); |
|
145 CleanupStack::PushL(self); |
|
146 self->ConstructL(aFileObserverNumber); |
|
147 CleanupStack::Pop(); |
|
148 return self; |
|
149 } |
|
150 |
|
151 CBackupFileObserver::~CBackupFileObserver() |
|
152 { |
|
153 LogThread(); |
|
154 RDebug::Print(_L("CBackupFileObserver::~CBackupFileObserver")); |
|
155 |
|
156 delete iBackupSession; |
|
157 |
|
158 delete iLocalRTest; |
|
159 } |
|
160 |
|
161 void CBackupFileObserver::AddFileL(TInt aFileNumber) |
|
162 { |
|
163 LogThread(); |
|
164 RDebug::Print(_L("CBackupFileObserver::AddFileL")); |
|
165 |
|
166 // We base the filename of the number of thread in the RArray |
|
167 iFileName.Format(_L("FileName%d"), aFileNumber); |
|
168 |
|
169 iBackupSession->RegisterFileL(iFileName,*this); |
|
170 } |
|
171 |
|
172 TInt CBackupFileObserver::GetFileLocksChanged() |
|
173 { |
|
174 return iFileLocksChanged; |
|
175 } |
|
176 |
|
177 void CBackupFileObserver::ZeroFileLocksChanged() |
|
178 { |
|
179 iFileLocksChanged = 0; |
|
180 } |
|
181 |
|
182 void CBackupFileObserver::SetDelay(TBool aDelay) |
|
183 { |
|
184 iDelay = aDelay; |
|
185 } |
|
186 |
|
187 void CBackupFileObserver::ChangeFileLockL(const TDesC& aFileName,TFileLockFlags aFlags) |
|
188 { |
|
189 LogThread(); |
|
190 RDebug::Print(_L("BackupFileObserver::ChangeFileLockL")); |
|
191 |
|
192 // Keep a count of how many release notifications there have been |
|
193 if (aFlags != MBackupObserver::ETakeLock) |
|
194 { |
|
195 iFileLocksChanged++; |
|
196 } |
|
197 |
|
198 // If delay is set then insert wait now |
|
199 if (iDelay && (!(aFileName.Compare(KFileName1)))) |
|
200 { |
|
201 User::After(10000000); |
|
202 } |
|
203 |
|
204 // Check this file is the one for this observer - if not fail test; |
|
205 if (iFileName.Compare(aFileName)) |
|
206 { |
|
207 RDebug::Print(_L("\nReceived notification for non-registered file!")); |
|
208 (*iLocalRTest)(EFalse); |
|
209 } |
|
210 |
|
211 // Update the local file lock array |
|
212 CBackupFileObserver::TFileLock flag = (CBackupFileObserver::TFileLock) aFlags; |
|
213 iFileLockState = flag; |
|
214 |
|
215 // Test output |
|
216 TBuf<150> buf; |
|
217 buf.Format(_L("File backup observer number %d was notified for file %S of file lock type: %d\n"),iFileObserverNumber, &aFileName, flag); |
|
218 RDebug::Print(buf); |
|
219 } |
|
220 |
|
221 void CBackupFileObserver::DoCancel() |
|
222 { ; } |
|
223 |
|
224 void CBackupFileObserver::RunL() |
|
225 { |
|
226 // Okay - we're back in the right thread! |
|
227 LogThread(); |
|
228 RDebug::Print(_L("CBackupFileObserver::RunL")); |
|
229 |
|
230 // Finished with this object |
|
231 delete this; |
|
232 |
|
233 // And the active scheduler in this thread |
|
234 CActiveScheduler::Current()->Stop(); |
|
235 |
|
236 } |
|
237 |
|
238 void CBackupFileObserver::Kill(RThread* aThread) |
|
239 { |
|
240 LogThread(); |
|
241 RDebug::Print(_L("CBackupFileObserver::Kill")); |
|
242 |
|
243 // Trigger the Active Object locally - in a different thread! |
|
244 TRequestStatus* tempStatus=(&iStatus); |
|
245 aThread->RequestComplete(tempStatus, KErrNone); |
|
246 } |
|
247 |
|
248 // |
|
249 // class CBackupTestsStateMachine |
|
250 // |
|
251 |
|
252 CBackupTestsStateMachine* CBackupTestsStateMachine::NewL() |
|
253 { |
|
254 CBackupTestsStateMachine* self = new (ELeave) CBackupTestsStateMachine(); |
|
255 CleanupStack::PushL(self); |
|
256 self->ConstructL(); |
|
257 CleanupStack::Pop(); |
|
258 return self; |
|
259 } |
|
260 |
|
261 CBackupTestsStateMachine::CBackupTestsStateMachine() |
|
262 : CActive(0) |
|
263 { ; } |
|
264 |
|
265 void CBackupTestsStateMachine::ConstructL() |
|
266 { |
|
267 // Set up the RTest for this thread and display we're started |
|
268 iLocalRTest = new (ELeave) RTest(_L("T_BACKUP_SRV")); |
|
269 iLocalRTest->Title(); |
|
270 |
|
271 // Set the ititial state |
|
272 iState = EStateMachineStart; |
|
273 |
|
274 // Zero the EndBackupRecursionCount (see below) |
|
275 iEndBackupRecursionCount = 0; |
|
276 |
|
277 // Add this to the Active Scheduler and set us active |
|
278 CActiveScheduler::Add(this); |
|
279 SetActive(); |
|
280 |
|
281 // Create the backup "command" session |
|
282 iBackupSession = CBaBackupSessionWrapper::NewL(); |
|
283 |
|
284 // Set up the mutex |
|
285 iMutex.CreateLocal(); |
|
286 } |
|
287 |
|
288 // Observers need to have their own thread |
|
289 void CBackupTestsStateMachine::CreateObserversThreadsL() |
|
290 { |
|
291 RDebug::Print(_L("Starting observers threads")); |
|
292 |
|
293 TInt i; |
|
294 TBuf<30> newThreadNames; |
|
295 TInt error; |
|
296 for (i = 0; i<4 ; i++) |
|
297 { |
|
298 // Backup observer |
|
299 iBackupObserverThreads.AppendL(new (ELeave) RThread); |
|
300 newThreadNames.Format(_L("Backup Observer Thread %d"), i+1); |
|
301 error = iBackupObserverThreads[i]->Create(newThreadNames, CBackupTestsStateMachine::BackupObserversThreadStartL, 0x2000, NULL, (TAny*)this); |
|
302 (*iLocalRTest)(error==KErrNone); |
|
303 iBackupObserverThreads[i]->Resume(); |
|
304 |
|
305 // File observer |
|
306 iFileObserverThreads.AppendL(new (ELeave) RThread); |
|
307 newThreadNames.Format(_L("File Observer Thread %d"), i+1); |
|
308 error = iFileObserverThreads[i]->Create(newThreadNames, CBackupTestsStateMachine::FileObserversThreadStartL, 0x2000, NULL, (TAny*)this); |
|
309 |
|
310 (*iLocalRTest)(error==KErrNone); |
|
311 iFileObserverThreads[i]->Resume(); |
|
312 |
|
313 // Brief delay to let the observer threads get started |
|
314 User::After(1000000); |
|
315 } |
|
316 |
|
317 } |
|
318 |
|
319 // Static starting function for the backup observers threads |
|
320 TInt CBackupTestsStateMachine::BackupObserversThreadStartL(TAny* aPtr) |
|
321 { |
|
322 // Create the Cleanup Stack and Active Scheduler for this thread |
|
323 |
|
324 CTrapCleanup* theTrapCleanup = CTrapCleanup::New(); |
|
325 CActiveScheduler *activeScheduler = new CActiveScheduler; |
|
326 CActiveScheduler::Install(activeScheduler); |
|
327 |
|
328 // Create the observer instances |
|
329 CBackupTestsStateMachine* objectPtr = static_cast<CBackupTestsStateMachine*>(aPtr); |
|
330 TRAPD(error, objectPtr->CreateBackupObserverInstanceL()); |
|
331 User::LeaveIfError(error); |
|
332 |
|
333 // Go to Active Scheduler main loop for this thread |
|
334 CActiveScheduler::Start(); |
|
335 |
|
336 // And we're done |
|
337 delete activeScheduler; |
|
338 delete theTrapCleanup; |
|
339 |
|
340 return KErrNone; |
|
341 } |
|
342 |
|
343 // Static starting function for the file observers threads |
|
344 TInt CBackupTestsStateMachine::FileObserversThreadStartL(TAny* aPtr) |
|
345 { |
|
346 // Create the Cleanup Stack and Active Scheduler for this thread |
|
347 CTrapCleanup* theTrapCleanup = CTrapCleanup::New(); |
|
348 CActiveScheduler* activeScheduler = new CActiveScheduler; |
|
349 CActiveScheduler::Install(activeScheduler); |
|
350 |
|
351 // Create the observer instances |
|
352 CBackupTestsStateMachine* objectPtr = static_cast<CBackupTestsStateMachine*>(aPtr); |
|
353 TRAPD(error, objectPtr->CreateFileObserverInstanceL()); |
|
354 User::LeaveIfError(error); |
|
355 |
|
356 // Go to Active Scheduler main loop for this thread |
|
357 CActiveScheduler::Start(); |
|
358 |
|
359 // And we're done |
|
360 delete activeScheduler; |
|
361 delete theTrapCleanup; |
|
362 |
|
363 return KErrNone; |
|
364 } |
|
365 |
|
366 void CBackupTestsStateMachine::CreateBackupObserverInstanceL() |
|
367 { |
|
368 iMutex.Wait(); |
|
369 |
|
370 TInt count = iBackupObserverThreads.Count(); |
|
371 |
|
372 // Create the new object instance (one object per thread) |
|
373 // We base the thread number of the number of thread in the RArray |
|
374 CBackupOperationObserver* newObserver = CBackupOperationObserver::NewL(count); |
|
375 iBackupObservers.AppendL(newObserver); |
|
376 |
|
377 iMutex.Signal(); |
|
378 } |
|
379 |
|
380 void CBackupTestsStateMachine::CreateFileObserverInstanceL() |
|
381 { |
|
382 iMutex.Wait(); |
|
383 |
|
384 TInt count = iBackupFileObservers.Count(); |
|
385 |
|
386 // Create the new object instance (one object per thread) |
|
387 CBackupFileObserver* newObserver = CBackupFileObserver::NewL(count + 1); |
|
388 iBackupFileObservers.AppendL(newObserver); |
|
389 |
|
390 // Register the file for this thread / instance |
|
391 iBackupFileObservers[count]->AddFileL(count + 1); |
|
392 |
|
393 iMutex.Signal(); |
|
394 } |
|
395 |
|
396 // State Machine destructor |
|
397 CBackupTestsStateMachine::~CBackupTestsStateMachine() |
|
398 { |
|
399 // Close our session into the backup server |
|
400 delete iBackupSession; |
|
401 |
|
402 // Delete all the observers (only 3 of each of by this point) |
|
403 TInt i; |
|
404 |
|
405 for (i = 0; i<3 ; i++) |
|
406 { |
|
407 iBackupObservers[i]->Kill(iBackupObserverThreads[i]); |
|
408 iBackupFileObservers[i]->Kill(iFileObserverThreads[i]); |
|
409 User::After(50000000); |
|
410 } |
|
411 iBackupObservers.Close(); |
|
412 iBackupFileObservers.Close(); |
|
413 |
|
414 // Kill the observer threads |
|
415 for (i = 0; i<3 ; i++) |
|
416 |
|
417 { |
|
418 iBackupObserverThreads[i]->Kill(KErrNone); |
|
419 delete iBackupObserverThreads[i]; |
|
420 iFileObserverThreads[i]->Kill(KErrNone); |
|
421 delete iFileObserverThreads[i]; |
|
422 } |
|
423 iBackupObserverThreads.Close(); |
|
424 iFileObserverThreads.Close(); |
|
425 |
|
426 // Display we're finished |
|
427 iLocalRTest->Close(); |
|
428 delete iLocalRTest; |
|
429 |
|
430 // Cancel this is it's active |
|
431 if (IsActive()) |
|
432 { |
|
433 Cancel(); |
|
434 } |
|
435 } |
|
436 |
|
437 // Common starting function for all test-related calls to CloseAll |
|
438 void CBackupTestsStateMachine::CloseAllStartL(StateMachineState aNextState, MBackupObserver::TFileLockFlags aFlag) |
|
439 { |
|
440 StartBackupL(); |
|
441 iState = aNextState; |
|
442 iBackupSession->CloseAll(aFlag, iStatus); |
|
443 } |
|
444 |
|
445 // Common ending function for all test-related calls to CloseAll |
|
446 void CBackupTestsStateMachine::CloseAllEndL(StateMachineState aNextState, TInt aExpectedNotifications) |
|
447 { |
|
448 iState = aNextState; |
|
449 SignalEndBackupL(); |
|
450 EndBackup(aExpectedNotifications, ETrue); |
|
451 iLocalRTest->End(); |
|
452 Complete(); |
|
453 } |
|
454 |
|
455 // State machine call back - get here by calls to Complete and returns for asynchronous server calls |
|
456 void CBackupTestsStateMachine::RunL() |
|
457 { |
|
458 switch(iState) |
|
459 { |
|
460 case EStateMachineStart: |
|
461 // Create observers threads |
|
462 CreateObserversThreadsL(); |
|
463 iState = ECloseAllNormalReadOnly; |
|
464 Complete(); |
|
465 break; |
|
466 case ECloseAllNormalReadOnly: |
|
467 iLocalRTest->Start(_L("\nCloseAllFiles normal ReadOnly\n")); |
|
468 CloseAllStartL(ECloseAllNormalReadOnlyReturned, MBackupObserver::EReleaseLockReadOnly); |
|
469 break; |
|
470 case ECloseAllNormalReadOnlyReturned: |
|
471 CloseAllEndL(ECloseAllNormalNoAccess, 4); |
|
472 break; |
|
473 case ECloseAllNormalNoAccess: |
|
474 iLocalRTest->Start(_L("\nCloseAllFiles normal NoAccess\n")); |
|
475 CloseAllStartL(ECloseAllNormalNoAccessReturned, MBackupObserver::EReleaseLockNoAccess); |
|
476 break; |
|
477 case ECloseAllNormalNoAccessReturned: |
|
478 CloseAllEndL(ECloseAllDelayReadOnly, 4); |
|
479 break; |
|
480 case ECloseAllDelayReadOnly: |
|
481 iLocalRTest->Start(_L("\nCloseAllFiles delay ReadOnly\n")); |
|
482 iBackupFileObservers[0]->SetDelay(ETrue); |
|
483 CloseAllStartL(ECloseAllDelayReadOnlyReturned, MBackupObserver::EReleaseLockReadOnly); |
|
484 break; |
|
485 case ECloseAllDelayReadOnlyReturned: |
|
486 iBackupFileObservers[0]->SetDelay(EFalse); |
|
487 CloseAllEndL(ECloseAllDelayNoAccess, 4); |
|
488 // Nice long wait for the timer to expire in the other thread |
|
489 User::After(10000000); |
|
490 break; |
|
491 case ECloseAllDelayNoAccess: |
|
492 iLocalRTest->Start(_L("\nCloseAllFiles delay NoAccess\n")); |
|
493 iBackupFileObservers[0]->SetDelay(ETrue); |
|
494 CloseAllStartL(ECloseAllDelayNoAccessReturned, MBackupObserver::EReleaseLockNoAccess); |
|
495 break; |
|
496 case ECloseAllDelayNoAccessReturned: |
|
497 iBackupFileObservers[0]->SetDelay(EFalse); |
|
498 CloseAllEndL(ECloseAllDropFileSession, 4); |
|
499 // Nice long wait for the timer to expire in the other thread |
|
500 User::After(10000000); |
|
501 break; |
|
502 case ECloseAllDropFileSession: |
|
503 iLocalRTest->Start(_L("\nCloseAllFiles dropping file session\n")); |
|
504 // Drop one of the file registration / observer sessions |
|
505 iBackupFileObservers[0]->Kill(iFileObserverThreads[0]); |
|
506 // Nice long wait for the observer to be killed in the other thread |
|
507 User::After(10000000); |
|
508 // Remove it from the list |
|
509 iBackupFileObservers.Remove(0); |
|
510 // Kill the thread |
|
511 iFileObserverThreads[0]->Kill(KErrNone); |
|
512 delete iFileObserverThreads[0]; |
|
513 iFileObserverThreads.Remove(0); |
|
514 // All done - start this sub-test |
|
515 CloseAllStartL(ECloseAllDropFileSessionReturned, MBackupObserver::EReleaseLockReadOnly); |
|
516 break; |
|
517 case ECloseAllDropFileSessionReturned: |
|
518 CloseAllEndL(ECloseAllDropBackupObserverSession, 3); |
|
519 break; |
|
520 case ECloseAllDropBackupObserverSession: |
|
521 iLocalRTest->Start(_L("\nCloseAllFiles dropping backup session\n")); |
|
522 // Drop one of the backup observer sessions |
|
523 iBackupObservers[0]->Kill(iBackupObserverThreads[0]); |
|
524 // Nice long wait for the observer to be killed in the other thread |
|
525 User::After(10000000); |
|
526 // Remove it from the list |
|
527 iBackupObservers.Remove(0); |
|
528 // Kill the thread |
|
529 iBackupObserverThreads[0]->Kill(KErrNone); |
|
530 delete iBackupObserverThreads[0]; |
|
531 iBackupObserverThreads.Remove(0); |
|
532 // All done - start this sub-test |
|
533 CloseAllStartL(ECloseAllDropBackupObserverSessionReturned, MBackupObserver::EReleaseLockReadOnly); |
|
534 break; |
|
535 case ECloseAllDropBackupObserverSessionReturned: |
|
536 CloseAllEndL(ESingleFileTests, 3); |
|
537 break; |
|
538 case ESingleFileTests: |
|
539 iLocalRTest->Start(_L("\nSingle file lock tests\n")); |
|
540 StartBackupL(); |
|
541 SingleFileLockTestsL(); |
|
542 SignalEndBackupL(); |
|
543 // Can call EndBackup synchronously here as nothing in SingleFileLockTests is asynchronous |
|
544 EndBackup(3, EFalse); |
|
545 iLocalRTest->End(); |
|
546 iState = ENoBackupSessionSingleFileTests; |
|
547 Complete(); |
|
548 break; |
|
549 // Required to cover the situation when the backup server is used purely for message signalling |
|
550 // For example in the LogEng compnent |
|
551 case ENoBackupSessionSingleFileTests: |
|
552 iLocalRTest->Start(_L("\nNo backup session single file lock tests\n")); |
|
553 SingleFileLockTestsL(); |
|
554 // Can call EndBackup synchronously here as nothing in SingleFileLockTests is asynchronous |
|
555 EndBackup(3, EFalse); |
|
556 iLocalRTest->End(); |
|
557 iState = EStateMachineEnd; |
|
558 Complete(); |
|
559 break; |
|
560 case EStateMachineEnd: |
|
561 RDebug::Print(_L("\nEnd of state machine\n")); |
|
562 End(); |
|
563 break; |
|
564 default: |
|
565 RDebug::Print(_L("\nCBackupTestsStateMachine::RunL problem")); |
|
566 break; |
|
567 } |
|
568 if (!IsActive()) |
|
569 { |
|
570 SetActive(); |
|
571 } |
|
572 } |
|
573 |
|
574 void CBackupTestsStateMachine::DoCancel() |
|
575 { |
|
576 Complete(); |
|
577 } |
|
578 |
|
579 void CBackupTestsStateMachine::RunError() |
|
580 { ; } |
|
581 |
|
582 // Common function to start a backup |
|
583 void CBackupTestsStateMachine::StartBackupL() |
|
584 { |
|
585 TBackupOperationAttributes attribs; |
|
586 attribs.iFileFlag=MBackupObserver::EReleaseLockNoAccess; |
|
587 attribs.iOperation=MBackupOperationObserver::EStart; |
|
588 iBackupSession->NotifyBackupOperationL(attribs); |
|
589 RDebug::Print(_L("\nStarting backup\n")); |
|
590 } |
|
591 |
|
592 void CBackupTestsStateMachine::SignalEndBackupL() |
|
593 { |
|
594 // Tell the server the backup is over |
|
595 TBackupOperationAttributes attribs; |
|
596 attribs.iFileFlag=MBackupObserver::EReleaseLockNoAccess; |
|
597 attribs.iOperation=MBackupOperationObserver::EEnd; |
|
598 iBackupSession->NotifyBackupOperationL(attribs); |
|
599 } |
|
600 |
|
601 // This function works in two ways. If oneTimeOnly is ETrue then all file lock |
|
602 // change notifications must have been received before this function is called. |
|
603 // If oneTimeOnly is EFalse this function recursively calls itself (a finate number |
|
604 // of times) until all notifications have arrived (this happens with single file testing) |
|
605 void CBackupTestsStateMachine::EndBackup(TInt aFileLockChangesExpected, TBool oneTimeOnly) |
|
606 { |
|
607 // Get the total notification count so far |
|
608 TInt numberOfObservers = iBackupFileObservers.Count(); |
|
609 TInt totalNotificationCount = 0; |
|
610 for (TInt i=0; i<numberOfObservers ; i++) |
|
611 { |
|
612 totalNotificationCount += iBackupFileObservers[i]->GetFileLocksChanged(); |
|
613 } |
|
614 if (aFileLockChangesExpected == totalNotificationCount) |
|
615 { |
|
616 // Reset the recursion count |
|
617 iEndBackupRecursionCount = 0; |
|
618 |
|
619 // Zero the notification counts in the file lock observers |
|
620 for (TInt i = 0 ; i<numberOfObservers ; i++) |
|
621 { |
|
622 iBackupFileObservers[i]->ZeroFileLocksChanged(); |
|
623 } |
|
624 |
|
625 // Debug output |
|
626 TBuf<100> buf; |
|
627 buf.Format(_L("\nBackup finished sucsessfully on recusion count %d of EndBackup\n"), iEndBackupRecursionCount); |
|
628 RDebug::Print(buf); |
|
629 } |
|
630 else if (oneTimeOnly) |
|
631 { |
|
632 // No second chances - fail here |
|
633 (*iLocalRTest)(EFalse); |
|
634 } |
|
635 else |
|
636 { |
|
637 // Give it 5 more seconds (in 10 .5 second iterations) for the notifications to arrive |
|
638 User::After(500000); |
|
639 // 5 seconds is more than enough (timeouts in server should have gone off by now anyway) |
|
640 iEndBackupRecursionCount++; |
|
641 if (iEndBackupRecursionCount > 10) |
|
642 { |
|
643 (*iLocalRTest)(EFalse); |
|
644 } |
|
645 // Recursively calling isn't great but it needs to leave the function so the AO can run |
|
646 EndBackup(aFileLockChangesExpected, EFalse); |
|
647 } |
|
648 |
|
649 } |
|
650 |
|
651 void CBackupTestsStateMachine::Complete() |
|
652 { |
|
653 // Trigger the Active Object locally |
|
654 TRequestStatus* tempStatus=(&iStatus); |
|
655 User::RequestComplete(tempStatus, KErrNone); |
|
656 } |
|
657 |
|
658 void CBackupTestsStateMachine::Start() |
|
659 { |
|
660 // Time to start testing |
|
661 RDebug::Print(_L("\nCBackupTestsStateMachine::Start")); |
|
662 Complete(); |
|
663 } |
|
664 |
|
665 void CBackupTestsStateMachine::End() |
|
666 { |
|
667 // We're done testing - kill the Active Scheduler |
|
668 RDebug::Print(_L("\nAll test complete\n")); |
|
669 Cancel(); |
|
670 CActiveScheduler::Current()->Stop(); |
|
671 } |
|
672 |
|
673 void CBackupTestsStateMachine::SingleFileLockTestsL() |
|
674 { |
|
675 TFileName file; |
|
676 |
|
677 // File 1 |
|
678 file.Copy(KFileName1); |
|
679 iLocalRTest->Next(file); |
|
680 |
|
681 iBackupSession->CloseFileL(KFileName1, MBackupObserver::EReleaseLockReadOnly); |
|
682 iBackupSession->RestartFile(file); |
|
683 |
|
684 // iBackupSession->CloseFileL(KFileName1, MBackupObserver::EReleaseLockNoAccess); |
|
685 // iBackupSession->RestartFile(file); |
|
686 |
|
687 // File 2 |
|
688 file.Copy(KFileName2); |
|
689 iLocalRTest->Next(file); |
|
690 |
|
691 iBackupSession->CloseFileL(KFileName2, MBackupObserver::EReleaseLockReadOnly); |
|
692 iBackupSession->RestartFile(file); |
|
693 |
|
694 // iBackupSession->CloseFileL(KFileName2, MBackupObserver::EReleaseLockNoAccess); |
|
695 // iBackupSession->RestartFile(file); |
|
696 |
|
697 // File 3 |
|
698 file.Copy(KFileName3); |
|
699 iLocalRTest->Next(file); |
|
700 |
|
701 iBackupSession->CloseFileL(KFileName3, MBackupObserver::EReleaseLockReadOnly); |
|
702 iBackupSession->RestartFile(file); |
|
703 |
|
704 // iBackupSession->CloseFileL(KFileName3, MBackupObserver::EReleaseLockNoAccess); |
|
705 // iBackupSession->RestartFile(file); |
|
706 |
|
707 // File 3 |
|
708 file.Copy(KFileName4); |
|
709 iLocalRTest->Next(file); |
|
710 |
|
711 iBackupSession->CloseFileL(KFileName4, MBackupObserver::EReleaseLockReadOnly); |
|
712 iBackupSession->RestartFile(file); |
|
713 |
|
714 // iBackupSession->CloseFileL(KFileName4, MBackupObserver::EReleaseLockNoAccess); |
|
715 // iBackupSession->RestartFile(file); |
|
716 } |
|
717 |
|
718 /** |
|
719 @SYMTestCaseID SYSLIB-BAFL-CT-0467 |
|
720 @SYMTestCaseDesc Tests the functionality of CBaBackupSessionWrapper class |
|
721 @SYMTestPriority High |
|
722 @SYMTestActions Tests for the enabling backup of files |
|
723 @SYMTestExpectedResults Test must not fail |
|
724 @SYMREQ REQ0000 |
|
725 */ |
|
726 LOCAL_D void StartTestsL() |
|
727 { |
|
728 // For the sake of logging let's start off by renaming the main "command" thread |
|
729 RThread().RenameMe(_L("Main thread")); |
|
730 |
|
731 // Create state machine |
|
732 CBackupTestsStateMachine* stateMachine = CBackupTestsStateMachine::NewL(); |
|
733 |
|
734 // Kick it off |
|
735 stateMachine->Start(); |
|
736 |
|
737 // Start the Active Scheduler |
|
738 CActiveScheduler::Start(); |
|
739 |
|
740 // Clean up the state machine |
|
741 delete stateMachine; |
|
742 } |
|
743 |
|
744 TInt E32Main() |
|
745 { |
|
746 MainTest.Title(); |
|
747 MainTest.Start(_L(" @SYMTestCaseID:SYSLIB-BAFL-CT-0467 Loading Device")); |
|
748 |
|
749 __UHEAP_MARK; |
|
750 |
|
751 CTrapCleanup* theTrapCleanup=CTrapCleanup::New(); |
|
752 CActiveScheduler *activeScheduler=new CActiveScheduler; |
|
753 CActiveScheduler::Install(activeScheduler); |
|
754 |
|
755 TRAPD(error, StartTestsL()); |
|
756 User::LeaveIfError(error); |
|
757 |
|
758 delete activeScheduler; |
|
759 delete theTrapCleanup; |
|
760 |
|
761 __UHEAP_MARKEND; |
|
762 |
|
763 MainTest.End(); |
|
764 |
|
765 |
|
766 return(KErrNone); |
|
767 } |