|
Teuchos Package Browser (Single Doxygen Collection) Version of the Day
|
00001 /* 00002 // @HEADER 00003 // *********************************************************************** 00004 // 00005 // Teuchos: Common Tools Package 00006 // Copyright (2004) Sandia Corporation 00007 // 00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00009 // license for use of this work by or on behalf of the U.S. Government. 00010 // 00011 // This library is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU Lesser General Public License as 00013 // published by the Free Software Foundation; either version 2.1 of the 00014 // License, or (at your option) any later version. 00015 // 00016 // This library is distributed in the hope that it will be useful, but 00017 // WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 // Lesser General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Lesser General Public 00022 // License along with this library; if not, write to the Free Software 00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00024 // USA 00025 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00026 // 00027 // *********************************************************************** 00028 // @HEADER 00029 */ 00030 00031 #include "Teuchos_UnitTestHarness.hpp" 00032 #include "Teuchos_RCPNode.hpp" 00033 #include "Teuchos_getConst.hpp" 00034 #include "Teuchos_TypeNameTraits.hpp" 00035 #include "TestClasses.hpp" 00036 00037 00038 namespace Teuchos { 00039 00040 00041 template<class T> 00042 class MockRCP { 00043 public: 00044 T* access_private_ptr() const 00045 { 00046 return (T*)(0x777777); // Just some bogus address printed to out 00047 } 00048 }; 00049 00050 00051 template<class T> 00052 RCPNode* basicRCPNodeNoAlloc(T* p, const bool has_ownership) 00053 { 00054 RCPNodeTmpl<T,DeallocDelete<T> > *rcpNode = 00055 new RCPNodeTmpl<T,DeallocDelete<T> >(p, DeallocDelete<T>(), has_ownership); 00056 return rcpNode; 00057 } 00058 00059 00060 template<class T> 00061 RCPNode* basicRCPNode(const bool has_ownership, T **p_out = 0) 00062 { 00063 T *p = new T; 00064 if (p_out) 00065 *p_out = p; 00066 RCPNode *rcpNode = basicRCPNodeNoAlloc<T>(p, has_ownership); 00067 return rcpNode; 00068 } 00069 00070 00071 void deleteRCPNode( RCPNode **node ) 00072 { 00073 TEUCHOS_ASSERT(node); 00074 TEUCHOS_ASSERT(*node); 00075 (*node)->delete_obj(); 00076 delete (*node); 00077 *node = 0; 00078 } 00079 00080 00081 template<class T> 00082 RCPNodeHandle basicRCPNodeHandle(const bool has_ownership, T **p_out = 0) 00083 { 00084 T *p = 0; 00085 RCPNode *rcpNode = basicRCPNode(has_ownership, &p); 00086 if (p_out) 00087 *p_out = p; 00088 #ifdef TEUCHOS_DEBUG 00089 return RCPNodeHandle(rcpNode, p, typeName(*p), concreteTypeName(*p), has_ownership); 00090 #else 00091 return RCPNodeHandle(rcpNode); 00092 #endif 00093 } 00094 00095 00096 TEUCHOS_STATIC_SETUP() 00097 { 00098 } 00099 00100 00101 // 00102 // Non-templated tests 00103 // 00104 00105 00106 TEUCHOS_UNIT_TEST( RCPNodeHandle, assignSelf ) 00107 { 00108 RCPNodeHandle nodeRef; 00109 nodeRef = nodeRef; 00110 } 00111 00112 00113 TEUCHOS_UNIT_TEST( RCPNodeHandle, defaultConstruct) 00114 { 00115 RCPNodeHandle nodeRef; 00116 TEST_EQUALITY_CONST( nodeRef.count(), 0 ); 00117 TEST_EQUALITY_CONST( nodeRef.has_ownership(), false ); 00118 nodeRef.has_ownership(true); 00119 TEST_EQUALITY_CONST( nodeRef.has_ownership(), false ); 00120 #ifdef TEUCHOS_DEBUG 00121 TEST_EQUALITY_CONST( nodeRef.get_base_obj_map_key_void_ptr(), static_cast<void*>(0) ); 00122 TEST_THROW({nodeRef.set_extra_data(any(),"", PRE_DESTROY, true);}, 00123 NullReferenceError); 00124 TEST_THROW({any &a = nodeRef.get_extra_data("int","blob"); (void)a;}, 00125 NullReferenceError); 00126 TEST_THROW({const any &a = getConst(nodeRef).get_extra_data("int","blob"); (void)a;}, 00127 NullReferenceError); 00128 TEST_THROW({any *a = nodeRef.get_optional_extra_data("int","blob"); (void)a;}, 00129 NullReferenceError); 00130 TEST_THROW({const any *a = getConst(nodeRef).get_optional_extra_data("int","blob"); (void)a;}, 00131 NullReferenceError); 00132 #endif // TEUCHOS_DEBUG 00133 } 00134 00135 00136 #ifdef TEUCHOS_DEBUG 00137 00138 00139 TEUCHOS_UNIT_TEST( RCPNodeHandle, add_New_RCPNode_basic ) 00140 { 00141 00142 typedef RCPNodeTracer::RCPNodeStatistics RCPNodeStatistics; 00143 00144 SET_RCPNODE_TRACING(); 00145 00146 RCPNode *node = basicRCPNode<A>(true); 00147 00148 const int numActiveNodesBase = RCPNodeTracer::numActiveRCPNodes(); 00149 const RCPNodeStatistics rcpNodeStatisticsBefore = RCPNodeTracer::getRCPNodeStatistics(); 00150 00151 out << std::endl; 00152 ECHO(RCPNodeTracer::addNewRCPNode(node, "dummy")); 00153 00154 out << std::endl; 00155 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1); 00156 00157 out << std::endl; 00158 const RCPNodeStatistics rcpNodeStatistics1 = RCPNodeTracer::getRCPNodeStatistics(); 00159 TEST_COMPARE(rcpNodeStatistics1.maxNumRCPNodes, >=, 00160 rcpNodeStatisticsBefore.maxNumRCPNodes); 00161 TEST_EQUALITY(rcpNodeStatistics1.totalNumRCPNodeAllocations, 00162 rcpNodeStatisticsBefore.totalNumRCPNodeAllocations+1); 00163 TEST_EQUALITY(rcpNodeStatistics1.totalNumRCPNodeDeletions, 00164 rcpNodeStatisticsBefore.totalNumRCPNodeDeletions); 00165 00166 out << std::endl; 00167 ECHO(RCPNodeTracer::removeRCPNode(node)); 00168 00169 out << std::endl; 00170 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase); 00171 00172 out << std::endl; 00173 const RCPNodeStatistics rcpNodeStatistics2 = RCPNodeTracer::getRCPNodeStatistics(); 00174 TEST_COMPARE(rcpNodeStatistics2.maxNumRCPNodes, >=, 00175 rcpNodeStatisticsBefore.maxNumRCPNodes); 00176 TEST_EQUALITY(rcpNodeStatistics2.totalNumRCPNodeAllocations, 00177 rcpNodeStatisticsBefore.totalNumRCPNodeAllocations+1); 00178 TEST_EQUALITY(rcpNodeStatistics2.totalNumRCPNodeDeletions, 00179 rcpNodeStatisticsBefore.totalNumRCPNodeDeletions+1); 00180 00181 out << std::endl; 00182 std::ostringstream statsOut_oss; 00183 RCPNodeTracer::printRCPNodeStatistics(rcpNodeStatistics2, statsOut_oss); 00184 std::ostringstream expectedStatsOut_oss; 00185 expectedStatsOut_oss 00186 << "\n***" 00187 << "\n*** RCPNode Tracing statistics:" 00188 << "\n**\n" 00189 << "\n maxNumRCPNodes = "<<rcpNodeStatistics2.maxNumRCPNodes 00190 << "\n totalNumRCPNodeAllocations = "<<rcpNodeStatistics2.totalNumRCPNodeAllocations 00191 << "\n totalNumRCPNodeDeletions = "<<rcpNodeStatistics2.totalNumRCPNodeDeletions 00192 << "\n"; 00193 TEST_EQUALITY(statsOut_oss.str(), expectedStatsOut_oss.str()); 00194 00195 deleteRCPNode(&node); 00196 00197 } 00198 00199 00200 TEUCHOS_UNIT_TEST( RCPNodeHandle, add_New_RCPNode_add_owning_twice_error ) 00201 { 00202 SET_RCPNODE_TRACING(); 00203 A *a_ptr = new A; 00204 RCPNode *node1 = basicRCPNodeNoAlloc<A>(a_ptr, true); 00205 const int numActiveNodesBase = RCPNodeTracer::numActiveRCPNodes(); 00206 ECHO(RCPNodeTracer::addNewRCPNode(node1, "dummy1")); 00207 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1); 00208 RCPNode *node2 = basicRCPNodeNoAlloc<A>(a_ptr, true); 00209 TEST_THROW(RCPNodeTracer::addNewRCPNode(node2, "dummy2"), DuplicateOwningRCPError); 00210 ECHO(RCPNodeTracer::removeRCPNode(node1)); 00211 deleteRCPNode(&node1); 00212 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase); 00213 node2->has_ownership(false); 00214 deleteRCPNode(&node2); 00215 } 00216 00217 00218 TEUCHOS_UNIT_TEST( RCPNodeHandle, add_New_RCPNode_add_nonowning_twice_okay_1 ) 00219 { 00220 SET_RCPNODE_TRACING(); 00221 A *a_ptr = new A; 00222 RCPNode *node1 = basicRCPNodeNoAlloc<A>(a_ptr, true); 00223 const int numActiveNodesBase = RCPNodeTracer::numActiveRCPNodes(); 00224 ECHO(RCPNodeTracer::addNewRCPNode(node1, "dummy1")); 00225 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1); 00226 RCPNode *node2 = basicRCPNodeNoAlloc<A>(a_ptr, false); 00227 ECHO(RCPNodeTracer::addNewRCPNode(node2, "dummy2")); 00228 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+2); 00229 TEST_EQUALITY(RCPNodeTracer::getExistingRCPNode(a_ptr), node1); 00230 ECHO(RCPNodeTracer::removeRCPNode(node2)); 00231 deleteRCPNode(&node2); 00232 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1); 00233 ECHO(RCPNodeTracer::removeRCPNode(node1)); 00234 deleteRCPNode(&node1); 00235 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase); 00236 } 00237 00238 00239 TEUCHOS_UNIT_TEST( RCPNodeHandle, add_New_RCPNode_add_nonowning_twice_okay_2 ) 00240 { 00241 SET_RCPNODE_TRACING(); 00242 A *a_ptr = new A; 00243 RCPNode *node1 = basicRCPNodeNoAlloc<A>(a_ptr, false); 00244 const int numActiveNodesBase = RCPNodeTracer::numActiveRCPNodes(); 00245 ECHO(RCPNodeTracer::addNewRCPNode(node1, "dummy1")); 00246 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1); 00247 RCPNode *node2 = basicRCPNodeNoAlloc<A>(a_ptr, true); 00248 ECHO(RCPNodeTracer::addNewRCPNode(node2, "dummy2")); 00249 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+2); 00250 TEST_EQUALITY(RCPNodeTracer::getExistingRCPNode(a_ptr), node2); 00251 ECHO(RCPNodeTracer::removeRCPNode(node2)); 00252 deleteRCPNode(&node2); 00253 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1); 00254 ECHO(RCPNodeTracer::removeRCPNode(node1)); 00255 deleteRCPNode(&node1); 00256 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase); 00257 } 00258 00259 00260 TEUCHOS_UNIT_TEST( RCPNodeHandle, add_New_RCPNode_add_two_nodes_same_obj ) 00261 { 00262 SET_RCPNODE_TRACING(); 00263 ECHO(C *c_ptr = new C); 00264 ECHO(RCPNode *node_c = basicRCPNodeNoAlloc<C>(c_ptr, true)); 00265 ECHO(RCPNode *node_b1 = basicRCPNodeNoAlloc<B1>(c_ptr, true)); 00266 ECHO(const int numActiveNodesBase = RCPNodeTracer::numActiveRCPNodes()); 00267 ECHO(RCPNodeTracer::addNewRCPNode(node_c, "dummy")); 00268 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1); 00269 #ifdef HAS_TEUCHOS_GET_BASE_OBJ_VOID_PTR 00270 // We can detect that these are the same object! 00271 TEST_THROW(RCPNodeTracer::addNewRCPNode(node_b1, "dummy"), DuplicateOwningRCPError); 00272 #else 00273 // We can not detect if these are the same object! 00274 ECHO(RCPNodeTracer::addNewRCPNode(node_b1, "dummy")); 00275 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+2); 00276 ECHO(RCPNodeTracer::removeRCPNode(node_b1)); 00277 #endif 00278 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase+1); 00279 ECHO(RCPNodeTracer::removeRCPNode(node_c)); 00280 TEST_EQUALITY(RCPNodeTracer::numActiveRCPNodes(), numActiveNodesBase); 00281 ECHO(node_b1->has_ownership(false)); 00282 ECHO(deleteRCPNode(&node_b1)); 00283 ECHO(deleteRCPNode(&node_c)); 00284 } 00285 00286 00287 #ifdef HAVE_TEUCHOS_DEBUG_RCP_NODE_TRACING 00288 TEUCHOS_UNIT_TEST( RCPNodeHandle, remove_RCPNode_missing_node ) 00289 { 00290 SET_RCPNODE_TRACING(); 00291 RCPNode *node = basicRCPNode<A>(true); 00292 TEST_THROW(RCPNodeTracer::removeRCPNode(node), std::logic_error); 00293 deleteRCPNode(&node); 00294 } 00295 #endif // HAVE_TEUCHOS_DEBUG_RCP_NODE_TRACING 00296 00297 00298 #endif // TEUCHOS_DEBUG 00299 00300 00301 // 00302 // Templated tests 00303 // 00304 00305 00306 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, basicConstruct_owns_mem, T ) 00307 { 00308 T *p = 0; 00309 RCPNodeHandle nodeRef(basicRCPNodeHandle<T>(true, &p)); 00310 TEST_EQUALITY_CONST( nodeRef.count(), 1 ); 00311 TEST_EQUALITY_CONST( nodeRef.has_ownership(), true ); 00312 nodeRef.has_ownership(false); 00313 TEST_EQUALITY_CONST( nodeRef.has_ownership(), false ); 00314 #ifdef TEUCHOS_DEBUG 00315 TEST_INEQUALITY_CONST( nodeRef.get_base_obj_map_key_void_ptr(), static_cast<void*>(0) ); 00316 TEST_EQUALITY( nodeRef.get_base_obj_map_key_void_ptr(), static_cast<void*>(p) ); 00317 TEST_THROW({any &a = nodeRef.get_extra_data("int","blob"); (void)a;}, 00318 std::invalid_argument); 00319 TEST_THROW({const any &a = getConst(nodeRef).get_extra_data("int","blob"); (void)a;}, 00320 std::invalid_argument); 00321 #endif // TEUCHOS_DEBUG 00322 TEST_EQUALITY_CONST(nodeRef.get_optional_extra_data("int","blob"), 0); 00323 TEST_EQUALITY_CONST(getConst(nodeRef).get_optional_extra_data("int","blob"), 0); 00324 nodeRef.has_ownership(true); 00325 } 00326 00327 00328 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, basicConstruct_no_owns_mem, T ) 00329 { 00330 RCPNodeHandle nodeRef(basicRCPNodeHandle<T>(false)); 00331 TEST_EQUALITY_CONST( nodeRef.count(), 1 ); 00332 TEST_EQUALITY_CONST( nodeRef.has_ownership(), false ); 00333 nodeRef.has_ownership(true); 00334 TEST_EQUALITY_CONST( nodeRef.has_ownership(), true ); 00335 } 00336 00337 00338 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, weakPtr_basic_1, T ) 00339 { 00340 00341 ECHO(RCPNodeHandle nodeRef1(basicRCPNodeHandle<T>(true))); 00342 TEST_EQUALITY_CONST( nodeRef1.strength(), RCP_STRONG ); 00343 00344 ECHO(RCPNodeHandle nodeRef2 = nodeRef1.create_weak()); 00345 00346 TEST_EQUALITY_CONST( nodeRef2.strength(), RCP_WEAK ); 00347 TEST_EQUALITY_CONST( nodeRef1.strong_count(), 1 ); 00348 TEST_EQUALITY_CONST( nodeRef1.weak_count(), 1 ); 00349 TEST_EQUALITY_CONST( nodeRef2.strong_count(), 1 ); 00350 TEST_EQUALITY_CONST( nodeRef2.weak_count(), 1 ); 00351 00352 ECHO(RCPNodeHandle nodeRef3 = nodeRef2.create_strong()); 00353 00354 TEST_EQUALITY_CONST( nodeRef3.strength(), RCP_STRONG ); 00355 TEST_EQUALITY_CONST( nodeRef1.strong_count(), 2 ); 00356 TEST_EQUALITY_CONST( nodeRef1.weak_count(), 1 ); 00357 TEST_EQUALITY_CONST( nodeRef2.strong_count(), 2 ); 00358 TEST_EQUALITY_CONST( nodeRef2.weak_count(), 1 ); 00359 00360 MockRCP<T> mockRCP; 00361 ECHO(nodeRef2.debug_assert_valid_ptr(mockRCP)); // Should not throw! 00362 00363 // This will make the underlying object T get deleted! 00364 ECHO(nodeRef1 = null); 00365 ECHO(nodeRef3 = null); 00366 00367 TEST_EQUALITY_CONST( nodeRef1.node_ptr()==0, true ); 00368 TEST_EQUALITY_CONST( nodeRef1.is_node_null(), true ); 00369 TEST_EQUALITY_CONST( nodeRef1.is_valid_ptr(), true ); 00370 00371 TEST_EQUALITY_CONST( nodeRef2.node_ptr()!=0, true ); 00372 TEST_EQUALITY_CONST( nodeRef2.is_node_null(), false ); 00373 TEST_EQUALITY_CONST( nodeRef2.is_valid_ptr(), false ); 00374 00375 #ifdef TEUCHOS_DEBUG 00376 TEST_THROW( nodeRef2.debug_assert_valid_ptr(mockRCP), 00377 DanglingReferenceError ); 00378 #endif 00379 00380 ECHO(nodeRef2 = null); // Should make the underlying node go away 00381 00382 } 00383 00384 00385 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, weakPtr_basic_2, T ) 00386 { 00387 00388 ECHO(RCPNodeHandle nodeRef1(basicRCPNodeHandle<T>(true))); 00389 TEST_EQUALITY_CONST( nodeRef1.strength(), RCP_STRONG ); 00390 00391 ECHO(RCPNodeHandle nodeRef2 = nodeRef1.create_weak()); 00392 TEST_EQUALITY_CONST( nodeRef2.strength(), RCP_WEAK ); 00393 TEST_EQUALITY_CONST( nodeRef1.strong_count(), 1 ); 00394 TEST_EQUALITY_CONST( nodeRef1.weak_count(), 1 ); 00395 TEST_EQUALITY_CONST( nodeRef2.strong_count(), 1 ); 00396 TEST_EQUALITY_CONST( nodeRef2.weak_count(), 1 ); 00397 00398 MockRCP<T> mockRCP; 00399 00400 ECHO(nodeRef2.debug_assert_valid_ptr(mockRCP)); // Should not throw! 00401 00402 ECHO(nodeRef2 = null); // The underlying object stays alive! 00403 00404 TEST_EQUALITY_CONST( nodeRef2.node_ptr()==0, true ); 00405 TEST_EQUALITY_CONST( nodeRef2.is_node_null(), true ); 00406 TEST_EQUALITY_CONST( nodeRef2.is_valid_ptr(), true ); 00407 00408 TEST_EQUALITY_CONST( nodeRef1.node_ptr()!=0, true ); 00409 TEST_EQUALITY_CONST( nodeRef1.is_node_null(), false ); 00410 TEST_EQUALITY_CONST( nodeRef1.is_valid_ptr(), true ); 00411 00412 nodeRef1.debug_assert_valid_ptr(mockRCP); // Should not throw! 00413 00414 } 00415 00416 // 00417 // Test behavior of RCP node tracing but only if it is off by default 00418 // 00419 // NOTE: If node tracing is on by default then we can't control how many nodes 00420 // get created in other code not in the unit test. 00421 // 00422 00423 #if defined(TEUCHOS_DEBUG) && !defined(HAVE_TEUCHOS_DEBUG_RCP_NODE_TRACING) 00424 # define DO_RCPNODE_TRACING_TESTS 1 00425 #endif 00426 00427 00428 #ifdef DO_RCPNODE_TRACING_TESTS 00429 00430 00431 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, debugWithNodeTracingPrint, T ) 00432 { 00433 00434 TEST_EQUALITY_CONST(RCPNodeTracer::isTracingActiveRCPNodes(), false); 00435 RCPNodeTracer::setTracingActiveRCPNodes(true); 00436 TEST_EQUALITY_CONST(RCPNodeTracer::isTracingActiveRCPNodes(), true); 00437 00438 { 00439 00440 T *p = new T; // Never do this in production code! 00441 const std::string T_name = "T_name"; 00442 const std::string concreateT_name = "concreateT_name"; 00443 const bool has_ownership = true; 00444 RCPNode *node = new RCPNodeTmpl<T,DeallocDelete<T> >( 00445 p, DeallocDelete<T>(), has_ownership); 00446 00447 RCPNodeHandle nodeRef(node, p, T_name, concreateT_name, has_ownership); 00448 00449 TEST_EQUALITY_CONST(RCPNodeTracer::numActiveRCPNodes(), 1); 00450 00451 out << "\nMake sure output is printed when there is an active node with tracing ...\n"; 00452 00453 const void* rcpNodeKey = RCPNodeTracer::getRCPNodeBaseObjMapKeyVoidPtr(p); 00454 00455 std::ostringstream expendedOutput_oss; 00456 expendedOutput_oss 00457 << RCPNodeTracer::getActiveRCPNodeHeaderString() 00458 << "\n" 00459 << " 0: RCPNode (map_key_void_ptr=" << rcpNodeKey << ")\n" 00460 << " Information = {T="<<T_name<<", ConcreteT="<<concreateT_name<<", p="<<p<<", has_ownership="<<has_ownership<<"}\n" 00461 << " RCPNode address = " << node << "\n" 00462 << " insertionNumber = " << node->insertion_number() 00463 << "\n\n" 00464 << RCPNodeTracer::getCommonDebugNotesString(); 00465 00466 std::ostringstream printActiveRCPNodes_out; 00467 RCPNodeTracer::printActiveRCPNodes(printActiveRCPNodes_out); 00468 TEST_EQUALITY( printActiveRCPNodes_out.str(), expendedOutput_oss.str() ); 00469 00470 // NOTE: The above test basically copied and pasted the ouptut stream code 00471 // from printActiveRCPNodes(...) and will need to be maintained 00472 // with this code. However, this is a good test because it ensures that 00473 // the arguments node, p, T_name, and concreateT_name are passed, stored, 00474 // and retrieved correctly. It is also a good test because it ensures 00475 // that output is printed when node tracing is turned on. 00476 // 00477 // This is the very definition of a "white box" test but that is just fine 00478 // for a unit test. 00479 00480 } 00481 00482 TEST_EQUALITY_CONST(RCPNodeTracer::numActiveRCPNodes(), 0); 00483 00484 out << "\nMake sure no output is printed when there are no active nodes ...\n"; 00485 const std::string expendedOutput = ""; 00486 std::ostringstream printActiveRCPNodes_out; 00487 RCPNodeTracer::printActiveRCPNodes(printActiveRCPNodes_out); 00488 TEST_EQUALITY( printActiveRCPNodes_out.str(), expendedOutput ); 00489 00490 RCPNodeTracer::setTracingActiveRCPNodes(false); 00491 TEST_EQUALITY_CONST(RCPNodeTracer::isTracingActiveRCPNodes(), false); 00492 00493 } 00494 00495 00496 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, debugWithoutNodeTracingPrint, T ) 00497 { 00498 00499 TEST_EQUALITY_CONST(RCPNodeTracer::isTracingActiveRCPNodes(), false); 00500 RCPNodeTracer::setTracingActiveRCPNodes(false); 00501 TEST_EQUALITY_CONST(RCPNodeTracer::isTracingActiveRCPNodes(), false); 00502 00503 T *p = new T; // Never do this in production code! 00504 const std::string T_name = "T_name"; 00505 const std::string concreateT_name = "concreateT_name"; 00506 const bool has_ownership = true; 00507 RCPNode *node = new RCPNodeTmpl<T,DeallocDelete<T> >( 00508 p, DeallocDelete<T>(), has_ownership); 00509 00510 RCPNodeHandle nodeRef(node, p, T_name, concreateT_name, has_ownership); 00511 00512 TEST_EQUALITY_CONST(RCPNodeTracer::numActiveRCPNodes(), 0); 00513 00514 out << "\nMake sure no output is printed when there are no active nodes without tracing ...\n"; 00515 const std::string expendedOutput = ""; 00516 std::ostringstream printActiveRCPNodes_out; 00517 RCPNodeTracer::printActiveRCPNodes(printActiveRCPNodes_out); 00518 TEST_EQUALITY( printActiveRCPNodes_out.str(), expendedOutput ); 00519 00520 } 00521 00522 00523 #endif // DO_RCPNODE_TRACING_TESTS 00524 00525 00526 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, copyConstruct, T ) 00527 { 00528 RCPNodeHandle nodeRef1(basicRCPNodeHandle<T>(true)); 00529 RCPNodeHandle nodeRef2(nodeRef1); 00530 TEST_EQUALITY_CONST( nodeRef1.count(), 2 ); 00531 TEST_EQUALITY_CONST( nodeRef2.count(), 2 ); 00532 TEST_EQUALITY_CONST( nodeRef1.has_ownership(), true ); 00533 TEST_EQUALITY_CONST( nodeRef2.has_ownership(), true ); 00534 } 00535 00536 00537 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, assignmentOperator, T ) 00538 { 00539 RCPNodeHandle nodeRef1(basicRCPNodeHandle<T>(true)); 00540 RCPNodeHandle nodeRef2; 00541 nodeRef2 = nodeRef1; 00542 TEST_EQUALITY_CONST( nodeRef1.count(), 2 ); 00543 TEST_EQUALITY_CONST( nodeRef2.count(), 2 ); 00544 TEST_EQUALITY_CONST( nodeRef1.has_ownership(), true ); 00545 TEST_EQUALITY_CONST( nodeRef2.has_ownership(), true ); 00546 } 00547 00548 00549 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, extraData_basic, T ) 00550 { 00551 00552 RCPNodeHandle nodeRef(basicRCPNodeHandle<T>(true)); 00553 00554 const int v1 = 2; 00555 const any a1(v1); 00556 nodeRef.set_extra_data(a1, "a1", PRE_DESTROY, true); 00557 00558 any &a2 = nodeRef.get_extra_data(a1.typeName(), "a1"); 00559 TEST_EQUALITY_CONST( a1.same(a2), true ); 00560 TEST_EQUALITY( any_cast<int>(a2), v1 ); 00561 00562 any *a3 = nodeRef.get_optional_extra_data(a1.typeName(), "a1"); 00563 TEST_EQUALITY_CONST( a3!=0, true ); 00564 TEST_EQUALITY( &a2, a3 ); 00565 TEST_EQUALITY_CONST( a3->same(a1), true ); 00566 00567 RCPNodeHandle nodeRef2 = nodeRef; 00568 00569 const int v2 = 3; 00570 a2 = v2; 00571 TEST_EQUALITY( any_cast<int>(a1), v1 ); 00572 TEST_EQUALITY( any_cast<int>(*a3), v2 ); 00573 00574 any &a4 = nodeRef2.get_extra_data(a1.typeName(), "a1"); 00575 TEST_EQUALITY( &a4, &a2 ); 00576 TEST_EQUALITY( &a4, a3 ); 00577 TEST_EQUALITY( any_cast<int>(a4), v2 ); 00578 00579 } 00580 00581 00582 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, extraData_basic_const, T ) 00583 { 00584 00585 RCPNodeHandle nodeRef(basicRCPNodeHandle<T>(true)); 00586 00587 const int v1 = 2; 00588 const any a1(v1); 00589 nodeRef.set_extra_data(a1, "a1", PRE_DESTROY, true); 00590 00591 const RCPNodeHandle nodeRef2 = nodeRef; 00592 00593 const any &a2 = nodeRef2.get_extra_data(a1.typeName(), "a1"); 00594 TEST_EQUALITY_CONST( a1.same(a2), true ); 00595 TEST_EQUALITY( any_cast<int>(a2), v1 ); 00596 00597 const any *a3 = nodeRef2.get_optional_extra_data(a1.typeName(), "a1"); 00598 TEST_EQUALITY_CONST( a3!=0, true ); 00599 TEST_EQUALITY( &a2, a3 ); 00600 TEST_EQUALITY_CONST( a3->same(a1), true ); 00601 00602 } 00603 00604 00605 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, extraData_failed, T ) 00606 { 00607 00608 RCPNodeHandle nodeRef(basicRCPNodeHandle<T>(true)); 00609 00610 const int v1 = 2; 00611 const any a1(v1); 00612 nodeRef.set_extra_data(a1, "a1", PRE_DESTROY, true); 00613 00614 #ifdef TEUCHOS_DEBUG 00615 00616 TEST_THROW({nodeRef.get_extra_data("wrong type", "a1");}, 00617 std::invalid_argument); 00618 00619 TEST_THROW({nodeRef.get_extra_data(a1.typeName(), "wrong name");}, 00620 std::invalid_argument); 00621 00622 #endif // TEUCHOS_DEBUG 00623 00624 any *a2 = nodeRef.get_optional_extra_data("wrong type", "a1"); 00625 TEST_EQUALITY_CONST( a2, 0 ); 00626 00627 any *a3 = nodeRef.get_optional_extra_data(a1.typeName(), "wrong name"); 00628 TEST_EQUALITY_CONST( a3, 0 ); 00629 00630 } 00631 00632 00633 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( RCPNodeHandle, extraData_failed_const, T ) 00634 { 00635 00636 RCPNodeHandle nodeRef(basicRCPNodeHandle<T>(true)); 00637 00638 const int v1 = 2; 00639 const any a1(v1); 00640 nodeRef.set_extra_data(a1, "a1", PRE_DESTROY, true); 00641 00642 const RCPNodeHandle nodeRef2 = nodeRef; 00643 00644 #ifdef TEUCHOS_DEBUG 00645 00646 TEST_THROW({nodeRef2.get_extra_data("wrong type", "a1");}, 00647 std::invalid_argument); 00648 00649 TEST_THROW({nodeRef2.get_extra_data(a1.typeName(), "wrong name");}, 00650 std::invalid_argument); 00651 00652 #endif // TEUCHOS_DEBUG 00653 00654 const any *a2 = nodeRef2.get_optional_extra_data("wrong type", "a1"); 00655 TEST_EQUALITY_CONST( a2, 0 ); 00656 00657 const any *a3 = nodeRef2.get_optional_extra_data(a1.typeName(), "wrong name"); 00658 TEST_EQUALITY_CONST( a3, 0 ); 00659 00660 } 00661 00662 00663 // 00664 // Instantiations 00665 // 00666 00667 00668 #ifdef DO_RCPNODE_TRACING_TESTS 00669 00670 # define DEBUG_UNIT_TEST_GROUP( T ) \ 00671 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, debugWithNodeTracingPrint, T ) \ 00672 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, debugWithoutNodeTracingPrint, T ) 00673 00674 #else 00675 00676 # define DEBUG_UNIT_TEST_GROUP( T ) 00677 00678 #endif 00679 00680 00681 #define UNIT_TEST_GROUP( T ) \ 00682 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, basicConstruct_owns_mem, T ) \ 00683 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, basicConstruct_no_owns_mem, T ) \ 00684 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, weakPtr_basic_1, T ) \ 00685 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, weakPtr_basic_2, T ) \ 00686 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, copyConstruct, T ) \ 00687 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, assignmentOperator, T ) \ 00688 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, extraData_basic, T ) \ 00689 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, extraData_basic_const, T ) \ 00690 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, extraData_failed, T ) \ 00691 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( RCPNodeHandle, extraData_failed_const, T ) \ 00692 DEBUG_UNIT_TEST_GROUP(T) 00693 00694 00695 UNIT_TEST_GROUP(A) 00696 //UNIT_TEST_GROUP(B1) 00697 //UNIT_TEST_GROUP(B2) 00698 UNIT_TEST_GROUP(C) 00699 //UNIT_TEST_GROUP(D) 00700 UNIT_TEST_GROUP(E) 00701 00702 // 2008/09/22: rabartl: Above: We don't need to test with all of these classes 00703 // in order to test this functionality. 00704 00705 00706 } // namespace Teuchos
1.7.4