1 /* Copyright (C) 2014 InfiniDB, Inc.
2 
3    This program is free software; you can redistribute it and/or
4    modify it under the terms of the GNU General Public License
5    as published by the Free Software Foundation; version 2 of
6    the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16    MA 02110-1301, USA. */
17 
18 /*********************************************************************
19  *   $Id: tdriver.cpp 1823 2013-01-21 14:13:09Z rdempsey $
20  *
21  ********************************************************************/
22 
23 #include <iostream>
24 #include <pthread.h>
25 #include <errno.h>
26 #include <sys/types.h>
27 #include <sys/ipc.h>
28 #include <sys/sem.h>
29 #include <sys/shm.h>
30 #include <stdexcept>
31 #include <signal.h>
32 #include <values.h>
33 #include <cppunit/extensions/HelperMacros.h>
34 
35 #include "brm.h"
36 #include "lbidresourcegraph.h"
37 
38 #ifdef NO_TESTS
39 #undef CPPUNIT_ASSERT
40 #define CPPUNIT_ASSERT(a)
41 #endif
42 
43 using namespace BRM;
44 using namespace std;
45 using namespace config;
46 
47 pthread_mutex_t mutex;
48 
keepalive(int signum)49 void keepalive(int signum)
50 {
51     cerr << "Yes, it's still going..." << endl;
52     alarm(290);
53 }
54 
dummy_1(void * arg)55 void* dummy_1(void* arg)
56 {
57     LBIDResourceGraph* rg = (LBIDResourceGraph*) arg;
58     int err;
59     VER_t txn = 2;
60 
61     pthread_mutex_lock(&mutex);
62     err = rg->reserveRange(0, 2000, txn, mutex);
63     CPPUNIT_ASSERT(err == 0);
64     rg->releaseResources(txn);
65     pthread_mutex_unlock(&mutex);
66     return NULL;
67 }
68 
dummy_deadlock(void * arg)69 void* dummy_deadlock(void* arg)
70 {
71     LBIDResourceGraph* rg = (LBIDResourceGraph*) arg;
72     int err;
73     VER_t txn = 2;
74 
75     pthread_mutex_lock(&mutex);
76     err = rg->reserveRange(1001, 2000, txn, mutex);
77     CPPUNIT_ASSERT(err == 0);
78     err = rg->reserveRange(0, 1000, txn, mutex);
79     CPPUNIT_ASSERT(err == 0);
80     rg->releaseResources(txn);
81     CPPUNIT_ASSERT(err == 0);
82     pthread_mutex_unlock(&mutex);
83     return NULL;
84 }
85 
fragd_range_helper(void * arg)86 void* fragd_range_helper(void* arg)
87 {
88     LBIDResourceGraph* rg = (LBIDResourceGraph*) arg;
89     set<ResourceNode*, RNLess<ResourceNode*> >* resources;
90     map<VER_t, TransactionNode*>* txns;
91     int err;
92     VER_t txn = 2;
93 
94     pthread_mutex_lock(&mutex);
95     resources = rg->getResources();
96     txns = rg->getTxns();
97     CPPUNIT_ASSERT(resources->size() == 2);
98     CPPUNIT_ASSERT(txns->size() == 1);
99     err = rg->reserveRange(0, 5000, txn, mutex);
100 
101     // blocks, main thread releases
102 
103     CPPUNIT_ASSERT(err == 0);
104     CPPUNIT_ASSERT(resources->size() == 5);
105     CPPUNIT_ASSERT(txns->size() == 1);
106     rg->releaseResources(txn);
107     pthread_mutex_unlock(&mutex);
108 
109     return NULL;
110 }
111 
overlapping_range_helper(void * arg)112 void* overlapping_range_helper(void* arg)
113 {
114     LBIDResourceGraph* rg = (LBIDResourceGraph*) arg;
115     set<ResourceNode*, RNLess<ResourceNode*> >* resources;
116     set<ResourceNode*, RNLess<ResourceNode*> >::const_iterator it;
117     map<VER_t, TransactionNode*>* txns;
118     int err;
119     VER_t txn = 2;
120 
121     pthread_mutex_lock(&mutex);
122     resources = rg->getResources();
123     txns = rg->getTxns();
124     CPPUNIT_ASSERT(resources->size() == 2);
125     CPPUNIT_ASSERT(txns->size() == 1);
126     err = rg->reserveRange(1100, 3900, txn, mutex);
127 
128     // blocks, main thread releases
129 
130     CPPUNIT_ASSERT(err == 0);
131     CPPUNIT_ASSERT(resources->size() == 3);
132     it = resources->begin();
133     CPPUNIT_ASSERT((*it)->start() == 1100);
134     CPPUNIT_ASSERT((*it)->end() == 2000);
135     it++;
136     CPPUNIT_ASSERT((*it)->start() == 2001);
137     CPPUNIT_ASSERT((*it)->end() == 3000);
138     it++;
139     CPPUNIT_ASSERT((*it)->start() == 3001);
140     CPPUNIT_ASSERT((*it)->end() == 3900);
141     CPPUNIT_ASSERT(txns->size() == 1);
142     rg->releaseResources(txn);
143     pthread_mutex_unlock(&mutex);
144 
145     return NULL;
146 }
147 
148 class BRMTest : public CppUnit::TestFixture
149 {
150 
151     CPPUNIT_TEST_SUITE(BRMTest);
152     CPPUNIT_TEST(masterSegmentTest_goodbad);
153     CPPUNIT_TEST(extentMap_good_1);
154 #ifdef PARTITIONING
155     CPPUNIT_TEST(extentMap_range_1);
156 #endif
157     CPPUNIT_TEST(extentMap_freelist);
158 // CPPUNIT_TEST(extentMap_overfill);
159 //CPPUNIT_TEST(many_ExtentMap_instances); //Jean unsuggested this case since writeengine use singleton
160     CPPUNIT_TEST(copyLocks_good_1);
161     CPPUNIT_TEST(vbbm_good_1);
162     CPPUNIT_TEST(vbbm_good_1);
163     CPPUNIT_TEST(vss_good_1);
164     CPPUNIT_TEST(vss_good_1);
165 //CPPUNIT_TEST(brm_extentmap_good_1);//fix for bug 640, this test case has a bug
166 #ifdef PARTITIONING
167     CPPUNIT_TEST(brm_extentmap_range_1);
168 #endif
169     CPPUNIT_TEST(brm_good_2);
170     CPPUNIT_TEST(brm_good_3);
171     CPPUNIT_TEST(brm_deleteOID);
172     CPPUNIT_TEST(brm_HWM);
173     CPPUNIT_TEST(resource_graph_1);
174     CPPUNIT_TEST(resource_graph_fragd_range);
175     CPPUNIT_TEST(resource_graph_deadlock);
176     CPPUNIT_TEST(resource_graph_overlapping_ranges);
177 
178     CPPUNIT_TEST_SUITE_END();
179 
180 private:
181 public:
182 
masterSegmentTest_goodbad()183     void masterSegmentTest_goodbad()
184     {
185         MasterSegmentTable mst;
186         struct MSTEntry* mt;
187 
188 // 		cerr << "MST goodbad" << endl;
189 
190         mt = mst.getTable_write(MasterSegmentTable::EMTable, false);
191         CPPUNIT_ASSERT(mt != NULL);
192         mt = mst.getTable_write(MasterSegmentTable::EMTable, false);
193         CPPUNIT_ASSERT(mt == NULL);
194         mt = mst.getTable_write(MasterSegmentTable::EMFreeList, false);
195         CPPUNIT_ASSERT(mt != NULL);
196         mt = mst.getTable_write(MasterSegmentTable::EMFreeList, false);
197         CPPUNIT_ASSERT(mt == NULL);
198         mt = mst.getTable_write(MasterSegmentTable::VBBMSegment, false);
199         CPPUNIT_ASSERT(mt != NULL);
200         mt = mst.getTable_write(MasterSegmentTable::VBBMSegment, false);
201         CPPUNIT_ASSERT(mt == NULL);
202 
203         mst.releaseTable_write(MasterSegmentTable::EMTable);
204         mst.releaseTable_write(MasterSegmentTable::EMFreeList);
205         mst.releaseTable_write(MasterSegmentTable::VBBMSegment);
206 
207         mt = mst.getTable_write(MasterSegmentTable::EMTable, false);
208         CPPUNIT_ASSERT(mt != NULL);
209         mt = mst.getTable_write(MasterSegmentTable::EMFreeList, false);
210         CPPUNIT_ASSERT(mt != NULL);
211         mt = mst.getTable_write(MasterSegmentTable::VBBMSegment, false);
212         CPPUNIT_ASSERT(mt != NULL);
213         mt = mst.getTable_write(MasterSegmentTable::EMTable, false);
214         CPPUNIT_ASSERT(mt == NULL);
215         mt = mst.getTable_write(MasterSegmentTable::EMFreeList, false);
216         CPPUNIT_ASSERT(mt == NULL);
217         mt = mst.getTable_write(MasterSegmentTable::VBBMSegment, false);
218         CPPUNIT_ASSERT(mt == NULL);
219         mst.releaseTable_write(MasterSegmentTable::EMTable);
220         mst.releaseTable_write(MasterSegmentTable::EMFreeList);
221         mst.releaseTable_write(MasterSegmentTable::VBBMSegment);
222 
223         mt = mst.getTable_read(MasterSegmentTable::EMTable, false);
224         CPPUNIT_ASSERT(mt != NULL);
225         mt = mst.getTable_read(MasterSegmentTable::EMTable, false);
226         CPPUNIT_ASSERT(mt != NULL);
227         mt = mst.getTable_read(MasterSegmentTable::EMTable, false);
228         CPPUNIT_ASSERT(mt != NULL);
229         mt = mst.getTable_write(MasterSegmentTable::EMTable, false);
230         CPPUNIT_ASSERT(mt == NULL);
231         mst.releaseTable_read(MasterSegmentTable::EMTable);
232         mst.releaseTable_read(MasterSegmentTable::EMTable);
233         mst.releaseTable_read(MasterSegmentTable::EMTable);
234 
235         mt = mst.getTable_write(MasterSegmentTable::EMTable, false);
236         CPPUNIT_ASSERT(mt != NULL);
237         mt = mst.getTable_read(MasterSegmentTable::EMTable, false);
238         CPPUNIT_ASSERT(mt == NULL);
239         mst.releaseTable_write(MasterSegmentTable::EMTable);
240         Config::deleteInstanceMap();
241     }
242 
extentMap_good_1()243     void extentMap_good_1()
244     {
245         ExtentMap em;
246         int i, err, oid, iterations = 1300;  // (EM_INITIAL_SIZE + 3*EM_INCREMENT)
247         int caughtException = 0, allocdSize;
248         uint32_t fbo, hwm;
249         BRM::HWM_t hwm2;
250         BRM::VER_t txnID;
251         vector<LBID_t> lbids;
252         const uint32_t extentSize = em.getExtentSize();
253 
254 // 		cerr << "em_good_1" << endl;
255 
256         for (i = 1; i < iterations; i++)
257         {
258             em.createExtent(extentSize, i, lbids, allocdSize);
259             em.confirmChanges();
260             CPPUNIT_ASSERT(lbids.size() == 1);
261             CPPUNIT_ASSERT((uint32_t)allocdSize == extentSize);
262             CPPUNIT_ASSERT(lbids.back() == static_cast<LBID_t>((i - 1)*extentSize));
263         }
264 
265         em.checkConsistency();
266         em.save(string("EMImage"));
267         em.load(string("EMImage"));
268         em.checkConsistency();
269 
270         for (i = 1; i < iterations; i++)
271         {
272             err = em.lookup(static_cast<LBID_t>((i - 1) * extentSize), oid, fbo);
273             CPPUNIT_ASSERT(err == 0);
274             CPPUNIT_ASSERT(oid == i);
275             CPPUNIT_ASSERT(fbo == 0);
276 
277             if (i != 1)
278             {
279                 err = em.lookup(static_cast<LBID_t>((i - 1) * extentSize - 1), oid, fbo);
280                 CPPUNIT_ASSERT(err == 0);
281                 CPPUNIT_ASSERT(oid == i - 1);
282                 CPPUNIT_ASSERT(fbo == extentSize - 1);
283             }
284 
285             if (i != iterations - 1)
286             {
287                 err = em.lookup(static_cast<LBID_t>((i - 1) * extentSize + 1), oid, fbo);
288                 CPPUNIT_ASSERT(err == 0);
289                 CPPUNIT_ASSERT(oid == i);
290                 CPPUNIT_ASSERT(fbo == 1);
291             }
292         }
293 
294         em.checkConsistency();
295 
296         err = em.lookup(static_cast<LBID_t>(i * extentSize), oid, fbo);
297         CPPUNIT_ASSERT(err == -1);
298 
299         for (i = 1; i < iterations; i++)
300         {
301             err = em.getBulkInsertVars(static_cast<LBID_t>((i - 1) * extentSize),
302                                        hwm2, txnID);
303             CPPUNIT_ASSERT(err == 0);
304             CPPUNIT_ASSERT(hwm2 == 0);
305             CPPUNIT_ASSERT(txnID == 0);
306             err = em.setBulkInsertVars(static_cast<LBID_t>((i - 1) * extentSize),
307                                        i, i + 1);
308             em.confirmChanges();
309             CPPUNIT_ASSERT(err == 0);
310             err = em.getBulkInsertVars(static_cast<LBID_t>((i - 1) * extentSize),
311                                        hwm2, txnID);
312             CPPUNIT_ASSERT(err == 0);
313             CPPUNIT_ASSERT(hwm2 == static_cast<LBID_t>(i));
314             CPPUNIT_ASSERT(txnID == static_cast<VER_t>(i + 1));
315 
316             hwm = em.getHWM(i);
317             CPPUNIT_ASSERT(hwm == 0);
318             em.setHWM(i, ((uint32_t)i > (extentSize - 1) ? extentSize - 1 : i));
319             em.confirmChanges();
320             hwm = em.getHWM(i);
321             CPPUNIT_ASSERT(hwm == static_cast<uint32_t>((uint32_t)i > extentSize - 1 ? extentSize - 1 : i));
322         }
323 
324         em.checkConsistency();
325 
326 #ifdef BRM_DEBUG
327         caughtException = 0;
328 
329         try
330         {
331             em.setHWM(i, hwm);
332         }
333         catch (std::invalid_argument e)
334         {
335             caughtException = 1;
336         }
337 
338         em.undoChanges();
339         CPPUNIT_ASSERT(caughtException == 1);
340 #endif
341 
342         for (i = 1; i < iterations; i++)
343         {
344             em.deleteOID(i);
345             em.confirmChanges();
346         }
347 
348 #ifdef BRM_DEBUG
349         caughtException = 0;
350 
351         try
352         {
353             em.deleteOID(i);
354         }
355         catch (std::invalid_argument& e)
356         {
357             caughtException = 1;
358         }
359 
360         em.undoChanges();
361         CPPUNIT_ASSERT(caughtException == 1);
362 #endif
363 
364         em.checkConsistency();
365         Config::deleteInstanceMap();
366     }
367 
368 #ifdef PARTITIONING
extentMap_range_1()369     void extentMap_range_1()
370     {
371         ExtentMap em;
372         int i, err, iterations = 1300;  // (EM_INITIAL_SIZE + 3*EM_INCREMENT)
373         int caughtException = 0, allocdSize;
374         uint32_t hwm;
375         BRM::HWM_t hwm2;
376         BRM::VER_t txnID;
377         vector<LBID_t> lbids;
378         const uint32_t extentSize = em.getExtentSize();
379 
380         for (i = 1; i < iterations; i++)
381         {
382             em.createRangeExtent(extentSize, i, lbids, allocdSize, EMRangePartition_t(0, 10, true, true));
383             em.confirmChanges();
384             CPPUNIT_ASSERT(lbids.size() == 1);
385             CPPUNIT_ASSERT((uint32_t)allocdSize == extentSize);
386             CPPUNIT_ASSERT(lbids.back() == static_cast<LBID_t>((i - 1)*extentSize));
387         }
388 
389         em.checkConsistency();
390         em.save(string("EMImage"));
391         em.load(string("EMImage"));
392         em.checkConsistency();
393 
394         LBIDRange_v lbidList;
395 
396         for (i = 1; i < iterations; i++)
397         {
398 
399             err = em.lookup(i, 1, lbidList);
400             CPPUNIT_ASSERT(lbidList.size() == 1);
401             CPPUNIT_ASSERT(err == lbidList.size());
402 
403             err = em.lookup(i, i + 10, lbidList);
404             CPPUNIT_ASSERT(lbidList.size() == 0);
405             CPPUNIT_ASSERT(err == lbidList.size());
406 
407             err = em.lookup(i * 10000, 1, lbidList);
408             CPPUNIT_ASSERT(lbidList.size() == 0);
409             CPPUNIT_ASSERT(err == lbidList.size());
410         }
411 
412         em.checkConsistency();
413 
414         err = em.lookup(i, 99, lbidList);
415         CPPUNIT_ASSERT(err == 0);
416         CPPUNIT_ASSERT(lbidList.size() == 0);
417 
418 #ifdef BRM_DEBUG
419         caughtException = 0;
420 
421         try
422         {
423             em.setHWM(i, hwm);
424         }
425         catch (std::invalid_argument e)
426         {
427             caughtException = 1;
428         }
429 
430         em.undoChanges();
431         CPPUNIT_ASSERT(caughtException == 1);
432 #endif
433 
434         for (i = 1; i < iterations; i++)
435         {
436             em.deleteOID(i);
437             em.confirmChanges();
438         }
439 
440 #ifdef BRM_DEBUG
441         caughtException = 0;
442 
443         try
444         {
445             em.deleteOID(i);
446         }
447         catch (std::invalid_argument& e)
448         {
449             caughtException = 1;
450         }
451 
452         em.undoChanges();
453         CPPUNIT_ASSERT(caughtException == 1);
454 #endif
455 
456         em.checkConsistency();
457         Config::deleteInstanceMap();
458     }
459 #endif
460 
extentMap_freelist()461     void extentMap_freelist()
462     {
463         ExtentMap em;
464         int i, allocdSize, iterations = 1400;  // (EM_INITIAL_SIZE + 4*EM_INCREMENT)
465         vector<LBID_t> lbids;
466         const int extentSize = em.getExtentSize();
467 
468 // 		cerr << "em_freelist" << endl;
469 
470         for (i = 1; i < iterations; i++)
471         {
472             em.createExtent(extentSize, i, lbids, allocdSize);
473             em.confirmChanges();
474             CPPUNIT_ASSERT(lbids.back() == static_cast<LBID_t>((i - 1)*extentSize));
475         }
476 
477         em.checkConsistency();
478 
479         //frag the lbid space to blow up the free list
480         for (i = 1; i < iterations; i += 2)
481         {
482             em.deleteOID(i);
483             em.confirmChanges();
484         }
485 
486         em.checkConsistency();
487 
488         //fill in the holes
489         for (i = 1; i < iterations; i += 2)
490         {
491             em.createExtent(extentSize, i, lbids, allocdSize);
492             em.confirmChanges();
493         }
494 
495         for (i = 1; i < iterations; i += 2)
496         {
497             em.deleteOID(i);
498             em.confirmChanges();
499         }
500 
501         for (i = 2; i < iterations; i += 2)
502         {
503             em.deleteOID(i);
504             em.confirmChanges();
505         }
506 
507         em.checkConsistency();
508         Config::deleteInstanceMap();
509     }
510 
511     /* This test verifies that the ExtentMap stops allocating space when it's full.
512     (Bug #104)	It takes a long time to run with the default LBID
513     space characteristics so by default it's disabled.*/
extentMap_overfill()514     void extentMap_overfill()
515     {
516         int i, err, tmp;
517         BlockResolutionManager brm;
518         vector<LBID_t> lbids;
519 
520         for (i = 1; i < 67109; i++)
521         {
522             err = brm.createExtent(1024000, i, lbids, tmp);
523             CPPUNIT_ASSERT(err == 0);
524         }
525 
526         err = brm.createExtent(1024000, i, lbids, tmp);
527         CPPUNIT_ASSERT(err == -1);
528 
529         for (i = 1; i < 67109; i++)
530         {
531             err = brm.deleteOID(i);
532             CPPUNIT_ASSERT(err == 0);
533         }
534 
535         err = brm.deleteOID(i);
536         CPPUNIT_ASSERT(err == -1);
537         Config::deleteInstanceMap();
538     }
539 
copyLocks_good_1()540     void copyLocks_good_1()
541     {
542         CopyLocks cl;
543         LBIDRange range;
544         int i, iterations = 1000;
545 
546 // 		cerr << "copylocks_good_1" << endl;
547 
548         cl.lock(CopyLocks::WRITE);
549         range.start = 5;
550         range.size = 2;
551         cl.lockRange(range, 0);
552         CPPUNIT_ASSERT(cl.isLocked(range) == true);
553         range.start++;
554         CPPUNIT_ASSERT(cl.isLocked(range) == true);
555         range.start++;
556         CPPUNIT_ASSERT(cl.isLocked(range) == false);
557         range.start = 0;
558         CPPUNIT_ASSERT(cl.isLocked(range) == false);
559         range.start = 3;
560         CPPUNIT_ASSERT(cl.isLocked(range) == false);
561         range.start++;
562         CPPUNIT_ASSERT(cl.isLocked(range) == true);
563         range.start = 5;
564         range.size = 1;
565         CPPUNIT_ASSERT(cl.isLocked(range) == true);
566         range.size = 2;
567         cl.releaseRange(range);
568 
569         //make sure it can grow
570         for (i = 0; i < iterations * 2; i += 2)
571         {
572             range.start = i;
573             cl.lockRange(range, 0);
574         }
575 
576         range.size = 1;
577 
578         cl.save(string("CLImage"));
579         cl.load(string("CLImage"));
580 
581         for (i = 0; i < iterations * 2; i++)
582         {
583             range.start = i;
584             CPPUNIT_ASSERT(cl.isLocked(range) == true);
585         }
586 
587         range.start = i;
588         CPPUNIT_ASSERT(cl.isLocked(range) == false);
589 
590         for (i = 0; i < iterations * 2; i += 2)
591         {
592             range.start = i;
593             cl.releaseRange(range);
594         }
595 
596         cl.release(CopyLocks::WRITE);
597         Config::deleteInstanceMap();
598     }
599 
brm_extentmap_good_1()600     void brm_extentmap_good_1()
601     {
602 
603         BlockResolutionManager brm;
604         int i, err, oid, allocdSize,
605             iterations = 1300;  // (EM_INITIAL_SIZE + 3*EM_INCREMENT)
606         uint32_t fbo, hwm;
607         vector<LBID_t> lbids;
608         HWM_t hwm2;
609         VER_t txnID;
610         const uint32_t extentSize = brm.getExtentSize();
611 
612 // 		cerr << "brm_extentmap_good_1" << endl;
613 
614         for (i = 1; i < iterations; i++)
615         {
616             brm.createExtent(extentSize, i, lbids, allocdSize);
617             CPPUNIT_ASSERT(lbids.back() == static_cast<LBID_t>((i - 1)*extentSize));
618         }
619 
620         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
621         brm.saveExtentMap(string("EMImage"));
622         brm.loadExtentMap(string("EMImage"));
623         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
624         ExtentMap em;
625 
626         //int32_t seqNum=0;
627         //int64_t max=0;
628         //int64_t min=0;
629         LBID_t lbid;
630         /*
631         		for (i = 1; i < iterations; i++) {
632         			lbid=(i-1)*extentSize;
633         			err=em.updateMaxMin(lbid, 1, 0, seqNum); // sequenceNum=0
634         			em.confirmChanges();
635         			CPPUNIT_ASSERT(err==0);
636 
637         			max=-1;
638         			min=-1;
639         			err=em.getMaxMin(lbid, max, min, seqNum);
640         			CPPUNIT_ASSERT(max==1);
641         			CPPUNIT_ASSERT(min==0);
642         			CPPUNIT_ASSERT(err==2);
643         			CPPUNIT_ASSERT(seqNum==0);
644 
645         			err=em.updateMaxMin(lbid, 4, 2, seqNum); // sequenceNum=0
646         			em.confirmChanges();
647         			CPPUNIT_ASSERT(err==0);
648 
649         			max=-1;
650         			min=-1;
651         			seqNum++;
652         			err=em.getMaxMin(lbid, max, min, seqNum);
653         			CPPUNIT_ASSERT(max==4);
654         			CPPUNIT_ASSERT(min==2);
655         			CPPUNIT_ASSERT(err==2);
656         			CPPUNIT_ASSERT(seqNum==0);
657 
658         			err=em.markInvalid(lbid); // sequenceNum=1, valid=1
659         			em.confirmChanges();
660         			CPPUNIT_ASSERT(err==0);
661 
662         			seqNum=0; // re-init seqNum
663         			err=em.getMaxMin(lbid, max, min, seqNum);
664         			CPPUNIT_ASSERT(err==1);
665         			CPPUNIT_ASSERT(seqNum==1);
666 
667         			seqNum=0;
668         		}
669         */
670 
671         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
672 
673         vector<LBID_t> lbidVector;
674         uint32_t offset;
675 
676         for (i = 1; i < iterations; i++)
677         {
678             lbid = (i - 1) * extentSize;
679 
680             for (int j = 0; (uint32_t)j < extentSize; j++)
681                 lbidVector.push_back(lbid + j);
682 
683             err = em.markInvalid(lbidVector);
684             em.confirmChanges();
685             CPPUNIT_ASSERT(err == 1);
686             lbidVector.clear();
687             em.lookup(lbid, oid, offset);
688             err = em.markInvalid(oid);
689             em.confirmChanges();
690             CPPUNIT_ASSERT(err == 0);
691             //CPPUNIT_ASSERT(oid==i);
692             oid = -1;
693             offset = 0;
694         }
695 
696         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
697 
698         for (i = 1; i < iterations; i++)
699         {
700             err = brm.lookup(static_cast<LBID_t>((i - 1) * extentSize), 0, false, oid, fbo);
701             CPPUNIT_ASSERT(err == 0);
702             CPPUNIT_ASSERT(oid == i);
703             CPPUNIT_ASSERT(fbo == 0);
704 
705             if (i != 1)
706             {
707                 err = brm.lookup(static_cast<LBID_t>((i - 1) * extentSize - 1), 0, false, oid, fbo);
708                 CPPUNIT_ASSERT(err == 0);
709                 CPPUNIT_ASSERT(oid == i - 1);
710                 CPPUNIT_ASSERT(fbo == extentSize - 1);
711             }
712 
713             if (i != iterations)
714             {
715                 err = brm.lookup(static_cast<LBID_t>((i - 1) * extentSize + 1), 0, false, oid, fbo);
716                 CPPUNIT_ASSERT(err == 0);
717                 CPPUNIT_ASSERT(oid == i);
718                 CPPUNIT_ASSERT(fbo == 1);
719             }
720         }
721 
722         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
723 
724         err = brm.lookup(static_cast<LBID_t>((i - 1) * extentSize), 0, false, oid, fbo);
725         CPPUNIT_ASSERT(err == -1);
726 
727         for (i = 1; i < iterations; i++)
728         {
729             err = brm.getBulkInsertVars(static_cast<LBID_t>((i - 1) * extentSize),
730                                         hwm2, txnID);
731             CPPUNIT_ASSERT(err == 0);
732             CPPUNIT_ASSERT(hwm2 == 0);
733             CPPUNIT_ASSERT(txnID == 0);
734             err = brm.setBulkInsertVars(static_cast<LBID_t>((i - 1) * extentSize),
735                                         i, i + 1);
736             CPPUNIT_ASSERT(err == 0);
737             err = brm.getBulkInsertVars(static_cast<LBID_t>((i - 1) * extentSize),
738                                         hwm2, txnID);
739             CPPUNIT_ASSERT(err == 0);
740             CPPUNIT_ASSERT(hwm2 == static_cast<BRM::LBID_t>(i));
741             CPPUNIT_ASSERT(txnID == static_cast<BRM::VER_t>(i + 1));
742 
743             err = brm.getHWM(i, hwm);
744             CPPUNIT_ASSERT(err == 0);
745             CPPUNIT_ASSERT(hwm == 0);
746             err = brm.setHWM(i, ((uint32_t)i > extentSize - 1 ? extentSize - 1 : i));
747             CPPUNIT_ASSERT(err == 0);
748             err = brm.getHWM(i, hwm);
749             CPPUNIT_ASSERT(err == 0);
750             CPPUNIT_ASSERT(hwm == static_cast<uint32_t>((uint32_t)i > extentSize - 1 ? extentSize - 1 : i));
751         }
752 
753         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
754 
755 #ifdef BRM_DEBUG
756         err = brm.setHWM(i, hwm);
757         CPPUNIT_ASSERT(err == -1);
758 #endif
759 
760         for (i = 1; i < iterations; i++)
761         {
762             err = brm.deleteOID(i);
763             CPPUNIT_ASSERT(err == 0);
764         }
765 
766         err = brm.deleteOID(i);
767         CPPUNIT_ASSERT(err == -1);
768 
769         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
770         Config::deleteInstanceMap();
771     }
772 
773 #ifdef PARTITIONING
brm_extentmap_range_1()774     void brm_extentmap_range_1()
775     {
776 
777         BlockResolutionManager brm;
778         int i,
779             err,
780             oid,
781             allocdSize,
782             iterations = 1300;  // (EM_INITIAL_SIZE + 3*EM_INCREMENT)
783         uint32_t fbo, hwm;
784         vector<LBID_t> lbids;
785         HWM_t hwm2;
786         VER_t txnID;
787         const uint32_t extentSize = brm.getExtentSize();
788         LBIDRange_v lbidList;
789 
790 // 		cerr << "brm_extentmap_range_1" << endl;
791 
792         for (i = 1; i < iterations; i++)
793         {
794             brm.createRangeExtent(extentSize, i, lbids, allocdSize,
795                                   EMRangePartition_t(0, 9, true, true) );
796             CPPUNIT_ASSERT(lbids.back() == static_cast<LBID_t>((i - 1)*extentSize));
797             CPPUNIT_ASSERT(lbids.size() == 1);
798         }
799 
800         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
801         brm.saveExtentMap(string("EMImage"));
802         brm.loadExtentMap(string("EMImage"));
803         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
804 
805         for (i = 1; i < iterations; i++)
806         {
807 
808             err = brm.lookup(i, 1, lbidList);
809             CPPUNIT_ASSERT(err == 0);
810             CPPUNIT_ASSERT(lbidList.size() == 1);
811 
812             err = brm.lookup(i, 10, lbidList);
813             CPPUNIT_ASSERT(err == 0);
814             CPPUNIT_ASSERT(lbidList.size() == 0);
815 
816             err = brm.lookup(i * 10000, 1, lbidList);
817             CPPUNIT_ASSERT(err == 0);
818             CPPUNIT_ASSERT(lbidList.size() == 0);
819 
820         }
821 
822         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
823 
824         err = brm.lookup(static_cast<LBID_t>((i - 1) * extentSize), 0, false, oid, fbo);
825         CPPUNIT_ASSERT(err == -1);
826 
827         for (i = 1; i < iterations; i++)
828         {
829             err = brm.getBulkInsertVars(static_cast<LBID_t>((i - 1) * extentSize),
830                                         hwm2, txnID);
831             CPPUNIT_ASSERT(err == 0);
832             CPPUNIT_ASSERT(hwm2 == 0);
833             CPPUNIT_ASSERT(txnID == 0);
834             err = brm.setBulkInsertVars(static_cast<LBID_t>((i - 1) * extentSize),
835                                         i, i + 1);
836             CPPUNIT_ASSERT(err == 0);
837             err = brm.getBulkInsertVars(static_cast<LBID_t>((i - 1) * extentSize),
838                                         hwm2, txnID);
839             CPPUNIT_ASSERT(err == 0);
840             CPPUNIT_ASSERT(hwm2 == static_cast<BRM::LBID_t>(i));
841             CPPUNIT_ASSERT(txnID == static_cast<BRM::VER_t>(i + 1));
842 
843             err = brm.getHWM(i, hwm);
844             CPPUNIT_ASSERT(err == 0);
845             CPPUNIT_ASSERT(hwm == 0);
846             err = brm.setHWM(i, (i > extentSize - 1 ? extentSize - 1 : i));
847             CPPUNIT_ASSERT(err == 0);
848             err = brm.getHWM(i, hwm);
849             CPPUNIT_ASSERT(err == 0);
850             CPPUNIT_ASSERT(hwm == static_cast<uint32_t>(i > extentSize - 1 ? extentSize - 1 : i));
851         }
852 
853         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
854 
855 #ifdef BRM_DEBUG
856         err = brm.setHWM(i, hwm);
857         CPPUNIT_ASSERT(err == -1);
858 #endif
859 
860         for (i = 1; i < iterations; i++)
861         {
862             err = brm.deleteOID(i);
863             CPPUNIT_ASSERT(err == 0);
864         }
865 
866         err = brm.deleteOID(i);
867         CPPUNIT_ASSERT(err == -1);
868         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
869         Config::deleteInstanceMap();
870     }
871 #endif
872 
brm_good_2()873     void brm_good_2()
874     {
875         BlockResolutionManager brm;
876         VBBM vbbm;
877         VSS vss;
878         CopyLocks cl;
879         int i, err, size;
880         vector<LBID_t> lbids;
881         vector<EMEntry> extents;
882         LBIDRange_v ranges;
883         LBIDRange_v::iterator lbidRangeIT;
884         vector<VBRange> vbRanges, vbRanges2;
885         vector<VBRange>::iterator vbRangesIT;
886         EMEntry em;
887         OID_t oid;
888         uint32_t fbo;
889         LBIDRange range;
890         VBRange vbRange;
891         VER_t verID;
892         bool vbFlag;
893 
894         // Buildbot times out on the getBlocks() call during leakcheck b/c it takes
895         // > 5 mins for some reason.  Have to ping it before 300 seconds go by.
896         void (*oldsig)(int);
897 
898 // 		cerr << "brm_good_2" << endl;
899 
900         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
901 
902         oldsig = signal(SIGALRM, keepalive);
903         alarm(290);
904 
905         err = brm.lookup(0, 0, false, oid, fbo);
906         CPPUNIT_ASSERT(err == -1);
907         err = brm.lookup(0, 0, true, oid, fbo);
908         CPPUNIT_ASSERT(err == -1);
909 
910         err = brm.createExtent(8000, 1, lbids, size);
911         CPPUNIT_ASSERT(err == 0);
912         CPPUNIT_ASSERT(size == brm.getExtentSize());
913         CPPUNIT_ASSERT(lbids.size() == 1);
914 //  		CPPUNIT_ASSERT(*(lbids.begin()) == 0);
915 
916         err = brm.getExtents(1, extents);
917         CPPUNIT_ASSERT(err == 0);
918         CPPUNIT_ASSERT(extents.size() == 1);
919 
920         em = *(extents.begin());
921 // 		CPPUNIT_ASSERT(em.range.start == 0);
922         CPPUNIT_ASSERT(em.range.size * 1024 == static_cast<uint32_t>(brm.getExtentSize()));
923         CPPUNIT_ASSERT(em.HWM == 0);
924         CPPUNIT_ASSERT(em.blockOffset == 0);
925 
926         for (i = 0; i < 50; i++)
927         {
928             range.start = i * 100;
929             range.size = 100;
930             ranges.push_back(range);
931         }
932 
933         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
934 
935         err = brm.beginVBCopy(1, ranges, vbRanges);
936         CPPUNIT_ASSERT(err == 0);
937 
938         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
939 
940         cl.lock(CopyLocks::READ);
941 
942         for (lbidRangeIT = ranges.begin(); lbidRangeIT != ranges.end();
943                 lbidRangeIT++)
944             CPPUNIT_ASSERT(cl.isLocked(*lbidRangeIT));
945 
946         cl.release(CopyLocks::READ);
947 
948         err = brm.beginVBCopy(1, ranges, vbRanges2);
949         CPPUNIT_ASSERT(err == -1);
950 
951         cl.lock(CopyLocks::READ);
952 
953         for (lbidRangeIT = ranges.begin(); lbidRangeIT != ranges.end();
954                 lbidRangeIT++)
955             CPPUNIT_ASSERT(cl.isLocked(*lbidRangeIT));
956 
957         cl.release(CopyLocks::READ);
958 
959         for (i = 0; i < 5000; i++)
960         {
961             verID = MAXINT;
962             err = brm.vssLookup(i, verID, 1, vbFlag);
963             CPPUNIT_ASSERT(err == -1);
964         }
965 
966         vbRange = *(vbRanges.begin());
967 
968 // 		CPPUNIT_ASSERT(vbRange.vbFBO == 0);
969         for (i = 0; i < (int)vbRange.size; i++)
970         {
971             err = brm.writeVBEntry(1, i, vbRange.vbOID, vbRange.vbFBO + i);
972             CPPUNIT_ASSERT(err == 0);
973         }
974 
975         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
976 
977         for (i = 0; i < (int)vbRange.size; i++)
978         {
979             verID = MAXINT;
980             err = brm.vssLookup(i, verID, 1, vbFlag);
981             CPPUNIT_ASSERT(err == 0);
982             CPPUNIT_ASSERT(verID == 1);
983             CPPUNIT_ASSERT(vbFlag == false);
984             verID = MAXINT;
985             err = brm.vssLookup(i, verID, 0, vbFlag);
986             CPPUNIT_ASSERT(err == 0);
987             CPPUNIT_ASSERT(verID == 0);
988             CPPUNIT_ASSERT(vbFlag == true);
989         }
990 
991         for (; i < 5000; i++)
992         {
993             verID = MAXINT;
994             err = brm.vssLookup(i, verID, 1, vbFlag);
995             CPPUNIT_ASSERT(err == -1);
996         }
997 
998         err = brm.endVBCopy(0, ranges);
999 
1000         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
1001 
1002         cl.lock(CopyLocks::READ);
1003 
1004         for (lbidRangeIT = ranges.begin(); lbidRangeIT != ranges.end();
1005                 lbidRangeIT++)
1006             CPPUNIT_ASSERT(!cl.isLocked(*lbidRangeIT));
1007 
1008         cl.release(CopyLocks::READ);
1009 
1010         brm.saveState("TestImage");
1011         brm.loadState("TestImage");
1012 
1013         brm.vbCommit(1);
1014 
1015         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
1016 
1017         for (i = 0; i < (int)vbRange.size; i++)
1018         {
1019             verID = MAXINT;
1020             err = brm.vssLookup(i, verID, 0, vbFlag);
1021             CPPUNIT_ASSERT(err == 0);
1022             CPPUNIT_ASSERT(verID == 1);
1023             CPPUNIT_ASSERT(vbFlag == false);
1024 
1025             verID = 0;
1026             err = brm.vssLookup(i, verID, 0, vbFlag);
1027             CPPUNIT_ASSERT(err == 0);
1028             CPPUNIT_ASSERT(verID == 0);
1029             CPPUNIT_ASSERT(vbFlag == true);
1030 
1031             err = brm.lookup(i, verID, vbFlag, oid, fbo);
1032             CPPUNIT_ASSERT(err == 0);
1033             CPPUNIT_ASSERT(oid == vbRange.vbOID);
1034             CPPUNIT_ASSERT(fbo == static_cast<uint32_t>(i + vbRange.vbFBO));
1035 
1036             vbbm.lock(VBBM::WRITE);
1037             vss.lock(VSS::WRITE);
1038             vbbm.removeEntry(i, verID);
1039 // 			vss.removeEntry(i, 1);
1040             vss.removeEntry(i, verID);
1041             vbbm.confirmChanges();
1042             vss.confirmChanges();
1043             vss.release(VSS::WRITE);
1044             vbbm.release(VBBM::WRITE);
1045         }
1046 
1047         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
1048 
1049         brm.deleteOID(1);
1050 
1051         vss.lock(VSS::READ);
1052         vbbm.lock(VBBM::READ);
1053         CPPUNIT_ASSERT(vbbm.size() == 0);
1054         CPPUNIT_ASSERT(vbbm.hashEmpty());
1055         CPPUNIT_ASSERT(vss.size() == 0);
1056         CPPUNIT_ASSERT(vss.hashEmpty());
1057         vss.release(VSS::READ);
1058         vbbm.release(VBBM::READ);
1059 
1060         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
1061         Config::deleteInstanceMap();
1062     }
1063 
1064     // cut & pasted from brm_good_2(), but with rollback instead of commit.
brm_good_3()1065     void brm_good_3()
1066     {
1067         BlockResolutionManager brm;
1068         VBBM vbbm;
1069         VSS vss;
1070         CopyLocks cl;
1071         int i, err, size;
1072         vector<LBID_t> lbids;
1073         vector<LBID_t>::iterator lbid;
1074         vector<EMEntry> extents;
1075         LBIDRange_v ranges;
1076         LBIDRange_v::iterator lbidRangeIT;
1077         VBRange_v vbRanges, vbRanges2;
1078         VBRange_v::iterator vbRangesIT;
1079         LBIDRange_v tmp;
1080         EMEntry em;
1081         OID_t oid;
1082         uint32_t fbo;
1083         LBIDRange range;
1084         VBRange vbRange;
1085         VER_t verID;
1086         bool vbFlag;
1087         bool caughtException;
1088 
1089         // Buildbot times out on the getBlocks() call during leakcheck b/c it takes
1090         // > 5 mins for some reason.  Have to ping it before 300 seconds go by.
1091         void (*oldsig)(int);
1092 
1093 // 		cerr << "brm_good_3" << endl;
1094 
1095         oldsig = signal(SIGALRM, keepalive);
1096         alarm(290);
1097 
1098         err = brm.lookup(0, 0, false, oid, fbo);
1099         CPPUNIT_ASSERT(err == -1);
1100         err = brm.lookup(0, 0, true, oid, fbo);
1101         CPPUNIT_ASSERT(err == -1);
1102 
1103         err = brm.createExtent(8000, 1, lbids, size);
1104         CPPUNIT_ASSERT(err == 0);
1105         CPPUNIT_ASSERT(size == brm.getExtentSize());
1106         CPPUNIT_ASSERT(lbids.size() == 1);
1107         CPPUNIT_ASSERT(*(lbids.begin()) == 0);
1108 
1109         err = brm.getExtents(1, extents);
1110         CPPUNIT_ASSERT(err == 0);
1111         CPPUNIT_ASSERT(extents.size() == 1);
1112 
1113         em = *(extents.begin());
1114         CPPUNIT_ASSERT(em.range.start == 0);
1115         CPPUNIT_ASSERT(em.range.size * 1024 == static_cast<uint32_t>(brm.getExtentSize()));
1116         CPPUNIT_ASSERT(em.HWM == 0);
1117         CPPUNIT_ASSERT(em.blockOffset == 0);
1118 
1119         for (i = 0; i < 50; i++)
1120         {
1121             range.start = i * 100;
1122             range.size = 100;
1123             ranges.push_back(range);
1124         }
1125 
1126         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
1127 
1128         err = brm.beginVBCopy(1, ranges, vbRanges);
1129         CPPUNIT_ASSERT(err == 0);
1130 
1131         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
1132 
1133         cl.lock(CopyLocks::READ);
1134 
1135         for (lbidRangeIT = ranges.begin(); lbidRangeIT != ranges.end();
1136                 lbidRangeIT++)
1137             CPPUNIT_ASSERT(cl.isLocked(*lbidRangeIT));
1138 
1139         cl.release(CopyLocks::READ);
1140 
1141         err = brm.beginVBCopy(1, ranges, vbRanges2);
1142         CPPUNIT_ASSERT(err == -1);
1143 
1144         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
1145 
1146         cl.lock(CopyLocks::READ);
1147 
1148         for (lbidRangeIT = ranges.begin(); lbidRangeIT != ranges.end();
1149                 lbidRangeIT++)
1150             CPPUNIT_ASSERT(cl.isLocked(*lbidRangeIT));
1151 
1152         cl.release(CopyLocks::READ);
1153 
1154         for (i = 0; i < 5000; i++)
1155         {
1156             verID = MAXINT;
1157             err = brm.vssLookup(i, verID, 1, vbFlag);
1158             CPPUNIT_ASSERT(err == -1);
1159         }
1160 
1161         vbRange = *(vbRanges.begin());
1162 
1163 // 		CPPUNIT_ASSERT(vbRange.vbFBO == 0);
1164         for (i = 0; i < (int)vbRange.size; i++)
1165         {
1166             err = brm.writeVBEntry(1, i, vbRange.vbOID, vbRange.vbFBO + i);
1167             CPPUNIT_ASSERT(err == 0);
1168         }
1169 
1170         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
1171 
1172         for (i = 0; i < (int)vbRange.size; i++)
1173         {
1174             verID = MAXINT;
1175             err = brm.vssLookup(i, verID, 1, vbFlag);
1176             CPPUNIT_ASSERT(err == 0);
1177             CPPUNIT_ASSERT(verID == 1);
1178             CPPUNIT_ASSERT(vbFlag == false);
1179             verID = MAXINT;
1180             err = brm.vssLookup(i, verID, 0, vbFlag);
1181             CPPUNIT_ASSERT(err == 0);
1182             CPPUNIT_ASSERT(verID == 0);
1183             CPPUNIT_ASSERT(vbFlag == true);
1184         }
1185 
1186         for (; i < 5000; i++)
1187         {
1188             verID = MAXINT;
1189             err = brm.vssLookup(i, verID, 1, vbFlag);
1190             CPPUNIT_ASSERT(err == -1);
1191         }
1192 
1193         err = brm.endVBCopy(0, ranges);
1194 
1195         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
1196 
1197         cl.lock(CopyLocks::READ);
1198 
1199         for (lbidRangeIT = ranges.begin(); lbidRangeIT != ranges.end();
1200                 lbidRangeIT++)
1201             CPPUNIT_ASSERT(!cl.isLocked(*lbidRangeIT));
1202 
1203         cl.release(CopyLocks::READ);
1204 
1205         err = brm.getUncommittedLBIDs(1, lbids);
1206         CPPUNIT_ASSERT(err == 0);
1207         CPPUNIT_ASSERT(lbids.size() == vbRange.size);
1208         sort<vector<LBID_t>::iterator>(lbids.begin(), lbids.end());
1209         lbid = lbids.begin();
1210 
1211         for (i = 0; i < static_cast<int>(lbids.size()); i++, lbid++)
1212             CPPUNIT_ASSERT((*lbid) == static_cast<LBID_t>(i));
1213 
1214         range.start = 0;
1215         range.size = i;
1216         tmp.push_back(range);
1217         err = brm.vbRollback(1, tmp);
1218         CPPUNIT_ASSERT(err == 0);
1219 
1220         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
1221 
1222         for (i = 0; i < (int)vbRange.size; i++)
1223         {
1224             verID = MAXINT;
1225 
1226             err = brm.vssLookup(i, verID, 0, vbFlag);
1227             CPPUNIT_ASSERT(err == 0);
1228             CPPUNIT_ASSERT(verID == 0);
1229             CPPUNIT_ASSERT(vbFlag == false);
1230 
1231             err = brm.lookup(i, verID, vbFlag, oid, fbo);
1232             CPPUNIT_ASSERT(err == 0);
1233             CPPUNIT_ASSERT(oid == 1);
1234             CPPUNIT_ASSERT(fbo == static_cast<uint32_t>(i));
1235 
1236             vbbm.lock(VBBM::WRITE);
1237             vss.lock(VSS::WRITE);
1238 
1239 #ifdef BRM_DEBUG
1240             caughtException = false;
1241 
1242             try
1243             {
1244                 vbbm.removeEntry(i, verID);
1245                 vbbm.confirmChanges();
1246             }
1247             catch (logic_error& e)
1248             {
1249                 vbbm.undoChanges();
1250                 caughtException = true;
1251             }
1252 
1253             CPPUNIT_ASSERT(caughtException);
1254             caughtException = false;
1255 
1256             try
1257             {
1258                 vss.removeEntry(i, 1);
1259                 vss.confirmChanges();
1260             }
1261             catch (logic_error& e)
1262             {
1263                 vss.undoChanges();
1264                 caughtException = true;
1265             }
1266 
1267             CPPUNIT_ASSERT(caughtException);
1268 #endif
1269 
1270             vss.removeEntry(i, verID);
1271             vss.confirmChanges();
1272             vss.release(VSS::WRITE);
1273             vbbm.release(VBBM::WRITE);
1274         }
1275 
1276         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
1277 
1278         brm.deleteOID(1);
1279 
1280         vbbm.lock(VBBM::READ);
1281         vss.lock(VSS::READ);
1282         CPPUNIT_ASSERT(vbbm.size() == 0);
1283         CPPUNIT_ASSERT(vbbm.hashEmpty());
1284         CPPUNIT_ASSERT(vss.size() == 0);
1285         CPPUNIT_ASSERT(vss.hashEmpty());
1286         vss.release(VSS::READ);
1287         vbbm.release(VBBM::READ);
1288 
1289         CPPUNIT_ASSERT(brm.checkConsistency() == 0);
1290         Config::deleteInstanceMap();
1291     }
1292 
1293     /* This test verifies that deleteOID returns an error for
1294     non-existant OIDs (bug #105) */
brm_deleteOID()1295     void brm_deleteOID()
1296     {
1297         BlockResolutionManager brm;
1298         int err;
1299         vector<EMEntry> extents;
1300 
1301 // 		cerr << "brm_deleteOID" << endl;
1302 
1303         err = brm.getExtents(1, extents);
1304 #ifdef BRM_DEBUG
1305 
1306         if (err != -1)
1307             cerr << "Make sure OID 1 isn't allocated in the extent map" << endl;
1308 
1309         CPPUNIT_ASSERT(err == -1);
1310 #else
1311         CPPUNIT_ASSERT(err == 0);
1312         CPPUNIT_ASSERT(extents.empty());
1313 #endif
1314         err = brm.deleteOID(1);
1315         CPPUNIT_ASSERT(err == -1);
1316         Config::deleteInstanceMap();
1317     }
1318 
1319     /* This test verifies that setHWM and getHWM return an error for
1320     nonexistant OIDs (bugs #106, 107) */
1321 
brm_HWM()1322     void brm_HWM()
1323     {
1324         BlockResolutionManager brm;
1325         int err;
1326         HWM_t hwm;
1327         vector<EMEntry> extents;
1328 
1329 // 		cerr << "brm_HWM" << endl;
1330 
1331         err = brm.getExtents(1, extents);
1332 #ifdef BRM_DEBUG
1333 
1334         if (err != -1)
1335             cerr << "Make sure OID 1 isn't allocated in the extent map" << endl;
1336 
1337         CPPUNIT_ASSERT(err == -1);
1338 #else
1339         CPPUNIT_ASSERT(err == 0);
1340 #endif
1341         CPPUNIT_ASSERT(extents.size() == 0);
1342         err = brm.setHWM(1, 10);
1343         CPPUNIT_ASSERT(err == -1);
1344         err = brm.getHWM(1, hwm);
1345         CPPUNIT_ASSERT(err == -1);
1346         Config::deleteInstanceMap();
1347     }
1348 
vbbm_good_1()1349     void vbbm_good_1()
1350     {
1351 
1352         // add some VBBM entries
1353         // do some lookups
1354         // manipulate them
1355         // do more lookups
1356 
1357         VBBM vbbm;
1358         VSS vss;
1359         vector<VBRange> ranges;
1360         vector<VBRange>::iterator it;
1361         int i, iterations = 100010, err;
1362         OID_t oid;
1363         uint32_t fbo, fbo2;
1364 
1365         // Buildbot times out on the getBlocks() call during leakcheck b/c it takes
1366         // > 5 mins for some reason.  Have to ping it before 300 seconds go by.
1367         void (*oldsig)(int);
1368 
1369 // 		cerr << "vbbm_good_1" << endl;
1370 
1371         oldsig = signal(SIGALRM, keepalive);
1372         alarm(290);
1373 
1374 //  		cerr << "\nVBBM test (this can take awhile)\n";
1375         vbbm.lock(VBBM::READ);
1376         vbbm.release(VBBM::READ);
1377         vbbm.lock(VBBM::WRITE);
1378         vbbm.release(VBBM::WRITE);
1379 
1380         vbbm.lock(VBBM::WRITE);
1381 
1382         err = vbbm.lookup(0, 0, oid, fbo);
1383         CPPUNIT_ASSERT(err == -1);
1384 
1385 //  		cerr << "step 1/4: get some VB blocks" << endl;
1386 
1387         vss.lock(VSS::WRITE);
1388         vbbm.getBlocks(iterations, ranges, vss);
1389         vbbm.confirmChanges();
1390         vss.confirmChanges();
1391         vss.release(VSS::WRITE);
1392         CPPUNIT_ASSERT(!ranges.empty());
1393 
1394 //   		cerr << "step 2/4: inserts & lookups" << endl;
1395         for (it = ranges.begin(), i = 0; it != ranges.end(); it++)
1396         {
1397             for (fbo = (*it).vbFBO; fbo < (*it).vbFBO + (*it).size; fbo++, i++)
1398             {
1399                 vbbm.insert(i, i + 1, (*it).vbOID, fbo);
1400                 vbbm.confirmChanges();
1401                 err = vbbm.lookup(i, i + 1, oid, fbo2);
1402                 CPPUNIT_ASSERT(err == 0);
1403                 CPPUNIT_ASSERT(oid == (*it).vbOID);
1404                 CPPUNIT_ASSERT(fbo2 == fbo);
1405             }
1406         }
1407 
1408         /*
1409         	for (i = 0; i < iterations; i++) {
1410 
1411         	vbbm.insert(i, i+1, i+2, i+3);
1412         	err = vbbm.lookup(i, i+1, oid, fbo);
1413         	CPPUNIT_ASSERT(err == 0);
1414         	CPPUNIT_ASSERT(oid == i + 2);
1415         	CPPUNIT_ASSERT(fbo == static_cast<uint32_t>(i + 3));
1416         }
1417         */
1418 
1419         vbbm.save(string("VBBMImage"));
1420         vbbm.load(string("VBBMImage"));
1421 
1422 //   		cerr << "step 3/4: lookups" << endl;
1423         for (it = ranges.begin(), i = 0; it != ranges.end(); it++)
1424         {
1425             for (fbo = (*it).vbFBO; fbo < (*it).vbFBO + (*it).size; fbo++, i++)
1426             {
1427                 err = vbbm.lookup(i, i + 1, oid, fbo2);
1428                 CPPUNIT_ASSERT(err == 0);
1429                 CPPUNIT_ASSERT(oid == (*it).vbOID);
1430                 CPPUNIT_ASSERT(fbo2 == fbo);
1431             }
1432         }
1433 
1434         /*
1435         for (i = 0; i < iterations; i++) {
1436         	err = vbbm.lookup(i, i+1, oid, fbo);
1437         	CPPUNIT_ASSERT(err == 0);
1438         	CPPUNIT_ASSERT(oid == i + 2);
1439         	CPPUNIT_ASSERT(fbo == static_cast<uint32_t>(i + 3));
1440         } */
1441 
1442 //   		cerr << "step 4/4: remove all entries" << endl;
1443         for (i = 0; i < iterations; i++)
1444         {
1445             vbbm.removeEntry(i, i + 1);
1446             vbbm.confirmChanges();
1447         }
1448 
1449         CPPUNIT_ASSERT(vbbm.size() == 0);
1450         CPPUNIT_ASSERT(vbbm.hashEmpty());
1451 
1452         vbbm.release(VBBM::WRITE);
1453         Config::deleteInstanceMap();
1454     }
1455 
vss_good_1()1456     void vss_good_1()
1457     {
1458         VSS vss;
1459         VBBM vbbm;
1460         ExtentMap em;
1461         int i, err, iterations = 100010;
1462         VER_t verID;
1463         bool vbFlag;
1464         vector<LBID_t> lbids;
1465         LBIDRange range;
1466 
1467         // Buildbot times out on the getBlocks() call during leakcheck b/c it takes
1468         // > 5 mins for some reason.  Have to ping it before 300 seconds go by.
1469         void (*oldsig)(int);
1470 
1471 // 		cerr << "vss_good_1" << endl;
1472 
1473         oldsig = signal(SIGALRM, keepalive);
1474         alarm(290);
1475 
1476         cerr << endl << "VSS test (this can take awhile)" << endl;
1477 
1478         vss.lock(VSS::READ);
1479         vss.release(VSS::READ);
1480 
1481         vss.lock(VSS::WRITE);
1482 
1483         cerr << "step 1/5: insert 2 entries for 100010 LBIDs & test lookup logic" << endl;
1484 
1485         range.start = 0;
1486         range.size = 200000;
1487 
1488         CPPUNIT_ASSERT(!vss.isLocked(range));
1489 
1490         for (i = 0; i < iterations; i++)
1491         {
1492             vss.insert(i, i + 1, (i % 2 ? true : false), (i % 2 ? false : true));
1493             vss.insert(i, i, true, false);
1494             vss.confirmChanges();
1495 
1496             if (i == 0)
1497             {
1498                 range.start = 0;
1499                 range.size = 1;
1500                 CPPUNIT_ASSERT(vss.isLocked(range));
1501             }
1502             else if (i == 1)
1503             {
1504                 range.start = 1;
1505                 CPPUNIT_ASSERT(!vss.isLocked(range));
1506             }
1507 
1508             verID = i + 10;
1509             err = vss.lookup(i, verID, i + 1, vbFlag);
1510             CPPUNIT_ASSERT(err == 0);
1511             CPPUNIT_ASSERT(verID == i + 1);
1512             CPPUNIT_ASSERT((vbFlag && (i % 2)) || (!vbFlag && !(i % 2)));
1513             verID = i + 10;
1514             err = vss.lookup(i, verID, 0, vbFlag);
1515             CPPUNIT_ASSERT(err == 0);
1516             CPPUNIT_ASSERT(verID == (i % 2 ? i + 1 : i));
1517             CPPUNIT_ASSERT(vbFlag == true);
1518 
1519             if (i > 0)
1520             {
1521                 verID = i - 1;
1522                 err = vss.lookup(i, verID, 0, vbFlag);
1523                 CPPUNIT_ASSERT(err == -1);
1524             }
1525 
1526         }
1527 
1528         range.start = 0;
1529         range.size = 200000;
1530         CPPUNIT_ASSERT(vss.isLocked(range));
1531         vss.save(string("VSSImage"));
1532         vss.load(string("VSSImage"));
1533 
1534         // this loop actually breaks the locked -> !vbFlag invariant
1535         // switch it back afterward
1536         cerr << "step 2/5: flip the vbFlag on half of the entries & test lookup logic" << endl;
1537 
1538         for (i = 0; i < iterations; i++)
1539         {
1540             vss.setVBFlag(i, i + 1, (i % 2 ? false : true));
1541             vss.confirmChanges();
1542         }
1543 
1544         for (i = 0; i < iterations; i++)
1545         {
1546             verID = i + 10;
1547             err = vss.lookup(i, verID, i + 1, vbFlag);
1548             CPPUNIT_ASSERT(err == 0);
1549             CPPUNIT_ASSERT(verID == i + 1);
1550             CPPUNIT_ASSERT((!vbFlag && (i % 2)) || (vbFlag && !(i % 2)));
1551         }
1552 
1553         cerr << "step 3/5: some clean up" << endl;
1554 
1555         for (i = 0; i < iterations; i++)
1556         {
1557             vss.setVBFlag(i, i + 1, (i % 2 ? true : false));
1558             vss.confirmChanges();
1559         }
1560 
1561 
1562         // there are 2 entries for every txnid at this point, one
1563         // which is locked, one which isn't.  That's technically a violation,
1564         // so we have to get rid of the unlocked ones for the next test.
1565         for (i = 0; i < iterations; i++)
1566         {
1567             vss.removeEntry(i, i);
1568             vss.confirmChanges();
1569         }
1570 
1571         //speed up the next step!
1572         for (i = iterations / 50; i < iterations; i++)
1573         {
1574             vss.removeEntry(i, i + 1);
1575             vss.confirmChanges();
1576         }
1577 
1578         cerr << "step 4/5: get \'uncommitted\' LBIDs, commit, and test lookup logic" << endl;
1579 
1580         for (i = 1; i < iterations / 50; i++)
1581         {
1582             bool ex = false;
1583 
1584             if (i % 2 == 0)
1585             {
1586 #ifdef BRM_DEBUG
1587 
1588                 try
1589                 {
1590                     vss.getUncommittedLBIDs(i, lbids);
1591                 }
1592                 catch (logic_error& e)
1593                 {
1594                     ex = true;
1595                 }
1596 
1597                 CPPUNIT_ASSERT(ex == true);
1598 #endif
1599             }
1600             else
1601             {
1602                 LBID_t lbid;
1603 
1604                 vss.getUncommittedLBIDs(i, lbids);
1605                 CPPUNIT_ASSERT(lbids.size() == 1);
1606                 lbid = *(lbids.begin());
1607                 CPPUNIT_ASSERT(lbid == i - 1);
1608                 verID = i + 10;
1609                 err = vss.lookup(i - 1, verID, i, vbFlag);
1610                 CPPUNIT_ASSERT(err == 0);
1611                 CPPUNIT_ASSERT(verID == i);
1612                 CPPUNIT_ASSERT(vbFlag == false);
1613 
1614                 err = vss.lookup(i - 1, verID, 0, vbFlag);
1615                 CPPUNIT_ASSERT(err == -1);
1616 
1617                 vss.commit(i);
1618                 vss.confirmChanges();
1619                 verID = i + 10;
1620                 err = vss.lookup(i - 1, verID, 0, vbFlag);
1621                 CPPUNIT_ASSERT(err == 0);
1622                 CPPUNIT_ASSERT(verID == i);
1623                 CPPUNIT_ASSERT(vbFlag == false);
1624 
1625             }
1626         }
1627 
1628         cerr << "step 5/5: final clean up" << endl;
1629 
1630         CPPUNIT_ASSERT(vss.size() == iterations / 50);
1631         range.start = 0;
1632         range.size = iterations / 50;
1633         vss.removeEntriesFromDB(range, vbbm, false);
1634         vbbm.confirmChanges();
1635         vss.confirmChanges();
1636 
1637         // the new logic for removeEntriesFromDB deletes all entries in the range,
1638         // locked or not, in the VB or not
1639 
1640 // 		CPPUNIT_ASSERT(vss.size() == iterations/100);
1641 
1642 //  		for (i = 1; i < iterations/50; i+=2)
1643 //  			vss.removeEntry(i, i+1);
1644 
1645         CPPUNIT_ASSERT(vss.size() == 0);
1646         CPPUNIT_ASSERT(vss.hashEmpty());
1647         vss.release(VSS::WRITE);
1648 
1649         alarm(0);
1650         signal(SIGALRM, oldsig);
1651         Config::deleteInstanceMap();
1652     }
1653 
1654     /* This test was suggested by Jean, who observed some odd behavior at around
1655     1032 EM instances in her code.  This test creates 2000 instances and uses 1400 of them
1656     to do the extentmap_freelist_1 test above. */
many_ExtentMap_instances()1657     void many_ExtentMap_instances()
1658     {
1659         ExtentMap** ems;
1660         int i, allocdSize, iterations = 1400;  // (EM_INITIAL_SIZE + 4*EM_INCREMENT)
1661         vector<LBID_t> lbids;
1662         uint32_t extentSize;
1663 
1664 //  		cerr << endl << "Extent Map instance test" << endl;
1665 
1666         ems = new ExtentMap*[2000];
1667 
1668         for (i = 0; i < 2000; i++)
1669             ems[i] = new ExtentMap();
1670 
1671         extentSize = ems[0]->getExtentSize();
1672 
1673 // 		cerr << "  - Successfully created 2000 instances, starting the freelist test"
1674 // 				<< endl;
1675         for (i = 1; i < iterations; i++)
1676         {
1677             ems[i]->createExtent(extentSize, i, lbids, allocdSize);
1678             ems[i]->confirmChanges();
1679             CPPUNIT_ASSERT(lbids.back() == static_cast<LBID_t>((i - 1)*extentSize));
1680         }
1681 
1682         //frag the lbid space to blow up the free list
1683         for (i = 1; i < iterations; i += 2)
1684         {
1685             ems[i]->deleteOID(i);
1686             ems[i]->confirmChanges();
1687         }
1688 
1689         //fill in the holes
1690         for (i = 1; i < iterations; i += 2)
1691         {
1692             ems[i]->createExtent(extentSize, i, lbids, allocdSize);
1693             ems[i]->confirmChanges();
1694         }
1695 
1696         for (i = 1; i < iterations; i += 2)
1697         {
1698             ems[i]->deleteOID(i);
1699             ems[i]->confirmChanges();
1700         }
1701 
1702         for (i = 2; i < iterations; i += 2)
1703         {
1704             ems[i]->deleteOID(i);
1705             ems[i]->confirmChanges();
1706         }
1707 
1708 // 		cerr << "done.  sleeping for 30 seconds." << endl;
1709 // 		sleep(30);
1710 
1711         for (i = 0; i < 2000; i++)
1712             delete ems[i];
1713 
1714         delete [] ems;
1715         Config::deleteInstanceMap();
1716 
1717     }
1718 
resource_graph_1()1719     void resource_graph_1()
1720     {
1721         LBIDResourceGraph rg;
1722         pthread_t t;
1723         VER_t txn = 1;
1724         int err;
1725 
1726         pthread_mutex_init(&mutex, NULL);
1727         pthread_mutex_lock(&mutex);
1728 
1729         err = rg.reserveRange(1001, 2000, txn, mutex);
1730         CPPUNIT_ASSERT(err == 0);
1731         err = rg.reserveRange(2001, 2000, txn, mutex);
1732         CPPUNIT_ASSERT(err == 0);
1733         err = rg.reserveRange(0, 1000, txn, mutex);
1734         CPPUNIT_ASSERT(err == 0);
1735         err = rg.reserveRange(3001, 2000, txn, mutex);
1736         CPPUNIT_ASSERT(err == 0);
1737         pthread_create(&t, NULL, dummy_1, &rg);
1738         pthread_mutex_unlock(&mutex);
1739         sleep(5);
1740 
1741         // thread should sleep here
1742 
1743         pthread_mutex_lock(&mutex);
1744         rg.releaseResources(txn);
1745         pthread_mutex_unlock(&mutex);
1746 
1747         // thread should be unblocked and finish here
1748 
1749         pthread_join(t, NULL);
1750         pthread_mutex_lock(&mutex);
1751         err = rg.reserveRange(0, 1000, txn, mutex);
1752         CPPUNIT_ASSERT(err == 0);
1753         rg.releaseResources(txn);
1754         pthread_mutex_unlock(&mutex);
1755         pthread_mutex_destroy(&mutex);
1756         Config::deleteInstanceMap();
1757     }
1758 
resource_graph_deadlock()1759     void resource_graph_deadlock()
1760     {
1761         LBIDResourceGraph rg;
1762         pthread_t t;
1763         VER_t txn = 1;
1764         int err;
1765 
1766         pthread_mutex_init(&mutex, NULL);
1767         pthread_mutex_lock(&mutex);
1768         err = rg.reserveRange(0, 1000, txn, mutex);
1769         CPPUNIT_ASSERT(err == 0);
1770         pthread_create(&t, NULL, dummy_deadlock, &rg);
1771         pthread_mutex_unlock(&mutex);
1772         sleep(1);
1773 
1774         // thread grabs 1001-2000, then 0-1000 and blocks
1775 
1776         pthread_mutex_lock(&mutex);
1777         err = rg.reserveRange(1001, 2000, txn, mutex);  // deadlock
1778         CPPUNIT_ASSERT(err == ERR_DEADLOCK);
1779         rg.releaseResources(txn);
1780 
1781         pthread_mutex_unlock(&mutex);  // should wake the thread
1782         pthread_join(t, NULL);		// wait for it to finish
1783 
1784         pthread_mutex_lock(&mutex);
1785         err = rg.reserveRange(0, 2000, txn, mutex);  //verify we can now grab both ranges
1786         CPPUNIT_ASSERT(err == ERR_OK);
1787         pthread_mutex_unlock(&mutex);
1788         pthread_mutex_destroy(&mutex);
1789         Config::deleteInstanceMap();
1790     }
1791 
resource_graph_fragd_range()1792     void resource_graph_fragd_range()
1793     {
1794         LBIDResourceGraph rg;
1795         set<ResourceNode*, RNLess<ResourceNode*> >* resources;
1796         map<VER_t, TransactionNode*>* txns;
1797         pthread_t t;
1798         VER_t txn = 1;
1799         int err;
1800 
1801         pthread_mutex_init(&mutex, NULL);
1802         pthread_mutex_lock(&mutex);
1803 
1804         err = rg.reserveRange(1001, 2000, txn, mutex);
1805         CPPUNIT_ASSERT(err == ERR_OK);
1806         err = rg.reserveRange(3001, 4000, txn, mutex);
1807         CPPUNIT_ASSERT(err == ERR_OK);
1808         pthread_create(&t, NULL, fragd_range_helper, &rg);
1809         pthread_mutex_unlock(&mutex);
1810         sleep(1);
1811 
1812         // thread wakes, tries to grab 0-5000
1813         // check that there are 5 resource nodes
1814 
1815         pthread_mutex_lock(&mutex);
1816         resources = rg.getResources();
1817         txns = rg.getTxns();
1818         CPPUNIT_ASSERT(resources->size() == 5);
1819         CPPUNIT_ASSERT(txns->size() == 2);
1820         rg.releaseResources(txn);
1821         CPPUNIT_ASSERT(resources->size() == 3);
1822         CPPUNIT_ASSERT(txns->size() == 1);
1823         pthread_mutex_unlock(&mutex);
1824 
1825         // thread releases, exits
1826 
1827         pthread_join(t, NULL);
1828         CPPUNIT_ASSERT(resources->size() == 0);
1829         CPPUNIT_ASSERT(txns->size() == 0);
1830 
1831         pthread_mutex_destroy(&mutex);
1832         Config::deleteInstanceMap();
1833     }
1834 
resource_graph_overlapping_ranges()1835     void resource_graph_overlapping_ranges()
1836     {
1837         LBIDResourceGraph rg;
1838         set<ResourceNode*, RNLess<ResourceNode*> >* resources;
1839         set<ResourceNode*, RNLess<ResourceNode*> >::const_iterator it;
1840         map<VER_t, TransactionNode*>* txns;
1841         pthread_t t;
1842         VER_t txn = 1;
1843         int err;
1844 
1845         // make a fragmented range, then request a range that overlaps existing
1846         // ranges on both ends
1847 
1848         pthread_mutex_init(&mutex, NULL);
1849         pthread_mutex_lock(&mutex);
1850 
1851         err = rg.reserveRange(1001, 2000, txn, mutex);
1852         CPPUNIT_ASSERT(err == ERR_OK);
1853         err = rg.reserveRange(3001, 4000, txn, mutex);
1854         CPPUNIT_ASSERT(err == ERR_OK);
1855         pthread_create(&t, NULL, overlapping_range_helper, &rg);
1856         pthread_mutex_unlock(&mutex);
1857         sleep(1);
1858 
1859         // thread executes, tries to grab 1100-3900
1860 
1861         pthread_mutex_lock(&mutex);
1862         resources = rg.getResources();
1863         txns = rg.getTxns();
1864 
1865 #ifdef BRM_VERBOSE
1866         cerr << " resources->size = " << resources->size() << endl;
1867 
1868         for (it = resources->begin(); it != resources->end(); it++)
1869             cerr << "  " << (*it)->start() << "-" << (*it)->end() << endl;
1870 
1871 #endif
1872 
1873         it = resources->begin();
1874         CPPUNIT_ASSERT(resources->size() == 3);
1875         CPPUNIT_ASSERT((*it)->start() == 1001);
1876         CPPUNIT_ASSERT((*it)->end() == 2000);
1877         it++;
1878         CPPUNIT_ASSERT((*it)->start() == 2001);
1879         CPPUNIT_ASSERT((*it)->end() == 3000);
1880         it++;
1881         CPPUNIT_ASSERT((*it)->start() == 3001);
1882         CPPUNIT_ASSERT((*it)->end() == 4000);
1883 
1884         CPPUNIT_ASSERT(txns->size() == 2);
1885         rg.releaseResources(txn);
1886         CPPUNIT_ASSERT(txns->size() == 1);
1887         pthread_mutex_unlock(&mutex);
1888 
1889         pthread_join(t, NULL);
1890         CPPUNIT_ASSERT(resources->size() == 0);
1891         CPPUNIT_ASSERT(txns->size() == 0);
1892 
1893         pthread_mutex_destroy(&mutex);
1894         Config::deleteInstanceMap();
1895     }
1896 
1897 };
1898 
1899 
1900 
1901 CPPUNIT_TEST_SUITE_REGISTRATION( BRMTest );
1902 
1903 #include <cppunit/extensions/TestFactoryRegistry.h>
1904 #include <cppunit/ui/text/TestRunner.h>
1905 
main(int argc,char ** argv)1906 int main( int argc, char** argv)
1907 {
1908     CppUnit::TextUi::TestRunner runner;
1909     CppUnit::TestFactoryRegistry& registry = CppUnit::TestFactoryRegistry::getRegistry();
1910     runner.addTest( registry.makeTest() );
1911     bool wasSuccessful = runner.run( "", false );
1912     return (wasSuccessful ? 0 : 1);
1913 }
1914 
1915 
1916