THRIFT-4974: Add cross test for Python's Unix domain socket transport

Client: Python

This closes #1896.
diff --git a/LANGUAGES.md b/LANGUAGES.md
index 923b045..afd7799 100644
--- a/LANGUAGES.md
+++ b/LANGUAGES.md
@@ -315,7 +315,7 @@
 <!-- Since -----------------><td>0.2.0</td>
 <!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
 <!-- Language Levels -------><td>2.7.12, 3.5.2</td><td>2.7.15, 3.6.8</td>
-<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
+<!-- Low-Level Transports --><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
 <!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
 <!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
 <!-- Servers ---------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
diff --git a/test/known_failures_Linux.json b/test/known_failures_Linux.json
index dd6195a..e165aa4 100644
--- a/test/known_failures_Linux.json
+++ b/test/known_failures_Linux.json
@@ -85,74 +85,109 @@
   "cpp-nodejs_multij-json_http-domain",
   "cpp-nodejs_multij-json_http-ip",
   "cpp-nodejs_multij-json_http-ip-ssl",
+  "cpp-py3_binary-accel_http-domain",
   "cpp-py3_binary-accel_http-ip",
   "cpp-py3_binary-accel_http-ip-ssl",
+  "cpp-py3_binary_http-domain",
   "cpp-py3_binary_http-ip",
   "cpp-py3_binary_http-ip-ssl",
+  "cpp-py3_compact-accelc_http-domain",
   "cpp-py3_compact-accelc_http-ip",
   "cpp-py3_compact-accelc_http-ip-ssl",
+  "cpp-py3_compact_http-domain",
   "cpp-py3_compact_http-ip",
   "cpp-py3_compact_http-ip-ssl",
+  "cpp-py3_header_http-domain",
   "cpp-py3_header_http-ip",
   "cpp-py3_header_http-ip-ssl",
+  "cpp-py3_json_http-domain",
   "cpp-py3_json_http-ip",
   "cpp-py3_json_http-ip-ssl",
+  "cpp-py3_multi-accel_http-domain",
   "cpp-py3_multi-accel_http-ip",
   "cpp-py3_multi-accel_http-ip-ssl",
+  "cpp-py3_multi-binary_http-domain",
   "cpp-py3_multi-binary_http-ip",
   "cpp-py3_multi-binary_http-ip-ssl",
+  "cpp-py3_multi-multia_http-domain",
   "cpp-py3_multi-multia_http-ip",
   "cpp-py3_multi-multia_http-ip-ssl",
+  "cpp-py3_multi_http-domain",
   "cpp-py3_multi_http-ip",
   "cpp-py3_multi_http-ip-ssl",
+  "cpp-py3_multic-accelc_http-domain",
   "cpp-py3_multic-accelc_http-ip",
   "cpp-py3_multic-accelc_http-ip-ssl",
+  "cpp-py3_multic-compact_http-domain",
   "cpp-py3_multic-compact_http-ip",
   "cpp-py3_multic-compact_http-ip-ssl",
+  "cpp-py3_multic-multiac_http-domain",
   "cpp-py3_multic-multiac_http-ip",
   "cpp-py3_multic-multiac_http-ip-ssl",
+  "cpp-py3_multic_http-domain",
   "cpp-py3_multic_http-ip",
   "cpp-py3_multic_http-ip-ssl",
+  "cpp-py3_multih-header_http-domain",
   "cpp-py3_multih-header_http-ip",
   "cpp-py3_multih-header_http-ip-ssl",
+  "cpp-py3_multij-json_http-domain",
   "cpp-py3_multij-json_http-ip",
   "cpp-py3_multij-json_http-ip-ssl",
+  "cpp-py3_multij_http-domain",
   "cpp-py3_multij_http-ip",
   "cpp-py3_multij_http-ip-ssl",
+  "cpp-py_binary-accel_http-domain",
   "cpp-py_binary-accel_http-ip",
   "cpp-py_binary-accel_http-ip-ssl",
+  "cpp-py_binary_http-domain",
   "cpp-py_binary_http-ip",
   "cpp-py_binary_http-ip-ssl",
+  "cpp-py_compact-accelc_http-domain",
   "cpp-py_compact-accelc_http-ip",
   "cpp-py_compact-accelc_http-ip-ssl",
