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