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