+  "cpp-py_compact_http-domain",
   "cpp-py_compact_http-ip",
   "cpp-py_compact_http-ip-ssl",
+  "cpp-py_header_http-domain",
   "cpp-py_header_http-ip",
   "cpp-py_header_http-ip-ssl",
+  "cpp-py_json_http-domain",
   "cpp-py_json_http-ip",
   "cpp-py_json_http-ip-ssl",
+  "cpp-py_multi-accel_http-domain",
   "cpp-py_multi-accel_http-ip",
   "cpp-py_multi-accel_http-ip-ssl",
+  "cpp-py_multi-binary_http-domain",
   "cpp-py_multi-binary_http-ip",
   "cpp-py_multi-binary_http-ip-ssl",
+  "cpp-py_multi-multia_http-domain",
   "cpp-py_multi-multia_http-ip",
   "cpp-py_multi-multia_http-ip-ssl",
+  "cpp-py_multi_http-domain",
   "cpp-py_multi_http-ip",
   "cpp-py_multi_http-ip-ssl",
+  "cpp-py_multic-accelc_http-domain",
   "cpp-py_multic-accelc_http-ip",
   "cpp-py_multic-accelc_http-ip-ssl",
+  "cpp-py_multic-compact_http-domain",
   "cpp-py_multic-compact_http-ip",
   "cpp-py_multic-compact_http-ip-ssl",
+  "cpp-py_multic-multiac_http-domain",
   "cpp-py_multic-multiac_http-ip",
   "cpp-py_multic-multiac_http-ip-ssl",
+  "cpp-py_multic_http-domain",
   "cpp-py_multic_http-ip",
   "cpp-py_multic_http-ip-ssl",
+  "cpp-py_multih-header_http-domain",
   "cpp-py_multih-header_http-ip",
   "cpp-py_multih-header_http-ip-ssl",
+  "cpp-py_multih_http-domain",
   "cpp-py_multih_http-ip",
   "cpp-py_multih_http-ip-ssl",
+  "cpp-py_multij-json_http-domain",
   "cpp-py_multij-json_http-ip",
   "cpp-py_multij-json_http-ip-ssl",
+  "cpp-py_multij_http-domain",
   "cpp-py_multij_http-ip",
   "cpp-py_multij_http-ip-ssl",
   "cpp-rs_multi_buffered-ip",
@@ -389,76 +424,112 @@
   "nodejs-lua_binary_http-ip",
   "nodejs-lua_compact_http-ip",
   "nodejs-lua_json_http-ip",
+  "nodejs-py3_binary-accel_http-domain",
   "nodejs-py3_binary-accel_http-ip",
   "nodejs-py3_binary-accel_http-ip-ssl",
+  "nodejs-py3_binary_http-domain",
   "nodejs-py3_binary_http-ip",
   "nodejs-py3_binary_http-ip-ssl",
+  "nodejs-py3_compact-accelc_http-domain",
   "nodejs-py3_compact-accelc_http-ip",
   "nodejs-py3_compact-accelc_http-ip-ssl",
+  "nodejs-py3_compact_http-domain",
   "nodejs-py3_compact_http-ip",
   "nodejs-py3_compact_http-ip-ssl",
+  "nodejs-py3_header_http-domain",
   "nodejs-py3_header_http-ip",
   "nodejs-py3_header_http-ip-ssl",
+  "nodejs-py3_json_http-domain",
   "nodejs-py3_json_http-ip",
   "nodejs-py3_json_http-ip-ssl",
+  "nodejs-py_binary-accel_http-domain",
   "nodejs-py_binary-accel_http-ip",
   "nodejs-py_binary-accel_http-ip-ssl",
+  "nodejs-py_binary_http-domain",
   "nodejs-py_binary_http-ip",
   "nodejs-py_binary_http-ip-ssl",
+  "nodejs-py_compact-accelc_http-domain",
   "nodejs-py_compact-accelc_http-ip",
   "nodejs-py_compact-accelc_http-ip-ssl",
+  "nodejs-py_compact_http-domain",
   "nodejs-py_compact_http-ip",
   "nodejs-py_compact_http-ip-ssl",
+  "nodejs-py_header_http-domain",
   "nodejs-py_header_http-ip",
   "nodejs-py_header_http-ip-ssl",
