kerneltest/e32test/bench/t_proc1.cpp
author Tom Cosgrove <tom.cosgrove@nokia.com>
Fri, 28 May 2010 16:26:05 +0100
branchRCL_3
changeset 29 743008598095
parent 0 a41df078684a
permissions -rw-r--r--
Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h) Have multiple extension sections in the bld.inf, one for each version of the compiler. The RVCT version building the tools will build the runtime libraries for its version, but make sure we extract all the other versions from zip archives. Also add the archive for RVCT4.

// Copyright (c) 1996-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\bench\t_proc1.cpp
// One half of the process relative type test stuff
// Overview:
// Tests the RProcess class, including tests on the heap, process naming, 
// process resumption, process creation and shared chunks. 
// API Information:
// RProcess
// Details:
// - Open a nonexistent process by a process Id and checks for the failure 
// of finding this process.
// - Open a process with invalid name and verify failure results are as expected.
// - Test the closing of processes by calling Kill, Terminate, and Panic methods.
// Verify results are as expected.
// - Create a process and verify the full path name of the loaded executable on 
// which this process is based.
// - Open a process by name, rename the process in a variety of ways and verify 
// the results are as expected.
// - Open a process, assign high, low, and bad priorities, verify the results
// are as expected.
// - Open a process, kill it and verify the results are as expected.
// - Open a process by name based on the file name, verify the results are as 
// expected.
// - Retrieve the process Id and open a handle on it. Create a duplicate process.
// Verify the results are as expected.
// - Find a process using TFindProcess() and open a handle on it. Verify the
// results are as expected.
// - Check chunk sharing between threads and verify results are as expected.
// - Perform a "speed" test where a new thread is created and the thread increments
// a count until stopped. Calculate and display counts per second. Verify results
// are as expected.
// - Verify the ExitReason, ExitType and ExitCatagory when the thread dies.
// - Verify that stopping the process completes existing pending requests with 
// KErrServerTerminated.
// - Verify that the heap was not corrupted by the tests.
// Platforms/Drives/Compatibility:
// All.
// Assumptions/Requirement/Pre-requisites:
// Failures and causes:
// Base Port information:
// 
//

#include <e32test.h>
#include "../mmu/mmudetect.h"
#include "t_proc.h"

LOCAL_D RTest test(_L("T_PROC1"));

const TBufC<67> tooLong=_L("This should return KErrBadName and not crash.......0123456789ABCDEF");
const TBufC<66> notQuiteTooLong=_L("This should return KErrNone and be completely OK..0123456789ABCDEF");
const TBufC<26> bond=_L("Bond, James Bond[00000000]");
const TBufC<16> jamesBond=_L("Bond, James Bond");

RProcess proc;
RProcess proc2;
RProcess proc3;
RProcess proc4;

TName command;
TRequestStatus stat,notStat;

const TInt KKillReason=2563453;
const TInt KTerminateReason=8034255;
const TInt KPanicReason=39365235;

LOCAL_D RSemaphore client;
LOCAL_D TInt speedCount;

class RDisplay : public RSessionBase
	{
public:
	TInt Open();
	TInt Display(const TDesC& aMessage);
	TInt Read();
	TInt Write();
	TInt Stop();
	TInt Test();
	TVersion Version();
	};

TInt RDisplay::Open()
//
// Open the server.
//
	{

	return(CreateSession(_L("Display"),Version(),1));
	}

TInt RDisplay::Display(const TDesC& aMessage)
//
// Display a message.
//
	{

	TBuf<0x10> b(aMessage);
	return(SendReceive(CMyServer::EDisplay,TIpcArgs(&b)));
	}

TInt RDisplay::Read()
//
// Get session to test CSession2::ReadL.
//
	{

	TBuf<0x10> b(_L("Testing read"));
	return(SendReceive(CMyServer::ERead,TIpcArgs(&b)));
	}

TInt RDisplay::Write()
//
// Get session to test CSession2::WriteL.
//
	{

	TBuf<0x10> b;
    TBufC<0x10> c; // Bad descriptor - read only
	TInt r=SendReceive(CMyServer::EWrite,TIpcArgs(&b,&c));
	if (r==KErrNone && b!=_L("It worked!"))
		r=KErrGeneral;
	return r;
	}

TInt RDisplay::Test()
//
// Send a message and wait for completion.
//
	{

	TInt i[4];
	return(SendReceive(CMyServer::ETest,TIpcArgs(&i[0])));
	}

TInt RDisplay::Stop()
//
// Stop the server.
//
	{

	TInt i[4];
	return(SendReceive(CMyServer::EStop,TIpcArgs(&i[0])));
	}

TVersion RDisplay::Version()
//
// Return the current version.
//
	{

	TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
	return(v);
	}

LOCAL_C TInt RunPanicThread(RThread& aThread)
	{
	TRequestStatus s;
	aThread.Logon(s);
	TBool jit = User::JustInTime();
	User::SetJustInTime(EFalse);
	aThread.Resume();
	User::WaitForRequest(s);
	User::SetJustInTime(jit);
	return s.Int();
	}

TInt KillProtectedEntry(TAny*)
	{
	proc.Kill(KErrGeneral);
	return KErrGeneral;
	}

TInt createProc2(RProcess& aProcess)
	{
	TFileName filename(RProcess().FileName());
	TInt pos=filename.LocateReverse(TChar('\\'));
	filename.SetLength(pos+1);
	filename+=_L("T_PROC2.EXE");
	TInt r=aProcess.Create(filename, command);
	if (r==KErrNone)
		{
		TFullName fn(aProcess.FullName());
		test.Printf(_L("Created %S\n"),&fn);
		}
	return r;
	}

void simpleTests1()
	{
	test.Next(_L("Open by name"));
	RProcess me;
	TInt r=proc2.Open(me.Name());
	test(r==KErrNone);
	test.Next(_L("Rename"));
	TName initName(me.Name());
	r=User::RenameProcess(jamesBond);
	test(r==KErrNone);
	test(me.Name().Left(26)==bond);
	test(proc2.Name().Left(26)==bond);
	r=User::RenameProcess(tooLong);
	test(r==KErrBadName);
	test(me.Name().Left(26)==bond);
	test(proc2.Name().Left(26)==bond);
	TName* work=new TName(notQuiteTooLong);
	r=User::RenameProcess(*work);
	test(r==KErrNone);
	work->Append(_L("[00000000]"));
	test(me.Name().Length()==KMaxKernelName);
	test(me.Name().Left(KMaxKernelName-4)==*work);
	test(proc2.Name().Length()==KMaxKernelName);
	test(proc2.Name().Left(KMaxKernelName-4)==*work);
	delete work;
	r=User::RenameProcess(_L("T_PROC1"));
	test(r==KErrNone);
	TFullName fn(_L("T_PROC1["));
	TUidType uidType(me.Type());
	TUint32 uid3 = uidType[2].iUid;
	fn.AppendNumFixedWidth(uid3,EHex,8);
	fn.Append(']');
	test(proc2.Name().Left(17)==fn);
	test(me.Name().Left(17)==fn);
	TInt l = initName.Locate('[');
	r=User::RenameProcess(initName.Left(l));
	test(r==KErrNone);
	test(proc2.Name()==initName);
	proc2.Close();
	}

TInt BadPriority(TAny* proc2)
	{
	((RProcess*)proc2)->SetPriority(EPriorityWindowServer);
	return KErrNone; 
	}

void simpleTests2()
	{
	TInt r=proc2.Open(proc.Name());
	test.Next(_L("Mess with Priority"));
	proc.SetPriority(EPriorityHigh);
	test.Printf(_L("%d %d\n"),proc.Priority(),proc2.Priority());
	test(proc.Priority()==EPriorityHigh);
	test(proc2.Priority()==EPriorityHigh);
	proc2.SetPriority(EPriorityLow);
	test(proc.Priority()==EPriorityLow);
	test(proc2.Priority()==EPriorityLow);

	RThread thread;
	r=thread.Create(_L("Bad Priority"),BadPriority,KDefaultStackSize,NULL,&proc2);
	test(r==KErrNone);
	r=RunPanicThread(thread);
	test(r==EBadPriority);
	test(thread.ExitType()==EExitPanic);
	test(thread.ExitReason()==EBadPriority);
	test(thread.ExitCategory()==_L("KERN-EXEC"));
	CLOSE_AND_WAIT(thread);
	test(proc.Priority()==EPriorityLow);
	test(proc2.Priority()==EPriorityLow);
	proc2.Close();
	}

void procTests1()
	{
	test.Next(_L("Test functions"));
    TFileName fileName(proc.FileName());
    test.Printf(fileName);
#ifndef __WINS__
	if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
		test(fileName.Mid(1).CompareF(_L(":\\Sys\\Bin\\T_PROC2.EXE"))==0);
	else
		test(fileName.Mid(1).CompareF(_L(":\\System\\Bin\\T_PROC2.EXE"))==0);
#else
	if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
		test(fileName.CompareF(_L("Z:\\Sys\\Bin\\T_PROC2.EXE"))==0);
	else
		test(fileName.CompareF(_L("Z:\\System\\Bin\\T_PROC2.EXE"))==0);
#endif
	test(proc.Name().Left(21).CompareF(_L("T_PROC2.EXE[00000000]"))==0);
	test(proc.Priority()==EPriorityForeground);
	test(proc.ExitType()==EExitPending);
	test(proc.ExitReason()==0);
	test(proc.ExitCategory()==KNullDesC);
	}

void procTests2()
	{
	test.Next(_L("Kill and recreate"));
	RProcess proc2;
	TInt r=proc2.Open(proc.Id());
	test(r==KErrNone);
	test(proc2.Handle()!=0);
	proc.Logon(stat);
	proc.Logon(notStat);
	r=proc.LogonCancel(notStat);
	test(r==KErrNone);
	test(notStat==KErrNone);
	proc.Kill(KKillReason);
	User::WaitForRequest(stat);
	test(stat==KKillReason);
	test(proc.ExitType()==EExitKill);
	test(proc.ExitReason()==KKillReason);
	test(proc.ExitCategory()==_L("Kill"));
	proc.Close();
	test(proc.Handle()==0);
	test(proc2.ExitType()==EExitKill);
	test(proc2.ExitReason()==KKillReason);
	test(proc2.ExitCategory()==_L("Kill"));
	CLOSE_AND_WAIT(proc2);
	test(proc2.Handle()==0);
	}

void procTests3()
	{
	TFileName filename(RProcess().FileName());
	TInt pos=filename.LocateReverse(TChar('\\'));
	filename.SetLength(pos+1);
	filename+=_L("T_PROC2.EXE");
	TInt r=proc.Create(filename, command);
	test(r==KErrNone);
	TFullName fn(proc.FullName());
	test.Printf(_L("Created %S\n"),&fn);
	test(proc.FileName().CompareF(filename)==0);
	test(proc.Name().Left(21).CompareF(_L("T_PROC2.EXE[00000000]"))==0);
	test(proc.Priority()==EPriorityForeground);
	test(proc.ExitType()==EExitPending);
	test(proc.ExitReason()==0);
	test(proc.ExitCategory()==KNullDesC);
	}

void procTests4()
	{
	test.Next(_L("Get and open by Id"));
	TProcessId id=proc.Id();
	TProcessId id2=proc.Id();
	test(id==id2);
	TInt r=proc2.Open(proc.Name());
	test(r==KErrNone);
	id2=proc2.Id();
	test(id==id2);
	r=proc3.Open(id);
	test(r==KErrNone);
	id2=proc3.Id();
	test(id==id2);
	proc3.Close();
	if (HaveVirtMem())
		{
		test.Next(_L("Create duplicate"));
		r=createProc2(proc3);
		test(r==KErrNone);
		id2=proc3.Id();
		test(id!=id2);
		test(*(TUint*)&id<*(TUint*)&id2);
		}
	}

void procTests5()
	{
	test.Next(_L("Try to find processes"));
	TFindProcess* findProc=new TFindProcess(_L("T_PROC2*"));
	test(findProc!=NULL);
	TFullName* result=new TFullName;
	test(result!=NULL);
	TInt r=findProc->Next(*result);
	test(r==KErrNone);
	TFullName temp = proc.FullName();
	test(result->CompareF(temp)==0);
	r=findProc->Next(*result);
	test(r==KErrNone);
	test(result->CompareF(proc3.FullName())==0);
	r=findProc->Next(*result);
	test(r==KErrNotFound);
	findProc->Find(_L("T?PROC2*]*"));
	r=findProc->Next(*result);
	test(r==KErrNone);
	test(result->CompareF(temp)==0);
	r=findProc->Next(*result);
	test(r==KErrNone);
	test(result->CompareF(proc3.FullName())==0);
	delete result;
	test.Next(_L("Open by find handle"));
	r=proc4.Open(*findProc);
	test(r==KErrNone);
	TProcessId id=proc3.Id();
	TProcessId id2=proc4.Id();
	test(id==id2);
	delete findProc;
	}

