THRIFT-2013: add multiplex server and client test support to cpp language
add multiplex client test support to csharp and java languages
fix a bug in the server-side header protocol factory
fix a bug in the cpp SSL server socket implementation
remove unnecessary sleep in cpp server testOneway

This closes #1414
diff --git a/test/ThriftTest.thrift b/test/ThriftTest.thrift
index c56f571..24dcbb9 100644
--- a/test/ThriftTest.thrift
+++ b/test/ThriftTest.thrift
@@ -321,13 +321,12 @@
 
 service SecondService
 {
-  void blahBlah()
   /**
    * Prints 'testString("%s")' with thing as '%s'
    * @param string thing - the string to print
    * @return string - returns the string 'thing'
    */
-  string       secondtestString(1: string thing),
+  string secondtestString(1: string thing)
 }
 
 struct VersioningTestV1 {
diff --git a/test/c_glib/src/thrift_second_service_handler.c b/test/c_glib/src/thrift_second_service_handler.c
index c464372..66ac7bc 100644
--- a/test/c_glib/src/thrift_second_service_handler.c
+++ b/test/c_glib/src/thrift_second_service_handler.c
@@ -50,17 +50,6 @@
   return TRUE;
 }
 
-gboolean
-second_service_handler_blah_blah (TTestSecondServiceIf *iface, GError **error)
-{
-  THRIFT_UNUSED_VAR (iface);
-  THRIFT_UNUSED_VAR (error);
-
-  printf ("blahBlah()\n");
-
-  return TRUE;
-}
-
 static void
 second_service_handler_init (SecondServiceHandler *self)
 {
@@ -76,7 +65,5 @@
 
   base_class->secondtest_string =
       second_service_handler_secondtest_string;
-  base_class->blah_blah =
-      second_service_handler_blah_blah;
 
 }
