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


class_loader
Author(s): Mirza Shah
autogenerated on Sun Oct 5 2014 22:50:57