xref: /aoo4110/main/sal/qa/osl/module/osl_Module.cxx (revision b1cdbd2c)
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