|
1 // Copyright (c) 2008-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\demandpaging\t_chunkheapcreate.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 // |
|
19 #define __E32TEST_EXTENSION__ |
|
20 #include <e32test.h> |
|
21 #include <dptest.h> |
|
22 #include <e32hal.h> |
|
23 #include <u32exec.h> |
|
24 #include <e32svr.h> |
|
25 #include <e32panic.h> |
|
26 #include "u32std.h" |
|
27 |
|
28 #include "t_dpcmn.h" |
|
29 |
|
30 enum |
|
31 { |
|
32 ETestLocal, |
|
33 ETestGlobal, |
|
34 ETestExisting, |
|
35 }; |
|
36 |
|
37 static TPtrC gGlobalDes = _L("GlobalHeap"); |
|
38 |
|
39 void UseOrCreateChunk(TChunkHeapCreateInfo aCreateInfo, TInt aTestType) |
|
40 { |
|
41 switch(aTestType) |
|
42 { |
|
43 case ETestLocal: |
|
44 aCreateInfo.SetCreateChunk(NULL); |
|
45 break; |
|
46 |
|
47 case ETestGlobal: |
|
48 aCreateInfo.SetCreateChunk(&gGlobalDes); |
|
49 break; |
|
50 |
|
51 case ETestExisting: |
|
52 aCreateInfo.SetUseChunk(gChunk); |
|
53 break; |
|
54 } |
|
55 } |
|
56 |
|
57 /** |
|
58 Attempt to create a global or local UserHeap with the given attributes |
|
59 |
|
60 @return ETrue The chunk is paged or unpaged as expected. |
|
61 */ |
|
62 TInt UserHeapAtt(TBool aPaged, TChunkHeapCreateInfo& aCreateInfo) |
|
63 { |
|
64 UpdatePaged(aPaged); |
|
65 |
|
66 RHeap* heap = UserHeap::ChunkHeap(aCreateInfo); |
|
67 |
|
68 test_NotNull(heap); |
|
69 RChunk chunk; |
|
70 chunk.SetHandle(heap->ChunkHandle()); |
|
71 TBool paged = chunk.IsPaged(); |
|
72 chunk.Close(); |
|
73 return (aPaged == paged); |
|
74 } |
|
75 |
|
76 TInt PanicUserHeap(TAny*) |
|
77 { |
|
78 TChunkHeapCreateInfo createInfo(0, gPageSize); |
|
79 createInfo.SetCreateChunk(NULL); |
|
80 createInfo.SetMode((TUint)~UserHeap::EChunkHeapMask); |
|
81 test(UserHeapAtt(gProcessPaged, createInfo)); |
|
82 return KErrGeneral; // Shouldn't reach here. |
|
83 } |
|
84 |
|
85 TInt PanicChunkHeapCreate(TAny* aCreateInfo) |
|
86 { |
|
87 TChunkHeapCreateInfo createInfo((*(TChunkHeapCreateInfo*) aCreateInfo)); |
|
88 UserHeap::ChunkHeap(createInfo); |
|
89 return KErrGeneral; // Should never reahc here |
|
90 } |
|
91 |
|
92 // |
|
93 // TestChunkHeapCreate |
|
94 // |
|
95 //---------------------------------------------------------------------------------------------- |
|
96 //! @SYMTestCaseID KBASE-T_CHUNKHEAPCREATE-xxxx |
|
97 //! @SYMTestType UT |
|
98 //! @SYMPREQ PREQ1954 |
|
99 //! @SYMTestCaseDesc Testing TChunkHeapCreateInfo |
|
100 //! Verify the chunk heap creation implementation |
|
101 //! @SYMTestActions |
|
102 //! 1. Create a local chunk by calling SetCreateChunk(NULL). |
|
103 //! Following this check the paging status of the chunk heap. |
|
104 //! 2. Create a local chunk by calling SetCreateChunk(NULL). Set the chunk heap to EPaged. |
|
105 //! Following this check the paging status of the chunk heap. |
|
106 //! 3. Create a local chunk by calling SetCreateChunk(NULL). Set the chunk heap to EUnPaged. |
|
107 //! Following this check the paging status of the chunk heap. |
|
108 //! 4. Create a heap within a local chunk and set the minimum length of the heap to be greater |
|
109 //! than the maximum length of the heap |
|
110 //! 5. Create a heap within a local chunk and set the minimum length of the heap to -1 |
|
111 //! 6. Create a heap within a local chunk and set the maximum length of the heap to |
|
112 //! less than KMinHeapSize |
|
113 //! 7. Call TChunkHeapCreateInfo::SetUseChunk() on a created local chunk calling SetCreateChunk(NULL) |
|
114 //! before hand. Following this call UserHeap::ChunkHeap() and compare the heap and the chunk handles |
|
115 //! 8. Call TChunkHeapCreateInfo::SetUseChunk() on a created local chunk calling SetCreateChunk(NULL) |
|
116 //! after. Following this call UserHeap::ChunkHeap() and compare the heap and the chunk handles |
|
117 //! 9. Call TChunkHeapCreateInfo::SetSingleThread() on a created local chunk specifying EFalse. |
|
118 //! Following this call UserHeap::ChunkHeap(); |
|
119 //! 10. Call TChunkHeapCreateInfo::SetSingleThread() on a created local chunk specifying ETrue. |
|
120 //! Following this call UserHeap::ChunkHeap(); |
|
121 //! 11. Call TChunkHeapCreateInfo::SetAlignment() on a created local chunk specifying aAlign to |
|
122 //! be a valid value. Following this call UserHeap::ChunkHeap(); |
|
123 //! 12. Call TChunkHeapCreateInfo::SetAlignment() on a created local chunk specifying aAlign to be |
|
124 //! an invalid value (-1). Following this call UserHeap::ChunkHeap(); |
|
125 //! 13. Call TChunkHeapCreateInfo::SetGrowBy() on a created local chunk specifying aGrowBy to be |
|
126 //! a valid value. Following this call UserHeap::ChunkHeap(). Following this create and array of |
|
127 //! integers on the heap and check the size of the chunk. |
|
128 //! 14. Call TChunkHeapCreateInfo::SetGrowBy() on a created local chunk specifying aGrowBy to |
|
129 //! be greater than the maximum size of the chunk. Following this call UserHeap::ChunkHeap(); |
|
130 //! 15. Call TChunkHeapCreateInfo::SetOffset() on a created local chunk specifying aOffset to |
|
131 //! be a valid value. Following this call UserHeap::ChunkHeap(); |
|
132 //! 16. Call TChunkHeapCreateInfo:: SetMode () on a created local chunk specifying aMode to |
|
133 //! be an invalid value. Following this call UserHeap::ChunkHeap(); |
|
134 //! |
|
135 //! @SYMTestExpectedResults All tests should pass. |
|
136 //! @SYMTestPriority High |
|
137 //! @SYMTestStatus Implemented |
|
138 //---------------------------------------------------------------------------------------------- |
|
139 void TestChunkHeapCreate(TInt aTestType) |
|
140 { |
|
141 |
|
142 |
|
143 test.Start(_L("Test UserHeap::ChunkHeap() data paging attributes")); |
|
144 { |
|
145 TChunkHeapCreateInfo createInfo(0, gPageSize); |
|
146 |
|
147 UseOrCreateChunk(createInfo, aTestType); |
|
148 |
|
149 test(UserHeapAtt(gProcessPaged, createInfo)); |
|
150 |
|
151 createInfo.SetPaging(TChunkHeapCreateInfo::EPaged); |
|
152 test(UserHeapAtt(ETrue, createInfo)); |
|
153 |
|
154 createInfo.SetPaging(TChunkHeapCreateInfo::EUnpaged); |
|
155 test(UserHeapAtt(EFalse, createInfo)); |
|
156 } |
|
157 |
|
158 test.Next(_L("Test maxHeapSize < minHeapSize")); |
|
159 { |
|
160 TChunkHeapCreateInfo createInfo(KMinHeapSize + gPageSize, KMinHeapSize); |
|
161 UseOrCreateChunk(createInfo, aTestType); |
|
162 RThread thread; |
|
163 test_KErrNone(thread.Create(_L("Panic UserHeap"), PanicChunkHeapCreate, KDefaultStackSize, KMinHeapSize, |
|
164 KMinHeapSize, (TAny*) &createInfo)); |
|
165 |
|
166 test_KErrNone(TestThreadExit(thread, EExitPanic, ETHeapCreateMaxLessThanMin)); |
|
167 } |
|
168 |
|
169 test.Next(_L("Test invalid minHeapSize")); |
|
170 { |
|
171 TChunkHeapCreateInfo createInfo(-1, KMinHeapSize); |
|
172 UseOrCreateChunk(createInfo, aTestType); |
|
173 RThread thread; |
|
174 test_KErrNone(thread.Create(_L("Panic UserHeap"), PanicChunkHeapCreate, KDefaultStackSize, KMinHeapSize, |
|
175 KMinHeapSize, (TAny*) &createInfo)); |
|
176 |
|
177 test_KErrNone(TestThreadExit(thread, EExitPanic, ETHeapMinLengthNegative)); |
|
178 } |
|
179 |
|
180 test.Next(_L("Test invalid maxHeapSize")); |
|
181 { |
|
182 RHeap* heap; |
|
183 TChunkHeapCreateInfo createInfo(0, 0); |
|
184 UseOrCreateChunk(createInfo, aTestType); |
|
185 heap = (RHeap*)UserHeap::ChunkHeap(createInfo); |
|
186 if (heap == NULL) |
|
187 { |
|
188 test.Printf(_L("RHeap not created")); |
|
189 } |
|
190 TUint maxLength = heap->MaxLength(); |
|
191 test.Printf(_L("heap max length = 0x%x\n"), maxLength); |
|
192 |
|
193 // Need to round up to page size as RHeap maxLength is rounded |
|
194 // up to the nearest page size |
|
195 TUint expectedMaxSize = _ALIGN_UP(KMinHeapSize, gPageSize); |
|
196 test_Equal(expectedMaxSize, maxLength); |
|
197 heap->Close(); |
|
198 } |
|
199 |
|
200 test.Next(_L("Test SetUseChunk - calling SetCreate before")); |
|
201 { |
|
202 RHeap* heap; |
|
203 RChunk chunky; |
|
204 |
|
205 TChunkCreateInfo chunkCreateInfo; |
|
206 chunkCreateInfo.SetNormal(gPageSize, gPageSize); |
|
207 test_KErrNone(chunky.Create(chunkCreateInfo)); |
|
208 |
|
209 TChunkHeapCreateInfo createInfo(0, gPageSize); |
|
210 |
|
211 createInfo.SetCreateChunk(NULL); |
|
212 createInfo.SetUseChunk(chunky); |
|
213 heap = (RHeap*)UserHeap::ChunkHeap(createInfo); |
|
214 if (heap == NULL) |
|
215 { |
|
216 test.Printf(_L("RHeap not created\n")); |
|
217 } |
|
218 test.Printf(_L("chunkHandle = %d heapHandle = %d\n"),chunky.Handle(), heap->ChunkHandle()); |
|
219 test_Equal(chunky.Handle(), heap->ChunkHandle()); |
|
220 heap->Close(); |
|
221 } |
|
222 |
|
223 test.Next(_L("Test SetUseChunk - calling SetCreate after")); |
|
224 { |
|
225 RHeap* heap; |
|
226 RChunk chunky; |
|
227 |
|
228 TChunkCreateInfo chunkCreateInfo; |
|
229 chunkCreateInfo.SetNormal(gPageSize, gPageSize); |
|
230 test_KErrNone(chunky.Create(chunkCreateInfo)); |
|
231 |
|
232 TChunkHeapCreateInfo createInfo(0, gPageSize); |
|
233 createInfo.SetUseChunk(chunky); |
|
234 createInfo.SetCreateChunk(NULL); |
|
235 |
|
236 heap = (RHeap*)UserHeap::ChunkHeap(createInfo); |
|
237 if (heap == NULL) |
|
238 { |
|
239 test.Printf(_L("RHeap not created\n")); |
|
240 } |
|
241 test.Printf(_L("chunkHandle = %d heapHandle = %d\n"),chunky.Handle(), heap->ChunkHandle()); |
|
242 TBool isSame = EFalse; |
|
243 if (chunky.Handle() == heap->ChunkHandle()) |
|
244 isSame = ETrue; |
|
245 test_Equal(EFalse, isSame); |
|
246 heap->Close(); |
|
247 } |
|
248 |
|
249 test.Next(_L("Test SetSingleThread - ETrue")); |
|
250 { |
|
251 RHeap* heap; |
|
252 TChunkHeapCreateInfo createInfo(0, gPageSize); |
|
253 UseOrCreateChunk(createInfo, aTestType); |
|
254 createInfo.SetSingleThread(ETrue); |
|
255 heap = (RHeap*)UserHeap::ChunkHeap(createInfo); |
|
256 test_NotNull(heap); |
|
257 heap->Close(); |
|
258 } |
|
259 |
|
260 test.Next(_L("Test SetSingleThread - EFalse")); |
|
261 { |
|
262 RHeap* heap; |
|
263 TChunkHeapCreateInfo createInfo(0, gPageSize); |
|
264 UseOrCreateChunk(createInfo, aTestType); |
|
265 createInfo.SetSingleThread(EFalse); |
|
266 heap = (RHeap*)UserHeap::ChunkHeap(createInfo); |
|
267 test_NotNull(heap); |
|
268 heap->Close(); |
|
269 } |
|
270 |
|
271 test.Next(_L("Test SetAlignment 0")); |
|
272 { |
|
273 RHeap* heap; |
|
274 TChunkHeapCreateInfo createInfo(0, gPageSize); |
|
275 UseOrCreateChunk(createInfo, aTestType); |
|
276 createInfo.SetAlignment(0); |
|
277 heap = (RHeap*)UserHeap::ChunkHeap(createInfo); |
|
278 test_NotNull(heap); |
|
279 heap->Close(); |
|
280 } |
|
281 |
|
282 |
|
283 test.Next(_L("Test SetAlignment -1")); |
|
284 { |
|
285 TChunkHeapCreateInfo createInfo(0, gPageSize); |
|
286 UseOrCreateChunk(createInfo, aTestType); |
|
287 createInfo.SetAlignment(-1); |
|
288 |
|
289 RThread thread; |
|
290 test_KErrNone(thread.Create(_L("Panic UserHeap"), PanicChunkHeapCreate, KDefaultStackSize, KMinHeapSize, |
|
291 KMinHeapSize, (TAny*) &createInfo)); |
|
292 |
|
293 test_KErrNone(TestThreadExit(thread, EExitPanic, ETHeapNewBadAlignment)); |
|
294 } |
|
295 |
|
296 |
|
297 test.Next(_L("Test SetGrowby")); |
|
298 { |
|
299 RHeap* heap; |
|
300 TChunkHeapCreateInfo createInfo(0, gPageSize * 10); |
|
301 UseOrCreateChunk(createInfo, aTestType); |
|
302 createInfo.SetGrowBy(gPageSize); |
|
303 createInfo.SetMode(UserHeap::EChunkHeapSwitchTo); |
|
304 heap = (RHeap*)UserHeap::ChunkHeap(createInfo); |
|
305 test_NotNull(heap); |
|
306 RChunk chunk; |
|
307 chunk.SetHandle(heap->ChunkHandle()); |
|
308 TInt* numBuf = new TInt[gPageSize]; |
|
309 test_NotNull(numBuf); |
|
310 test.Printf(_L("chunkSize = %d\n"), chunk.Size()); |
|
311 test(chunk.Size() > KMinHeapGrowBy); |
|
312 delete numBuf; |
|
313 heap->Close(); |
|
314 } |
|
315 |
|
316 test.Next(_L("Test SetGrowby growBy > maxSize")); |
|
317 { |
|
318 RHeap* heap; |
|
319 TChunkHeapCreateInfo createInfo(0, gPageSize * 5); |
|
320 UseOrCreateChunk(createInfo, aTestType); |
|
321 createInfo.SetGrowBy(gPageSize * 6); |
|
322 createInfo.SetMode(UserHeap::EChunkHeapSwitchTo); |
|
323 heap = (RHeap*)UserHeap::ChunkHeap(createInfo); |
|
324 test_NotNull(heap); |
|
325 RChunk chunk; |
|
326 chunk.SetHandle(heap->ChunkHandle()); |
|
327 TInt* numBuf = new TInt[gPageSize]; |
|
328 test_Equal(NULL, numBuf); |
|
329 |
|
330 delete numBuf; |
|
331 heap->Close(); |
|
332 } |
|
333 |
|
334 |
|
335 test.Next(_L("Test SetOffset ")); |
|
336 { |
|
337 RHeap* heap; |
|
338 TChunkHeapCreateInfo createInfo(0, gPageSize * 10); |
|
339 UseOrCreateChunk(createInfo, aTestType); |
|
340 createInfo.SetOffset(8); |
|
341 createInfo.SetMode(UserHeap::EChunkHeapSwitchTo); |
|
342 heap = (RHeap*)UserHeap::ChunkHeap(createInfo); |
|
343 TInt heapAddr = (TInt)heap; |
|
344 RChunk chunk; |
|
345 chunk.SetHandle(heap->ChunkHandle()); |
|
346 test_Equal((TInt)chunk.Base() + 8, heapAddr); |
|
347 test_NotNull(heap); |
|
348 heap->Close(); |
|
349 } |
|
350 |
|
351 test.Next(_L("Test UserHeap::ChunkHeap() SetMode() invalid")); |
|
352 { |
|
353 TChunkHeapCreateInfo createInfo(0, gPageSize); |
|
354 UseOrCreateChunk(createInfo, aTestType); |
|
355 |
|
356 // Test creating a UserHeap with invalid attributes panics. |
|
357 RThread thread; |
|
358 test_KErrNone(thread.Create(_L("Panic UserHeap"), PanicUserHeap, KDefaultStackSize, |
|
359 KMinHeapSize, KMinHeapSize, NULL)); |
|
360 test_KErrNone(TestThreadExit(thread, EExitPanic, EHeapCreateInvalidMode)); |
|
361 } |
|
362 |
|
363 test.End(); |
|
364 } |
|
365 |
|
366 TInt TestingTChunkHeapCreate() |
|
367 { |
|
368 test.Start(_L("Test TChunkHeapCreateInfo - heap within local chunk")); |
|
369 TestChunkHeapCreate(ETestLocal); |
|
370 |
|
371 test.Next(_L("Test TChunkHeapCreateInfo - heap within global chunk")); |
|
372 TestChunkHeapCreate(ETestGlobal); |
|
373 |
|
374 test.Next(_L("Test TChunkHeapCreateInfo - heap within existing chunk")); |
|
375 TestChunkHeapCreate(ETestExisting); |
|
376 |
|
377 test.End(); |
|
378 return 0; |
|
379 } |