|
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // e32test\heap\t_heapdb.cpp |
|
15 // Tests the _DEBUG build dependent aspects of RHeap |
|
16 // Overview: |
|
17 // Tests debug build dependent aspects of RHeap. |
|
18 // API Information: |
|
19 // RHeap. |
|
20 // Details: |
|
21 // Test1: |
|
22 // - Allocate a variety of user heap objects and verify the nesting level, allocation count, |
|
23 // allocation level and length are correct. Also check for heap corruption. |
|
24 // Test 2: |
|
25 // - Some assorted indirect calls to alloc, and verify the nesting level, allocation count, |
|
26 // allocation level and length are correct. Also check for heap corruption. |
|
27 // Test3: |
|
28 // - Allocate a variety of objects and verify that the UHEAP_CHECKALL count is correct. |
|
29 // - Verify the nesting of UHEAP_MARK and UHEAP_MARKEND macros. |
|
30 // - Check the validity of the current thread's default heap. |
|
31 // Test4: |
|
32 // - Allocate memory for different heaps, check the total number of allocated cells |
|
33 // for different heaps and for the current nested level is as expected. |
|
34 // Test5: |
|
35 // - Simulate heap allocation failures, allocate the memory from user and |
|
36 // kernel heap and check results are as expected. |
|
37 // Platforms/Drives/Compatibility: |
|
38 // All |
|
39 // Assumptions/Requirement/Pre-requisites: |
|
40 // Failures and causes: |
|
41 // Base Port information: |
|
42 // |
|
43 // |
|
44 |
|
45 #include <e32test.h> |
|
46 #include <e32def.h> |
|
47 #include <e32def_private.h> |
|
48 |
|
49 LOCAL_D RTest test(_L("T_HEAPDB")); |
|
50 |
|
51 #if defined(_DEBUG) |
|
52 |
|
53 RHeap::SHeapCellInfo CellInfo[4]; |
|
54 |
|
55 class RTestHeap : public RHeap |
|
56 { |
|
57 public: |
|
58 void AttachInfo(SHeapCellInfo* aInfo) |
|
59 {iTestData = aInfo;} |
|
60 }; |
|
61 |
|
62 void AttachToHeap(RHeap* aHeap, TInt aInfo) |
|
63 { |
|
64 if (!aHeap) |
|
65 aHeap = (RHeap*)&User::Allocator(); |
|
66 ((RTestHeap*)aHeap)->AttachInfo(CellInfo + aInfo); |
|
67 } |
|
68 |
|
69 void TestCellInfo(TInt aInfo, TInt aNest, TInt aAllocCount, TInt aLevelAlloc, TInt aSize, TAny* aAddr) |
|
70 { |
|
71 RHeap::SHeapCellInfo& ci = CellInfo[aInfo]; |
|
72 RHeap::SDebugCell& cell = *ci.iStranded; |
|
73 test(cell.nestingLevel == aNest); |
|
74 test(cell.allocCount == aAllocCount); |
|
75 test(ci.iLevelAlloc == aLevelAlloc); |
|
76 test(cell.len == aSize + RHeap::EAllocCellSize); |
|
77 test((&cell+1) == aAddr); |
|
78 } |
|
79 |
|
80 const TInt KMaxFailureRate=100; |
|
81 const TInt KThreadMemError=-50; |
|
82 const TInt KCellSize=(sizeof(RHeap::SCell)); // Size of free cell header |
|
83 const TInt KHeadSize=(sizeof(RHeap::SDebugCell)); // Size of allocated cell header with space for heaven info |
|
84 |
|
85 LOCAL_D TInt heapCount=1; |
|
86 LOCAL_D RSemaphore threadSemaphore; |
|
87 LOCAL_D TBool array1[KMaxFailureRate+1]; |
|
88 LOCAL_D TBool array2[KMaxFailureRate+1]; |
|
89 |
|
90 LOCAL_C TInt ThreadEntryPoint(TAny*) |
|
91 { |
|
92 threadSemaphore.Wait(); |
|
93 if (User::Alloc(4)==NULL) |
|
94 return(KThreadMemError); |
|
95 else |
|
96 return(KErrNone); |
|
97 } |
|
98 |
|
99 class TestRHeapDebug |
|
100 { |
|
101 public: |
|
102 void Test1(void); |
|
103 void Test2(void); |
|
104 void Test3(void); |
|
105 void Test4(void); |
|
106 void Test5(void); |
|
107 }; |
|
108 |
|
109 LOCAL_C RHeap* allocHeap(TInt aSize) |
|
110 // |
|
111 // Allocate a chunk heap with max size aSize |
|
112 // |
|
113 { |
|
114 |
|
115 TName n; |
|
116 n.Format(_L("TESTHEAP%d"),heapCount++); |
|
117 return(User::ChunkHeap(&n,aSize,aSize)); |
|
118 } |
|
119 |
|
120 void TestRHeapDebug::Test1(void) |
|
121 { |
|
122 |
|
123 TAny* p; |
|
124 |
|
125 /////////////////////// |
|
126 // Test heaven cell is found for each method of allocating memory |
|
127 //////////////////////// |
|
128 |
|
129 // new(TInt aSize) |
|
130 __UHEAP_MARK; |
|
131 __UHEAP_CHECKALL(0); |
|
132 __UHEAP_CHECK(0); |
|
133 p=new TUint; |
|
134 __UHEAP_CHECKALL(1); |
|
135 __UHEAP_CHECK(1); |
|
136 __UHEAP_MARKEND; |
|
137 __UHEAP_CHECK(0); |
|
138 __UHEAP_CHECKALL(1); |
|
139 TestCellInfo(0, 1, 1, 1, User::AllocLen(p), p); |
|
140 User::Free(p); |
|
141 |
|
142 // new(TInt aSize,TInt anExtraSize) |
|
143 __UHEAP_MARK; |
|
144 p=new(4) TUint; |
|
145 __UHEAP_MARKEND; |
|
146 TestCellInfo(0, 1, 1, 1, User::AllocLen(p), p); |
|
147 User::Free(p); |
|
148 |
|
149 // new(TInt aSize,TLeave) |
|
150 __UHEAP_MARK; |
|
151 p=new(ELeave) TUint; |
|
152 __UHEAP_MARKEND; |
|
153 TestCellInfo(0, 1, 1, 1, User::AllocLen(p), p); |
|
154 User::Free(p); |
|
155 |
|
156 // Alloc |
|
157 __UHEAP_MARK; |
|
158 p=User::Alloc(32); |
|
159 __UHEAP_MARKEND; |
|
160 TestCellInfo(0, 1, 1, 1, User::AllocLen(p), p); |
|
161 User::Free(p); |
|
162 |
|
163 // AllocL |
|
164 __UHEAP_MARK; |
|
165 p=User::AllocL(32); |
|
166 __UHEAP_MARKEND; |
|
167 TestCellInfo(0, 1, 1, 1, User::AllocLen(p), p); |
|
168 User::Free(p); |
|
169 |
|
170 // ReAlloc with Null parameter |
|
171 __UHEAP_MARK; |
|
172 p=User::ReAlloc(NULL, 32); |
|
173 __UHEAP_MARKEND; |
|
174 TestCellInfo(0, 1, 1, 1, User::AllocLen(p), p); |
|
175 User::Free(p); |
|
176 |
|
177 // ReAllocL with Null parameter |
|
178 __UHEAP_MARK; |
|
179 p=User::ReAllocL(NULL, 32); |
|
180 __UHEAP_MARKEND; |
|
181 TestCellInfo(0, 1, 1, 1, User::AllocLen(p), p); |
|
182 User::Free(p); |
|
183 |
|
184 // ReAlloc with non Null parameter |
|
185 __UHEAP_MARK; |
|
186 p=User::Alloc(128); |
|
187 p=User::ReAlloc(p, 4); |
|
188 __UHEAP_MARKEND; |
|
189 TestCellInfo(0, 1, 1, 1, User::AllocLen(p), p); |
|
190 User::Free(p); |
|
191 |
|
192 // ReAlloc with non Null parameter such that cell is moved in memory |
|
193 __UHEAP_MARK; |
|
194 p=User::Alloc(128); |
|
195 TAny* temp=User::Alloc(128); |
|
196 p=User::ReAlloc(p, 526); |
|
197 User::Free(temp); |
|
198 __UHEAP_MARKEND; |
|
199 TestCellInfo(0, 1, 3, 1, User::AllocLen(p), p); |
|
200 User::Free(p); |
|
201 |
|
202 // ReAllocL with non Null parameter |
|
203 __UHEAP_MARK; |
|
204 p=User::Alloc(32); |
|
205 p=User::ReAllocL(p, 128); |
|
206 __UHEAP_MARKEND; |
|
207 TestCellInfo(0, 1, 1, 1, User::AllocLen(p), p); |
|
208 User::Free(p); |
|
209 } |
|
210 |
|
211 |
|
212 void TestRHeapDebug::Test2(void) |
|
213 { |
|
214 // Some assorted indirect calls to alloc |
|
215 |
|
216 __UHEAP_MARK; |
|
217 CBufFlat* pBuf=CBufFlat::NewL(10); |
|
218 __UHEAP_MARKEND; |
|
219 TestCellInfo(0, 1, 1, 1, User::AllocLen(pBuf), pBuf); |
|
220 delete pBuf; |
|
221 |
|
222 __UHEAP_MARK; |
|
223 HBufC8* pHBufC=HBufC8::New(10); |
|
224 __UHEAP_MARKEND; |
|
225 TestCellInfo(0, 1, 1, 1, User::AllocLen(pHBufC), pHBufC); |
|
226 delete pHBufC; |
|
227 |
|
228 // can also create a HBufC8 from a descriptor by using TDesC::Alloc |
|
229 } |
|
230 |
|
231 |
|
232 void TestRHeapDebug::Test3(void) |
|
233 { |
|
234 |
|
235 // Check num of cells detected is correct and CHECKTOTALNUM is ok |
|
236 // NOTE: CHECKTOTALNUM counts the TOTAL number of allocations in the heap regardless of |
|
237 // any MARKSTARTs |
|
238 // NOTE: the alloc count commences from the FIRST occurrence of a MARKSTART, so if one is nested |
|
239 // in another the alloc count will only start from the second MARKSTART if it applies to a |
|
240 // different heap. |
|
241 __UHEAP_MARK; |
|
242 __UHEAP_CHECKALL(0); |
|
243 TAny* p1= new TUint; |
|
244 __UHEAP_CHECKALL(1); |
|
245 TAny* p2= new(20) TUint; |
|
246 __UHEAP_CHECKALL(2); |
|
247 TAny* p3= User::Alloc(15); |
|
248 __UHEAP_CHECKALL(3); |
|
249 __UHEAP_MARK; |
|
250 __UHEAP_CHECK(0); |
|
251 TAny* p4=User::Alloc(1); |
|
252 TAny* p5 =new TUint; |
|
253 __UHEAP_CHECK(2); |
|
254 __UHEAP_CHECKALL(5); |
|
255 __UHEAP_MARKEND; |
|
256 TestCellInfo(0, 2, 4, 2, User::AllocLen(p4), p4); |
|
257 __UHEAP_CHECKALL(5); |
|
258 __UHEAP_CHECK(3); |
|
259 __UHEAP_MARKENDC(3); |
|
260 User::Free(p1); |
|
261 User::Free(p2); |
|
262 User::Free(p3); |
|
263 User::Free(p4); |
|
264 User::Free(p5); |
|
265 |
|
266 // Check some nesting out |
|
267 p1=new TUint; |
|
268 __UHEAP_MARK; |
|
269 p2=new TUint; |
|
270 __UHEAP_MARK; |
|
271 p3=new TUint; |
|
272 __UHEAP_MARK; |
|
273 p4=new TUint; |
|
274 __UHEAP_MARKEND; |
|
275 TestCellInfo(0, 3, 3, 1, User::AllocLen(p4), p4); |
|
276 __UHEAP_MARKEND; |
|
277 TestCellInfo(0, 2, 2, 1, User::AllocLen(p3), p3); |
|
278 __UHEAP_MARKEND; |
|
279 TestCellInfo(0, 1, 1, 1, User::AllocLen(p2), p2); |
|
280 User::Free(p1); |
|
281 User::Free(p2); |
|
282 User::Free(p3); |
|
283 User::Free(p4); |
|
284 User::Check(); |
|
285 } |
|
286 |
|
287 void TestRHeapDebug::Test4(void) |
|
288 { |
|
289 // Test with different heaps |
|
290 TAny* p1=new TUint; |
|
291 __UHEAP_MARK; // Default start |
|
292 __UHEAP_CHECKALL(1); |
|
293 __UHEAP_CHECK(0); |
|
294 TAny* p2=new TUint; |
|
295 RHeap* pHeap1=allocHeap(1000); |
|
296 AttachToHeap(pHeap1,1); |
|
297 __RHEAP_MARK(pHeap1); // Heap1 start |
|
298 __RHEAP_CHECKALL(pHeap1,0); |
|
299 __RHEAP_CHECK(pHeap1,0); |
|
300 TAny* p3=pHeap1->Alloc(4); |
|
301 __RHEAP_CHECKALL(pHeap1,1); |
|
302 __RHEAP_CHECK(pHeap1,1); |
|
303 __RHEAP_CHECKALL(pHeap1,1); |
|
304 __UHEAP_CHECKALL(3); |
|
305 RHeap* pHeap2=allocHeap(1000); |
|
306 AttachToHeap(pHeap2,2); |
|
307 RHeap* pHeap3=allocHeap(1000); |
|
308 AttachToHeap(pHeap3,3); |
|
309 __UHEAP_CHECKALL(5); |
|
310 __RHEAP_MARK(pHeap2); // Heap2 start |
|
311 __RHEAP_MARK(pHeap3); // Heap3 start |
|
312 TAny* p4=pHeap2->Alloc(8); |
|
313 TAny* p5=pHeap2->Alloc(37); |
|
314 TAny* p6=pHeap3->Alloc(32); |
|
315 TAny* p7=pHeap1->Alloc(43); |
|
316 __UHEAP_CHECKALL(5); |
|
317 __RHEAP_CHECKALL(pHeap1,2); |
|
318 __RHEAP_CHECKALL(pHeap2,2); |
|
319 __RHEAP_CHECKALL(pHeap3,1); |
|
320 __RHEAP_MARKEND(pHeap3); // Heap3 end |
|
321 TestCellInfo(3, 1, 1, 1, pHeap3->AllocLen(p6), p6); |
|
322 __RHEAP_MARKEND(pHeap2); // Heap2 end |
|
323 TestCellInfo(2, 1, 1, 2, pHeap2->AllocLen(p4), p4); |
|
324 pHeap1->Free(p3); |
|
325 __RHEAP_MARKEND(pHeap1); // Heap1 end |
|
326 TestCellInfo(1, 1, 2, 1, pHeap1->AllocLen(p7), p7); |
|
327 User::Free(p1); |
|
328 User::Free(p2); |
|
329 pHeap2->Free(p4); |
|
330 pHeap2->Free(p5); |
|
331 pHeap3->Free(p6); |
|
332 pHeap1->Free(p7); |
|
333 __UHEAP_CHECKALL(3); |
|
334 pHeap2->Close(); |
|
335 pHeap3->Close(); |
|
336 __UHEAP_MARKEND; |
|
337 pHeap1->Close(); |
|
338 __UHEAP_CHECKALL(0); |
|
339 } |
|
340 |
|
341 void TestRHeapDebug::Test5() |
|
342 // Check the alloc failure macros |
|
343 { |
|
344 TAny *p, *p1; |
|
345 RHeap* pHeap=allocHeap(1000); |
|
346 |
|
347 // DETERMINISTIC FAILURE |
|
348 __UHEAP_RESET; |
|
349 __UHEAP_FAILNEXT(1); |
|
350 test(User::Alloc(1)==NULL); |
|
351 p=User::Alloc(1); |
|
352 test(p!=NULL); |
|
353 User::FreeZ(p); |
|
354 __UHEAP_RESET; |
|
355 |
|
356 __RHEAP_RESET(pHeap); |
|
357 __RHEAP_FAILNEXT(pHeap,1); |
|
358 test(pHeap->Alloc(1)==NULL); |
|
359 p=pHeap->Alloc(1); |
|
360 test(p!=NULL); |
|
361 pHeap->FreeZ(p); |
|
362 __RHEAP_RESET(pHeap); |
|
363 |
|
364 __KHEAP_RESET; |
|
365 __KHEAP_FAILNEXT(1); |
|
366 RSemaphore semaphore; |
|
367 test(semaphore.CreateLocal(1)==KErrNoMemory); // allocated from the kernel heap |
|
368 test(semaphore.CreateLocal(1)==KErrNone); |
|
369 semaphore.Close(); |
|
370 __KHEAP_RESET; |
|
371 |
|
372 __UHEAP_SETFAIL(RHeap::EDeterministic,0); |
|
373 test(User::Alloc(1)==NULL); |
|
374 __UHEAP_RESET; |
|
375 |
|
376 __RHEAP_SETFAIL(pHeap,RHeap::EDeterministic,0); |
|
377 test(pHeap->Alloc(1)==NULL); |
|
378 __RHEAP_RESET(pHeap); |
|
379 |
|
380 __KHEAP_SETFAIL(RHeap::EDeterministic,0); |
|
381 test(semaphore.CreateLocal(1)==KErrNoMemory); |
|
382 __KHEAP_RESET; |
|
383 |
|
384 TInt determinism; |
|
385 for(determinism=1; determinism<=KMaxFailureRate; determinism++) |
|
386 { |
|
387 __UHEAP_SETFAIL(RHeap::EDeterministic,determinism); |
|
388 __RHEAP_SETFAIL(pHeap,RHeap::EDeterministic,determinism); |
|
389 for(TInt ii=1; ii<=determinism; ii++) |
|
390 { |
|
391 p=User::Alloc(1); |
|
392 p1=pHeap->Alloc(1); |
|
393 if(ii%determinism==0) |
|
394 { |
|
395 test(p==NULL); |
|
396 test(p1==NULL); |
|
397 } |
|
398 else |
|
399 { |
|
400 test(p!=NULL); |
|
401 test(p1!=NULL); |
|
402 pHeap->Free(p1); |
|
403 User::Free(p); |
|
404 } |
|
405 } |
|
406 } |
|
407 __UHEAP_RESET; |
|
408 __RHEAP_RESET(pHeap); |
|
409 |
|
410 // Test SetKernelAllocFail |
|
411 // its not possible to test SetKernelAllocFail as above as it is not possible to control the |
|
412 // number of calls to Alloc for the dernel heap - but the following will definitely fail: |
|
413 __KHEAP_SETFAIL(RHeap::EDeterministic,1); |
|
414 RSemaphore r; |
|
415 test(r.CreateLocal(1)==KErrNoMemory); // allocated from the kernel heap |
|
416 __KHEAP_SETFAIL(RHeap::EDeterministic,50); |
|
417 test(r.CreateLocal(1)==KErrNone); |
|
418 r.Close(); |
|
419 __KHEAP_RESET; |
|
420 |
|
421 // RANDOM TESTS |
|
422 TInt numOccurences1, numOccurences2; |
|
423 |
|
424 __UHEAP_SETFAIL(RHeap::ERandom,1); |
|
425 test(User::Alloc(1)==NULL); |
|
426 __UHEAP_RESET; |
|
427 |
|
428 __RHEAP_SETFAIL(pHeap,RHeap::ERandom,1); |
|
429 test(pHeap->Alloc(1)==NULL); |
|
430 __RHEAP_RESET(pHeap); |
|
431 |
|
432 // __KHEAP_SETFAIL(RHeap::ERandom,1); |
|
433 // test(semaphore.CreateLocal(1)==KErrNoMemory); |
|
434 // __KHEAP_RESET; |
|
435 |
|
436 __UHEAP_SETFAIL(RHeap::ETrueRandom,1); |
|
437 test(User::Alloc(1)==NULL); |
|
438 __UHEAP_RESET; |
|
439 |
|
440 __RHEAP_SETFAIL(pHeap,RHeap::ETrueRandom,1); |
|
441 test(pHeap->Alloc(1)==NULL); |
|
442 __RHEAP_RESET(pHeap); |
|
443 |
|
444 // __KHEAP_SETFAIL(RHeap::ETrueRandom,1); |
|
445 // test(semaphore.CreateLocal(1)==KErrNoMemory); |
|
446 // __KHEAP_RESET; |
|
447 |
|
448 for(determinism=1; determinism<=KMaxFailureRate; determinism++) |
|
449 { |
|
450 __UHEAP_SETFAIL(RHeap::ERandom,determinism); |
|
451 __RHEAP_SETFAIL(pHeap,RHeap::ERandom,determinism); |
|
452 TInt ii; |
|
453 for(ii=1; ii<=determinism; ii++) |
|
454 { |
|
455 p=User::Alloc(1); |
|
456 p1=pHeap->Alloc(1); |
|
457 array1[ii]=(p==NULL); |
|
458 array2[ii]=(p==NULL); |
|
459 if(p) |
|
460 User::Free(p); |
|
461 if(p1) |
|
462 pHeap->Free(p1); |
|
463 } |
|
464 numOccurences1=0; |
|
465 numOccurences2=0; |
|
466 for(ii=1; ii<=determinism; ii++) |
|
467 { |
|
468 if(array1[ii]) |
|
469 numOccurences1++; |
|
470 if(array2[ii]) |
|
471 numOccurences2++; |
|
472 } |
|
473 test(numOccurences1==1); |
|
474 test(numOccurences2==1); |
|
475 } |
|
476 __UHEAP_RESET; |
|
477 __RHEAP_RESET(pHeap); |
|
478 |
|
479 __UHEAP_SETFAIL(RHeap::ERandom,5); |
|
480 TInt ii; |
|
481 for(ii=1; ii<=50; ii++) |
|
482 { |
|
483 p=User::Alloc(1); |
|
484 array1[ii]=(p==NULL); |
|
485 if(p) |
|
486 User::Free(p); |
|
487 } |
|
488 numOccurences1=0; |
|
489 numOccurences2=0; |
|
490 for(ii=1; ii<=50; ii++) |
|
491 { |
|
492 if(array1[ii]) |
|
493 { |
|
494 numOccurences1++; |
|
495 numOccurences2++; |
|
496 } |
|
497 if(ii%5==0) |
|
498 { |
|
499 test(numOccurences1==1); |
|
500 numOccurences1=0; |
|
501 } |
|
502 } |
|
503 test(numOccurences2==50/5); |
|
504 |
|
505 // Cannot really test random failure of the kernel heap accurately |
|
506 |
|
507 pHeap->Close(); |
|
508 //client.Disconnect(); |
|
509 |
|
510 // Test failing the heap of a child thread |
|
511 // 1st test that it allocates normally |
|
512 TRequestStatus stat; |
|
513 RThread thread; |
|
514 test(threadSemaphore.CreateLocal(0)==KErrNone); |
|
515 test(thread.Create(_L("Thread"),ThreadEntryPoint,KDefaultStackSize,0x200,0x200,NULL)==KErrNone); |
|
516 thread.Logon(stat); |
|
517 thread.Resume(); |
|
518 threadSemaphore.Signal(); |
|
519 User::WaitForRequest(stat); |
|
520 test(thread.ExitReason()==KErrNone); |
|
521 thread.Close(); |
|
522 #if defined(CAN_TEST_THREADS) |
|
523 // Now make the thread's heap fail |
|
524 test(thread.Create(_L("Thread"),ThreadEntryPoint,KDefaultStackSize,0x200,0x200,NULL)==KErrNone); |
|
525 thread.Logon(stat); |
|
526 thread.Resume(); |
|
527 TH_FAILNEXT(thread.Handle()); |
|
528 threadSemaphore.Signal(); |
|
529 User::WaitForRequest(stat); |
|
530 test(thread.ExitReason()==KThreadMemError); |
|
531 thread.Close(); |
|
532 threadSemaphore.Close(); |
|
533 #endif |
|
534 } |
|
535 |
|
536 GLDEF_C TInt E32Main(void) |
|
537 { |
|
538 |
|
539 test.Title(); |
|
540 AttachToHeap(NULL,0); |
|
541 test.Start(_L("Test1")); |
|
542 TestRHeapDebug T; |
|
543 T.Test1(); |
|
544 test.Next(_L("Test2")); |
|
545 T.Test2(); |
|
546 test.Next(_L("Test3")); |
|
547 T.Test3(); |
|
548 test.Next(_L("Test4")); |
|
549 T.Test4(); |
|
550 test.Next(_L("Test5")); |
|
551 T.Test5(); |
|
552 test.End(); |
|
553 return(0); |
|
554 } |
|
555 #else |
|
556 GLDEF_C TInt E32Main() |
|
557 // |
|
558 // Test unavailable in release build. |
|
559 // |
|
560 { |
|
561 |
|
562 test.Title(); |
|
563 test.Start(_L("No tests for release builds")); |
|
564 test.End(); |
|
565 return(0); |
|
566 } |
|
567 #endif |
|
568 |
|
569 |
|
570 |