void procTests6()
	{
	test.Next(_L("Kill duplicate"));
	proc3.Logon(stat);
	test(stat==KRequestPending);
	proc4.Kill(12345);
	User::WaitForRequest(stat);
	test(stat==12345);
	}

void createProcess()
//
// Create T_PROC2 and, on the way, do lots of basic tests
//
	{
	test.Start(_L("Create"));
	TInt r=globSem1.CreateGlobal(_L("GlobSem1"), 0);
	test(r==KErrNone);
	r=globSem2.CreateGlobal(_L("GlobSem2"), 0);
	test(r==KErrNone);

	r=createProc2(proc);
	test(r==KErrNone);

	procTests1();

	simpleTests1();
	simpleTests2();

	procTests2();
	procTests3();
	procTests4();
	if (HaveVirtMem())
		{
		procTests5();
		procTests6();
		}

	proc2.Close();
	proc3.Close();
	if (proc4.Handle())
		CLOSE_AND_WAIT(proc4);

	test.Next(_L("Resume"));
	proc.Logon(stat); // logon to process
	proc.Logon(notStat);
	r=proc.LogonCancel(notStat);
	test(r==KErrNone);
	test(notStat==KErrNone);
	test(proc.ExitType()==EExitPending);
	proc.Resume();
	globSem1.Wait(); // wait for T_PROC2 to get started
	test.End();
	}

void murderProcess()
	{
	test.Start(_L("Kill"));
	RProcess process;
	TInt r=createProc2(process);
	test(r==KErrNone);
	TProcessId id=process.Id();
	TProcessId id2=process.Id();
	test(id==id2);
 	TRequestStatus stat;
	process.Logon(stat);
	test(process.ExitType()==EExitPending);
	process.Kill(KKillReason);
	User::WaitForRequest(stat);
	test(stat==KKillReason);
	test(process.ExitType()==EExitKill);
	test(process.ExitReason()==KKillReason);
	test(process.ExitCategory()==_L("Kill"));
	CLOSE_AND_WAIT(process);

	test.Next(_L("Terminate"));
	r=createProc2(process);
	test(r==KErrNone);
	id2=process.Id();
	test(*(TUint*)&id+2==*(TUint*)&id2);	// use 2 ID's each time, one for process, one for thread
	process.Logon(stat);
	test(process.ExitType()==EExitPending);
	process.Terminate(KTerminateReason);
	User::WaitForRequest(stat);
	test(stat==KTerminateReason);
	test(process.ExitType()==EExitTerminate);
	test(process.ExitReason()==KTerminateReason);
	test(process.ExitCategory()==_L("Terminate"));
	CLOSE_AND_WAIT(process);

	test.Next(_L("Panic"));
	r=createProc2(process);
	test(r==KErrNone);
	id2=process.Id();
	test(*(TUint*)&id+4==*(TUint*)&id2);
 	test(process.ExitType()==EExitPending);
	process.Logon(stat);
	process.SetJustInTime(EFalse);	// prevent the process panic from starting the debugger
	process.Panic(_L("BOO!"),KPanicReason);
	User::WaitForRequest(stat);
	test(stat==KPanicReason);
	test(process.ExitType()==EExitPanic);
	test(process.ExitReason()==KPanicReason);
	test(process.ExitCategory()==_L("BOO!"));
	CLOSE_AND_WAIT(process);
	test.End();
	}

void sharedChunks()
	{
	test.Start(_L("Test chunk sharing between threads"));

	test.Next(_L("Create chunk Marmalade"));
	TInt r=0;
	RChunk chunk;
	TInt size=0x1000;
	TInt maxSize=0x5000;
	r=chunk.CreateGlobal(_L("Marmalade"),size,maxSize);
	test(r==KErrNone);
	test.Next(_L("Write 0-9 to it"));
	TUint8* base=chunk.Base();
	for (TInt8 j=0;j<10;j++)
		*base++=j; // write 0 - 9 to the chunk
  	globSem2.Signal(); // T_PROC2 can check the chunk now
	globSem1.Wait();
	chunk.Close(); // now it's ok to kill the chunk

	test.End();
	}