diff --git a/test/cpp/CMakeLists.txt b/test/cpp/CMakeLists.txt
index 1facfa4..cdd63db 100755
--- a/test/cpp/CMakeLists.txt
+++ b/test/cpp/CMakeLists.txt
@@ -34,6 +34,7 @@
 include_directories("${PROJECT_SOURCE_DIR}/lib/cpp/src")
 
 set(crosstestgencpp_SOURCES
+    gen-cpp/SecondService.cpp
     gen-cpp/ThriftTest.cpp
     gen-cpp/ThriftTest_types.cpp
     gen-cpp/ThriftTest_constants.cpp
@@ -44,7 +45,7 @@
 
 set(crossstressgencpp_SOURCES
     gen-cpp/Service.cpp
-    #gen-cpp/StressTest_types.cpp #basically empty, so omitting
+    gen-cpp/StressTest_types.cpp
     gen-cpp/StressTest_constants.cpp
 )
 add_library(crossstressgencpp STATIC ${crossstressgencpp_SOURCES})
@@ -79,7 +80,7 @@
 # Common thrift code generation rules
 #
 
-add_custom_command(OUTPUT gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_constants.cpp
+add_custom_command(OUTPUT gen-cpp/SecondService.cpp gen-cpp/SecondService.h gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest.h gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_constants.cpp
     COMMAND ${THRIFT_COMPILER} --gen cpp:templates,cob_style -r ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
 )
 
diff --git a/test/cpp/Makefile.am b/test/cpp/Makefile.am
index 359e7e6..e8be80a 100755
--- a/test/cpp/Makefile.am
+++ b/test/cpp/Makefile.am
@@ -21,12 +21,16 @@
 BUILT_SOURCES = gen-cpp/ThriftTest.cpp \
                 gen-cpp/ThriftTest_types.cpp \
                 gen-cpp/ThriftTest_constants.cpp \
+                gen-cpp/SecondService.cpp \
                 gen-cpp/StressTest_types.cpp \
                 gen-cpp/StressTest_constants.cpp \
                 gen-cpp/Service.cpp
 
 noinst_LTLIBRARIES = libtestgencpp.la libstresstestgencpp.la
 nodist_libtestgencpp_la_SOURCES = \
+	gen-cpp/SecondService.cpp \
+	gen-cpp/SecondService.h \
+	gen-cpp/SecondService.tcc \
 	gen-cpp/ThriftTest_constants.cpp \
 	gen-cpp/ThriftTest_constants.h \
 	gen-cpp/ThriftTest_types.cpp \
@@ -98,7 +102,7 @@
 #
 # Common thrift code generation rules
 #
-gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_constants.cpp: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
+gen-cpp/ThriftTest.cpp gen-cpp/ThriftTest_types.cpp gen-cpp/ThriftTest_constants.cpp gen-cpp/SecondService.cpp gen-cpp/SecondService.h gen-cpp/SecondService.tcc: $(top_srcdir)/test/ThriftTest.thrift $(THRIFT)
 	$(THRIFT) --gen cpp:templates,cob_style -r $<
 
 gen-cpp/StressTest_types.cpp gen-cpp/StressTest_constants.cpp gen-cpp/Service.cpp: $(top_srcdir)/test/StressTest.thrift $(THRIFT)
diff --git a/test/cpp/src/TestClient.cpp b/test/cpp/src/TestClient.cpp
index 6b2e731..6e7ff8e 100644
--- a/test/cpp/src/TestClient.cpp
+++ b/test/cpp/src/TestClient.cpp
@@ -26,6 +26,7 @@
 #include <thrift/protocol/TCompactProtocol.h>
 #include <thrift/protocol/THeaderProtocol.h>
 #include <thrift/protocol/TJSONProtocol.h>
+#include <thrift/protocol/TMultiplexedProtocol.h>
 #include <thrift/transport/THttpClient.h>
 #include <thrift/transport/TTransportUtils.h>
 #include <thrift/transport/TSocket.h>
@@ -40,13 +41,15 @@
 #include <inttypes.h>
 #endif
 
-#include <boost/program_options.hpp>
+#include <boost/algorithm/string.hpp>
 #include <boost/filesystem.hpp>
+#include <boost/program_options.hpp>
 #include <thrift/stdcxx.h>
 #if _WIN32
 #include <thrift/windows/TWinsockSingleton.h>
 #endif
 
+#include "SecondService.h"
 #include "ThriftTest.h"
 
 using namespace std;
@@ -156,28 +159,33 @@
   int return_code = 0;
 
   boost::program_options::options_description desc("Allowed options");
-  desc.add_options()("help,h",
-                     "produce help message")("host",
-                                             boost::program_options::value<string>(&host)
-                                                 ->default_value(host),
-                                             "Host to connect")("port",
-                                                                boost::program_options::value<int>(
-                                                                    &port)->default_value(port),
-                                                                "Port number to connect")(
-      "domain-socket",
-      boost::program_options::value<string>(&domain_socket)->default_value(domain_socket),
-      "Domain Socket (e.g. /tmp/ThriftTest.thrift), instead of host and port")(
-      "abstract-namespace",
-      "Look for the domain socket in the Abstract Namespace (no connection with filesystem pathnames)")(
-      "transport",
-      boost::program_options::value<string>(&transport_type)->default_value(transport_type),
-      "Transport: buffered, framed, http, evhttp")(
-      "protocol",
-      boost::program_options::value<string>(&protocol_type)->default_value(protocol_type),
-      "Protocol: binary, header, compact, json")("ssl", "Encrypted Transport using SSL")(
-      "testloops,n",
-      boost::program_options::value<int>(&numTests)->default_value(numTests),
-      "Number of Tests")("noinsane", "Do not run insanity test");
+  desc.add_options()
+      ("help,h", "produce help message")
+      ("host", 
+          boost::program_options::value<string>(&host)->default_value(host), 
+          "Host to connect")
+      ("port", 
+          boost::program_options::value<int>(&port)->default_value(port), 
+          "Port number to connect")
+      ("domain-socket", 
+          boost::program_options::value<string>(&domain_socket)->default_value(domain_socket),
+          "Domain Socket (e.g. /tmp/ThriftTest.thrift), instead of host and port")
+      ("abstract-namespace",
+          "Look for the domain socket in the Abstract Namespace"
+          " (no connection with filesystem pathnames)")
+      ("transport",
+          boost::program_options::value<string>(&transport_type)->default_value(transport_type),
+          "Transport: buffered, framed, http, evhttp")
+      ("protocol",
+          boost::program_options::value<string>(&protocol_type)->default_value(protocol_type),
+          "Protocol: binary, compact, header, json, multi, multic, multih, multij")
+      ("ssl", 
+          "Encrypted Transport using SSL")
+      ("testloops,n",
+          boost::program_options::value<int>(&numTests)->default_value(numTests),
+          "Number of Tests")
+      ("noinsane",
+          "Do not run insanity test");
 
   boost::program_options::variables_map vm;
   boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
@@ -194,6 +202,10 @@
       } else if (protocol_type == "compact") {
       } else if (protocol_type == "header") {
       } else if (protocol_type == "json") {
+      } else if (protocol_type == "multi") {
+      } else if (protocol_type == "multic") {
+      } else if (protocol_type == "multih") {
+      } else if (protocol_type == "multij") {
       } else {
         throw invalid_argument("Unknown protocol type " + protocol_type);
       }
@@ -232,6 +244,7 @@
   stdcxx::shared_ptr<TSocket> socket;
   stdcxx::shared_ptr<TTransport> transport;
   stdcxx::shared_ptr<TProtocol> protocol;
+  stdcxx::shared_ptr<TProtocol> protocol2;	// SecondService for multiplexed
 
   if (ssl) {
     cout << "Client Certificate File: " << certPath << endl;
@@ -271,18 +284,20 @@
     transport = bufferedSocket;
   }
 
-  if (protocol_type.compare("json") == 0) {
-    stdcxx::shared_ptr<TProtocol> jsonProtocol(new TJSONProtocol(transport));
-    protocol = jsonProtocol;
-  } else if (protocol_type.compare("compact") == 0) {
-    stdcxx::shared_ptr<TProtocol> compactProtocol(new TCompactProtocol(transport));
-    protocol = compactProtocol;
-  } else if (protocol_type == "header") {
-    stdcxx::shared_ptr<TProtocol> headerProtocol(new THeaderProtocol(transport));
-    protocol = headerProtocol;
+  if (protocol_type == "json" || protocol_type == "multij") {
+    protocol = stdcxx::make_shared<TJSONProtocol>(transport);
+  } else if (protocol_type == "compact" || protocol_type == "multic") {
+    protocol = stdcxx::make_shared<TCompactProtocol>(transport);
+  } else if (protocol_type == "header" || protocol_type == "multih") {
+    protocol = stdcxx::make_shared<THeaderProtocol>(transport);
   } else {
-    stdcxx::shared_ptr<TBinaryProtocol> binaryProtocol(new TBinaryProtocol(transport));
-    protocol = binaryProtocol;
+    protocol = stdcxx::make_shared<TBinaryProtocol>(transport);
+  }
+
+  if (boost::starts_with(protocol_type, "multi")) {
+	protocol2 = stdcxx::make_shared<TMultiplexedProtocol>(protocol, "SecondService");
+	// we don't need access to the original protocol any more, so...
+	protocol = stdcxx::make_shared<TMultiplexedProtocol>(protocol, "ThriftTest");
   }
 
   // Connection info
@@ -367,6 +382,25 @@
       return_code |= ERR_BASETYPES;
     }
 
+    //
+    // Multiplexed protocol - call another service method
+    // in the middle of the ThriftTest
+    //
+    if (boost::starts_with(protocol_type, "multi")) {
+		SecondServiceClient ssc(protocol2);
+		// transport is already open...
+		  
+        try {
+          cout << "secondService.secondTestString(\"foo\") => " << flush;
+	  	  std::string result;
+		  ssc.secondtestString(result, "foo");
+		  cout << "{" << result << "}" << endl;
+	    } catch (std::exception& e) {
+		  cout << "  *** FAILED *** " << e.what() << endl;
+		  return_code |= ERR_EXCEPTIONS;
+		}
+    }
+
     try {
 #ifdef _MSC_VER
 #pragma warning( push )
@@ -1096,12 +1130,14 @@
     /**
      * I32 TEST
      */
-    cout << "re-test testI32(-1)";
+    cout << "re-test testI32(-1)" << flush;
     int i32 = testClient.testI32(-1);
     cout << " = " << i32 << endl;
     if (i32 != -1)
       return_code |= ERR_BASETYPES;
 
+    cout << endl << "All tests done." << endl << flush;
+    
     uint64_t stop = now();
     uint64_t tot = stop - start;
 
@@ -1115,10 +1151,10 @@
       time_max = tot;
     }
 
+    cout << flush;
     transport->close();
   }
 
