aboutsummaryrefslogtreecommitdiff
path: root/src/test/DUtilUnitTest/MemUtilTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/DUtilUnitTest/MemUtilTest.cpp')
-rw-r--r--src/test/DUtilUnitTest/MemUtilTest.cpp491
1 files changed, 491 insertions, 0 deletions
diff --git a/src/test/DUtilUnitTest/MemUtilTest.cpp b/src/test/DUtilUnitTest/MemUtilTest.cpp
new file mode 100644
index 00000000..6dec9682
--- /dev/null
+++ b/src/test/DUtilUnitTest/MemUtilTest.cpp
@@ -0,0 +1,491 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5using namespace System;
6using namespace Xunit;
7using namespace WixTest;
8
9namespace DutilTests
10{
11 struct ArrayValue
12 {
13 DWORD dwNum;
14 void *pvNull1;
15 LPWSTR sczString;
16 void *pvNull2;
17 };
18
19 public ref class MemUtil
20 {
21 public:
22 [Fact]
23 void MemUtilAppendTest()
24 {
25 HRESULT hr = S_OK;
26 DWORD dwSize;
27 ArrayValue *rgValues = NULL;
28 DWORD cValues = 0;
29
30 try
31 {
32 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5);
33 NativeAssert::Succeeded(hr, "Failed to grow array size to 1");
34 ++cValues;
35 SetItem(rgValues + 0, 0);
36
37 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5);
38 NativeAssert::Succeeded(hr, "Failed to grow array size to 2");
39 ++cValues;
40 SetItem(rgValues + 1, 1);
41
42 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5);
43 NativeAssert::Succeeded(hr, "Failed to grow array size to 3");
44 ++cValues;
45 SetItem(rgValues + 2, 2);
46
47 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5);
48 NativeAssert::Succeeded(hr, "Failed to grow array size to 4");
49 ++cValues;
50 SetItem(rgValues + 3, 3);
51
52 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5);
53 NativeAssert::Succeeded(hr, "Failed to grow array size to 5");
54 ++cValues;
55 SetItem(rgValues + 4, 4);
56
57 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5);
58 NativeAssert::Succeeded(hr, "Failed to grow array size to 6");
59 ++cValues;
60 SetItem(rgValues + 5, 5);
61
62 // OK, we used growth size 5, so let's try ensuring we have space for 6 (5 + first item) items
63 // and make sure it doesn't grow since we already have enough space
64 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues, sizeof(ArrayValue), 5);
65 NativeAssert::Succeeded(hr, "Failed to ensure array size matches what it should already be");
66 dwSize = MemSize(rgValues);
67 if (dwSize != 6 * sizeof(ArrayValue))
68 {
69 hr = E_FAIL;
70 ExitOnFailure(hr, "MemEnsureArraySize is growing an array that is already big enough!");
71 }
72
73 for (DWORD i = 0; i < cValues; ++i)
74 {
75 CheckItem(rgValues + i, i);
76 }
77
78 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5);
79 NativeAssert::Succeeded(hr, "Failed to grow array size to 7");
80 ++cValues;
81 SetItem(rgValues + 6, 6);
82
83 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5);
84 NativeAssert::Succeeded(hr, "Failed to grow array size to 7");
85 ++cValues;
86 SetItem(rgValues + 7, 7);
87
88 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5);
89 NativeAssert::Succeeded(hr, "Failed to grow array size to 7");
90 ++cValues;
91 SetItem(rgValues + 8, 8);
92
93 for (DWORD i = 0; i < cValues; ++i)
94 {
95 CheckItem(rgValues + i, i);
96 }
97 }
98 finally
99 {
100 ReleaseMem(rgValues);
101 }
102
103 LExit:
104 return;
105 }
106
107 [Fact]
108 void MemUtilInsertTest()
109 {
110 HRESULT hr = S_OK;
111 ArrayValue *rgValues = NULL;
112 DWORD cValues = 0;
113
114 try
115 {
116 hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 0, 1, cValues + 1, sizeof(ArrayValue), 5);
117 NativeAssert::Succeeded(hr, "Failed to insert into beginning of empty array");
118 ++cValues;
119 CheckNullItem(rgValues + 0);
120 SetItem(rgValues + 0, 5);
121
122 hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 1, 1, cValues + 1, sizeof(ArrayValue), 5);
123 NativeAssert::Succeeded(hr, "Failed to insert at end of array");
124 ++cValues;
125 CheckNullItem(rgValues + 1);
126 SetItem(rgValues + 1, 6);
127
128 hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 0, 1, cValues + 1, sizeof(ArrayValue), 5);
129 NativeAssert::Succeeded(hr, "Failed to insert into beginning of array");
130 ++cValues;
131 CheckNullItem(rgValues + 0);
132 SetItem(rgValues + 0, 4);
133
134 hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 0, 1, cValues + 1, sizeof(ArrayValue), 5);
135 NativeAssert::Succeeded(hr, "Failed to insert into beginning of array");
136 ++cValues;
137 CheckNullItem(rgValues + 0);
138 SetItem(rgValues + 0, 3);
139
140 hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 0, 1, cValues + 1, sizeof(ArrayValue), 5);
141 NativeAssert::Succeeded(hr, "Failed to insert into beginning of array");
142 ++cValues;
143 CheckNullItem(rgValues + 0);
144 SetItem(rgValues + 0, 1);
145
146 hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 1, 1, cValues + 1, sizeof(ArrayValue), 5);
147 NativeAssert::Succeeded(hr, "Failed to insert into beginning of array");
148 ++cValues;
149 CheckNullItem(rgValues + 1);
150 SetItem(rgValues + 1, 2);
151
152 hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 0, 1, cValues + 1, sizeof(ArrayValue), 5);
153 NativeAssert::Succeeded(hr, "Failed to insert into beginning of array");
154 ++cValues;
155 CheckNullItem(rgValues + 0);
156 SetItem(rgValues + 0, 0);
157
158 for (DWORD i = 0; i < cValues; ++i)
159 {
160 CheckItem(rgValues + i, i);
161 }
162
163 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), cValues + 1, sizeof(ArrayValue), 5);
164 NativeAssert::Succeeded(hr, "Failed to grow array size to 7");
165 ++cValues;
166 CheckNullItem(rgValues + 7);
167 SetItem(rgValues + 7, 7);
168
169 hr = MemInsertIntoArray(reinterpret_cast<LPVOID*>(&rgValues), 8, 1, cValues + 1, sizeof(ArrayValue), 5);
170 NativeAssert::Succeeded(hr, "Failed to insert into beginning of array");
171 ++cValues;
172 CheckNullItem(rgValues + 8);
173 SetItem(rgValues + 8, 8);
174
175 for (DWORD i = 0; i < cValues; ++i)
176 {
177 CheckItem(rgValues + i, i);
178 }
179 }
180 finally
181 {
182 ReleaseMem(rgValues);
183 }
184 }
185
186 [Fact]
187 void MemUtilRemovePreserveOrderTest()
188 {
189 HRESULT hr = S_OK;
190 ArrayValue *rgValues = NULL;
191 DWORD cValues = 0;
192
193 try
194 {
195 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), 10, sizeof(ArrayValue), 10);
196 NativeAssert::Succeeded(hr, "Failed to grow array size to 10");
197
198 cValues = 10;
199 for (DWORD i = 0; i < cValues; ++i)
200 {
201 SetItem(rgValues + i, i);
202 }
203
204 // Remove last item
205 MemRemoveFromArray(rgValues, 9, 1, cValues, sizeof(ArrayValue), TRUE);
206 --cValues;
207
208 for (DWORD i = 0; i < cValues; ++i)
209 {
210 CheckItem(rgValues + i, i);
211 }
212
213 // Remove last two items
214 MemRemoveFromArray(rgValues, 7, 2, cValues, sizeof(ArrayValue), TRUE);
215 cValues -= 2;
216
217 for (DWORD i = 0; i < cValues; ++i)
218 {
219 CheckItem(rgValues + i, i);
220 }
221
222 // Remove first item
223 MemRemoveFromArray(rgValues, 0, 1, cValues, sizeof(ArrayValue), TRUE);
224 --cValues;
225
226 for (DWORD i = 0; i < cValues; ++i)
227 {
228 CheckItem(rgValues + i, i + 1);
229 }
230
231
232 // Remove first two items
233 MemRemoveFromArray(rgValues, 0, 2, cValues, sizeof(ArrayValue), TRUE);
234 cValues -= 2;
235
236 for (DWORD i = 0; i < cValues; ++i)
237 {
238 CheckItem(rgValues + i, i + 3);
239 }
240
241 // Remove middle two items
242 MemRemoveFromArray(rgValues, 1, 2, cValues, sizeof(ArrayValue), TRUE);
243 cValues -= 2;
244
245 CheckItem(rgValues, 3);
246 CheckItem(rgValues + 1, 6);
247
248 // Remove last 2 items to ensure we don't crash
249 MemRemoveFromArray(rgValues, 0, 2, cValues, sizeof(ArrayValue), TRUE);
250 cValues -= 2;
251 }
252 finally
253 {
254 ReleaseMem(rgValues);
255 }
256 }
257
258 [Fact]
259 void MemUtilRemoveFastTest()
260 {
261 HRESULT hr = S_OK;
262 ArrayValue *rgValues = NULL;
263 DWORD cValues = 0;
264
265 try
266 {
267 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), 10, sizeof(ArrayValue), 10);
268 NativeAssert::Succeeded(hr, "Failed to grow array size to 10");
269
270 cValues = 10;
271 for (DWORD i = 0; i < cValues; ++i)
272 {
273 SetItem(rgValues + i, i);
274 }
275
276 // Remove last item
277 MemRemoveFromArray(rgValues, 9, 1, cValues, sizeof(ArrayValue), FALSE);
278 --cValues;
279
280 for (DWORD i = 0; i < cValues; ++i)
281 {
282 CheckItem(rgValues + i, i);
283 }
284
285 // Remove last two items
286 MemRemoveFromArray(rgValues, 7, 2, cValues, sizeof(ArrayValue), FALSE);
287 cValues -= 2;
288
289 for (DWORD i = 0; i < cValues; ++i)
290 {
291 CheckItem(rgValues + i, i);
292 }
293
294 // Remove first item
295 MemRemoveFromArray(rgValues, 0, 1, cValues, sizeof(ArrayValue), FALSE);
296 --cValues;
297
298 CheckItem(rgValues, 6);
299 CheckItem(rgValues + 1, 1);
300 CheckItem(rgValues + 2, 2);
301 CheckItem(rgValues + 3, 3);
302 CheckItem(rgValues + 4, 4);
303 CheckItem(rgValues + 5, 5);
304
305 // Remove first two items
306 MemRemoveFromArray(rgValues, 0, 2, cValues, sizeof(ArrayValue), FALSE);
307 cValues -= 2;
308
309 CheckItem(rgValues, 4);
310 CheckItem(rgValues + 1, 5);
311 CheckItem(rgValues + 2, 2);
312 CheckItem(rgValues + 3, 3);
313
314
315 // Remove middle two items
316 MemRemoveFromArray(rgValues, 1, 2, cValues, sizeof(ArrayValue), FALSE);
317 cValues -= 2;
318
319 CheckItem(rgValues, 4);
320 CheckItem(rgValues + 1, 3);
321
322 // Remove last 2 items to ensure we don't crash
323 MemRemoveFromArray(rgValues, 0, 2, cValues, sizeof(ArrayValue), FALSE);
324 cValues -= 2;
325 }
326 finally
327 {
328 ReleaseMem(rgValues);
329 }
330 }
331
332 [Fact]
333 void MemUtilSwapTest()
334 {
335 HRESULT hr = S_OK;
336 ArrayValue *rgValues = NULL;
337 DWORD cValues = 0;
338
339 try
340 {
341 hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&rgValues), 10, sizeof(ArrayValue), 10);
342 NativeAssert::Succeeded(hr, "Failed to grow array size to 10");
343
344 cValues = 10;
345 for (DWORD i = 0; i < cValues; ++i)
346 {
347 SetItem(rgValues + i, i);
348 }
349
350 // Swap first two
351 MemArraySwapItems(rgValues, 0, 1, sizeof(ArrayValue));
352 --cValues;
353
354 CheckItem(rgValues, 1);
355 CheckItem(rgValues + 1, 0);
356 for (DWORD i = 2; i < cValues; ++i)
357 {
358 CheckItem(rgValues + i, i);
359 }
360
361 // Swap them back
362 MemArraySwapItems(rgValues, 0, 1, sizeof(ArrayValue));
363 --cValues;
364
365 for (DWORD i = 0; i < cValues; ++i)
366 {
367 CheckItem(rgValues + i, i);
368 }
369
370 // Swap first and last items (index 0 and 9)
371 MemArraySwapItems(rgValues, 0, 9, sizeof(ArrayValue));
372 --cValues;
373
374 CheckItem(rgValues, 9);
375 CheckItem(rgValues + 9, 0);
376 for (DWORD i = 1; i < cValues - 1; ++i)
377 {
378 CheckItem(rgValues + i, i);
379 }
380
381 // Swap index 1 and 8
382 MemArraySwapItems(rgValues, 1, 8, sizeof(ArrayValue));
383 --cValues;
384
385 CheckItem(rgValues, 9);
386 CheckItem(rgValues + 1, 8);
387 CheckItem(rgValues + 8, 1);
388 CheckItem(rgValues + 9, 0);
389 for (DWORD i = 2; i < cValues - 2; ++i)
390 {
391 CheckItem(rgValues + i, i);
392 }
393
394 // Swap index 2 and 7
395 MemArraySwapItems(rgValues, 2, 7, sizeof(ArrayValue));
396 --cValues;
397
398 CheckItem(rgValues, 9);
399 CheckItem(rgValues + 1, 8);
400 CheckItem(rgValues + 2, 7);
401 CheckItem(rgValues + 7, 2);
402 CheckItem(rgValues + 8, 1);
403 CheckItem(rgValues + 9, 0);
404 for (DWORD i = 3; i < cValues - 3; ++i)
405 {
406 CheckItem(rgValues + i, i);
407 }
408
409 // Swap index 0 and 1
410 MemArraySwapItems(rgValues, 0, 1, sizeof(ArrayValue));
411 --cValues;
412
413 CheckItem(rgValues, 8);
414 CheckItem(rgValues + 1, 9);
415 CheckItem(rgValues + 2, 7);
416 CheckItem(rgValues + 7, 2);
417 CheckItem(rgValues + 8, 1);
418 CheckItem(rgValues + 9, 0);
419 for (DWORD i = 3; i < cValues - 3; ++i)
420 {
421 CheckItem(rgValues + i, i);
422 }
423 }
424 finally
425 {
426 ReleaseMem(rgValues);
427 }
428 }
429
430 private:
431 void SetItem(ArrayValue *pValue, DWORD dwValue)
432 {
433 HRESULT hr = S_OK;
434 pValue->dwNum = dwValue;
435
436 hr = StrAllocFormatted(&pValue->sczString, L"%u", dwValue);
437 NativeAssert::Succeeded(hr, "Failed to allocate string");
438 }
439
440 void CheckItem(ArrayValue *pValue, DWORD dwValue)
441 {
442 HRESULT hr = S_OK;
443 LPWSTR sczTemp = NULL;
444
445 try
446 {
447 NativeAssert::Equal(dwValue, pValue->dwNum);
448
449 hr = StrAllocFormatted(&sczTemp, L"%u", dwValue);
450 NativeAssert::Succeeded(hr, "Failed to allocate temp string");
451
452 NativeAssert::StringEqual(sczTemp, pValue->sczString, TRUE);
453
454 if (pValue->pvNull1 || pValue->pvNull2)
455 {
456 hr = E_FAIL;
457 ExitOnFailure(hr, "One of the expected NULL values wasn't NULL!");
458 }
459 }
460 finally
461 {
462 ReleaseStr(sczTemp);
463 }
464
465 LExit:
466 return;
467 }
468
469 void CheckNullItem(ArrayValue *pValue)
470 {
471 HRESULT hr = S_OK;
472
473 NativeAssert::Equal<DWORD>(0, pValue->dwNum);
474
475 if (pValue->sczString)
476 {
477 hr = E_FAIL;
478 ExitOnFailure(hr, "Item found isn't NULL!");
479 }
480
481 if (pValue->pvNull1 || pValue->pvNull2)
482 {
483 hr = E_FAIL;
484 ExitOnFailure(hr, "One of the expected NULL values wasn't NULL!");
485 }
486
487 LExit:
488 return;
489 }
490 };
491}