TInt sharedChunks2(TAny* /*aDummy*/)
	{
    RTest test(_L("Shared Chunks 2"));

	test.Title();	
	test.Start(_L("Test chunk sharing between threads"));

	test.Next(_L("Create chunk Marmalade"));
	TInt r=0;
	RChunk chunk;
	TInt size=0x1000;
	TInt maxSize=0x5000;
	r=chunk.CreateGlobal(_L("Marmalade"),size,maxSize);
	test(r==KErrNone);
	test.Next(_L("Write 0-9 to it"));
	TUint8* base=chunk.Base();
	for (TInt8 j=0;j<10;j++)
		*base++=j; // write 0 - 9 to the chunk
  	globSem2.Signal(); // T_PROC2 can check the chunk now
	globSem1.Wait();
	chunk.Close(); // now it's ok to kill the chunk

	test.End();
    return(KErrNone);
	}

TInt speedyThreadEntryPoint(TAny*)
//
// The entry point for the speed test thread.
//
	{
	RDisplay t;
	TInt r=t.Open();
	test(r==KErrNone);
	speedCount=0;
	client.Signal();
	while ((r=t.Test())==KErrNone)
		speedCount++;
	t.Close();
	return r;
	}

TInt BadName(TAny*)
	{
	proc.Open(_L("*"));
	return KErrNone;
	}

TInt sharedHeap(TAny*)
	{
	RTest test2(_L("sharedHeap"));
	test2.Title();
	test2.Start(_L("Shared heap tests"));

	RAllocator* allocator = &User::Allocator();
	test2.Printf(_L("sharedHeap's heap is at %08x\n"), allocator);
	
	TInt size;
	allocator->AllocSize(size);
	test2.Printf(_L("sharedHeap's heap allocsize is %08x\n"),size);

// Press a key only if running the test in manual mode. We will be
// able to ascertain this when RTest has been enhanced.
//	test.Next(_L("Press a key to continue"));
//	test2.Getch();

	test2.End();
	return(KErrNone);
	}

_LIT(KTestProcessNewName,"T_PROC1_NEW.EXE");

TInt DupRenameProcTest(TInt aCall)
	{
	test.Printf(_L("DupRenameProcTest: call %d\n"),aCall);

	TInt r;

	switch(aCall)
		{
	case 1:
		{
		r = User::RenameProcess(KTestProcessNewName);
		test(r==KErrNone);
		TFullName fn(RProcess().FullName());
		test.Printf(_L("Renamed to %S\n"),&fn);
		TInt li = fn.Locate('[');
		TInt ri = fn.Locate(']');
		test(fn.Left(li)==KTestProcessNewName);
		test(fn.Mid(ri+1)==_L("0001"));
		}

	case 0:
		{
		TFileName filename(RProcess().FileName());
		TInt pos=filename.LocateReverse(TChar('\\'));
		filename.SetLength(pos+1);
		filename+=_L("T_PROC1.EXE");
		RProcess pr;
		TBuf16<10> call;
		call.Num(aCall+1);
		r = pr.Create(filename, call);
		TFullName fn(pr.FullName());
		test.Printf(_L("Created %S\n"),&fn);
		TRequestStatus st;
		pr.Logon(st);
		pr.Resume();
		User::WaitForRequest(st);
		CLOSE_AND_WAIT(pr);
		}
		return KErrNone;

	case 2:
		{
		r = User::RenameProcess(KTestProcessNewName);
		test(r==KErrNone);
		TFullName fn(RProcess().FullName());
		test.Printf(_L("Renamed to %S\n"),&fn);
		TInt li = fn.Locate('[');
		TInt ri = fn.Locate(']');
		test(fn.Left(li)==KTestProcessNewName);
		test(fn.Mid(ri+1)==_L("0002"));
		}
		return KErrNone;

	default:
		return KErrArgument;
		}
	}

_LIT(KTestProcessName,"TestName");

void TestProcessRename()
	{
	// Rename the current process with test name
    TInt r = User::RenameProcess(KTestProcessName);
    test(r==KErrNone);
    TName name1 = RProcess().Name();

    // Check new name is correct
    TName name2 = name1;
    name2.SetLength(KTestProcessName().Length());
    test(name2.CompareF(KTestProcessName)==0);
    
    // Rename the process with same test name
    r = User::RenameProcess(KTestProcessName);
    test(r==KErrNone);
    name2 = RProcess().Name();
    test(name1.Compare(name2)==0);  // name should be unchanged
	}

