OpenWalnut  1.4.0
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 #ifndef Q_MOC_RUN
31 #include <boost/thread.hpp>
32 #endif
33 #include <cxxtest/TestSuite.h>
34 
35 #include "../WFlag.h"
36 #include "../WConditionOneShot.h"
37 
38 /**
39  * Helper class.
40  */
41 class Callable
42 {
43 public:
44  /**
45  * The flag to be tested
46  */
48 
49  /**
50  * True if the thread finishes.
51  */
52  bool finished;
53 
54  /**
55  * Constructor. To init the Flag.
56  */
58  {
59  finished = false;
60  flag = new WFlag< bool >( new WConditionOneShot(), false );
61  }
62 
63  /**
64  * Thread function.
65  */
66  void threadMain()
67  {
68  // just wait
69  flag->wait();
70  finished = true;
71  };
72 };
73 
74 /**
75  * Test WFlag
76  */
77 class WFlagTest : public CxxTest::TestSuite
78 {
79 public:
80  /**
81  * A temporary holder for some value.
82  */
84 
85  /**
86  * Helper function which simply sets the value above to true. It is used to test some conditions here.
87  */
88  void setTemporary()
89  {
90  m_testTemporary = true;
91  }
92 
93  /**
94  * An instantiation should never throw an exception, as well as tear down.
95  */
96  void testInstantiation( void )
97  {
98  WFlag< bool >* flag = 0;
99 
100  TS_ASSERT_THROWS_NOTHING( flag = new WFlag< bool >( new WConditionOneShot(), false ) );
101  TS_ASSERT_THROWS_NOTHING( delete flag );
102  }
103 
104  /**
105  * Test whether notification is working.
106  */
108  {
109  Callable t;
110  // the flag should be false now
111  // NOTE: the syntax to get the value of the flag looks ugly here, but you normally do not use pointers
112  TS_ASSERT( !( *t.flag )() );
113 
114  // start a thread
115  boost::thread thread = boost::thread( boost::bind( &Callable::threadMain, &t ) );
116 
117  // set value equal to the one already set
118  ( *t.flag )( false );
119  // this should NOT notify the thread since the set value is not different to the initial one
120  TS_ASSERT( !t.finished );
121 
122  // notify
123  ( *t.flag )( true );
124  thread.join();
125 
126  TS_ASSERT( ( *t.flag )() );
127  }
128 
129  /**
130  * Test whether change condition is fired.
131  */
133  {
134  m_testTemporary = false;
135 
136  // create a condition
138  c->subscribeSignal( boost::bind( &WFlagTest::setTemporary, this ) );
139 
140  // use own condition here
141  WFlag< bool >* flag = new WFlag< bool >( c, false );
142 
143  // change value
144  flag->set( !flag->get( true ) );
145 
146  // condition fired?
147  // Remember: the condition calls the above member function when fired
148  TS_ASSERT( m_testTemporary );
149 
150  // setting with the suppression flag enabled should not fire the condition:
151  m_testTemporary = false;
152  // change value
153  flag->set( !flag->get( true ), true );
154  TS_ASSERT( !m_testTemporary );
155 
156  // setting without a change of value should also not call the condition
157  flag->set( flag->get( true ) );
158  TS_ASSERT( !m_testTemporary );
159  }
160 
161  /**
162  * Test whether change flag is set and reset.
163  */
165  {
166  // create a flag
167  WFlag< bool >* flag = new WFlag< bool >( new WConditionOneShot(), false );
168 
169  // after creation, the change flag always is true
170  TS_ASSERT( flag->changed() );
171 
172  // getting the value does not change the flag
173  bool v = flag->get();
174  TS_ASSERT( !v );
175  TS_ASSERT( flag->changed() );
176 
177  // getting the value with the argument "true" should reset the change flag
178  v = flag->get( true );
179  TS_ASSERT( !flag->changed() );
180 
181  delete flag;
182  }
183 
184  /**
185  * Test whether copy construction/cloning is working.
186  */
188  {
189  // create a flag
190  WFlag< bool >* flag = new WFlag< bool >( new WConditionOneShot(), false );
191 
192  // clone
193  WFlag< bool >* flagClone = new WFlag< bool >( *flag );
194 
195  // check that value, flag and so on are the same
196  TS_ASSERT( flag->get() == flagClone->get() );
197  TS_ASSERT( flag->changed() == flagClone->changed() );
198 
199  // the first should not influence the clone
200  flag->get( true );
201  TS_ASSERT( flag->changed() != flagClone->changed() );
202  flagClone->set( !flagClone->get( true ) );
203  TS_ASSERT( flag->get() != flagClone->get() );
204 
205  // the conditions need to be different
206  // 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
207  TS_ASSERT( flag->getCondition() != flagClone->getCondition() );
208  TS_ASSERT( flag->getValueChangeCondition() != flagClone->getValueChangeCondition() );
209  }
210 };
211 
212 #endif // WFLAG_TEST_H
213 
214 
boost::signals2::connection subscribeSignal(t_ConditionNotifierType notifier) const
Subscribes a specified function to be notified on condition change.
Definition: WCondition.cpp:50
void testChangeCondition()
Test whether change condition is fired.
Definition: WFlag_test.h:132
bool flag
Flag set to true when thread starts.
boost::shared_ptr< WCondition > getCondition()
Returns the condition that is used by this flag.
Definition: WFlag.h:320
void setTemporary()
Helper function which simply sets the value above to true.
Definition: WFlag_test.h:88
Implements a WCondition, but can be fired only ONCE.
void threadMain()
Thread function.
Definition: WFlag_test.h:66
bool m_testTemporary
A temporary holder for some value.
Definition: WFlag_test.h:83
Test WFlag.
Definition: WFlag_test.h:77
bool finished
True if the thread finishes.
Definition: WFlag_test.h:52
void testChangeFlagAndReset()
Test whether change flag is set and reset.
Definition: WFlag_test.h:164
Helper class.
WFlag< bool > * flag
The flag to be tested.
Definition: WFlag_test.h:47
void testInstantiation(void)
An instantiation should never throw an exception, as well as tear down.
Definition: WFlag_test.h:96
virtual bool changed(bool reset=false)
True whenever the value inside this flag has changed since the last reset.
Definition: WFlag.h:345
void testWaitNotify()
Test whether notification is working.
Definition: WFlag_test.h:107
void testCopyConstruction()
Test whether copy construction/cloning is working.
Definition: WFlag_test.h:187
virtual void wait() const
Wait for the flag to change its value.
Definition: WFlag.h:280
virtual bool set(const T &value, bool suppressNotification=false)
Sets the new value for this flag.
Definition: WFlag.h:292
virtual const T & get(bool resetChangeState=false)
Operator returns value of the flag.
Definition: WFlag.h:258
boost::shared_ptr< WCondition > getValueChangeCondition()
Returns the condition denoting a value change.
Definition: WFlag.h:326
Callable()
Constructor.
Definition: WFlag_test.h:57