summaryrefslogtreecommitdiff
path: root/indra/test
diff options
context:
space:
mode:
authorBryan O'Sullivan <bos@lindenlab.com>2008-06-02 21:14:31 +0000
committerBryan O'Sullivan <bos@lindenlab.com>2008-06-02 21:14:31 +0000
commit9db949eec327df4173fde3de934a87bedb0db13c (patch)
treeaeffa0f0e68b1d2ceb74d460cbbd22652c9cd159 /indra/test
parent419e13d0acaabf5e1e02e9b64a07648bce822b2f (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.txt152
-rw-r--r--indra/test/io.cpp14
-rw-r--r--indra/test/llblowfish_tut.cpp14
-rw-r--r--indra/test/llhttpdate_tut.cpp31
-rw-r--r--indra/test/lliohttpserver_tut.cpp4
-rw-r--r--indra/test/llmessagetemplateparser_tut.cpp2
-rwxr-xr-xindra/test/llsdmessagereader_tut.cpp4
-rw-r--r--indra/test/llsdutil_tut.cpp8
-rw-r--r--indra/test/lltemplatemessagebuilder_tut.cpp4
-rw-r--r--indra/test/message_tut.cpp49
-rw-r--r--indra/test/test.cpp87
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;
}