OpenWalnut  1.5.0dev
WFlag_test.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WFLAG_TEST_H
26 #define WFLAG_TEST_H
27 
28 #include <iostream>
29 
30 #include <boost/thread.hpp>
31 #include <cxxtest/TestSuite.h>
32 
33 #include "../WFlag.h"
34 #include "../WConditionOneShot.h"
35 
36 /**
37  * Helper class.
38  */
39 class Callable
40 {
41 public:
42  /**
43  * The flag to be tested
44  */
46 
47  /**
48  * True if the thread finishes.
49  */
50  bool finished;
51 
52  /**
53  * Constructor. To init the Flag.
54  */
56  {
57  finished = false;
58  flag = new WFlag< bool >( new WConditionOneShot(), false );
59  }
60 
61  /**
62  * Thread function.
63  */
64  void threadMain()
65  {
66  // just wait
67  flag->wait();
68  finished = true;
69  };
70 };
71 
72 /**
73  * Test WFlag
74  */
75 class WFlagTest : public CxxTest::TestSuite
76 {
77 public:
78  /**
79  * A temporary holder for some value.
80  */
82 
83  /**
84  * Helper function which simply sets the value above to true. It is used to test some conditions here.
85  */
86  void setTemporary()
87  {
88  m_testTemporary = true;
89  }
90 
91  /**
92  * An instantiation should never throw an exception, as well as tear down.
93  */
94  void testInstantiation( void )
95  {
96  WFlag< bool >* flag = 0;
97 
98  TS_ASSERT_THROWS_NOTHING( flag = new WFlag< bool >( new WConditionOneShot(), false ) );
99  TS_ASSERT_THROWS_NOTHING( delete flag );
100  }
101 
102  /**
103  * Test whether notification is working.
104  */
106  {
107  Callable t;
108  // the flag should be false now
109  // NOTE: the syntax to get the value of the flag looks ugly here, but you normally do not use pointers
110  TS_ASSERT( !( *t.flag )() );
111 
112  // start a thread
113  boost::thread thread = boost::thread( boost::bind( &Callable::threadMain, &t ) );
114 
115  // set value equal to the one already set
116  ( *t.flag )( false );
117  // this should NOT notify the thread since the set value is not different to the initial one
118  TS_ASSERT( !t.finished );
119 
120  // notify
121  ( *t.flag )( true );
122  thread.join();
123 
124  TS_ASSERT( ( *t.flag )() );
125  }
126 
127  /**
128  * Test whether change condition is fired.
129  */
131  {
132  m_testTemporary = false;
133 
134  // create a condition
136  c->subscribeSignal( boost::bind( &WFlagTest::setTemporary, this ) );
137 
138  // use own condition here
139  WFlag< bool >* flag = new WFlag< bool >( c, false );
140 
141  // change value
142  flag->set( !flag->get( true ) );
143 
144  // condition fired?
145  // Remember: the condition calls the above member function when fired
146  TS_ASSERT( m_testTemporary );
147 
148  // setting with the suppression flag enabled should not fire the condition:
149  m_testTemporary = false;
150  // change value
151  flag->set( !flag->get( true ), true );
152  TS_ASSERT( !m_testTemporary );
153 
154  // setting without a change of value should also not call the condition
155  flag->set( flag->get( true ) );
156  TS_ASSERT( !m_testTemporary );
157  }
158 
159  /**
160  * Test whether change flag is set and reset.
161  */
163  {
164  // create a flag
165  WFlag< bool >* flag = new WFlag< bool >( new WConditionOneShot(), false );
166 
167  // after creation, the change flag always is true
168  TS_ASSERT( flag->changed() );
169 
170  // getting the value does not change the flag
171  bool v = flag->get();
172  TS_ASSERT( !v );
173  TS_ASSERT( flag->changed() );
174 
175  // getting the value with the argument "true" should reset the change flag
176  v = flag->get( true );
177  TS_ASSERT( !flag->changed() );
178 
179  delete flag;
180  }
181 
182  /**
183  * Test whether copy construction/cloning is working.
184  */
186  {
187  // create a flag
188  WFlag< bool >* flag = new WFlag< bool >( new WConditionOneShot(), false );
189 
190  // clone
191  WFlag< bool >* flagClone = new WFlag< bool >( *flag );
192 
193  // check that value, flag and so on are the same
194  TS_ASSERT( flag->get() == flagClone->get() );
195  TS_ASSERT( flag->changed() == flagClone->changed() );
196 
197  // the first should not influence the clone
198  flag->get( true );
199  TS_ASSERT( flag->changed() != flagClone->changed() );
200  flagClone->set( !flagClone->get( true ) );
201  TS_ASSERT( flag->get() != flagClone->get() );
202 
203  // the conditions need to be different
204  // This is because the flag is another one and you won't expect to wake up if someone changes a Flag you do not know
205  TS_ASSERT( flag->getCondition() != flagClone->getCondition() );
206  TS_ASSERT( flag->getValueChangeCondition() != flagClone->getValueChangeCondition() );
207  }
208 };
209 
210 #endif // WFLAG_TEST_H
211 
212 
Helper class.
Definition: WFlag_test.h:40
WFlag< bool > * flag
The flag to be tested.
Definition: WFlag_test.h:45
void threadMain()
Thread function.
Definition: WFlag_test.h:64
bool finished
True if the thread finishes.
Definition: WFlag_test.h:50
Callable()
Constructor.
Definition: WFlag_test.h:55
Implements a WCondition, but can be fired only ONCE.
boost::signals2::connection subscribeSignal(t_ConditionNotifierType notifier) const
Subscribes a specified function to be notified on condition change.
Definition: WCondition.cpp:50
Test WFlag.
Definition: WFlag_test.h:76
void testChangeCondition()
Test whether change condition is fired.
Definition: WFlag_test.h:130
bool m_testTemporary
A temporary holder for some value.
Definition: WFlag_test.h:81
void setTemporary()
Helper function which simply sets the value above to true.
Definition: WFlag_test.h:86
void testInstantiation(void)
An instantiation should never throw an exception, as well as tear down.
Definition: WFlag_test.h:94
void testChangeFlagAndReset()
Test whether change flag is set and reset.
Definition: WFlag_test.h:162
void testWaitNotify()
Test whether notification is working.
Definition: WFlag_test.h:105
void testCopyConstruction()
Test whether copy construction/cloning is working.
Definition: WFlag_test.h:185
virtual void wait() const
Wait for the flag to change its value.
Definition: WFlag.h:279
std::shared_ptr< WCondition > getCondition()
Returns the condition that is used by this flag.
Definition: WFlag.h:319
virtual bool changed(bool reset=false)
True whenever the value inside this flag has changed since the last reset.
Definition: WFlag.h:344
virtual const T & get(bool resetChangeState=false)
Operator returns value of the flag.
Definition: WFlag.h:257
std::shared_ptr< WCondition > getValueChangeCondition()
Returns the condition denoting a value change.
Definition: WFlag.h:325
virtual bool set(const T &value, bool suppressNotification=false)
Sets the new value for this flag.
Definition: WFlag.h:291