]> git.saurik.com Git - apple/xnu.git/blame - iokit/Tests/TestContainers.cpp
xnu-4903.270.47.tar.gz
[apple/xnu.git] / iokit / Tests / TestContainers.cpp
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
0a7de745 5 *
2d21ac55
A
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.
0a7de745 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
0a7de745 17 *
2d21ac55
A
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
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
0a7de745 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
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
35static const char testC00[] = "The quick brown fox jumps over the lazy dog. ";
36static const char testC01[] = "The quick brown fox ";
37static const char testC02[] = "jumps over the ";
38static const char testC03[] = "lazy dog. \n";
39static const char testC04[] = "The ";
40static const char testC05[] = "quick ";
41static const char testC06[] = "brown ";
42static const char testC07[] = "fox ";
43static const char testC08[] = "jumps ";
44static const char testC09[] = "over ";
45static const char testC10[] = "the ";
46static const char testC11[] = "lazy ";
47static const char testC12[] = "dog. \n";
48static const char testC13[] = "Now is the time for all good "
0a7de745 49 "men to come to the aid of the party \n";
1c79356b
A
50static const char testC14[] = "Now is the time for ";
51static const char testC15[] = "all good men to come ";
52static const char testC16[] = "to the aid of the party \n";
53static const char testC17[] = "Now ";
54static const char testC18[] = "is ";
55static const char testC19[] = "the ";
56static const char testC20[] = "time ";
57static const char testC21[] = "for ";
58static const char testC22[] = "all ";
59static const char testC23[] = "good ";
60static const char testC24[] = "men ";
61static const char testC25[] = "to ";
62static const char testC26[] = "come ";
63static const char testC27[] = "to ";
64static const char testC28[] = "the ";
65static const char testC29[] = "aid ";
66static const char testC30[] = "of ";
67static const char testC31[] = "the ";
68static const char testC32[] = "party. \n";
69static const char testC33[] = "Frank Burns eats worms. \n";
70static const char testC34[] = "Frank Burns ";
71static const char testC35[] = "eats worms. \n";
72static const char testC36[] = "Frank ";
73static const char testC37[] = "Burns ";
74static const char testC38[] = "eats ";
75static const char testC39[] = "worms. \n";
76static const char testC40[] = "Tired eyes? Stiff neck? Tight shoulders? "
0a7de745
A
77 "Aching back? The right moves can help "
78 "prevent these kinds of problem. ";
1c79356b
A
79static const char testC41[] = "Tired eyes? Stiff neck? ";
80static const char testC42[] = "Tight shoulders? Aching back? ";
81static const char testC43[] = "The right moves can help prevent ";
82static const char testC44[] = "these kinds of problem. ";
83static const char testC45[] = "Tired ";
84static const char testC46[] = "eyes? ";
85static const char testC47[] = "Stiff ";
86static const char testC48[] = "neck? ";
87static const char testC49[] = "Tight ";
88static const char testC50[] = "shoulders? ";
89static const char testC51[] = "Aching ";
90static const char testC52[] = "back? ";
91static const char testC53[] = "The ";
92static const char testC54[] = "right ";
93static const char testC55[] = "moves ";
94static const char testC56[] = "can ";
95static const char testC57[] = "help ";
96static const char testC58[] = "prevent ";
97static const char testC59[] = "these ";
98static const char testC60[] = "kinds ";
99static const char testC61[] = "of ";
100static const char testC62[] = "problem. ";
101
102const char *strCache[] = {
0a7de745
A
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,
1c79356b 111};
0a7de745 112const int numStrCache = ((int) (sizeof(strCache) / sizeof(strCache[0])));
1c79356b 113
0a7de745
A
114void
115testData()
1c79356b 116{
0a7de745
A
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 }
1c79356b
A
247#undef DATA_SIZE_4
248#undef DATA_SIZE_3
249#undef DATA_SIZE_2
250#undef DATA_SIZE_1
251}
252
0a7de745
A
253void
254testString()
1c79356b 255{
0a7de745
A
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 }
1c79356b
A
387}
388
0a7de745
A
389void
390testSymbol()
1c79356b 391{
0a7de745
A
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 }
1c79356b
A
507}
508
509#endif /* DEBUG */