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 // Documentation about bootstraping can be found at:
28 // http://udk.openoffice.org/common/man/concept/micro_deployment.html
29 
30 #include <math.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <algorithm> // STL
34 
35 #ifdef WNT
36 #define WIN32_LEAN_AND_MEAN
37 #include <windows.h>
38 #endif
39 
40 #include "gtest/gtest.h"
41 //#include "stringhelper.hxx"
42 //#include "valueequal.hxx"
43 #include <rtl/bootstrap.hxx>
44 
45 #include <rtl/ustrbuf.hxx>
46 #include <rtl/ustring.h>
47 #include <rtl/ustring.hxx>
48 #include <osl/file.hxx>
49 #include <osl/module.hxx>
50 #include <osl/process.h> /* osl_getExecutableFile() */
51 
52 #include <osl/thread.hxx>
53 
54 // using namespace osl;
55 using namespace rtl;
56 
57 #define TESTSHL2_INI "testshl2"
58 #define PSEUDO_INI   "pseudo"
59 
60 /** print a UNI_CODE String. And also print some comments of the string.
61  */
printUString(const::rtl::OUString & str,const sal_Char * msg="")62 inline void printUString( const ::rtl::OUString & str, const sal_Char * msg = "" )
63 {
64 
65     if (strlen(msg) > 0)
66     {
67         printf("%s: ", msg );
68     }
69     rtl::OString aString;
70     aString = ::rtl::OUStringToOString( str, RTL_TEXTENCODING_ASCII_US );
71     printf("%s\n", (char *)aString.getStr( ) );
72 }
73 
74 /** if the file exist
75  */
t_fileExist(rtl::OUString const & _sFilename)76 bool t_fileExist(rtl::OUString const& _sFilename)
77 {
78     ::osl::FileBase::RC   nError1;
79     ::osl::File aTestFile( _sFilename );
80     nError1 = aTestFile.open ( OpenFlag_Read );
81     if ( ( ::osl::FileBase::E_NOENT != nError1 ) && ( ::osl::FileBase::E_ACCES != nError1 ) )
82     {
83         aTestFile.close( );
84         return true;
85     }
86     return false;
87 }
88 
89 /** get the exectutable path ( here is bootstrap_process), on Linux, such as "sal/unxlngi4.pro/bin/"
90   */
getModulePath(void)91 inline ::rtl::OUString getModulePath( void )
92 {
93     ::rtl::OUString suDirPath;
94     ::osl::Module::getUrlFromAddress( ( oslGenericFunction ) &getModulePath, suDirPath );
95 
96     suDirPath = suDirPath.copy( 0, suDirPath.lastIndexOf('/') );
97     suDirPath = suDirPath.copy( 0, suDirPath.lastIndexOf('/') + 1);
98     suDirPath += rtl::OUString::createFromAscii("bin");
99     return suDirPath;
100 }
101 
102 #define TESTSHL2_INI "testshl2"
103 #define PSEUDO_INI   "pseudo"
104 
105 
getExecutableDirectory()106 static rtl::OUString getExecutableDirectory()
107 {
108     rtl::OUString fileName;
109     osl_getExecutableFile(&fileName.pData);
110 
111     sal_Int32 nDirEnd = fileName.lastIndexOf('/');
112 
113     OSL_ENSURE(nDirEnd >= 0, "Cannot locate executable directory");
114 
115     rtl::OUString aDirURL = fileName.copy(0, nDirEnd);
116     return aDirURL;
117 }
118 
119 
120 // get the URL of testshl2rc/rtlrc/pseudorc
t_getSourcePath(rtl::OString const & _sFilename)121 inline rtl::OUString t_getSourcePath(rtl::OString const& _sFilename)
122 {
123 
124      rtl::OUString aDirURL(getExecutableDirectory());
125      aDirURL += OUString::createFromAscii( "/");
126      aDirURL += OUString::createFromAscii( _sFilename.getStr() );
127 #if defined(WNT) || defined(OS2)
128     aDirURL += rtl::OUString::createFromAscii(".ini");
129 #else
130     aDirURL += rtl::OUString::createFromAscii("rc");
131 #endif
132     return aDirURL;
133 
134 // LLA: does not right work on my personal laptop, SRC_ROOT does not show where the source is :-(.
135 /*
136   sal_Char *  pStr = getenv("SRC_ROOT");
137   rtl::OUString suPath;
138   if (filename != "")
139   {
140   suPath = rtl::OUString::createFromAscii(pStr) + rtl::OUString::createFromAscii( "/sal/qa/rtl/bootstrap/" )
141   + rtl::OUString::createFromAscii( filename );
142   }
143   else
144   {
145   suPath = rtl::OUString::createFromAscii(pStr) + rtl::OUString::createFromAscii( "/sal/qa/rtl/bootstrap" );
146   }
147   rtl::OUString suURL;
148   ::osl::FileBase::getFileURLFromSystemPath( suPath, suURL );
149   return suURL;
150 */
151 }
152 
thread_sleep_tenth_sec(sal_Int32 _nTenthSec)153 void thread_sleep_tenth_sec(sal_Int32 _nTenthSec)
154 {
155 #ifdef WNT      //Windows
156     Sleep(_nTenthSec * 100 );
157 #endif
158 #if ( defined UNX ) || ( defined OS2 )  //Unix
159     TimeValue nTV;
160     nTV.Seconds = static_cast<sal_uInt32>( _nTenthSec/10 );
161     nTV.Nanosec = ( (_nTenthSec%10 ) * 100000000 );
162     osl_waitThread(&nTV);
163 #endif
164 }
165 
166 // -----------------------------------------------------------------------------
167 
168 namespace rtl_Bootstrap
169 {
170     class ctor : public ::testing::Test
171     {
172     public:
173         // initialise your test code values here.
SetUp()174         void SetUp()
175         {
176         }
177 
TearDown()178         void TearDown()
179         {
180         }
181     }; // class ctor
182 
183     // ctor with ini name
TEST_F(ctor,ctor_001)184     TEST_F(ctor, ctor_001)
185     {
186         rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
187         printUString( suIniname );
188         Bootstrap aBootstrap( suIniname );
189         rtl::OUString suGetname; // = rtl::OUString::createFromAscii("");
190         aBootstrap.getIniName( suGetname );
191         printUString( suGetname );
192 
193         // LLA: first: this seems to be a wrong test.
194         //      second: there seems to be a design hole, if I give a absolute path ini file,
195         //              but try to use ${file::KEYVALUE} than 'file' will only used out of the 'executable path'/file
196         //              not from the path given from the absolute path.
197 
198         // Due to the fact, we create at this position a file (createTestshl2rc() ), we check for existence
199         bool bFileExist = t_fileExist( suGetname );
200         ASSERT_TRUE(bFileExist == true) << "ctor error with initial file.";
201     }
202 
TEST_F(ctor,ctor_002)203     TEST_F(ctor, ctor_002)
204     {
205         rtl::Bootstrap aBootstrap;
206         rtl::OUString suGetname;
207         aBootstrap.getIniName( suGetname );
208         printUString( suGetname );
209         ASSERT_TRUE(suGetname.getLength() != 0) << "ctor error without initial file.";
210     }
211 
212     class getFrom : public ::testing::Test
213     {
214     public:
215         // initialise your test code values here.
SetUp()216         void SetUp()
217         {
218         }
219 
TearDown()220         void TearDown()
221         {
222         }
223 
224 	/** helper function: return the child process's ret value( typedef sal_uInt32 oslProcessExitCode;)
225 	   * param1 is the process's name(only file name, not include path)
226 	  */
ini_execProcess(const sal_Char * process_name,const sal_Char * flag)227 	 oslProcessExitCode ini_execProcess( const sal_Char* process_name, const sal_Char * flag )
228 	 {
229 	 	rtl::OUString suCWD = getModulePath();
230     		oslProcess hProcess = NULL;
231    		rtl::OUString suFileURL = suCWD;
232         	suFileURL += rtl::OUString::createFromAscii("/") +  rtl::OUString::createFromAscii(process_name) ;
233 #if defined(WNT) || defined(OS2)
234 		suFileURL += rtl::OUString::createFromAscii(".exe");
235 #endif
236         	const int nParameterCount = 3;
237     		rtl_uString* pParameters[ nParameterCount ];
238     		OUString suFlag( OUString::createFromAscii(flag) );
239 		OUString suEnv1( OUString::createFromAscii("-env:UNO_SERVICES=service.rdb"));
240 		OUString suIniname = t_getSourcePath("rtl");
241 		printUString( suIniname, "rtl path:");
242 		//OUString suEnv2( OUString::createFromAscii("-env:MYENV=bootstrap_process"));
243 
244         	pParameters[0] = suFlag.pData;
245         	pParameters[1] = suEnv1.pData;
246         	// the custom ini/rc file's URL
247         	pParameters[2] = suIniname.pData;
248 
249         	oslProcessError osl_error = osl_executeProcess(
250         	    suFileURL.pData,
251         	    pParameters,
252             	    nParameterCount,
253         	    osl_Process_WAIT,
254         	    0,
255         	    suCWD.pData,
256         	    NULL,
257         	    0,
258         	    &hProcess );
259 
260         	EXPECT_TRUE(osl_error == osl_Process_E_None)
261         	    << "osl_createProcess failed";
262 	       	osl_joinProcess(hProcess);
263         	oslProcessInfo* pInfo = new oslProcessInfo;
264 		pInfo->Size = sizeof( oslProcessInfo );
265 		osl_error = osl_getProcessInfo( hProcess, osl_Process_EXITCODE, pInfo );
266 		EXPECT_TRUE(osl_Process_E_None == osl_error)
267         	    << "osl_getProcessInfo returned with failure";
268 
269 		printf("the exit code is %d.\n", pInfo->Code );
270 		oslProcessExitCode nCode = pInfo->Code;
271 		delete pInfo;
272 	 	return nCode;
273 	}
274 
275     }; // class getFrom
276 
277     // get the value of env variable
TEST_F(getFrom,getFrom_001)278     TEST_F(getFrom, getFrom_001)
279         {
280             Bootstrap aBootstrap;
281             rtl::OUString suValue;
282             rtl::OUString suValuename = rtl::OUString::createFromAscii( "SOLAR_JAVA" );
283             //aBootstrap.getFrom( suValuename, suValue );
284             aBootstrap.getFrom( suValuename, suValue );
285             sal_Char *  pStr = getenv("SOLAR_JAVA");
286             //      printUString( suGetname );
287             ASSERT_TRUE(suValue.compareToAscii( pStr ) == 0) << "get the value of environment variable.";
288         }
289     /* Notes on Windows:
290        void getFrom_001_1()
291        {
292        Bootstrap aBootstrap;
293        rtl::OUString suValue;
294        rtl::OUString suValuename = rtl::OUString::createFromAscii( "SRC_ROOT" );
295        //aBootstrap.getFrom( suValuename, suValue );
296        aBootstrap.getFrom( suValuename, suValue );
297        sal_Char *  pStr = getenv("SRC_ROOT");
298        //   printUString( suGetname );
299        ASSERT_TRUE(suValue.compareToAscii( pStr ) == 0) << "get the value of environment variable.";
300        }
301        The result on Windows:
302        # # the SRC_ROOT is e:\Qadev\cvs\m19
303        # # suValue is e:Qadevcvsm19
304        reason:
305        The problem is that the internally getenv()ed variable SRC_ROOT is macro expanded,
306        thus every \ will introduce an escape.
307     */
308 
309     // get the value of a variable in ini file
TEST_F(getFrom,getFrom_002)310     TEST_F(getFrom, getFrom_002)
311     {
312         rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
313         Bootstrap aBootstrap( suIniname );
314         rtl::OUString suGetname;
315         rtl::OUString suValuename = rtl::OUString::createFromAscii( "INHERITED_VALUE" );
316         aBootstrap.getFrom( suValuename, suGetname );
317         printUString( suGetname );
318         ASSERT_TRUE(suGetname.getLength() != 0) << "get the value of a variable in ini file.";
319     }
320 
321     //use defaut value
TEST_F(getFrom,getFrom_003)322     TEST_F(getFrom, getFrom_003)
323     {
324         rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
325         Bootstrap aBootstrap( suIniname );
326         rtl::OUString suGetname;
327         rtl::OUString suValuename = rtl::OUString::createFromAscii( "MY_VALUE" );
328         rtl::OUString myDefault = rtl::OUString::createFromAscii( "2" );
329         aBootstrap.getFrom( suValuename, suGetname, myDefault );
330         //printUString( suGetname );
331         ASSERT_TRUE(suGetname.compareTo( myDefault ) == 0) << "getFrom use default.";
332     }
333 
TEST_F(getFrom,getFrom_004)334     TEST_F(getFrom, getFrom_004)
335     {
336         printf("1\n");
337         // initialise Bootstrap with an own ini file
338         // PSEUDO_INI is pseudo(rc|.ini) created be create_pseudorc()
339         rtl::OUString suIniname = t_getSourcePath(PSEUDO_INI);
340         Bootstrap aBootstrap( suIniname );
341 
342         rtl::OUString suGetIniName;
343         aBootstrap.getIniName( suGetIniName );
344 
345         printUString(suGetIniName, "Current bootstrap file");
346         sal_Int32 nIndex = suGetIniName.indexOf(rtl::OUString::createFromAscii( "pseudo" ));
347         ASSERT_TRUE(nIndex > 0) << "ini name must have 'pseudo' in name.";
348 
349         // rtlBootstrapHandle bsHandle = aBootstrap.getHandle();
350         // ASSERT_TRUE(bsHandle != 0) << "getHandle return NULL!";
351 
352         rtl::OUString suValue;
353         rtl::OUString suKeyName = rtl::OUString::createFromAscii( "FILE" );
354         aBootstrap.getFrom( suKeyName, suValue );
355         printUString( suValue );
356         sal_Int32 nCompare = suValue.compareTo( rtl::OUString::createFromAscii("pseudo file") );
357 
358         ASSERT_TRUE(nCompare == 0)
359             << "<Bootstrap('pseudo')>.getFrom('FILE', ...) result is unexpected.";
360     }
361 
TEST_F(getFrom,getFrom_004_1)362     TEST_F(getFrom, getFrom_004_1)
363     {
364         // get the same key out of the default context
365         rtl::OUString suKeyName = rtl::OUString::createFromAscii( "FILE" );
366         rtl::OUString suGetValue;
367         Bootstrap::get( suKeyName, suGetValue );
368         printUString( suGetValue );
369 
370         ASSERT_TRUE(suGetValue.compareTo( rtl::OUString::createFromAscii("testshl2 file") ) == 0)
371             << "Bootstrap::get('FILE', ...)";
372     }
373 
TEST_F(getFrom,getFrom_005_1)374     TEST_F(getFrom, getFrom_005_1)
375     {
376         oslProcessExitCode nExitCode = ini_execProcess( "bootstrap_process", "1" );
377         ASSERT_TRUE(nExitCode == 10) << "Parameters passed by command line can not be gotten!";
378     }
TEST_F(getFrom,getFrom_005_2)379     TEST_F(getFrom, getFrom_005_2)
380     {
381         oslProcessExitCode nExitCode = ini_execProcess( "bootstrap_process", "2" );
382         ASSERT_TRUE(nExitCode == 20) << "Parameters passed by .ini/rc file can not be gotten!";
383     }
TEST_F(getFrom,getFrom_005_3)384     TEST_F(getFrom, getFrom_005_3)
385     {
386 #if (defined WNT) || (defined SOLARIS)
387         putenv(const_cast< char * >("QADEV_BOOTSTRAP=sun&ms"));
388 #else
389         setenv("QADEV_BOOTSTRAP", "sun&ms", 0);
390 #endif
391         oslProcessExitCode nExitCode = ini_execProcess( "bootstrap_process", "3" );
392         ASSERT_TRUE(nExitCode == 30) << "Parameters passed by environment variables can not be gotten!";
393     }
TEST_F(getFrom,getFrom_005_4)394     TEST_F(getFrom, getFrom_005_4)
395     {
396         oslProcessExitCode nExitCode = ini_execProcess( "bootstrap_process", "4" );
397         ASSERT_TRUE(nExitCode == 40) << "Parameters passed by customed .ini/rc file can not be gotten!";
398     }
TEST_F(getFrom,getFrom_005_5)399     TEST_F(getFrom, getFrom_005_5)
400     {
401         oslProcessExitCode nExitCode = ini_execProcess( "bootstrap_process", "5" );
402         ASSERT_TRUE(nExitCode == 50) << "Parameters passed by inheritance can not be gotten!";
403     }
TEST_F(getFrom,getFrom_005_6)404     TEST_F(getFrom, getFrom_005_6)
405     {
406         oslProcessExitCode nExitCode = ini_execProcess( "bootstrap_process", "6" );
407         ASSERT_TRUE(nExitCode == 60) << "Parameters passed by default can not be gotten!";
408     }
409 
410     class setIniFilename : public ::testing::Test
411     {
412     public:
413         // initialise your test code values here.
SetUp()414         void SetUp()
415         {
416         }
417 
TearDown()418         void TearDown()
419         {
420         }
421     }; // class setIniFilename
422 
TEST_F(setIniFilename,setIniFilename_001)423     TEST_F(setIniFilename, setIniFilename_001)
424     {
425         Bootstrap aBootstrap;
426 
427         rtl::OUString suGetIniname;
428         aBootstrap.getIniName( suGetIniname );
429         //which should be .....testshl2rc
430         //printUString( suGetIniname );
431 
432         rtl::OUString suIniname = t_getSourcePath(PSEUDO_INI);
433         Bootstrap::setIniFilename( suIniname );
434 
435         rtl::OUString suGetname;
436         aBootstrap.getIniName( suGetname );
437 
438         printUString( suGetname );
439         ASSERT_TRUE(suGetname.compareTo( suIniname ) == 0
440                                && suGetname.compareTo( suGetIniname ) != 0) << "setIniFilename then get it.";
441     }
442 
TEST_F(setIniFilename,setIniFilename_002)443     TEST_F(setIniFilename, setIniFilename_002)
444     {
445         rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
446         // ASSERT_TRUE(t_fileExist(suIniname ) == true) <<
447         //     "test failed, Bootstrap ini does not exist."
448 
449         Bootstrap::setIniFilename( suIniname );
450         //rtl_bootstrap_args_open( suIniname.pData );
451         rtl::OUString suGetname;
452         rtl::OUString suValuename = rtl::OUString::createFromAscii( "INHERITED_VALUE" );
453         //aBootstrap.getFrom( suValuename, suGetname  );
454         Bootstrap::get( suValuename, suGetname  );
455         printUString( suGetname );
456         ASSERT_TRUE(suGetname.getLength() != 0) << "setIniFilename and get value of the argument.";
457     }
458 
459     class getHandle : public ::testing::Test
460     {
461     public:
462         // initialise your test code values here.
SetUp()463         void SetUp()
464         {
465         }
466 
TearDown()467         void TearDown()
468         {
469         }
470     }; // class getHandle
471 
TEST_F(getHandle,getHandle_001)472     TEST_F(getHandle, getHandle_001)
473     {
474         rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
475         Bootstrap aBootstrap;
476         rtlBootstrapHandle bsHandle = aBootstrap.getHandle();
477         ASSERT_TRUE(bsHandle == 0) << "getHandle should return 0 if the bootstrap has no ini file!";
478     }
TEST_F(getHandle,getHandle_002)479     TEST_F(getHandle, getHandle_002)
480     {
481         rtl::OUString suIniname = t_getSourcePath(PSEUDO_INI);
482         Bootstrap aBootstrap( suIniname );
483 
484         rtlBootstrapHandle bsHandle = aBootstrap.getHandle();
485         ASSERT_TRUE(bsHandle != 0) << "getHandle return NULL!";
486 
487         //rtl::OUString iniName;
488         //rtl_bootstrap_get_iniName_from_handle( bsHandle, &iniName.pData );
489 
490         rtl::OUString suValue;
491         rtl::OUString suKeyName = rtl::OUString::createFromAscii( "PSEUDOFILE" );
492         rtl_bootstrap_get_from_handle(bsHandle, suKeyName.pData, &suValue.pData, NULL);
493         printUString( suValue);
494 
495         ASSERT_TRUE(suValue.equals( rtl::OUString::createFromAscii("be pseudo") ) == sal_True) << "Can not use the handle which is returned by getHandle!";
496 
497         // ASSERT_TRUE(//      suGetname.equalsIgnoreAsciiCase( iniName ) == sal_True) << "Can not use the handle which is returned by getHandle!";
498     }
499 
500     class set : public ::testing::Test
501     {
502     public:
503         // initialise your test code values here.
SetUp()504         void SetUp()
505         {
506         }
507 
TearDown()508         void TearDown()
509         {
510         }
511     }; // class set
512 
TEST_F(set,set_001)513     TEST_F(set, set_001)
514     {
515         //in ini fle, INHERITED_VALUE=inherited_value
516         rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
517         Bootstrap aBootstrap( suIniname);
518         rtl::OUString suName = rtl::OUString::createFromAscii( "INHERITED_VALUE" );
519         rtl::OUString suValue = rtl::OUString::createFromAscii( "ok" );
520         // set to another value
521         Bootstrap::set( suName, suValue );
522         rtl::OUString suGetValue;
523         Bootstrap::get( suName, suGetValue);
524         ASSERT_TRUE(suGetValue.compareTo(suValue) == 0) << "set and get argument failed.";
525     }
TEST_F(set,set_002)526     TEST_F(set, set_002)
527     {
528         rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
529         Bootstrap myBootstrap( suIniname);
530         rtl::OUString suName = rtl::OUString::createFromAscii( "INHERITED_VALUE" );
531         rtl::OUString suGetOrientValue;
532         Bootstrap::get( suName, suGetOrientValue);
533         // ??  INHERITED_VALUE = ok now, which is set in set_001
534         printUString( suGetOrientValue );
535 
536         rtl::OUString suValue = rtl::OUString::createFromAscii( TESTSHL2_INI );
537         // set to another value
538         Bootstrap::set( suName, suValue );
539         rtl::OUString suGetValue;
540         Bootstrap::get( suName, suGetValue);
541         ASSERT_TRUE(suGetValue.compareTo(suValue) == 0) << "set and get argument failed.";
542     }
543 
544     class expandMacrosFrom : public ::testing::Test
545     {
546     public:
SetUp()547         void SetUp()
548         {
549         }
550 
TearDown()551         void TearDown()
552         {
553         }
554     }; // class expandMacrosFrom
555 
TEST_F(expandMacrosFrom,expandMacrosFrom_001)556     TEST_F(expandMacrosFrom, expandMacrosFrom_001)
557     {
558         rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
559         Bootstrap aBootstrap( suIniname);
560         rtl::OUString suMacro = rtl::OUString::createFromAscii( "$MYVAR/expand1" );
561         //printUString( suMacro );
562         //expandMacro now
563         aBootstrap.expandMacrosFrom( suMacro );
564         rtl::OUString suExpectedMacro = rtl::OUString::createFromAscii( "src680_test/expand1" );
565         //printUString( suMacro );
566         ASSERT_TRUE(suMacro.compareTo(suExpectedMacro) == 0) << "expandMacrosFrom failed.";
567     }
568 
569     /** here a special macro should expand
570       * if rtlrc is under sal/qa/rtl/bootstrap/, "${rtlrc:Bootstrap:RTLVALUE}" could be expanded
571       * else rtlrc is under solver/680/unxlngi4.pro/bin/, "${file:/// ....solver/680/unxlngi4.pro/bin/rtlrc:Bootstrap:RTLVALUE}"
572   * could not be expanded
573   */
TEST_F(expandMacrosFrom,expandMacrosFrom_002)574     TEST_F(expandMacrosFrom, expandMacrosFrom_002)
575     {
576         // Build a string with '${rtl.ini:RTLVALUE}' and try to expand it.
577         // In function 'create_rtlrc() is the content of the rtl.ini file.
578 
579         rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
580         printf("inifile is:");
581         printUString( suIniname );
582         Bootstrap aBootstrap( suIniname) ;
583         rtl::OUString suMacro = rtl::OUString::createFromAscii( "${" );         //rtlrc:Bootstrap:RTLVALUE}");
584 
585 rtl::OUString aDirURL = OUString::createFromAscii( "$ORIGIN");
586 aDirURL += OUString::createFromAscii( "/");
587 aDirURL += OUString::createFromAscii( "rtl" );
588 #if defined(WNT) || defined(OS2)
589 aDirURL += rtl::OUString::createFromAscii(".ini");
590 #else
591 aDirURL += rtl::OUString::createFromAscii("rc");
592 #endif
593 
594         suMacro += aDirURL;//t_getSourcePath("rtl");
595         suMacro += rtl::OUString::createFromAscii( "::RTLVALUE}");
596 
597         printf("created macro is: ");
598         printUString( suMacro );
599         //expandMacro now
600         aBootstrap.expandMacrosFrom( suMacro );
601         printf("expanded macro is:");
602         printUString( suMacro );
603         rtl::OUString suExpectedMacro = rtl::OUString::createFromAscii( "qadev17" );
604         ASSERT_TRUE(suMacro.compareTo(suExpectedMacro) == 0 )
605             << "failed, can't expand '${file:///.../" SAL_CONFIGFILE("rtl") "::RTLVALUE}' to 'qadev17'";
606     }
TEST_F(expandMacrosFrom,expandMacrosFrom_002_1)607     TEST_F(expandMacrosFrom, expandMacrosFrom_002_1)
608     {
609         rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
610         printf("inifile is:");
611         printUString( suIniname );
612         Bootstrap aBootstrap( suIniname);
613 
614         rtl::OUString suMacro;
615         // just a simple test, if this really work.
616         aBootstrap.getFrom(rtl::OUString::createFromAscii( "SOFROMVALUE2" ), suMacro );
617         printf("SOFROMVALUE2:");
618         printUString( suMacro );
619         ASSERT_TRUE(suMacro.getLength() > 0) << "'SOFROMVALUE2' seems to do not exist.";
620 
621         aBootstrap.getFrom(rtl::OUString::createFromAscii( "SOFROMVALUE" ), suMacro );
622 
623         printf("SOFROMVALUE:");
624         printUString( suMacro );
625 
626         //expandMacro now
627         // seems to be, that getFrom() already expand the string
628         // printf("expanded macro is:");
629         // aBootstrap.expandMacrosFrom( suMacro );
630         // printUString( suMacro );
631         rtl::OUString suExpectedMacro = rtl::OUString::createFromAscii( "src680_qadev" );
632         ASSERT_TRUE(suMacro.compareTo(suExpectedMacro) == 0)
633             << "failed, can't expand '${" SAL_CONFIGFILE("rtl") "::SOVALUE}' to 'src680_qadev'";
634     }
TEST_F(expandMacrosFrom,expandMacrosFrom_002_2)635     TEST_F(expandMacrosFrom, expandMacrosFrom_002_2)
636     {
637         // test, to read and expand SOFROMVALUE3
638         // SOFROMVALUE3 is 'rtl(.ini|rc)::TESTSHL_SOVALUE' which should expand to 'rtlfile' if all is ok.
639 
640         rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
641         printf("inifile is:");
642         printUString( suIniname );
643         Bootstrap aBootstrap( suIniname);
644 
645         rtl::OUString suMacro;
646         aBootstrap.getFrom(rtl::OUString::createFromAscii( "SOFROMVALUE3" ), suMacro );
647 
648         printf("SOFROMVALUE3:");
649         printUString( suMacro );
650 
651         if (suMacro.equals(rtl::OUString::createFromAscii("testshl2_file") ) == sal_True)
652         {
653             ASSERT_TRUE(0) << "Value 'SOFROMVALUE3' is read from the wrong ini file.";
654         }
655         else
656         {
657             ASSERT_TRUE(suMacro.equals(rtl::OUString::createFromAscii("rtlfile") ) == sal_True) << "SOFROMVALUE3 should contain 'rtlfile'.";
658         }
659     }
660 //? I don't know if this is a right test.
661 //         void expandMacrosFrom_002_3()
662 //             {
663 //                 // test, to read and expand SOFROMVALUE4
664 //                 // SOFROMVALUE4 is 'rtl(.ini|rc):Other_Section:TESTSHL_SOVALUE' which should expand to '' if all is ok.
665 //
666 //                 rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
667 //                 printf("inifile is:");
668 //              printUString( suIniname );
669 //                 Bootstrap aBootstrap( suIniname);
670 //
671 //                 rtl::OUString suMacro;
672 //                 aBootstrap.getFrom(rtl::OUString::createFromAscii( "SOFROMVALUE4" ), suMacro );
673 //
674 //                 printf("SOFROMVALUE4:");
675 //                 printUString( suMacro );
676 //
677 //                 if (suMacro.equals(rtl::OUString::createFromAscii("testshl2_file") ) == sal_True)
678 //                 {
679 //                     ASSERT_TRUE(0) << "Value 'SOFROMVALUE4' is read from the wrong section out of the wrong ini file.";
680 //                 }
681 //                 else if (suMacro.equals(rtl::OUString::createFromAscii("testshl2_file_other") ) == sal_True)
682 //                 {
683 //                     ASSERT_TRUE(0) << "Value 'SOFROMVALUE4' is read from the wrong ini file.";
684 //                 }
685 //                 else
686 //                 {
687 //                     ASSERT_TRUE(suMacro.equals(rtl::OUString::createFromAscii("rtlfile_other") ) == sal_True) << "Value 'SOFROMVALUE4' should contain 'rtlfile_other'.";
688 //                 }
689 //             }
TEST_F(expandMacrosFrom,expandMacrosFrom_003)690     TEST_F(expandMacrosFrom, expandMacrosFrom_003)
691     {
692         rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
693         Bootstrap aBootstrap( suIniname);
694         rtl::OUString suMacro[4];
695         suMacro[0] = rtl::OUString::createFromAscii( "$SYSUSERCONFIG" );
696         suMacro[1] = rtl::OUString::createFromAscii( "$SYSUSERHOME" );
697         suMacro[2] = rtl::OUString::createFromAscii( "$SYSBINDIR" );
698         suMacro[3] = rtl::OUString::createFromAscii( "$ORIGIN" );
699 
700         for ( int i = 0; i < 4; i++ )
701         {
702             aBootstrap.expandMacrosFrom( suMacro[i] );
703             printUString(suMacro[i]);
704         }
705         // printUString( t_getSourcePath("") );
706         // ASSERT_TRUE(suMacro[3].equalsIgnoreAsciiCase(t_getSourcePath("")) == sal_True) << "some integral variables.";
707         ASSERT_TRUE(suMacro[0].getLength() > 0 &&
708                                suMacro[1].getLength() > 0 &&
709                                suMacro[2].getLength() > 0 &&
710                                suMacro[3].getLength() > 0) << "some integral variables.";
711     }
712 
TEST_F(expandMacrosFrom,testRecursion)713     TEST_F(expandMacrosFrom, testRecursion) {
714         rtl::OUString t(RTL_CONSTASCII_USTRINGPARAM("$RECURSIVE"));
715         Bootstrap(t_getSourcePath(TESTSHL2_INI)).expandMacrosFrom(t);
716         ASSERT_TRUE(t.equalsAsciiL(
717                 RTL_CONSTASCII_STRINGPARAM("***RECURSION DETECTED***"))) << "recursion detection";
718     }
719 
TEST_F(expandMacrosFrom,testLink)720     TEST_F(expandMacrosFrom, testLink) {
721         rtl::OUString t(RTL_CONSTASCII_USTRINGPARAM("$LINKED"));
722         Bootstrap(t_getSourcePath(TESTSHL2_INI)).expandMacrosFrom(t);
723         ASSERT_TRUE(t.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("qadev17"))) << "link file";
724     }
725 
TEST_F(expandMacrosFrom,testOverride)726     TEST_F(expandMacrosFrom, testOverride) {
727         rtl::OUString t1(
728             RTL_CONSTASCII_USTRINGPARAM(
729                 "${.override:$ORIGIN/" SAL_CONFIGFILE("rtl") ":ORIGIN}"));
730         Bootstrap(t_getSourcePath("rtl")).expandMacrosFrom(t1);
731         ASSERT_TRUE(t1.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("direct"))) << "override ORIGIN";
732         rtl::OUString t2(
733             RTL_CONSTASCII_USTRINGPARAM(
734                 "${.override:$ORIGIN/" SAL_CONFIGFILE("none") ":MYVAR}"));
735         Bootstrap::expandMacros(t2);
736         ASSERT_TRUE(t2.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("src680_test"))) << "override MYVAR";
737     }
738 
TEST_F(expandMacrosFrom,testNonexisting)739     TEST_F(expandMacrosFrom, testNonexisting) {
740         rtl::OUString t(
741             RTL_CONSTASCII_USTRINGPARAM(
742                 "${$ORIGIN/" SAL_CONFIGFILE("none") ":MYVAR}"));
743         Bootstrap::expandMacros(t);
744         ASSERT_TRUE(t.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("src680_test"))) << "nonexisting";
745     }
746 
TEST_F(expandMacrosFrom,testSection)747     TEST_F(expandMacrosFrom, testSection) {
748         rtl::OUStringBuffer b;
749         b.appendAscii(RTL_CONSTASCII_STRINGPARAM("${"));
750         rtl::OUString p(t_getSourcePath(TESTSHL2_INI));
751         for (sal_Int32 i = 0; i < p.getLength(); ++i) {
752             if (p[i] != 'u') {
753                 b.append(static_cast< sal_Unicode >('\\'));
754             }
755             b.append(p[i]);
756         }
757         b.appendAscii(RTL_CONSTASCII_STRINGPARAM(":Other_Section:EXPAND}"));
758         rtl::OUString t(b.makeStringAndClear());
759         Bootstrap(t_getSourcePath(TESTSHL2_INI)).expandMacrosFrom(t);
760         ASSERT_TRUE(t.equalsAsciiL(
761                 RTL_CONSTASCII_STRINGPARAM("$FILE"))) << "section expansion";
762             // the correct answer would be "testshl2 file" instead, but
763             // expansion including a section currently erroneously does not
764             // recursively expand macros in the resulting replacement text
765     }
766 
767     class expandMacros : public ::testing::Test
768     {
769     public:
770         // initialise your test code values here.
SetUp()771         void SetUp()
772         {
773         }
774 
TearDown()775         void TearDown()
776         {
777         }
778     }; // class expandMacros
779 
780 
TEST_F(expandMacros,expandMacros_001)781     TEST_F(expandMacros, expandMacros_001)
782     {
783         rtl::OUString suIniname = t_getSourcePath(TESTSHL2_INI);
784         Bootstrap aBootstrap( suIniname) ;
785         rtl::OUString suMacro = rtl::OUString::createFromAscii( "$INHERITED_VALUE/well" );
786         Bootstrap::expandMacros( suMacro );
787 
788         rtl::OUString suName = rtl::OUString::createFromAscii( "INHERITED_VALUE" );
789         OUString suGetValue;
790         Bootstrap::get( suName, suGetValue );
791         suGetValue += OUString::createFromAscii( "/well" );
792         ASSERT_TRUE(suGetValue.compareTo(suMacro) == 0) << "expandMacros failed.";
793     }
794 } // namespace rtl_Bootstrap
795 
796 // -----------------------------------------------------------------------------
797 
798 // this macro creates an empty function, which will called by the RegisterAllFunctions()
799 // to let the user the possibility to also register some functions by hand.
800 // NOADDITIONAL;
801 
802 
803 // Here are some helpers, which create a new file 'rtlrc' at the executable path position
804 // and fill the file with some information.
805 // static rtl::OUString getExecutableDirectory()
806 // {
807 //     rtl::OUString fileName;
808 //     osl_getExecutableFile(&fileName.pData);
809 //
810 //     sal_Int32 nDirEnd = fileName.lastIndexOf('/');
811 //
812 //     OSL_ENSURE(nDirEnd >= 0, "Cannot locate executable directory");
813 //
814 //     rtl::OUString aDirURL = fileName.copy(0, nDirEnd);
815 //     return aDirURL;
816 // }
817 
removeAndCreateFile(rtl::OUString const & _suFileURL,rtl::OString const & _sContent)818 static void removeAndCreateFile(rtl::OUString const& _suFileURL, rtl::OString const& _sContent)
819 {
820     osl::File::remove(_suFileURL);
821 
822     ::std::auto_ptr<osl::File> pFile( new osl::File( _suFileURL ) );
823     ::osl::FileBase::RC nError = pFile->open( OpenFlag_Write | OpenFlag_Create );
824     if ( ::osl::FileBase::E_None == nError || ::osl::FileBase::E_EXIST == nError )
825     {
826         printf("%s\n" , OString(_suFileURL.getStr(), _suFileURL.getLength(), RTL_TEXTENCODING_ASCII_US).getStr());
827         sal_uInt64 nWritenBytes;
828         pFile->write(_sContent.getStr(), _sContent.getLength(), nWritenBytes);
829         // printf("nBytes: %ld\n", nBytes);
830 
831         rtl::OString sError = "can't write enough bytes to file";
832         sError += OString(_suFileURL.getStr(), _suFileURL.getLength(), RTL_TEXTENCODING_ASCII_US);
833         OSL_ENSURE(nWritenBytes == _sContent.getLength(), sError.getStr());
834 
835         pFile->close();
836     }
837     else
838     {
839         rtl::OString sError = "can't create file URL: '";
840         rtl::OString sFile(_suFileURL.getStr(), _suFileURL.getLength(), RTL_TEXTENCODING_ASCII_US);
841         sError += sFile;
842         sError += "' maybe no write access. If it is true with no write access, please create a local environment and start these tests again. rtl::Bootstrap test must quit.";
843         printf("%s\n", sError.getStr() );
844         exit(1);
845     }
846     OSL_ASSERT(t_fileExist(_suFileURL) == true);
847 }
848 
849 // -----------------------------------------------------------------------------
create_rtlrc()850 static void create_rtlrc()
851 {
852     rtl::OUString aFileURL(getExecutableDirectory());
853 #if defined(WNT) || defined(OS2)
854     aFileURL += rtl::OUString::createFromAscii("/rtl.ini");
855 #else
856     aFileURL += rtl::OUString::createFromAscii("/rtlrc");
857 #endif
858 
859     rtl::OString sLines;
860     sLines += "[Bootstrap]\n";
861     sLines += "SOVALUE=src680_qadev\n";
862     sLines += "RTLVALUE=qadev17\n";
863     sLines += "TESTSHL_SOVALUE=rtlfile\n";
864     sLines += "RECURSIVE=${$ORIGIN/" SAL_CONFIGFILE("testshl2") ":RECURSIVE}\n";
865     sLines += "ORIGIN=direct\n";
866     sLines += "[Other_Section]\n";
867     sLines += "TESTSHL_SOVALUE=rtlfile_other\n";
868 
869     removeAndCreateFile(aFileURL, sLines);
870 }
871 
872 // -----------------------------------------------------------------------------
create_testshl2rc()873 static void create_testshl2rc()
874 {
875     rtl::OUString aFileURL(getExecutableDirectory());
876 #if defined(WNT) || defined(OS2)
877     aFileURL += rtl::OUString::createFromAscii("/testshl2.ini");
878 #else
879     aFileURL += rtl::OUString::createFromAscii("/testshl2rc");
880 #endif
881     rtl::OString sLines;
882     sLines += "[Bootstrap]\n";
883     sLines += "FILE=testshl2 file\n";
884     sLines += "MYBOOTSTRAPTESTVALUE=file\n";
885     sLines += "INHERITED_VALUE=inherited_value\n";
886     sLines += "INHERITED_OVERWRITTEN_VALUE=not_overwritten\n";
887     sLines += "MYVAR=src680_test\n";
888     sLines += "SOFROMVALUE=${$ORIGIN/" SAL_CONFIGFILE("rtl") "::SOVALUE}\n";
889     sLines += "SOFROMVALUE2=test\n";
890     sLines += "SOFROMVALUE3=${$ORIGIN/" SAL_CONFIGFILE("rtl") "::TESTSHL_SOVALUE}\n";
891     sLines += "TESTSHL_SOVALUE=testshl2_file\n";
892     //? sLines += "SOFROMVALUE4=${" SAL_CONFIGFILE("rtl") ":Other_Section:TESTSHL_SOVALUE}\n";
893     sLines += "ILLEGAL VALUE=test\n";
894     sLines += "ILLEGAL.DOT=test\n";
895     sLines += "ILLEGAL;SEMICOLON=test\n";
896     sLines += "ILLEGAL:COLON=test\n";
897     sLines += "  KEY_FOR_TRIM_TEST  =   value for trim test    \n";
898     sLines += "RECURSIVE=${$ORIGIN/" SAL_CONFIGFILE("rtl") ":RECURSIVE}\n";
899     sLines += "LINKED=${${.link:$ORIGIN/testshl2-link}:RTLVALUE}\n";
900     sLines += "[Other_Section]\n";
901     sLines += "FILE=testshl2 file other\n";
902     sLines += "EXPAND=$FILE\n";
903     //? sLines += "TESTSHL_SOVALUE=testshl2_file_other\n";
904 
905     removeAndCreateFile(aFileURL, sLines);
906 
907     removeAndCreateFile(
908         (getExecutableDirectory() +
909          rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/testshl2-link"))),
910         SAL_CONFIGFILE("rtl"));
911 }
912 
913 // -----------------------------------------------------------------------------
914 
create_pseudorc()915 static void create_pseudorc()
916 {
917     rtl::OUString aFileURL(getExecutableDirectory());
918 #if defined(WNT) || defined(OS2)
919     aFileURL += rtl::OUString::createFromAscii("/pseudo.ini");
920 #else
921     aFileURL += rtl::OUString::createFromAscii("/pseudorc");
922 #endif
923     rtl::OString sLines;
924     sLines += "[Bootstrap]\n";
925     sLines += "FILE=pseudo file\n";
926     sLines += "PSEUDOFILE=be pseudo\n";
927 
928     removeAndCreateFile(aFileURL, sLines);
929 }
930 
931 // -----------------------------------------------------------------------------
create_bootstrap_processrc()932 void create_bootstrap_processrc()
933 {
934     rtl::OUString aDirURL(getModulePath());
935 #if defined(WNT) || defined(OS2)
936     aDirURL += rtl::OUString::createFromAscii("/bootstrap_process.ini");
937 #else
938     aDirURL += rtl::OUString::createFromAscii("/bootstrap_processrc");
939 #endif
940     rtl::OString sLines;
941     sLines += "[Bootstrap]\n";
942     sLines += "EXECUTABLE_RC=true\n";
943     sLines += "IF_CUSTOM_RC=false\n";
944 
945     removeAndCreateFile(aDirURL, sLines);
946 }
947 // -----------------------------------------------------------------------------
948 
949 
main(int argc,char ** argv)950 int main(int argc, char **argv)
951 {
952     // start message
953     printf("Initializing ...\n" );
954     osl_setCommandArgs(argc, argv);
955     create_rtlrc();
956     create_testshl2rc();
957     create_pseudorc();
958     create_bootstrap_processrc();
959 
960     printf("Initialization Done.\n" );
961     ::testing::InitGoogleTest(&argc, argv);
962     return RUN_ALL_TESTS();
963 }
964