+  "nodejs-py_json_http-domain",
   "nodejs-py_json_http-ip",
   "nodejs-py_json_http-ip-ssl",
   "perl-rs_multi_buffered-ip",
   "perl-rs_multi_framed-ip",
+  "py-cpp_accel-binary_http-domain",
   "py-cpp_accel-binary_http-ip",
   "py-cpp_accel-binary_http-ip-ssl",
+  "py-cpp_accel-binary_zlib-domain",
   "py-cpp_accel-binary_zlib-ip",
   "py-cpp_accel-binary_zlib-ip-ssl",
+  "py-cpp_accelc-compact_http-domain",
   "py-cpp_accelc-compact_http-ip",
   "py-cpp_accelc-compact_http-ip-ssl",
+  "py-cpp_accelc-compact_zlib-domain",
   "py-cpp_accelc-compact_zlib-ip",
   "py-cpp_accelc-compact_zlib-ip-ssl",
+  "py-cpp_binary_http-domain",
   "py-cpp_binary_http-ip",
   "py-cpp_binary_http-ip-ssl",
+  "py-cpp_compact_http-domain",
   "py-cpp_compact_http-ip",
   "py-cpp_compact_http-ip-ssl",
+  "py-cpp_header_http-domain",
   "py-cpp_header_http-ip",
   "py-cpp_header_http-ip-ssl",
+  "py-cpp_json_http-domain",
   "py-cpp_json_http-ip",
   "py-cpp_json_http-ip-ssl",
+  "py-cpp_multi-binary_http-domain",
   "py-cpp_multi-binary_http-ip",
   "py-cpp_multi-binary_http-ip-ssl",
+  "py-cpp_multi_http-domain",
   "py-cpp_multi_http-ip",
   "py-cpp_multi_http-ip-ssl",
+  "py-cpp_multia-binary_http-domain",
   "py-cpp_multia-binary_http-ip",
   "py-cpp_multia-binary_http-ip-ssl",
+  "py-cpp_multia-binary_zlib-domain",
   "py-cpp_multia-binary_zlib-ip",
   "py-cpp_multia-binary_zlib-ip-ssl",
+  "py-cpp_multia-multi_http-domain",
   "py-cpp_multia-multi_http-ip",
   "py-cpp_multia-multi_http-ip-ssl",
+  "py-cpp_multia-multi_zlib-domain",
   "py-cpp_multia-multi_zlib-ip",
   "py-cpp_multia-multi_zlib-ip-ssl",
+  "py-cpp_multiac-compact_http-domain",
   "py-cpp_multiac-compact_http-ip",
   "py-cpp_multiac-compact_http-ip-ssl",
+  "py-cpp_multiac-compact_zlib-domain",
   "py-cpp_multiac-compact_zlib-ip",
   "py-cpp_multiac-compact_zlib-ip-ssl",
+  "py-cpp_multiac-multic_http-domain",
   "py-cpp_multiac-multic_http-ip",
   "py-cpp_multiac-multic_http-ip-ssl",
+  "py-cpp_multiac-multic_zlib-domain",
   "py-cpp_multiac-multic_zlib-ip",
   "py-cpp_multiac-multic_zlib-ip-ssl",
+  "py-cpp_multic-compact_http-domain",
   "py-cpp_multic-compact_http-ip",
   "py-cpp_multic-compact_http-ip-ssl",
+  "py-cpp_multic_http-domain",
   "py-cpp_multic_http-ip",
   "py-cpp_multic_http-ip-ssl",
+  "py-cpp_multih_http-domain",
+  "py-cpp_multih-header_http-domain",
   "py-cpp_multih-header_http-ip",
   "py-cpp_multih-header_http-ip-ssl",
+  "py-cpp_multij_http-domain",
   "py-cpp_multih_http-ip",
   "py-cpp_multih_http-ip-ssl",
+  "py-cpp_multij-json_http-domain",
   "py-cpp_multij-json_http-ip",
   "py-cpp_multij-json_http-ip-ssl",
   "py-cpp_multij_http-ip",
@@ -504,6 +575,12 @@
   "py-lua_binary_http-ip",
   "py-lua_compact_http-ip",
   "py-lua_json_http-ip",
