THRIFT-3437 Fixed MinGW-w64 build
Client: Build
Patch: Antonio Di Monaco

This closes #771
diff --git a/lib/cpp/test/CMakeLists.txt b/lib/cpp/test/CMakeLists.txt
index 5d017b4..7fb2aa3 100644
--- a/lib/cpp/test/CMakeLists.txt
+++ b/lib/cpp/test/CMakeLists.txt
@@ -23,6 +23,10 @@
 include_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
 include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}")
 
+if (WITH_DYN_LINK_TEST)
+    add_definitions( -DBOOST_TEST_DYN_LINK )
+endif()
+
 #Make sure gen-cpp files can be included
 include_directories("${CMAKE_CURRENT_BINARY_DIR}")
 
@@ -106,7 +110,7 @@
     ${Boost_LIBRARIES}
 )
 LINK_AGAINST_THRIFT_LIBRARY(TInterruptTest thrift)
-if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW)
 target_link_libraries(TInterruptTest -lrt)
 endif ()
 add_test(NAME TInterruptTest COMMAND TInterruptTest "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys")
@@ -117,7 +121,7 @@
     ${Boost_LIBRARIES}
 )
 LINK_AGAINST_THRIFT_LIBRARY(TServerIntegrationTest thrift)
-if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW)
 target_link_libraries(TServerIntegrationTest -lrt)
 endif ()
 add_test(NAME TServerIntegrationTest COMMAND TServerIntegrationTest)
@@ -303,7 +307,7 @@
     ${Boost_LIBRARIES}
 )
 LINK_AGAINST_THRIFT_LIBRARY(SecurityTest thrift)
-if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW)
 target_link_libraries(SecurityTest -lrt)
 endif ()
 add_test(NAME SecurityTest COMMAND SecurityTest "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys")
diff --git a/lib/cpp/test/OpenSSLManualInitTest.cpp b/lib/cpp/test/OpenSSLManualInitTest.cpp
index 6afd7ce..5cd5e48 100644
--- a/lib/cpp/test/OpenSSLManualInitTest.cpp
+++ b/lib/cpp/test/OpenSSLManualInitTest.cpp
@@ -67,6 +67,20 @@
   openssl_cleanup();
 }
 
+#ifdef BOOST_TEST_DYN_LINK
+bool init_unit_test_suite() {
+  boost::unit_test::test_suite* suite = &boost::unit_test::framework::master_test_suite();
+  suite->p_name.value = "OpenSSLManualInit";
+
+  suite->add(BOOST_TEST_CASE(test_openssl_availability));
+
+  return true;
+}
+ 
+int main( int argc, char* argv[] ) {
+  return ::boost::unit_test::unit_test_main(&init_unit_test_suite,argc,argv);
+}
+#else
 boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) {
   THRIFT_UNUSED_VARIABLE(argc);
   THRIFT_UNUSED_VARIABLE(argv);
@@ -77,3 +91,4 @@
 
   return NULL;
 }
+#endif
\ No newline at end of file
diff --git a/lib/cpp/test/SecurityTest.cpp b/lib/cpp/test/SecurityTest.cpp
index 213efd4..1369077 100644
--- a/lib/cpp/test/SecurityTest.cpp
+++ b/lib/cpp/test/SecurityTest.cpp
@@ -108,8 +108,8 @@
 
             pServerSocketFactory.reset(new TSSLSocketFactory(static_cast<apache::thrift::transport::SSLProtocol>(protocol)));
             pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
-            pServerSocketFactory->loadCertificate(certFile("server.crt").native().c_str());
-            pServerSocketFactory->loadPrivateKey(certFile("server.key").native().c_str());
+            pServerSocketFactory->loadCertificate(certFile("server.crt").string().c_str());
+            pServerSocketFactory->loadPrivateKey(certFile("server.key").string().c_str());
             pServerSocketFactory->server(true);
             pServerSocket.reset(new TSSLServerSocket("localhost", m_serverPort, pServerSocketFactory));
             boost::shared_ptr<TTransport> connectedClient;
