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