Update copyright to LGPL on all files
[dyninst.git] / testsuite / src / symtab / test_ser_anno.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #include "symtab_comp.h"
33 #include "test_lib.h"
34 #include "Annotatable.h"
35 #include "Serialization.h"
36 #include <iostream>
37
38 #if 0
39 #include "Symtab.h"
40 #include "Symbol.h"
41 #include "Function.h"
42 #include "Variable.h"
43 #include "Module.h"
44 #include "Region.h"
45 #include "Type.h"
46 #include "Archive.h"
47 #endif
48
49 using namespace Dyninst;
50 using namespace SymtabAPI;
51
52 class test_ser_anno_Mutator : public SymtabMutator {
53
54         public:
55
56         test_ser_anno_Mutator() { };
57         virtual test_results_t executeTest();
58 };
59
60 extern "C" DLLEXPORT TestMutator* test_ser_anno_factory()
61 {
62         return new test_ser_anno_Mutator();
63 }
64
65 class AnnotateeBase : public Serializable
66 {
67         public:
68
69                 int somestuff1;
70                 long somestuff2;
71                 Address somestuff3;
72                 float somestuff4;
73                 std::string somestuff5;
74
75                 AnnotateeBase() {}
76                 ~AnnotateeBase() {}
77
78                 void print()
79                 {
80                         logerror( "%s[%d]:  AnnotateeBase[%d, %lu, %p, %f, %s]\n", 
81                                         FILE__, __LINE__, somestuff1, somestuff2, (void *) somestuff3, 
82                                         somestuff4, somestuff5.c_str());
83                 }
84
85                 bool operator==(const AnnotateeBase &src)
86                 {
87                         if (somestuff1 != src.somestuff1) 
88                         {
89                                 logerror( "%s[%d]:  %d != %d\n", FILE__, __LINE__, 
90                                                 somestuff1, src.somestuff1);
91                                 return false;
92                         }
93                         if (somestuff2 != src.somestuff2) 
94                         {
95                                 logerror( "%s[%d]:  %lu != %lu\n", FILE__, __LINE__, 
96                                                 somestuff2, src.somestuff2);
97                                 return false;
98                         }
99                         if (somestuff3 != src.somestuff3) 
100                         {
101                                 logerror( "%s[%d]:  %p != %p\n", FILE__, __LINE__, 
102                                                 somestuff3, src.somestuff3);
103                                 return false;
104                         }
105                         if (somestuff4 != src.somestuff4) 
106                         {
107                                 logerror( "%s[%d]:  %f != %f\n", FILE__, __LINE__, 
108                                                 somestuff4, src.somestuff4);
109                                 return false;
110                         }
111                         if (somestuff5 != src.somestuff5) 
112                         {
113                                 logerror( "%s[%d]:  %s != %s\n", FILE__, __LINE__, 
114                                                 somestuff5.c_str(), src.somestuff5.c_str());
115                                 return false;
116                         }
117                         return true;
118                 }
119
120                 bool operator!=(const AnnotateeBase &src)
121                 {
122                         return (!(*this == src));
123                 }
124
125
126                 Serializable *serialize_impl(SerializerBase *sb, const char *) THROW_SPEC(SerializerError)
127                 {
128                         logerror("%s[%d]:  welcome to AnnotateeBase::serialize_impl: %s\n", 
129                                         FILE__, __LINE__, is_input(sb) ? "deserialize" : "serialize");
130                         //ifxml_start_element(sb, "AnnotateeBase");
131                         gtranslate(sb, somestuff1, "somestuff1");
132                         gtranslate(sb, somestuff2, "somestuff2");
133                         gtranslate(sb, somestuff3, "somestuff3");
134                         gtranslate(sb, somestuff4, "somestuff4");
135                         gtranslate(sb, somestuff5, "somestuff5");
136                         //ifxml_end_element(sb, "AnnotateeBase");
137                         logerror("%s[%d]:  leaving to AnnotateeBase::serialize_impl\n", 
138                                         FILE__, __LINE__);
139                         return NULL;
140                 }
141 };
142
143 #define INIT_OR_CHECK(VAR, VAL, SELECT) \
144         (SELECT ? (NULL != &(VAR = VAL)) : (VAR == VAL))
145
146 #define INIT true
147 #define CHECK false
148
149 int init_or_check_values(AnnotateeBase &ab, bool init_or_check)
150 {
151         if (!INIT_OR_CHECK(ab.somestuff1, 5, init_or_check)) return 1;
152         if (!INIT_OR_CHECK(ab.somestuff2, 55, init_or_check)) return 2;
153         if (!INIT_OR_CHECK(ab.somestuff3, (Address)0x5, init_or_check)) return 3;
154         if (!INIT_OR_CHECK(ab.somestuff4, 5.5, init_or_check)) return 4;
155         if (!INIT_OR_CHECK(ab.somestuff5, std::string("5"), init_or_check)) return 5;
156
157         return 0;
158 }
159
160 class AnnotateeSparse : public AnnotateeBase, public AnnotatableSparse 
161 {
162         public:
163                 AnnotateeSparse() : AnnotateeBase() {}
164                 ~AnnotateeSparse() {}
165 };
166
167 class AnnotateeDense : public AnnotateeBase, public AnnotatableDense 
168 {
169         public:
170                 AnnotateeDense() : AnnotateeBase() {}
171                 ~AnnotateeDense() {}
172 };
173
174 #if 0
175 template <class T>
176 class AnnotateeContainer : public Serializable, public AnnotatableSparse
177 {
178         std::vector<T> elements;
179         public:
180         AnnotateeContainer() {}
181         void addElement(T it) {elements.push_back(it);}
182
183         void serialize_impl(SerializerBase *sb, const char *) THROW_SPEC(SerializerError)
184         {
185                 logerror("%s[%d]:  welcome to MyAnnotationClass::serialize_impl: val = %d, id = %d\n", 
186                                 FILE__, __LINE__, val, getID());
187                 gtranslate(sb, elements, "elements");
188         }
189
190         bool operator==(AnnotateeContainer &src)
191         {
192                 if (elements.size() != src.elements.size())
193                 {
194                         logerror( "%s[%d]:  size mismatch: %d--%d\n", 
195                                         FILE__, __LINE__, elements.size(), src.elements.size());
196                         return false;
197                 }
198
199                 for (unsigned int i = 0; i < elements.size(); ++i)
200                         if (elements[i] != src.elements[i]) 
201                                 return false;
202
203                 return true;
204         }
205
206         bool operator!=(AnnotateeContainer &src)
207         {
208                 return !(*this == src);
209         }
210 };
211
212 template <class T, class A>
213 void test4(AnnotateeContainer<T> &cont, std::vector<T> &elems, std::vector<A> &annos)
214 {
215         assert(elems.size() == annos.size());
216         for (unsigned int i = 0; i < annos.size(); ++i)
217         {
218                 cont.addElement(elems[i]);
219         }
220 }
221 #endif
222
223 class MyAnnotationClass : public Serializable
224 {
225         int val;
226         public:
227
228         MyAnnotationClass() : val(666){}
229         MyAnnotationClass(int x) : val(x) {}
230         ~MyAnnotationClass() {}
231
232
233         Serializable *serialize_impl(SerializerBase *sb, const char *) THROW_SPEC(SerializerError)
234         {
235                 logerror("%s[%d]:  welcome to MyAnnotationClass::serialize_impl: val = %d, id = %d\n", 
236                                 FILE__, __LINE__, val, getID());
237
238                 ifxml_start_element(sb, "MyAnnotationClass");
239                 gtranslate(sb, val, "val");
240                 ifxml_end_element(sb, "MyAnnotationClass");
241
242                 logerror("%s[%d]:  leaving to MyAnnotationClass::serialize_impl, val = %d\n", 
243                                 FILE__, __LINE__, val);
244                 return NULL;
245         }
246
247         bool operator==(MyAnnotationClass &src)
248         {
249                 return src.val == val;
250         }
251
252         bool operator!=(MyAnnotationClass &src)
253         {
254                 return !(*this == src);
255         }
256         friend std::ostream &operator<<(std::ostream &os, const MyAnnotationClass &mac);
257         void print()
258         {
259                 logerror( "%s[%d]:  MyAnnotateeClass: val = %d\n", FILE__, __LINE__, val);
260         }
261 };
262
263 std::ostream &operator<<(std::ostream &os, const MyAnnotationClass &mac)
264 {
265         return os << mac.val;
266 }
267
268 template <class T>
269 class MyAnnotationContainer : public AnnotationContainer<T>
270 {
271         std::vector<T> vec;
272         bool addItem_impl(T i) {vec.push_back(i); return true;}
273
274         public:
275
276         MyAnnotationContainer() : AnnotationContainer<T>() 
277         {
278                 //logerror( "%s[%d]:  MyAnnotationContainer ctor: %p\n", FILE__, __LINE__, this);
279         }
280
281         bool operator==(MyAnnotationContainer &src)
282         {
283                 if (vec.size() != src.vec.size())
284                 {
285                         logerror( "%s[%d]:  size mismatch: %d--%d\n", 
286                                         FILE__, __LINE__, vec.size(), src.vec.size());
287                         return false;
288                 }
289
290                 for (unsigned int i = 0; i < vec.size(); ++i)
291                         if (vec[i] != src.vec[i]) 
292                                 return false;
293
294 #if 0
295                 logerror( "%s[%d]:  annotation container elem0 is %d\n", 
296                                 FILE__, __LINE__, vec.size() ? vec[0] : -1);
297 #endif
298
299                 return true;
300         }
301
302         bool operator!=(MyAnnotationContainer &src)
303         {
304                 return !(*this == src);
305         }
306
307         void print()
308         {
309                 logerror( "%s[%d]:  MyAnnotateeContainer<%s>(size %d): [ ", 
310                                 FILE__, __LINE__, typeid(T).name(), vec.size());
311                 for (unsigned int i = 0; i < vec.size(); ++i)
312                         std::cerr << vec[i] << " ";
313                 logerror( "]\n");
314         }
315
316         Serializable *ac_serialize_impl(SerializerBase *sb, const char *a) THROW_SPEC(SerializerError)
317         {
318                 //logerror( "%s[%d]:  welcome to MyAnnotationContainer::ac_serialize_impl %s: vec.size() = %d, this = %p\n", FILE__, __LINE__, sb_is_input(sb) ? "deserialize" : "serialize", vec.size(), this);
319
320                 gtranslate(sb, vec, "MyAnnotationContainer");
321
322                 //logerror( "%s[%d]:  leaving MyAnnotationContainer::ac_serialize_impl, vec.size() = %d\n", FILE__, __LINE__, vec.size());
323                 return NULL;
324         }
325 };
326
327 class MyAnnotationContainer2 : public AnnotationContainer<MyAnnotationClass *>
328 {
329         std::vector<MyAnnotationClass *> vec;
330         bool addItem_impl(MyAnnotationClass *i) {vec.push_back(i); return true;}
331
332         public:
333
334         MyAnnotationContainer2() : AnnotationContainer<MyAnnotationClass *>() 
335         {
336                 logerror( "%s[%d]:  MyAnnotationContainer2 ctor: %p\n", FILE__, __LINE__, this);
337         }
338
339         bool operator==(MyAnnotationContainer2 &src)
340         {
341                 if (vec.size() != src.vec.size())
342                 {
343                         logerror( "%s[%d]:  size mismatch: %d--%d\n", 
344                                         FILE__, __LINE__, vec.size(), src.vec.size());
345                         return false;
346                 }
347
348                 for (unsigned int i = 0; i < vec.size(); ++i)
349                         if ( (*vec[i]) != (*src.vec[i])) 
350                                 return false;
351
352 #if 0
353                 logerror( "%s[%d]:  annotation container elem0 is %d\n", 
354                                 FILE__, __LINE__, vec.size() ? (*vec[0]) : -1);
355 #endif
356
357                 return true;
358         }
359
360         bool operator!=(MyAnnotationContainer2 &src)
361         {
362                 return !(*this == src);
363         }
364
365         void print()
366         {
367                 logerror( "%s[%d]:  MyAnnotateeContainer2(size %d): [ ", 
368                                 FILE__, __LINE__, vec.size());
369                 for (unsigned int i = 0; i < vec.size(); ++i)
370                         std::cerr << *vec[i] << " ";
371                 logerror( "]\n");
372         }
373
374         Serializable *ac_serialize_impl(SerializerBase *sb, const char *a) THROW_SPEC(SerializerError)
375         {
376                 logerror( "%s[%d]:  welcome to MyAnnotationContainer2::ac_serialize_impl %s: vec.size() = %d, this = %p\n", FILE__, __LINE__, sb_is_input(sb) ? "deserialize" : "serialize", vec.size(), this);
377
378                 gtranslate(sb, vec, "MyAnnotationContainer2");
379
380                 logerror( "%s[%d]:  leaving MyAnnotationContainer2::ac_serialize_impl, vec.size() = %d\n", FILE__, __LINE__, vec.size());
381                 return NULL;
382         }
383 };
384
385
386 void unlinkSerfile(SerContextBase *scb)
387 {
388         if (!scb) return;
389         std::string fname = scb->getSerFileName();
390         if (fname.length())
391         {
392                 logerror("%s[%d]:  unlinking %s\n", FILE__, __LINE__, fname.c_str());
393                 unlink(fname.c_str());
394         }
395 }
396 template <class A, class C>
397 void serialize_test1(A &annotatee, C &control) THROW_SPEC(LocErr)
398 {
399         SerContext<A> *scs = NULL;
400         try {
401         //  serialize_test1:  add annotation to class A (annotatee), serialize A.
402         //  Then deserialize A and verify that (1) serialization worked for A proper,
403         //  and (2) that added annotation was also properly serialized
404         //
405         //  This should work for both cases where C (the annotation class) is derived
406         //  from Serializable and when it is a basic type
407
408         if (dynamic_cast<AnnotatableSparse *>(&annotatee))
409                 logerror("%s[%d]:  annotatee is sparse\n", FILE__, __LINE__);
410         else if (dynamic_cast<AnnotatableDense *>(&annotatee))
411                 logerror("%s[%d]:  annotatee is dense\n", FILE__, __LINE__);
412         else {
413                 EFAIL("ERROR:  annotatee is not annotatable\n");
414         }
415
416         logerror( "%s[%d]: welcome to serialize test for annotating type %s with %s\n",
417                         FILE__, __LINE__, typeid(A).name(), typeid(C).name());
418
419         Tempfile tf;
420         std::string file(tf.getName());
421
422         //  Add the annotation
423         std::string an = std::string(typeid(C).name()) + std::string(typeid(A).name());
424
425         AnnotationClass<C> *my_acp = new AnnotationClass<C>(an);
426         AnnotationClass<C> &my_ac = *my_acp;
427
428         if (!annotatee.addAnnotation(&control, my_ac))
429         {
430                 EFAIL("failed to add annotation");
431         }
432
433         if (NULL == my_ac.getSerializeFunc())
434                 EFAIL("annotation class has no serialize func");
435
436         //  Do the serialization
437         scs = new SerContext<A>(&annotatee, file);
438         scs->enableSerDes(true);
439
440         if (!annotatee.serialize(file, scs, ser_bin))
441         {
442                 unlinkSerfile(scs);
443                 EFAIL("serialize failed");
444         }
445
446         //  It is necessary to flush the file buffers to make sure the cache file is
447         //  fully synchronized before we do deserialize.
448         fflush(NULL);
449
450         logerror( "%s[%d]:  after serialize\n", FILE__, __LINE__);
451
452         A deserialize_result;
453         Serializable &c_serial = (Serializable &) deserialize_result;
454
455         //  Do the deserialize
456         try 
457         {
458                 c_serial.deserialize(file, scs);
459         }
460         catch (const SerializerError &serr)
461         {
462                 logerror( "%s[%d]:  serializer function threw exception:\n", FILE__, __LINE__);
463                 logerror( "\tfrom %s[%d]: %s\n", serr.file().c_str(), serr.line(), serr.what());
464                 unlinkSerfile(scs);
465                 EFAIL("deserialize failed");
466         }
467
468         if (annotatee != deserialize_result)
469         {
470                 deserialize_result.print();
471                 unlinkSerfile(scs);
472                 EFAIL("deserialize result is incorrect");
473         }
474
475         //  checking equality is fine, but let's also check absolute values
476         int res = 0;
477         if ( 0 != (res = init_or_check_values(deserialize_result, CHECK))) 
478         {
479                 deserialize_result.print();
480                 logerror( "%s[%d]:  res = %d\n", FILE__, __LINE__);
481                 unlinkSerfile(scs);
482                 EFAIL("deserialized annotatee has bad values");
483         }
484
485         //  operator== will check basic class values, but we also need to verify annotations
486         C *des_annotation;
487         if (!deserialize_result.getAnnotation(des_annotation, my_ac))
488         {
489                 unlinkSerfile(scs);
490                 EFAIL("could not find annotation in deserialized result");
491         }
492
493         if (*des_annotation != control)
494         {
495                 logerror( "%s[%d]:  annotations (id = %d) did not match after deserialize\n", FILE__, __LINE__, my_ac.getID());
496                 logerror( "%s[%d]:  des_annotation = %p, des_obj = %p, control = %p\n", FILE__, __LINE__, des_annotation, &deserialize_result, &control);
497
498                 des_annotation->print();
499                 control.print();
500                 unlinkSerfile(scs);
501                 EFAIL("deserialized annotation did not match provided value");
502         }
503         }
504         catch (const SerializerError &serr)
505         {
506                 logerror( "%s[%d]:  serializer function threw exception:\n", FILE__, __LINE__);
507                 logerror( "\tfrom %s[%d]: %s\n", serr.file().c_str(), serr.line(), serr.what());
508                 //EFAIL("deserialize failed\n");
509         }
510 #if 0
511         catch (...)
512         {
513                 logerror( "%s[%d]:  caught unknown exception\n", FILE__, __LINE__);
514         }
515 #endif
516         unlinkSerfile(scs);
517 }
518
519 template <class A, class C>
520 void serialize_test2(A &annotatee, C &control) THROW_SPEC(LocErr)
521 {
522         //  serialize_test2:  First serialize A, then add an annotation to A.  
523         //  Then deserialize A and verify that (1) serialization worked for A proper,
524         //  and (2) that added annotation was also properly serialized
525         //
526         //  This should work for both cases where C (the annotation class) is derived
527         //  from Serializable and when it is a basic type
528
529         SerContext<A> *scs = NULL;
530
531         AnnotatableDense *ad = NULL;
532         if (dynamic_cast<AnnotatableSparse *>(&annotatee))
533                 logerror("%s[%d]:  annotatee is sparse\n", FILE__, __LINE__);
534         else if (NULL != ( ad = dynamic_cast<AnnotatableDense *>(&annotatee)))
535                 logerror("%s[%d]:  \nannotatee is dense: %p\n", FILE__, __LINE__, ad);
536         else {
537                 EFAIL("ERROR:  annotatee is not annotatable\n");
538         }
539
540         logerror( "%s[%d]: welcome to serialize test for annotating type %s with %s\n",
541                         FILE__, __LINE__, typeid(A).name(), typeid(C).name());
542
543         Tempfile tf;
544         std::string file(tf.getName());
545
546         //  Do the serialization
547         //annotatee.serialize(serializer, NULL);
548         
549         scs = new SerContext<A>(&annotatee, file);
550         scs->enableSerDes(true);
551         if (!annotatee.serialize(file, scs, ser_bin))
552         {
553                 unlinkSerfile(scs);
554                 EFAIL("serialize failed");
555         }
556
557         //  Add the annotation
558         std::string an = std::string(typeid(C).name()) + std::string(typeid(A).name());
559         AnnotationClass<C> *my_acp = new AnnotationClass<C>(an);
560         AnnotationClass<C> &my_ac = *my_acp;
561
562         if (NULL == my_ac.getSerializeFunc())
563         {
564                 unlinkSerfile(scs);
565                 EFAIL("annotation class has no serialize func");
566         }
567
568         if (!annotatee.addAnnotation(&control, my_ac))
569         {
570                 unlinkSerfile(scs);
571                 EFAIL("failed to add annotation");
572         }
573
574         //  It is necessary to flush the file buffers to make sure the cache file is
575         //  fully synchronized before we do deserialize.
576         if (0 !=fflush(NULL))
577         {
578                 logerror( "%s[%d]:  fflush failed: %s\n", FILE__, __LINE__, strerror(errno));
579         }
580
581         logerror( "%s[%d]:  after serialize\n", FILE__, __LINE__);
582
583
584         A deserialize_result;
585         Serializable &c_serial = (Serializable &) deserialize_result;
586
587
588         //  Do the deserialize
589         try 
590         {
591                 //c_serial.serialize(deserializer, NULL);
592                 if (!c_serial.deserialize(file, scs))
593                 {
594                         unlinkSerfile(scs);
595                         EFAIL("deserialize failed");
596                 }
597         }
598         catch (const SerializerError &serr)
599         {
600                 logerror( "%s[%d]:  serializer function threw exception:\n", FILE__, __LINE__);
601                 logerror( "\tfrom %s[%d]: %s\n", serr.file().c_str(), serr.line(), serr.what());
602                 unlinkSerfile(scs);
603                 EFAIL("deserialize failed\n");
604         }
605
606         if (annotatee != deserialize_result)
607         {
608                 deserialize_result.print();
609                 unlinkSerfile(scs);
610                 EFAIL("deserialize result is incorrect");
611         }
612
613         //  checking equality is fine, but let's also check absolute values
614         if ( 0 != init_or_check_values(deserialize_result, CHECK)) 
615         {
616                 deserialize_result.print();
617                 unlinkSerfile(scs);
618                 EFAIL("deserialized annotatee has bad values");
619         }
620
621         //  operator== will check basic class values, but we also need to verify annotations
622         C *des_annotation;
623         if (!deserialize_result.getAnnotation(des_annotation, my_ac))
624         {
625                 unlinkSerfile(scs);
626                 EFAIL("could not find annotation in deserialized result");
627         }
628
629         if (*des_annotation != control)
630         {
631                 des_annotation->print();
632                 control.print();
633                 unlinkSerfile(scs);
634                 EFAIL("deserialized annotation did not match provided value");
635         }
636         unlinkSerfile(scs);
637 }
638
639
640 template <class A, class C, class I>
641 void serialize_test3(A &annotatee, C &container, I item) THROW_SPEC(LocErr)
642 {
643         //  serialize_test3:  Add annotation to A, then serialize A.  
644         //  Then add item to annotation container and verify that (1) serialization 
645         //  worked for A proper,
646         //  and (2) that added annotation was also properly serialized
647         //  and (3) that added item was also properly serialized
648
649         SerContext<A> *scs = NULL;
650         AnnotatableDense *ad = NULL;
651         if (dynamic_cast<AnnotatableSparse *>(&annotatee))
652                 logerror("%s[%d]:  annotatee is sparse\n", FILE__, __LINE__);
653         else if (NULL != ( ad = dynamic_cast<AnnotatableDense *>(&annotatee)))
654                 logerror("%s[%d]:  \nannotatee is dense: %p\n", FILE__, __LINE__, ad);
655         else {
656                 EFAIL("ERROR:  annotatee is not annotatable\n");
657         }
658
659         logerror( "%s[%d]: welcome to serialize test for annotating type %s with %s\n",
660                         FILE__, __LINE__, typeid(A).name(), typeid(C).name());
661
662         Tempfile tf;
663         std::string file(tf.getName());
664
665         
666         //  Add the annotation
667         std::string an = std::string(typeid(C).name()) + std::string(typeid(A).name()) + std::string(typeid(I).name());
668         AnnotationClass<C> *my_acp = new AnnotationClass<C>(an);
669         AnnotationClass<C> &my_ac = *my_acp;
670
671         if (NULL == my_ac.getSerializeFunc())
672                 EFAIL("annotation class has no serialize func");
673
674         if (!annotatee.addAnnotation(&container, my_ac))
675                 EFAIL("failed to add annotation");
676
677         //  Do the serialization
678         //annotatee.serialize(serializer, NULL);
679         scs = new SerContext<A>(&annotatee, file);
680         scs->enableSerDes(true);
681         if (!annotatee.serialize(file, scs, ser_bin))
682         {
683                 unlinkSerfile(scs);
684                 EFAIL("serialize failed");
685         }
686
687         //  Add the item to the container post-serialize
688         if (!container.addItem(item))
689         {
690                 unlinkSerfile(scs);
691                 EFAIL("failed to add item to container here");
692         }
693
694         //  It is necessary to flush the file buffers to make sure the cache file is
695         //  fully synchronized before we do deserialize.
696         if (0 !=fflush(NULL))
697
698         logerror( "%s[%d]:  after serialize\n", FILE__, __LINE__);
699
700
701         A deserialize_result;
702         Serializable &c_serial = (Serializable &) deserialize_result;
703
704
705         //  Do the deserialize
706         try 
707         {
708                 //c_serial.serialize(deserializer, NULL);
709                 if (!c_serial.deserialize(file, scs))
710                 {
711                         logerror( "%s[%d]:  deserialize failed\n", FILE__, __LINE__);
712                 }
713         }
714         catch (const SerializerError &serr)
715         {
716                 logerror( "%s[%d]:  serializer function threw exception:\n", FILE__, __LINE__);
717                 logerror( "\tfrom %s[%d]: %s\n", serr.file().c_str(), serr.line(), serr.what());
718                 unlinkSerfile(scs);
719                 EFAIL("deserialize failed\n");
720         }
721
722         if (annotatee != deserialize_result)
723         {
724                 logerror( "%s[%d]:  deserialize result is incorrect\n", FILE__, __LINE__);
725                 deserialize_result.print();
726         }
727
728         //  checking equality is fine, but let's also check absolute values
729         if ( 0 != init_or_check_values(deserialize_result, CHECK)) 
730         {
731                 deserialize_result.print();
732                 unlinkSerfile(scs);
733                 EFAIL("deserialized annotatee has bad values\n");
734         }
735
736         //  operator== will check basic class values, but we also need to verify annotations
737         C *des_annotation;
738         if (!deserialize_result.getAnnotation(des_annotation, my_ac))
739         {
740                 unlinkSerfile(scs);
741                 EFAIL("could not find annotation in deserialized result");
742         }
743
744         if (*des_annotation != container)
745         {
746                 des_annotation->print();
747                 container.print();
748                 unlinkSerfile(scs);
749                 EFAIL("deserialized annotation did not match provided value");
750         }
751
752         unlinkSerfile(scs);
753 }
754 test_results_t test_ser_anno_Mutator::executeTest()
755 {
756
757         //  set environment variable enabling serialization
758         errno = 0;
759
760         try 
761         {
762                 AnnotateeSparse as1;
763                 Serializable *s = dynamic_cast<Serializable *>(&as1);
764                 if (!s)
765                 {
766                         logerror( "%s[%d]:  as1 not serializable\n", FILE__, __LINE__);
767                         return FAILED;
768                 }
769                 AnnotatableSparse *ss = dynamic_cast<AnnotatableSparse *>(s);
770                 if (!ss)
771                 {
772                         logerror( "%s[%d]:  as1 not annotatableSparse\n", FILE__, __LINE__);
773                         return FAILED;
774                 }
775                 if ( 0 != init_or_check_values(as1, INIT)) 
776                 {
777                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
778                                         FILE__, __LINE__);
779                         return FAILED;
780                 }
781                 as1.print();
782                 MyAnnotationClass mac(77);
783                 serialize_test1(as1, mac);
784
785                 AnnotateeDense ad1;
786                 if ( 0 != init_or_check_values(ad1, INIT)) 
787                 {
788                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
789                                         FILE__, __LINE__);
790                         return FAILED;
791                 }
792                 ad1.print();
793                 MyAnnotationClass mac2(8);
794                 serialize_test1(ad1, mac2);
795
796                 AnnotateeSparse *as2 = new AnnotateeSparse();
797                 if ( 0 != init_or_check_values(*as2, INIT)) 
798                 {
799                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
800                                         FILE__, __LINE__);
801                         return FAILED;
802                 }
803                 as2->print();
804                 MyAnnotationClass mac3(11);
805                 serialize_test2(*as2, mac3);
806
807
808                 AnnotateeDense ad2;
809                 if ( 0 != init_or_check_values(ad2, INIT)) 
810                 {
811                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
812                                         FILE__, __LINE__);
813                         return FAILED;
814                 }
815                 ad2.print();
816                 MyAnnotationClass mac4(10);
817                 serialize_test2(ad2, mac4);
818
819                 //  same thing with annotation containers
820                 //  First check that empty containers work...
821                 AnnotateeSparse as3;
822                 if ( 0 != init_or_check_values(as3, INIT)) 
823                 {
824                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
825                                         FILE__, __LINE__);
826                         return FAILED;
827                 }
828                 as3.print();
829                 MyAnnotationContainer<int> cont1;
830                 serialize_test1(as1, cont1);
831
832                 AnnotateeDense ad3;
833                 if ( 0 != init_or_check_values(ad3, INIT)) 
834                 {
835                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
836                                         FILE__, __LINE__);
837                         return FAILED;
838                 }
839                 ad3.print();
840                 MyAnnotationContainer<int> cont2;
841                 serialize_test1(ad3, cont2);
842
843                 AnnotateeSparse as4;
844                 if ( 0 != init_or_check_values(as4, INIT)) 
845                 {
846                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
847                                         FILE__, __LINE__);
848                         return FAILED;
849                 }
850                 as4.print();
851                 MyAnnotationContainer<int> cont3;
852                 serialize_test2(as4, cont3);
853
854                 AnnotateeDense ad4;
855                 if ( 0 != init_or_check_values(ad4, INIT)) 
856                 {
857                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
858                                         FILE__, __LINE__);
859                         return FAILED;
860                 }
861                 ad4.print();
862                 MyAnnotationContainer<int> cont4;
863                 serialize_test2(ad4, cont4);
864
865                 //  Slightly less trivial case:  the annotation containers actually contain stuff
866                 AnnotateeSparse as5;
867                 if ( 0 != init_or_check_values(as5, INIT)) 
868                 {
869                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
870                                         FILE__, __LINE__);
871                         return FAILED;
872                 }
873                 as5.print();
874                 MyAnnotationContainer<int> cont5;
875                 cont5.addItem(5);
876                 serialize_test1(as5, cont5);
877
878                 AnnotateeDense ad5;
879                 if ( 0 != init_or_check_values(ad5, INIT)) 
880                 {
881                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
882                                         FILE__, __LINE__);
883                         return FAILED;
884                 }
885                 ad5.print();
886                 MyAnnotationContainer<int> cont6;
887                 cont6.addItem(6);
888                 serialize_test1(ad5, cont6);
889
890                 AnnotateeSparse as6;
891                 if ( 0 != init_or_check_values(as6, INIT)) 
892                 {
893                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
894                                         FILE__, __LINE__);
895                         return FAILED;
896                 }
897                 as6.print();
898                 MyAnnotationContainer<int> cont7;
899                 cont7.addItem(7);
900                 serialize_test2(as6, cont7);
901
902                 AnnotateeDense ad6;
903                 if ( 0 != init_or_check_values(ad6, INIT)) 
904                 {
905                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
906                                         FILE__, __LINE__);
907                         return FAILED;
908                 }
909                 ad6.print();
910                 MyAnnotationContainer<int> cont8;
911                 cont8.addItem(8);
912                 serialize_test2(ad6, cont8);
913
914                 //  now test serializing additions to containers
915
916                 //  first use int
917                 AnnotateeSparse as7;
918                 if ( 0 != init_or_check_values(as7, INIT)) 
919                 {
920                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
921                                         FILE__, __LINE__);
922                         return FAILED;
923                 }
924                 as7.print();
925                 MyAnnotationContainer<int> cont9;
926                 serialize_test3(as7, cont9, 9);
927
928                 AnnotateeDense ad7;
929                 if ( 0 != init_or_check_values(ad7, INIT)) 
930                 {
931                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
932                                         FILE__, __LINE__);
933                         return FAILED;
934                 }
935                 ad7.print();
936                 MyAnnotationContainer<int> cont10;
937                 serialize_test3(ad7, cont10, 10);
938
939                 //  then use descendant of Serializable
940                 AnnotateeSparse as8;
941                 if ( 0 != init_or_check_values(as8, INIT)) 
942                 {
943                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
944                                         FILE__, __LINE__);
945                         return FAILED;
946                 }
947                 as8.print();
948                 MyAnnotationContainer<MyAnnotationClass> cont11;
949                 MyAnnotationClass mac11(11);
950                 serialize_test3(as8, cont11, mac11);
951
952                 AnnotateeDense ad8;
953                 if ( 0 != init_or_check_values(ad8, INIT)) 
954                 {
955                         logerror( "%s[%d]:  weird, failed to init annotatee here\n", 
956                                         FILE__, __LINE__);
957                         return FAILED;
958                 }
959                 ad8.print();
960                 MyAnnotationContainer<MyAnnotationClass> cont12;
961                 MyAnnotationClass mac12(12);
962                 serialize_test3(ad8, cont12, mac12);
963
964                 //  then test container of pointers to Serializable
965         }
966         catch (const LocErr &err) {
967                 logerror( "%s[%d]:  FAILED\n", FILE__, __LINE__);
968                 err.print(stderr);
969                 return FAILED;
970         }
971         catch (const SerializerError &serr)
972         {
973                 logerror( "%s[%d]:  serializer function threw exception:\n", FILE__, __LINE__);
974                 logerror( "\tfrom %s[%d]: %s\n", serr.file().c_str(), serr.line(), serr.what());
975                 EFAIL("deserialize failed");
976         }
977         catch (...)
978         {
979                 logerror( "%s[%d]:  caught unknown exception\n", FILE__, __LINE__);
980                 return FAILED;
981         }
982                 
983         return PASSED;
984 }