THRIFT-3706: Implement multiplexed protocol client and test client for c_glib; test server for java; integrate into crosstest
Client: c_glib

This closes #1191
This closes #1199
diff --git a/test/c_glib/src/test_client.c b/test/c_glib/src/test_client.c
index 9713e8c..a6ef869 100644
--- a/test/c_glib/src/test_client.c
+++ b/test/c_glib/src/test_client.c
@@ -28,6 +28,7 @@
 #include <thrift/c_glib/thrift.h>
 #include <thrift/c_glib/protocol/thrift_binary_protocol.h>
 #include <thrift/c_glib/protocol/thrift_compact_protocol.h>
+#include <thrift/c_glib/protocol/thrift_multiplexed_protocol.h>
 #include <thrift/c_glib/transport/thrift_buffered_transport.h>
 #include <thrift/c_glib/transport/thrift_framed_transport.h>
 #include <thrift/c_glib/transport/thrift_ssl_socket.h>
@@ -73,6 +74,32 @@
   return result;
 }
 
+/**
+ * It gets a multiplexed protocol which uses binary underneath
+ * @param  transport      the underlying transport
+ * @param  service_name   the single supported service name
+ * @todo                  need to allow multiple services to fully test multiplexed
+ * @return                a multiplexed protocol wrapping the correct underlying protocol
+ */
+ThriftProtocol *
+get_multiplexed_protocol(ThriftTransport *transport, gchar *service_name)
+{
+  ThriftProtocol * result_protocol=NULL;
+  ThriftProtocol * multiplexed_protocol=NULL;
+
+  multiplexed_protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL,
+               "transport", transport,
+               NULL);
+
+  result_protocol = g_object_new (THRIFT_TYPE_MULTIPLEXED_PROTOCOL,
+          "transport",  transport,
+          "protocol",   multiplexed_protocol,
+          "service-name",   service_name,
+          NULL);
+
+  return result_protocol;
+}
+
 int
 main (int argc, char **argv)
 {
@@ -94,7 +121,7 @@
     { "transport",       't', 0, G_OPTION_ARG_STRING,   &transport_option,
       "Transport: buffered, framed (=buffered)", NULL },
     { "protocol",        'r', 0, G_OPTION_ARG_STRING,   &protocol_option,
-      "Protocol: binary, compact (=binary)", NULL },
+      "Protocol: binary, compact, multiplexed (=binary)", NULL },
     { "testloops",       'n', 0, G_OPTION_ARG_INT,      &num_tests,
       "Number of tests (=1)", NULL },
     { NULL }
@@ -153,7 +180,14 @@
       protocol_type = THRIFT_TYPE_COMPACT_PROTOCOL;
       protocol_name = "compact";
     }
-    else if (strncmp (protocol_option, "binary", 7) != 0) {
+    else if (strncmp (protocol_option, "multiplexed", 12) == 0) {
+      protocol_type = THRIFT_TYPE_MULTIPLEXED_PROTOCOL;
+      protocol_name = "multiplexed(binary)";
+    }
+    else if (strncmp (protocol_option, "binary", 7) == 0) {
+      printf("We are going with default binary protocol");
+    }
+    else {
       fprintf (stderr, "Unknown protocol type %s\n", protocol_option);
       options_valid = FALSE;
     }
@@ -213,9 +247,22 @@
   transport = g_object_new (transport_type,
                             "transport", socket,
                             NULL);
-  protocol = g_object_new (protocol_type,
-                           "transport", transport,
-                           NULL);
+
+  if(protocol_type==THRIFT_TYPE_MULTIPLEXED_PROTOCOL) {
+    // TODO: A multiplexed test should also test "Second" (see Java TestServer)
+    // The context comes from the name of the thrift file. If multiple thrift
+    // schemas are used we have to redo the way this is done.
+    protocol = get_multiplexed_protocol(transport, "ThriftTest");
+    if (NULL == protocol) {
+      g_object_unref (transport);
+      g_object_unref (socket);
+      return 252;
+    }
+  }else{
+    protocol = g_object_new (protocol_type,
+           "transport", transport,
+           NULL);
+  }
   test_client = g_object_new (T_TEST_TYPE_THRIFT_TEST_CLIENT,
                               "input_protocol",  protocol,
                               "output_protocol", protocol,
diff --git a/test/crossrunner/report.py b/test/crossrunner/report.py
index cc5f26f..26f7d9e 100644
--- a/test/crossrunner/report.py
+++ b/test/crossrunner/report.py
@@ -104,7 +104,7 @@
 
     def _print_bar(self, out=None):
         print(
-            '==========================================================================',
+            '===============================================================================',
             file=(out or self.out))
 
     def _print_exec_time(self):
@@ -259,14 +259,14 @@
         name = '%s-%s' % (test.server.name, test.client.name)
         trans = '%s-%s' % (test.transport, test.socket)
         if not with_result:
-            return '{:24s}{:13s}{:25s}'.format(name[:23], test.protocol[:12], trans[:24])
+            return '{:24s}{:18s}{:25s}'.format(name[:23], test.protocol[:17], trans[:24])
         else:
-            return '{:24s}{:13s}{:25s}{:s}\n'.format(name[:23], test.protocol[:12], trans[:24], self._result_string(test))
+            return '{:24s}{:18s}{:25s}{:s}\n'.format(name[:23], test.protocol[:17], trans[:24], self._result_string(test))
 
     def _print_test_header(self):
         self._print_bar()
         print(
-            '{:24s}{:13s}{:25s}{:s}'.format('server-client:', 'protocol:', 'transport:', 'result:'),
+            '{:24s}{:18s}{:25s}{:s}'.format('server-client:', 'protocol:', 'transport:', 'result:'),
             file=self.out)
 
     def _print_header(self):
diff --git a/test/tests.json b/test/tests.json
index f1d6a47..2ab2e1d 100644
--- a/test/tests.json
+++ b/test/tests.json
@@ -13,6 +13,9 @@
       "command": [
         "test_client"
       ],
+      "protocols": [
+        "multiplexed"
+      ],
       "sockets": [
         "ip-ssl"
       ]
@@ -106,7 +109,10 @@
     ],
     "server": {
       "delay": 10,
-      "extra_args": ["run-testserver"]
+      "extra_args": ["run-testserver"],
+      "protocols": [
+        "multiplexed"
+      ]
     },
     "client": {
       "timeout": 13,
@@ -125,8 +131,8 @@
       "ip-ssl"
     ],
     "protocols": [
-      "compact",
       "binary",
+      "compact",
       "json"
     ],
     "workdir": "../lib/java"