+  "py-nodejs_accel-binary_http-domain",
+  "py-nodejs_accelc-compact_http-domain",
+  "py-nodejs_binary_http-domain",
+  "py-nodejs_compact_http-domain",
+  "py-nodejs_json_http-domain",
+  "py-nodejs_header_http-domain",
   "py-rs_multi_buffered-ip",
   "py-rs_multi_framed-ip",
   "py-rs_multia-multi_buffered-ip",
@@ -512,52 +589,76 @@
   "py-rs_multiac-multic_framed-ip",
   "py-rs_multic_buffered-ip",
   "py-rs_multic_framed-ip",
+  "py3-cpp_accel-binary_http-domain",
   "py3-cpp_accel-binary_http-ip",
   "py3-cpp_accel-binary_http-ip-ssl",
+  "py3-cpp_accel-binary_zlib-domain",
   "py3-cpp_accel-binary_zlib-ip",
   "py3-cpp_accel-binary_zlib-ip-ssl",
+  "py3-cpp_accelc-compact_http-domain",
   "py3-cpp_accelc-compact_http-ip",
   "py3-cpp_accelc-compact_http-ip-ssl",
+  "py3-cpp_accelc-compact_zlib-domain",
   "py3-cpp_accelc-compact_zlib-ip",
   "py3-cpp_accelc-compact_zlib-ip-ssl",
+  "py3-cpp_binary_http-domain",
   "py3-cpp_binary_http-ip",
   "py3-cpp_binary_http-ip-ssl",
+  "py3-cpp_compact_http-domain",
   "py3-cpp_compact_http-ip",
   "py3-cpp_compact_http-ip-ssl",
+  "py3-cpp_header_http-domain",
   "py3-cpp_header_http-ip",
   "py3-cpp_header_http-ip-ssl",
+  "py3-cpp_json_http-domain",
   "py3-cpp_json_http-ip",
   "py3-cpp_json_http-ip-ssl",
+  "py3-cpp_multi-binary_http-domain",
   "py3-cpp_multi-binary_http-ip",
   "py3-cpp_multi-binary_http-ip-ssl",
+  "py3-cpp_multi_http-domain",
   "py3-cpp_multi_http-ip",
   "py3-cpp_multi_http-ip-ssl",
+  "py3-cpp_multia-binary_http-domain",
   "py3-cpp_multia-binary_http-ip",
   "py3-cpp_multia-binary_http-ip-ssl",
+  "py3-cpp_multia-binary_zlib-domain",
   "py3-cpp_multia-binary_zlib-ip",
   "py3-cpp_multia-binary_zlib-ip-ssl",
+  "py3-cpp_multia-multi_http-domain",
   "py3-cpp_multia-multi_http-ip",
   "py3-cpp_multia-multi_http-ip-ssl",
+  "py3-cpp_multia-multi_zlib-domain",
   "py3-cpp_multia-multi_zlib-ip",
   "py3-cpp_multia-multi_zlib-ip-ssl",
+  "py3-cpp_multiac-compact_http-domain",
   "py3-cpp_multiac-compact_http-ip",
   "py3-cpp_multiac-compact_http-ip-ssl",
+  "py3-cpp_multiac-compact_zlib-domain",
   "py3-cpp_multiac-compact_zlib-ip",
   "py3-cpp_multiac-compact_zlib-ip-ssl",
+  "py3-cpp_multiac-multic_http-domain",
   "py3-cpp_multiac-multic_http-ip",
   "py3-cpp_multiac-multic_http-ip-ssl",
+  "py3-cpp_multiac-multic_zlib-domain",
   "py3-cpp_multiac-multic_zlib-ip",
   "py3-cpp_multiac-multic_zlib-ip-ssl",
+  "py3-cpp_multic-compact_http-domain",
   "py3-cpp_multic-compact_http-ip",
   "py3-cpp_multic-compact_http-ip-ssl",
+  "py3-cpp_multic_http-domain",
   "py3-cpp_multic_http-ip",
   "py3-cpp_multic_http-ip-ssl",
+  "py3-cpp_multih-header_http-domain",
   "py3-cpp_multih-header_http-ip",
   "py3-cpp_multih-header_http-ip-ssl",
+  "py3-cpp_multih_http-domain",
   "py3-cpp_multih_http-ip",
   "py3-cpp_multih_http-ip-ssl",
