Teuchos Package Browser (Single Doxygen Collection) Version of the Day
RCPNodeHandle_UnitTests.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines