PageRenderTime 42ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcommon/tests/llinstancetracker_test.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 232 lines | 172 code | 15 blank | 45 comment | 5 complexity | 5f6b89e18f572e3913902a9981ee5d46 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llinstancetracker_test.cpp
  3. * @author Nat Goodspeed
  4. * @date 2009-11-10
  5. * @brief Test for llinstancetracker.
  6. *
  7. * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  8. * Second Life Viewer Source Code
  9. * Copyright (C) 2010, Linden Research, Inc.
  10. *
  11. * This library is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation;
  14. * version 2.1 of the License only.
  15. *
  16. * This library is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with this library; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *
  25. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  26. * $/LicenseInfo$
  27. */
  28. // Precompiled header
  29. #include "linden_common.h"
  30. // associated header
  31. #include "llinstancetracker.h"
  32. // STL headers
  33. #include <string>
  34. #include <vector>
  35. #include <set>
  36. #include <algorithm> // std::sort()
  37. // std headers
  38. // external library headers
  39. #include <boost/scoped_ptr.hpp>
  40. // other Linden headers
  41. #include "../test/lltut.h"
  42. #include "wrapllerrs.h"
  43. struct Keyed: public LLInstanceTracker<Keyed, std::string>
  44. {
  45. Keyed(const std::string& name):
  46. LLInstanceTracker<Keyed, std::string>(name),
  47. mName(name)
  48. {}
  49. std::string mName;
  50. };
  51. struct Unkeyed: public LLInstanceTracker<Unkeyed>
  52. {
  53. };
  54. /*****************************************************************************
  55. * TUT
  56. *****************************************************************************/
  57. namespace tut
  58. {
  59. struct llinstancetracker_data
  60. {
  61. };
  62. typedef test_group<llinstancetracker_data> llinstancetracker_group;
  63. typedef llinstancetracker_group::object object;
  64. llinstancetracker_group llinstancetrackergrp("llinstancetracker");
  65. template<> template<>
  66. void object::test<1>()
  67. {
  68. ensure_equals(Keyed::instanceCount(), 0);
  69. {
  70. Keyed one("one");
  71. ensure_equals(Keyed::instanceCount(), 1);
  72. Keyed* found = Keyed::getInstance("one");
  73. ensure("couldn't find stack Keyed", found);
  74. ensure_equals("found wrong Keyed instance", found, &one);
  75. {
  76. boost::scoped_ptr<Keyed> two(new Keyed("two"));
  77. ensure_equals(Keyed::instanceCount(), 2);
  78. Keyed* found = Keyed::getInstance("two");
  79. ensure("couldn't find heap Keyed", found);
  80. ensure_equals("found wrong Keyed instance", found, two.get());
  81. }
  82. ensure_equals(Keyed::instanceCount(), 1);
  83. }
  84. Keyed* found = Keyed::getInstance("one");
  85. ensure("Keyed key lives too long", ! found);
  86. ensure_equals(Keyed::instanceCount(), 0);
  87. }
  88. template<> template<>
  89. void object::test<2>()
  90. {
  91. ensure_equals(Unkeyed::instanceCount(), 0);
  92. {
  93. Unkeyed one;
  94. ensure_equals(Unkeyed::instanceCount(), 1);
  95. Unkeyed* found = Unkeyed::getInstance(&one);
  96. ensure_equals(found, &one);
  97. {
  98. boost::scoped_ptr<Unkeyed> two(new Unkeyed);
  99. ensure_equals(Unkeyed::instanceCount(), 2);
  100. Unkeyed* found = Unkeyed::getInstance(two.get());
  101. ensure_equals(found, two.get());
  102. }
  103. ensure_equals(Unkeyed::instanceCount(), 1);
  104. }
  105. ensure_equals(Unkeyed::instanceCount(), 0);
  106. }
  107. template<> template<>
  108. void object::test<3>()
  109. {
  110. Keyed one("one"), two("two"), three("three");
  111. // We don't want to rely on the underlying container delivering keys
  112. // in any particular order. That allows us the flexibility to
  113. // reimplement LLInstanceTracker using, say, a hash map instead of a
  114. // std::map. We DO insist that every key appear exactly once.
  115. typedef std::vector<std::string> StringVector;
  116. StringVector keys(Keyed::beginKeys(), Keyed::endKeys());
  117. std::sort(keys.begin(), keys.end());
  118. StringVector::const_iterator ki(keys.begin());
  119. ensure_equals(*ki++, "one");
  120. ensure_equals(*ki++, "three");
  121. ensure_equals(*ki++, "two");
  122. // Use ensure() here because ensure_equals would want to display
  123. // mismatched values, and frankly that wouldn't help much.
  124. ensure("didn't reach end", ki == keys.end());
  125. // Use a somewhat different approach to order independence with
  126. // beginInstances(): explicitly capture the instances we know in a
  127. // set, and delete them as we iterate through.
  128. typedef std::set<Keyed*> InstanceSet;
  129. InstanceSet instances;
  130. instances.insert(&one);
  131. instances.insert(&two);
  132. instances.insert(&three);
  133. for (Keyed::instance_iter ii(Keyed::beginInstances()), iend(Keyed::endInstances());
  134. ii != iend; ++ii)
  135. {
  136. Keyed& ref = *ii;
  137. ensure_equals("spurious instance", instances.erase(&ref), 1);
  138. }
  139. ensure_equals("unreported instance", instances.size(), 0);
  140. }
  141. template<> template<>
  142. void object::test<4>()
  143. {
  144. Unkeyed one, two, three;
  145. typedef std::set<Unkeyed*> KeySet;
  146. KeySet instances;
  147. instances.insert(&one);
  148. instances.insert(&two);
  149. instances.insert(&three);
  150. for (Unkeyed::instance_iter ii(Unkeyed::beginInstances()), iend(Unkeyed::endInstances()); ii != iend; ++ii)
  151. {
  152. Unkeyed& ref = *ii;
  153. ensure_equals("spurious instance", instances.erase(&ref), 1);
  154. }
  155. ensure_equals("unreported instance", instances.size(), 0);
  156. }
  157. template<> template<>
  158. void object::test<5>()
  159. {
  160. set_test_name("delete Keyed with outstanding instance_iter");
  161. std::string what;
  162. Keyed* keyed = new Keyed("one");
  163. {
  164. WrapLL_ERRS wrapper;
  165. Keyed::instance_iter i(Keyed::beginInstances());
  166. try
  167. {
  168. delete keyed;
  169. }
  170. catch (const WrapLL_ERRS::FatalException& e)
  171. {
  172. what = e.what();
  173. }
  174. }
  175. ensure(! what.empty());
  176. }
  177. template<> template<>
  178. void object::test<6>()
  179. {
  180. set_test_name("delete Keyed with outstanding key_iter");
  181. std::string what;
  182. Keyed* keyed = new Keyed("one");
  183. {
  184. WrapLL_ERRS wrapper;
  185. Keyed::key_iter i(Keyed::beginKeys());
  186. try
  187. {
  188. delete keyed;
  189. }
  190. catch (const WrapLL_ERRS::FatalException& e)
  191. {
  192. what = e.what();
  193. }
  194. }
  195. ensure(! what.empty());
  196. }
  197. template<> template<>
  198. void object::test<7>()
  199. {
  200. set_test_name("delete Unkeyed with outstanding instance_iter");
  201. std::string what;
  202. Unkeyed* unkeyed = new Unkeyed;
  203. {
  204. WrapLL_ERRS wrapper;
  205. Unkeyed::instance_iter i(Unkeyed::beginInstances());
  206. try
  207. {
  208. delete unkeyed;
  209. }
  210. catch (const WrapLL_ERRS::FatalException& e)
  211. {
  212. what = e.what();
  213. }
  214. }
  215. ensure(! what.empty());
  216. }
  217. } // namespace tut