kerneltest/e32test/pccd/t_medch.cpp
changeset 0 a41df078684a
child 102 ef2a444a7410
child 256 c1f20ce4abcf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/pccd/t_medch.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,372 @@
+// Copyright (c) 1997-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\pccd\t_medch.cpp
+// Continuously generate media changes followesd by a remount of the peripheral bus controller.
+// 
+//
+
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+#include <e32svr.h>
+#include <hal.h>
+#include "d_medch.h"
+
+//#define __SOAK_TEST__				// Define to run until a key is pressed (Automatic tests only)
+//#define __MANUAL_TEST__			// Define to allow manual control of the door/media
+//#define __DEVICE_HAS_NO_DOOR__	// Define for devices that have no door (Manual tests only)
+
+#if defined(__MANUAL_TEST__) && defined(__WINS__)
+#define __DEVICE_HAS_NO_DOOR__
+#endif
+
+#if !defined(__MANUAL_TEST__) && defined(__DEVICE_HAS_NO_DOOR__)
+#undef __DEVICE_HAS_NO_DOOR__
+#endif
+
+#if defined(__MANUAL_TEST__) && defined(__SOAK_TEST__)
+#undef __SOAK_TEST__
+#endif
+
+#ifndef __SOAK_TEST__
+#ifdef __WINS__
+const TInt KMaxTestTime	=  5000000;	// Run the test for 5 seconds on emulator
+#else
+const TInt KMaxTestTime	= 10000000;	// Run the test for 10 seconds on target
+#endif
+#endif
+
+#define MMC_PDD_NAME _L("MEDMMC")
+
+const TInt KPowerUpTimeOut = 5000000; // Give the card 5 seconds to power up
+
+LOCAL_D	RTest test(_L("Media change test"));
+
+LOCAL_D	TBusLocalDrive TheDrive;
+LOCAL_D	RMedCh TheMediaChange;
+LOCAL_D TRequestStatus TheMediaStatus;
+LOCAL_D TBool TheChangedFlag;
+
+
+LOCAL_C TBool SetupDrivesForPlatform(TInt& aDrive, TInt& aSocket)
+/**
+ * Finds a suitable drive for the media change test
+ *
+ * @param aDrive  The number of the local drive to test
+ * @param aSocket The number of the socket to test
+ * @return TBool ETrue if a suitable drive is found, EFalse otherwise.
+ */
+	{
+	
+	TDriveInfoV1Buf diBuf;
+	UserHal::DriveInfo(diBuf);
+	TDriveInfoV1 &di=diBuf();
+
+	aDrive  = -1;
+	aSocket = -1;
+	
+	for(aDrive=0; aDrive < di.iTotalSupportedDrives; aDrive++)
+		{
+		test.Printf(_L(" Drive %d - %S\r\n"), aDrive, &di.iDriveName[aDrive]);
+		if(di.iDriveName[aDrive].MatchF(_L("MultiMediaCard0")) == KErrNone)
+			break;
+		}
+
+	if(aDrive == di.iTotalSupportedDrives)
+		{
+		test.Printf(_L(" MMC Drive Not Found\r\n"));
+		return EFalse;
+		}
+		
+	
+	for(aSocket=0; aSocket < di.iTotalSockets; aSocket++)
+		{
+		test.Printf(_L("Socket %d - %S\r\n"), aSocket, &di.iSocketName[aSocket]);
+		if(di.iSocketName[aSocket].MatchF(_L("MultiMediaCard0")) == KErrNone)
+			break;
+		}
+
+	if(aSocket == di.iTotalSockets)
+		{
+		test.Printf(_L(" MMC Socket Not Found\r\n"));
+		return EFalse;
+		}
+
+	return ETrue;
+	}
+
+LOCAL_C void TestMediaAccess(TInt aExpectedError, TBool aExpectedChange)
+/**
+ * Tests that the drive is accessable (or not) by issuing a request 
+ * to power up the media.  Also verifies that the attributes are correct.
+ * 
+ * @param aExpectedError The expected result of powering up the drive
+ * @param aExpectedChange ETrue if the changed flag is expected to be set
+ *
+ * @return ETrue if successful, EFalse otherwise
+ */
+	{
+	
+	RTimer rto;
+	TInt r = rto.CreateLocal();
+	test(r == KErrNone);
+	
+	TRequestStatus rtoStat;
+	rto.After(rtoStat, KPowerUpTimeOut);
+	test(rtoStat == KRequestPending);
+	
+	if(aExpectedChange)
+		{
+		// TheChangedFlag is set when the door is opened if media was present.
+		// The asynch notifier is signalled when media is removed OR inserted.
+		User::WaitForRequest(TheMediaStatus, rtoStat);
+		test(TheMediaStatus != KRequestPending);
+		}
+
+	// ...aChangedFlag's purpose is to notify us of media removal.
+	test_Equal(aExpectedChange,TheChangedFlag);
+
+	TheDrive.NotifyChange(&TheMediaStatus);
+	TheChangedFlag = EFalse;
+
+	// Attempt to power up the drive
+	TLocalDriveCapsV2Buf info;
+	do
+		{
+		r = TheDrive.Caps(info);
+		}
+	while(r != aExpectedError && rtoStat == KRequestPending);
+
+	rto.Cancel();
+	rto.Close();
+
+	// ...was the error as expected?
+	test(r == aExpectedError);
+
+	// ...and are the caps still OK?
+	if(r == KErrNone)
+		test(info().iType == EMediaHardDisk);
+	else if(r == KErrNotReady)
+		test(info().iType == EMediaNotPresent);
+
+	if(aExpectedChange == EFalse)
+		test(TheMediaStatus == KRequestPending);
+	}
+
+LOCAL_C void NextTest(const TDesC& aTitle, TInt aCycles)
+/**
+ * Simply displays a string on the console and the current iteration.
+ * 
+ * @param aTitle  The text to be displayed
+ * @param aCycles The current iteration
+ */
+	{
+	test.Console()->SetPos(20, 25);
+	test.Printf(_L("%S [%d cycles]"), &aTitle, aCycles);
+#ifdef __MANUAL_TEST__
+	test.Console()->SetPos(20, 27);
+	test.Printf(_L("<press a key>"));
+	test.Getch();
+#endif
+	}
+		
+GLDEF_C TInt E32Main()
+/**
+ * Test Entry Point for T_MEDCH.
+ * 
+ * This test uses the associated driver (D_MEDCH) to simulate media removal and 
+ * door opening/closing.  The media is powered up in each state and verified that 
+ * the correct error code and changed count is returned.
+ */
+    {
+	TBuf<64> b;
+	test.Title();
+
+	/**
+	 * Load the associated media driver (MEDMMC by default).  This is required to ensure 
+	 * that the device can be powered up and the capabilities if the media accessed.
+	 */
+	test.Start(_L("Load Media Driver"));
+	TInt r;
+	r=User::LoadPhysicalDevice(MMC_PDD_NAME);
+	if(r==KErrNotFound)
+		{
+		test.Printf(_L("Test not supported on this platform \n"));
+		test.End();
+		return(0);
+		}
+	test(r==KErrNone || r==KErrAlreadyExists);
+
+	/**
+	 * Connect to the required local drive.
+	 * TheChangedFlag is used for detection of media removal.
+	 */
+	TInt drive;
+	TInt socket;
+	if(SetupDrivesForPlatform(drive, socket))
+		{
+		b.Format(_L("Connect to local drive %d"), drive);
+		test.Next(b);
+		TheDrive.Connect(drive, TheChangedFlag);
+	
+		/**
+		 * Read the drive capabilities to ensure that this test may be run.
+		 */
+		test.Next(_L("Get drive capabilities"));
+		TLocalDriveCapsV2Buf info;
+		r = TheDrive.Caps(info);
+		if(r == KErrNotReady || r == KErrNotSupported)
+			{
+			test.Next(_L("\r\nTest requires media to be present and the door closed - Disconnecting"));
+			TheDrive.Disconnect();		
+			test.End();
+			return KErrNone;
+			}	
+		test(r == KErrNone);
+	
+		test(TheDrive.Caps(info) == KErrNone);
+		test(info().iType == EMediaHardDisk);
+	
+		/**
+		 * Load the media simulation test driver
+		 */
+		test.Next(_L("Load media change logical device"));
+		r=User::LoadLogicalDevice(_L("D_MEDCH"));
+		test(r == KErrNone || r == KErrAlreadyExists);
+	
+		test.Next(_L("Open device"));
+		r=TheMediaChange.Open(socket, TheMediaChange.VersionRequired());
+		if(r == KErrNotSupported)
+			{
+			test.Next(_L("\r\nTest not supported on this drive - Disconnecting"));
+			r=User::FreeLogicalDevice(_L("MedCh"));
+			test(r == KErrNone);
+			TheDrive.Disconnect();
+			test.End();
+			return KErrNone;
+			}	
+		test(r == KErrNone);
+	
+		/**
+		 * Verify that the system supports simulation of media change events
+		 */
+		test.Next(_L("Test support for media change simulation"));
+		r = TheMediaChange.DoorNormal();
+		test(r == KErrNone || r == KErrNotSupported);
+	
+		/**
+		 * Now for the real testing...
+		 */
+		if(r == KErrNone)
+			{
+			/**
+	    	 * Test0 - Simulate 2 consecutive door open interrupts
+			 */
+			test.Next(_L("Test that the pbus can handle 2 consecutive door open interrupts"));
+			TheDrive.NotifyChange(&TheMediaStatus);
+			r = TheMediaChange.DoubleDoorOpen();
+			test(r == KErrNone || r == KErrNotSupported);
+			TestMediaAccess(KErrNone, ETrue);
+		
+
+			TInt cycles=0;
+#if defined(__SOAK_TEST__)
+			TRequestStatus endStat;
+			test.Console()->Read(endStat);
+			while(endStat == KRequestPending)
+#elif !defined(__MANUAL_TEST__)
+			RTimer t;
+			r=t.CreateLocal();
+			test(r == KErrNone);
+			TRequestStatus endStat;
+			t.After(endStat, KMaxTestTime);
+			test(endStat == KRequestPending);
+			while(endStat == KRequestPending)
+#endif
+				{
+				TheChangedFlag = EFalse;
+	
+				TheDrive.NotifyChange(&TheMediaStatus);
+	
+				/**
+	    		 * Test1 - Simulate door open
+				 *		 - Power up responds with KErrNotReady
+				 */
+				NextTest(_L("Open Door......"), cycles);
+#ifndef __MANUAL_TEST__
+				test(TheMediaChange.DoorOpen() == KErrNone);
+#endif
+				TestMediaAccess(KErrNotReady, ETrue);
+				TheDrive.NotifyChange(&TheMediaStatus);
+	
+				/**
+	    		 * Test2 - Simulate door closed (with media removed)
+				 *		 - Power up responds with KErrNotReady
+				 */
+#ifndef __DEVICE_HAS_NO_DOOR__
+	    		NextTest(_L("Remove Media..."), cycles);
+#ifndef __MANUAL_TEST__
+				test(TheMediaChange.DoorClose(EFalse) == KErrNone);		
+#endif
+				TestMediaAccess(KErrNotReady, EFalse);					
+				/**
+	    		 * Test3 - Simulate door open
+				 *		 - Power up responds with KErrNotReady
+				 */
+				NextTest(_L("Open Door......"), cycles);
+#ifndef __MANUAL_TEST__
+				test(TheMediaChange.DoorOpen() == KErrNone);			
+#endif
+				TestMediaAccess(KErrNotReady, EFalse);				// Power up responds with KErrNotReady
+#endif
+				/**
+	    		 * Test4 - Simulate door closed (with media present)
+				 *		 - Power up responds with KErrNone
+				 */
+	    		NextTest(_L("Insert Media..."), cycles);
+#ifndef __MANUAL_TEST__
+				test(TheMediaChange.DoorClose(ETrue) == KErrNone);
+#endif
+				TestMediaAccess(KErrNone, ETrue);
+				++cycles;
+				}
+	
+			test.Console()->SetPos(0, 27);
+#if !defined(__SOAK_TEST__) && !defined(__MANUAL_TEST__)
+			t.Close();
+#endif
+			}
+		else if(r == KErrNotSupported)
+			{
+			test.Printf(_L("Media change simulation not supported"));
+			}
+	
+		/**
+		 * Tidy up and exit
+		 */
+		test.Next(_L("\r\nClose device"));
+		TheMediaChange.Close();
+	
+		test.Next(_L("Free device"));
+		r=User::FreeLogicalDevice(_L("MedCh"));
+		test(r == KErrNone);
+	
+		b.Format(_L("\r\nDisconnect from local drive %d "), drive);
+		test.Next(b);
+		TheDrive.Disconnect();
+		}
+
+	test.End();
+	return(0);
+	}
+