-  cout << endl << "All tests done." << endl;
 
   uint64_t time_avg = time_tot / numTests;
 
diff --git a/test/cpp/src/TestServer.cpp b/test/cpp/src/TestServer.cpp
index 37d0eb6..744a86c 100644
--- a/test/cpp/src/TestServer.cpp
+++ b/test/cpp/src/TestServer.cpp
@@ -17,26 +17,29 @@
  * under the License.
  */
 
-#include <thrift/concurrency/ThreadManager.h>
+#include <thrift/async/TAsyncBufferProcessor.h>
+#include <thrift/async/TAsyncProtocolProcessor.h>
+#include <thrift/async/TEvhttpServer.h>
 #include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/concurrency/ThreadManager.h>
+#include <thrift/processor/TMultiplexedProcessor.h>
 #include <thrift/protocol/TBinaryProtocol.h>
 #include <thrift/protocol/TCompactProtocol.h>
 #include <thrift/protocol/THeaderProtocol.h>
 #include <thrift/protocol/TJSONProtocol.h>
-#include <thrift/server/TSimpleServer.h>
-#include <thrift/server/TThreadedServer.h>
-#include <thrift/server/TThreadPoolServer.h>
-#include <thrift/async/TEvhttpServer.h>
-#include <thrift/async/TAsyncBufferProcessor.h>
-#include <thrift/async/TAsyncProtocolProcessor.h>
 #include <thrift/server/TNonblockingServer.h>
