utest.cpp
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(); //See if lazy load works
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     //The library will unload automatically when the only plugin object left is destroyed
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   //Note: Hard to test thread safety to make sure memory isn't corrupted. The hope is this test is hard enough that once in a while it'll segfault or something if there's some implementation error.
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 // Run all the tests that were declared with TEST()
00366 int main(int argc, char **argv){
00367   testing::InitGoogleTest(&argc, argv);
00368   return RUN_ALL_TESTS();
00369 }
00370 
00371 


class_loader
Author(s): Mirza Shah
autogenerated on Fri Jul 28 2017 05:48:18