1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sal.hxx" 26 27 //------------------------------------------------------------------------ 28 // include files 29 //------------------------------------------------------------------------ 30 #include <osl_Module_Const.h> 31 #include "gtest/gtest.h" 32 33 using namespace osl; 34 using namespace rtl; 35 36 37 //------------------------------------------------------------------------ 38 // helper functions and classes 39 //------------------------------------------------------------------------ 40 41 /** print Boolean value. 42 */ 43 inline void printBool( sal_Bool bOk ) 44 { 45 printf("#printBool# " ); 46 ( sal_True == bOk ) ? printf("TRUE!\n" ): printf("FALSE!\n" ); 47 } 48 49 /** print a UNI_CODE String. 50 */ 51 inline void printUString( const ::rtl::OUString & str ) 52 { 53 rtl::OString aString; 54 55 printf("#printUString_u# " ); 56 aString = ::rtl::OUStringToOString( str, RTL_TEXTENCODING_ASCII_US ); 57 printf("%s\n", aString.getStr( ) ); 58 } 59 60 /** get dll file URL. 61 */ 62 inline ::rtl::OUString getDllURL( void ) 63 { 64 #if ( defined WNT ) // lib in Unix and lib in Windows are not same in file name. 65 ::rtl::OUString libPath( rtl::OUString::createFromAscii( "Module_DLL.dll" ) ); 66 #else 67 ::rtl::OUString libPath( rtl::OUString::createFromAscii( "libModule_DLL.so" ) ); 68 #endif 69 70 ::rtl::OUString dirPath, dllPath; 71 osl::Module::getUrlFromAddress( ( void* ) &getDllURL, dirPath ); 72 // file:///aoo/main/sal/unx/bin/osl_Module 73 dirPath = dirPath.copy( 0, dirPath.lastIndexOf('/')); 74 // file:///aoo/main/sal/unx/bin 75 dirPath = dirPath.copy( 0, dirPath.lastIndexOf('/') + 1); 76 // file:///aoo/main/sal/unx/ 77 dirPath = dirPath + rtl::OUString::createFromAscii( "lib/" ); 78 // file:///aoo/main/sal/unx/lib/ 79 osl::FileBase::getAbsoluteFileURL( dirPath, libPath, dllPath ); 80 81 rtl::OString aOString = ::rtl::OUStringToOString (dllPath, RTL_TEXTENCODING_UTF8); 82 printf("getDllURL() returning %s\n", aOString.getStr()); 83 return dllPath; 84 } 85 86 /** print a UNI_CODE file name. 87 */ 88 inline void printFileName( const ::rtl::OUString & str ) 89 { 90 rtl::OString aString; 91 92 printf("#printFileName_u# " ); 93 aString = ::rtl::OUStringToOString( str, RTL_TEXTENCODING_ASCII_US ); 94 printf("%s\n", aString.getStr( ) ); 95 } 96 97 inline sal_Bool isURL( const ::rtl::OUString pathname ) 98 { 99 ::rtl::OUString aPreURL( rtl::OUString::createFromAscii( "file:///" ) ); 100 return ( ( pathname.indexOf( aPreURL ) == 0 ) ? sal_True : sal_False ); 101 } 102 103 /** create a temp test directory using OUString name of full qualified URL or system path. 104 */ 105 inline void createTestDirectory( const ::rtl::OUString dirname ) 106 { 107 ::rtl::OUString aPathURL = dirname.copy( 0 ); 108 ::osl::FileBase::RC nError; 109 110 if ( !isURL( dirname ) ) 111 ::osl::FileBase::getFileURLFromSystemPath( dirname, aPathURL ); //convert if not full qualified URL 112 nError = ::osl::Directory::create( aPathURL ); 113 ASSERT_TRUE(( ::osl::FileBase::E_None == nError ) || ( nError == ::osl::FileBase::E_EXIST )) << "In createTestDirectory Function: creation: "; 114 } 115 116 /** delete a temp test directory using OUString name of full qualified URL or system path. 117 */ 118 inline void deleteTestDirectory( const ::rtl::OUString dirname ) 119 { 120 ::rtl::OUString aPathURL = dirname.copy( 0 ); 121 ::osl::FileBase::RC nError; 122 if ( !isURL( dirname ) ) 123 ::osl::FileBase::getFileURLFromSystemPath( dirname, aPathURL ); //convert if not full qualified URL 124 125 ::osl::Directory testDir( aPathURL ); 126 if ( testDir.isOpen( ) == sal_True ) 127 { 128 testDir.close( ); //close if still open. 129 } 130 131 nError = ::osl::Directory::remove( aPathURL ); 132 ASSERT_TRUE(( ::osl::FileBase::E_None == nError ) || ( nError == ::osl::FileBase::E_NOENT )) << "In deleteTestDirectory function: remove "; 133 } 134 135 //check if the file exist 136 inline sal_Bool ifFileExist( const ::rtl::OUString & str ) 137 { 138 ::rtl::OUString aUStr; 139 if ( isURL( str ) ) 140 ::osl::FileBase::getSystemPathFromFileURL( str, aUStr ); 141 else 142 return sal_False; 143 144 ::osl::File strFile( aUStr ); 145 ::osl::FileBase::RC nError = strFile.open( OpenFlag_Read ); 146 if ( ::File::E_NOENT == nError ) 147 return sal_False; 148 else{ 149 strFile.close( ); 150 return sal_True; 151 } 152 } 153 154 /** detete a temp test file using OUString name. 155 */ 156 inline void deleteTestFile( const ::rtl::OUString filename ) 157 { 158 ::rtl::OUString aPathURL = filename.copy( 0 ); 159 ::osl::FileBase::RC nError; 160 161 if ( !isURL( filename ) ) 162 ::osl::FileBase::getFileURLFromSystemPath( filename, aPathURL ); //convert if not full qualified URL 163 164 nError = ::osl::File::setAttributes( aPathURL, Attribute_GrpWrite| Attribute_OwnWrite| Attribute_OthWrite ); // if readonly, make writtenable. 165 ASSERT_TRUE(( ::osl::FileBase::E_None == nError ) || ( ::osl::FileBase::E_NOENT == nError )) << "In deleteTestFile Function: set writtenable "; 166 167 nError = ::osl::File::remove( aPathURL ); 168 ASSERT_TRUE(( ::osl::FileBase::E_None == nError ) || ( nError == ::osl::FileBase::E_NOENT )) << "In deleteTestFile Function: remove "; 169 } 170 171 172 //------------------------------------------------------------------------ 173 // test code start here 174 //------------------------------------------------------------------------ 175 176 namespace osl_Module 177 { 178 179 /** class and member function that is available for module test : 180 */ 181 182 class testClass 183 { 184 public: 185 static void myFunc() 186 { 187 printf("#Sun Microsystem\n"); 188 }; 189 }; 190 191 192 /** testing the methods: 193 Module(); 194 Module( const ::rtl::OUString& strModuleName, sal_Int32 nRtldMode = SAL_LOADMODULE_DEFAULT); 195 */ 196 class ctors : public ::testing::Test 197 { 198 public: 199 sal_Bool bRes, bRes1; 200 }; // class ctors 201 202 203 TEST_F(ctors, ctors_none) 204 { 205 ::osl::Module aMod; 206 bRes = aMod.is(); 207 208 ASSERT_TRUE( sal_False == bRes ) << "#test comment#: test constructor without parameter."; 209 } 210 211 TEST_F(ctors, ctors_name_mode) 212 { 213 ::osl::Module aMod( getDllURL( ) ); 214 bRes = aMod.is( ); 215 aMod.unload( ); 216 217 ASSERT_TRUE( sal_True == bRes ) << "#test comment#: test constructor with load action."; 218 } 219 220 /** testing the methods: 221 static sal_Bool getUrlFromAddress(void * addr, ::rtl::OUString & libraryUrl) 222 */ 223 class getUrlFromAddress : public ::testing::Test 224 { 225 public: 226 sal_Bool bRes, bRes1; 227 }; // class getUrlFromAddress 228 229 /* tester comments: another case is getFunctionSymbol_001*/ 230 231 TEST_F(getUrlFromAddress, getUrlFromAddress_001 ) 232 { 233 OUString aFileURL; 234 bRes = osl::Module::getUrlFromAddress( ( void* ) &::osl_Module::testClass::myFunc, aFileURL ) ; 235 if ( !( bRes ) ) 236 { 237 ASSERT_TRUE(sal_False) << "Cannot locate current module."; 238 } 239 240 ASSERT_TRUE(sal_True == bRes && 0 < aFileURL.lastIndexOf('/')) << "#test comment#: test get Module URL from address."; 241 } 242 243 TEST_F(getUrlFromAddress, getUrlFromAddress_002 ) 244 { 245 ::osl::Module aMod( getDllURL( ) ); 246 FuncPtr pFunc = ( FuncPtr ) aMod.getSymbol( rtl::OUString::createFromAscii( "firstfunc" ) ); 247 248 OUString aFileURL; 249 bRes = osl::Module::getUrlFromAddress( ( void* )pFunc, aFileURL ); 250 if ( !( bRes ) ) 251 { 252 ASSERT_TRUE(sal_False) << "Cannot locate current module."; 253 } 254 aMod.unload( ); 255 256 ASSERT_TRUE( sal_True == bRes && 0 < aFileURL.lastIndexOf('/') && aFileURL.equalsIgnoreAsciiCase( getDllURL( ) ) ) 257 << "#test comment#: load an external library, get its function address and get its URL."; 258 } 259 260 /** testing the method: 261 sal_Bool SAL_CALL load( const ::rtl::OUString& strModuleName, 262 sal_Int32 nRtldMode = SAL_LOADMODULE_DEFAULT) 263 */ 264 class load : public ::testing::Test 265 { 266 public: 267 sal_Bool bRes, bRes1; 268 }; // class load 269 270 TEST_F(load, load_001 ) 271 { 272 ::osl::Module aMod( getDllURL( ) ); 273 ::osl::Module aMod1; 274 275 aMod1.load( getDllURL( ) ); 276 bRes = oslModule(aMod) == oslModule(aMod1); 277 aMod.unload( ); 278 aMod1.unload( ); 279 280 ASSERT_TRUE(sal_True == bRes) << "#test comment#: load function should do the same thing as constructor with library name."; 281 } 282 // load lib which is under a CJK directory 283 TEST_F(load, load_002 ) 284 { 285 #ifdef UNX 286 //Can not get a CJK directory already exist, so here create one. Perhaps reason is encoding problem. 287 ::rtl::OUString aPidDirURL = rtl::OUString::createFromAscii( "file:///tmp/" ) + ::rtl::OUString::valueOf( ( long )getpid( ) ); 288 ::rtl::OUString aMyDirURL = aPidDirURL + aKname; 289 createTestDirectory( aPidDirURL ); 290 createTestDirectory( aMyDirURL ); 291 292 ::rtl::OUString aDLLURL = aMyDirURL + rtl::OUString::createFromAscii( "/libModule_DLL.so" ); 293 //check if the lib exist. 294 //FIXME: if assert condition is false, the case will return, so the directory will not be clean-up 295 ASSERT_TRUE(ifFileExist( getDllURL( ) ) == sal_True) << "#Source file is not exist. please manually clean-up directory and file under /tmp"; 296 ::osl::FileBase::RC nError = ::osl::File::copy( getDllURL( ), aDLLURL ); 297 ASSERT_TRUE(nError == ::osl::FileBase::E_None) << "#copy failed. please manually clean-up directory and file under /tmp"; 298 //ifFileExist returned false but the file exist 299 ASSERT_TRUE( ifFileExist( aDLLURL ) == sal_True ) 300 << "#This file is not exist, copy failed. please manually clean-up directory and file under /tmp"; 301 302 //test if can create a normal file 303 ::rtl::OUString aFileURL = aMyDirURL + rtl::OUString::createFromAscii( "/test_file" ); 304 ::osl::File testFile( aFileURL ); 305 nError = testFile.open( OpenFlag_Create ); 306 ASSERT_TRUE(nError == ::osl::FileBase::E_None) << "#create failed. please manually clean-up directory and file under /tmp"; 307 ASSERT_TRUE( ifFileExist( aFileURL ) == sal_True ) 308 << "#This file is not exist, create failed. please manually clean-up directory and file under /tmp"; 309 310 //load the copied dll 311 ::osl::Module aMod( aDLLURL ); 312 ::osl::Module aMod1; 313 314 sal_Bool bOK = aMod1.load( aDLLURL ); 315 bRes = oslModule(aMod) == oslModule(aMod1); 316 aMod.unload( ); 317 aMod1.unload( ); 318 deleteTestFile( aFileURL ); 319 deleteTestFile( aDLLURL ); 320 deleteTestDirectory( aMyDirURL ); 321 deleteTestDirectory( aPidDirURL ); 322 323 ASSERT_TRUE(sal_True == bRes && bOK == sal_True) << "#test comment#: load lib which is under a CJK directory."; 324 #endif 325 } 326 327 /** testing the method: 328 void SAL_CALL unload() 329 */ 330 class unload : public ::testing::Test 331 { 332 public: 333 sal_Bool bRes, bRes1; 334 }; // class unload 335 336 TEST_F(unload, unload_001) 337 { 338 ::osl::Module aMod( getDllURL( ) ); 339 340 aMod.unload( ); 341 bRes = oslModule(aMod) ==NULL; 342 343 ASSERT_TRUE(sal_True == bRes) << "#test comment#: unload function should do the same thing as destructor."; 344 } 345 346 /** testing the methods: 347 sal_Bool SAL_CALL is() const 348 */ 349 class is : public ::testing::Test 350 { 351 public: 352 sal_Bool bRes, bRes1; 353 }; // class is 354 355 TEST_F(is, is_001) 356 { 357 ::osl::Module aMod; 358 bRes = aMod.is( ); 359 aMod.load( getDllURL( ) ); 360 bRes1 = aMod.is( ); 361 aMod.unload( ); 362 363 ASSERT_TRUE(sal_False == bRes && sal_True == bRes1) << "#test comment#: test if a module is a loaded module."; 364 } 365 366 /** testing the methods: 367 void* SAL_CALL getSymbol( const ::rtl::OUString& strSymbolName) 368 */ 369 class getSymbol : public ::testing::Test 370 { 371 public: 372 sal_Bool bRes; 373 }; // class getSymbol 374 375 TEST_F(getSymbol, getSymbol_001) 376 { 377 ::osl::Module aMod( getDllURL( ) ); 378 FuncPtr pFunc = ( FuncPtr ) aMod.getSymbol( rtl::OUString::createFromAscii( "firstfunc" ) ); 379 bRes = sal_False; 380 if ( pFunc ) 381 bRes = pFunc( bRes ); 382 aMod.unload(); 383 384 ASSERT_TRUE(sal_True == bRes) << "#test comment#: load a dll and call one function in it."; 385 } 386 387 /** testing the methods: 388 operator oslModule() const 389 */ 390 class optr_oslModule : public ::testing::Test 391 { 392 public: 393 sal_Bool bRes, bRes1; 394 }; // class optr_oslModule 395 396 TEST_F(optr_oslModule, optr_oslModule_001 ) 397 { 398 ::osl::Module aMod; 399 bRes = ( (oslModule)aMod == NULL ); 400 401 aMod.load( getDllURL( ) ); 402 bRes1 = (oslModule)aMod != NULL; 403 404 aMod.unload( ); 405 406 ASSERT_TRUE(sal_True == bRes && sal_True == bRes1) 407 << "#test comment#: the m_Module of a Module instance will be NULL when is not loaded, it will not be NULL after loaded."; 408 } 409 410 TEST_F(optr_oslModule, optr_oslModule_002 ) 411 { 412 ::osl::Module aMod( getDllURL( ) ); 413 ::rtl::OUString funcName(::rtl::OUString::createFromAscii( "firstfunc" ) ); 414 415 FuncPtr pFunc = ( FuncPtr ) osl_getSymbol( (oslModule)aMod, funcName.pData ); 416 bRes = sal_False; 417 if ( pFunc ) 418 bRes = pFunc( bRes ); 419 420 aMod.unload(); 421 422 ASSERT_TRUE(sal_True == bRes) << "#test comment#: use m_Module to call osl_getSymbol() function."; 423 } 424 425 /** testing the methods: 426 oslGenericFunction SAL_CALL getFunctionSymbol( const ::rtl::OUString& ustrFunctionSymbolName ) 427 */ 428 class getFunctionSymbol : public ::testing::Test 429 { 430 public: 431 sal_Bool bRes, bRes1; 432 }; // class getFunctionSymbol 433 434 TEST_F(getFunctionSymbol, getFunctionSymbol_001) 435 { 436 ::osl::Module aMod( getDllURL( ) ); 437 oslGenericFunction oslFunc = aMod.getFunctionSymbol( rtl::OUString::createFromAscii( "firstfunc" ) ); 438 ::rtl::OUString aLibraryURL; 439 bRes = ::osl::Module::getUrlFromAddress( oslFunc, aLibraryURL); 440 aMod.unload(); 441 printFileName( aLibraryURL ); 442 443 ASSERT_TRUE(sal_True == bRes && aLibraryURL.equalsIgnoreAsciiCase( getDllURL() )) << "#test comment#: load a dll and get its function addr and get its URL."; 444 } 445 446 } // namespace osl_Module 447 448 int main(int argc, char **argv) 449 { 450 ::testing::InitGoogleTest(&argc, argv); 451 return RUN_ALL_TESTS(); 452 } 453