ClassLoaderTest.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. //
  2. // ClassLoaderTest.cpp
  3. //
  4. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  5. // and Contributors.
  6. //
  7. // SPDX-License-Identifier: BSL-1.0
  8. //
  9. #include "ClassLoaderTest.h"
  10. #include "CppUnit/TestCaller.h"
  11. #include "CppUnit/TestSuite.h"
  12. #include "Poco/ClassLoader.h"
  13. #include "Poco/Manifest.h"
  14. #include "Poco/Exception.h"
  15. #include "Poco/Path.h"
  16. #include "Poco/File.h"
  17. #include "Poco/Format.h"
  18. #include "TestPlugin.h"
  19. using Poco::ClassLoader;
  20. using Poco::Manifest;
  21. using Poco::SharedLibrary;
  22. using Poco::AbstractMetaObject;
  23. using Poco::NotFoundException;
  24. using Poco::InvalidAccessException;
  25. using Poco::Path;
  26. using Poco::File;
  27. ClassLoaderTest::ClassLoaderTest(const std::string& name): CppUnit::TestCase(name)
  28. {
  29. }
  30. ClassLoaderTest::~ClassLoaderTest()
  31. {
  32. }
  33. void ClassLoaderTest::testClassLoader1()
  34. {
  35. std::string libraryPath = getFullName("TestLibrary");
  36. ClassLoader<TestPlugin> cl;
  37. assertTrue (cl.begin() == cl.end());
  38. assertNullPtr (cl.findClass("PluginA"));
  39. assertNullPtr (cl.findManifest(libraryPath));
  40. assertTrue (!cl.isLibraryLoaded(libraryPath));
  41. try
  42. {
  43. const ClassLoader<TestPlugin>::Meta& POCO_UNUSED meta = cl.classFor("PluginA");
  44. fail("not found - must throw exception");
  45. }
  46. catch (NotFoundException&)
  47. {
  48. }
  49. catch (...)
  50. {
  51. failmsg("wrong exception");
  52. }
  53. try
  54. {
  55. const ClassLoader<TestPlugin>::Manif& POCO_UNUSED manif = cl.manifestFor(libraryPath);
  56. fail("not found - must throw exception");
  57. }
  58. catch (NotFoundException&)
  59. {
  60. }
  61. catch (...)
  62. {
  63. failmsg("wrong exception");
  64. }
  65. }
  66. void ClassLoaderTest::testClassLoader2()
  67. {
  68. std::string libraryPath = getFullName("TestLibrary");
  69. ClassLoader<TestPlugin> cl;
  70. cl.loadLibrary(libraryPath);
  71. assertTrue (cl.begin() != cl.end());
  72. assertNotNullPtr (cl.findClass("PluginA"));
  73. assertNotNullPtr (cl.findClass("PluginB"));
  74. assertNotNullPtr (cl.findClass("PluginC"));
  75. assertNotNullPtr (cl.findManifest(libraryPath));
  76. assertTrue (cl.isLibraryLoaded(libraryPath));
  77. assertTrue (cl.manifestFor(libraryPath).size() == 3);
  78. ClassLoader<TestPlugin>::Iterator it = cl.begin();
  79. assertTrue (it != cl.end());
  80. assertTrue (it->first == libraryPath);
  81. assertTrue (it->second->size() == 3);
  82. ++it;
  83. assertTrue (it == cl.end());
  84. TestPlugin* pPluginA = cl.classFor("PluginA").create();
  85. assertTrue (pPluginA->name() == "PluginA");
  86. assertTrue (!cl.classFor("PluginA").isAutoDelete(pPluginA));
  87. delete pPluginA;
  88. TestPlugin* pPluginB = cl.classFor("PluginB").create();
  89. assertTrue (pPluginB->name() == "PluginB");
  90. delete pPluginB;
  91. pPluginB = cl.create("PluginB");
  92. assertTrue (pPluginB->name() == "PluginB");
  93. delete pPluginB;
  94. assertTrue (cl.canCreate("PluginA"));
  95. assertTrue (cl.canCreate("PluginB"));
  96. assertTrue (!cl.canCreate("PluginC"));
  97. TestPlugin& pluginC = cl.instance("PluginC");
  98. assertTrue (pluginC.name() == "PluginC");
  99. try
  100. {
  101. TestPlugin& POCO_UNUSED plgB = cl.instance("PluginB");
  102. fail("not a singleton - must throw");
  103. }
  104. catch (InvalidAccessException&)
  105. {
  106. }
  107. try
  108. {
  109. TestPlugin* POCO_UNUSED pPluginC = cl.create("PluginC");
  110. fail("cannot create a singleton - must throw");
  111. }
  112. catch (InvalidAccessException&)
  113. {
  114. }
  115. try
  116. {
  117. const AbstractMetaObject<TestPlugin>& meta = cl.classFor("PluginC");
  118. meta.autoDelete(&(meta.instance()));
  119. fail("cannot take ownership of a singleton - must throw");
  120. }
  121. catch (InvalidAccessException&)
  122. {
  123. }
  124. const AbstractMetaObject<TestPlugin>& meta1 = cl.classFor("PluginC");
  125. assertTrue (meta1.isAutoDelete(&(meta1.instance())));
  126. // the following must not produce memory leaks
  127. const AbstractMetaObject<TestPlugin>& meta2 = cl.classFor("PluginA");
  128. meta2.autoDelete(meta2.create());
  129. meta2.autoDelete(meta2.create());
  130. TestPlugin* pPlugin = meta2.create();
  131. meta2.autoDelete(pPlugin);
  132. assertTrue (meta2.isAutoDelete(pPlugin));
  133. meta2.destroy(pPlugin);
  134. assertTrue (!meta2.isAutoDelete(pPlugin));
  135. cl.unloadLibrary(libraryPath);
  136. }
  137. void ClassLoaderTest::testClassLoader3()
  138. {
  139. std::string libraryPath = getFullName("TestLibrary");
  140. ClassLoader<TestPlugin> cl;
  141. cl.loadLibrary(libraryPath);
  142. cl.loadLibrary(libraryPath);
  143. cl.unloadLibrary(libraryPath);
  144. assertTrue (cl.manifestFor(libraryPath).size() == 3);
  145. ClassLoader<TestPlugin>::Iterator it = cl.begin();
  146. assertTrue (it != cl.end());
  147. assertTrue (it->first == libraryPath);
  148. assertTrue (it->second->size() == 3);
  149. ++it;
  150. assertTrue (it == cl.end());
  151. cl.unloadLibrary(libraryPath);
  152. assertNullPtr (cl.findManifest(libraryPath));
  153. }
  154. std::string ClassLoaderTest::getFullName(const std::string& libName)
  155. {
  156. std::string name = Path::expand("$POCO_BASE");
  157. char c = Path::separator();
  158. std::string OSNAME = Path::expand("$OSNAME");
  159. std::string OSARCH = Path::expand("$OSARCH");
  160. name.append(1, c)
  161. .append(Poco::format("Foundation%ctestsuite%cbin%c", c, c, c))
  162. .append(Poco::format("%s%c%s%c", OSNAME, c, OSARCH, c))
  163. .append(libName).append(SharedLibrary::suffix());
  164. // CMake
  165. if (!File(name).exists())
  166. {
  167. name = Path::expand("$POCO_BASE");
  168. name.append(Poco::format("%ccmake-build%cbin%c", c, c, c))
  169. .append(libName).append(SharedLibrary::suffix());
  170. }
  171. if (!File(name).exists())
  172. name = libName + SharedLibrary::suffix();
  173. return name;
  174. }
  175. void ClassLoaderTest::setUp()
  176. {
  177. }
  178. void ClassLoaderTest::tearDown()
  179. {
  180. }
  181. CppUnit::Test* ClassLoaderTest::suite()
  182. {
  183. CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ClassLoaderTest");
  184. CppUnit_addTest(pSuite, ClassLoaderTest, testClassLoader1);
  185. CppUnit_addTest(pSuite, ClassLoaderTest, testClassLoader2);
  186. CppUnit_addTest(pSuite, ClassLoaderTest, testClassLoader3);
  187. return pSuite;
  188. }