diff options
Diffstat (limited to 'src/jaegertracing/thrift/test/features')
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) |