kerneltest/e32test/property/t_stress_property.cpp
changeset 0 a41df078684a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/property/t_stress_property.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,262 @@
+// Copyright (c) 2002-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:
+//
+
+#include <e32test.h>
+#include "t_property.h"
+
+_LIT(KTestName,"t_stress_property");
+
+RTest test(KTestName);
+
+const TInt32 KUidPropTestCategoryValue = 0x101f75b8;
+const TUid KPropTestCategory = { KUidPropTestCategoryValue };
+
+#define TEST_TIME 36000			//10 hours
+
+#define TEST_ERROR(rl,rr) { if((TInt)rl!=(TInt)rr) { ExitThread(rl, rr, __LINE__); return KErrGeneral; } }
+
+TBool volatile StopAndExit = EFalse;
+TTime startTime;
+
+LOCAL_D void ExitThread(TInt rl, TInt rr, TInt aLine)
+	{
+	test.Printf(_L("Test '%S' failed at line %d; Expected value=%d Actual value=%d; \n"), &KTestName, aLine, rr, rl);
+	StopAndExit = ETrue;
+	//delete if it's not deleted, to wake up subscribing threads waiting for events on this property
+	RProperty::Delete(KPropTestCategory,0);
+	}
+
+LOCAL_D TInt LowPriorityThread1(TAny* /*aParameter*/)
+	{
+	RProperty prop;
+	TBuf8<512> buffer;
+	TInt length = 2;
+
+	TInt r=prop.Attach(KPropTestCategory,0);
+	TEST_ERROR(r,KErrNone);
+
+	while(!StopAndExit)
+		{
+		buffer.SetLength(length);
+		buffer[0]=(TUint8)(length%256);
+		buffer[length-1]=(TUint8)((length-1)%256);
+		++length;
+		if(length>512)
+			length=2;
+		r=prop.Set(buffer);
+		if(r!=KErrArgument && r!=KErrNotFound)
+			{
+			//if it's not of type EInt and defined
+			TEST_ERROR(r,KErrNone);
+			}
+		User::AfterHighRes(0);
+		}
+
+	return KErrNone;
+	}
+
+LOCAL_D TInt LowPriorityThread2(TAny* /*aParameter*/)
+	{
+	RProperty prop;
+	TBuf8<512> buffer;
+
+	TInt r=prop.Attach(KPropTestCategory,0);
+	TEST_ERROR(r,KErrNone);
+
+	while(!StopAndExit)
+		{
+		r=prop.Get(buffer);
+		if(r!=KErrArgument && r!=KErrNotFound)
+			{
+			//if it's not of type EInt and defined
+			TEST_ERROR(r,KErrNone);
+			TInt length=buffer.Length();
+			if(length>0)
+				{
+				TEST_ERROR(buffer[0],length%256);
+				TEST_ERROR(buffer[length-1],(length-1)%256);
+				}
+			}
+		}
+	return KErrNone;
+	}
+
+LOCAL_D TInt MediumPriorityThread(TAny* /*aParameter*/)
+	{
+	RProperty prop;
+	TBuf8<512> buffer;
+
+	TInt r=prop.Attach(KPropTestCategory,0);
+	TEST_ERROR(r,KErrNone);
+
+	TRequestStatus status;
+	
+	while(!StopAndExit)
+		{
+		prop.Subscribe(status);
+
+		User::WaitForRequest(status);
+		if(StopAndExit)
+			break;
+		if(status.Int() != KErrNotFound)
+			{
+			//property is defined
+			TEST_ERROR(status.Int(),KErrNone);
+
+			r=prop.Get(buffer);
+			if(r!=KErrArgument)
+				{
+				TEST_ERROR(r,KErrNone);
+				TInt length=buffer.Length();
+				if(length>0)
+					{
+					TEST_ERROR(buffer[0],length%256);
+					TEST_ERROR(buffer[length-1],(length-1)%256);
+					}
+				}
+			}
+		}
+
+	return KErrNone;
+	}
+
+LOCAL_D TInt HighPriorityThread(TAny* /*aParameter*/)
+	{
+
+	TInt type=RProperty::EInt;
+	TInt iteration=0;
+	TInt r;
+
+	while(!StopAndExit)
+		{
+		User::AfterHighRes(1000); //wait for 1ms
+		
+//		test.Printf(_L("Deleting property\r\n"));
+		r=RProperty::Delete(KPropTestCategory,0);
+		TEST_ERROR(r,KErrNone);
+
+//		test.Printf(_L("Defining property\r\n"));
+		r=RProperty::Define(KPropTestCategory,0,type, KPassPolicy, KPassPolicy);
+		TEST_ERROR(r,KErrNone);
+
+		type=(type+1)%RProperty::ETypeLimit;
+
+		if(1000 == ++iteration)
+			{
+			//check if we should exit
+			TTimeIntervalSeconds timeTaken;
+			TTime time;
+			time.HomeTime();
+			TInt r = time.SecondsFrom(startTime, timeTaken);
+			TEST_ERROR(r,KErrNone);
+
+			if(timeTaken.Int() >= TEST_TIME)
+				{
+				//we should exit
+
+				StopAndExit=ETrue;
+				//delete if it's not deleted, to wake up subscribing threads waiting for events on this property
+				RProperty::Delete(KPropTestCategory,0);
+				break;
+				}
+			iteration=0;
+			}
+		}
+	return KErrNone;
+	}
+
+
+
+GLDEF_C TInt E32Main()
+	{
+
+	test.Start(_L("Stress test using multiple threads accessing the same property"));
+
+    startTime.HomeTime();
+	TInt r=RProperty::Define(KPropTestCategory,0,RProperty::EInt, KPassPolicy, KPassPolicy);
+	test(r==KErrNone);
+
+	TRequestStatus status1;
+	TRequestStatus status2;
+	TRequestStatus status3;
+	TRequestStatus status4;
+	RThread t1;
+	RThread t2;
+	RThread t3;
+	RThread t4;
+
+	r = t1.Create(KNullDesC, LowPriorityThread1, 0x2000, NULL, 0);
+	test(r == KErrNone);
+	t1.SetPriority(EPriorityLess);
+	t1.Logon(status1);
+
+	r = t2.Create(KNullDesC, LowPriorityThread2, 0x2000, NULL, 0);
+	test(r == KErrNone);
+	t2.SetPriority(EPriorityLess);
+	t2.Logon(status2);
+
+	r = t3.Create(KNullDesC, MediumPriorityThread, 0x2000, NULL, 0);
+	test(r == KErrNone);
+	t3.SetPriority(EPriorityNormal);
+	t3.Logon(status3);
+	
+	r = t4.Create(KNullDesC, HighPriorityThread, 0x2000, NULL, 0);
+	test(r == KErrNone);
+	t4.SetPriority(EPriorityMore);
+	t4.Logon(status4);
+	
+	TBool jit = User::JustInTime();
+	User::SetJustInTime(EFalse);
+
+	t1.Resume();
+	t2.Resume();
+	t3.Resume();
+	t4.Resume();
+
+	User::WaitForRequest(status1);
+	User::WaitForRequest(status2);
+	User::WaitForRequest(status3);
+	User::WaitForRequest(status4);
+
+	User::SetJustInTime(jit);
+
+	test(status1 == KErrNone);
+	test(status2 == KErrNone);
+	test(status3 == KErrNone);
+	test(status4 == KErrNone);
+
+	TTimeIntervalSeconds timeTaken;
+	TTime time;
+	time.HomeTime();
+	r = time.SecondsFrom(startTime, timeTaken);
+	test(r==KErrNone);
+	TInt totalTime = timeTaken.Int();
+	
+	TInt seconds = totalTime % 60;
+    TInt minutes = (totalTime / 60) % 60;
+    TInt hours   = totalTime / 3600;
+
+    test.Printf(_L("Time taken since test started: %d:%d:%d\r\n"), 
+                   hours, minutes, seconds);
+
+	CLOSE_AND_WAIT(t1);
+	CLOSE_AND_WAIT(t2);
+	CLOSE_AND_WAIT(t3);
+	CLOSE_AND_WAIT(t4);
+
+	test.End();
+
+	return KErrNone;
+	}