]> git.saurik.com Git - apple/xnu.git/blame - iokit/Tests/TestContainers.cpp
xnu-792.22.5.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 *
8f6c56a5 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
8f6c56a5
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.
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
8ad349bb 24 * limitations under the License.
8f6c56a5
A
25 *
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 "
49 "men to come to the aid of the party \n";
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? "
77 "Aching back? The right moves can help "
78 "prevent these kinds of problem. ";
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[] = {
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};
112const int numStrCache = ((int) (sizeof(strCache)/sizeof(strCache[0])));
113
114void testData()
115{
116#define DATA_SIZE_1 256
117#define DATA_SIZE_2 512
118#define DATA_SIZE_3 1024
119#define DATA_SIZE_4 8192
120
121 OSData *test1, *test2, *test3;
122 void *spaceCheck;
123 unsigned int len;
124 unsigned int i;
125 bool res = true;
126 unsigned short testData[DATA_SIZE_4/sizeof(short)], *cp;
127
128 // very first test initialises the OSMetaClass cache.
129 test1 = OSData::withCapacity(DATA_SIZE_1);
130 TEST_ASSERT('d', "0a", test1);
131 if (test1)
132 test1->release();
133
134 for (i = 0; i < sizeof(testData)/sizeof(short); i++)
135 testData[i] = (unsigned short) i;
136
137 // Check empty data allocation
138 spaceCheck = checkPointSpace();
139 test1 = OSData::withCapacity(DATA_SIZE_1);
140 TEST_ASSERT('d', "1a", test1);
141 if (test1) {
142 TEST_ASSERT('d', "1b", !test1->getLength());
143 TEST_ASSERT('d', "1c", test1->getCapacity() == DATA_SIZE_1);
144 TEST_ASSERT('d', "1d", !test1->getBytesNoCopy());
145 TEST_ASSERT('d', "1e", !test1->getBytesNoCopy(10, DATA_SIZE_1 - 10));
146 TEST_ASSERT('d', "1f", test1->appendBytes(spaceCheck, 0));
147 TEST_ASSERT('d', "1g", !test1->getLength());
148 TEST_ASSERT('d', "1h", test1->getCapacity() == DATA_SIZE_1);
149 TEST_ASSERT('d', "1i", !test1->getBytesNoCopy());
150 test1->release();
151 }
152 res = res && checkSpace("(d)1", spaceCheck, 0);
153
154 // Check appending to empty data allocation
155 spaceCheck = checkPointSpace();
156 test1 = OSData::withCapacity(DATA_SIZE_1);
157 TEST_ASSERT('d', "2a", test1);
158 if (test1) {
159 TEST_ASSERT('d', "2b", !test1->getLength());
160 TEST_ASSERT('d', "2c", !test1->getBytesNoCopy());
161 TEST_ASSERT('d', "2d", test1->appendBytes(testData, DATA_SIZE_1));
162 TEST_ASSERT('d', "2e", test1->getLength() == DATA_SIZE_1);
163 TEST_ASSERT('d', "2f", test1->getBytesNoCopy());
164 cp = (unsigned short *) test1->getBytesNoCopy();
165 for (i = 0; cp && i < (DATA_SIZE_1/sizeof(short)); i++) {
166 TEST_ASSERT('d', "2g", *cp++ == testData[i]);
167 if (*cp != testData[i])
168 break;
169 }
170 TEST_ASSERT('d', "2h", test1->getBytesNoCopy(10, DATA_SIZE_1-10));
171 cp = (unsigned short *) test1->getBytesNoCopy(10, DATA_SIZE_1 - 10);
172 for (i = 5; cp && i < (DATA_SIZE_1/sizeof(short)) - 5; i++) {
173 TEST_ASSERT('d', "2i", *cp++ == testData[i]);
174 if (*cp != testData[i])
175 break;
176 }
177 TEST_ASSERT('d', "2j", test1->isEqualTo(testData, DATA_SIZE_1));
178 test1->release();
179 }
180 res = res && checkSpace("(d)2", spaceCheck, 0);
181
182 // Check data allocation from some constant data
183 spaceCheck = checkPointSpace();
184 test1 = OSData::withBytes(testData, sizeof(testData));
185 TEST_ASSERT('d', "3a", test1);
186 if (test1) {
187 TEST_ASSERT('d', "3b", test1->getLength() == sizeof(testData));
188 TEST_ASSERT('d', "3c", test1->getCapacity() == sizeof(testData));
189 TEST_ASSERT('d', "3d", test1->getBytesNoCopy());
190 TEST_ASSERT('d', "3e", test1->getBytesNoCopy(10, sizeof(testData)-10));
191 TEST_ASSERT('d', "3f", test1->appendBytes(spaceCheck, 0));
192 TEST_ASSERT('d', "3g", test1->getLength() == sizeof(testData));
193 TEST_ASSERT('d', "3h", test1->getCapacity() == sizeof(testData));
194 TEST_ASSERT('d', "3i", test1->getBytesNoCopy());
195 TEST_ASSERT('d', "3j", test1->getBytesNoCopy(10, sizeof(testData)-10));
196 TEST_ASSERT('d', "3k", !test1->appendBytes(testData, 10));
197 test1->release();
198 }
199 res = res && checkSpace("(d)3", spaceCheck, 0);
200
201 // Check and continious addition of more data
202 spaceCheck = checkPointSpace();
203 test1 = OSData::withCapacity(DATA_SIZE_4);
204 test2 = OSData::withBytesNoCopy(testData, DATA_SIZE_3);
205 len = DATA_SIZE_3;
206 TEST_ASSERT('d', "4a", (test1 && test2));
207 if (test1 && test2) {
208 TEST_ASSERT('d', "4b", !test1->getLength());
209 for (i = 0; i < DATA_SIZE_4; i += DATA_SIZE_3)
210 TEST_ASSERT('d', "4c", test1->appendBytes(test2));
211 TEST_ASSERT('d', "4d", !test1->appendBytes(test2));
212 for (i = 0; i < DATA_SIZE_4; i += DATA_SIZE_3) {
213
214 TEST_ASSERT('d', "4e", test2->isEqualTo(
215 test1->getBytesNoCopy(i, DATA_SIZE_3),
216 DATA_SIZE_3));
217
218 test3 = OSData::withData(test1, i, DATA_SIZE_3);
219 TEST_ASSERT('d', "4f", test3);
220 if (test3) {
221 TEST_ASSERT('d', "4g", test2->isEqualTo(test3));
222 test3->release();
223 }
224
225 test3 = OSData::withData(test1, i, len);
226 TEST_ASSERT('d', "4i", test3);
227 if (test3) {
228 TEST_ASSERT('d', "4j", test2->isEqualTo(test3));
229 test3->release();
230 }
231 }
232 test1->release();
233 test2->release();
234 }
235 res = res && checkSpace("(d)3", spaceCheck, 0);
236
237 if (res)
238 verPrintf(("testData: All OSData Tests passed\n"));
239 else
240 logPrintf(("testData: Some OSData Tests failed\n"));
241#undef DATA_SIZE_4
242#undef DATA_SIZE_3
243#undef DATA_SIZE_2
244#undef DATA_SIZE_1
245}
246
247void testString()
248{
249 OSString *test1, *test2;
250 void *spaceCheck;
251 int i;
252 char c;
253 bool res = true;
254
255 // very first test initialises the OSMetaClass cache.
256 test1 = OSString::withCStringNoCopy(testC00);
257 TEST_ASSERT('s', "0a", test1);
258 if (test1)
259 test1->release();
260
261 // Check c string allocation
262 spaceCheck = checkPointSpace();
263 test1 = OSString::withCString(testC00);
264 TEST_ASSERT('s', "1a", test1);
265 TEST_ASSERT('s', "1b", testC00 != test1->getCStringNoCopy());
266 TEST_ASSERT('s', "1c", strcmp(testC00, test1->getCStringNoCopy()) == 0);
267 TEST_ASSERT('s', "1d", strlen(testC00) == test1->getLength());
268 TEST_ASSERT('s', "1e", test1->isEqualTo(testC00));
269 TEST_ASSERT('s', "1f", !test1->isEqualTo(testC01));
270 if (test1) test1->release();
271 res = res && checkSpace("(s)1", spaceCheck, 0);
272
273 // Check c string no allocation
274 spaceCheck = checkPointSpace();
275 test1 = OSString::withCStringNoCopy(testC00);
276 TEST_ASSERT('s', "2a", test1);
277 TEST_ASSERT('s', "2b", testC00 == test1->getCStringNoCopy());
278 if (test1) test1->release();
279 res = res && checkSpace("(s)2", spaceCheck, 0);
280
281 // Check string from other string generation
282 spaceCheck = checkPointSpace();
283 test1 = OSString::withCStringNoCopy(testC00);
284 TEST_ASSERT('s', "3a", test1);
285 test2 = OSString::withString(test1);
286 TEST_ASSERT('s', "3b", test2);
287 TEST_ASSERT('s', "3c", test1 != test2);
288 TEST_ASSERT('s', "3d", test1->isEqualTo(test2));
289 if (test1) test1->release();
290 if (test2) test2->release();
291 res = res && checkSpace("(s)3", spaceCheck, 0);
292
293 // Check string comparison functionality no copy
294 spaceCheck = checkPointSpace();
295 test1 = OSString::withCStringNoCopy(testC00);
296 test2 = OSString::withCStringNoCopy(testC01);
297 TEST_ASSERT('s', "4a", test1 && test2);
298 TEST_ASSERT('s', "4b", !test1->isEqualTo(test2));
299 TEST_ASSERT('s', "4c", !test1->isEqualTo(testC01));
300 TEST_ASSERT('s', "4d", test1->isEqualTo(testC00));
301 if (test1) test1->release();
302 if (test2) test2->release();
303 res = res && checkSpace("(s)4", spaceCheck, 0);
304
305 // Check string comparison functionality with copy
306 spaceCheck = checkPointSpace();
307 test1 = OSString::withCString(testC00);
308 test2 = OSString::withCString(testC01);
309 TEST_ASSERT('s', "5a", test1 && test2);
310 TEST_ASSERT('s', "5b", !test1->isEqualTo(test2));
311 TEST_ASSERT('s', "5c", !test1->isEqualTo(testC01));
312 TEST_ASSERT('s', "5d", test1->isEqualTo(testC00));
313 if (test1) test1->release();
314 if (test2) test2->release();
315 res = res && checkSpace("(s)5", spaceCheck, 0);
316
317 // Check string inplace modifications
318 spaceCheck = checkPointSpace();
319 test1 = OSString::withCString(testC00);
320 TEST_ASSERT('s', "6a", test1);
321 for (i = 0; (c = test1->getChar(i)); i++)
322 if (c != testC00[i]) {
323 verPrintf(("testString(s) test 6b failed\n")); res = false;
324 break;
325 }
326 TEST_ASSERT('s', "6c", !c);
327 TEST_ASSERT('s', "6d", test1->setChar(' ', 0));
328 TEST_ASSERT('s', "6e", !test1->isEqualTo(testC00));
329 TEST_ASSERT('s', "6f", test1->setChar('T', 0));
330 TEST_ASSERT('s', "6g", !test1->setChar(' ', sizeof(testC00)));
331 TEST_ASSERT('s', "6h", test1->isEqualTo(testC00));
332 if (test1) test1->release();
333 res = res && checkSpace("(s)6", spaceCheck, 0);
334
335 // Check const string fail inplace modifications
336 spaceCheck = checkPointSpace();
337 test1 = OSString::withCStringNoCopy(testC00);
338 TEST_ASSERT('s', "7a", test1);
339 for (i = 0; (c = test1->getChar(i)); i++)
340 if (c != testC00[i]) {
341 verPrintf(("testString(s) test 7b failed\n")); res = false;
342 break;
343 }
344 TEST_ASSERT('s', "7c", !c);
345 TEST_ASSERT('s', "7d", !test1->setChar(' ', 0));
346 TEST_ASSERT('s', "7e", test1->isEqualTo(testC00));
347 TEST_ASSERT('s', "7f", !test1->setChar(' ', sizeof(testC00)));
348 TEST_ASSERT('s', "7g", test1->isEqualTo(testC00));
349 if (test1) test1->release();
350 res = res && checkSpace("(s)7", spaceCheck, 0);
351
352 if (res)
353 verPrintf(("testString: All OSString Tests passed\n"));
354 else
355 logPrintf(("testString: Some OSString Tests failed\n"));
356}
357
358void testSymbol()
359{
360 bool res = true;
361 int i, j;
362 int countDups;
363 const OSSymbol *cache[numStrCache];
364 void *spaceCheck;
365
366 // very first test initialises the OSMetaClass cache.
367 cache[0] = IOSymbol::withCStringNoCopy(testC00);
368 TEST_ASSERT('u', "0a", cache[0]);
369 if (cache[0])
370 cache[0]->release();
371
372 spaceCheck = checkPointSpace();
373
374 // Setup the symbol cache, make sure it grows the symbol unique'ing
375 // hash table. Also determine that the symbol is created ok and that
376 // it is indeed equal to the creating cString by strcmp.
377 for (i = 0; i < numStrCache; i++) {
378 cache[i] = OSSymbol::withCStringNoCopy(strCache[i]);
379 if (!cache[i]) {
380 verPrintf(("testSymbol(u) test 1a%d failed\n", i)); res = false;
381 }
382 else if (!cache[i]->isEqualTo(strCache[i])) {
383 verPrintf(("testSymbol(u) test 1b%d failed\n", i)); res = false;
384 }
385 }
386
387 // The strCache does have some duplicates in it, mostly 'the'. Make
388 // sure that we wind them and that different cache entries really are
389 // different by strcmp. Fundamental to OSSymbol semantics.
390 countDups = 0;
391 for (i = 0; i < numStrCache; i++)
392 for (j = i+1; j < numStrCache; j++) {
393 if (cache[i] != cache[j] && cache[i]->isEqualTo(cache[j])) {
394 verPrintf(("testSymbol(u) test 2a%d,%d failed\n", i, j));
395 res = false;
396 }
397 else if (cache[i] == cache[j]) {
398 if (cache[i]->getRetainCount() == 1) {
399 verPrintf(("testSymbol(u) test 2b%d,%d failed\n", i, j));
400 res = false;
401 }
402 countDups++;
403 }
404 }
405 TEST_ASSERT('u', "2c", countDups);
406
407 // Clear out the cache and check that the unique'ing hashtable has grown
408 for (i = 0; i < numStrCache; i++) {
409 if (cache[i]) {
410 cache[i]->release();
411 cache[i] = 0;
412 }
413 }
414 // As of 1998-11-17 the hash growth is 364.
415 res = res && checkSpace("(u)3", spaceCheck, 972);
416 logSpace();
417
418 // Check for leaks by repeating the cacheing and freeing
419 spaceCheck = checkPointSpace();
420 for (i = 0; i < numStrCache; i++)
421 cache[i] = OSSymbol::withCString(strCache[i]);
422 for (i = 0; i < numStrCache; i++) {
423 if (cache[i]) {
424 cache[i]->release();
425 cache[i] = 0;
426 }
427 }
428 res = res && checkSpace("(u)4", spaceCheck, 0);
429
430 // Check that the OSString based symbol constructors work
431 // and that they don't leak, and finally double check that while
432 // the cache is active the symbol semantics still work.
433 spaceCheck = checkPointSpace();
434 for (i = 0; i < numStrCache; i++) {
435 OSString *tmpStr;
436
437 tmpStr = (i&1)
438 ? OSString::withCString(strCache[i])
439 : OSString::withCStringNoCopy(strCache[i]);
440 if (tmpStr) {
441 cache[i] = OSSymbol::withString(tmpStr);
442 if (!cache[i]) {
443 verPrintf(("testSymbol(u) test 5a%d failed\n", i));
444 res = false;
445 }
446 tmpStr->release();
447 }
448 }
449
450 for (i = 0; i < numStrCache; i++) {
451 if (cache[i]) {
452 const OSSymbol *tmpSymb;
453
454 tmpSymb = OSSymbol::withCStringNoCopy(strCache[i]);
455 if (cache[i] != tmpSymb) {
456 verPrintf(("testSymbol(u) test 5b%d failed\n", i));
457 res = false;
458 }
459 tmpSymb->release();
460 cache[i]->release();
461 cache[i] = 0;
462 }
463 else {
464 verPrintf(("testSymbol(u) test 5c%d failed\n", i));
465 res = false;
466 }
467 }
468 res = res && checkSpace("(u)5", spaceCheck, 0);
469
470 if (res)
471 verPrintf(("testSymbol: All OSSymbol Tests passed\n"));
472 else
473 logPrintf(("testSymbol: Some OSSymbol Tests failed\n"));
474}
475
476#endif /* DEBUG */