@@ -160,9 +160,9 @@
             {
                 pClientSocketFactory.reset(new TSSLSocketFactory(static_cast<apache::thrift::transport::SSLProtocol>(protocol)));
                 pClientSocketFactory->authenticate(true);
-                pClientSocketFactory->loadCertificate(certFile("client.crt").native().c_str());
-                pClientSocketFactory->loadPrivateKey(certFile("client.key").native().c_str());
-                pClientSocketFactory->loadTrustedCertificates(certFile("CA.pem").native().c_str());
+                pClientSocketFactory->loadCertificate(certFile("client.crt").string().c_str());
+                pClientSocketFactory->loadPrivateKey(certFile("client.key").string().c_str());
+                pClientSocketFactory->loadTrustedCertificates(certFile("CA.pem").string().c_str());
                 pClientSocket = pClientSocketFactory->createSocket("localhost", m_serverPort);
                 pClientSocket->open();
 
diff --git a/lib/cpp/test/TFileTransportTest.cpp b/lib/cpp/test/TFileTransportTest.cpp
index 294c9a6..8551b78 100644
--- a/lib/cpp/test/TFileTransportTest.cpp
+++ b/lib/cpp/test/TFileTransportTest.cpp
@@ -30,6 +30,14 @@
 
 #include <thrift/transport/TFileTransport.h>
 
+#ifdef __MINGW32__
+  #include <io.h>
+  #include <unistd.h>
+  #include <sys/types.h>
+  #include <fcntl.h>
+  #include <sys\stat.h>
+#endif
+
 using namespace apache::thrift::transport;
 
 /**************************************************************************
@@ -91,6 +99,19 @@
 class TempFile {
 public:
   TempFile(const char* directory, const char* prefix) {
+  #ifdef __MINGW32__
+    size_t path_len = strlen(prefix) + 8;
+    path_ = new char[path_len];
+    snprintf(path_, path_len, "%sXXXXXX", prefix);
+    if (_mktemp_s(path_,path_len) == 0) {
+      fd_ = open(path_,O_CREAT | O_RDWR | O_BINARY,S_IREAD | S_IWRITE);
+      if (fd_ < 0) {
+        throw apache::thrift::TException("_mktemp_s() failed");
+      }
+    } else {
+      throw apache::thrift::TException("_mktemp_s() failed");
+    }
+  #else
     size_t path_len = strlen(directory) + strlen(prefix) + 8;
     path_ = new char[path_len];
     snprintf(path_, path_len, "%s/%sXXXXXX", directory, prefix);
@@ -99,6 +120,7 @@
     if (fd_ < 0) {
       throw apache::thrift::TException("mkstemp() failed");
     }
+  #endif
   }
 
   ~TempFile() {
@@ -367,6 +389,24 @@
   }
 }
 
+#ifdef BOOST_TEST_DYN_LINK
+static int myArgc = 0;
+static char **myArgv = NULL;
+ 
+bool init_unit_test_suite() {
+  boost::unit_test::framework::master_test_suite().p_name.value = "TFileTransportTest";
+ 
+  // Parse arguments
+  parse_args(myArgc,myArgv);
+  return true;
+}
+ 
+int main( int argc, char* argv[] ) {
+  myArgc = argc;
+  myArgv = argv;
+  return ::boost::unit_test::unit_test_main(&init_unit_test_suite,argc,argv);
+}
+#else 
 boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) {
   boost::unit_test::framework::master_test_suite().p_name.value = "TFileTransportTest";
 
@@ -374,3 +414,4 @@
   parse_args(argc, argv);
   return NULL;
 }
+#endif
\ No newline at end of file
diff --git a/lib/cpp/test/TSSLSocketInterruptTest.cpp b/lib/cpp/test/TSSLSocketInterruptTest.cpp
index c723d0e..f19b159 100644
--- a/lib/cpp/test/TSSLSocketInterruptTest.cpp
+++ b/lib/cpp/test/TSSLSocketInterruptTest.cpp
@@ -119,8 +119,8 @@
 
   pServerSocketFactory.reset(new TSSLSocketFactory());
   pServerSocketFactory->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
-  pServerSocketFactory->loadCertificate(certFile("server.crt").native().c_str());
-  pServerSocketFactory->loadPrivateKey(certFile("server.key").native().c_str());
+  pServerSocketFactory->loadCertificate(certFile("server.crt").string().c_str());
+  pServerSocketFactory->loadPrivateKey(certFile("server.key").string().c_str());
   pServerSocketFactory->server(true);
   return pServerSocketFactory;
 }
@@ -130,9 +130,9 @@
 
   pClientSocketFactory.reset(new TSSLSocketFactory());
   pClientSocketFactory->authenticate(true);
-  pClientSocketFactory->loadCertificate(certFile("client.crt").native().c_str());
-  pClientSocketFactory->loadPrivateKey(certFile("client.key").native().c_str());
-  pClientSocketFactory->loadTrustedCertificates(certFile("CA.pem").native().c_str());
+  pClientSocketFactory->loadCertificate(certFile("client.crt").string().c_str());
+  pClientSocketFactory->loadPrivateKey(certFile("client.key").string().c_str());
+  pClientSocketFactory->loadTrustedCertificates(certFile("CA.pem").string().c_str());
   return pClientSocketFactory;
 }
 
diff --git a/lib/cpp/test/TransportTest.cpp b/lib/cpp/test/TransportTest.cpp
index c056a5d..6cc2c87 100644
--- a/lib/cpp/test/TransportTest.cpp
+++ b/lib/cpp/test/TransportTest.cpp
@@ -1024,6 +1024,25 @@
 BOOST_GLOBAL_FIXTURE(global_fixture)
 #endif
 
+#ifdef BOOST_TEST_DYN_LINK
+bool init_unit_test_suite() {
+  struct timeval tv;
+  THRIFT_GETTIMEOFDAY(&tv, NULL);
+  int seed = tv.tv_sec ^ tv.tv_usec;
+
+  initrand(seed);
+
+  boost::unit_test::test_suite* suite = &boost::unit_test::framework::master_test_suite();
+  suite->p_name.value = "TransportTest";
+  TransportTestGen transport_test_generator(suite, 1);
+  transport_test_generator.generate();
+  return true;
+}
+
+int main( int argc, char* argv[] ) {
+  return ::boost::unit_test::unit_test_main(&init_unit_test_suite,argc,argv);
+}
+#else
 boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) {
   THRIFT_UNUSED_VARIABLE(argc);
   THRIFT_UNUSED_VARIABLE(argv);
@@ -1039,3 +1058,4 @@
   transport_test_generator.generate();
   return NULL;
 }
+#endif
diff --git a/lib/cpp/test/ZlibTest.cpp b/lib/cpp/test/ZlibTest.cpp
index fa237a2..e155970 100644
--- a/lib/cpp/test/ZlibTest.cpp
+++ b/lib/cpp/test/ZlibTest.cpp
@@ -412,6 +412,31 @@
   fprintf(f, "  --help\n");
 }
 
+#ifdef BOOST_TEST_DYN_LINK
+bool init_unit_test_suite() {
+  uint32_t seed = static_cast<uint32_t>(time(NULL));
+#ifdef HAVE_INTTYPES_H
+  printf("seed: %" PRIu32 "\n", seed);
+#endif
+  rng.seed(seed);
+
+  boost::unit_test::test_suite* suite = &boost::unit_test::framework::master_test_suite();
+  suite->p_name.value = "ZlibTest";
+
+  uint32_t buf_len = 1024 * 32;
+  add_tests(suite, gen_uniform_buffer(buf_len, 'a'), buf_len, "uniform");
+  add_tests(suite, gen_compressible_buffer(buf_len), buf_len, "compressible");
+  add_tests(suite, gen_random_buffer(buf_len), buf_len, "random");
+
+  suite->add(BOOST_TEST_CASE(test_no_write));
+
+  return true;
+}
+
+int main( int argc, char* argv[] ) {
+  return ::boost::unit_test::unit_test_main(&init_unit_test_suite,argc,argv);
+}
+#else
 boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) {
   THRIFT_UNUSED_VARIABLE(argc);
   THRIFT_UNUSED_VARIABLE(argv);
@@ -433,3 +458,4 @@
 
   return NULL;
 }
+#endif
diff --git a/lib/cpp/test/processor/ProcessorTest.cpp b/lib/cpp/test/processor/ProcessorTest.cpp
index 5aaa57e..0066657 100644
--- a/lib/cpp/test/processor/ProcessorTest.cpp
+++ b/lib/cpp/test/processor/ProcessorTest.cpp
@@ -908,9 +908,20 @@
 
 // TODO: We should test TEventServer in the future.
 // For now, it is known not to work correctly with TProcessorEventHandler.
+#ifdef BOOST_TEST_DYN_LINK
+bool init_unit_test_suite() {
+  unit_test::framework::master_test_suite().p_name.value = "ProcessorTest";
+  return true;
+}
+
+int main( int argc, char* argv[] ) {
+  return ::boost::unit_test::unit_test_main(&init_unit_test_suite,argc,argv);
+}
+#else
 unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) {
   THRIFT_UNUSED_VARIABLE(argc);
   THRIFT_UNUSED_VARIABLE(argv);
   unit_test::framework::master_test_suite().p_name.value = "ProcessorTest";
   return NULL;
 }
+#endif
diff --git a/lib/cpp/test/qt/TQTcpServerTest.cpp b/lib/cpp/test/qt/TQTcpServerTest.cpp
index 79c0dfc..0cad6a9 100644
--- a/lib/cpp/test/qt/TQTcpServerTest.cpp
+++ b/lib/cpp/test/qt/TQTcpServerTest.cpp
@@ -1,18 +1,20 @@
 #define BOOST_TEST_MODULE TQTcpServerTest
 #include <QTest>
-#include <boost/smart_ptr.hpp>
 #include <iostream>
 
 #include <QTcpServer>
 #include <QTcpSocket>
 #include <QHostAddress>
 
-#include "thrift/protocol/TBinaryProtocol.h"
-#include "thrift/async/TAsyncProcessor.h"
-#include "thrift/qt/TQTcpServer.h"
-#include "thrift/qt/TQIODeviceTransport.h"
-
-#include "gen-cpp/ParentService.h"
+#ifndef Q_MOC_RUN
+  #include <boost/smart_ptr.hpp>
+  #include "thrift/protocol/TBinaryProtocol.h"
+  #include "thrift/async/TAsyncProcessor.h"
+  #include "thrift/qt/TQTcpServer.h"
+  #include "thrift/qt/TQIODeviceTransport.h"
+  
+  #include "gen-cpp/ParentService.h"
+#endif
 
 using namespace apache::thrift;