summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/thrift/test/features
diff options
context:
space:
mode:
Diffstat (limited to 'src/jaegertracing/thrift/test/features')
-rw-r--r--src/jaegertracing/thrift/test/features/Makefile.am30
-rw-r--r--src/jaegertracing/thrift/test/features/container_limit.py72
-rw-r--r--src/jaegertracing/thrift/test/features/index.html51
-rw-r--r--src/jaegertracing/thrift/test/features/known_failures_Linux.json52
-rw-r--r--src/jaegertracing/thrift/test/features/local_thrift/__init__.py32
-rwxr-xr-xsrc/jaegertracing/thrift/test/features/nosslv3.sh59
-rw-r--r--src/jaegertracing/thrift/test/features/setup.cfg2
-rw-r--r--src/jaegertracing/thrift/test/features/string_limit.py62
-rw-r--r--src/jaegertracing/thrift/test/features/tests.json114
-rw-r--r--src/jaegertracing/thrift/test/features/theader_binary.py70
-rwxr-xr-xsrc/jaegertracing/thrift/test/features/tls.sh72
-rw-r--r--src/jaegertracing/thrift/test/features/util.py40
12 files changed, 656 insertions, 0 deletions
diff --git a/src/jaegertracing/thrift/test/features/Makefile.am b/src/jaegertracing/thrift/test/features/Makefile.am
new file mode 100644
index 000000000..337d78950
--- /dev/null
+++ b/src/jaegertracing/thrift/test/features/Makefile.am
@@ -0,0 +1,30 @@
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+EXTRA_DIST = \
+ local_thrift \
+ index.html \
+ container_limit.py \
+ index.html \
+ known_failures_Linux.json \
+ Makefile.am \
+ nosslv3.sh \
+ string_limit.py \
+ tests.json \
+ theader_binary.py \
+ setup.cfg \
+ tls.sh \
+ util.py
diff --git a/src/jaegertracing/thrift/test/features/container_limit.py b/src/jaegertracing/thrift/test/features/container_limit.py
new file mode 100644
index 000000000..88f8487fa
--- /dev/null
+++ b/src/jaegertracing/thrift/test/features/container_limit.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+import argparse
+import sys
+
+from util import add_common_args, init_protocol
+from local_thrift import thrift # noqa
+from thrift.Thrift import TMessageType, TType
+
+
+# TODO: generate from ThriftTest.thrift
+def test_list(proto, value):
+ method_name = 'testList'
+ ttype = TType.LIST
+ etype = TType.I32
+ proto.writeMessageBegin(method_name, TMessageType.CALL, 3)
+ proto.writeStructBegin(method_name + '_args')
+ proto.writeFieldBegin('thing', ttype, 1)
+ proto.writeListBegin(etype, len(value))
+ for e in value:
+ proto.writeI32(e)
+ proto.writeListEnd()
+ proto.writeFieldEnd()
+ proto.writeFieldStop()
+ proto.writeStructEnd()
+ proto.writeMessageEnd()
+ proto.trans.flush()
+
+ _, mtype, _ = proto.readMessageBegin()
+ assert mtype == TMessageType.REPLY
+ proto.readStructBegin()
+ _, ftype, fid = proto.readFieldBegin()
+ assert fid == 0
+ assert ftype == ttype
+ etype2, len2 = proto.readListBegin()
+ assert etype == etype2
+ assert len2 == len(value)
+ for i in range(len2):
+ v = proto.readI32()
+ assert v == value[i]
+ proto.readListEnd()
+ proto.readFieldEnd()
+ _, ftype, _ = proto.readFieldBegin()
+ assert ftype == TType.STOP
+ proto.readStructEnd()
+ proto.readMessageEnd()
+
+
+def main(argv):
+ p = argparse.ArgumentParser()
+ add_common_args(p)
+ p.add_argument('--limit', type=int)
+ args = p.parse_args()
+ proto = init_protocol(args)
+ # TODO: test set and map
+ test_list(proto, list(range(args.limit - 1)))
+ test_list(proto, list(range(args.limit - 1)))
+ print('[OK]: limit - 1')
+ test_list(proto, list(range(args.limit)))
+ test_list(proto, list(range(args.limit)))
+ print('[OK]: just limit')
+ try:
+ test_list(proto, list(range(args.limit + 1)))
+ except Exception:
+ print('[OK]: limit + 1')
+ else:
+ print('[ERROR]: limit + 1')
+ assert False
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/src/jaegertracing/thrift/test/features/index.html b/src/jaegertracing/thrift/test/features/index.html
new file mode 100644
index 000000000..34a00102f
--- /dev/null
+++ b/src/jaegertracing/thrift/test/features/index.html
@@ -0,0 +1,51 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Apache Thrift - integration test suite</title>
+<link rel="stylesheet" type="text/css" href="http://cdn.datatables.net/1.10.4/css/jquery.dataTables.css">
+<script type="text/javascript" charset="utf-8" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
+<script type="text/javascript" charset="utf-8" src="http://cdn.datatables.net/1.10.4/js/jquery.dataTables.js"></script>
+<script src="../result.js">
+</script>
+</head>
+<body>
+<h2>Apache Thrift - integration test suite: Results</h2>
+<table id="test_results" class="display">
+ <thead>
+ <tr>
+ <th>Server</th>
+ <th>Client</th>
+ <th>Protocol</th>
+ <th>Transport</th>
+ <th>Result (log)</th>
+ <th>Expected</th>
+ </tr>
+ </thead>
+</table>
+<h2>Test Information</h2>
+<pre id="test_info"></pre>
+
+<a href="log">browse raw log files</a>
+
+</body>
+</html>
diff --git a/src/jaegertracing/thrift/test/features/known_failures_Linux.json b/src/jaegertracing/thrift/test/features/known_failures_Linux.json
new file mode 100644
index 000000000..6547860cb
--- /dev/null
+++ b/src/jaegertracing/thrift/test/features/known_failures_Linux.json
@@ -0,0 +1,52 @@
+[
+ "c_glib-limit_container_length_binary_buffered-ip",
+ "c_glib-limit_string_length_binary_buffered-ip",
+ "cl-limit_string_length_binary_buffered-ip",
+ "cl-limit_container_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",
+ "csharp-limit_string_length_compact_buffered-ip",
+ "d-limit_container_length_binary_buffered-ip",
+ "d-limit_container_length_compact_buffered-ip",
+ "d-limit_string_length_binary_buffered-ip",
+ "d-limit_string_length_compact_buffered-ip",
+ "erl-limit_container_length_binary_buffered-ip",
+ "erl-limit_container_length_compact_buffered-ip",
+ "erl-limit_string_length_binary_buffered-ip",
+ "erl-limit_string_length_compact_buffered-ip",
+ "go-limit_container_length_binary_buffered-ip",
+ "go-limit_container_length_compact_buffered-ip",
+ "go-limit_string_length_binary_buffered-ip",
+ "go-limit_string_length_compact_buffered-ip",
+ "hs-limit_container_length_binary_buffered-ip",
+ "hs-limit_container_length_compact_buffered-ip",
+ "hs-limit_string_length_binary_buffered-ip",
+ "hs-limit_string_length_compact_buffered-ip",
+ "nodejs-limit_container_length_binary_buffered-ip",
+ "nodejs-limit_container_length_compact_buffered-ip",
+ "nodejs-limit_string_length_binary_buffered-ip",
+ "nodejs-limit_string_length_compact_buffered-ip",
+ "perl-limit_container_length_binary_buffered-ip",
+ "perl-limit_string_length_binary_buffered-ip",
+ "rb-limit_container_length_accel-binary_buffered-ip",
+ "rb-limit_container_length_binary_buffered-ip",
+ "rb-limit_container_length_compact_buffered-ip",
+ "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_string_length_multic-compact_buffered-ip",
+ "netcore-limit_string_length_compact_buffered-ip",
+ "netcore-limit_container_length_compact_buffered-ip",
+ "nodejs-theader_framed_binary_header_buffered-ip",
+ "nodejs-theader_framed_compact_header_buffered-ip"
+]
diff --git a/src/jaegertracing/thrift/test/features/local_thrift/__init__.py b/src/jaegertracing/thrift/test/features/local_thrift/__init__.py
new file mode 100644
index 000000000..c85cebe5f
--- /dev/null
+++ b/src/jaegertracing/thrift/test/features/local_thrift/__init__.py
@@ -0,0 +1,32 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+import glob
+import os
+import sys
+
+_SCRIPT_DIR = os.path.realpath(os.path.dirname(__file__))
+_ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(_SCRIPT_DIR)))
+_LIBDIR = os.path.join(_ROOT_DIR, 'lib', 'py', 'build', 'lib.*')
+
+for libpath in glob.glob(_LIBDIR):
+ if libpath.endswith('-%d.%d' % (sys.version_info[0], sys.version_info[1])):
+ sys.path.insert(0, libpath)
+ thrift = __import__('thrift')
+ break
diff --git a/src/jaegertracing/thrift/test/features/nosslv3.sh b/src/jaegertracing/thrift/test/features/nosslv3.sh
new file mode 100755
index 000000000..38cca0786
--- /dev/null
+++ b/src/jaegertracing/thrift/test/features/nosslv3.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+#
+# Checks to make sure SSLv3 is not allowed by a server.
+#
+
+THRIFTHOST=localhost
+THRIFTPORT=9090
+
+while [[ $# -ge 1 ]]; do
+ arg="$1"
+ argIN=(${arg//=/ })
+
+ case ${argIN[0]} in
+ -h|--host)
+ THRIFTHOST=${argIN[1]}
+ shift # past argument
+ ;;
+ -p|--port)
+ THRIFTPORT=${argIN[1]}
+ shift # past argument
+ ;;
+ *)
+ # unknown option ignored
+ ;;
+ esac
+
+ shift # past argument or value
+done
+
+function nosslv3
+{
+ local nego
+ local negodenied
+ local opensslv
+
+ opensslv=$(openssl version | cut -d' ' -f2)
+ if [[ $opensslv > "1.0" ]]; then
+ echo "[pass] OpenSSL 1.1 or later - no need to check ssl3"
+ return 0
+ fi
+
+ # echo "openssl s_client -connect $THRIFTHOST:$THRIFTPORT -CAfile ../keys/CA.pem -ssl3 2>&1 < /dev/null"
+ nego=$(openssl s_client -connect $THRIFTHOST:$THRIFTPORT -CAfile ../keys/CA.pem -ssl3 2>&1 < /dev/null)
+ negodenied=$?
+
+ if [[ $negodenied -ne 0 ]]; then
+ echo "[pass] SSLv3 negotiation disabled"
+ echo $nego
+ return 0
+ fi
+
+ echo "[fail] SSLv3 negotiation enabled! stdout:"
+ echo $nego
+ return 1
+}
+
+nosslv3
+exit $?
diff --git a/src/jaegertracing/thrift/test/features/setup.cfg b/src/jaegertracing/thrift/test/features/setup.cfg
new file mode 100644
index 000000000..7da1f9608
--- /dev/null
+++ b/src/jaegertracing/thrift/test/features/setup.cfg
@@ -0,0 +1,2 @@
+[flake8]
+max-line-length = 100
diff --git a/src/jaegertracing/thrift/test/features/string_limit.py b/src/jaegertracing/thrift/test/features/string_limit.py
new file mode 100644
index 000000000..b8991d64f
--- /dev/null
+++ b/src/jaegertracing/thrift/test/features/string_limit.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+
+import argparse
+import sys
+
+from util import add_common_args, init_protocol
+from local_thrift import thrift # noqa
+from thrift.Thrift import TMessageType, TType
+
+
+# TODO: generate from ThriftTest.thrift
+def test_string(proto, value):
+ method_name = 'testString'
+ ttype = TType.STRING
+ proto.writeMessageBegin(method_name, TMessageType.CALL, 3)
+ proto.writeStructBegin(method_name + '_args')
+ proto.writeFieldBegin('thing', ttype, 1)
+ proto.writeString(value)
+ proto.writeFieldEnd()
+ proto.writeFieldStop()
+ proto.writeStructEnd()
+ proto.writeMessageEnd()
+ proto.trans.flush()
+
+ _, mtype, _ = proto.readMessageBegin()
+ assert mtype == TMessageType.REPLY
+ proto.readStructBegin()
+ _, ftype, fid = proto.readFieldBegin()
+ assert fid == 0
+ assert ftype == ttype
+ result = proto.readString()
+ proto.readFieldEnd()
+ _, ftype, _ = proto.readFieldBegin()
+ assert ftype == TType.STOP
+ proto.readStructEnd()
+ proto.readMessageEnd()
+ assert value == result
+
+
+def main(argv):
+ p = argparse.ArgumentParser()
+ add_common_args(p)
+ p.add_argument('--limit', type=int)
+ args = p.parse_args()
+ proto = init_protocol(args)
+ test_string(proto, 'a' * (args.limit - 1))
+ test_string(proto, 'a' * (args.limit - 1))
+ print('[OK]: limit - 1')
+ test_string(proto, 'a' * args.limit)
+ test_string(proto, 'a' * args.limit)
+ print('[OK]: just limit')
+ try:
+ test_string(proto, 'a' * (args.limit + 1))
+ except Exception:
+ print('[OK]: limit + 1')
+ else:
+ print('[ERROR]: limit + 1')
+ assert False
+
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
diff --git a/src/jaegertracing/thrift/test/features/tests.json b/src/jaegertracing/thrift/test/features/tests.json
new file mode 100644
index 000000000..41e07d7f6
--- /dev/null
+++ b/src/jaegertracing/thrift/test/features/tests.json
@@ -0,0 +1,114 @@
+[
+ {
+ "description": "THeader detects unframed binary wire format",
+ "name": "theader_unframed_binary",
+ "command": [
+ "python",
+ "theader_binary.py",
+ "--override-protocol=binary",
+ "--override-transport=buffered"
+ ],
+ "protocols": ["header"],
+ "transports": ["buffered"],
+ "sockets": ["ip"],
+ "workdir": "features"
+ },
+ {
+ "description": "THeader detects framed binary wire format",
+ "name": "theader_framed_binary",
+ "command": [
+ "python",
+ "theader_binary.py",
+ "--override-protocol=binary",
+ "--override-transport=framed"
+ ],
+ "protocols": ["header"],
+ "transports": ["buffered"],
+ "sockets": ["ip"],
+ "workdir": "features"
+ },
+ {
+ "description": "THeader detects unframed compact wire format",
+ "name": "theader_unframed_compact",
+ "command": [
+ "python",
+ "theader_binary.py",
+ "--override-protocol=compact",
+ "--override-transport=buffered"
+ ],
+ "protocols": ["header"],
+ "transports": ["buffered"],
+ "sockets": ["ip"],
+ "workdir": "features"
+ },
+ {
+ "description": "THeader detects framed compact wire format",
+ "name": "theader_framed_compact",
+ "command": [
+ "python",
+ "theader_binary.py",
+ "--override-protocol=compact",
+ "--override-transport=framed"
+ ],
+ "protocols": ["header"],
+ "transports": ["buffered"],
+ "sockets": ["ip"],
+ "workdir": "features"
+ },
+ {
+ "name": "limit_string_length",
+ "command": [
+ "python",
+ "string_limit.py",
+ "--limit=50"
+ ],
+ "remote_args": [
+ "--string-limit=50"
+ ],
+ "protocols": [
+ "compact"
+ ],
+ "transports": ["buffered"],
+ "sockets": ["ip"],
+ "workdir": "features"
+ },
+ {
+ "name": "limit_container_length",
+ "command": [
+ "python",
+ "container_limit.py",
+ "--limit=50"
+ ],
+ "remote_args": [
+ "--container-limit=50"
+ ],
+ "protocols": [
+ "compact"
+ ],
+ "transports": ["buffered"],
+ "sockets": ["ip"],
+ "workdir": "features"
+ },
+ {
+ "name": "nosslv3",
+ "comment": "check to make sure SSLv3 is not supported",
+ "command": [
+ "nosslv3.sh"
+ ],
+ "protocols": ["binary"],
+ "transports": ["buffered"],
+ "sockets": ["ip-ssl"],
+ "workdir": "features"
+ },
+ {
+ "name": "tls",
+ "comment": "check to make sure TLSv1.0 or later is supported",
+ "command": [
+ "tls.sh"
+ ],
+ "protocols": ["binary"],
+ "transports": ["buffered"],
+ "sockets": ["ip-ssl"],
+ "workdir": "features"
+ }
+]
diff --git a/src/jaegertracing/thrift/test/features/theader_binary.py b/src/jaegertracing/thrift/test/features/theader_binary.py
new file mode 100644
index 000000000..451399aa7
--- /dev/null
+++ b/src/jaegertracing/thrift/test/features/theader_binary.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+
+import argparse
+import socket
+import sys
+
+from util import add_common_args
+from local_thrift import thrift # noqa
+from thrift.Thrift import TMessageType, TType
+from thrift.transport.TSocket import TSocket
+from thrift.transport.TTransport import TBufferedTransport, TFramedTransport
+from thrift.protocol.TBinaryProtocol import TBinaryProtocol
+from thrift.protocol.TCompactProtocol import TCompactProtocol
+
+
+def test_void(proto):
+ proto.writeMessageBegin('testVoid', TMessageType.CALL, 3)
+ proto.writeStructBegin('testVoid_args')
+ proto.writeFieldStop()
+ proto.writeStructEnd()
+ proto.writeMessageEnd()
+ proto.trans.flush()
+
+ _, mtype, _ = proto.readMessageBegin()
+ assert mtype == TMessageType.REPLY
+ proto.readStructBegin()
+ _, ftype, _ = proto.readFieldBegin()
+ assert ftype == TType.STOP
+ proto.readStructEnd()
+ proto.readMessageEnd()
+
+
+# THeader stack should accept binary protocol with optionally framed transport
+def main(argv):
+ p = argparse.ArgumentParser()
+ add_common_args(p)
+ # Since THeaderTransport acts as framed transport when detected frame, we
+ # cannot use --transport=framed as it would result in 2 layered frames.
+ p.add_argument('--override-transport')
+ p.add_argument('--override-protocol')
+ args = p.parse_args()
+ assert args.protocol == 'header'
+ assert args.transport == 'buffered'
+ assert not args.ssl
+
+ sock = TSocket(args.host, args.port, socket_family=socket.AF_INET)
+ if not args.override_transport or args.override_transport == 'buffered':
+ trans = TBufferedTransport(sock)
+ elif args.override_transport == 'framed':
+ print('TFRAMED')
+ trans = TFramedTransport(sock)
+ else:
+ raise ValueError('invalid transport')
+ trans.open()
+
+ if not args.override_protocol or args.override_protocol == 'binary':
+ proto = TBinaryProtocol(trans)
+ elif args.override_protocol == 'compact':
+ proto = TCompactProtocol(trans)
+ else:
+ raise ValueError('invalid transport')
+
+ test_void(proto)
+ test_void(proto)
+
+ trans.close()
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/src/jaegertracing/thrift/test/features/tls.sh b/src/jaegertracing/thrift/test/features/tls.sh
new file mode 100755
index 000000000..6fd90a5fc
--- /dev/null
+++ b/src/jaegertracing/thrift/test/features/tls.sh
@@ -0,0 +1,72 @@
+#!/bin/bash
+
+#
+# Checks to make sure TLSv1.0 or later is allowed by a server.
+#
+
+THRIFTHOST=localhost
+THRIFTPORT=9090
+
+while [[ $# -ge 1 ]]; do
+ arg="$1"
+ argIN=(${arg//=/ })
+
+ case ${argIN[0]} in
+ -h|--host)
+ THRIFTHOST=${argIN[1]}
+ shift # past argument
+ ;;
+ -p|--port)
+ THRIFTPORT=${argIN[1]}
+ shift # past argument
+ ;;
+ *)
+ # unknown option ignored
+ ;;
+ esac
+
+ shift # past argument or value
+done
+
+declare -A EXPECT_NEGOTIATE
+EXPECT_NEGOTIATE[tls1]=1
+EXPECT_NEGOTIATE[tls1_1]=1
+EXPECT_NEGOTIATE[tls1_2]=1
+EXPECT_NEGOTIATE[tls1_3]=1
+
+failures=0
+
+function tls
+{
+ for PROTO in "${!EXPECT_NEGOTIATE[@]}"; do
+
+ local nego
+ local negodenied
+ local res
+
+ echo "openssl s_client -connect $THRIFTHOST:$THRIFTPORT -CAfile ../keys/CA.pem -$PROTO 2>&1 < /dev/null"
+ nego=$(openssl s_client -connect $THRIFTHOST:$THRIFTPORT -CAfile ../keys/CA.pem -$PROTO 2>&1 < /dev/null)
+ negodenied=$?
+ echo "result of command: $negodenied"
+
+ res="enabled"; if [[ ${EXPECT_NEGOTIATE[$PROTO]} -eq 0 ]]; then res="disabled"; fi
+
+ if [[ $negodenied -ne ${EXPECT_NEGOTIATE[$PROTO]} ]]; then
+ echo "$PROTO negotiation allowed"
+ else
+ echo "[warn] $PROTO negotiation did not work"
+ echo $nego
+ ((failures++))
+ fi
+ done
+}
+
+tls
+
+if [[ $failures -eq 4 ]]; then
+ echo "[fail] At least one of TLSv1.0, TLSv1.1, TLSv1.2, or TLSv1.3 needs to work, but does not"
+ exit $failures
+fi
+
+echo "[pass] At least one of TLSv1.0, TLSv1.1, TLSv1.2, or TLSv1.3 worked"
+exit 0
diff --git a/src/jaegertracing/thrift/test/features/util.py b/src/jaegertracing/thrift/test/features/util.py
new file mode 100644
index 000000000..3abbbbd9a
--- /dev/null
+++ b/src/jaegertracing/thrift/test/features/util.py
@@ -0,0 +1,40 @@
+import argparse
+import socket
+
+from local_thrift import thrift # noqa
+from thrift.transport.TSocket import TSocket
+from thrift.transport.TTransport import TBufferedTransport, TFramedTransport
+from thrift.transport.THttpClient import THttpClient
+from thrift.protocol.TBinaryProtocol import TBinaryProtocol
+from thrift.protocol.TCompactProtocol import TCompactProtocol
+from thrift.protocol.TJSONProtocol import TJSONProtocol
+
+
+def add_common_args(p):
+ p.add_argument('--host', default='localhost')
+ p.add_argument('--port', type=int, default=9090)
+ p.add_argument('--protocol', default='binary')
+ p.add_argument('--transport', default='buffered')
+ p.add_argument('--ssl', action='store_true')
+
+
+def parse_common_args(argv):
+ p = argparse.ArgumentParser()
+ add_common_args(p)
+ return p.parse_args(argv)
+
+
+def init_protocol(args):
+ sock = TSocket(args.host, args.port, socket_family=socket.AF_INET)
+ sock.setTimeout(500)
+ trans = {
+ 'buffered': TBufferedTransport,
+ 'framed': TFramedTransport,
+ 'http': THttpClient,
+ }[args.transport](sock)
+ trans.open()
+ return {
+ 'binary': TBinaryProtocol,
+ 'compact': TCompactProtocol,
+ 'json': TJSONProtocol,
+ }[args.protocol](trans)