phonebookengines_old/contactsmodel/tsrc/T_Concurrent.cpp
changeset 40 b46a585f6909
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines_old/contactsmodel/tsrc/T_Concurrent.cpp	Fri Jun 11 13:29:23 2010 +0300
@@ -0,0 +1,373 @@
+// Copyright (c) 2000-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 Files  
+#include "T_Concurrent.h"
+#include <e32base.h>
+#include <e32std.h>
+#include <e32cons.h>            
+#include <cntdb.h>
+#include <cntdbobs.h>
+#include <cntitem.h>
+#include <cntfield.h>
+#include <cntfldst.h>
+
+
+//  Constants
+_LIT(KThreadTitle, "Thread2");
+_LIT(KTextFailed, " failed, leave code = %d");
+
+// Global Variables
+RTest MainTest(_L("Concurrent test"));	// Main RTest
+CContactDatabase * database = NULL;		// Shared database.
+RSemaphore sem;							// Synchronising Semaphore
+TInt t1MachineId = 0;					// Thread1 machineId from db.
+TInt currentStep = 0;					// Current test step.
+
+//
+//                  CHILD THREAD FUNCTIONS.
+//
+
+/**
+* The main function called when the child thread is invoked.
+*/
+TInt RunChildThread(TAny * /* ptr */)
+	{
+    // Create cleanup stack
+    __UHEAP_MARK;
+    CTrapCleanup* cleanup = CTrapCleanup::New();
+    
+    // Create active scheduler (to run active objects)
+    CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
+    CActiveScheduler::Install(scheduler);
+    CChildThread* childThread = NULL;
+    
+    TInt err;
+    TRAP(err, childThread = CChildThread::NewL());
+	if (err == KErrNone)
+		{
+		TRAP(err, childThread->AccessDBTestL() );
+		}
+    
+	if (err != KErrNone)
+    	MainTest.Printf( _L(" Child thread test returned with error = %d"),  err);
+
+	delete childThread;
+    delete cleanup;
+    delete scheduler;
+	__UHEAP_MARKEND;
+    return KErrNone;	
+	}
+
+/**
+* The child thread accesses the shared db session.
+* A basic operation like getting the count of contacts is performed.
+*/
+CChildThread * CChildThread::NewL()
+	{
+	CChildThread * self = new(ELeave) CChildThread;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+void CChildThread::ConstructL()
+	{
+	TBuf<100> threadName;
+	threadName.Format(_L("Child Thread"));
+	iTest = new(ELeave) RTest(threadName);
+	}
+
+CChildThread::~CChildThread()
+	{
+	iTest->Close();
+	delete iTest;
+	iTest = NULL;
+	}
+	
+
+/**
+* This function tries to access the db and check the count, or perform some other action
+* on the db. The session object is shared with the main thread .
+*/
+void CChildThread::AccessDBTestL()
+	{
+    
+    while(currentStep != ETestsEnd)
+    	{
+	    TInt t2MachineId = database->MachineId();
+	    TInt count = database->CountL();
+	    iTest->Printf( _L("Thread2: Contact Count = %d"), count  );
+	    
+	    // Check that the child thread is accessing the shared db session correctly.
+	    MainTest(count==1);
+	    MainTest( t2MachineId == t1MachineId );
+	    
+	    sem.Signal();
+	    RThread().Suspend();
+	    }
+	   
+	// Child thread is now over.  
+	sem.Signal();  
+	    
+	}
+
+
+//
+//                  MAIN THREAD FUNCTIONS.
+//
+/**
+* The main thread object which owns the session with the database in thread shared mode.
+*/
+CMainThread * CMainThread::NewL()
+	{
+	CMainThread * self = new (ELeave) CMainThread;
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();
+	return self;
+	}
+	
+void CMainThread::ConstructL()
+	{
+	TBuf<100> threadName;
+	threadName.Format(_L("Main Thread"));
+	iTest = new(ELeave) RTest(threadName);
+	}
+	
+CMainThread::~CMainThread()
+	{
+	TRAP_IGNORE(CloseDatabaseSessionL() );
+	iTest->Close();
+	delete iTest;
+	iTest = NULL;
+	iChildThread.Close();
+	}
+	
+/** 
+* The function to empty the database and close the database session.
+*/
+void CMainThread::CloseDatabaseSessionL()
+	{
+		TestDeleteContactL();
+		delete database;
+		database = NULL;
+	}
+
+/**
+* Create the database in shared mode.
+*/
+void CMainThread::TestCreateDatabaseL()
+	{
+	// Creat the database in the first thread.
+    iTest->Next( _L("CreateDatabaseL :Test creating the db in multi - thread mode.") );
+    TRAP_IGNORE(CContactDatabase::DeleteDefaultFileL());
+    database = CContactDatabase::CreateL( CContactDatabase::EMultiThread );
+    t1MachineId = database->MachineId();
+	}
+
+/**
+* Open the database in shared mode.
+*/
+void CMainThread::TestOpenDatabaseL()
+	{
+	// Open the database in the first thread.
+    iTest->Next( _L("OpenDatabaseL :Test Opening the db in multi - thread mode.") );
+    database = CContactDatabase::OpenL( CContactDatabase::EMultiThread );
+    t1MachineId = database->MachineId();
+	}
+
+/**
+* Replace the database in shared mode.
+*/
+void CMainThread::TestReplaceDatabaseL()
+	{
+    // Replace the database in the first thread, in mutithread mode.
+    iTest->Next( _L("ReplaceDatabaseL :Test Replacing the db in multi - thread mode.") );
+    database = CContactDatabase::ReplaceL( CContactDatabase::EMultiThread );
+    t1MachineId = database->MachineId();
+	}
+
+/**
+* Add one contact to the database.
+*/
+void CMainThread::TestAddContactL()
+	{
+    
+    // Add a contact 
+	_LIT(KForename,"Jo"); 
+	_LIT(KSurname,"Stichbury"); 
+
+	// Create a  contact card to contain the data
+	CContactCard* newCard = CContactCard::NewLC();
+    
+	// Create the firstName field and add the data to it
+	CContactItemField* firstName = CContactItemField::NewLC(KStorageTypeText, KUidContactFieldGivenName);
+	firstName->TextStorage()->SetTextL(KForename);
+	newCard->AddFieldL(*firstName);
+  	CleanupStack::Pop(firstName);
+  	
+	// Create the lastName field and add the data to it
+   	CContactItemField* lastName= CContactItemField::NewLC(KStorageTypeText, KUidContactFieldFamilyName);
+  	lastName ->TextStorage()->SetTextL(KSurname);
+  	newCard->AddFieldL(*lastName);
+   	CleanupStack::Pop(lastName);
+   		    
+	// Add newCard to the database
+	iContactId = database->AddNewContactL(*newCard);
+	CleanupStack::PopAndDestroy(newCard);
+	
+	iTest->Printf( _L("Thread1: Added 1 contact to the database."));
+	}
+
+/**
+* Delete the contact from the database.
+*/
+void CMainThread::TestDeleteContactL()
+	{
+	// Check if a contact has been stored in the db and delete it.
+	if (iContactId)
+		{
+		database->DeleteContactL(iContactId);
+		iContactId = 0;
+		}
+	}
+
+/**
+* The main thread controls the child thread
+*/
+void CMainThread::LaunchChildThreadL()
+	{
+	
+    TRAPD(err,iChildThread.Create(KThreadTitle, RunChildThread, KDefaultStackSize, NULL, NULL, EOwnerProcess));
+    
+    if(err != KErrNone)
+		{
+		iTest->Printf(_L("Failed to create the child thread, error code=%d"), err);
+		User::Leave(err);
+		}
+	}
+
+/**
+* Resume the child thread.
+*/	
+
+void CMainThread::ResumeChildThreadL()
+	{
+    iChildThread.Resume();
+	}
+
+
+//
+//                  MAIN FUNCTIONS.
+//
+
+/**
+* The main function which creates the main thread controller object 
+* and invokes all the tests.
+*/
+
+/**
+
+@SYMTestCaseID     PIM-T-CONCURRENT-0001
+
+*/
+
+LOCAL_C void DoTestsL()
+    {
+    
+    // Initialisation
+    MainTest.Start(_L("@SYMTESTCaseID:PIM-T-CONCURRENT-0001 T_Concurrent"));
+
+    
+    // Create active scheduler (to run active objects)
+    CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
+    CleanupStack::PushL(scheduler);
+    CActiveScheduler::Install(scheduler);
+
+    // Create main thread object, child thread and synchnising semaphore.
+    sem.CreateLocal(0);
+    CMainThread * ptr = CMainThread::NewL();
+    CleanupStack::PushL(ptr);
+    ptr->LaunchChildThreadL();
+	
+	// Run all the tests
+	while (currentStep <= ETestsEnd)
+		{
+		switch(currentStep)
+			{
+			case ETestCreate:
+				// create the db in shared mode and add a contact. 
+			    ptr->TestCreateDatabaseL();
+			    ptr->TestAddContactL();
+				break;
+			case ETestOpen:
+			 	// create the db in shared mode 
+			    ptr->TestOpenDatabaseL();
+			    ptr->TestAddContactL();
+				break;
+			case ETestReplace:
+				// create the db in shared mode 
+			    ptr->TestReplaceDatabaseL();
+				ptr->TestAddContactL();
+				break;
+			case ETestsEnd:
+				break;
+			default:
+				break;
+			} // end of switch
+			
+			// Run the child thread and let it access the shared session.
+		    ptr->ResumeChildThreadL();
+		    sem.Wait();
+		    ptr->CloseDatabaseSessionL();
+		    currentStep++ ;
+		} // end of while
+
+    // Cleanup and close.
+    sem.Close();
+    CleanupStack::PopAndDestroy(ptr);
+    CleanupStack::PopAndDestroy(scheduler);
+    }
+
+
+/**
+*  Entry point function.
+*/
+GLDEF_C TInt E32Main()
+    {
+    // Create cleanup stack
+    __UHEAP_MARK;
+    CTrapCleanup* cleanup = CTrapCleanup::New();
+	
+    TRAPD(mainError, DoTestsL());
+    if (mainError)
+        MainTest.Printf(KTextFailed, mainError);
+    
+    MainTest.End();
+    MainTest.Close();
+    delete cleanup;
+    
+    __UHEAP_MARKEND;
+    return KErrNone;
+    }
+
+	
+
+
+
+
+