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