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();
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
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
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
00304 int main(int argc, char **argv){
00305 testing::InitGoogleTest(&argc, argv);
00306 return RUN_ALL_TESTS();
00307 }
00308
00309