phonebookengines_old/contactsmodel/tsrc/T_OwnCardDelete.CPP
changeset 40 b46a585f6909
child 49 74b30151afd6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines_old/contactsmodel/tsrc/T_OwnCardDelete.CPP	Fri Jun 11 13:29:23 2010 +0300
@@ -0,0 +1,516 @@
+// 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 <e32std.h>
+#include <e32test.h>
+#include <e32const.h>
+#include <collate.h>
+#include <cntdb.h>
+#include <cntitem.h>
+#include <cntfldst.h>
+#include "t_utils2.h"
+#include "T_UTILS.H"
+#include <badesca.h>
+
+LOCAL_D TInt ThreadFunction(TAny*);
+
+_LIT(KDatabaseFileName, "C:T_OwnCardDelete");
+_LIT(KOwnCardMutex, "OwnCardMutex");
+_LIT(KOwnCard, "OwnCard");
+_LIT(KThreadFunc, "ThreadFunc");
+
+const TInt KTotalContacts  = 4;
+const TInt KTimeout = 2000000; 
+
+LOCAL_D TInt gEventCounter = 0;
+LOCAL_D TInt gUnknownEventCounter = 0;
+// Add*KTotalContacts + 1*OwnCardChanged + 1*UnknownChanges + OwnCardDeleted
+const TInt KMaxNumOfEvents = KTotalContacts + 3; 
+const TInt KMaxUnknownEvents = 1;
+
+
+class RTestPtr
+    {
+public:
+    RTestPtr(RTest* aPtr) : iPtr(aPtr) 
+        {
+        }       
+    ~RTestPtr()
+        { 
+        iPtr->Close();
+        delete iPtr; 
+        }              
+    RTest* operator->()
+        {
+        return iPtr; 
+        }                
+    RTest& Ref()
+        {
+        return *iPtr;
+        }                      
+private:
+    RTest* iPtr;
+    };              
+
+
+class CMyObserver :  public CActive, public MContactDbObserver
+    {
+public:
+    CMyObserver() : CActive(EPriorityIdle)
+        {
+        iStart.UniversalTime();
+        }
+    void Activate();
+            
+private: // From CActive.
+    void RunL();
+    void DoCancel();
+    TInt RunError(TInt aError);
+
+private: // From MContactDbObserver
+    void HandleDatabaseEventL(TContactDbObserverEvent aEvent);
+    
+private:
+    TTime     iStart;
+    TTime     iEnd;
+    };
+
+void CMyObserver::RunL()
+    {
+    iEnd.UniversalTime();
+    // Timeout has been excedeed, stop waiting
+    if( iEnd.MicroSecondsFrom(iStart.Int64()) > KTimeout )
+        {        
+        CActiveScheduler::Stop();
+        }
+    else // Waiting for next event
+        {
+        Activate();
+        }
+    }
+
+void CMyObserver::DoCancel()
+    {   
+    }
+
+TInt CMyObserver::RunError(TInt aError)
+    {
+    return aError;
+    }
+
+void CMyObserver::Activate()
+    {
+    if(!IsActive())
+        {
+        TRequestStatus* pS = &iStatus;
+        User::RequestComplete(pS, KErrNone);
+        SetActive();
+        }
+    }
+
+
+void CMyObserver::HandleDatabaseEventL(TContactDbObserverEvent aEvent)
+    {      
+    switch( aEvent.iType )
+        {
+        case EContactDbObserverEventUnknownChanges:
+            {
+            gUnknownEventCounter++;              
+            }break;
+        default:
+            {                        
+            Activate();
+            break;
+            }
+        }            
+    gEventCounter++;
+    }
+    
+    
+LOCAL_C void WaitForNotificationsL(CContactDatabase* aDb)
+    {                
+    CMyObserver* observer = new (ELeave) CMyObserver();
+    CleanupStack::PushL(observer);
+    CContactChangeNotifier* notifier = CContactChangeNotifier::NewL(*aDb, observer);
+    CleanupStack::PushL(notifier);
+    CActiveScheduler::Add(observer);
+    observer->Activate();
+    CActiveScheduler::Start();
+    
+    CleanupStack::PopAndDestroy(notifier);
+    CleanupStack::PopAndDestroy(observer);
+    }
+                
+    
+LOCAL_C void DeleteMultipleContactsL(CContactDatabase* aDb)
+    {
+    CContactIdArray* idArray = aDb->ContactsChangedSinceL(TTime(0));
+    CleanupStack::PushL(idArray);
+    aDb->DeleteContactsL(*idArray);        
+    CleanupStack::PopAndDestroy(idArray);
+    }
+
+LOCAL_C void DeleteOwnContactL(CContactDatabase* aDb)
+    {
+    TContactItemId contactId = aDb->OwnCardId();
+    aDb->DeleteContactL(contactId);
+    }
+    
+    
+LOCAL_C void TestSetOwnCardL(CContactDatabase* aDb)
+    {
+    CContactIdArray* idArray = aDb->ContactsChangedSinceL(TTime(0));
+    CleanupStack::PushL(idArray);
+    TInt count = idArray->Count();
+    if (count > 0)
+        {
+        TInt someIndex(0); //Make the first contact own contact           
+        TContactItemId id = (*idArray)[someIndex];
+        CContactItem* item = aDb->ReadContactLC(id); // take ownership of item
+        aDb->SetOwnCardL(*item);
+        CleanupStack::PopAndDestroy(item);
+        }        
+    CleanupStack::PopAndDestroy(idArray);
+    }
+    
+    
+LOCAL_C void PopulateDatabaseL(CContactDatabase* aDb, TInt aCntCount)
+    {        
+    CRandomContactGenerator* randomCnt = CRandomContactGenerator::NewL();
+    CleanupStack::PushL(randomCnt);
+    randomCnt->SetDbL(*aDb);    
+    for (TInt i = 0; i < aCntCount; ++i)
+        {
+        randomCnt->AddTypicalRandomContactL();        
+        }          
+    CleanupStack::PopAndDestroy(randomCnt);       
+    }
+    
+    
+LOCAL_D void SwitchToMainThread(RMutex& aMutex)
+    {    
+    RThread::Rendezvous(KErrNone);         
+    aMutex.Wait();     
+    aMutex.Signal();
+    User::After(10);
+    }
+ 
+    
+LOCAL_D void SwitchToWorkerThread(RMutex& aMutex, RThread& aThread, TBool aSignal, TBool aWait)
+    {
+    if (aSignal)
+        {
+        aMutex.Signal();             
+        User::After(10);         
+        }
+        
+    if (aWait)
+        {            
+        aMutex.Wait(); 
+        }
+        
+    TRequestStatus status;            
+    aThread.Rendezvous(status);         
+
+
+    User::WaitForRequest(status);            
+    }    
+    
+LOCAL_D void ThreadFirstTestL(RTest& aTest)
+    {
+    aTest.Next(_L("-- Running worker thread --"));
+
+
+    RMutex mutex;
+    TInt errMutex = mutex.OpenGlobal(KOwnCardMutex);   
+    User::LeaveIfError(errMutex);
+    CleanupClosePushL(mutex);
+    
+    aTest.Printf(_L("Replacing the database \n"));
+    CContactDatabase* db = CContactDatabase::ReplaceL(KDatabaseFileName);
+    CleanupStack::PushL(db); 
+    
+    // get a second database object
+    CContactDatabase* dbAnother = CContactDatabase::OpenL(KDatabaseFileName);
+    CleanupStack::PushL(dbAnother);    
+        
+    SwitchToMainThread(mutex); // 1) Back to MT-a
+    
+    //
+    // Main thread has now opened the database    
+    //
+                        
+    aTest.Printf(_L("Populating the database \n"));
+    PopulateDatabaseL(db, KTotalContacts);    
+    WaitForNotificationsL(db);        
+                    
+    aTest.Printf(_L("Set the Own card id \n"));                    
+    TestSetOwnCardL(db);                
+    WaitForNotificationsL(db);
+    
+    aTest.Printf(_L("Checking count value \n"));
+    TInt count = db->CountL();    
+    TInt countAnother = dbAnother->CountL();
+    aTest.Printf(_L("Count: %d \n"), count );
+    aTest(count == KTotalContacts && countAnother == KTotalContacts, __LINE__);
+    
+    aTest.Printf(_L("Checking the id \n"));
+    TContactItemId id = db->OwnCardId();
+    TContactItemId idCopy = dbAnother->OwnCardId();
+    aTest.Printf(_L("Id: %d \n"), id);    
+    aTest(id != KNullContactId && idCopy != KNullContactId, __LINE__);                
+        
+    SwitchToMainThread(mutex); // 2) Back to MT-b 
+    
+    //
+    // Main thread has now checked the added values    
+    //    
+    
+    DeleteMultipleContactsL(db);    
+    WaitForNotificationsL(db);         
+        
+    aTest.Printf(_L("Checking deleted count value \n"));
+    count = db->CountL();
+    countAnother = dbAnother->CountL();    
+    aTest.Printf(_L("Count: %d \n"), count );
+    aTest(count == 0 && countAnother == 0, __LINE__);
+    
+    aTest.Printf(_L("Checking the deleted id \n"));
+    id = db->OwnCardId();
+    idCopy = dbAnother->OwnCardId();
+    aTest.Printf(_L("Id: %d \n"), id);    
+    aTest(id == KNullContactId && idCopy == KNullContactId, __LINE__);
+            
+    SwitchToMainThread(mutex); // 3) Back to MT-c
+    
+    //
+    // Main thread has now checked the deleted values    
+    //    
+    
+    CleanupStack::PopAndDestroy(dbAnother);        
+    CleanupStack::PopAndDestroy(db);
+    CleanupStack::PopAndDestroy(); // close mutex handle
+                
+    RThread::Rendezvous(KErrNone); // Finish) back to MT-d
+    }          
+    
+LOCAL_D void TestSecondL(RTest& aTest)
+    {
+    aTest.Next(_L("-- Second Owncard Test --"));
+
+    
+    RMutex mtx;
+    TInt errMutex = mtx.CreateGlobal(KOwnCardMutex);
+    User::LeaveIfError(errMutex);
+    CleanupClosePushL(mtx);    
+    
+    RThread thd;  
+    aTest.Printf(_L("Creating worker thread \n"));  
+    TInt errThread = thd.Create(KThreadFunc, ThreadFunction, KDefaultStackSize, KDefaultStackSize*20, KDefaultStackSize*40, NULL);  
+    User::LeaveIfError(errThread);
+    CleanupClosePushL(thd);
+    thd.Resume();    
+         
+    SwitchToWorkerThread(mtx, thd, EFalse, ETrue); // a) Run: WT-start to WT-1
+                  
+    //
+    // Worker thread has now replaced the database    
+    //
+        
+    aTest.Printf(_L("Open existing database \n"));
+    CContactDatabase* db = CContactDatabase::OpenL(KDatabaseFileName);
+    CleanupStack::PushL(db);
+        
+    SwitchToWorkerThread(mtx, thd, ETrue, ETrue); // b) Run: WT-1 to WT-2                    
+    
+    //
+    // Worker thread has now added the contacts
+    //
+        
+    WaitForNotificationsL(db); 
+    
+    aTest.Printf(_L("Checking db count \n"));          
+    TInt count = db->CountL();
+    aTest.Printf(_L("Count: %d \n"), count);
+    aTest(count == KTotalContacts, __LINE__);
+    
+    aTest.Printf(_L("Checking owncard id \n"));      
+    TContactItemId id = db->OwnCardId();  
+    aTest.Printf(_L("id: %d \n"), id);
+    aTest(id != KNullContactId, __LINE__);
+    
+    SwitchToWorkerThread(mtx, thd, ETrue, ETrue); // c) Run: WT-2 to WT-3      
+    
+    //
+    // Worker thread has now deleted the contacts
+    //
+    
+    aTest.Printf(_L("Checking deleted db count \n"));      
+        
+    WaitForNotificationsL(db); 
+    
+    count = db->CountL();
+    aTest.Printf(_L("Count: %d \n"), count);
+    aTest(count == 0, __LINE__);
+    
+    aTest.Printf(_L("Checking deleted owncard id \n"));      
+    id = db->OwnCardId();  
+    aTest.Printf(_L("id: %d \n"), id);
+    aTest(id == KNullContactId, __LINE__);
+                 
+    CleanupStack::PopAndDestroy(db);           
+        
+    SwitchToWorkerThread(mtx, thd, ETrue, EFalse); // d) Run: WT-3 to end
+    
+    CleanupStack::PopAndDestroy(); // close thd handle
+    CleanupStack::PopAndDestroy(); // close mtx handle        
+    }
+  
+    
+LOCAL_D void TestFirstL(RTest& aTest)
+    {
+    aTest.Next(_L("@SYMTestCaseID:PIM-T-OWNCARDDELETE-0001 -- First Owncard Test --"));
+
+    aTest.Printf(_L("Replacing database \n"));
+    CContactDatabase* db = CContactDatabase::ReplaceL(KDatabaseFileName);
+    CleanupStack::PushL(db); 
+    
+    CContactDatabase* dbAnother = CContactDatabase::OpenL(KDatabaseFileName);
+    CleanupStack::PushL(dbAnother);
+        
+    PopulateDatabaseL(db, KTotalContacts);        
+    WaitForNotificationsL(db);        
+                    
+    TestSetOwnCardL(db);                
+    WaitForNotificationsL(db);        
+    
+    aTest.Printf(_L("Checking the count value \n"));
+    TInt count = dbAnother->CountL();    
+    aTest.Printf(_L("Count: %d \n"), count);
+    aTest(count == KTotalContacts, __LINE__);
+      
+    aTest.Printf(_L("Checking the id \n"));    
+    TContactItemId id = dbAnother->OwnCardId();    
+    aTest.Printf(_L("id: %d \n"), id);
+    aTest(id != KNullContactId, __LINE__);
+    
+    TContactIter iter(*db); //Test that the iterator is updated
+    TContactItemId firstContactId;
+    firstContactId = iter.FirstL(); //should be own contactId
+    
+    DeleteOwnContactL(dbAnother);
+    WaitForNotificationsL(dbAnother);
+    
+    TContactItemId secondContactId;
+    TRAPD (err,  secondContactId = iter.FirstL());
+    aTest(err == KErrNone && firstContactId != secondContactId, __LINE__);
+    
+    
+    DeleteMultipleContactsL(db);    
+    WaitForNotificationsL(db); 
+    
+    aTest.Printf(_L("Checking the deleted count value \n"));
+    count = dbAnother->CountL();    
+    aTest.Printf(_L("Count: %d \n"), count);
+    aTest(count == 0, __LINE__);
+      
+    aTest.Printf(_L("Checking the deleted id \n"));    
+    id = dbAnother->OwnCardId();    
+    aTest.Printf(_L("id: %d \n"), id);
+    aTest(id == KNullContactId, __LINE__);     
+    
+    aTest(gEventCounter == KMaxNumOfEvents, __LINE__);
+    aTest(gUnknownEventCounter == KMaxUnknownEvents, __LINE__);                             
+    
+    CleanupStack::PopAndDestroy(2,db);    
+    } 
+    
+    
+LOCAL_D void ThreadDoTestsL()
+    {
+    RTestPtr myTest(new(ELeave) RTest(KThreadFunc));
+    
+    myTest->Start(KThreadFunc);        
+    ThreadFirstTestL(myTest.Ref());    
+    myTest->End();    
+    }
+     
+
+/**
+@SYMTestCaseID PIM-T-OWNCARDDELETE-0001
+@SYMTestType UT
+@SYMTestPriority Medium
+@SYMDEF PDEF107246
+@SYMTestCaseDependencies CntModel CoreAppsTest
+@SYMTestCaseDesc Check that updates to one CContactDatabase-instance will propagate to a second instance
+@SYMTestActions Add some contacts. Set one as own card. Check that the count is the same for all instances. 
+                Check that the own card id is the same for all instances. Delete all contacts and check that 
+                the count is zero and own card id is KNullContactId (-1) for all instances.                
+@SYMTestExpectedResults see above.
+*/
+LOCAL_D void DoTestsL()
+    {  
+    RTestPtr myTest(new(ELeave) RTest(KOwnCard));
+        
+    myTest->Start(KOwnCard);          
+    TestFirstL(myTest.Ref());                          
+    TestSecondL(myTest.Ref());         
+    
+    CContactDatabase::DeleteDatabaseL(KDatabaseFileName);   
+    myTest->Printf(_L("Completed OK \n"));        
+    myTest->End();  
+    }
+    
+    
+LOCAL_D TInt ThreadFunction(TAny*)
+    {      
+    __UHEAP_MARK;                     
+    CActiveScheduler* scheduler = new CActiveScheduler;
+    if (scheduler)
+        {        
+        CActiveScheduler::Install(scheduler);    
+        CTrapCleanup* cleanup = CTrapCleanup::New();
+        if (cleanup)
+            {                            
+            TRAPD(err, ThreadDoTestsL());
+            __ASSERT_ALWAYS(err == KErrNone, User::Panic(_L("Failure in Worker Thread"),err));
+            delete cleanup;
+            }
+        delete scheduler;        
+        }             
+    __UHEAP_MARKEND;                 
+    return KErrNone;
+    }    
+    
+           
+GLDEF_C TInt E32Main()
+    {            
+    __UHEAP_MARK;
+    CActiveScheduler* scheduler = new CActiveScheduler;
+    if (scheduler)
+        {    
+        CActiveScheduler::Install(scheduler);    
+        CTrapCleanup* cleanup = CTrapCleanup::New();
+        if (cleanup)
+            {
+            TRAPD(err, DoTestsL());                            
+            __ASSERT_ALWAYS(err == KErrNone, User::Panic(_L("Failure in Main Thread"),err));            
+            delete cleanup;
+            }
+        delete scheduler;
+        }    
+    __UHEAP_MARKEND;
+    return KErrNone;
+    }