OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WFLAG_TEST_H 00026 #define WFLAG_TEST_H 00027 00028 #include <iostream> 00029 00030 #include <boost/thread.hpp> 00031 #include <cxxtest/TestSuite.h> 00032 00033 #include "../WFlag.h" 00034 #include "../WConditionOneShot.h" 00035 00036 /** 00037 * Helper class. 00038 */ 00039 class Callable 00040 { 00041 public: 00042 /** 00043 * The flag to be tested 00044 */ 00045 WFlag<bool>* flag; 00046 00047 /** 00048 * True if the thread finishes. 00049 */ 00050 bool finished; 00051 00052 /** 00053 * Constructor. To init the Flag. 00054 */ 00055 Callable() 00056 { 00057 finished = false; 00058 flag = new WFlag< bool >( new WConditionOneShot(), false ); 00059 } 00060 00061 /** 00062 * Thread function. 00063 */ 00064 void threadMain() 00065 { 00066 // just wait 00067 flag->wait(); 00068 finished = true; 00069 }; 00070 }; 00071 00072 /** 00073 * Test WFlag 00074 */ 00075 class WFlagTest : public CxxTest::TestSuite 00076 { 00077 public: 00078 /** 00079 * A temporary holder for some value. 00080 */ 00081 bool m_testTemporary; 00082 00083 /** 00084 * Helper function which simply sets the value above to true. It is used to test some conditions here. 00085 */ 00086 void setTemporary() 00087 { 00088 m_testTemporary = true; 00089 } 00090 00091 /** 00092 * An instantiation should never throw an exception, as well as tear down. 00093 */ 00094 void testInstantiation( void ) 00095 { 00096 WFlag< bool >* flag = 0; 00097 00098 TS_ASSERT_THROWS_NOTHING( flag = new WFlag< bool >( new WConditionOneShot(), false ) ); 00099 TS_ASSERT_THROWS_NOTHING( delete flag ); 00100 } 00101 00102 /** 00103 * Test whether notification is working. 00104 */ 00105 void testWaitNotify() 00106 { 00107 Callable t; 00108 // the flag should be false now 00109 // NOTE: the syntax to get the value of the flag looks ugly here, but you normally do not use pointers 00110 TS_ASSERT( !( *t.flag )() ); 00111 00112 // start a thread 00113 boost::thread thread = boost::thread( boost::bind( &Callable::threadMain, &t ) ); 00114 00115 // set value equal to the one already set 00116 ( *t.flag )( false ); 00117 // this should NOT notify the thread since the set value is not different to the initial one 00118 TS_ASSERT( !t.finished ); 00119 00120 // notify 00121 ( *t.flag )( true ); 00122 thread.join(); 00123 00124 TS_ASSERT( ( *t.flag )() ); 00125 } 00126 00127 /** 00128 * Test whether change condition is fired. 00129 */ 00130 void testChangeCondition() 00131 { 00132 m_testTemporary = false; 00133 00134 // create a condition 00135 WConditionOneShot* c = new WConditionOneShot(); 00136 c->subscribeSignal( boost::bind( &WFlagTest::setTemporary, this ) ); 00137 00138 // use own condition here 00139 WFlag< bool >* flag = new WFlag< bool >( c, false ); 00140 00141 // change value 00142 flag->set( !flag->get( true ) ); 00143 00144 // condition fired? 00145 // Remember: the condition calls the above member function when fired 00146 TS_ASSERT( m_testTemporary ); 00147 00148 // setting with the suppression flag enabled should not fire the condition: 00149 m_testTemporary = false; 00150 // change value 00151 flag->set( !flag->get( true ), true ); 00152 TS_ASSERT( !m_testTemporary ); 00153 00154 // setting without a change of value should also not call the condition 00155 flag->set( flag->get( true ) ); 00156 TS_ASSERT( !m_testTemporary ); 00157 } 00158 00159 /** 00160 * Test whether change flag is set and reset. 00161 */ 00162 void testChangeFlagAndReset() 00163 { 00164 // create a flag 00165 WFlag< bool >* flag = new WFlag< bool >( new WConditionOneShot(), false ); 00166 00167 // after creation, the change flag always is true 00168 TS_ASSERT( flag->changed() ); 00169 00170 // getting the value does not change the flag 00171 bool v = flag->get(); 00172 TS_ASSERT( !v ); 00173 TS_ASSERT( flag->changed() ); 00174 00175 // getting the value with the argument "true" should reset the change flag 00176 v = flag->get( true ); 00177 TS_ASSERT( !flag->changed() ); 00178 00179 delete flag; 00180 } 00181 00182 /** 00183 * Test whether copy construction/cloning is working. 00184 */ 00185 void testCopyConstruction() 00186 { 00187 // create a flag 00188 WFlag< bool >* flag = new WFlag< bool >( new WConditionOneShot(), false ); 00189 00190 // clone 00191 WFlag< bool >* flagClone = new WFlag< bool >( *flag ); 00192 00193 // check that value, flag and so on are the same 00194 TS_ASSERT( flag->get() == flagClone->get() ); 00195 TS_ASSERT( flag->changed() == flagClone->changed() ); 00196 00197 // the first should not influence the clone 00198 flag->get( true ); 00199 TS_ASSERT( flag->changed() != flagClone->changed() ); 00200 flagClone->set( !flagClone->get( true ) ); 00201 TS_ASSERT( flag->get() != flagClone->get() ); 00202 00203 // the conditions need to be different 00204 // 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 00205 TS_ASSERT( flag->getCondition() != flagClone->getCondition() ); 00206 TS_ASSERT( flag->getValueChangeCondition() != flagClone->getValueChangeCondition() ); 00207 } 00208 }; 00209 00210 #endif // WFLAG_TEST_H 00211 00212