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 */
printBool(sal_Bool bOk)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 */
printUString(const::rtl::OUString & str)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 */
getDllURL(void)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 */
printFileName(const::rtl::OUString & str)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
isURL(const::rtl::OUString pathname)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 */
createTestDirectory(const::rtl::OUString dirname)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 */
deleteTestDirectory(const::rtl::OUString dirname)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
ifFileExist(const::rtl::OUString & str)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 /** delete a temp test file using OUString name.
155 */
deleteTestFile(const::rtl::OUString filename)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:
myFunc()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
TEST_F(ctors,ctors_none)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
TEST_F(ctors,ctors_name_mode)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
TEST_F(getUrlFromAddress,getUrlFromAddress_001)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
TEST_F(getUrlFromAddress,getUrlFromAddress_002)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
TEST_F(load,load_001)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
TEST_F(load,load_002)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
TEST_F(unload,unload_001)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
TEST_F(is,is_001)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
TEST_F(getSymbol,getSymbol_001)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
TEST_F(optr_oslModule,optr_oslModule_001)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
TEST_F(optr_oslModule,optr_oslModule_002)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
TEST_F(getFunctionSymbol,getFunctionSymbol_001)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
main(int argc,char ** argv)448 int main(int argc, char **argv)
449 {
450 ::testing::InitGoogleTest(&argc, argv);
451 return RUN_ALL_TESTS();
452 }
453