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