]> git.saurik.com Git - apple/xnu.git/blob - iokit/Tests/TestContainers.cpp
xnu-344.49.tar.gz
[apple/xnu.git] / iokit / Tests / TestContainers.cpp
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 #if DEBUG
26 #include "Tests.h"
27
28 #include <libkern/c++/OSData.h>
29 #include <libkern/c++/OSString.h>
30 #include <libkern/c++/OSSymbol.h>
31
32 static const char testC00[] = "The quick brown fox jumps over the lazy dog. ";
33 static const char testC01[] = "The quick brown fox ";
34 static const char testC02[] = "jumps over the ";
35 static const char testC03[] = "lazy dog. \n";
36 static const char testC04[] = "The ";
37 static const char testC05[] = "quick ";
38 static const char testC06[] = "brown ";
39 static const char testC07[] = "fox ";
40 static const char testC08[] = "jumps ";
41 static const char testC09[] = "over ";
42 static const char testC10[] = "the ";
43 static const char testC11[] = "lazy ";
44 static const char testC12[] = "dog. \n";
45 static const char testC13[] = "Now is the time for all good "
46 "men to come to the aid of the party \n";
47 static const char testC14[] = "Now is the time for ";
48 static const char testC15[] = "all good men to come ";
49 static const char testC16[] = "to the aid of the party \n";
50 static const char testC17[] = "Now ";
51 static const char testC18[] = "is ";
52 static const char testC19[] = "the ";
53 static const char testC20[] = "time ";
54 static const char testC21[] = "for ";
55 static const char testC22[] = "all ";
56 static const char testC23[] = "good ";
57 static const char testC24[] = "men ";
58 static const char testC25[] = "to ";
59 static const char testC26[] = "come ";
60 static const char testC27[] = "to ";
61 static const char testC28[] = "the ";
62 static const char testC29[] = "aid ";
63 static const char testC30[] = "of ";
64 static const char testC31[] = "the ";
65 static const char testC32[] = "party. \n";
66 static const char testC33[] = "Frank Burns eats worms. \n";
67 static const char testC34[] = "Frank Burns ";
68 static const char testC35[] = "eats worms. \n";
69 static const char testC36[] = "Frank ";
70 static const char testC37[] = "Burns ";
71 static const char testC38[] = "eats ";
72 static const char testC39[] = "worms. \n";
73 static const char testC40[] = "Tired eyes? Stiff neck? Tight shoulders? "
74 "Aching back? The right moves can help "
75 "prevent these kinds of problem. ";
76 static const char testC41[] = "Tired eyes? Stiff neck? ";
77 static const char testC42[] = "Tight shoulders? Aching back? ";
78 static const char testC43[] = "The right moves can help prevent ";
79 static const char testC44[] = "these kinds of problem. ";
80 static const char testC45[] = "Tired ";
81 static const char testC46[] = "eyes? ";
82 static const char testC47[] = "Stiff ";
83 static const char testC48[] = "neck? ";
84 static const char testC49[] = "Tight ";
85 static const char testC50[] = "shoulders? ";
86 static const char testC51[] = "Aching ";
87 static const char testC52[] = "back? ";
88 static const char testC53[] = "The ";
89 static const char testC54[] = "right ";
90 static const char testC55[] = "moves ";
91 static const char testC56[] = "can ";
92 static const char testC57[] = "help ";
93 static const char testC58[] = "prevent ";
94 static const char testC59[] = "these ";
95 static const char testC60[] = "kinds ";
96 static const char testC61[] = "of ";
97 static const char testC62[] = "problem. ";
98
99 const char *strCache[] = {
100 testC00, testC01, testC02, testC03, testC04, testC05, testC06, testC07,
101 testC08, testC09, testC10, testC11, testC12, testC13, testC14, testC15,
102 testC16, testC17, testC18, testC19, testC20, testC21, testC22, testC23,
103 testC24, testC25, testC26, testC27, testC28, testC29, testC30, testC31,
104 testC32, testC33, testC34, testC35, testC36, testC37, testC38, testC39,
105 testC40, testC41, testC42, testC43, testC44, testC45, testC46, testC47,
106 testC48, testC49, testC50, testC51, testC52, testC53, testC54, testC55,
107 testC56, testC57, testC58, testC59, testC60, testC61, testC62,
108 };
109 const int numStrCache = ((int) (sizeof(strCache)/sizeof(strCache[0])));
110
111 void testData()
112 {
113 #define DATA_SIZE_1 256
114 #define DATA_SIZE_2 512
115 #define DATA_SIZE_3 1024
116 #define DATA_SIZE_4 8192
117
118 OSData *test1, *test2, *test3;
119 void *spaceCheck;
120 unsigned int len;
121 unsigned int i;
122 bool res = true;
123 unsigned short testData[DATA_SIZE_4/sizeof(short)], *cp;
124
125 // very first test initialises the OSMetaClass cache.
126 test1 = OSData::withCapacity(DATA_SIZE_1);
127 TEST_ASSERT('d', "0a", test1);
128 if (test1)
129 test1->release();
130
131 for (i = 0; i < sizeof(testData)/sizeof(short); i++)
132 testData[i] = (unsigned short) i;
133
134 // Check empty data allocation
135 spaceCheck = checkPointSpace();
136 test1 = OSData::withCapacity(DATA_SIZE_1);
137 TEST_ASSERT('d', "1a", test1);
138 if (test1) {
139 TEST_ASSERT('d', "1b", !test1->getLength());
140 TEST_ASSERT('d', "1c", test1->getCapacity() == DATA_SIZE_1);
141 TEST_ASSERT('d', "1d", !test1->getBytesNoCopy());
142 TEST_ASSERT('d', "1e", !test1->getBytesNoCopy(10, DATA_SIZE_1 - 10));
143 TEST_ASSERT('d', "1f", test1->appendBytes(spaceCheck, 0));
144 TEST_ASSERT('d', "1g", !test1->getLength());
145 TEST_ASSERT('d', "1h", test1->getCapacity() == DATA_SIZE_1);
146 TEST_ASSERT('d', "1i", !test1->getBytesNoCopy());
147 test1->release();
148 }
149 res = res && checkSpace("(d)1", spaceCheck, 0);
150
151 // Check appending to empty data allocation
152 spaceCheck = checkPointSpace();
153 test1 = OSData::withCapacity(DATA_SIZE_1);
154 TEST_ASSERT('d', "2a", test1);
155 if (test1) {
156 TEST_ASSERT('d', "2b", !test1->getLength());
157 TEST_ASSERT('d', "2c", !test1->getBytesNoCopy());
158 TEST_ASSERT('d', "2d", test1->appendBytes(testData, DATA_SIZE_1));
159 TEST_ASSERT('d', "2e", test1->getLength() == DATA_SIZE_1);
160 TEST_ASSERT('d', "2f", test1->getBytesNoCopy());
161 cp = (unsigned short *) test1->getBytesNoCopy();
162 for (i = 0; cp && i < (DATA_SIZE_1/sizeof(short)); i++) {
163 TEST_ASSERT('d', "2g", *cp++ == testData[i]);
164 if (*cp != testData[i])
165 break;
166 }
167 TEST_ASSERT('d', "2h", test1->getBytesNoCopy(10, DATA_SIZE_1-10));
168 cp = (unsigned short *) test1->getBytesNoCopy(10, DATA_SIZE_1 - 10);
169 for (i = 5; cp && i < (DATA_SIZE_1/sizeof(short)) - 5; i++) {
170 TEST_ASSERT('d', "2i", *cp++ == testData[i]);
171 if (*cp != testData[i])
172 break;
173 }
174 TEST_ASSERT('d', "2j", test1->isEqualTo(testData, DATA_SIZE_1));
175 test1->release();
176 }
177 res = res && checkSpace("(d)2", spaceCheck, 0);
178
179 // Check data allocation from some constant data
180 spaceCheck = checkPointSpace();
181 test1 = OSData::withBytes(testData, sizeof(testData));
182 TEST_ASSERT('d', "3a", test1);
183 if (test1) {
184 TEST_ASSERT('d', "3b", test1->getLength() == sizeof(testData));
185 TEST_ASSERT('d', "3c", test1->getCapacity() == sizeof(testData));
186 TEST_ASSERT('d', "3d", test1->getBytesNoCopy());
187 TEST_ASSERT('d', "3e", test1->getBytesNoCopy(10, sizeof(testData)-10));
188 TEST_ASSERT('d', "3f", test1->appendBytes(spaceCheck, 0));
189 TEST_ASSERT('d', "3g", test1->getLength() == sizeof(testData));
190 TEST_ASSERT('d', "3h", test1->getCapacity() == sizeof(testData));
191 TEST_ASSERT('d', "3i", test1->getBytesNoCopy());
192 TEST_ASSERT('d', "3j", test1->getBytesNoCopy(10, sizeof(testData)-10));
193 TEST_ASSERT('d', "3k", !test1->appendBytes(testData, 10));
194 test1->release();
195 }
196 res = res && checkSpace("(d)3", spaceCheck, 0);
197
198 // Check and continious addition of more data
199 spaceCheck = checkPointSpace();
200 test1 = OSData::withCapacity(DATA_SIZE_4);
201 test2 = OSData::withBytesNoCopy(testData, DATA_SIZE_3);
202 len = DATA_SIZE_3;
203 TEST_ASSERT('d', "4a", (test1 && test2));
204 if (test1 && test2) {
205 TEST_ASSERT('d', "4b", !test1->getLength());
206 for (i = 0; i < DATA_SIZE_4; i += DATA_SIZE_3)
207 TEST_ASSERT('d', "4c", test1->appendBytes(test2));
208 TEST_ASSERT('d', "4d", !test1->appendBytes(test2));
209 for (i = 0; i < DATA_SIZE_4; i += DATA_SIZE_3) {
210
211 TEST_ASSERT('d', "4e", test2->isEqualTo(
212 test1->getBytesNoCopy(i, DATA_SIZE_3),
213 DATA_SIZE_3));
214
215 test3 = OSData::withData(test1, i, DATA_SIZE_3);
216 TEST_ASSERT('d', "4f", test3);
217 if (test3) {
218 TEST_ASSERT('d', "4g", test2->isEqualTo(test3));
219 test3->release();
220 }
221
222 test3 = OSData::withData(test1, i, len);
223 TEST_ASSERT('d', "4i", test3);
224 if (test3) {
225 TEST_ASSERT('d', "4j", test2->isEqualTo(test3));
226 test3->release();
227 }
228 }
229 test1->release();
230 test2->release();
231 }
232 res = res && checkSpace("(d)3", spaceCheck, 0);
233
234 if (res)
235 verPrintf(("testData: All OSData Tests passed\n"));
236 else
237 logPrintf(("testData: Some OSData Tests failed\n"));
238 #undef DATA_SIZE_4
239 #undef DATA_SIZE_3
240 #undef DATA_SIZE_2
241 #undef DATA_SIZE_1
242 }
243
244 void testString()
245 {
246 OSString *test1, *test2;
247 void *spaceCheck;
248 int i;
249 char c;
250 bool res = true;
251
252 // very first test initialises the OSMetaClass cache.
253 test1 = OSString::withCStringNoCopy(testC00);
254 TEST_ASSERT('s', "0a", test1);
255 if (test1)
256 test1->release();
257
258 // Check c string allocation
259 spaceCheck = checkPointSpace();
260 test1 = OSString::withCString(testC00);
261 TEST_ASSERT('s', "1a", test1);
262 TEST_ASSERT('s', "1b", testC00 != test1->getCStringNoCopy());
263 TEST_ASSERT('s', "1c", strcmp(testC00, test1->getCStringNoCopy()) == 0);
264 TEST_ASSERT('s', "1d", strlen(testC00) == test1->getLength());
265 TEST_ASSERT('s', "1e", test1->isEqualTo(testC00));
266 TEST_ASSERT('s', "1f", !test1->isEqualTo(testC01));
267 if (test1) test1->release();
268 res = res && checkSpace("(s)1", spaceCheck, 0);
269
270 // Check c string no allocation
271 spaceCheck = checkPointSpace();
272 test1 = OSString::withCStringNoCopy(testC00);
273 TEST_ASSERT('s', "2a", test1);
274 TEST_ASSERT('s', "2b", testC00 == test1->getCStringNoCopy());
275 if (test1) test1->release();
276 res = res && checkSpace("(s)2", spaceCheck, 0);
277
278 // Check string from other string generation
279 spaceCheck = checkPointSpace();
280 test1 = OSString::withCStringNoCopy(testC00);
281 TEST_ASSERT('s', "3a", test1);
282 test2 = OSString::withString(test1);
283 TEST_ASSERT('s', "3b", test2);
284 TEST_ASSERT('s', "3c", test1 != test2);
285 TEST_ASSERT('s', "3d", test1->isEqualTo(test2));
286 if (test1) test1->release();
287 if (test2) test2->release();
288 res = res && checkSpace("(s)3", spaceCheck, 0);
289
290 // Check string comparison functionality no copy
291 spaceCheck = checkPointSpace();
292 test1 = OSString::withCStringNoCopy(testC00);
293 test2 = OSString::withCStringNoCopy(testC01);
294 TEST_ASSERT('s', "4a", test1 && test2);
295 TEST_ASSERT('s', "4b", !test1->isEqualTo(test2));
296 TEST_ASSERT('s', "4c", !test1->isEqualTo(testC01));
297 TEST_ASSERT('s', "4d", test1->isEqualTo(testC00));
298 if (test1) test1->release();
299 if (test2) test2->release();
300 res = res && checkSpace("(s)4", spaceCheck, 0);
301
302 // Check string comparison functionality with copy
303 spaceCheck = checkPointSpace();
304 test1 = OSString::withCString(testC00);
305 test2 = OSString::withCString(testC01);
306 TEST_ASSERT('s', "5a", test1 && test2);
307 TEST_ASSERT('s', "5b", !test1->isEqualTo(test2));
308 TEST_ASSERT('s', "5c", !test1->isEqualTo(testC01));
309 TEST_ASSERT('s', "5d", test1->isEqualTo(testC00));
310 if (test1) test1->release();
311 if (test2) test2->release();
312 res = res && checkSpace("(s)5", spaceCheck, 0);
313
314 // Check string inplace modifications
315 spaceCheck = checkPointSpace();
316 test1 = OSString::withCString(testC00);
317 TEST_ASSERT('s', "6a", test1);
318 for (i = 0; (c = test1->getChar(i)); i++)
319 if (c != testC00[i]) {
320 verPrintf(("testString(s) test 6b failed\n")); res = false;
321 break;
322 }
323 TEST_ASSERT('s', "6c", !c);
324 TEST_ASSERT('s', "6d", test1->setChar(' ', 0));
325 TEST_ASSERT('s', "6e", !test1->isEqualTo(testC00));
326 TEST_ASSERT('s', "6f", test1->setChar('T', 0));
327 TEST_ASSERT('s', "6g", !test1->setChar(' ', sizeof(testC00)));
328 TEST_ASSERT('s', "6h", test1->isEqualTo(testC00));
329 if (test1) test1->release();
330 res = res && checkSpace("(s)6", spaceCheck, 0);
331
332 // Check const string fail inplace modifications
333 spaceCheck = checkPointSpace();
334 test1 = OSString::withCStringNoCopy(testC00);
335 TEST_ASSERT('s', "7a", test1);
336 for (i = 0; (c = test1->getChar(i)); i++)
337 if (c != testC00[i]) {
338 verPrintf(("testString(s) test 7b failed\n")); res = false;
339 break;
340 }
341 TEST_ASSERT('s', "7c", !c);
342 TEST_ASSERT('s', "7d", !test1->setChar(' ', 0));
343 TEST_ASSERT('s', "7e", test1->isEqualTo(testC00));
344 TEST_ASSERT('s', "7f", !test1->setChar(' ', sizeof(testC00)));
345 TEST_ASSERT('s', "7g", test1->isEqualTo(testC00));
346 if (test1) test1->release();
347 res = res && checkSpace("(s)7", spaceCheck, 0);
348
349 if (res)
350 verPrintf(("testString: All OSString Tests passed\n"));
351 else
352 logPrintf(("testString: Some OSString Tests failed\n"));
353 }
354
355 void testSymbol()
356 {
357 bool res = true;
358 int i, j;
359 int countDups;
360 const OSSymbol *cache[numStrCache];
361 void *spaceCheck;
362
363 // very first test initialises the OSMetaClass cache.
364 cache[0] = IOSymbol::withCStringNoCopy(testC00);
365 TEST_ASSERT('u', "0a", cache[0]);
366 if (cache[0])
367 cache[0]->release();
368
369 spaceCheck = checkPointSpace();
370
371 // Setup the symbol cache, make sure it grows the symbol unique'ing
372 // hash table. Also determine that the symbol is created ok and that
373 // it is indeed equal to the creating cString by strcmp.
374 for (i = 0; i < numStrCache; i++) {
375 cache[i] = OSSymbol::withCStringNoCopy(strCache[i]);
376 if (!cache[i]) {
377 verPrintf(("testSymbol(u) test 1a%d failed\n", i)); res = false;
378 }
379 else if (!cache[i]->isEqualTo(strCache[i])) {
380 verPrintf(("testSymbol(u) test 1b%d failed\n", i)); res = false;
381 }
382 }
383
384 // The strCache does have some duplicates in it, mostly 'the'. Make
385 // sure that we wind them and that different cache entries really are
386 // different by strcmp. Fundamental to OSSymbol semantics.
387 countDups = 0;
388 for (i = 0; i < numStrCache; i++)
389 for (j = i+1; j < numStrCache; j++) {
390 if (cache[i] != cache[j] && cache[i]->isEqualTo(cache[j])) {
391 verPrintf(("testSymbol(u) test 2a%d,%d failed\n", i, j));
392 res = false;
393 }
394 else if (cache[i] == cache[j]) {
395 if (cache[i]->getRetainCount() == 1) {
396 verPrintf(("testSymbol(u) test 2b%d,%d failed\n", i, j));
397 res = false;
398 }
399 countDups++;
400 }
401 }
402 TEST_ASSERT('u', "2c", countDups);
403
404 // Clear out the cache and check that the unique'ing hashtable has grown
405 for (i = 0; i < numStrCache; i++) {
406 if (cache[i]) {
407 cache[i]->release();
408 cache[i] = 0;
409 }
410 }
411 // As of 1998-11-17 the hash growth is 364.
412 res = res && checkSpace("(u)3", spaceCheck, 972);
413 logSpace();
414
415 // Check for leaks by repeating the cacheing and freeing
416 spaceCheck = checkPointSpace();
417 for (i = 0; i < numStrCache; i++)
418 cache[i] = OSSymbol::withCString(strCache[i]);
419 for (i = 0; i < numStrCache; i++) {
420 if (cache[i]) {
421 cache[i]->release();
422 cache[i] = 0;
423 }
424 }
425 res = res && checkSpace("(u)4", spaceCheck, 0);
426
427 // Check that the OSString based symbol constructors work
428 // and that they don't leak, and finally double check that while
429 // the cache is active the symbol semantics still work.
430 spaceCheck = checkPointSpace();
431 for (i = 0; i < numStrCache; i++) {
432 OSString *tmpStr;
433
434 tmpStr = (i&1)
435 ? OSString::withCString(strCache[i])
436 : OSString::withCStringNoCopy(strCache[i]);
437 if (tmpStr) {
438 cache[i] = OSSymbol::withString(tmpStr);
439 if (!cache[i]) {
440 verPrintf(("testSymbol(u) test 5a%d failed\n", i));
441 res = false;
442 }
443 tmpStr->release();
444 }
445 }
446
447 for (i = 0; i < numStrCache; i++) {
448 if (cache[i]) {
449 const OSSymbol *tmpSymb;
450
451 tmpSymb = OSSymbol::withCStringNoCopy(strCache[i]);
452 if (cache[i] != tmpSymb) {
453 verPrintf(("testSymbol(u) test 5b%d failed\n", i));
454 res = false;
455 }
456 tmpSymb->release();
457 cache[i]->release();
458 cache[i] = 0;
459 }
460 else {
461 verPrintf(("testSymbol(u) test 5c%d failed\n", i));
462 res = false;
463 }
464 }
465 res = res && checkSpace("(u)5", spaceCheck, 0);
466
467 if (res)
468 verPrintf(("testSymbol: All OSSymbol Tests passed\n"));
469 else
470 logPrintf(("testSymbol: Some OSSymbol Tests failed\n"));
471 }
472
473 #endif /* DEBUG */