2 * Copyright (c) 2020 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 #include <os/collections.h>
29 #include <darwintest.h>
32 T_DECL(map_basic_64
, "Make sure 64 bit map basics work",
33 T_META("owner", "Core Darwin Daemons & Tools"))
35 os_map_64_t basic_64_map
;
36 __block
bool got_cafebabe
= false;
37 __block
bool got_deadbeaf
= false;
42 // *** BASIC 64 bit key testing ***
44 os_map_init(&basic_64_map
, NULL
);
46 T_ASSERT_EQ(os_map_count(&basic_64_map
), 0, "Expect map to be empty");
48 os_map_insert(&basic_64_map
, 0xCAFECAFE, (void *)0xCAFEBABE);
49 os_map_insert(&basic_64_map
, 0xDEADDEAD, (void *)0xDEADBEEF);
51 T_ASSERT_EQ(os_map_count(&basic_64_map
), 2,
52 "Expect map to have 2 entries");
54 os_map_foreach(&basic_64_map
, ^bool (uint64_t key
, void *value
){
55 T_LOG("Foreach called for 0x%llx, 0x%llx",
56 (unsigned long long)key
, (unsigned long long)value
);
57 if (key
== 0xCAFECAFE) {
58 T_ASSERT_EQ(value
, (void *)0xCAFEBABE,
59 "Callback expect 0xCAFEBABE");
61 } else if (key
== 0xDEADDEAD) {
62 T_ASSERT_EQ(value
, (void *)0xDEADBEEF,
63 "Callback expec 0xDEADBEEF");
66 T_FAIL("Got unexpected callback 0x%llx, 0x%llx",
67 (unsigned long long)key
,
68 (unsigned long long)value
);
73 if (!got_cafebabe
|| !got_deadbeaf
) {
74 T_FAIL("Failed to get callback");
77 value
= (uint64_t)os_map_find(&basic_64_map
, 0xDEADDEAD);
78 T_ASSERT_EQ(value
, (uint64_t)0xDEADBEEF, "Find 1");
80 value
= (uint64_t)os_map_find(&basic_64_map
, 0xCAFECAFE);
81 T_ASSERT_EQ(value
, (uint64_t)0xCAFEBABE, "Find 2");
83 value
= (uint64_t)os_map_find(&basic_64_map
, 0xFF00F0F0);
84 T_ASSERT_EQ(value
, (uint64_t)0x0, "Find 3");
87 os_map_delete(&basic_64_map
, 0xDEADDEAD);
89 T_ASSERT_EQ(os_map_count(&basic_64_map
), 1,
90 "Expect map to have 1 entries");
92 value
= (uint64_t)os_map_find(&basic_64_map
, 0xDEADDEAD);
93 T_ASSERT_EQ(value
, (uint64_t)0x0, "After-delete Find 1");
95 value
= (uint64_t)os_map_find(&basic_64_map
, 0xCAFECAFE);
96 T_ASSERT_EQ(value
, (uint64_t)0xCAFEBABE, "After-delete find 2");
98 os_map_delete(&basic_64_map
, 0xCAFECAFE);
100 T_ASSERT_EQ(os_map_count(&basic_64_map
), 0,
101 "Expect map to be empty");
103 value
= (uint64_t)os_map_find(&basic_64_map
, 0xDEADDEAD);
104 T_ASSERT_EQ(value
, (uint64_t)0x0, "After-delete Find 3");
106 value
= (uint64_t)os_map_find(&basic_64_map
, 0xCAFECAFE);
107 T_ASSERT_EQ(value
, (uint64_t)0x0, "After-delete find 4");
109 os_map_destroy(&basic_64_map
);
112 T_DECL(map_basic_32
, "Make sure 32 bit map basics work",
113 T_META("owner", "Core Darwin Daemons & Tools"))
115 os_map_32_t basic_32_map
;
116 __block
bool got_cafebabe
= false;
117 __block
bool got_deadbeaf
= false;
122 os_map_init(&basic_32_map
, NULL
);
124 T_ASSERT_EQ(os_map_count(&basic_32_map
), 0, "Expect map to be empty");
126 os_map_insert(&basic_32_map
, 0xCAFECAFE, (void *)0xCAFEBABE);
127 os_map_insert(&basic_32_map
, 0xDEADDEAD, (void *)0xDEADBEEF);
129 T_ASSERT_EQ(os_map_count(&basic_32_map
), 2,
130 "Expect map to have 2 entries");
132 os_map_foreach(&basic_32_map
, ^bool (uint32_t key
, void *value
){
133 T_LOG("Foreach called for 0x%llx, 0x%llx",
134 (unsigned long long)key
, (unsigned long long)value
);
135 if (key
== 0xCAFECAFE) {
136 T_ASSERT_EQ(value
, (void *)0xCAFEBABE,
137 "Callback expect 0xCAFEBABE");
139 } else if (key
== 0xDEADDEAD) {
140 T_ASSERT_EQ(value
, (void *)0xDEADBEEF,
141 "Callback expec 0xDEADBEEF");
144 T_FAIL("Got unexpected callback 0x%llx, 0x%llx",
145 (unsigned long long)key
,
146 (unsigned long long)value
);
151 if (!got_cafebabe
|| !got_deadbeaf
) {
152 T_FAIL("Failed to get callback");
155 value
= (uint64_t)os_map_find(&basic_32_map
, 0xDEADDEAD);
156 T_ASSERT_EQ(value
, (uint64_t)0xDEADBEEF, "Find 1");
158 value
= (uint64_t)os_map_find(&basic_32_map
, 0xCAFECAFE);
159 T_ASSERT_EQ(value
, (uint64_t)0xCAFEBABE, "Find 2");
161 value
= (uint64_t)os_map_find(&basic_32_map
, 0xFF00F0F0);
162 T_ASSERT_EQ(value
, (uint64_t)0x0, "Find 3");
164 os_map_delete(&basic_32_map
, 0xDEADDEAD);
166 T_ASSERT_EQ(os_map_count(&basic_32_map
), 1,
167 "Expect map to have 1 entries");
169 value
= (uint64_t)os_map_find(&basic_32_map
, 0xDEADDEAD);
170 T_ASSERT_EQ(value
, (uint64_t)0x0, "After-delete Find 1");
172 value
= (uint64_t)os_map_find(&basic_32_map
, 0xCAFECAFE);
173 T_ASSERT_EQ(value
, (uint64_t)0xCAFEBABE, "After-delete find 2");
175 os_map_delete(&basic_32_map
, 0xCAFECAFE);
177 T_ASSERT_EQ(os_map_count(&basic_32_map
), 0, "Expect map to be empty");
179 value
= (uint64_t)os_map_find(&basic_32_map
, 0xDEADDEAD);
180 T_ASSERT_EQ(value
, (uint64_t)0x0, "After-delete Find 3");
182 value
= (uint64_t)os_map_find(&basic_32_map
, 0xCAFECAFE);
183 T_ASSERT_EQ(value
, (uint64_t)0x0, "After-delete find 4");
185 os_map_destroy(&basic_32_map
);
189 T_DECL(map_basic_string
, "Make sure string map basics work",
190 T_META("owner", "Core Darwin Daemons & Tools"))
192 os_map_str_t basic_string_map
;
193 __block
bool got_cafebabe
= false;
194 __block
bool got_deadbeaf
= false;
199 os_map_init(&basic_string_map
, NULL
);
201 T_ASSERT_EQ(os_map_count(&basic_string_map
), 0,
202 "Expect map to be empty");
204 os_map_insert(&basic_string_map
, "0xCAFECAFE", (void *)0xCAFEBABE);
205 os_map_insert(&basic_string_map
, "0xDEADDEAD", (void *)0xDEADBEEF);
207 T_ASSERT_EQ(os_map_count(&basic_string_map
), 2,
208 "Expect map to have 2 entries");
210 os_map_foreach(&basic_string_map
, ^bool (const char *key
, void *value
){
211 T_LOG("Foreach called for 0x%llx, 0x%llx",
212 (unsigned long long)key
, (unsigned long long)value
);
213 if (strcmp("0xCAFECAFE", key
) == 0) {
214 T_ASSERT_EQ(value
, (void *)0xCAFEBABE,
215 "Callback expect 0xCAFEBABE");
217 } else if (strcmp("0xDEADDEAD", key
) == 0) {
218 T_ASSERT_EQ(value
, (void *)0xDEADBEEF,
219 "Callback expec 0xDEADBEEF");
222 T_FAIL("Got unexpected callback 0x%llx, 0x%llx",
223 (unsigned long long)key
,
224 (unsigned long long)value
);
229 if (!got_cafebabe
|| !got_deadbeaf
) {
230 T_FAIL("Failed to get callback");
233 value
= (uint64_t)os_map_find(&basic_string_map
, "0xDEADDEAD");
234 T_ASSERT_EQ(value
, (uint64_t)0xDEADBEEF, "Find 1");
236 value
= (uint64_t)os_map_find(&basic_string_map
, "0xCAFECAFE");
237 T_ASSERT_EQ(value
, (uint64_t)0xCAFEBABE, "Find 2");
239 value
= (uint64_t)os_map_find(&basic_string_map
, "0xFF00F0F0");
240 T_ASSERT_EQ(value
, (uint64_t)0x0, "Find 3");
243 os_map_delete(&basic_string_map
, "0xDEADDEAD");
245 T_ASSERT_EQ(os_map_count(&basic_string_map
), 1,
246 "Expect map to have 1 entries");
248 value
= (uint64_t)os_map_find(&basic_string_map
, "0xDEADDEAD");
249 T_ASSERT_EQ(value
, (uint64_t)0x0, "After-delete Find 1");
251 value
= (uint64_t)os_map_find(&basic_string_map
, "0xCAFECAFE");
252 T_ASSERT_EQ(value
, (uint64_t)0xCAFEBABE, "After-delete find 2");
254 os_map_delete(&basic_string_map
, "0xCAFECAFE");
256 T_ASSERT_EQ(os_map_count(&basic_string_map
), 0,
257 "Expect map to be empty");
259 value
= (uint64_t)os_map_find(&basic_string_map
, "0xDEADDEAD");
260 T_ASSERT_EQ(value
, (uint64_t)0x0, "After-delete Find 3");
262 value
= (uint64_t)os_map_find(&basic_string_map
, "0xCAFECAFE");
263 T_ASSERT_EQ(value
, (uint64_t)0x0, "After-delete find 4");
265 os_map_destroy(&basic_string_map
);
268 T_DECL(map_entry_string
, "Make sure string entry fetching works",
269 T_META("owner", "Core Darwin Daemons & Tools"))
272 os_map_str_t basic_string_map
;
276 os_map_init(&basic_string_map
, NULL
);
278 os_map_insert(&basic_string_map
, "CAFE", (void *)0xCAFEBABE);
280 // Extra steps are taken to make sure the lookup strings aren't compiled
281 // to the same pointer.
282 volatile char lookup_string_1
[5];
283 sprintf(lookup_string_1
, "CAFE");
284 volatile char lookup_string_2
[5];
285 sprintf(lookup_string_2
, "CAFE");
287 T_ASSERT_EQ(strcmp(&lookup_string_1
, "CAFE"), 0,
288 "Expect lookup strings to be CAFE");
289 T_ASSERT_EQ(strcmp(&lookup_string_2
, "CAFE"), 0,
290 "Expect lookup strings to be CAFE");
291 T_ASSERT_NE(&lookup_string_1
, &lookup_string_2
,
292 "Expect lookup strings to be different");
294 const char *entry_string_1
= os_map_entry(&basic_string_map
,
297 T_ASSERT_NOTNULL(entry_string_1
, "Expect entry strings to be nonnull");
298 T_ASSERT_EQ(strcmp(entry_string_1
, "CAFE"), 0,
299 "Expect entry strings to be CAFE");
301 const char *entry_string_2
= os_map_entry(&basic_string_map
,
304 T_ASSERT_NE(entry_string_2
, NULL
, "Expect entry strings to be nonnull");
305 T_ASSERT_EQ(strcmp(entry_string_2
, "CAFE"), 0,
306 "Expect entry strings to be CAFE");
308 T_ASSERT_EQ(entry_string_1
, entry_string_2
,
309 "Expect entry strings to be literally equal");
311 os_map_destroy(&basic_string_map
);
314 T_DECL(map_basic_128
, "Make sure 64 bit map basics work",
315 T_META("owner", "Core Darwin Daemons & Tools"))
317 os_map_128_t basic_128_map
;
318 __block
bool got_cafebabe
= false;
319 __block
bool got_deadbeaf
= false;
324 // *** BASIC 64 bit key testing ***
326 os_map_init(&basic_128_map
, NULL
);
328 T_ASSERT_EQ(os_map_count(&basic_128_map
), 0, "Expect map to be empty");
330 os_map_128_key_t key
;
332 key
.x
[0] = 0xCAFECAFE;
333 key
.x
[1] = 0xBABEBABE;
334 os_map_insert(&basic_128_map
, key
, (void *)0xCAFEBABE);
336 key
.x
[0] = 0xDEADDEAD;
337 key
.x
[1] = 0xBEEFBEEF;
338 os_map_insert(&basic_128_map
, key
, (void *)0xDEADBEEF);
340 T_ASSERT_EQ(os_map_count(&basic_128_map
), 2, "Expect map to have 2 entries");
342 os_map_foreach(&basic_128_map
, ^bool (os_map_128_key_t key
, void *value
){
343 T_LOG("Foreach called for 0x%llx:0x%llx, 0x%llx",
344 (unsigned long long)key
.x
[0], (unsigned long long)key
.x
[1],
345 (unsigned long long)value
);
346 if (key
.x
[0] == 0xCAFECAFE && key
.x
[1] == 0xBABEBABE) {
347 T_ASSERT_EQ(value
, (void *)0xCAFEBABE,
348 "Callback expect 0xCAFEBABE");
350 } else if (key
.x
[0] == 0xDEADDEAD && key
.x
[1] == 0xBEEFBEEF) {
351 T_ASSERT_EQ(value
, (void *)0xDEADBEEF, "Callback expec 0xDEADBEEF");
354 T_FAIL("Got unexpected callback 0x%llx:0x%llx, 0x%llx",
355 (unsigned long long)key
.x
[0], (unsigned long long)key
.x
[1],
356 (unsigned long long)value
);
361 if (!got_cafebabe
|| !got_deadbeaf
) {
362 T_FAIL("Failed to get callback");
365 key
.x
[0] = 0xCAFECAFE;
366 key
.x
[1] = 0xBABEBABE;
367 value
= (uint64_t)os_map_find(&basic_128_map
, key
);
368 T_ASSERT_EQ(value
, (uint64_t)0xCAFEBABE, "Find 1");
370 key
.x
[0] = 0xDEADDEAD;
371 key
.x
[1] = 0xBEEFBEEF;
372 value
= (uint64_t)os_map_find(&basic_128_map
, key
);
373 T_ASSERT_EQ(value
, (uint64_t)0xDEADBEEF, "Find 2");
375 key
.x
[0] = 0xFF00F0F0;
376 key
.x
[1] = 0xFF00F0F0;
377 value
= (uint64_t)os_map_find(&basic_128_map
, key
);
378 T_ASSERT_EQ(value
, (uint64_t)0x0, "Find 3");
380 key
.x
[0] = 0xFF00F0F0;
381 key
.x
[1] = 0xBABEBABE;
382 value
= (uint64_t)os_map_find(&basic_128_map
, key
);
383 T_ASSERT_EQ(value
, (uint64_t)0x0, "Find 4");
385 key
.x
[0] = 0xCAFECAFE;
386 key
.x
[1] = 0xFF00F0F0;
387 value
= (uint64_t)os_map_find(&basic_128_map
, key
);
388 T_ASSERT_EQ(value
, (uint64_t)0x0, "Find 5");
390 key
.x
[0] = 0xDEADDEAD;
391 key
.x
[1] = 0xBEEFBEEF;
392 os_map_delete(&basic_128_map
, key
);
394 T_ASSERT_EQ(os_map_count(&basic_128_map
), 1,
395 "Expect map to have 1 entries");
397 key
.x
[0] = 0xDEADDEAD;
398 key
.x
[1] = 0xBEEFBEEF;
399 value
= (uint64_t)os_map_find(&basic_128_map
, key
);
400 T_ASSERT_EQ(value
, (uint64_t)0x0, "After-delete Find 1");
402 key
.x
[0] = 0xCAFECAFE;
403 key
.x
[1] = 0xBABEBABE;
404 value
= (uint64_t)os_map_find(&basic_128_map
, key
);
405 T_ASSERT_EQ(value
, (uint64_t)0xCAFEBABE, "After-delete find 2");
407 key
.x
[0] = 0xCAFECAFE;
408 key
.x
[1] = 0xBABEBABE;
409 os_map_delete(&basic_128_map
, key
);
411 T_ASSERT_EQ(os_map_count(&basic_128_map
), 0, "Expect map to be empty");
413 key
.x
[0] = 0xDEADDEAD;
414 key
.x
[1] = 0xBEEFBEEF;
415 value
= (uint64_t)os_map_find(&basic_128_map
, key
);
416 T_ASSERT_EQ(value
, (uint64_t)0x0, "After-delete Find 3");
418 key
.x
[0] = 0xCAFECAFE;
419 key
.x
[1] = 0xBABEBABE;
420 value
= (uint64_t)os_map_find(&basic_128_map
, key
);
421 T_ASSERT_EQ(value
, (uint64_t)0x0, "After-delete find 4");
423 os_map_destroy(&basic_128_map
);