📄 testing.cpp
字号:
/**
*
* @brief OOM Test Harness example
*
* Runs the code in DoTestL() with increasing heap failure intervals until it succeeds, thus
* proving that it doesn't leak resources under Out-Of-Memory conditions.
* Note that Cleanup Stack code may cause the heap allocation failure as well as user code.
*
* Copyright (c) EMCC Software Ltd 2003
* @version 1.0
*/
// INCLUDE FILES
// System includes
#include <e32test.h> // RTest
// User include
#include "CleanupSupport.inl" // CleanupResetAndDestroyPushL
// Function declarations
LOCAL_C void DoTestL(); // The function under test.
LOCAL_C void RunOOMTestL(); // The OOM test harness.
// CONSTANTS
_LIT(KTestTitle, "OOM Test");
_LIT(KTestOOM, "Testing OOM");
// Prints expected allocation failure interval, if defined (verbose output).
#define PRINT_FAILURE_NUMBER
// Waits for user input on an unexpected error, if defined (test would no longer be automatic).
//#define WAIT_IF_ERROR
// Print the error number of any unexpected errors caught, if defined (verbose output).
#define PRINT_ERROR_NUMBER
// Orphans memory on the heap, if defined (to show test failing).
//#define INTRODUCE_ERROR
// Magic number, for test purposes.
const TInt KNumberOfDescriptors = 50;
// ================= FUNCTIONS =======================
/**
* Main executable entry point.
* Creates a Cleanup Stack and runs the OOM test.
*/
GLDEF_C TInt E32Main()
{
__UHEAP_MARK; // Set heap memory checking on.
// Create a Cleanup Stack.
CTrapCleanup* cleanup = CTrapCleanup::New();
if (!cleanup) // Test that the construction worked!
{
return KErrNoMemory;
}
// Run the OOM tests and trap any leaves that occur.
TRAPD(error, RunOOMTestL());
delete cleanup; // Delete the Cleanup Stack.
// Panic if the test code leaves.
__ASSERT_ALWAYS(!error, User::Panic(KTestTitle, error));
__UHEAP_MARKEND; // Check the test program doesn't leak memory.
return KErrNone;
}
/**
* The OOM test harness.
* The test code is checked to make sure that it doesn't orphan heap memory.
*/
LOCAL_C void RunOOMTestL()
{
// Create the RTest console mechanism and add it to the Cleanup Stack.
RTest test(KTestTitle);
CleanupClosePushL(test);
test.Title(); // Print the text which was set in the RTest constructor.
// Test 001
test.Start(KTestOOM); // Set the test level to 001 and print a message to screen.
TInt error = KErrNoMemory;
TInt failAt = 0;
// Loop, failing heap allocations at increasing intervals, until the test function
// succeeds. This will prove that the test function can handle any OOM errors without
// orphaning resources or otherwise corrupting the application.
while (error != KErrNone)
{
failAt++; // Increase the failure interval.
#ifdef PRINT_FAILURE_NUMBER
// Print out the expected allocation failure interval.
// Note the new line character is required for the log.
TBuf<200> indicator;
_LIT(KFailureInterval, "Memory will fail at allocation \t%d\n");
indicator.Format(KFailureInterval, failAt);
test.Printf(indicator);
#endif
// Set the failure interval and start nested heap checking.
__UHEAP_SETFAIL(RHeap::EDeterministic, failAt);
__UHEAP_MARK;
// Run the test code in a trap harness.
TRAP(error, DoTestL());
// End nested heap checking and reset (turn off) heap failure.
__UHEAP_MARKEND;
__UHEAP_RESET;
// We are expecting either an OOM error (if the heap fails),
// or no error - anything else is unexpected.
if ((error != KErrNoMemory) && (error != KErrNone))
{
#ifdef PRINT_ERROR_NUMBER
// Print the error number.
test.Printf(_L("Non standard error: %d\n"), error);
#endif
#ifdef WAIT_IF_ERROR
// Waits for user input on the console if an unexpected error occurs.
test.Getch();
#endif
}
// Test that we have no unexpected errors.
// This will Panic and break out of the loop on failure of the test conditions.
test((error == KErrNoMemory) || (error == KErrNone));
}
CleanupStack::Pop(); // test.
test.End(); // Close the test level.
#ifndef __WINS__
test.Getch(); // Pause the console if running on target, so we can see the results.
#endif
test.Close(); // Close the RTest console.
}
/**
* The actual test function.
* This simply creates an array of descriptors, but can be easily replaced with any other test code.
*/
LOCAL_C void DoTestL()
{
// Create a pointer array of descriptors. The array will own the instances pointed to.
RPointerArray<HBufC> bigArray(KNumberOfDescriptors);
// Push the array onto the Cleanup Stack, using the support for calling
// RPointerArray::ResetAndDestroy() on destruction, provided in CleanupSupport.inl.
CleanupResetAndDestroyPushL(bigArray);
// Create KNumberOfDescriptors descriptors and append them to the array
for (TInt loop = 0; loop < KNumberOfDescriptors; loop ++)
{
HBufC* temp = HBufC::NewLC(KTestTitle().Length());
*temp = KTestTitle;
User::LeaveIfError(bigArray.Append(temp));
CleanupStack::Pop(temp);
}
#ifdef INTRODUCE_ERROR
// Orphans memory on the heap.
HBufC::NewL(KTestTitle().Length());
#endif
CleanupStack::PopAndDestroy(); // bigArray. (Also deletes all items in the array.)
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -