kerneltest/e32test/system/t_dobject.cpp
changeset 0 a41df078684a
child 8 538db54a451d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/system/t_dobject.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,498 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "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:
+// e32test\system\t_dobject.cpp
+// Overview:
+// Test RObjectIx strategy of memory reallocation and 
+// free list maintenance.
+// Test DObjectCon findhandle methods
+// API Information:
+// DObject, RObjectIx
+// Details:
+// - Add a number of DObjects to RObjectIx, then remove them 
+// in the same order. Verify results are as expected. Time
+// how long the process takes to complete.
+// - Add a number of DObjects to RObjectIx, then remove them
+// in the reverse order. Verify results are as expected. Time
+// how long the process takes to complete.
+// - Add and remove a random number of DObjects to/from RObjectIx.
+// Time how long the process takes to complete.
+// Platforms/Drives/Compatibility:
+// All.
+// Assumptions/Requirement/Pre-requisites:
+// Failures and causes:
+// Base Port information:
+// 
+//
+
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+#include <e32math.h>
+#include "d_dobject.h"
+
+LOCAL_D RTest test(_L("T_DOBJECT"));
+
+TInt TestRObjectIxAccess(TAny* aRObjectIxPtr)
+	{
+	const TInt  KConcurrentDObjectTestRepeats = 1;
+	
+	RTestDObject  ldd;
+	TInt  ret;
+	
+	ret = ldd.Open();
+	if (ret == KErrNone)
+		{
+		for (TInt  repeat = 0;  repeat < KConcurrentDObjectTestRepeats;  repeat++)
+			{
+			ret = ldd.RObjectIxThreadTestExerciseIx(aRObjectIxPtr);
+			if (ret != KErrNone)
+				{
+				break;
+				}
+			}
+		ldd.Close();
+		}
+	
+	return ret;
+	} // TestRObjectIxAccess
+
+void TestConcurrentRObjectIxAccess(RTestDObject& aLdd)
+	{
+	const TInt  KConcurrentDObjectThreads = 4;
+	_LIT(KConcurrentDObjectThreadName, "T_DObject_Thread");
+	
+	TInt ret;
+	
+	//
+	// Create a RObjectIx in the driver (pointer not valid user side!)...
+	//
+	void*  objectIxPtr = NULL;
+	
+	ret = aLdd.RObjectIxThreadTestCreateIx(objectIxPtr);
+	test_KErrNone(ret);
+	
+	//
+	// Run KConcurrentDObjectThreads number of threads which random add/remove
+	// DObjects to the same RObjectIx...
+	//
+	RThread  threadHandle[KConcurrentDObjectThreads];
+	TRequestStatus  status[KConcurrentDObjectThreads];
+	TBuf<32>  threadName;
+	TInt  thread;
+
+	for (thread = 0;  thread < KConcurrentDObjectThreads;  thread++)
+		{
+		threadName.Copy(KConcurrentDObjectThreadName);
+		threadName.AppendNum(thread);
+		
+		ret = threadHandle[thread].Create(threadName, TestRObjectIxAccess, KDefaultStackSize, NULL, objectIxPtr);
+		test_KErrNone(ret);
+
+		threadHandle[thread].Logon(status[thread]);
+		}
+
+	//
+	// The test thread must be higher priority to ensure all the threads start.
+	// All the threads are then resumed and allowed to run to completion...
+	//
+	RThread().SetPriority(EPriorityMore);
+
+	for (thread = 0;  thread < KConcurrentDObjectThreads;  thread++)
+		{
+		threadHandle[thread].Resume();
+		}
+
+	for (thread = 0;  thread < KConcurrentDObjectThreads;  thread++)
+		{
+		User::WaitForRequest(status[thread]);
+		test_KErrNone(status[thread].Int());
+		CLOSE_AND_WAIT(threadHandle[thread]);
+		}
+	
+	RThread().SetPriority(EPriorityNormal);
+
+	//
+	// Free the RObjectIx in the driver...
+	//
+	ret = aLdd.RObjectIxThreadTestFreeIx(objectIxPtr);
+	test_KErrNone(ret);
+	} // TestConcurrentRObjectIxAccess
+
+
+void ListAllMutexes()
+	{
+	test.Printf(_L("Mutexes:\n"));
+	TFullName name;
+	TFindMutex find;
+	while (find.Next(name) == KErrNone)
+		{
+		test.Printf(_L("  %S (find handle == %08x)\n"), &name, find.Handle());
+		}
+	}
+
+const TInt KObjectCount = 20;
+_LIT(KDoubleMatch, "*double*");
+_LIT(KTrippleMatch, "*tripple*");
+
+RMutex Mutexes[KObjectCount];
+TBuf<32> ObjectName;
+
+const TDesC& MutexName(TInt i)
+	{
+	ObjectName.Zero();
+	ObjectName.AppendFormat(_L("Mutex_%02d"), i);
+	if (i % 2 == 0)
+		ObjectName.Append(_L("_double"));
+	if (i % 3 == 0)
+		ObjectName.Append(_L("_tripple"));
+	return ObjectName;
+	}
+
+void CreateMutexes()
+	{
+	for (TInt i = 0 ; i < KObjectCount ; ++i)
+		{
+		test(Mutexes[i].CreateGlobal(MutexName(i)) == KErrNone);
+		}
+	}
+
+void DeleteMutexes()
+	{
+	for (TInt i = 0 ; i < KObjectCount ; ++i)
+		{
+		Mutexes[i].Close();
+		}
+	}
+
+void TestMutexesCreated()
+	{
+	test.Next(_L("Test mutexes have been created"));
+	
+	TFullName name;
+	TFindMutex find;
+	for (TInt i = 0 ; i < KObjectCount ; ++i)
+		{
+		test(find.Next(name) == KErrNone);
+		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
+		test(name == MutexName(i));
+		}
+	test(find.Next(name) == KErrNotFound);
+	}
+
+void TestMutexesDeleted()
+	{
+	test.Next(_L("Test mutexes deleted"));
+
+	TFindMutex find;
+	TFullName name;
+	test(find.Next(name) == KErrNotFound);
+	}
+
+void TestFindSpecificMutex()
+	{
+	test.Next(_L("Test finding specific mutexes"));
+	
+	for (TInt i = 0 ; i < KObjectCount ; ++i)
+		{
+		TFullName name;
+		TFindMutex find(MutexName(i));
+		test(find.Next(name) == KErrNone);
+		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
+		test(name == MutexName(i));
+		RMutex mutex;
+		test(mutex.Open(find) == KErrNone);
+		test(mutex.Name() == MutexName(i));
+		mutex.Close();
+		test(find.Next(name) == KErrNotFound);
+		}	
+	}
+
+void TestFindMutexGroups()
+	{
+	test.Next(_L("Test finding groups of mutexes using wildcard name matching"));
+
+	TFullName name;
+	TInt i;
+	
+	TFindMutex find2(KDoubleMatch);
+	for (i = 0 ; i < KObjectCount ; i += 2)
+		{
+		test(find2.Next(name) == KErrNone);
+		test.Printf(_L("  %02d: found handle %08x\n"), i, find2.Handle());
+		test(name == MutexName(i));
+		}
+	test(find2.Next(name) == KErrNotFound);
+
+	TFindMutex find3(KTrippleMatch);
+	for (i = 0 ; i < KObjectCount ; i += 3)
+		{
+		test(find3.Next(name) == KErrNone);
+		test.Printf(_L("  %02d: found handle %08x\n"), i, find3.Handle());
+		test(name == MutexName(i));
+		}
+	test(find3.Next(name) == KErrNotFound);
+	}
+
+void TestMatchChange()
+	{
+	test.Next(_L("Test changing match half way through find"));
+
+
+	TFullName name;
+	TInt i;
+	
+	TFindMutex find(KDoubleMatch);
+	for (i = 0 ; i < KObjectCount/2 ; i += 2)
+		{
+		test(find.Next(name) == KErrNone);
+		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
+		test(name == MutexName(i));
+		}
+
+	find.Find(KTrippleMatch);
+	for (i = 0 ; i < KObjectCount ; i += 3)
+		{
+		test(find.Next(name) == KErrNone);
+		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
+		test(name == MutexName(i));
+		}
+	test(find.Next(name) == KErrNotFound);
+	}
+
+void TestFindAndDeleteMutex1()
+	{
+	test.Next(_L("Test finding mutexes when the last found object has been deleted"));
+
+	// Find and delete even mutexes
+	TFullName name;
+	TFindMutex find2(KDoubleMatch);
+	TInt i;
+	for (i = 0 ; i < KObjectCount ; i += 2)
+		{
+		test(find2.Next(name) == KErrNone);
+		test.Printf(_L("  %02d: found handle %08x\n"), i, find2.Handle());
+		test(name == MutexName(i));
+		Mutexes[i].Close();
+		RMutex mutex;
+		test(mutex.Open(find2) == KErrNotFound);
+		}
+	test(find2.Next(name) == KErrNotFound);
+
+	// Check odd mutexes remaining
+	TFindMutex find;
+	for (i = 1 ; i < KObjectCount ; i += 2)
+		{
+		test(find.Next(name) == KErrNone);
+		test(name == MutexName(i));
+		}
+	test(find2.Next(name) == KErrNotFound);
+	}
+
+void TestFindAndDeleteMutex2()
+	{
+	test.Next(_L("Test finding mutexes when the last found object has moved in the container"));
+
+	// Find even mutexes and delete odd
+	TFullName name;
+	TFindMutex find2(KDoubleMatch);
+	TInt i;
+	for (i = 0 ; i < KObjectCount ; i += 2)
+		{
+		test(find2.Next(name) == KErrNone);
+		test.Printf(_L("  %02d: found handle %08x\n"), i, find2.Handle());
+		test(name == MutexName(i));
+		Mutexes[(i+KObjectCount-1)%KObjectCount].Close();	// -1%n = -1 or n-1, unspecified
+		RMutex mutex;
+		test(mutex.Open(find2) == KErrNone);
+		test(mutex.Name() == MutexName(i));
+		mutex.Close();
+		}
+	test(find2.Next(name) == KErrNotFound);
+
+	// Check even mutexes remaining
+	TFindMutex find;
+	for (i = 0 ; i < KObjectCount ; i += 2)
+		{
+		test(find.Next(name) == KErrNone);
+		test(name == MutexName(i));
+		}
+	test(find2.Next(name) == KErrNotFound);
+	}
+
+void TestFindWithCreation()
+	{
+	test.Next(_L("Test finding mutexes interleaved with creation"));
+
+	TFullName name;
+	TFindMutex find;
+	
+	for (TInt i = 0 ; i < KObjectCount ; ++i)
+		{
+		test(Mutexes[i].CreateGlobal(MutexName(i)) == KErrNone);
+		test(find.Next(name) == KErrNone);
+		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
+		test(name == MutexName(i));
+		RMutex mutex;
+		test(mutex.Open(find) == KErrNone);
+		test(mutex.Name() == MutexName(i));
+		mutex.Close();
+		}
+	test(find.Next(name) == KErrNotFound);
+	}
+
+void TestFindWithCreation2()
+	{
+	test.Next(_L("Test finding mutexes interleaved with creation and deletion"));
+
+	TFullName name;
+	TFindMutex find;
+
+	for (TInt i = 0 ; i < KObjectCount ; ++i)
+		{
+		RMutex mutex;
+		test(mutex.CreateGlobal(MutexName(0)) == KErrNone);
+		test(find.Next(name) == KErrNone);
+		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
+		test(name == MutexName(0));
+		mutex.Close();
+		RMutex mutex2;
+		test(mutex2.Open(find) == KErrNotFound);
+		}
+	test(find.Next(name) == KErrNotFound);
+	}
+
+void TestFindHandleOutOfRange()
+	{
+	test.Next(_L("Test finding mutexes when find handle index is off the end of container's array"));
+
+	TFullName name;
+	TFindMutex find;
+	for (TInt i = 0 ; i < KObjectCount ; ++i)
+		{
+		test(find.Next(name) == KErrNone);
+		test.Printf(_L("  %02d: found handle %08x\n"), i, find.Handle());
+		test(name == MutexName(i));
+		RMutex mutex;
+		test(mutex.Open(find) == KErrNone);
+		test(mutex.Name() == MutexName(i));
+		mutex.Close();
+
+		// towards the end, suddenly delete half the mutexes
+		if (i == (3 * KObjectCount) / 4)
+			{
+			for (TInt j = 0 ; j < KObjectCount / 2 ; ++j)
+				Mutexes[j].Close();
+			}
+		}
+	test(find.Next(name) == KErrNotFound);
+	}
+
+void TestFindHandles()
+	{
+	test.Start(_L("Test FindHandle APIs using mutex classes"));
+
+	CreateMutexes();
+	ListAllMutexes();
+	TestMutexesCreated();
+	TestFindSpecificMutex();
+	TestFindMutexGroups();
+	TestMatchChange();
+	DeleteMutexes();
+	TestMutexesDeleted();
+
+	CreateMutexes();
+	TestFindAndDeleteMutex1();
+	DeleteMutexes();
+
+	CreateMutexes();
+	TestFindHandleOutOfRange();
+	DeleteMutexes();
+	
+	CreateMutexes();
+	TestFindAndDeleteMutex2();
+	DeleteMutexes();
+
+	TestFindWithCreation();
+	DeleteMutexes();
+
+	TestFindWithCreation2();
+	TestMutexesDeleted();
+	
+	test.End();
+	}
+
+GLDEF_C TInt E32Main()
+    {
+	SParam param;
+	TInt duration, r;
+	RTestDObject ldd;
+
+	test.Title();
+
+	test.Start(_L("Loading test driver..."));
+
+	r=User::LoadLogicalDevice(KDObjectTestLddName);
+	test(r==KErrNone || r==KErrAlreadyExists);
+	r=ldd.Open();
+	test(r==KErrNone);
+
+	test.Next(_L("RObjectIxTest1 test ..."));
+	r=ldd.RObjectIxTest1(duration);
+	test(KErrNone==r);
+	test.Printf(_L("... completed in %d kernel ticks\n") , duration);
+
+	test.Next(_L("RObjectIxTest2 test ..."));
+	r=ldd.RObjectIxTest2(duration);
+	test(KErrNone==r);
+	test.Printf(_L("... completed in %d kernel ticks\n") , duration);
+
+	test.Next(_L("RObjectIxTest3 test (performance) ..."));
+	param.iSeed[0] = 0;
+	param.iSeed[1] = 1;
+	param.iPerformanceTest = ETrue;
+	r=ldd.RObjectIxTest3(param);
+	test(KErrNone==r);
+	test.Printf(_L("... completed in %d kernel ticks\n") , param.duration);
+
+	test.Next(_L("RObjectIxTest3 test (random)..."));
+	param.iSeed[0]=User::TickCount();
+	param.iSeed[1]=User::TickCount();
+	param.iPerformanceTest = EFalse;
+	test.Printf(_L("... seeds=%xh and %xh ..."),param.iSeed[0],param.iSeed[1]);
+	r=ldd.RObjectIxTest3(param);
+	test(KErrNone==r);
+	test.Printf(_L("... completed in %d kernel ticks\n") , param.duration);
+ 
+	test.Next(_L("RObjectIxTest4 test (reserved slots)..."));
+	test_KErrNone(ldd.RObjectIxTest4(duration));
+	test.Printf(_L("... completed in %d kernel ticks\n") , duration);
+
+	test.Next(_L("Test Concurrent access to RObjectIx"));
+	TestConcurrentRObjectIxAccess(ldd);
+
+	test.Next(_L("Test Invalid handle look up"));
+ 	test_KErrNone(ldd.InvalidHandleLookupTest());
+
+ 	test.Next(_L("Test Kern::ValidateName and Kern::ValidateFullName"));
+ 	test_KErrNone(ldd.DObjectNameTest());
+ 
+	test.Next(_L("Closing test driver"));
+	ldd.Close();
+
+	test.Next(_L("FindHandles test"));
+	TestFindHandles();
+	
+	test.End();
+
+	return(0);
+	}