-#include <thrift/transport/TServerSocket.h>
-#include <thrift/transport/TSSLServerSocket.h>
-#include <thrift/transport/TSSLSocket.h>
-#include <thrift/transport/TNonblockingServerSocket.h>
+#include <thrift/server/TSimpleServer.h>
+#include <thrift/server/TThreadPoolServer.h>
+#include <thrift/server/TThreadedServer.h>
 #include <thrift/transport/THttpServer.h>
 #include <thrift/transport/THttpTransport.h>
+#include <thrift/transport/TNonblockingServerSocket.h>
+#include <thrift/transport/TSSLServerSocket.h>
+#include <thrift/transport/TSSLSocket.h>
+#include <thrift/transport/TServerSocket.h>
 #include <thrift/transport/TTransportUtils.h>
+
+#include "SecondService.h"
 #include "ThriftTest.h"
 
 #ifdef HAVE_STDINT_H
@@ -50,6 +53,7 @@
 #include <stdexcept>
 #include <sstream>
 
+#include <boost/algorithm/string.hpp>
 #include <boost/program_options.hpp>
 #include <boost/filesystem.hpp>
 #include <thrift/stdcxx.h>
@@ -331,13 +335,18 @@
     }
   }
 
-  void testOneway(const int32_t sleepFor) {
-    printf("testOneway(%d): Sleeping...\n", sleepFor);
-    THRIFT_SLEEP_SEC(sleepFor);
-    printf("testOneway(%d): done sleeping!\n", sleepFor);
+  void testOneway(const int32_t aNum) {
+    printf("testOneway(%d): call received\n", aNum);
   }
 };
 
