gwenhywfar 5.12.0
simpleptrlist-t.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Fri Dec 06 2019
3 copyright : (C) 2019 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * *
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU Lesser General Public *
10 * License as published by the Free Software Foundation; either *
11 * version 2.1 of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this library; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 * *
23 ***************************************************************************/
24
25
26/* This file is included by "simpleptrlist.c" */
27
28
29#include <gwenhywfar/testframework.h>
30#include "simpleptrlist-t.h"
31
32
33#ifdef GWENHYWFAR_ENABLE_TESTCODE
34
35
36#include <gwenhywfar/mdigest.h>
37#include <string.h>
38
39
40
41
42/* ------------------------------------------------------------------------------------------------
43 * type definitions
44 * ------------------------------------------------------------------------------------------------
45 */
46
47typedef struct TEST_TYPE TEST_TYPE;
48GWEN_LIST_FUNCTION_DEFS(TEST_TYPE, TestType)
49struct TEST_TYPE {
50 GWEN_LIST_ELEMENT(TEST_TYPE)
51 int _refCounter;
52 int testPosition;
53 char *testStringPtr;
54 uint8_t testHash[20];
55};
56
57
58
59/* ------------------------------------------------------------------------------------------------
60 * forward declarations
61 * ------------------------------------------------------------------------------------------------
62 */
63
64
65static TEST_TYPE *TestType_new(const char *s, int pos);
66static void TestType_Attach(TEST_TYPE *tt);
67static void TestType_free(TEST_TYPE *tt);
68
69static int TestType_CalcHash(TEST_TYPE *tt);
70static int TestType_TestHash(const TEST_TYPE *tt);
71
72static GWENHYWFAR_CB void _attachToTestType(GWEN_SIMPLEPTRLIST *pl, void *p);
73static GWENHYWFAR_CB void _detachFromTestType(GWEN_SIMPLEPTRLIST *pl, void *p);
74
75
76static int GWENHYWFAR_CB test1(GWEN_TEST_MODULE *mod);
77static int GWENHYWFAR_CB test2(GWEN_TEST_MODULE *mod);
78static int GWENHYWFAR_CB test3(GWEN_TEST_MODULE *mod);
79static int GWENHYWFAR_CB test4(GWEN_TEST_MODULE *mod);
80static int GWENHYWFAR_CB test5(GWEN_TEST_MODULE *mod);
81static int GWENHYWFAR_CB test6(GWEN_TEST_MODULE *mod);
82
83static TEST_TYPE *createTestType(int num);
84static void dumpTestTypeList(TEST_TYPE_LIST *ttList);
85
86
87
88/* ------------------------------------------------------------------------------------------------
89 * implementations
90 * ------------------------------------------------------------------------------------------------
91 */
92
93
95{
96 GWEN_TEST_MODULE *newMod;
97
98 newMod=GWEN_Test_Module_AddModule(mod, "GWEN_SimplePtrList", NULL);
99
100 GWEN_Test_Module_AddTest(newMod, "test1", test1, NULL);
101 GWEN_Test_Module_AddTest(newMod, "test2", test2, NULL);
102 GWEN_Test_Module_AddTest(newMod, "test3", test3, NULL);
103 GWEN_Test_Module_AddTest(newMod, "test4", test4, NULL);
104 GWEN_Test_Module_AddTest(newMod, "test5", test5, NULL);
105 GWEN_Test_Module_AddTest(newMod, "test6", test6, NULL);
106
107 return 0;
108}
109
110
111
112GWEN_LIST_FUNCTIONS(TEST_TYPE, TestType)
113
114
115
116
117TEST_TYPE *TestType_new(const char *s, int pos)
118{
119 TEST_TYPE *tt;
120
121 GWEN_NEW_OBJECT(TEST_TYPE, tt);
122 tt->_refCounter=1;
123 GWEN_LIST_INIT(TEST_TYPE, tt);
124 if (s)
125 tt->testStringPtr=strdup(s);
126 tt->testPosition=pos;
127 return tt;
128}
129
130
131
132void TestType_Attach(TEST_TYPE *tt)
133{
134 assert(tt);
135 assert(tt->_refCounter);
136
137 if (tt && tt->_refCounter) {
138 tt->_refCounter++;
139 /*DBG_ERROR(GWEN_LOGDOMAIN, "Attached (%d: refcount=%d)", tt->testPosition, tt->_refCounter);*/
140 }
141 else {
142 DBG_ERROR(GWEN_LOGDOMAIN, "NULL pointer or already freed");
143 }
144}
145
146
147
148void TestType_free(TEST_TYPE *tt)
149{
150 if (tt && tt->_refCounter) {
151 /*DBG_ERROR(GWEN_LOGDOMAIN, "Detaching (%d: refcount=%d)", tt->testPosition, tt->_refCounter);*/
152 if (tt->_refCounter==1) {
153 GWEN_LIST_FINI(TEST_TYPE, tt);
154 if (tt->testStringPtr)
155 free(tt->testStringPtr);
156 tt->_refCounter=0;
158 }
159 else
160 tt->_refCounter--;
161 }
162}
163
164
165
166int TestType_CalcHash(TEST_TYPE *tt)
167{
168 if (tt->testStringPtr && *(tt->testStringPtr)) {
169 GWEN_MDIGEST *md;
170 int rv;
171
174 (const uint8_t *)tt->testStringPtr, strlen(tt->testStringPtr),
175 tt->testHash, sizeof(tt->testHash));
176 if (rv<0) {
177 DBG_ERROR(GWEN_LOGDOMAIN, "Error on GWEN_MDigest_Begin: %s (%d)", GWEN_Error_SimpleToString(rv), rv);
179 return rv;
180 }
182 }
183 return 0;
184}
185
186
187
188int TestType_TestHash(const TEST_TYPE *tt)
189{
190 if (tt->testStringPtr && *(tt->testStringPtr)) {
191 GWEN_MDIGEST *md;
192 uint8_t hash[20];
193 int rv;
194
197 (const uint8_t *)tt->testStringPtr, strlen(tt->testStringPtr),
198 hash, sizeof(hash));
199 if (rv<0) {
200 DBG_ERROR(GWEN_LOGDOMAIN, "Error on GWEN_MDigest_Digest: %s (%d)", GWEN_Error_SimpleToString(rv), rv);
202 return rv;
203 }
205
206 if (memcmp(hash, tt->testHash, sizeof(hash))!=0) {
207 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid hash, object was modified.");
208 return GWEN_ERROR_GENERIC;
209 }
210 }
211 return 0;
212}
213
214
215
216TEST_TYPE *createTestType(int num)
217{
218 TEST_TYPE *tt;
219 char testString[256];
220 int rv;
221
222 snprintf(testString, sizeof(testString), "This is test string number %d", num);
223 tt=TestType_new(testString, num);
224 if (tt==NULL) {
225 DBG_ERROR(GWEN_LOGDOMAIN, "Could not create test object %d", num);
226 return NULL;
227 }
228 rv=TestType_CalcHash(tt);
229 if (rv<0) {
230 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
231 TestType_free(tt);
232 return NULL;
233 }
234 return tt;
235}
236
237
238
239void _attachToTestType(GWEN_UNUSED GWEN_SIMPLEPTRLIST *pl, void *p)
240{
241 TEST_TYPE *tt;
242
243 tt=(TEST_TYPE *) p;
244 TestType_Attach(tt);
245}
246
247
248
249void _detachFromTestType(GWEN_UNUSED GWEN_SIMPLEPTRLIST *pl, void *p)
250{
251 TEST_TYPE *tt;
252
253 tt=(TEST_TYPE *) p;
254 TestType_free(tt);
255}
256
257
258
259void dumpTestTypeList(TEST_TYPE_LIST *ttList)
260{
261 TEST_TYPE *tt;
262
263 tt=TestType_List_First(ttList);
264 while (tt) {
265 fprintf(stderr, "%5d: %3d: %s\n", tt->testPosition, tt->_refCounter, tt->testStringPtr);
266 tt=TestType_List_Next(tt);
267 }
268}
269
270
271
272/* ------------------------------------------------------------------------------------------------
273 * test 1: test struct members after construction
274 * ------------------------------------------------------------------------------------------------
275 */
276
278{
280 int i;
281
282 pl=GWEN_SimplePtrList_new(128, 128);
283 if (pl==NULL) {
284 DBG_ERROR(GWEN_LOGDOMAIN, "Could not create pointer list");
285 return GWEN_ERROR_GENERIC;
286 }
287
288 if (pl->refCount!=1) {
289 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: refCounter");
291 return GWEN_ERROR_GENERIC;
292 }
293
294 if (pl->maxEntries!=128) {
295 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: maxEntries");
297 return GWEN_ERROR_GENERIC;
298 }
299
300 if (pl->usedEntries!=0) {
301 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: usedEntries");
303 return GWEN_ERROR_GENERIC;
304 }
305
306 if (pl->steps!=128) {
307 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: steps");
309 return GWEN_ERROR_GENERIC;
310 }
311
312
313 if (pl->entryList->refCounter!=1) {
314 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: refCounter");
316 return GWEN_ERROR_GENERIC;
317 }
318
319 if (pl->entryList->storedEntries!=128) {
320 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: storedEntries");
322 return GWEN_ERROR_GENERIC;
323 }
324
325
326 for (i=0; i<128; i++) {
327 if (pl->entryList->entries[i]!=NULL) {
328 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object entry: idx %d is not NULL", i);
330 return GWEN_ERROR_GENERIC;
331 }
332 }
333
334
336 return 0;
337}
338
339
340
341/* ------------------------------------------------------------------------------------------------
342 * test 2: test adding pointers
343 * ------------------------------------------------------------------------------------------------
344 */
345
347{
348
350 int i;
351
352 pl=GWEN_SimplePtrList_new(128, 128);
353 for (i=0; i<1024; i++) {
354 TEST_TYPE *tt;
355 int64_t idx;
356
357 tt=createTestType(i);
358 idx=GWEN_SimplePtrList_AddPtr(pl, tt);
359 if (idx<0) {
360 DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
362 return (int) idx;
363 }
364 } /* for */
365
366 if (pl->maxEntries!=1024) {
367 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: maxEntries");
369 return GWEN_ERROR_GENERIC;
370 }
371
372 if (pl->usedEntries!=1024) {
373 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: usedEntries");
375 return GWEN_ERROR_GENERIC;
376 }
377
378 for (i=0; i<1024; i++) {
379 TEST_TYPE *tt;
380 int rv;
381
382 tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(pl, i);
383 if (tt==NULL) {
384 DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
386 return GWEN_ERROR_GENERIC;
387 }
388
389 rv=TestType_TestHash(tt);
390 if (rv<0) {
391 DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
393 return rv;
394 }
395 } /* for */
396
397 /* free all objects */
398 for (i=0; i<1024; i++) {
399 TEST_TYPE *tt;
400
401 tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(pl, i);
402 if (tt==NULL) {
403 DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
405 return GWEN_ERROR_GENERIC;
406 }
408 TestType_free(tt);
409 } /* for */
410
412 return 0;
413}
414
415
416
417/* ------------------------------------------------------------------------------------------------
418 * test 3: test lazy copying
419 * ------------------------------------------------------------------------------------------------
420 */
421
423{
424
426 GWEN_SIMPLEPTRLIST *plCopy;
427 int i;
428
429 pl=GWEN_SimplePtrList_new(128, 128);
430 for (i=0; i<1000; i++) {
431 TEST_TYPE *tt;
432 int64_t idx;
433
434 tt=createTestType(i);
435 idx=GWEN_SimplePtrList_AddPtr(pl, tt);
436 if (idx<0) {
437 DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
439 return (int) idx;
440 }
441 } /* for */
442
444 if (plCopy==NULL) {
445 DBG_ERROR(GWEN_LOGDOMAIN, "Could not copy pointer list");
448 return GWEN_ERROR_INVALID;
449 }
450
451 if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)) {
452 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: flags");
455 return GWEN_ERROR_GENERIC;
456 }
457
458 if (!(pl->flags & GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)) {
459 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field in old list: flags");
462 return GWEN_ERROR_GENERIC;
463 }
464
465 if (plCopy->entryList != pl->entryList) {
466 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: entryList (should be the same after lazy copy)");
469 return GWEN_ERROR_GENERIC;
470 }
471
472 if (pl->entryList->refCounter!=2) {
473 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: refCounter (should be 2)");
475 return GWEN_ERROR_GENERIC;
476 }
477
478 for (i=1000; i<1024; i++) {
479 TEST_TYPE *tt;
480 int64_t idx;
481
482 tt=createTestType(i);
483 idx=GWEN_SimplePtrList_AddPtr(plCopy, tt);
484 if (idx<0) {
485 DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
488 return (int) idx;
489 }
490 } /* for */
491
492 if (plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE) {
493 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: flags (should have cleared GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)");
496 return GWEN_ERROR_GENERIC;
497 }
498
499 if (!(pl->flags & GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)) {
501 "Invalid object field in old list: flags (should not have cleared GWEN_SIMPLEPTRLIST_FLAGS_COPYONWRITE)");
504 return GWEN_ERROR_GENERIC;
505 }
506
507 if (plCopy->entryList == pl->entryList) {
508 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: entryList (should have changed)");
511 return GWEN_ERROR_GENERIC;
512 }
513
514 if (pl->entryList->refCounter!=1) {
515 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: refCounter (should be back to 1)");
517 return GWEN_ERROR_GENERIC;
518 }
519
520 if (plCopy->entryList->refCounter!=1) {
521 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid internal object field: refCounter (should be 1)");
523 return GWEN_ERROR_GENERIC;
524 }
525
526 if (plCopy->maxEntries!=1024+128) {
527 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: maxEntries (should be 1152)");
529 return GWEN_ERROR_GENERIC;
530 }
531
532 if (plCopy->usedEntries!=1024) {
533 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: usedEntries");
535 return GWEN_ERROR_GENERIC;
536 }
537
538 if (pl->maxEntries!=1024) {
539 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: maxEntries (should still be 1024)");
541 return GWEN_ERROR_GENERIC;
542 }
543
544 if (pl->usedEntries!=1000) {
545 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid object field: usedEntries (should still be 1000)");
547 return GWEN_ERROR_GENERIC;
548 }
549
550
551 for (i=0; i<1024; i++) {
552 TEST_TYPE *tt;
553 int rv;
554
555 tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, i);
556 if (tt==NULL) {
557 DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
560 return GWEN_ERROR_GENERIC;
561 }
562
563 rv=TestType_TestHash(tt);
564 if (rv<0) {
565 DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
568 return rv;
569 }
570 } /* for */
571
572 /* free all objects */
573 for (i=0; i<1024; i++) {
574 TEST_TYPE *tt;
575
576 tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, i);
577 if (tt==NULL) {
578 DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
581 return GWEN_ERROR_GENERIC;
582 }
584 TestType_free(tt);
585 } /* for */
586
587
590 return 0;
591}
592
593
594
595/* ------------------------------------------------------------------------------------------------
596 * test 4: test adding pointers with attach/detach
597 * ------------------------------------------------------------------------------------------------
598 */
599
601{
602
604 TEST_TYPE_LIST *ttList;
605 int i;
606
607 pl=GWEN_SimplePtrList_new(128, 128);
608 GWEN_SimplePtrList_SetAttachObjectFn(pl, _attachToTestType);
609 GWEN_SimplePtrList_SetFreeObjectFn(pl, _detachFromTestType);
612
613 ttList=TestType_List_new();
614
615 for (i=0; i<1024; i++) {
616 TEST_TYPE *tt;
617 int64_t idx;
618
619 tt=createTestType(i);
620 TestType_List_Add(tt, ttList);
621
622 idx=GWEN_SimplePtrList_AddPtr(pl, tt);
623 if (idx<0) {
624 DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
626 return (int) idx;
627 }
628 } /* for */
629
630 if (1) {
631 TEST_TYPE *tt;
632 int cnt=0;
633
634 tt=TestType_List_First(ttList);
635 while (tt) {
636 if (tt->_refCounter!=2) {
637 DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 2");
638 TestType_List_free(ttList);
640 return GWEN_ERROR_GENERIC;
641 }
642 cnt++;
643 tt=TestType_List_Next(tt);
644 }
645 if (cnt!=1024) {
646 DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
647 }
648 }
649
650 for (i=0; i<1024; i++) {
651 TEST_TYPE *tt;
652 int rv;
653
654 tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(pl, i);
655 if (tt==NULL) {
656 DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
657 TestType_List_free(ttList);
659 return GWEN_ERROR_GENERIC;
660 }
661
662 rv=TestType_TestHash(tt);
663 if (rv<0) {
664 DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
665 TestType_List_free(ttList);
667 return rv;
668 }
669 } /* for */
670
672
673 if (1) {
674 TEST_TYPE *tt;
675 int cnt=0;
676
677 tt=TestType_List_First(ttList);
678 while (tt) {
679 if (tt->_refCounter!=1) {
680 DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 1");
681 TestType_List_free(ttList);
682 return GWEN_ERROR_GENERIC;
683 }
684 cnt++;
685 tt=TestType_List_Next(tt);
686 }
687 if (cnt!=1024) {
688 DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
689 }
690 }
691
692 TestType_List_free(ttList);
693
694 return 0;
695}
696
697
698
699/* ------------------------------------------------------------------------------------------------
700 * test 5: test lazy copying with attach/detach
701 * ------------------------------------------------------------------------------------------------
702 */
703
705{
706
708 GWEN_SIMPLEPTRLIST *plCopy;
709 TEST_TYPE_LIST *ttList;
710 int i;
711
712 pl=GWEN_SimplePtrList_new(128, 128);
713 GWEN_SimplePtrList_SetAttachObjectFn(pl, _attachToTestType);
714 GWEN_SimplePtrList_SetFreeObjectFn(pl, _detachFromTestType);
717
718 ttList=TestType_List_new();
719 for (i=0; i<1000; i++) {
720 TEST_TYPE *tt;
721 int64_t idx;
722
723 tt=createTestType(i);
724 TestType_List_Add(tt, ttList);
725 idx=GWEN_SimplePtrList_AddPtr(pl, tt);
726 if (idx<0) {
727 DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
729 return (int) idx;
730 }
731 } /* for */
732
734 if (plCopy==NULL) {
735 DBG_ERROR(GWEN_LOGDOMAIN, "Could not copy pointer list");
738 return GWEN_ERROR_INVALID;
739 }
740
741 if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS)) {
743 "Invalid object field in list: flags (should have set GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS)");
746 return GWEN_ERROR_GENERIC;
747 }
748
749 if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS)) {
751 "Invalid object field in list: flags (should have set GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS)");
754 return GWEN_ERROR_GENERIC;
755 }
756
757
758 for (i=1000; i<1024; i++) {
759 TEST_TYPE *tt;
760 int64_t idx;
761
762 tt=createTestType(i);
763 TestType_List_Add(tt, ttList);
764 idx=GWEN_SimplePtrList_AddPtr(plCopy, tt);
765 if (idx<0) {
766 DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
769 return (int) idx;
770 }
771 } /* for */
772
773
774 for (i=0; i<1024; i++) {
775 TEST_TYPE *tt;
776 int rv;
777
778 tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, i);
779 if (tt==NULL) {
780 DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
781 TestType_List_free(ttList);
784 return GWEN_ERROR_GENERIC;
785 }
786
787 rv=TestType_TestHash(tt);
788 if (rv<0) {
789 DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
790 TestType_List_free(ttList);
793 return rv;
794 }
795 } /* for */
796
797
798 if (1) {
799 TEST_TYPE *tt;
800 int cnt=0;
801
802 tt=TestType_List_First(ttList);
803 while (tt) {
804 if (cnt<1000) {
805 if (tt->_refCounter!=3) {
806 DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object %d is not 3 (%d)", cnt, tt->_refCounter);
807 dumpTestTypeList(ttList);
808 TestType_List_free(ttList);
810 return GWEN_ERROR_GENERIC;
811 }
812 }
813 else {
814 if (tt->_refCounter!=2) {
815 DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 2");
816 TestType_List_free(ttList);
818 return GWEN_ERROR_GENERIC;
819 }
820 }
821 cnt++;
822 tt=TestType_List_Next(tt);
823 }
824 if (cnt!=1024) {
825 DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
826 }
827 }
828
829
831
832 if (1) {
833 TEST_TYPE *tt;
834 int cnt=0;
835
836 tt=TestType_List_First(ttList);
837 while (tt) {
838 if (cnt<1000) {
839 if (tt->_refCounter!=2) {
840 DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 2");
841 TestType_List_free(ttList);
843 return GWEN_ERROR_GENERIC;
844 }
845 }
846 else {
847 if (tt->_refCounter!=1) {
848 DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 1");
849 TestType_List_free(ttList);
851 return GWEN_ERROR_GENERIC;
852 }
853 }
854 cnt++;
855 tt=TestType_List_Next(tt);
856 }
857 if (cnt!=1024) {
858 DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
859 }
860 }
861
862
864
865 if (1) {
866 TEST_TYPE *tt;
867 int cnt=0;
868
869 tt=TestType_List_First(ttList);
870 while (tt) {
871 if (tt->_refCounter!=1) {
872 DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object is not 1");
873 TestType_List_free(ttList);
875 return GWEN_ERROR_GENERIC;
876 }
877 cnt++;
878 tt=TestType_List_Next(tt);
879 }
880 if (cnt!=1024) {
881 DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
882 }
883 }
884
885 TestType_List_free(ttList);
886
887 return 0;
888}
889
890
891
892/* ------------------------------------------------------------------------------------------------
893 * test 6: test lazy copying with attach/detach and setPtr
894 * ------------------------------------------------------------------------------------------------
895 */
896
898{
899
901 GWEN_SIMPLEPTRLIST *plCopy;
902 TEST_TYPE_LIST *ttList;
903 int i;
904
905 pl=GWEN_SimplePtrList_new(128, 128);
906 GWEN_SimplePtrList_SetAttachObjectFn(pl, _attachToTestType);
907 GWEN_SimplePtrList_SetFreeObjectFn(pl, _detachFromTestType);
910
911 ttList=TestType_List_new();
912 for (i=0; i<1024; i++) {
913 TEST_TYPE *tt;
914 int64_t idx;
915
916 tt=createTestType(i);
917 TestType_List_Add(tt, ttList);
918 idx=GWEN_SimplePtrList_AddPtr(pl, tt);
919 if (idx<0) {
920 DBG_ERROR(GWEN_LOGDOMAIN, "Error adding pointer %d to list: %s (%d)", i, GWEN_Error_SimpleToString((int)idx), (int)idx);
922 return (int) idx;
923 }
924 } /* for */
925
927 if (plCopy==NULL) {
928 DBG_ERROR(GWEN_LOGDOMAIN, "Could not copy pointer list");
931 return GWEN_ERROR_INVALID;
932 }
933
934 if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS)) {
936 "Invalid object field in list: flags (should have set GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS)");
939 return GWEN_ERROR_GENERIC;
940 }
941
942 if (!(plCopy->flags & GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS)) {
944 "Invalid object field in list: flags (should have set GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS)");
947 return GWEN_ERROR_GENERIC;
948 }
949
950
951 if (1) {
952 TEST_TYPE *tt;
953 int rv;
954
955 tt=createTestType(1024);
956 TestType_List_Add(tt, ttList);
957 rv=GWEN_SimplePtrList_SetPtrAt(plCopy, 100, tt);
958 if (rv<0) {
959 DBG_ERROR(GWEN_LOGDOMAIN, "Error setting pointer %d in list: %s (%d)", 100, GWEN_Error_SimpleToString(rv), rv);
962 return rv;
963 }
964 }
965
966
967 for (i=0; i<1024; i++) {
968 TEST_TYPE *tt;
969 int rv;
970
971 tt=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, i);
972 if (tt==NULL) {
973 DBG_ERROR(GWEN_LOGDOMAIN, "No object at position %d", i);
974 TestType_List_free(ttList);
977 return GWEN_ERROR_GENERIC;
978 }
979
980 rv=TestType_TestHash(tt);
981 if (rv<0) {
982 DBG_ERROR(GWEN_LOGDOMAIN, "Error testing hash of object %d: %s (%d)", i, GWEN_Error_SimpleToString(rv), rv);
983 TestType_List_free(ttList);
986 return rv;
987 }
988 } /* for */
989
990
991 if (1) {
992 TEST_TYPE *tt;
993 int cnt=0;
994
995 tt=TestType_List_First(ttList);
996 while (tt) {
997 if (cnt==1024 || cnt==100) {
998 if (tt->_refCounter!=2) {
999 DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object %d is not 2 (%d)", cnt, tt->_refCounter);
1000 TestType_List_free(ttList);
1003 return GWEN_ERROR_GENERIC;
1004 }
1005 }
1006 else {
1007 if (tt->_refCounter!=3) {
1008 DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter of object %d is not 3 (%d)", cnt, tt->_refCounter);
1009 TestType_List_free(ttList);
1012 return GWEN_ERROR_GENERIC;
1013 }
1014 }
1015 cnt++;
1016 tt=TestType_List_Next(tt);
1017 }
1018 if (cnt!=1025) {
1019 DBG_ERROR(GWEN_LOGDOMAIN, "Too few objects in list (%d instead of %d)", cnt, 1024);
1020 }
1021 }
1022
1023 if (1) {
1024 TEST_TYPE *tt1;
1025 TEST_TYPE *tt2;
1026
1027 tt1=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(plCopy, 100);
1028 tt2=(TEST_TYPE *) GWEN_SimplePtrList_GetPtrAt(pl, 100);
1029 if (!(tt1 && tt2 && tt1!=tt2)) {
1030 DBG_ERROR(GWEN_LOGDOMAIN, "Pointers 100 are unexpectedly equal in both lists");
1031 TestType_List_free(ttList);
1034 return GWEN_ERROR_GENERIC;
1035 }
1036
1037 if (tt1->_refCounter!=2) {
1038 DBG_ERROR(GWEN_LOGDOMAIN, "Refcounter in copy list object 100 is not 2 (%d)", tt1->_refCounter);
1039 TestType_List_free(ttList);
1042 return GWEN_ERROR_GENERIC;
1043 }
1044 }
1045
1048 TestType_List_free(ttList);
1049
1050 return 0;
1051}
1052
1053
1054
1055
1056
1057
1058
1059#else
1060
1062{
1063 DBG_ERROR(GWEN_LOGDOMAIN, "Gwenhywfar was compiled without test code enabled.");
1064 return GWEN_ERROR_GENERIC;
1065}
1066
1067
1068#endif
1069
1070
#define NULL
Definition binreloc.c:300
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
const char * GWEN_Error_SimpleToString(int i)
Returns a (very) short string describing the given GWEN error code, or "Unknown error" for unknown co...
Definition error.c:95
#define GWEN_ERROR_INVALID
Definition error.h:67
#define GWEN_ERROR_GENERIC
Definition error.h:62
int test5(int argc, char **argv)
int test2(int argc, char **argv)
int test4(int argc, char **argv)
int test6(int argc, char **argv)
#define GWEN_UNUSED
#define GWENHYWFAR_CB
int test3(int argc, char **argv)
Definition libtest.m:204
int test1()
Definition libtest.m:63
#define GWEN_LIST_FINI(t, element)
Definition list1.h:475
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition list1.h:367
#define GWEN_LIST_FUNCTION_DEFS(t, pr)
Definition list1.h:358
#define GWEN_LIST_INIT(t, element)
Definition list1.h:466
#define GWEN_LIST_ELEMENT(t)
Definition list1.h:255
#define GWEN_LOGDOMAIN
Definition logger.h:35
int GWEN_MDigest_Digest(GWEN_MDIGEST *md, const uint8_t *srcBuf, unsigned int srcLen, uint8_t *dstBuf, unsigned int dstLen)
Definition mdigest.c:165
void GWEN_MDigest_free(GWEN_MDIGEST *md)
Definition mdigest.c:54
GWENHYWFAR_API GWEN_MDIGEST * GWEN_MDigest_Rmd160_new(void)
Definition mdigestgc.c:158
struct GWEN_MDIGEST GWEN_MDIGEST
Definition mdigest.h:25
#define GWEN_FREE_OBJECT(varname)
Definition memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition memory.h:55
int GWEN_SimplePtrList_AddTests(GWEN_TEST_MODULE *mod)
GWEN_SIMPLEPTRLIST_ATTACHOBJECT_FN GWEN_SimplePtrList_SetAttachObjectFn(GWEN_SIMPLEPTRLIST *pl, GWEN_SIMPLEPTRLIST_ATTACHOBJECT_FN fn)
void GWEN_SimplePtrList_free(GWEN_SIMPLEPTRLIST *pl)
int64_t GWEN_SimplePtrList_AddPtr(GWEN_SIMPLEPTRLIST *pl, void *p)
GWEN_SIMPLEPTRLIST_FREEOBJECT_FN GWEN_SimplePtrList_SetFreeObjectFn(GWEN_SIMPLEPTRLIST *pl, GWEN_SIMPLEPTRLIST_FREEOBJECT_FN fn)
int GWEN_SimplePtrList_SetPtrAt(GWEN_SIMPLEPTRLIST *pl, uint64_t idx, void *p)
void GWEN_SimplePtrList_AddFlags(GWEN_SIMPLEPTRLIST *pl, uint32_t f)
GWEN_SIMPLEPTRLIST * GWEN_SimplePtrList_LazyCopy(GWEN_SIMPLEPTRLIST *oldList)
GWEN_SIMPLEPTRLIST * GWEN_SimplePtrList_new(uint64_t startEntries, uint64_t steps)
void * GWEN_SimplePtrList_GetPtrAt(const GWEN_SIMPLEPTRLIST *pl, uint64_t idx)
struct GWEN_SIMPLEPTRLIST GWEN_SIMPLEPTRLIST
#define GWEN_SIMPLEPTRLIST_FLAGS_ATTACHTOOBJECTS
#define GWEN_SIMPLEPTRLIST_FLAGS_DETACHFROMOBJECTS
GWEN_TEST_MODULE * GWEN_Test_Module_AddModule(GWEN_TEST_MODULE *st, const char *tName, const char *tDescr)
Definition testmodule.c:440
GWEN_TEST_MODULE * GWEN_Test_Module_AddTest(GWEN_TEST_MODULE *st, const char *tName, GWEN_TEST_MODULE_TEST_FN fn, const char *tDescr)
Definition testmodule.c:424
struct GWEN_TEST_MODULE GWEN_TEST_MODULE
Definition testmodule.h:65