diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2020-07-11 21:11:30 +1000 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2020-07-12 11:51:29 +1000 |
commit | 9c4b5559ccb55491fe68b0096d1be0496fd6fcc7 (patch) | |
tree | faa51204fc2e6e3dfd1b00ae03c7184c4fb0b4bf /src/test/DUtilUnitTest/MemUtilTest.cpp | |
parent | f651268309263fa67fa84caf9fb6dbebb5c900d9 (diff) | |
download | wix-9c4b5559ccb55491fe68b0096d1be0496fd6fcc7.tar.gz wix-9c4b5559ccb55491fe68b0096d1be0496fd6fcc7.tar.bz2 wix-9c4b5559ccb55491fe68b0096d1be0496fd6fcc7.zip |
Import DUtilUnitTest from old wix4 repo.
Diffstat (limited to 'src/test/DUtilUnitTest/MemUtilTest.cpp')
-rw-r--r-- | src/test/DUtilUnitTest/MemUtilTest.cpp | 491 |
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 | |||
5 | using namespace System; | ||
6 | using namespace Xunit; | ||
7 | using namespace WixTest; | ||
8 | |||
9 | namespace 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 | } | ||