+class SecondHandler : public SecondServiceIf
+{
+  public:
+    void secondtestString(std::string& result, const std::string& thing)
+    { result = "testString(\"" + thing + "\")"; }
+};	
+
 class TestProcessorEventHandler : public TProcessorEventHandler {
   virtual void* getContext(const char* fn_name, void* serverContext) {
     (void)serverContext;
@@ -565,7 +574,7 @@
     ("abstract-namespace", "Create the domain socket in the Abstract Namespace (no connection with filesystem pathnames)")
     ("server-type", po::value<string>(&server_type)->default_value(server_type), "type of server, \"simple\", \"thread-pool\", \"threaded\", or \"nonblocking\"")
     ("transport", po::value<string>(&transport_type)->default_value(transport_type), "transport: buffered, framed, http")
-    ("protocol", po::value<string>(&protocol_type)->default_value(protocol_type), "protocol: binary, compact, header, json")
+    ("protocol", po::value<string>(&protocol_type)->default_value(protocol_type), "protocol: binary, compact, header, json, multi, multic, multih, multij")
     ("ssl", "Encrypted Transport using SSL")
     ("processor-events", "processor-events")
     ("workers,n", po::value<size_t>(&workers)->default_value(workers), "Number of thread pools workers. Only valid for thread-pool server type")
@@ -597,6 +606,10 @@
       } else if (protocol_type == "compact") {
       } else if (protocol_type == "json") {
       } else if (protocol_type == "header") {
+      } else if (protocol_type == "multi") {	// multiplexed binary
+      } else if (protocol_type == "multic") {	// multiplexed compact
+      } else if (protocol_type == "multih") {	// multiplexed header
+      } else if (protocol_type == "multij") {	// multiplexed json
       } else {
         throw invalid_argument("Unknown protocol type " + protocol_type);
       }
@@ -627,15 +640,15 @@
 
   // Dispatcher
   stdcxx::shared_ptr<TProtocolFactory> protocolFactory;
-  if (protocol_type == "json") {
+  if (protocol_type == "json" || protocol_type == "multij") {
     stdcxx::shared_ptr<TProtocolFactory> jsonProtocolFactory(new TJSONProtocolFactory());
     protocolFactory = jsonProtocolFactory;
-  } else if (protocol_type == "compact") {
+  } else if (protocol_type == "compact" || protocol_type == "multic") {
     TCompactProtocolFactoryT<TBufferBase> *compactProtocolFactory = new TCompactProtocolFactoryT<TBufferBase>();
     compactProtocolFactory->setContainerSizeLimit(container_limit);
     compactProtocolFactory->setStringSizeLimit(string_limit);
     protocolFactory.reset(compactProtocolFactory);
-  } else if (protocol_type == "header") {
+  } else if (protocol_type == "header" || protocol_type == "multih") {
     stdcxx::shared_ptr<TProtocolFactory> headerProtocolFactory(new THeaderProtocolFactory());
     protocolFactory = headerProtocolFactory;
   } else {
@@ -645,9 +658,9 @@
     protocolFactory.reset(binaryProtocolFactory);
   }
 
-  // Processor
+  // Processors
   stdcxx::shared_ptr<TestHandler> testHandler(new TestHandler());
-  stdcxx::shared_ptr<ThriftTestProcessor> testProcessor(new ThriftTestProcessor(testHandler));
+  stdcxx::shared_ptr<TProcessor> testProcessor(new ThriftTestProcessor(testHandler));
 
   if (vm.count("processor-events")) {
     testProcessor->setEventHandler(
@@ -706,6 +719,18 @@
   }
   cout << endl;
 
+  // Multiplexed Processor if needed
+  if (boost::starts_with(protocol_type, "multi")) {
+    stdcxx::shared_ptr<SecondHandler> secondHandler(new SecondHandler());
+    stdcxx::shared_ptr<SecondServiceProcessor> secondProcessor(new SecondServiceProcessor(secondHandler));
+
+    stdcxx::shared_ptr<TMultiplexedProcessor> multiplexedProcessor(new TMultiplexedProcessor());
+    multiplexedProcessor->registerDefault(testProcessor); // non-multi clients go to the default processor (multi:binary, multic:compact, ...)
+    multiplexedProcessor->registerProcessor("ThriftTest", testProcessor);
+    multiplexedProcessor->registerProcessor("SecondService", secondProcessor);
+    testProcessor = stdcxx::dynamic_pointer_cast<TProcessor>(multiplexedProcessor);
+  }
+
   // Server
   stdcxx::shared_ptr<apache::thrift::server::TServer> server;
 
diff --git a/test/csharp/TestClient.cs b/test/csharp/TestClient.cs
index fad1057..17e5978 100644
--- a/test/csharp/TestClient.cs
+++ b/test/csharp/TestClient.cs
@@ -33,7 +33,7 @@
 {
     public class TestClient
     {
-        private class TestParams
+        public class TestParams
         {
             public int numIterations = 1;
             public string host = "localhost";
@@ -44,6 +44,7 @@
             public bool framed;
             public string protocol;
             public bool encrypted = false;
+            public bool multiplexed = false;
             protected bool _isFirstTransport = true;
 
 
@@ -105,21 +106,30 @@
         private const int ErrorStructs = 2;
         private const int ErrorContainers = 4;
         private const int ErrorExceptions = 8;
+        private const int ErrorProtocol = 16;
         private const int ErrorUnknown = 64;
 
         private class ClientTest
         {
+            private readonly TestParams param;
             private readonly TTransport transport;
+            private readonly SecondService.Client second;
             private readonly ThriftTest.Client client;
             private readonly int numIterations;
             private bool done;
 
             public int ReturnCode { get; set; }
 
-            public ClientTest(TestParams param)
+            public ClientTest(TestParams paramin)
             {
+                param = paramin;
                 transport = param.CreateTransport();
-                client = new ThriftTest.Client(param.CreateProtocol(transport));
+                TProtocol protocol = param.CreateProtocol(transport);
+                if (param.multiplexed)
+                {
+                    second = new SecondService.Client(new TMultiplexedProtocol(protocol, "SecondService"));
+                }
+                client = new ThriftTest.Client(protocol);
                 numIterations = param.numIterations;
             }
             public void Execute()
@@ -148,7 +158,7 @@
 
                     try
                     {
-                        ReturnCode |= ExecuteClientTest(client);
+                        ReturnCode |= ExecuteClientTest(client, second, param);
                     }
                     catch (Exception ex)
                     {
@@ -215,12 +225,12 @@
                         {
                             numThreads = Convert.ToInt32(args[++i]);
                         }
-                        else if (args[i] == "--compact" || args[i] == "--protocol=compact")
+                        else if (args[i] == "--compact" || args[i] == "--protocol=compact" || args[i] == "--protocol=multic")
                         {
                             param.protocol = "compact";
                             Console.WriteLine("Using compact protocol");
                         }
-                        else if (args[i] == "--json" || args[i] == "--protocol=json")
+                        else if (args[i] == "--json" || args[i] == "--protocol=json" || args[i] == "--protocol=multij")
                         {
                             param.protocol = "json";
                             Console.WriteLine("Using JSON protocol");
@@ -230,6 +240,11 @@
                             param.encrypted = true;
                             Console.WriteLine("Using encrypted transport");
                         }
+
+                        if (args[i].StartsWith("--protocol=multi"))
+                        {
+                            param.multiplexed = true;
+                        }
                     }
                 }
                 catch (Exception ex)
@@ -296,7 +311,7 @@
             return retval;
         }
 
-        public static int ExecuteClientTest(ThriftTest.Client client)
+        public static int ExecuteClientTest(ThriftTest.Client client, SecondService.Client second, TestParams param)
         {
             int returnCode = 0;
 
@@ -313,6 +328,18 @@
                 returnCode |= ErrorBaseTypes;
             }
 
+            if (param.multiplexed)
+            {
+                Console.WriteLine("secondTestString(\"Test2\")");
+                s = second.secondtestString("Test2");
+              Console.WriteLine(" = \"" + s + "\"");
+              if ("testString(\"Test2\")" != s)
+              {
+                  Console.WriteLine("*** FAILED ***");
+                  returnCode |= ErrorProtocol;
+              }
+            }
+
             Console.Write("testBool(true)");
             bool t = client.testBool((bool)true);
             Console.WriteLine(" = " + t);
diff --git a/test/features/known_failures_Linux.json b/test/features/known_failures_Linux.json
index e3575f9..f96356d 100644
--- a/test/features/known_failures_Linux.json
+++ b/test/features/known_failures_Linux.json
@@ -1,6 +1,10 @@
 [
   "c_glib-limit_container_length_binary_buffered-ip",
   "c_glib-limit_string_length_binary_buffered-ip",
+  "cpp-theader_framed_binary_multih-header_buffered-ip",
+  "cpp-theader_framed_compact_multih-header_buffered-ip",
+  "cpp-theader_unframed_binary_multih-header_buffered-ip",
+  "cpp-theader_unframed_compact_multih-header_buffered-ip",
   "csharp-limit_container_length_binary_buffered-ip",
   "csharp-limit_container_length_compact_buffered-ip",
   "csharp-limit_string_length_binary_buffered-ip",
@@ -33,8 +37,10 @@
   "rb-limit_string_length_accel-binary_buffered-ip",
   "rb-limit_string_length_binary_buffered-ip",
   "rb-limit_string_length_compact_buffered-ip",
+  "rs-limit_container_length_binary_buffered-ip",
+  "rs-limit_container_length_compact_buffered-ip",
+  "rs-limit_container_length_multic-compact_buffered-ip",
   "rs-limit_string_length_binary_buffered-ip",
   "rs-limit_string_length_compact_buffered-ip",
-  "rs-limit_container_length_binary_buffered-ip",
-  "rs-limit_container_length_compact_buffered-ip"
-]
+  "rs-limit_string_length_multic-compact_buffered-ip"
+]
\ No newline at end of file
diff --git a/test/known_failures_Linux.json b/test/known_failures_Linux.json
index eda5df0..ea194a1 100644
--- a/test/known_failures_Linux.json
+++ b/test/known_failures_Linux.json
@@ -1,38 +1,90 @@
 [
-  "cpp-cpp_binary_buffered-ip-ssl",
-  "cpp-cpp_binary_framed-ip-ssl",
+  "c_glib-csharp_multi-binary_buffered-ip",
+  "c_glib-csharp_multi-binary_framed-ip",
+  "c_glib-csharp_multi_buffered-ip",
+  "c_glib-csharp_multi_framed-ip",
+  "c_glib-csharp_multic_buffered-ip",
+  "c_glib-csharp_multic-compact_buffered-ip",
+  "c_glib-csharp_multic-compact_framed-ip",
+  "c_glib-csharp_multic_framed-ip",
+  "c_glib-rs_multi_buffered-ip",
+  "c_glib-rs_multi_framed-ip",
+  "c_glib-rs_multic_buffered-ip",
+  "c_glib-rs_multic_framed-ip",
   "cpp-cpp_binary_http-domain",
-  "cpp-cpp_binary_http-ip-ssl",
-  "cpp-cpp_compact_buffered-ip-ssl",
-  "cpp-cpp_compact_framed-ip-ssl",
-  "cpp-cpp_compact_http-ip-ssl",
-  "cpp-cpp_header_buffered-ip-ssl",
-  "cpp-cpp_header_framed-ip-ssl",
-  "cpp-cpp_header_http-ip-ssl",
-  "cpp-cpp_json_buffered-ip-ssl",
-  "cpp-cpp_json_framed-ip-ssl",
-  "cpp-cpp_json_http-ip-ssl",
+  "cpp-cpp_compact_http-domain",
+  "cpp-cpp_compact_http-ip",
+  "cpp-cpp_header_http-domain",
+  "cpp-cpp_json_http-domain",
+  "cpp-cpp_json_http-ip",
+  "cpp-cpp_multi-binary_http-domain",
+  "cpp-cpp_multi-binary_http-ip",
+  "cpp-cpp_multi_http-domain",
+  "cpp-cpp_multi_http-ip",
+  "cpp-cpp_multic-compact_http-domain",
+  "cpp-cpp_multic-compact_http-ip",
+  "cpp-cpp_multic_http-domain",
+  "cpp-cpp_multic_http-ip",
+  "cpp-cpp_multih-header_http-domain",
+  "cpp-cpp_multih-header_http-ip",
+  "cpp-cpp_multih_http-domain",
+  "cpp-cpp_multih_http-ip",
+  "cpp-cpp_multij-json_http-domain",
+  "cpp-cpp_multij-json_http-ip",
+  "cpp-cpp_multij_http-domain",
+  "cpp-cpp_multij_http-ip",
   "cpp-dart_binary_http-ip",
   "cpp-dart_compact_http-ip",
   "cpp-dart_json_http-ip",
+  "cpp-dart_multi-binary_http-ip",
+  "cpp-dart_multic-compact_http-ip",
+  "cpp-dart_multij-json_http-ip",
   "cpp-go_binary_http-ip",
   "cpp-go_binary_http-ip-ssl",
   "cpp-go_compact_http-ip",
   "cpp-go_compact_http-ip-ssl",
   "cpp-go_json_http-ip",
   "cpp-go_json_http-ip-ssl",
+  "cpp-go_multi-binary_http-ip",
+  "cpp-go_multi-binary_http-ip-ssl",
+  "cpp-go_multic-compact_http-ip",
+  "cpp-go_multic-compact_http-ip-ssl",
+  "cpp-go_multij-json_http-ip",
+  "cpp-go_multij-json_http-ip-ssl",
   "cpp-java_binary_http-ip",
   "cpp-java_binary_http-ip-ssl",
   "cpp-java_compact_http-ip",
   "cpp-java_compact_http-ip-ssl",
   "cpp-java_json_http-ip",
   "cpp-java_json_http-ip-ssl",
+  "cpp-java_multi-binary_http-ip",
+  "cpp-java_multi-binary_http-ip-ssl",
+  "cpp-java_multi_http-ip",
+  "cpp-java_multi_http-ip-ssl",
+  "cpp-java_multic-compact_http-ip",
+  "cpp-java_multic-compact_http-ip-ssl",
+  "cpp-java_multic_http-ip",
+  "cpp-java_multic_http-ip-ssl",
+  "cpp-java_multij-json_http-ip",
+  "cpp-java_multij-json_http-ip-ssl",
+  "cpp-java_multij_http-ip",
+  "cpp-java_multij_http-ip-ssl",
   "cpp-nodejs_binary_http-ip",
   "cpp-nodejs_binary_http-ip-ssl",
   "cpp-nodejs_compact_http-ip",
   "cpp-nodejs_compact_http-ip-ssl",
   "cpp-nodejs_json_http-ip",
   "cpp-nodejs_json_http-ip-ssl",
+  "cpp-nodejs_multi-binary_http-ip",
+  "cpp-nodejs_multi-binary_http-ip-ssl",
+  "cpp-nodejs_multic-compact_http-ip",
+  "cpp-nodejs_multic-compact_http-ip-ssl",
+  "cpp-nodejs_multij-json_http-ip",
+  "cpp-nodejs_multij-json_http-ip-ssl",
+  "cpp-rs_multi_buffered-ip",
+  "cpp-rs_multi_framed-ip",
+  "cpp-rs_multic_buffered-ip",
+  "cpp-rs_multic_framed-ip",
   "csharp-d_binary_buffered-ip-ssl",
   "csharp-d_binary_framed-ip-ssl",
   "csharp-d_compact_buffered-ip-ssl",
@@ -246,9 +298,19 @@
   "nodejs-netcore_json_framed-ip",
   "nodejs-netcore_json_framed-ip-ssl",
   "rs-csharp_binary_buffered-ip",
-  "rs-csharp_compact_buffered-ip",
   "rs-csharp_binary_framed-ip",
+  "rs-csharp_compact_buffered-ip",
   "rs-csharp_compact_framed-ip",
+  "rs-csharp_multi-binary_buffered-ip",
+  "rs-csharp_multi-binary_framed-ip",
+  "rs-csharp_multi_buffered-ip",
+  "rs-csharp_multi_framed-ip",
+  "rs-csharp_multic-compact_buffered-ip",
+  "rs-csharp_multic-compact_framed-ip",
+  "rs-csharp_multic_buffered-ip",
+  "rs-csharp_multic_framed-ip",
   "rs-dart_binary_framed-ip",
-  "rs-dart_compact_framed-ip"
+  "rs-dart_compact_framed-ip",
+  "rs-dart_multi-binary_framed-ip",
+  "rs-dart_multic-compact_framed-ip"
 ]
diff --git a/test/rs/src/bin/test_client.rs b/test/rs/src/bin/test_client.rs
index d720313..7c11ad5 100644
--- a/test/rs/src/bin/test_client.rs
+++ b/test/rs/src/bin/test_client.rs
@@ -287,18 +287,6 @@
 
     // do the multiplexed calls while making the main ThriftTest calls
     if let Some(ref mut client) = second_service_client.as_mut() {
-        info!("SecondService blahBlah");
-        {
-            let r = client.blah_blah();
-            match r {
-                Err(thrift::Error::Application(ref e)) => {
-                    info!("received an {:?}", e);
-                    Ok(())
-                }
-                _ => Err(thrift::Error::User("did not get exception".into())),
-            }?;
-        }
-
         info!("SecondService secondtestString");
         {
             verify_expected_result(
diff --git a/test/rs/src/bin/test_server.rs b/test/rs/src/bin/test_server.rs
index a32e938..81a2ad8 100644
--- a/test/rs/src/bin/test_server.rs
+++ b/test/rs/src/bin/test_server.rs
@@ -390,10 +390,6 @@
 
 struct SecondServiceSyncHandlerImpl;
 impl SecondServiceSyncHandler for SecondServiceSyncHandlerImpl {
-    fn handle_blah_blah(&self) -> thrift::Result<()> {
-        Err(thrift::new_application_error(thrift::ApplicationErrorKind::Unknown, "blahBlah"),)
-    }
-
     fn handle_secondtest_string(&self, thing: String) -> thrift::Result<String> {
         info!("testString({})", &thing);
         let ret = format!("testString(\"{}\")", &thing);
diff --git a/test/tests.json b/test/tests.json
index c1c3155..bde9014 100644
--- a/test/tests.json
+++ b/test/tests.json
@@ -11,9 +11,7 @@
       ],
       "protocols": [
         "binary:multi",
-        "compact:multic",
-        "multi",
-        "multic"
+        "compact:multic"
       ]
     },
     "client": {
@@ -22,8 +20,6 @@
         "--lt-debug"
       ],
       "protocols": [
-        "multi",
-        "multic",
         "multi:binary",
         "multic:compact"
       ],
@@ -40,7 +36,9 @@
     ],
     "protocols": [
       "binary",
-      "compact"
+      "compact",
+      "multi",
+      "multic"
     ],
     "workdir": "c_glib"
   },
@@ -124,10 +122,7 @@
       "protocols": [
         "binary:multi",
         "compact:multic",
-        "json:multij",
-        "multi",
-        "multic",
-        "multij"
+        "json:multij"
       ]
     },
     "client": {
@@ -135,6 +130,11 @@
       "extra_args": ["run-testclient"],
       "transports": [
         "http"
+      ],
+      "protocols": [
+        "multi:binary",
+        "multic:compact",
+        "multij:json"
       ]
     },
     "transports": [
@@ -149,7 +149,10 @@
     "protocols": [
       "binary",
       "compact",
-      "json"
+      "json",
+      "multi",
+      "multic",
+      "multij"
     ],
     "workdir": "../lib/java"
   },
@@ -298,12 +301,24 @@
     "server": {
       "command": [
         "TestServer"
+      ],
+      "protocols": [
+        "binary:multi",
+        "compact:multic",
+        "header:multih",
+        "json:multij"
       ]
     },
     "client": {
       "timeout": 8,
       "command": [
         "TestClient"
+      ],
+      "protocols": [
+        "multi:binary",
+        "multic:compact",
+        "multih:header",
+        "multij:json"
       ]
     },
     "transports": [
@@ -320,7 +335,11 @@
       "compact",
       "binary",
       "json",
-      "header"
+      "header",
+      "multi",
+      "multic",
+      "multih",
+      "multij"
     ],
     "workdir": "cpp"
   },
@@ -385,6 +404,12 @@
         "mono",
         "TestClientServer.exe",
         "client"
+      ],
+      "protocols": [
+        "multi",
+        "multic",
+        "multi:binary",
+        "multic:compact"
       ]
     },
     "workdir": "csharp"
@@ -408,9 +433,9 @@
       "command": [
         "dotnet",
         "run",
-	"--no-build",
-	"--no-restore",
-	"--",
+  "--no-build",
+  "--no-restore",
+  "--",
         "server"
       ]
     },
@@ -419,9 +444,9 @@
       "command": [
         "dotnet",
         "run",
-	"--no-build",
-	"--no-restore",
-	"--",
+  "--no-build",
+  "--no-restore",
+  "--",
         "client"
       ]
     },
@@ -622,12 +647,20 @@
     "server": {
       "command": [
         "test_server"
+      ],
+      "protocols": [
+        "binary:multi",
+        "compact:multic"
       ]
     },
     "client": {
       "timeout": 6,
       "command": [
         "test_client"
+      ],
+      "protocols": [
+        "multi:binary",
+        "multic:compact"
       ]
     },
     "sockets": [