Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <boost/thread.hpp>
00031 #include <boost/bind.hpp>
00032 #include <iostream>
00033 #include <string>
00034 #include <vector>
00035
00036 #include "class_loader/class_loader.hpp"
00037 #include "class_loader/multi_library_class_loader.hpp"
00038
00039 #include "gtest/gtest.h"
00040
00041 #include "./base.hpp"
00042
00043 const char LIBRARY_1[] = "libclass_loader_TestPlugins1.so";
00044 const char LIBRARY_2[] = "libclass_loader_TestPlugins2.so";
00045
00046
00047 TEST(ClassLoaderTest, basicLoad) {
00048 try {
00049 class_loader::ClassLoader loader1(LIBRARY_1, false);
00050 loader1.createInstance<Base>("Cat")->saySomething();
00051 } catch (class_loader::ClassLoaderException & e) {
00052 FAIL() << "ClassLoaderException: " << e.what() << "\n";
00053 }
00054
00055 SUCCEED();
00056 }
00057
00058
00059 TEST(ClassLoaderTest, correctNonLazyLoadUnload) {
00060 try {
00061 ASSERT_FALSE(class_loader::class_loader_private::isLibraryLoadedByAnybody(LIBRARY_1));
00062 class_loader::ClassLoader loader1(LIBRARY_1, false);
00063 ASSERT_TRUE(class_loader::class_loader_private::isLibraryLoadedByAnybody(LIBRARY_1));
00064 ASSERT_TRUE(loader1.isLibraryLoaded());
00065 loader1.unloadLibrary();
00066 ASSERT_FALSE(class_loader::class_loader_private::isLibraryLoadedByAnybody(LIBRARY_1));
00067 ASSERT_FALSE(loader1.isLibraryLoaded());
00068 return;
00069 } catch (class_loader::ClassLoaderException & e) {
00070 FAIL() << "ClassLoaderException: " << e.what() << "\n";
00071 } catch (...) {
00072 FAIL() << "Unhandled exception";
00073 }
00074 }
00075
00076
00077 TEST(ClassLoaderTest, correctLazyLoadUnload) {
00078 try {
00079 ASSERT_FALSE(class_loader::class_loader_private::isLibraryLoadedByAnybody(LIBRARY_1));
00080 class_loader::ClassLoader loader1(LIBRARY_1, true);
00081 ASSERT_FALSE(class_loader::class_loader_private::isLibraryLoadedByAnybody(LIBRARY_1));
00082 ASSERT_FALSE(loader1.isLibraryLoaded());
00083
00084 {
00085 boost::shared_ptr<Base> obj = loader1.createInstance<Base>("Cat");
00086 ASSERT_TRUE(class_loader::class_loader_private::isLibraryLoadedByAnybody(LIBRARY_1));
00087 ASSERT_TRUE(loader1.isLibraryLoaded());
00088 }
00089
00090
00091 ASSERT_FALSE(class_loader::class_loader_private::isLibraryLoadedByAnybody(LIBRARY_1));
00092 return;
00093 } catch (class_loader::ClassLoaderException & e) {
00094 FAIL() << "ClassLoaderException: " << e.what() << "\n";
00095 } catch (...) {
00096 FAIL() << "Unhandled exception";
00097 }
00098 }
00099
00100
00101
00102 TEST(ClassLoaderTest, nonExistentPlugin) {
00103 class_loader::ClassLoader loader1(LIBRARY_1, false);
00104
00105 try {
00106 boost::shared_ptr<Base> obj = loader1.createInstance<Base>("Bear");
00107 if (NULL == obj) {
00108 FAIL() << "Null object being returned instead of exception thrown.";
00109 }
00110
00111 obj->saySomething();
00112 } catch (const class_loader::CreateClassException &) {
00113 SUCCEED();
00114 return;
00115 } catch (...) {
00116 FAIL() << "Unknown exception caught.\n";
00117 }
00118
00119 FAIL() << "Did not throw exception as expected.\n";
00120 }
00121
00122
00123 TEST(ClassLoaderTest, nonExistentLibrary) {
00124 try {
00125 class_loader::ClassLoader loader1("libDoesNotExist.so", false);
00126 } catch (const class_loader::LibraryLoadException &) {
00127 SUCCEED();
00128 return;
00129 } catch (...) {
00130 FAIL() << "Unknown exception caught.\n";
00131 }
00132
00133 FAIL() << "Did not throw exception as expected.\n";
00134 }
00135
00136
00137
00138 class InvalidBase
00139 {
00140 };
00141
00142 TEST(ClassLoaderTest, invalidBase) {
00143 try {
00144 class_loader::ClassLoader loader1(LIBRARY_1, false);
00145 if (loader1.isClassAvailable<InvalidBase>("Cat")) {
00146 FAIL() << "Cat should not be available for InvalidBase";
00147 } else if (loader1.isClassAvailable<Base>("Cat")) {
00148 SUCCEED();
00149 return;
00150 } else {
00151 FAIL() << "Class not available for correct base class.";
00152 }
00153 } catch (const class_loader::LibraryLoadException &) {
00154 FAIL() << "Unexpected exception";
00155 } catch (...) {
00156 FAIL() << "Unexpected and unknown exception caught.\n";
00157 }
00158 }
00159
00160
00161
00162 void wait(int seconds)
00163 {
00164 boost::this_thread::sleep(boost::posix_time::seconds(seconds));
00165 }
00166
00167 void run(class_loader::ClassLoader * loader)
00168 {
00169 std::vector<std::string> classes = loader->getAvailableClasses<Base>();
00170 for (unsigned int c = 0; c < classes.size(); c++) {
00171 loader->createInstance<Base>(classes.at(c))->saySomething();
00172 }
00173 }
00174
00175 TEST(ClassLoaderTest, threadSafety) {
00176 class_loader::ClassLoader loader1(LIBRARY_1);
00177 ASSERT_TRUE(loader1.isLibraryLoaded());
00178
00179
00180
00181
00182 try {
00183 std::vector<boost::thread *> client_threads;
00184
00185 for (unsigned int c = 0; c < 1000; c++) {
00186 client_threads.push_back(new boost::thread(boost::bind(&run, &loader1)));
00187 }
00188
00189 for (unsigned int c = 0; c < client_threads.size(); c++) {
00190 client_threads.at(c)->join();
00191 }
00192
00193 for (unsigned int c = 0; c < client_threads.size(); c++) {
00194 delete (client_threads.at(c));
00195 }
00196
00197 loader1.unloadLibrary();
00198 ASSERT_FALSE(loader1.isLibraryLoaded());
00199 } catch (const class_loader::ClassLoaderException &) {
00200 FAIL() << "Unexpected ClassLoaderException.";
00201 } catch (...) {
00202 FAIL() << "Unknown exception.";
00203 }
00204 }
00205
00206
00207
00208 TEST(ClassLoaderTest, loadRefCountingNonLazy) {
00209 try {
00210 class_loader::ClassLoader loader1(LIBRARY_1, false);
00211 ASSERT_TRUE(loader1.isLibraryLoaded());
00212
00213 loader1.loadLibrary();
00214 loader1.loadLibrary();
00215 ASSERT_TRUE(loader1.isLibraryLoaded());
00216
00217 loader1.unloadLibrary();
00218 ASSERT_TRUE(loader1.isLibraryLoaded());
00219
00220 loader1.unloadLibrary();
00221 ASSERT_TRUE(loader1.isLibraryLoaded());
00222
00223 loader1.unloadLibrary();
00224 ASSERT_FALSE(loader1.isLibraryLoaded());
00225
00226 loader1.unloadLibrary();
00227 ASSERT_FALSE(loader1.isLibraryLoaded());
00228
00229 loader1.loadLibrary();
00230 ASSERT_TRUE(loader1.isLibraryLoaded());
00231
00232 return;
00233 } catch (const class_loader::ClassLoaderException &) {
00234 FAIL() << "Unexpected exception.\n";
00235 } catch (...) {
00236 FAIL() << "Unknown exception caught.\n";
00237 }
00238
00239 FAIL() << "Did not throw exception as expected.\n";
00240 }
00241
00242
00243
00244 TEST(ClassLoaderTest, loadRefCountingLazy) {
00245 try {
00246 class_loader::ClassLoader loader1(LIBRARY_1, true);
00247 ASSERT_FALSE(loader1.isLibraryLoaded());
00248
00249 {
00250 boost::shared_ptr<Base> obj = loader1.createInstance<Base>("Dog");
00251 ASSERT_TRUE(loader1.isLibraryLoaded());
00252 }
00253
00254 ASSERT_FALSE(loader1.isLibraryLoaded());
00255
00256 loader1.loadLibrary();
00257 ASSERT_TRUE(loader1.isLibraryLoaded());
00258
00259 loader1.loadLibrary();
00260 ASSERT_TRUE(loader1.isLibraryLoaded());
00261
00262 loader1.unloadLibrary();
00263 ASSERT_TRUE(loader1.isLibraryLoaded());
00264
00265 loader1.unloadLibrary();
00266 ASSERT_FALSE(loader1.isLibraryLoaded());
00267
00268 loader1.unloadLibrary();
00269 ASSERT_FALSE(loader1.isLibraryLoaded());
00270
00271 loader1.loadLibrary();
00272 ASSERT_TRUE(loader1.isLibraryLoaded());
00273
00274 return;
00275 } catch (const class_loader::ClassLoaderException &) {
00276 FAIL() << "Unexpected exception.\n";
00277 } catch (...) {
00278 FAIL() << "Unknown exception caught.\n";
00279 }
00280
00281 FAIL() << "Did not throw exception as expected.\n";
00282 }
00283
00284
00285
00286
00287 void testMultiClassLoader(bool lazy)
00288 {
00289 try {
00290 class_loader::MultiLibraryClassLoader loader(lazy);
00291 loader.loadLibrary(LIBRARY_1);
00292 loader.loadLibrary(LIBRARY_2);
00293 for (int i = 0; i < 2; ++i) {
00294 loader.createInstance<Base>("Cat")->saySomething();
00295 loader.createInstance<Base>("Dog")->saySomething();
00296 loader.createInstance<Base>("Robot")->saySomething();
00297 }
00298 } catch (class_loader::ClassLoaderException & e) {
00299 FAIL() << "ClassLoaderException: " << e.what() << "\n";
00300 }
00301
00302 SUCCEED();
00303 }
00304
00305 TEST(MultiClassLoaderTest, lazyLoad) {
00306 testMultiClassLoader(true);
00307 }
00308 TEST(MultiClassLoaderTest, lazyLoadSecondTime) {
00309 testMultiClassLoader(true);
00310 }
00311 TEST(MultiClassLoaderTest, nonLazyLoad) {
00312 testMultiClassLoader(false);
00313 }
00314 TEST(MultiClassLoaderTest, noWarningOnLazyLoad) {
00315 try {
00316 boost::shared_ptr<Base> cat, dog, rob;
00317 {
00318 class_loader::MultiLibraryClassLoader loader(true);
00319 loader.loadLibrary(LIBRARY_1);
00320 loader.loadLibrary(LIBRARY_2);
00321
00322 cat = loader.createInstance<Base>("Cat");
00323 dog = loader.createInstance<Base>("Dog");
00324 rob = loader.createInstance<Base>("Robot");
00325 }
00326 cat->saySomething();
00327 dog->saySomething();
00328 rob->saySomething();
00329 } catch (class_loader::ClassLoaderException & e) {
00330 FAIL() << "ClassLoaderException: " << e.what() << "\n";
00331 }
00332
00333 SUCCEED();
00334 }
00335
00336
00337
00338
00339 int main(int argc, char ** argv)
00340 {
00341 testing::InitGoogleTest(&argc, argv);
00342 return RUN_ALL_TESTS();
00343 }