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