source: ThirdParty/CodePatterns/src/Patterns/unittests/SingletonUnitTest.cpp

Candidate_v1.6.1
Last change on this file was 41e8e2, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit '084729c5923f0123e695fbe2548b393288c1f13d' as 'ThirdParty/CodePatterns'

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * SingletonUnitTest.cpp
10 *
11 * Created on: Mar 11, 2010
12 * Author: crueger
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "SingletonUnitTest.hpp"
21
22#include <cppunit/CompilerOutputter.h>
23#include <cppunit/extensions/TestFactoryRegistry.h>
24#include <cppunit/ui/text/TestRunner.h>
25#include <iostream>
26
27#include "CodePatterns/Singleton.hpp"
28#include "CodePatterns/Singleton_impl.hpp"
29
30#ifdef HAVE_TESTRUNNER
31#include "UnitTestMain.hpp"
32#endif /*HAVE_TESTRUNNER*/
33
34CPPUNIT_TEST_SUITE_REGISTRATION( SingletonTest );
35
36// some necessary stubs
37class SingletonStub1 : public Singleton <SingletonStub1>{
38 friend class Singleton<SingletonStub1>;
39private:
40 SingletonStub1(){
41 count1++;
42 }
43 // explicit copy constructor to catch if this is ever called
44 SingletonStub1(const SingletonStub1&){
45 CPPUNIT_FAIL ( "Copy constructor of Singleton called" );
46 }
47 virtual ~SingletonStub1(){
48 count2++;
49 }
50public:
51 static int count1;
52 static int count2;
53};
54
55int SingletonStub1::count1 = 0;
56int SingletonStub1::count2 = 0;
57
58CONSTRUCT_SINGLETON(SingletonStub1);
59
60class SingletonStub2 : public Singleton<SingletonStub2>{
61 friend class Singleton<SingletonStub2>;
62private:
63 SingletonStub2(){
64 count1++;
65 }
66 // explicit copy constructor to catch if this is ever called
67 SingletonStub2(const SingletonStub2&){
68 CPPUNIT_FAIL ( "Copy constructor of Singleton called" );
69 }
70 virtual ~SingletonStub2(){
71 count2++;
72 }
73public:
74 static int count1;
75 static int count2;
76};
77
78int SingletonStub2::count1 = 0;
79int SingletonStub2::count2 = 0;
80
81CONSTRUCT_SINGLETON(SingletonStub2);
82
83void SingletonTest::setUp()
84{
85 ASSERT_DO(Assert::Throw);
86}
87
88void SingletonTest::tearDown(){}
89
90void SingletonTest::ConstructionTest(){
91 void *ptr_1_1 = reinterpret_cast<void*>(SingletonStub1::getPointer());
92 void *ptr_1_2 = reinterpret_cast<void*>(SingletonStub1::getPointer());
93 void *ptr_1_3 = reinterpret_cast<void*>(&(SingletonStub1::getInstance()));
94
95 // test if we always get the same instance of our singleton
96 CPPUNIT_ASSERT_EQUAL(ptr_1_1,ptr_1_2);
97 CPPUNIT_ASSERT_EQUAL(ptr_1_1,ptr_1_3);
98
99 void *ptr_2_1 = reinterpret_cast<void*>(SingletonStub2::getPointer());
100 void *ptr_2_2 = reinterpret_cast<void*>(SingletonStub2::getPointer());
101 void *ptr_2_3 = reinterpret_cast<void*>(&(SingletonStub2::getInstance()));
102
103 // same as above but for a different singleton
104 CPPUNIT_ASSERT_EQUAL(ptr_2_1,ptr_2_2);
105 CPPUNIT_ASSERT_EQUAL(ptr_2_1,ptr_2_3);
106
107 // see if the two singletons actually differ
108 CPPUNIT_ASSERT(ptr_1_1!=ptr_2_1);
109
110 // see if each constructor was called exactly once
111 CPPUNIT_ASSERT_EQUAL(1,SingletonStub1::count1);
112 CPPUNIT_ASSERT_EQUAL(1,SingletonStub2::count1);
113 // no calls to the destructor should have occured so far
114 CPPUNIT_ASSERT_EQUAL(0,SingletonStub1::count2);
115 CPPUNIT_ASSERT_EQUAL(0,SingletonStub2::count2);
116
117 SingletonStub1::purgeInstance();
118
119 void *ptr_3_1 = reinterpret_cast<void*>(SingletonStub1::getPointer());
120 void *ptr_3_2 = reinterpret_cast<void*>(SingletonStub1::getPointer());
121
122 // now the constructor should have been called twice
123 CPPUNIT_ASSERT_EQUAL(2,SingletonStub1::count1);
124 // the destructor should have been called once
125 CPPUNIT_ASSERT_EQUAL(1,SingletonStub1::count2);
126 // see if the singleton Assumption holds
127 CPPUNIT_ASSERT_EQUAL(ptr_3_1,ptr_3_2);
128 // Some esoteric thing might cause our pointer to lay at the position of Singleton2 now
129 // See that those two objects still differ
130 CPPUNIT_ASSERT(ptr_3_1!=ptr_2_1);
131 // don't test for pointer difference between first and second singleton here,
132 // because they might be constructed in the same place
133
134
135 SingletonStub2::resetInstance();
136 // now the constructor should have been called twice
137 CPPUNIT_ASSERT_EQUAL(2,SingletonStub2::count1);
138 // the destructor should have been called once
139 CPPUNIT_ASSERT_EQUAL(1,SingletonStub2::count2);
140
141 void *ptr_4_1 = reinterpret_cast<void*>(SingletonStub2::getPointer());
142 void *ptr_4_2 = reinterpret_cast<void*>(SingletonStub2::getPointer());
143
144 // Still only two calls to the constructor, one call to destructor
145 CPPUNIT_ASSERT_EQUAL(2,SingletonStub2::count1);
146 CPPUNIT_ASSERT_EQUAL(1,SingletonStub2::count2);
147
148 // test if Singleton assumption can be broken by reset
149 CPPUNIT_ASSERT_EQUAL(ptr_4_1,ptr_4_2);
150
151 // and again test if we actually have a object seperate from anything else
152 CPPUNIT_ASSERT(ptr_4_1!=ptr_3_1);
153
154
155 // we don't purge our singletons here. Purging should be done automatically by the Singleton
156 // mechanism. Check with Valgrind to see if memory-leak occurs
157 std::cout << "Not purging Singleton!\n Check with Valgrind to see if automatic purgins is working!" << std::endl;
158}
159
160void SingletonTest::LockedTest(){
161 const AtomicInstance<SingletonStub1> ptr_1_1(SingletonStub1::getLockedInstance());
162 const SingletonStub1 &test_1 = *ptr_1_1;
163
164 // this deadlocks
165// AtomicInstance<SingletonStub1> ptr_1_2(SingletonStub1::getLockedInstance());
166
167 AtomicInstance<SingletonStub2> ptr_2_1(SingletonStub2::getLockedInstance());
168 SingletonStub2 &test_2 = *ptr_2_1;
169
170 // this deadlocks
171// AtomicInstance<SingletonStub2> ptr_2_2(SingletonStub2::getLockedInstance());
172}
Note: See TracBrowser for help on using the repository browser.