summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2011-07-13 17:36:59 -0400
committerNat Goodspeed <nat@lindenlab.com>2011-07-13 17:36:59 -0400
commit0f665666201146069647d1686e2ff565d469097b (patch)
tree9b5a4ef8f508f090ac8418a1b5f1ac4d7205a772 /indra
parented648b1f08a191250c5c37f831280c31950b502a (diff)
Introduce support for C++ integration tests running Python scripts.
This is in its infancy; tested on Mac; needs to be ironed out on Windows and Linux. Goal is to test at least some cross-language LLSD serialization.
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/CMakeLists.txt3
-rw-r--r--indra/llcommon/tests/llsdserialize_test.cpp97
-rw-r--r--indra/llcommon/tests/setpython.py19
3 files changed, 103 insertions, 16 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 9910281b64..c755020a64 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -317,7 +317,8 @@ if (LL_TESTS)
LL_ADD_INTEGRATION_TEST(lllazy "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llprocessor "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")
- LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}")
+ LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}"
+ "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/setpython.py")
LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")
LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}")
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index 7b4c7d6a48..75b79467b7 100644
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
@@ -25,33 +25,26 @@
* $/LicenseInfo$
*/
-#if !LL_WINDOWS
-#include <netinet/in.h>
-#endif
-
#include "linden_common.h"
#include "../llsd.h"
#include "../llsdserialize.h"
#include "../llformat.h"
#include "../test/lltut.h"
-
+#include "llprocesslauncher.h"
+#include "stringize.h"
#if LL_WINDOWS
#include <winsock2.h>
typedef U32 uint32_t;
+#else
+#include <netinet/in.h>
+#include <errno.h>
#endif
-std::vector<U8> string_to_vector(std::string str)
+std::vector<U8> string_to_vector(const std::string& str)
{
- // bc LLSD can't...
- size_t len = (size_t)str.length();
- std::vector<U8> v(len);
- for (size_t i = 0; i < len ; i++)
- {
- v[i] = str[i];
- }
- return v;
+ return std::vector<U8>(str.begin(), str.end());
}
namespace tut
@@ -1494,5 +1487,79 @@ namespace tut
ensureBinaryAndNotation("map", test);
ensureBinaryAndXML("map", test);
}
-}
+ struct TestPythonCompatible
+ {
+ TestPythonCompatible() {}
+ ~TestPythonCompatible() {}
+
+ void python(const std::string& desc, const std::string& script, F32 timeout=5)
+ {
+ const char* PYTHON(getenv("PYTHON"));
+ ensure("Set $PYTHON to the Python interpreter", PYTHON);
+ LLProcessLauncher py;
+ py.setExecutable(PYTHON);
+ py.addArgument("-c");
+ py.addArgument(script);
+ ensure_equals(STRINGIZE("Couldn't launch " << desc << " script"), py.launch(), 0);
+
+#if LL_WINDOWS
+ ensure_equals(STRINGIZE(desc << " script ran beyond "
+ << std::fixed << std::setprecision(1)
+ << timeout << " seconds"),
+ WaitForSingleObject(py.getProcessHandle(), DWORD(timeout * 1000)),
+ WAIT_OBJECT_0);
+ DWORD rc(0);
+ GetExitCodeProcess(py.getProcessHandle(), &rc);
+ ensure_equals(STRINGIZE(desc << " script terminated with rc " << rc), rc, 0);
+#else
+ // Implementing timeout would mean messing with alarm() and
+ // catching SIGALRM... later maybe...
+ int status(0);
+ if (waitpid(py.getProcessID(), &status, 0) == -1)
+ {
+ int waitpid_errno(errno);
+ ensure_equals(STRINGIZE("Couldn't retrieve rc from " << desc << " script: "
+ "waitpid() errno " << waitpid_errno),
+ waitpid_errno, ECHILD);
+ }
+ else
+ {
+ if (WIFEXITED(status))
+ {
+ int rc(WEXITSTATUS(status));
+ ensure_equals(STRINGIZE(desc << " script terminated with rc " << rc), rc, 0);
+ }
+ else if (WIFSIGNALED(status))
+ {
+ ensure(STRINGIZE(desc << " script terminated by signal " << WTERMSIG(status)),
+ false);
+ }
+ else
+ {
+ ensure(STRINGIZE(desc << " script produced impossible status " << status),
+ false);
+ }
+ }
+#endif
+ }
+ };
+
+ typedef tut::test_group<TestPythonCompatible> TestPythonCompatibleGroup;
+ typedef TestPythonCompatibleGroup::object TestPythonCompatibleObject;
+ TestPythonCompatibleGroup pycompat("LLSD serialize Python compatibility");
+
+ template<> template<>
+ void TestPythonCompatibleObject::test<1>()
+ {
+ python("hello", "print 'Hello, world!'");
+ }
+
+ template<> template<>
+ void TestPythonCompatibleObject::test<2>()
+ {
+ python("platform",
+"import sys\n"
+"print 'Running on', sys.platform");
+ }
+}
diff --git a/indra/llcommon/tests/setpython.py b/indra/llcommon/tests/setpython.py
new file mode 100644
index 0000000000..df7b90428e
--- /dev/null
+++ b/indra/llcommon/tests/setpython.py
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+"""\
+@file setpython.py
+@author Nat Goodspeed
+@date 2011-07-13
+@brief Set PYTHON environment variable for tests that care.
+
+$LicenseInfo:firstyear=2011&license=viewerlgpl$
+Copyright (c) 2011, Linden Research, Inc.
+$/LicenseInfo$
+"""
+
+import os
+import sys
+import subprocess
+
+if __name__ == "__main__":
+ os.environ["PYTHON"] = sys.executable
+ sys.exit(subprocess.call(sys.argv[1:]))