+  "py3-cpp_multij-json_http-domain",
   "py3-cpp_multij-json_http-ip",
   "py3-cpp_multij-json_http-ip-ssl",
+  "py3-cpp_multij_http-domain",
   "py3-cpp_multij_http-ip",
   "py3-cpp_multij_http-ip-ssl",
   "py3-d_accel-binary_http-ip",
@@ -601,6 +702,12 @@
   "py3-lua_binary_http-ip",
   "py3-lua_compact_http-ip",
   "py3-lua_json_http-ip",
+  "py3-nodejs_accel-binary_http-domain",
+  "py3-nodejs_accelc-compact_http-domain",
+  "py3-nodejs_binary_http-domain",
+  "py3-nodejs_compact_http-domain",
+  "py3-nodejs_json_http-domain",
+  "py3-nodejs_header_http-domain",
   "py3-rs_multi_buffered-ip",
   "py3-rs_multi_framed-ip",
   "py3-rs_multia-multi_buffered-ip",
@@ -615,4 +722,4 @@
   "rb-cpp_json_framed-domain",
   "rb-cpp_json_framed-ip",
   "rb-cpp_json_framed-ip-ssl"
-]
\ No newline at end of file
+]
diff --git a/test/py/TestClient.py b/test/py/TestClient.py
index e7a9a1a..8a30c3a 100755
--- a/test/py/TestClient.py
+++ b/test/py/TestClient.py
@@ -51,7 +51,7 @@
                 from thrift.transport import TSSLSocket
                 socket = TSSLSocket.TSSLSocket(options.host, options.port, validate=False)
             else:
-                socket = TSocket.TSocket(options.host, options.port)
+                socket = TSocket.TSocket(options.host, options.port, options.domain_socket)
             # frame or buffer depending upon args
             self.transport = TTransport.TBufferedTransport(socket)
             if options.trans == 'framed':
@@ -474,6 +474,8 @@
                       help="protocol to use, one of: accel, accelc, binary, compact, header, json, multi, multia, multiac, multic, multih, multij")
     parser.add_option('--transport', dest="trans", type="string",
                       help="transport to use, one of: buffered, framed, http")
+    parser.add_option('--domain-socket', dest="domain_socket", type="string",
+                      help="Unix domain socket path")
     parser.set_defaults(framed=False, http_path=None, verbose=1, host='localhost', port=9090, proto='binary')
     options, args = parser.parse_args()
 
diff --git a/test/py/TestServer.py b/test/py/TestServer.py
index d0a13e5..4d90f8f 100755
--- a/test/py/TestServer.py
+++ b/test/py/TestServer.py
@@ -307,7 +307,7 @@
         from thrift.transport import TSSLSocket
         transport = TSSLSocket.TSSLServerSocket(host, options.port, certfile=abs_key_path)
     else:
-        transport = TSocket.TServerSocket(host, options.port)
+        transport = TSocket.TServerSocket(host, options.port, options.domain_socket)
     tfactory = TTransport.TBufferedTransportFactory()
     if options.trans == 'buffered':
         tfactory = TTransport.TBufferedTransportFactory()
@@ -385,6 +385,8 @@
                       help="protocol to use, one of: accel, accelc, binary, compact, json, multi, multia, multiac, multic, multih, multij")
     parser.add_option('--transport', dest="trans", type="string",
                       help="transport to use, one of: buffered, framed, http")
+    parser.add_option('--domain-socket', dest="domain_socket", type="string",
+                      help="Unix domain socket path")
     parser.add_option('--container-limit', dest='container_limit', type='int', default=None)
     parser.add_option('--string-limit', dest='string_limit', type='int', default=None)
     parser.set_defaults(port=9090, verbose=1, proto='binary', transport='buffered')
diff --git a/test/tests.json b/test/tests.json
index 78d4c0e..b8b85be 100644
--- a/test/tests.json
+++ b/test/tests.json
@@ -264,7 +264,8 @@
     ],
     "sockets": [
       "ip",
-      "ip-ssl"
+      "ip-ssl",
+      "domain"
     ],
     "protocols": [
       "binary",
@@ -313,7 +314,8 @@
     ],
     "sockets": [
       "ip",
-      "ip-ssl"
+      "ip-ssl",
+      "domain"
     ],
     "protocols": [
       "binary",