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