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