TInt E32Main()
	{
	__KHEAP_MARK;

	// Turn off lazy dll unloading
	RLoader l;
	test(l.Connect()==KErrNone);
	test(l.CancelLazyDllUnload()==KErrNone);
	l.Close();

	TBuf16<512> cmd;
	User::CommandLine(cmd);
	if(cmd.Length() && TChar(cmd[0]).IsDigit())
		{
		TInt r = DupRenameProcTest(TUint(TChar(cmd[0])) - '0');
		test(r==KErrNone);
		return 0;
		}

	test.Title();

	test.Start(_L("Testing process stuff 1"));
	TInt r;
	TRequestStatus s;
	test.Next(_L("Creating semaphore"));
	r=client.CreateLocal(0);
	test(r==KErrNone);

	test.Next(_L("Try to open nonexistant process by ID"));
	r=proc.Open(*(TProcessId*)&KMaxTUint);
	test(r==KErrNotFound);

	test.Next(_L("Try to open process with invalid name"));
	RThread thread;
	r=thread.Create(_L("Bad Name"),BadName,KDefaultStackSize,NULL,NULL);
	test(r==KErrNone);
	TRequestStatus threadStat;
	thread.Logon(threadStat);
	TBool justInTime=User::JustInTime();
	User::SetJustInTime(EFalse);
	thread.Resume();
	User::WaitForRequest(threadStat);
	User::SetJustInTime(justInTime);
	test(threadStat==EBadName);
	test(thread.ExitType()==EExitPanic);
	test(thread.ExitReason()==EBadName);
	test(thread.ExitCategory()==_L("KERN-EXEC"));
	CLOSE_AND_WAIT(thread);

	test.Next(_L("Murder processes in different ways"));
	murderProcess();

	test.Next(_L("Create second process"));
	createProcess();

	test.Next(_L("Shared Chunks from main thread"));
	sharedChunks();

	test.Next(_L("Shared chunks from secondary thread"));
	RThread t;
	r=t.Create(_L("Shared chunks 2"),sharedChunks2,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
    test(r==KErrNone);
	t.Logon(s);
	t.Resume();
	User::WaitForRequest(s);
	test(s==KErrNone);
	CLOSE_AND_WAIT(t);

	test.Next(_L("Starting speedy client"));
	RThread speedy;
	r=speedy.Create(_L("Speedy"),speedyThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
	test(r==KErrNone);

	RThread().SetPriority(EPriorityMuchMore);
    speedy.SetPriority(EPriorityNormal);
	TRequestStatus speedyStatus;
	speedy.Logon(speedyStatus);
	speedy.Resume();

	test.Next(_L("Wait for speedy to start"));
	client.Wait();

	globSem1.Wait(); // wait for proc2 to be nice & quiet
	test.Printf(_L("Starting speed test...\n"));
    User::After(300000);
    TInt b=speedCount;
    User::After(3000000);
    TInt n=speedCount;
    test.Printf(_L("Count = %d in 1 second\n"),(n-b)/3);

	test.Next(_L("Tell second process speed tests are done"));
	globSem2.Signal();

	test.Next(_L("Process Logon"));
	User::WaitForRequest(stat);
	const TDesC& cat=proc.ExitCategory();
	test.Printf(_L("Exit category = %S\n"),&cat);
	test.Printf(_L("Exit reason = %x\n"),proc.ExitReason());
	test.Printf(_L("Exit type = %x\n"),proc.ExitType());

	test(stat==KErrNone);
	test(proc.ExitCategory()==_L("Kill"));
	test(proc.ExitReason()==KErrNone);
	test(proc.ExitType()==EExitKill);
	test(notStat==KErrNone);
	test.Next(_L("Test LogonCancel to dead process is ok"));
	r=proc.LogonCancel(stat);
	test(r==KErrGeneral);
	globSem1.Close();
	globSem2.Close();
	client.Close();

	User::WaitForRequest(speedyStatus);
	test(speedyStatus==KErrServerTerminated);
	test(speedy.ExitReason()==KErrServerTerminated);
	test(speedy.ExitType()==EExitKill);
	CLOSE_AND_WAIT(speedy);
	CLOSE_AND_WAIT(proc);

	User::After(5000000);	// wait for MMC session to disappear

	test.Next(_L("Test rename of the processes with duplicate names"));
	r = DupRenameProcTest(0);
	test(r==KErrNone);

    TestProcessRename();

	test.Next(_L("Check for kernel alloc heaven"));
	__KHEAP_MARKEND; 

	test.End();

	return(KErrNone);
	}