phonebookengines_old/contactsmodel/tsrc/T_OwnCardDelete.CPP
changeset 40 b46a585f6909
child 49 74b30151afd6
equal deleted inserted replaced
37:fd64c38c277d 40:b46a585f6909
       
     1 // Copyright (c) 2007-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 <e32std.h>
       
    17 #include <e32test.h>
       
    18 #include <e32const.h>
       
    19 #include <collate.h>
       
    20 #include <cntdb.h>
       
    21 #include <cntitem.h>
       
    22 #include <cntfldst.h>
       
    23 #include "t_utils2.h"
       
    24 #include "T_UTILS.H"
       
    25 #include <badesca.h>
       
    26 
       
    27 LOCAL_D TInt ThreadFunction(TAny*);
       
    28 
       
    29 _LIT(KDatabaseFileName, "C:T_OwnCardDelete");
       
    30 _LIT(KOwnCardMutex, "OwnCardMutex");
       
    31 _LIT(KOwnCard, "OwnCard");
       
    32 _LIT(KThreadFunc, "ThreadFunc");
       
    33 
       
    34 const TInt KTotalContacts  = 4;
       
    35 const TInt KTimeout = 2000000; 
       
    36 
       
    37 LOCAL_D TInt gEventCounter = 0;
       
    38 LOCAL_D TInt gUnknownEventCounter = 0;
       
    39 // Add*KTotalContacts + 1*OwnCardChanged + 1*UnknownChanges + OwnCardDeleted
       
    40 const TInt KMaxNumOfEvents = KTotalContacts + 3; 
       
    41 const TInt KMaxUnknownEvents = 1;
       
    42 
       
    43 
       
    44 class RTestPtr
       
    45     {
       
    46 public:
       
    47     RTestPtr(RTest* aPtr) : iPtr(aPtr) 
       
    48         {
       
    49         }       
       
    50     ~RTestPtr()
       
    51         { 
       
    52         iPtr->Close();
       
    53         delete iPtr; 
       
    54         }              
       
    55     RTest* operator->()
       
    56         {
       
    57         return iPtr; 
       
    58         }                
       
    59     RTest& Ref()
       
    60         {
       
    61         return *iPtr;
       
    62         }                      
       
    63 private:
       
    64     RTest* iPtr;
       
    65     };              
       
    66 
       
    67 
       
    68 class CMyObserver :  public CActive, public MContactDbObserver
       
    69     {
       
    70 public:
       
    71     CMyObserver() : CActive(EPriorityIdle)
       
    72         {
       
    73         iStart.UniversalTime();
       
    74         }
       
    75     void Activate();
       
    76             
       
    77 private: // From CActive.
       
    78     void RunL();
       
    79     void DoCancel();
       
    80     TInt RunError(TInt aError);
       
    81 
       
    82 private: // From MContactDbObserver
       
    83     void HandleDatabaseEventL(TContactDbObserverEvent aEvent);
       
    84     
       
    85 private:
       
    86     TTime     iStart;
       
    87     TTime     iEnd;
       
    88     };
       
    89 
       
    90 void CMyObserver::RunL()
       
    91     {
       
    92     iEnd.UniversalTime();
       
    93     // Timeout has been excedeed, stop waiting
       
    94     if( iEnd.MicroSecondsFrom(iStart.Int64()) > KTimeout )
       
    95         {        
       
    96         CActiveScheduler::Stop();
       
    97         }
       
    98     else // Waiting for next event
       
    99         {
       
   100         Activate();
       
   101         }
       
   102     }
       
   103 
       
   104 void CMyObserver::DoCancel()
       
   105     {   
       
   106     }
       
   107 
       
   108 TInt CMyObserver::RunError(TInt aError)
       
   109     {
       
   110     return aError;
       
   111     }
       
   112 
       
   113 void CMyObserver::Activate()
       
   114     {
       
   115     if(!IsActive())
       
   116         {
       
   117         TRequestStatus* pS = &iStatus;
       
   118         User::RequestComplete(pS, KErrNone);
       
   119         SetActive();
       
   120         }
       
   121     }
       
   122 
       
   123 
       
   124 void CMyObserver::HandleDatabaseEventL(TContactDbObserverEvent aEvent)
       
   125     {      
       
   126     switch( aEvent.iType )
       
   127         {
       
   128         case EContactDbObserverEventUnknownChanges:
       
   129             {
       
   130             gUnknownEventCounter++;              
       
   131             }break;
       
   132         default:
       
   133             {                        
       
   134             Activate();
       
   135             break;
       
   136             }
       
   137         }            
       
   138     gEventCounter++;
       
   139     }
       
   140     
       
   141     
       
   142 LOCAL_C void WaitForNotificationsL(CContactDatabase* aDb)
       
   143     {                
       
   144     CMyObserver* observer = new (ELeave) CMyObserver();
       
   145     CleanupStack::PushL(observer);
       
   146     CContactChangeNotifier* notifier = CContactChangeNotifier::NewL(*aDb, observer);
       
   147     CleanupStack::PushL(notifier);
       
   148     CActiveScheduler::Add(observer);
       
   149     observer->Activate();
       
   150     CActiveScheduler::Start();
       
   151     
       
   152     CleanupStack::PopAndDestroy(notifier);
       
   153     CleanupStack::PopAndDestroy(observer);
       
   154     }
       
   155                 
       
   156     
       
   157 LOCAL_C void DeleteMultipleContactsL(CContactDatabase* aDb)
       
   158     {
       
   159     CContactIdArray* idArray = aDb->ContactsChangedSinceL(TTime(0));
       
   160     CleanupStack::PushL(idArray);
       
   161     aDb->DeleteContactsL(*idArray);        
       
   162     CleanupStack::PopAndDestroy(idArray);
       
   163     }
       
   164 
       
   165 LOCAL_C void DeleteOwnContactL(CContactDatabase* aDb)
       
   166     {
       
   167     TContactItemId contactId = aDb->OwnCardId();
       
   168     aDb->DeleteContactL(contactId);
       
   169     }
       
   170     
       
   171     
       
   172 LOCAL_C void TestSetOwnCardL(CContactDatabase* aDb)
       
   173     {
       
   174     CContactIdArray* idArray = aDb->ContactsChangedSinceL(TTime(0));
       
   175     CleanupStack::PushL(idArray);
       
   176     TInt count = idArray->Count();
       
   177     if (count > 0)
       
   178         {
       
   179         TInt someIndex(0); //Make the first contact own contact           
       
   180         TContactItemId id = (*idArray)[someIndex];
       
   181         CContactItem* item = aDb->ReadContactLC(id); // take ownership of item
       
   182         aDb->SetOwnCardL(*item);
       
   183         CleanupStack::PopAndDestroy(item);
       
   184         }        
       
   185     CleanupStack::PopAndDestroy(idArray);
       
   186     }
       
   187     
       
   188     
       
   189 LOCAL_C void PopulateDatabaseL(CContactDatabase* aDb, TInt aCntCount)
       
   190     {        
       
   191     CRandomContactGenerator* randomCnt = CRandomContactGenerator::NewL();
       
   192     CleanupStack::PushL(randomCnt);
       
   193     randomCnt->SetDbL(*aDb);    
       
   194     for (TInt i = 0; i < aCntCount; ++i)
       
   195         {
       
   196         randomCnt->AddTypicalRandomContactL();        
       
   197         }          
       
   198     CleanupStack::PopAndDestroy(randomCnt);       
       
   199     }
       
   200     
       
   201     
       
   202 LOCAL_D void SwitchToMainThread(RMutex& aMutex)
       
   203     {    
       
   204     RThread::Rendezvous(KErrNone);         
       
   205     aMutex.Wait();     
       
   206     aMutex.Signal();
       
   207     User::After(10);
       
   208     }
       
   209  
       
   210     
       
   211 LOCAL_D void SwitchToWorkerThread(RMutex& aMutex, RThread& aThread, TBool aSignal, TBool aWait)
       
   212     {
       
   213     if (aSignal)
       
   214         {
       
   215         aMutex.Signal();             
       
   216         User::After(10);         
       
   217         }
       
   218         
       
   219     if (aWait)
       
   220         {            
       
   221         aMutex.Wait(); 
       
   222         }
       
   223         
       
   224     TRequestStatus status;            
       
   225     aThread.Rendezvous(status);         
       
   226 
       
   227 
       
   228     User::WaitForRequest(status);            
       
   229     }    
       
   230     
       
   231 LOCAL_D void ThreadFirstTestL(RTest& aTest)
       
   232     {
       
   233     aTest.Next(_L("-- Running worker thread --"));
       
   234 
       
   235 
       
   236     RMutex mutex;
       
   237     TInt errMutex = mutex.OpenGlobal(KOwnCardMutex);   
       
   238     User::LeaveIfError(errMutex);
       
   239     CleanupClosePushL(mutex);
       
   240     
       
   241     aTest.Printf(_L("Replacing the database \n"));
       
   242     CContactDatabase* db = CContactDatabase::ReplaceL(KDatabaseFileName);
       
   243     CleanupStack::PushL(db); 
       
   244     
       
   245     // get a second database object
       
   246     CContactDatabase* dbAnother = CContactDatabase::OpenL(KDatabaseFileName);
       
   247     CleanupStack::PushL(dbAnother);    
       
   248         
       
   249     SwitchToMainThread(mutex); // 1) Back to MT-a
       
   250     
       
   251     //
       
   252     // Main thread has now opened the database    
       
   253     //
       
   254                         
       
   255     aTest.Printf(_L("Populating the database \n"));
       
   256     PopulateDatabaseL(db, KTotalContacts);    
       
   257     WaitForNotificationsL(db);        
       
   258                     
       
   259     aTest.Printf(_L("Set the Own card id \n"));                    
       
   260     TestSetOwnCardL(db);                
       
   261     WaitForNotificationsL(db);
       
   262     
       
   263     aTest.Printf(_L("Checking count value \n"));
       
   264     TInt count = db->CountL();    
       
   265     TInt countAnother = dbAnother->CountL();
       
   266     aTest.Printf(_L("Count: %d \n"), count );
       
   267     aTest(count == KTotalContacts && countAnother == KTotalContacts, __LINE__);
       
   268     
       
   269     aTest.Printf(_L("Checking the id \n"));
       
   270     TContactItemId id = db->OwnCardId();
       
   271     TContactItemId idCopy = dbAnother->OwnCardId();
       
   272     aTest.Printf(_L("Id: %d \n"), id);    
       
   273     aTest(id != KNullContactId && idCopy != KNullContactId, __LINE__);                
       
   274         
       
   275     SwitchToMainThread(mutex); // 2) Back to MT-b 
       
   276     
       
   277     //
       
   278     // Main thread has now checked the added values    
       
   279     //    
       
   280     
       
   281     DeleteMultipleContactsL(db);    
       
   282     WaitForNotificationsL(db);         
       
   283         
       
   284     aTest.Printf(_L("Checking deleted count value \n"));
       
   285     count = db->CountL();
       
   286     countAnother = dbAnother->CountL();    
       
   287     aTest.Printf(_L("Count: %d \n"), count );
       
   288     aTest(count == 0 && countAnother == 0, __LINE__);
       
   289     
       
   290     aTest.Printf(_L("Checking the deleted id \n"));
       
   291     id = db->OwnCardId();
       
   292     idCopy = dbAnother->OwnCardId();
       
   293     aTest.Printf(_L("Id: %d \n"), id);    
       
   294     aTest(id == KNullContactId && idCopy == KNullContactId, __LINE__);
       
   295             
       
   296     SwitchToMainThread(mutex); // 3) Back to MT-c
       
   297     
       
   298     //
       
   299     // Main thread has now checked the deleted values    
       
   300     //    
       
   301     
       
   302     CleanupStack::PopAndDestroy(dbAnother);        
       
   303     CleanupStack::PopAndDestroy(db);
       
   304     CleanupStack::PopAndDestroy(); // close mutex handle
       
   305                 
       
   306     RThread::Rendezvous(KErrNone); // Finish) back to MT-d
       
   307     }          
       
   308     
       
   309 LOCAL_D void TestSecondL(RTest& aTest)
       
   310     {
       
   311     aTest.Next(_L("-- Second Owncard Test --"));
       
   312 
       
   313     
       
   314     RMutex mtx;
       
   315     TInt errMutex = mtx.CreateGlobal(KOwnCardMutex);
       
   316     User::LeaveIfError(errMutex);
       
   317     CleanupClosePushL(mtx);    
       
   318     
       
   319     RThread thd;  
       
   320     aTest.Printf(_L("Creating worker thread \n"));  
       
   321     TInt errThread = thd.Create(KThreadFunc, ThreadFunction, KDefaultStackSize, KDefaultStackSize*20, KDefaultStackSize*40, NULL);  
       
   322     User::LeaveIfError(errThread);
       
   323     CleanupClosePushL(thd);
       
   324     thd.Resume();    
       
   325          
       
   326     SwitchToWorkerThread(mtx, thd, EFalse, ETrue); // a) Run: WT-start to WT-1
       
   327                   
       
   328     //
       
   329     // Worker thread has now replaced the database    
       
   330     //
       
   331         
       
   332     aTest.Printf(_L("Open existing database \n"));
       
   333     CContactDatabase* db = CContactDatabase::OpenL(KDatabaseFileName);
       
   334     CleanupStack::PushL(db);
       
   335         
       
   336     SwitchToWorkerThread(mtx, thd, ETrue, ETrue); // b) Run: WT-1 to WT-2                    
       
   337     
       
   338     //
       
   339     // Worker thread has now added the contacts
       
   340     //
       
   341         
       
   342     WaitForNotificationsL(db); 
       
   343     
       
   344     aTest.Printf(_L("Checking db count \n"));          
       
   345     TInt count = db->CountL();
       
   346     aTest.Printf(_L("Count: %d \n"), count);
       
   347     aTest(count == KTotalContacts, __LINE__);
       
   348     
       
   349     aTest.Printf(_L("Checking owncard id \n"));      
       
   350     TContactItemId id = db->OwnCardId();  
       
   351     aTest.Printf(_L("id: %d \n"), id);
       
   352     aTest(id != KNullContactId, __LINE__);
       
   353     
       
   354     SwitchToWorkerThread(mtx, thd, ETrue, ETrue); // c) Run: WT-2 to WT-3      
       
   355     
       
   356     //
       
   357     // Worker thread has now deleted the contacts
       
   358     //
       
   359     
       
   360     aTest.Printf(_L("Checking deleted db count \n"));      
       
   361         
       
   362     WaitForNotificationsL(db); 
       
   363     
       
   364     count = db->CountL();
       
   365     aTest.Printf(_L("Count: %d \n"), count);
       
   366     aTest(count == 0, __LINE__);
       
   367     
       
   368     aTest.Printf(_L("Checking deleted owncard id \n"));      
       
   369     id = db->OwnCardId();  
       
   370     aTest.Printf(_L("id: %d \n"), id);
       
   371     aTest(id == KNullContactId, __LINE__);
       
   372                  
       
   373     CleanupStack::PopAndDestroy(db);           
       
   374         
       
   375     SwitchToWorkerThread(mtx, thd, ETrue, EFalse); // d) Run: WT-3 to end
       
   376     
       
   377     CleanupStack::PopAndDestroy(); // close thd handle
       
   378     CleanupStack::PopAndDestroy(); // close mtx handle        
       
   379     }
       
   380   
       
   381     
       
   382 LOCAL_D void TestFirstL(RTest& aTest)
       
   383     {
       
   384     aTest.Next(_L("@SYMTestCaseID:PIM-T-OWNCARDDELETE-0001 -- First Owncard Test --"));
       
   385 
       
   386     aTest.Printf(_L("Replacing database \n"));
       
   387     CContactDatabase* db = CContactDatabase::ReplaceL(KDatabaseFileName);
       
   388     CleanupStack::PushL(db); 
       
   389     
       
   390     CContactDatabase* dbAnother = CContactDatabase::OpenL(KDatabaseFileName);
       
   391     CleanupStack::PushL(dbAnother);
       
   392         
       
   393     PopulateDatabaseL(db, KTotalContacts);        
       
   394     WaitForNotificationsL(db);        
       
   395                     
       
   396     TestSetOwnCardL(db);                
       
   397     WaitForNotificationsL(db);        
       
   398     
       
   399     aTest.Printf(_L("Checking the count value \n"));
       
   400     TInt count = dbAnother->CountL();    
       
   401     aTest.Printf(_L("Count: %d \n"), count);
       
   402     aTest(count == KTotalContacts, __LINE__);
       
   403       
       
   404     aTest.Printf(_L("Checking the id \n"));    
       
   405     TContactItemId id = dbAnother->OwnCardId();    
       
   406     aTest.Printf(_L("id: %d \n"), id);
       
   407     aTest(id != KNullContactId, __LINE__);
       
   408     
       
   409     TContactIter iter(*db); //Test that the iterator is updated
       
   410     TContactItemId firstContactId;
       
   411     firstContactId = iter.FirstL(); //should be own contactId
       
   412     
       
   413     DeleteOwnContactL(dbAnother);
       
   414     WaitForNotificationsL(dbAnother);
       
   415     
       
   416     TContactItemId secondContactId;
       
   417     TRAPD (err,  secondContactId = iter.FirstL());
       
   418     aTest(err == KErrNone && firstContactId != secondContactId, __LINE__);
       
   419     
       
   420     
       
   421     DeleteMultipleContactsL(db);    
       
   422     WaitForNotificationsL(db); 
       
   423     
       
   424     aTest.Printf(_L("Checking the deleted count value \n"));
       
   425     count = dbAnother->CountL();    
       
   426     aTest.Printf(_L("Count: %d \n"), count);
       
   427     aTest(count == 0, __LINE__);
       
   428       
       
   429     aTest.Printf(_L("Checking the deleted id \n"));    
       
   430     id = dbAnother->OwnCardId();    
       
   431     aTest.Printf(_L("id: %d \n"), id);
       
   432     aTest(id == KNullContactId, __LINE__);     
       
   433     
       
   434     aTest(gEventCounter == KMaxNumOfEvents, __LINE__);
       
   435     aTest(gUnknownEventCounter == KMaxUnknownEvents, __LINE__);                             
       
   436     
       
   437     CleanupStack::PopAndDestroy(2,db);    
       
   438     } 
       
   439     
       
   440     
       
   441 LOCAL_D void ThreadDoTestsL()
       
   442     {
       
   443     RTestPtr myTest(new(ELeave) RTest(KThreadFunc));
       
   444     
       
   445     myTest->Start(KThreadFunc);        
       
   446     ThreadFirstTestL(myTest.Ref());    
       
   447     myTest->End();    
       
   448     }
       
   449      
       
   450 
       
   451 /**
       
   452 @SYMTestCaseID PIM-T-OWNCARDDELETE-0001
       
   453 @SYMTestType UT
       
   454 @SYMTestPriority Medium
       
   455 @SYMDEF PDEF107246
       
   456 @SYMTestCaseDependencies CntModel CoreAppsTest
       
   457 @SYMTestCaseDesc Check that updates to one CContactDatabase-instance will propagate to a second instance
       
   458 @SYMTestActions Add some contacts. Set one as own card. Check that the count is the same for all instances. 
       
   459                 Check that the own card id is the same for all instances. Delete all contacts and check that 
       
   460                 the count is zero and own card id is KNullContactId (-1) for all instances.                
       
   461 @SYMTestExpectedResults see above.
       
   462 */
       
   463 LOCAL_D void DoTestsL()
       
   464     {  
       
   465     RTestPtr myTest(new(ELeave) RTest(KOwnCard));
       
   466         
       
   467     myTest->Start(KOwnCard);          
       
   468     TestFirstL(myTest.Ref());                          
       
   469     TestSecondL(myTest.Ref());         
       
   470     
       
   471     CContactDatabase::DeleteDatabaseL(KDatabaseFileName);   
       
   472     myTest->Printf(_L("Completed OK \n"));        
       
   473     myTest->End();  
       
   474     }
       
   475     
       
   476     
       
   477 LOCAL_D TInt ThreadFunction(TAny*)
       
   478     {      
       
   479     __UHEAP_MARK;                     
       
   480     CActiveScheduler* scheduler = new CActiveScheduler;
       
   481     if (scheduler)
       
   482         {        
       
   483         CActiveScheduler::Install(scheduler);    
       
   484         CTrapCleanup* cleanup = CTrapCleanup::New();
       
   485         if (cleanup)
       
   486             {                            
       
   487             TRAPD(err, ThreadDoTestsL());
       
   488             __ASSERT_ALWAYS(err == KErrNone, User::Panic(_L("Failure in Worker Thread"),err));
       
   489             delete cleanup;
       
   490             }
       
   491         delete scheduler;        
       
   492         }             
       
   493     __UHEAP_MARKEND;                 
       
   494     return KErrNone;
       
   495     }    
       
   496     
       
   497            
       
   498 GLDEF_C TInt E32Main()
       
   499     {            
       
   500     __UHEAP_MARK;
       
   501     CActiveScheduler* scheduler = new CActiveScheduler;
       
   502     if (scheduler)
       
   503         {    
       
   504         CActiveScheduler::Install(scheduler);    
       
   505         CTrapCleanup* cleanup = CTrapCleanup::New();
       
   506         if (cleanup)
       
   507             {
       
   508             TRAPD(err, DoTestsL());                            
       
   509             __ASSERT_ALWAYS(err == KErrNone, User::Panic(_L("Failure in Main Thread"),err));            
       
   510             delete cleanup;
       
   511             }
       
   512         delete scheduler;
       
   513         }    
       
   514     __UHEAP_MARKEND;
       
   515     return KErrNone;
       
   516     }