1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sal.hxx" 30 31 //------------------------------------------------------------------------ 32 // include files 33 //------------------------------------------------------------------------ 34 #include <osl_Module_Const.h> 35 36 using namespace osl; 37 using namespace rtl; 38 39 40 //------------------------------------------------------------------------ 41 // helper functions and classes 42 //------------------------------------------------------------------------ 43 44 /** print Boolean value. 45 */ 46 inline void printBool( sal_Bool bOk ) 47 { 48 t_print("#printBool# " ); 49 ( sal_True == bOk ) ? t_print("TRUE!\n" ): t_print("FALSE!\n" ); 50 } 51 52 /** print a UNI_CODE String. 53 */ 54 inline void printUString( const ::rtl::OUString & str ) 55 { 56 rtl::OString aString; 57 58 t_print("#printUString_u# " ); 59 aString = ::rtl::OUStringToOString( str, RTL_TEXTENCODING_ASCII_US ); 60 t_print("%s\n", aString.getStr( ) ); 61 } 62 63 /** get dll file URL. 64 */ 65 inline ::rtl::OUString getDllURL( void ) 66 { 67 #if ( defined WNT ) // lib in Unix and lib in Windows are not same in file name. 68 ::rtl::OUString libPath( rtl::OUString::createFromAscii( "Module_DLL.dll" ) ); 69 #else 70 ::rtl::OUString libPath( rtl::OUString::createFromAscii( "libModule_DLL.so" ) ); 71 #endif 72 73 ::rtl::OUString dirPath, dllPath; 74 osl::Module::getUrlFromAddress( ( void* ) &getDllURL, dirPath ); 75 dirPath = dirPath.copy( 0, dirPath.lastIndexOf('/') + 1); 76 osl::FileBase::getAbsoluteFileURL( dirPath, libPath, dllPath ); 77 78 return dllPath; 79 } 80 81 /** print a UNI_CODE file name. 82 */ 83 inline void printFileName( const ::rtl::OUString & str ) 84 { 85 rtl::OString aString; 86 87 t_print("#printFileName_u# " ); 88 aString = ::rtl::OUStringToOString( str, RTL_TEXTENCODING_ASCII_US ); 89 t_print("%s\n", aString.getStr( ) ); 90 } 91 92 inline sal_Bool isURL( const ::rtl::OUString pathname ) 93 { 94 ::rtl::OUString aPreURL( rtl::OUString::createFromAscii( "file:///" ) ); 95 return ( ( pathname.indexOf( aPreURL ) == 0 ) ? sal_True : sal_False ); 96 } 97 98 /** create a temp test directory using OUString name of full qualified URL or system path. 99 */ 100 inline void createTestDirectory( const ::rtl::OUString dirname ) 101 { 102 ::rtl::OUString aPathURL = dirname.copy( 0 ); 103 ::osl::FileBase::RC nError; 104 105 if ( !isURL( dirname ) ) 106 ::osl::FileBase::getFileURLFromSystemPath( dirname, aPathURL ); //convert if not full qualified URL 107 nError = ::osl::Directory::create( aPathURL ); 108 CPPUNIT_ASSERT_MESSAGE( "In createTestDirectory Function: creation: ", ( ::osl::FileBase::E_None == nError ) || ( nError == ::osl::FileBase::E_EXIST ) ); 109 } 110 111 /** delete a temp test directory using OUString name of full qualified URL or system path. 112 */ 113 inline void deleteTestDirectory( const ::rtl::OUString dirname ) 114 { 115 ::rtl::OUString aPathURL = dirname.copy( 0 ); 116 ::osl::FileBase::RC nError; 117 if ( !isURL( dirname ) ) 118 ::osl::FileBase::getFileURLFromSystemPath( dirname, aPathURL ); //convert if not full qualified URL 119 120 ::osl::Directory testDir( aPathURL ); 121 if ( testDir.isOpen( ) == sal_True ) 122 { 123 testDir.close( ); //close if still open. 124 } 125 126 nError = ::osl::Directory::remove( aPathURL ); 127 CPPUNIT_ASSERT_MESSAGE( "In deleteTestDirectory function: remove ", ( ::osl::FileBase::E_None == nError ) || ( nError == ::osl::FileBase::E_NOENT ) ); 128 } 129 130 //check if the file exist 131 inline sal_Bool ifFileExist( const ::rtl::OUString & str ) 132 { 133 ::rtl::OUString aUStr; 134 if ( isURL( str ) ) 135 ::osl::FileBase::getSystemPathFromFileURL( str, aUStr ); 136 else 137 return sal_False; 138 139 ::osl::File strFile( aUStr ); 140 ::osl::FileBase::RC nError = strFile.open( OpenFlag_Read ); 141 if ( ::File::E_NOENT == nError ) 142 return sal_False; 143 else{ 144 strFile.close( ); 145 return sal_True; 146 } 147 } 148 149 /** detete a temp test file using OUString name. 150 */ 151 inline void deleteTestFile( const ::rtl::OUString filename ) 152 { 153 ::rtl::OUString aPathURL = filename.copy( 0 ); 154 ::osl::FileBase::RC nError; 155 156 if ( !isURL( filename ) ) 157 ::osl::FileBase::getFileURLFromSystemPath( filename, aPathURL ); //convert if not full qualified URL 158 159 nError = ::osl::File::setAttributes( aPathURL, Attribute_GrpWrite| Attribute_OwnWrite| Attribute_OthWrite ); // if readonly, make writtenable. 160 CPPUNIT_ASSERT_MESSAGE( "In deleteTestFile Function: set writtenable ", ( ::osl::FileBase::E_None == nError ) || ( ::osl::FileBase::E_NOENT == nError ) ); 161 162 nError = ::osl::File::remove( aPathURL ); 163 CPPUNIT_ASSERT_MESSAGE( "In deleteTestFile Function: remove ", ( ::osl::FileBase::E_None == nError ) || ( nError == ::osl::FileBase::E_NOENT ) ); 164 } 165 166 167 //------------------------------------------------------------------------ 168 // test code start here 169 //------------------------------------------------------------------------ 170 171 namespace osl_Module 172 { 173 174 /** class and member function that is available for module test : 175 */ 176 177 class testClass 178 { 179 public: 180 static void myFunc() 181 { 182 t_print("#Sun Microsystem\n"); 183 }; 184 }; 185 186 187 /** testing the methods: 188 Module(); 189 Module( const ::rtl::OUString& strModuleName, sal_Int32 nRtldMode = SAL_LOADMODULE_DEFAULT); 190 */ 191 class ctors : public CppUnit::TestFixture 192 { 193 public: 194 sal_Bool bRes, bRes1; 195 196 void ctors_none( ) 197 { 198 ::osl::Module aMod; 199 bRes = aMod.is(); 200 201 CPPUNIT_ASSERT_MESSAGE( "#test comment#: test constructor without parameter.", 202 sal_False == bRes ); 203 } 204 205 void ctors_name_mode( ) 206 { 207 OUString aFileURL; 208 bRes = osl::Module::getUrlFromAddress( ( void* ) &::osl_Module::testClass::myFunc, aFileURL ); 209 210 if ( !( bRes ) ) 211 { 212 CPPUNIT_ASSERT_MESSAGE("Cannot locate current module.", sal_False ); 213 } 214 215 ::osl::Module aMod( aFileURL ); 216 bRes = aMod.is( ); 217 aMod.unload( ); 218 219 CPPUNIT_ASSERT_MESSAGE( "#test comment#: test constructor with load action.", 220 sal_True == bRes ); 221 } 222 223 CPPUNIT_TEST_SUITE( ctors ); 224 CPPUNIT_TEST( ctors_none ); 225 CPPUNIT_TEST( ctors_name_mode ); 226 CPPUNIT_TEST_SUITE_END( ); 227 }; // class ctors 228 229 230 /** testing the methods: 231 static sal_Bool getUrlFromAddress(void * addr, ::rtl::OUString & libraryUrl) 232 */ 233 class getUrlFromAddress : public CppUnit::TestFixture 234 { 235 public: 236 sal_Bool bRes, bRes1; 237 238 void getUrlFromAddress_001( ) 239 { 240 OUString aFileURL; 241 bRes = osl::Module::getUrlFromAddress( ( void* ) &::osl_Module::testClass::myFunc, aFileURL ) ; 242 if ( !( bRes ) ) 243 { 244 CPPUNIT_ASSERT_MESSAGE("Cannot locate current module.", sal_False ); 245 } 246 247 CPPUNIT_ASSERT_MESSAGE( "#test comment#: test get Module URL from address.", 248 sal_True == bRes && 0 < aFileURL.lastIndexOf('/') ); 249 } 250 251 void getUrlFromAddress_002( ) 252 { 253 ::osl::Module aMod( getDllURL( ) ); 254 FuncPtr pFunc = ( FuncPtr ) aMod.getSymbol( rtl::OUString::createFromAscii( "firstfunc" ) ); 255 256 OUString aFileURL; 257 bRes = osl::Module::getUrlFromAddress( ( void* )pFunc, aFileURL ); 258 if ( !( bRes ) ) 259 { 260 CPPUNIT_ASSERT_MESSAGE("Cannot locate current module.", sal_False ); 261 } 262 aMod.unload( ); 263 264 CPPUNIT_ASSERT_MESSAGE( "#test comment#: load an external library, get its function address and get its URL.", 265 sal_True == bRes && 0 < aFileURL.lastIndexOf('/') && aFileURL.equalsIgnoreAsciiCase( getDllURL( ) ) ); 266 } 267 268 /* tester comments: another case is getFunctionSymbol_001*/ 269 270 CPPUNIT_TEST_SUITE( getUrlFromAddress ); 271 CPPUNIT_TEST( getUrlFromAddress_001 ); 272 CPPUNIT_TEST( getUrlFromAddress_002 ); 273 CPPUNIT_TEST_SUITE_END( ); 274 }; // class getUrlFromAddress 275 276 277 /** testing the method: 278 sal_Bool SAL_CALL load( const ::rtl::OUString& strModuleName, 279 sal_Int32 nRtldMode = SAL_LOADMODULE_DEFAULT) 280 */ 281 class load : public CppUnit::TestFixture 282 { 283 public: 284 sal_Bool bRes, bRes1; 285 286 void load_001( ) 287 { 288 ::osl::Module aMod( getDllURL( ) ); 289 ::osl::Module aMod1; 290 291 aMod1.load( getDllURL( ) ); 292 bRes = oslModule(aMod) == oslModule(aMod1); 293 aMod.unload( ); 294 aMod1.unload( ); 295 296 CPPUNIT_ASSERT_MESSAGE( "#test comment#: load function should do the same thing as constructor with library name.", 297 sal_True == bRes ); 298 } 299 // load lib which is under a CJK directory 300 void load_002( ) 301 { 302 #ifdef UNX 303 //Can not get a CJK directory already exist, so here create one. Perhaps reason is encoding problem. 304 ::rtl::OUString aPidDirURL = rtl::OUString::createFromAscii( "file:///tmp/" ) + ::rtl::OUString::valueOf( ( long )getpid( ) ); 305 ::rtl::OUString aMyDirURL = aPidDirURL + aKname; 306 createTestDirectory( aPidDirURL ); 307 createTestDirectory( aMyDirURL ); 308 309 ::rtl::OUString aDLLURL = aMyDirURL + rtl::OUString::createFromAscii( "/libModule_DLL.so" ); 310 //check if the lib exist. 311 //FIXME: if assert condition is false, the case will return, so the directory will not be clean-up 312 CPPUNIT_ASSERT_MESSAGE( "#Source file is not exist. please manually clean-up directory and file under /tmp", ifFileExist( getDllURL( ) ) == sal_True ); 313 ::osl::FileBase::RC nError = ::osl::File::copy( getDllURL( ), aDLLURL ); 314 CPPUNIT_ASSERT_MESSAGE( "#copy failed. please manually clean-up directory and file under /tmp", nError == ::osl::FileBase::E_None ); 315 //ifFileExist returned false but the file exist 316 CPPUNIT_ASSERT_MESSAGE( "#This file is not exist, copy failed. please manually clean-up directory and file under /tmp", ifFileExist( aDLLURL ) == sal_True ); 317 318 //test if can create a normal file 319 ::rtl::OUString aFileURL = aMyDirURL + rtl::OUString::createFromAscii( "/test_file" ); 320 ::osl::File testFile( aFileURL ); 321 nError = testFile.open( OpenFlag_Create ); 322 CPPUNIT_ASSERT_MESSAGE( "#create failed. please manually clean-up directory and file under /tmp", nError == ::osl::FileBase::E_None ); 323 CPPUNIT_ASSERT_MESSAGE( "#This file is not exist, create failed. please manually clean-up directory and file under /tmp", ifFileExist( aFileURL ) == sal_True ); 324 325 //load the copied dll 326 ::osl::Module aMod( aDLLURL ); 327 ::osl::Module aMod1; 328 329 sal_Bool bOK = aMod1.load( aDLLURL ); 330 bRes = oslModule(aMod) == oslModule(aMod1); 331 aMod.unload( ); 332 aMod1.unload( ); 333 deleteTestFile( aFileURL ); 334 deleteTestFile( aDLLURL ); 335 deleteTestDirectory( aMyDirURL ); 336 deleteTestDirectory( aPidDirURL ); 337 338 CPPUNIT_ASSERT_MESSAGE( "#test comment#: load lib which is under a CJK directory.", 339 sal_True == bRes && bOK == sal_True ); 340 #endif 341 } 342 343 CPPUNIT_TEST_SUITE( load ); 344 CPPUNIT_TEST( load_001 ); 345 CPPUNIT_TEST( load_002 ); 346 CPPUNIT_TEST_SUITE_END( ); 347 }; // class load 348 349 350 /** testing the method: 351 void SAL_CALL unload() 352 */ 353 class unload : public CppUnit::TestFixture 354 { 355 public: 356 sal_Bool bRes, bRes1; 357 358 void unload_001( ) 359 { 360 ::osl::Module aMod( getDllURL( ) ); 361 362 aMod.unload( ); 363 bRes = oslModule(aMod) ==NULL; 364 365 CPPUNIT_ASSERT_MESSAGE( "#test comment#: unload function should do the same thing as destructor.", 366 sal_True == bRes ); 367 } 368 369 CPPUNIT_TEST_SUITE( unload ); 370 CPPUNIT_TEST( unload_001 ); 371 CPPUNIT_TEST_SUITE_END( ); 372 }; // class unload 373 374 375 /** testing the methods: 376 sal_Bool SAL_CALL is() const 377 */ 378 class is : public CppUnit::TestFixture 379 { 380 public: 381 sal_Bool bRes, bRes1; 382 383 void is_001( ) 384 { 385 OUString aFileURL; 386 bRes = osl::Module::getUrlFromAddress( ( void* ) &::osl_Module::testClass::myFunc, aFileURL ); 387 if ( !( bRes ) ) 388 { 389 CPPUNIT_ASSERT_MESSAGE("Cannot locate current module - using executable instead", sal_False ); 390 } 391 392 ::osl::Module aMod; 393 bRes = aMod.is( ); 394 aMod.load( aFileURL ); 395 bRes1 = aMod.is( ); 396 aMod.unload( ); 397 398 CPPUNIT_ASSERT_MESSAGE( "#test comment#: test if a module is a loaded module.", 399 sal_False == bRes && sal_True == bRes1); 400 } 401 CPPUNIT_TEST_SUITE( is ); 402 CPPUNIT_TEST( is_001 ); 403 CPPUNIT_TEST_SUITE_END( ); 404 }; // class is 405 406 407 /** testing the methods: 408 void* SAL_CALL getSymbol( const ::rtl::OUString& strSymbolName) 409 */ 410 class getSymbol : public CppUnit::TestFixture 411 { 412 public: 413 sal_Bool bRes; 414 415 void getSymbol_001( ) 416 { 417 ::osl::Module aMod( getDllURL( ) ); 418 FuncPtr pFunc = ( FuncPtr ) aMod.getSymbol( rtl::OUString::createFromAscii( "firstfunc" ) ); 419 bRes = sal_False; 420 if ( pFunc ) 421 bRes = pFunc( bRes ); 422 aMod.unload(); 423 424 CPPUNIT_ASSERT_MESSAGE( "#test comment#: load a dll and call one function in it.", 425 sal_True == bRes ); 426 } 427 428 CPPUNIT_TEST_SUITE( getSymbol ); 429 CPPUNIT_TEST( getSymbol_001 ); 430 CPPUNIT_TEST_SUITE_END( ); 431 }; // class getSymbol 432 433 434 /** testing the methods: 435 operator oslModule() const 436 */ 437 class optr_oslModule : public CppUnit::TestFixture 438 { 439 public: 440 sal_Bool bRes, bRes1; 441 442 void optr_oslModule_001( ) 443 { 444 ::osl::Module aMod; 445 bRes = ( (oslModule)aMod == NULL ); 446 447 aMod.load( getDllURL( ) ); 448 bRes1 = (oslModule)aMod != NULL; 449 450 aMod.unload( ); 451 452 CPPUNIT_ASSERT_MESSAGE( "#test comment#: the m_Module of a Module instance will be NULL when is not loaded, it will not be NULL after loaded.", 453 sal_True == bRes && sal_True == bRes1); 454 } 455 456 void optr_oslModule_002( ) 457 { 458 ::osl::Module aMod( getDllURL( ) ); 459 ::rtl::OUString funcName(::rtl::OUString::createFromAscii( "firstfunc" ) ); 460 461 FuncPtr pFunc = ( FuncPtr ) osl_getSymbol( (oslModule)aMod, funcName.pData ); 462 bRes = sal_False; 463 if ( pFunc ) 464 bRes = pFunc( bRes ); 465 466 aMod.unload(); 467 468 CPPUNIT_ASSERT_MESSAGE( "#test comment#: use m_Module to call osl_getSymbol() function.", 469 sal_True == bRes ); 470 } 471 472 CPPUNIT_TEST_SUITE( optr_oslModule ); 473 CPPUNIT_TEST( optr_oslModule_001 ); 474 CPPUNIT_TEST( optr_oslModule_002 ); 475 CPPUNIT_TEST_SUITE_END( ); 476 }; // class optr_oslModule 477 478 /** testing the methods: 479 oslGenericFunction SAL_CALL getFunctionSymbol( const ::rtl::OUString& ustrFunctionSymbolName ) 480 */ 481 class getFunctionSymbol : public CppUnit::TestFixture 482 { 483 public: 484 sal_Bool bRes, bRes1; 485 486 void getFunctionSymbol_001( ) 487 { 488 ::osl::Module aMod( getDllURL( ) ); 489 oslGenericFunction oslFunc = aMod.getFunctionSymbol( rtl::OUString::createFromAscii( "firstfunc" ) ); 490 ::rtl::OUString aLibraryURL; 491 bRes = ::osl::Module::getUrlFromAddress( oslFunc, aLibraryURL); 492 aMod.unload(); 493 printFileName( aLibraryURL ); 494 495 CPPUNIT_ASSERT_MESSAGE( "#test comment#: load a dll and get its function addr and get its URL.", 496 sal_True == bRes && aLibraryURL.equalsIgnoreAsciiCase( getDllURL() ) ); 497 } 498 499 CPPUNIT_TEST_SUITE( getFunctionSymbol ); 500 CPPUNIT_TEST( getFunctionSymbol_001 ); 501 //CPPUNIT_TEST( getFunctionSymbol_002 ); 502 CPPUNIT_TEST_SUITE_END( ); 503 }; // class getFunctionSymbol 504 505 // ----------------------------------------------------------------------------- 506 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Module::ctors, "osl_Module"); 507 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Module::getUrlFromAddress, "osl_Module"); 508 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Module::load, "osl_Module"); 509 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Module::unload, "osl_Module"); 510 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Module::is, "osl_Module"); 511 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Module::getSymbol, "osl_Module"); 512 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Module::optr_oslModule, "osl_Module"); 513 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Module::getFunctionSymbol, "osl_Module"); 514 // ----------------------------------------------------------------------------- 515 516 } // namespace osl_Module 517 518 // ----------------------------------------------------------------------------- 519 520 // this macro creates an empty function, which will called by the RegisterAllFunctions() 521 // to let the user the possibility to also register some functions by hand. 522 NOADDITIONAL; 523