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