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