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 */
printBool(sal_Bool bOk)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 */
printUString(const::rtl::OUString & str)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 */
getDllURL(void)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 */
printFileName(const::rtl::OUString & str)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
isURL(const::rtl::OUString pathname)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 */
createTestDirectory(const::rtl::OUString dirname)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 */
deleteTestDirectory(const::rtl::OUString dirname)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
ifFileExist(const::rtl::OUString & str)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 */
deleteTestFile(const::rtl::OUString filename)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:
myFunc()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
ctors_none()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
ctors_name_mode()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
getUrlFromAddress_001()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
getUrlFromAddress_002()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
load_001()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
load_002()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
unload_001()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
is_001()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
getSymbol_001()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
optr_oslModule_001()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
optr_oslModule_002()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
getFunctionSymbol_001()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