diff options
| author | Bryan O'Sullivan <bos@lindenlab.com> | 2008-06-02 21:14:31 +0000 | 
|---|---|---|
| committer | Bryan O'Sullivan <bos@lindenlab.com> | 2008-06-02 21:14:31 +0000 | 
| commit | 9db949eec327df4173fde3de934a87bedb0db13c (patch) | |
| tree | aeffa0f0e68b1d2ceb74d460cbbd22652c9cd159 /indra/test | |
| parent | 419e13d0acaabf5e1e02e9b64a07648bce822b2f (diff) | |
svn merge -r88066:88786 svn+ssh://svn.lindenlab.com/svn/linden/branches/cmake-9-merge
dataserver-is-deprecated
for-fucks-sake-whats-with-these-commit-markers
Diffstat (limited to 'indra/test')
| -rw-r--r-- | indra/test/CMakeLists.txt | 152 | ||||
| -rw-r--r-- | indra/test/io.cpp | 14 | ||||
| -rw-r--r-- | indra/test/llblowfish_tut.cpp | 14 | ||||
| -rw-r--r-- | indra/test/llhttpdate_tut.cpp | 31 | ||||
| -rw-r--r-- | indra/test/lliohttpserver_tut.cpp | 4 | ||||
| -rw-r--r-- | indra/test/llmessagetemplateparser_tut.cpp | 2 | ||||
| -rwxr-xr-x | indra/test/llsdmessagereader_tut.cpp | 4 | ||||
| -rw-r--r-- | indra/test/llsdutil_tut.cpp | 8 | ||||
| -rw-r--r-- | indra/test/lltemplatemessagebuilder_tut.cpp | 4 | ||||
| -rw-r--r-- | indra/test/message_tut.cpp | 49 | ||||
| -rw-r--r-- | indra/test/test.cpp | 87 | 
11 files changed, 327 insertions, 42 deletions
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt new file mode 100644 index 0000000000..32579e4fe2 --- /dev/null +++ b/indra/test/CMakeLists.txt @@ -0,0 +1,152 @@ +# -*- cmake -*- + +project (test) + +include(00-Common) +include(LLCommon) +include(LLDatabase) +include(LLInventory) +include(LLMath) +include(LLMessage) +include(LLVFS) +include(LLXML) +include(Linking) + +include_directories( +    ${LLCOMMON_INCLUDE_DIRS} +    ${LLDATABASE_INCLUDE_DIRS} +    ${LLMATH_INCLUDE_DIRS} +    ${LLMESSAGE_INCLUDE_DIRS} +    ${LLINVENTORY_INCLUDE_DIRS} +    ${LLVFS_INCLUDE_DIRS} +    ${LLXML_INCLUDE_DIRS} +    ) + +set(test_SOURCE_FILES +    common.cpp +    inventory.cpp +    io.cpp +    llapp_tut.cpp +    llbase64_tut.cpp +    llblowfish_tut.cpp +    llbuffer_tut.cpp +    lldatabase_tut.cpp +    lldate_tut.cpp +    llerror_tut.cpp +    llhost_tut.cpp +    llhttpdate_tut.cpp +    llhttpclient_tut.cpp +    llhttpnode_tut.cpp +    llinventoryparcel_tut.cpp +    lliohttpserver_tut.cpp +    lljoint_tut.cpp +    llmime_tut.cpp +    llmessageconfig_tut.cpp +    llnamevalue_tut.cpp +    llpermissions_tut.cpp +    llpipeutil.cpp +    llquaternion_tut.cpp +    llrandom_tut.cpp +    llsaleinfo_tut.cpp +    llsdmessagebuilder_tut.cpp +    llsdmessagereader_tut.cpp +    llsd_new_tut.cpp +    llsdserialize_tut.cpp +    llsdutil_tut.cpp +    llservicebuilder_tut.cpp +    llstreamtools_tut.cpp +    lltemplatemessagebuilder_tut.cpp +    lltiming_tut.cpp +    lltut.cpp +    lluri_tut.cpp +    lluuidhashmap_tut.cpp +    llxfer_tut.cpp +    math.cpp +    message_tut.cpp +    reflection_tut.cpp +    test.cpp +    v2math_tut.cpp +    v3color_tut.cpp +    v3dmath_tut.cpp +    v3math_tut.cpp +    v4color_tut.cpp +    v4coloru_tut.cpp +    v4math_tut.cpp +    ) + +set(test_HEADER_FILES +    CMakeLists.txt + +    llpipeutil.h +    llsdtraits.h +    lltut.h +    ) + +if (NOT WINDOWS) +  list(APPEND test_SOURCE_FILES +       llmessagetemplateparser_tut.cpp +       ) +endif (NOT WINDOWS) + +set_source_files_properties(${test_HEADER_FILES} +                            PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND test_SOURC_FILES ${test_HEADER_FILES}) + +add_executable(test ${test_SOURCE_FILES}) + +target_link_libraries(test +    ${LLDATABASE_LIBRARIES} +    ${LLINVENTORY_LIBRARIES} +    ${LLMESSAGE_LIBRARIES} +    ${LLMATH_LIBRARIES} +    ${LLVFS_LIBRARIES} +    ${LLXML_LIBRARIES} +    ${LLCOMMON_LIBRARIES} +    ${PTHREAD_LIBRARY} +    ${WINDOWS_LIBRARIES} +    ) + +if (WINDOWS) +  set_target_properties(test +          PROPERTIES  +          LINK_FLAGS "/NODEFAULTLIB:MSVCRT" +          LINK_FLAGS_DEBUG "/NODEFAULTLIB:LIBCMT" +          ) +endif (WINDOWS) + +get_target_property(TEST_EXE test LOCATION) + +add_custom_command( +  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt +  COMMAND ${TEST_EXE} +  ARGS +    --output=${CMAKE_CURRENT_BINARY_DIR}/cpp_test_results.txt +    --touch=${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt +  DEPENDS test +  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +  COMMENT "C++ unit tests" +  ) + +set(test_results ${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt) + +if (EXISTS /etc/debian_version_FAIL) +  # The Python tests have all kinds of wacky non-portable assumptions +  # built in. + +  add_custom_command( +    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/py_tests_ok.txt +    COMMAND ${PYTHON_EXECUTABLE} +    ARGS +      ${CMAKE_CURRENT_SOURCE_DIR}/test.py +      --output=${CMAKE_CURRENT_BINARY_DIR}/py_test_results.txt +      --touch=${CMAKE_CURRENT_BINARY_DIR}/py_tests_ok.txt +    DEPENDS test.py +    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +    COMMENT "Python unit tests" +    ) + +  list(APPEND test_results ${CMAKE_CURRENT_BINARY_DIR}/py_tests_ok.txt) +endif (EXISTS /etc/debian_version_FAIL) +     +add_custom_target(tests_ok ALL DEPENDS ${test_results}) diff --git a/indra/test/io.cpp b/indra/test/io.cpp index 3de1e8edef..3bb8f62ffb 100644 --- a/indra/test/io.cpp +++ b/indra/test/io.cpp @@ -36,7 +36,7 @@  #include <iterator> -#include <apr-1/apr_pools.h> +#include "apr_pools.h"  #include "llbuffer.h"  #include "llbufferstream.h" @@ -706,6 +706,9 @@ namespace tut  	template<> template<>  	void bas_object::test<10>()  	{ +//#if LL_WINDOWS && _MSC_VER >= 1400 +//        skip_fail("Fails on VS2005 due to broken LLSDSerialize::fromNotation() parser."); +//#endif  		const char LOGIN_STREAM[] = "{'method':'login', 'parameter': [ {"  										"'uri': 'sl-am:kellys.region.siva.lindenlab.com/location?start=url&px=128&py=128&pz=128&lx=0&ly=0&lz=0'}, "  										"{'version': i1}, {'texture_data': [ '61d724fb-ad79-f637-2186-5cf457560daa', '6e38b9be-b7cc-e77a-8aec-029a42b0b416', " @@ -791,6 +794,9 @@ namespace tut  	template<> template<>  	void bas_object::test<12>()  	{ +//#if LL_WINDOWS && _MSC_VER >= 1400 +//        skip_fail("Fails on VS2005 due to broken LLSDSerialize::fromNotation() parser."); +//#endif  		std::string val = "{!'foo':[i1,'hi',{@'bar'#:[$i2%,^'baz'&]*}+]=}";  		std::istringstream istr;  		istr.str(val); @@ -1309,6 +1315,9 @@ namespace tut  	template<> template<>  	void rpc_server_object::test<2>()  	{ +//#if LL_WINDOWS && _MSC_VER >= 1400 +//        skip_fail("Fails on VS2005 due to broken LLSDSerialize::fromNotation() parser."); +//#endif  		std::string uri("sl-am:66.150.244.180:12035/location?start=region&px=70.9247&py=254.378&pz=38.7304&lx=-0.043753&ly=-0.999042&lz=0");  		std::stringstream stream;  		stream << "{'task_id':ucc706f2d-0b68-68f8-11a4-f1043ff35ca0}\n{\n\tname\tObject|\n\tpermissions 0\n}"; @@ -1397,6 +1406,9 @@ namespace tut  	template<> template<>  	void rpc_server_object::test<3>()  	{ +//#if LL_WINDOWS && _MSC_VER >= 1400 +//        skip_fail("Fails on VS2005 due to broken LLSDSerialize::fromNotation() parser."); +//#endif  		std::string uri("sl-am:66.150.244.180:12035/location?start=region&px=70.9247&py=254.378&pz=38.7304&lx=-0.043753&ly=-0.999042&lz=0");  		LLBufferArray buffer; diff --git a/indra/test/llblowfish_tut.cpp b/indra/test/llblowfish_tut.cpp index 3859d6c3b1..3081ac3855 100644 --- a/indra/test/llblowfish_tut.cpp +++ b/indra/test/llblowfish_tut.cpp @@ -93,6 +93,9 @@ namespace tut  	template<> template<>  	void blowfish_object::test<1>()  	{ +#if !LL_LINUX +		skip_fail("Blowfish only supported on Linux."); +#else  		LLUUID blank;  		LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES); @@ -105,11 +108,15 @@ namespace tut  		dst_len = cipher.requiredEncryptionSpace(8);  		ensure("encryption space 8",  				(dst_len == 16)  ); +#endif // !LL_LINUX  	}  	template<> template<>  	void blowfish_object::test<2>()  	{ +#if !LL_LINUX +		skip_fail("Blowfish only supported on Linux."); +#else  		LLUUID blank;  		LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES); @@ -123,12 +130,16 @@ namespace tut  		result.resize(count);  		ensure("encrypt null key", matchFile("blowfish.1.bin", result)); +#endif // !LL_LINUX  	}  	template<> template<>  	void blowfish_object::test<3>()  	{ -		// same as base64 test id +#if !LL_LINUX +        skip_fail("Blowfish only supported on Linux."); +#else +        // same as base64 test id  		LLUUID id("526a1e07-a19d-baed-84c4-ff08a488d15e");  		LLBlowfishCipher cipher(&id.mData[0], UUID_BYTES); @@ -142,5 +153,6 @@ namespace tut  		result.resize(count);  		ensure("encrypt real key", matchFile("blowfish.2.bin", result)); +#endif // !LL_LINUX  	}  } diff --git a/indra/test/llhttpdate_tut.cpp b/indra/test/llhttpdate_tut.cpp index 1be98250d2..c630e9caf0 100644 --- a/indra/test/llhttpdate_tut.cpp +++ b/indra/test/llhttpdate_tut.cpp @@ -69,24 +69,25 @@ namespace tut          time_t sometime;          time(&sometime);          some_date = LLDate((F64) sometime); -        struct tm result; -        char expected[255], *actual; +        struct tm *result; +        char expected[255]; +		std::string actual; -        gmtime_r((time_t *)&sometime, &result); +        result = gmtime(&sometime);          /* -        std::cout << " seconds: "<< result.tm_sec  -                  << ", minutes: " << result.tm_min -                  << ", hours: " << result.tm_hour -                  << ", day of the month: " << result.tm_mday -                  << ", month: " << result.tm_mon -                  << ", year: " << result.tm_year -                  << ", day of the week: " << result.tm_wday -                  << ", day in the year: " << result.tm_yday -                  << ", DST: " << result.tm_isdst << std::endl; +        std::cout << " seconds: "<< result->tm_sec  +                  << ", minutes: " << result->tm_min +                  << ", hours: " << result->tm_hour +                  << ", day of the month: " << result->tm_mday +                  << ", month: " << result->tm_mon +                  << ", year: " << result->tm_year +                  << ", day of the week: " << result->tm_wday +                  << ", day in the year: " << result->tm_yday +                  << ", DST: " << result->tm_isdst << std::endl;          */ -        strftime(expected, 255, "%A, %d %h %Y %H:%M:%S GMT", &result); -        actual = (char *) some_date.asRFC1123().c_str(); +        strftime(expected, 255, "%A, %d %b %Y %H:%M:%S GMT", result); +        actual = some_date.asRFC1123();          // probably not a good idea to use strcmp but this is just a unit test -        ensure("Current time in RFC 1123", (strcmp(expected, actual) == 0)); +        ensure("Current time in RFC 1123", (strcmp(expected, actual.c_str()) == 0));      }  } diff --git a/indra/test/lliohttpserver_tut.cpp b/indra/test/lliohttpserver_tut.cpp index 5ac79e6931..5401d1a8ae 100644 --- a/indra/test/lliohttpserver_tut.cpp +++ b/indra/test/lliohttpserver_tut.cpp @@ -125,7 +125,7 @@ namespace tut  			pump->addChain(chain, DEFAULT_CHAIN_EXPIRY_SECS);  			pumpPipe(pump, 10); -			if(mResponse && (! timeout))  +			if(mResponse.notNull() && (! timeout))   			{  				mResponse->result(mResult);  				mResponse = NULL; @@ -138,7 +138,7 @@ namespace tut  			delete pump;  			apr_pool_destroy(pool); -			if(mResponse && timeout) +			if(mResponse.notNull() && timeout)  			{  				mResponse->result(mResult);  				mResponse = NULL; diff --git a/indra/test/llmessagetemplateparser_tut.cpp b/indra/test/llmessagetemplateparser_tut.cpp index e2680e315f..690cc26bcf 100644 --- a/indra/test/llmessagetemplateparser_tut.cpp +++ b/indra/test/llmessagetemplateparser_tut.cpp @@ -292,7 +292,7 @@ namespace tut  		delete message;  	} -	void LLMessageTemplateParserTestObject::test<8>() +	template<> template<> void LLMessageTemplateParserTestObject::test<8>()  		// tests message parsing on RezMultipleAttachmentsFromInv, a possibly-faulty message  	{  		std::string message_skel( diff --git a/indra/test/llsdmessagereader_tut.cpp b/indra/test/llsdmessagereader_tut.cpp index 67287d55e2..bee6f8a185 100755 --- a/indra/test/llsdmessagereader_tut.cpp +++ b/indra/test/llsdmessagereader_tut.cpp @@ -33,6 +33,10 @@  #include <tut/tut.h>  #include "linden_common.h"  #include "lltut.h" +#include "v3dmath.h" +#include "v3math.h" +#include "v4math.h" +#include "llquaternion.h"  #include "message.h"  #include "llsdmessagereader.h" diff --git a/indra/test/llsdutil_tut.cpp b/indra/test/llsdutil_tut.cpp index 3d0b601b34..e9a7c379bb 100644 --- a/indra/test/llsdutil_tut.cpp +++ b/indra/test/llsdutil_tut.cpp @@ -33,9 +33,15 @@  #include "linden_common.h"  #include "lltut.h" +#include "m4math.h" +#include "v2math.h" +#include "v2math.h"  #include "v3color.h" +#include "v3math.h" +#include "v3dmath.h" +#include "v4coloru.h"  #include "v4math.h" -#include "m4math.h" +#include "llquaternion.h"  #include "llsdutil.h" diff --git a/indra/test/lltemplatemessagebuilder_tut.cpp b/indra/test/lltemplatemessagebuilder_tut.cpp index a9d515dfdc..52d1436761 100644 --- a/indra/test/lltemplatemessagebuilder_tut.cpp +++ b/indra/test/lltemplatemessagebuilder_tut.cpp @@ -64,7 +64,9 @@ namespace tut  									   LL_VERSION_MINOR,          									   LL_VERSION_PATCH,          									   FALSE,         -									   "notasharedsecret"); +									   "notasharedsecret", +									   NULL, +									   false);  				//init_prehash_data();  				init = true;  			} diff --git a/indra/test/message_tut.cpp b/indra/test/message_tut.cpp index ca0452a9f3..57db6dd97a 100644 --- a/indra/test/message_tut.cpp +++ b/indra/test/message_tut.cpp @@ -35,6 +35,8 @@  #include "lltut.h"  #include "llapr.h" +#include "llmessageconfig.h" +#include "llsdserialize.h"  #include "llversionserver.h"  #include "message.h"  #include "message_prehash.h" @@ -56,10 +58,13 @@ namespace tut  {	  	struct LLMessageSystemTestData   	{ +		std::string mTestConfigDir; +		std::string mSep; +  		LLMessageSystemTestData()  		{  			static bool init = false; -			if(! init) +			if(!init)  			{  				ll_init_apr();  				//init_prehash_data(); @@ -72,7 +77,25 @@ namespace tut  								   LL_VERSION_MINOR,          								   LL_VERSION_PATCH,          								   FALSE,         -								   "notasharedsecret"); +								   "notasharedsecret", +								   NULL, +								   false); +			// generate temp dir +			std::ostringstream ostr; +#if LL_WINDOWS +			mSep = "\\"; +			ostr << "C:" << mSep; +#else +			mSep = "/"; +			ostr << mSep << "tmp" << mSep; +#endif +			LLUUID random; +			random.generate(); +			ostr << "message-test-" << random; +			mTestConfigDir = ostr.str(); +			LLFile::mkdir(mTestConfigDir.c_str()); +			writeConfigFile(LLSD()); +			LLMessageConfig::initClass("simulator", ostr.str());  		}  		~LLMessageSystemTestData() @@ -80,6 +103,28 @@ namespace tut  			// not end_messaging_system()  			delete gMessageSystem;  			gMessageSystem = NULL; + +			// rm contents of temp dir +			std::ostringstream ostr; +			ostr << mTestConfigDir << mSep << "message.xml"; +			int rmfile = LLFile::remove(ostr.str().c_str()); +			ensure_equals("rmfile value", rmfile, 0); + +			// rm temp dir +			int rmdir = LLFile::rmdir(mTestConfigDir.c_str()); +			ensure_equals("rmdir value", rmdir, 0); +		} + +		void writeConfigFile(const LLSD& config) +		{ +			std::ostringstream ostr; +			ostr << mTestConfigDir << mSep << "message.xml"; +			llofstream file(ostr.str().c_str()); +			if (file.is_open()) +			{ +				LLSDSerialize::toPrettyXML(config, file); +			} +			file.close();  		}  	}; diff --git a/indra/test/test.cpp b/indra/test/test.cpp index f573d53ba8..4a9b2825f2 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -43,8 +43,8 @@  #include "llerrorcontrol.h"  #include "lltut.h" -#include <apr-1/apr_pools.h> -#include <apr-1/apr_getopt.h> +#include "apr_pools.h" +#include "apr_getopt.h"  // the CTYPE_WORKAROUND is needed for linux dev stations that don't  // have the broken libc6 packages needed by our out-of-date static  @@ -62,13 +62,14 @@ namespace tut  class LLTestCallback : public tut::callback  {  public: -	LLTestCallback(bool verbose_mode) : +	LLTestCallback(bool verbose_mode, std::ostream *stream) :  		mVerboseMode(verbose_mode),  		mTotalTests(0),  		mPassedTests(0),  		mFailedTests(0),  		mSkippedTests(0), -		mSkipedFailTests(0) +		mSkippedFailTests(0), +		mStream(stream)  	{  	} @@ -109,7 +110,7 @@ public:  			out << "skipped";  			break;  		case tut::test_result::skip_fail: -			++mSkipedFailTests; +			++mSkippedFailTests;  			out << "skipped known failure";  			break;  		default: @@ -122,34 +123,57 @@ public:  			{  				out << ": '" << tr.message << "'";  			} +			if (mStream) +			{ +				*mStream << out.str() << std::endl; +			} +			  			std::cout << out.str() << std::endl;  		}  	}  	void run_completed()  	{ -		std::cout << std::endl; -		std::cout << "Total Tests:   " << mTotalTests << std::endl; -		std::cout << "Passed Tests: " << mPassedTests << std::endl; +		if (mStream) +		{ +			run_completed_(*mStream); +		} +		run_completed_(std::cout); + +		if (mFailedTests > 0) +		{ +			exit(1); +		} +	} +	 +private: +	void run_completed_(std::ostream &stream) +	{ +		stream << std::endl; +		stream << "Total Tests:   " << mTotalTests << std::endl; +		stream << "Passed Tests: " << mPassedTests << std::endl; + +		stream << std::endl; +		stream << "Total Tests:   " << mTotalTests << std::endl; +		stream << "Passed Tests: " << mPassedTests << std::endl;  		if (mSkippedTests > 0)  		{ -			std::cout << "Skipped Tests: " << mSkippedTests << std::endl; +			stream << "Skipped Tests: " << mSkippedTests << std::endl;  		} -		if (mSkipedFailTests > 0) +		if (mSkippedFailTests > 0)  		{ -			std::cout << "Skipped known failures: " << mSkipedFailTests +			stream << "Skipped known failures: " << mSkippedFailTests  				<< std::endl;  		}  		if(mFailedTests > 0)  		{ -			std::cout << "*********************************" << std::endl; -			std::cout << "Failed Tests:   " << mFailedTests << std::endl; -			std::cout << "Please report or fix the problem." << std::endl; -			std::cout << "*********************************" << std::endl; -			exit(1); +			stream << "*********************************" << std::endl; +			stream << "Failed Tests:   " << mFailedTests << std::endl; +			stream << "Please report or fix the problem." << std::endl; +			stream << "*********************************" << std::endl;  		}  	} @@ -159,7 +183,8 @@ protected:  	int mPassedTests;  	int mFailedTests;  	int mSkippedTests; -	int mSkipedFailTests; +	int mSkippedFailTests; +	std::ostream *mStream;  };  static const apr_getopt_option_t TEST_CL_OPTIONS[] = @@ -168,7 +193,9 @@ static const apr_getopt_option_t TEST_CL_OPTIONS[] =  	{"list", 'l', 0, "List available test groups."},  	{"verbose", 'v', 0, "Verbose output."},  	{"group", 'g', 1, "Run test group specified by option argument."}, +	{"output", 'o', 1, "Write output to the named file."},  	{"skip", 's', 1, "Skip test number specified by option argument. Only works when a specific group is being tested"}, +	{"touch", 't', 1, "Touch the given file if all tests succeed"},  	{"wait", 'w', 0, "Wait for input before exit."},  	{"debug", 'd', 0, "Emit full debug logs."},  	{0, 0, 0, 0} @@ -256,6 +283,9 @@ int main(int argc, char **argv)  	apr_status_t apr_err;  	const char* opt_arg = NULL;  	int opt_id = 0; +	std::ofstream *output = NULL; +	const char *touch = NULL; +	  	while(true)  	{  		apr_err = apr_getopt_long(os, TEST_CL_OPTIONS, &opt_id, &opt_arg); @@ -285,6 +315,13 @@ int main(int argc, char **argv)  		case 'v':  			verbose_mode = true;  			break; +		case 'o': +			output = new std::ofstream; +			output->open(opt_arg); +			break; +		case 't': +			touch = opt_arg; +			break;  		case 'w':  			wait_at_exit = true;  			break; @@ -301,7 +338,7 @@ int main(int argc, char **argv)  	}  	// run the tests -	LLTestCallback callback(verbose_mode); +	LLTestCallback callback(verbose_mode, output);  	tut::runner.get().set_callback(&callback);  	if(test_group.empty()) @@ -319,6 +356,20 @@ int main(int argc, char **argv)  		std::cin.get();  	} +	if (output) +	{ +		output->close(); +		delete output; +	} + +	if (touch) +	{ +		std::ofstream s; +		s.open(touch); +		s << "ok" << std::endl; +		s.close(); +	} +	  	apr_terminate();  	return 0;  }  | 
