Merge pull request #15176 from apolcyn/convert_resolver_component_test_to_python

Convert c-ares test runner from bash to python, to support windows
pull/15317/head
apolcyn 7 years ago committed by GitHub
commit eed1b6f45c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 191
      templates/test/cpp/naming/resolver_component_tests_defs.include
  2. 0
      templates/test/cpp/naming/resolver_component_tests_runner.py.template
  3. 7
      test/cpp/naming/BUILD
  4. 2
      test/cpp/naming/generate_resolver_component_tests.bzl
  5. 275
      test/cpp/naming/resolver_component_tests_runner.py
  6. 187
      test/cpp/naming/resolver_component_tests_runner.sh
  7. 2
      test/cpp/naming/resolver_component_tests_runner_invoker.cc
  8. 6
      test/cpp/naming/utils/dns_resolver.py
  9. 21
      test/cpp/naming/utils/dns_server.py
  10. 6
      test/cpp/naming/utils/tcp_connect.py

@ -1,4 +1,4 @@
<%def name="resolver_component_tests(tests)">#!/bin/bash <%def name="resolver_component_tests(tests)">#!/usr/bin/env python
# Copyright 2015 gRPC authors. # Copyright 2015 gRPC authors.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
@ -15,84 +15,129 @@
# This file is auto-generated # This file is auto-generated
set -ex import argparse
import sys
# all command args required in this set order import subprocess
FLAGS_test_bin_path=$(echo "$1" | grep '\--test_bin_path=' | sed 's/^--test_bin_path=//') import tempfile
FLAGS_dns_server_bin_path=$(echo "$2" | grep '\--dns_server_bin_path=' | sed 's/^--dns_server_bin_path=//') import os
FLAGS_records_config_path=$(echo "$3" | grep '\--records_config_path=' | sed 's/^--records_config_path=//') import time
FLAGS_dns_server_port=$(echo "$4" | grep '\--dns_server_port=' | sed 's/^--dns_server_port=//') import signal
FLAGS_dns_resolver_bin_path=$(echo "$5" | grep '\--dns_resolver_bin_path=' | sed 's/^--dns_resolver_bin_path=//')
FLAGS_tcp_connect_bin_path=$(echo "$6" | grep '\--tcp_connect_bin_path=' | sed 's/^--tcp_connect_bin_path=//')
argp = argparse.ArgumentParser(description='Run c-ares resolver tests')
for cmd_arg in "$FLAGS_test_bin_path" "$FLAGS_dns_server_bin_path" "$FLAGS_records_config_path" "$FLAGS_dns_server_port" "$FLAGS_dns_resolver_bin_path" "$FLAGS_tcp_connect_bin_path"; do argp.add_argument('--test_bin_path', default=None, type=str,
if [[ "$cmd_arg" == "" ]]; then help='Path to gtest test binary to invoke.')
echo "Missing a CMD arg" && exit 1 argp.add_argument('--dns_server_bin_path', default=None, type=str,
fi help='Path to local DNS server python script.')
done argp.add_argument('--records_config_path', default=None, type=str,
help=('Path to DNS records yaml file that '
if [[ "$GRPC_DNS_RESOLVER" != "" && "$GRPC_DNS_RESOLVER" != ares ]]; then 'specifies records for the DNS sever. '))
echo "This test only works under GRPC_DNS_RESOLVER=ares. Have GRPC_DNS_RESOLVER=$GRPC_DNS_RESOLVER" && exit 1 argp.add_argument('--dns_server_port', default=None, type=int,
fi help=('Port that local DNS server is listening on.'))
export GRPC_DNS_RESOLVER=ares argp.add_argument('--dns_resolver_bin_path', default=None, type=str,
help=('Path to the DNS health check utility.'))
DNS_SERVER_LOG="$(mktemp)" argp.add_argument('--tcp_connect_bin_path', default=None, type=str,
"$FLAGS_dns_server_bin_path" --records_config_path="$FLAGS_records_config_path" --port="$FLAGS_dns_server_port" > "$DNS_SERVER_LOG" 2>&1 & help=('Path to the TCP health check utility.'))
DNS_SERVER_PID=$! args = argp.parse_args()
echo "Local DNS server started. PID: $DNS_SERVER_PID"
def test_runner_log(msg):
# Health check local DNS server TCP and UDP ports sys.stderr.write('\n%s: %s\n' % (__file__, msg))
for ((i=0;i<30;i++));
do cur_resolver = os.environ.get('GRPC_DNS_RESOLVER')
echo "Retry health-check local DNS server by attempting a DNS query and TCP handshake" if cur_resolver and cur_resolver != 'ares':
RETRY=0 test_runner_log(('WARNING: cur resolver set to %s. This set of tests '
$FLAGS_dns_resolver_bin_path -s 127.0.0.1 -p "$FLAGS_dns_server_port" -n health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp. -t 1 | grep '123.123.123.123' || RETRY=1 'needs to use GRPC_DNS_RESOLVER=ares.'))
$FLAGS_tcp_connect_bin_path -s 127.0.0.1 -p "$FLAGS_dns_server_port" -t 1 || RETRY=1 test_runner_log('Exit 1 without running tests.')
if [[ "$RETRY" == 0 ]]; then sys.exit(1)
break os.environ.update({'GRPC_DNS_RESOLVER': 'ares'})
fi;
sleep 0.1 def wait_until_dns_server_is_up(args,
done dns_server_subprocess,
dns_server_subprocess_output):
if [[ $RETRY == 1 ]]; then for i in range(0, 30):
echo "FAILED TO START LOCAL DNS SERVER" test_runner_log('Health check: attempt to connect to DNS server over TCP.')
kill -SIGTERM "$DNS_SERVER_PID" || true tcp_connect_subprocess = subprocess.Popen([
wait args.tcp_connect_bin_path,
echo "========== DNS server log (merged stdout and stderr) =========" '--server_host', '127.0.0.1',
cat "$DNS_SERVER_LOG" '--server_port', str(args.dns_server_port),
echo "========== end DNS server log ================================" '--timeout', str(1)])
exit 1 tcp_connect_subprocess.communicate()
fi if tcp_connect_subprocess.returncode == 0:
test_runner_log(('Health check: attempt to make an A-record '
function terminate_all { 'query to DNS server.'))
echo "Received signal. Terminating $! and $DNS_SERVER_PID" dns_resolver_subprocess = subprocess.Popen([
kill -SIGTERM "$!" || true args.dns_resolver_bin_path,
kill -SIGTERM "$DNS_SERVER_PID" || true '--qname', 'health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp',
wait '--server_host', '127.0.0.1',
exit 1 '--server_port', str(args.dns_server_port)],
} stdout=subprocess.PIPE)
dns_resolver_stdout, _ = dns_resolver_subprocess.communicate()
trap terminate_all SIGTERM SIGINT if dns_resolver_subprocess.returncode == 0:
if '123.123.123.123' in dns_resolver_stdout:
EXIT_CODE=0 test_runner_log(('DNS server is up! '
# TODO: this test should check for GCE residency and skip tests using _grpclb._tcp.* SRV records once GCE residency checks are made 'Successfully reached it over UDP and TCP.'))
# in the resolver. return
time.sleep(0.1)
dns_server_subprocess.kill()
dns_server_subprocess.wait()
test_runner_log(('Failed to reach DNS server over TCP and/or UDP. '
'Exitting without running tests.'))
test_runner_log('======= DNS server stdout '
'(merged stdout and stderr) =============')
with open(dns_server_subprocess_output, 'r') as l:
test_runner_log(l.read())
test_runner_log('======= end DNS server output=========')
sys.exit(1)
dns_server_subprocess_output = tempfile.mktemp()
with open(dns_server_subprocess_output, 'w') as l:
dns_server_subprocess = subprocess.Popen([
args.dns_server_bin_path,
'--port', str(args.dns_server_port),
'--records_config_path', args.records_config_path],
stdin=subprocess.PIPE,
stdout=l,
stderr=l)
def _quit_on_signal(signum, _frame):
test_runner_log('Received signal: %d' % signum)
dns_server_subprocess.kill()
dns_server_subprocess.wait()
sys.exit(1)
signal.signal(signal.SIGINT, _quit_on_signal)
signal.signal(signal.SIGTERM, _quit_on_signal)
wait_until_dns_server_is_up(args,
dns_server_subprocess,
dns_server_subprocess_output)
num_test_failures = 0
% for test in tests: % for test in tests:
$FLAGS_test_bin_path \\ test_runner_log('Run test with target: %s' % '${test['target_name']}')\
--target_name='${test['target_name']}' \\ current_test_subprocess = subprocess.Popen([\
--expected_addrs='${test['expected_addrs']}' \\ args.test_bin_path,\
--expected_chosen_service_config='${test['expected_chosen_service_config']}' \\ '--target_name', '${test['target_name']}',\
--expected_lb_policy='${test['expected_lb_policy']}' \\ '--expected_addrs', '${test['expected_addrs']}',\
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" & '--expected_chosen_service_config', '${test['expected_chosen_service_config']}',\
wait "$!" || EXIT_CODE=1
'--expected_lb_policy', '${test['expected_lb_policy']}',\
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])\
current_test_subprocess.communicate()\
if current_test_subprocess.returncode != 0:\
num_test_failures += 1
% endfor % endfor
kill -SIGTERM "$DNS_SERVER_PID" || true test_runner_log('now kill DNS server')
wait dns_server_subprocess.kill()
exit $EXIT_CODE</%def> dns_server_subprocess.wait()
test_runner_log('%d tests failed.' % num_test_failures)
sys.exit(num_test_failures)</%def>

@ -22,16 +22,17 @@ package(
licenses(["notice"]) # Apache v2 licenses(["notice"]) # Apache v2
load("//bazel:grpc_build_system.bzl", "grpc_sh_binary", "grpc_py_binary") load("//bazel:grpc_build_system.bzl", "grpc_py_binary")
load(":generate_resolver_component_tests.bzl", "generate_resolver_component_tests") load(":generate_resolver_component_tests.bzl", "generate_resolver_component_tests")
# Meant to be invoked only through the top-level shell script driver. # Meant to be invoked only through the top-level shell script driver.
grpc_sh_binary( grpc_py_binary(
name = "resolver_component_tests_runner", name = "resolver_component_tests_runner",
srcs = [ srcs = [
"resolver_component_tests_runner.sh", "resolver_component_tests_runner.py",
], ],
testonly = True,
) )
generate_resolver_component_tests() generate_resolver_component_tests()

@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
load("//bazel:grpc_build_system.bzl", "grpc_sh_binary", "grpc_cc_test", "grpc_cc_binary") load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_binary")
def generate_resolver_component_tests(): def generate_resolver_component_tests():
for unsecure_build_config_suffix in ['_unsecure', '']: for unsecure_build_config_suffix in ['_unsecure', '']:

@ -0,0 +1,275 @@
#!/usr/bin/env python
# Copyright 2015 gRPC authors.
#
# Licensed 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.
# This file is auto-generated
import argparse
import sys
import subprocess
import tempfile
import os
import time
import signal
argp = argparse.ArgumentParser(description='Run c-ares resolver tests')
argp.add_argument('--test_bin_path', default=None, type=str,
help='Path to gtest test binary to invoke.')
argp.add_argument('--dns_server_bin_path', default=None, type=str,
help='Path to local DNS server python script.')
argp.add_argument('--records_config_path', default=None, type=str,
help=('Path to DNS records yaml file that '
'specifies records for the DNS sever. '))
argp.add_argument('--dns_server_port', default=None, type=int,
help=('Port that local DNS server is listening on.'))
argp.add_argument('--dns_resolver_bin_path', default=None, type=str,
help=('Path to the DNS health check utility.'))
argp.add_argument('--tcp_connect_bin_path', default=None, type=str,
help=('Path to the TCP health check utility.'))
args = argp.parse_args()
def test_runner_log(msg):
sys.stderr.write('\n%s: %s\n' % (__file__, msg))
cur_resolver = os.environ.get('GRPC_DNS_RESOLVER')
if cur_resolver and cur_resolver != 'ares':
test_runner_log(('WARNING: cur resolver set to %s. This set of tests '
'needs to use GRPC_DNS_RESOLVER=ares.'))
test_runner_log('Exit 1 without running tests.')
sys.exit(1)
os.environ.update({'GRPC_DNS_RESOLVER': 'ares'})
def wait_until_dns_server_is_up(args,
dns_server_subprocess,
dns_server_subprocess_output):
for i in range(0, 30):
test_runner_log('Health check: attempt to connect to DNS server over TCP.')
tcp_connect_subprocess = subprocess.Popen([
args.tcp_connect_bin_path,
'--server_host', '127.0.0.1',
'--server_port', str(args.dns_server_port),
'--timeout', str(1)])
tcp_connect_subprocess.communicate()
if tcp_connect_subprocess.returncode == 0:
test_runner_log(('Health check: attempt to make an A-record '
'query to DNS server.'))
dns_resolver_subprocess = subprocess.Popen([
args.dns_resolver_bin_path,
'--qname', 'health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp',
'--server_host', '127.0.0.1',
'--server_port', str(args.dns_server_port)],
stdout=subprocess.PIPE)
dns_resolver_stdout, _ = dns_resolver_subprocess.communicate()
if dns_resolver_subprocess.returncode == 0:
if '123.123.123.123' in dns_resolver_stdout:
test_runner_log(('DNS server is up! '
'Successfully reached it over UDP and TCP.'))
return
time.sleep(0.1)
dns_server_subprocess.kill()
dns_server_subprocess.wait()
test_runner_log(('Failed to reach DNS server over TCP and/or UDP. '
'Exitting without running tests.'))
test_runner_log('======= DNS server stdout '
'(merged stdout and stderr) =============')
with open(dns_server_subprocess_output, 'r') as l:
test_runner_log(l.read())
test_runner_log('======= end DNS server output=========')
sys.exit(1)
dns_server_subprocess_output = tempfile.mktemp()
with open(dns_server_subprocess_output, 'w') as l:
dns_server_subprocess = subprocess.Popen([
args.dns_server_bin_path,
'--port', str(args.dns_server_port),
'--records_config_path', args.records_config_path],
stdin=subprocess.PIPE,
stdout=l,
stderr=l)
def _quit_on_signal(signum, _frame):
test_runner_log('Received signal: %d' % signum)
dns_server_subprocess.kill()
dns_server_subprocess.wait()
sys.exit(1)
signal.signal(signal.SIGINT, _quit_on_signal)
signal.signal(signal.SIGTERM, _quit_on_signal)
wait_until_dns_server_is_up(args,
dns_server_subprocess,
dns_server_subprocess_output)
num_test_failures = 0
test_runner_log('Run test with target: %s' % 'srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.')
current_test_subprocess = subprocess.Popen([
args.test_bin_path,
'--target_name', 'srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.',
'--expected_addrs', '1.2.3.4:1234,True',
'--expected_chosen_service_config', '',
'--expected_lb_policy', '',
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
current_test_subprocess.communicate()
if current_test_subprocess.returncode != 0:
num_test_failures += 1
test_runner_log('Run test with target: %s' % 'srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.')
current_test_subprocess = subprocess.Popen([
args.test_bin_path,
'--target_name', 'srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.',
'--expected_addrs', '1.2.3.5:1234,True;1.2.3.6:1234,True;1.2.3.7:1234,True',
'--expected_chosen_service_config', '',
'--expected_lb_policy', '',
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
current_test_subprocess.communicate()
if current_test_subprocess.returncode != 0:
num_test_failures += 1
test_runner_log('Run test with target: %s' % 'srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.')
current_test_subprocess = subprocess.Popen([
args.test_bin_path,
'--target_name', 'srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.',
'--expected_addrs', '[2607:f8b0:400a:801::1001]:1234,True',
'--expected_chosen_service_config', '',
'--expected_lb_policy', '',
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
current_test_subprocess.communicate()
if current_test_subprocess.returncode != 0:
num_test_failures += 1
test_runner_log('Run test with target: %s' % 'srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.')
current_test_subprocess = subprocess.Popen([
args.test_bin_path,
'--target_name', 'srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.',
'--expected_addrs', '[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1003]:1234,True;[2607:f8b0:400a:801::1004]:1234,True',
'--expected_chosen_service_config', '',
'--expected_lb_policy', '',
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
current_test_subprocess.communicate()
if current_test_subprocess.returncode != 0:
num_test_failures += 1
test_runner_log('Run test with target: %s' % 'srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.')
current_test_subprocess = subprocess.Popen([
args.test_bin_path,
'--target_name', 'srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.',
'--expected_addrs', '1.2.3.4:1234,True',
'--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}',
'--expected_lb_policy', 'round_robin',
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
current_test_subprocess.communicate()
if current_test_subprocess.returncode != 0:
num_test_failures += 1
test_runner_log('Run test with target: %s' % 'ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.')
current_test_subprocess = subprocess.Popen([
args.test_bin_path,
'--target_name', 'ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.',
'--expected_addrs', '1.2.3.4:443,False',
'--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}',
'--expected_lb_policy', 'round_robin',
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
current_test_subprocess.communicate()
if current_test_subprocess.returncode != 0:
num_test_failures += 1
test_runner_log('Run test with target: %s' % 'ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.')
current_test_subprocess = subprocess.Popen([
args.test_bin_path,
'--target_name', 'ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.',
'--expected_addrs', '1.2.3.4:443,False',
'--expected_chosen_service_config', '',
'--expected_lb_policy', '',
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
current_test_subprocess.communicate()
if current_test_subprocess.returncode != 0:
num_test_failures += 1
test_runner_log('Run test with target: %s' % 'ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.')
current_test_subprocess = subprocess.Popen([
args.test_bin_path,
'--target_name', 'ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.',
'--expected_addrs', '1.2.3.4:443,False',
'--expected_chosen_service_config', '',
'--expected_lb_policy', '',
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
current_test_subprocess.communicate()
if current_test_subprocess.returncode != 0:
num_test_failures += 1
test_runner_log('Run test with target: %s' % 'ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.')
current_test_subprocess = subprocess.Popen([
args.test_bin_path,
'--target_name', 'ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.',
'--expected_addrs', '1.2.3.4:443,False',
'--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}',
'--expected_lb_policy', 'round_robin',
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
current_test_subprocess.communicate()
if current_test_subprocess.returncode != 0:
num_test_failures += 1
test_runner_log('Run test with target: %s' % 'ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.')
current_test_subprocess = subprocess.Popen([
args.test_bin_path,
'--target_name', 'ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.',
'--expected_addrs', '1.2.3.4:443,False',
'--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}',
'--expected_lb_policy', 'round_robin',
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
current_test_subprocess.communicate()
if current_test_subprocess.returncode != 0:
num_test_failures += 1
test_runner_log('Run test with target: %s' % 'srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.')
current_test_subprocess = subprocess.Popen([
args.test_bin_path,
'--target_name', 'srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.',
'--expected_addrs', '1.2.3.4:1234,True;1.2.3.4:443,False',
'--expected_chosen_service_config', '',
'--expected_lb_policy', '',
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
current_test_subprocess.communicate()
if current_test_subprocess.returncode != 0:
num_test_failures += 1
test_runner_log('Run test with target: %s' % 'srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.')
current_test_subprocess = subprocess.Popen([
args.test_bin_path,
'--target_name', 'srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.',
'--expected_addrs', '[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1002]:443,False',
'--expected_chosen_service_config', '',
'--expected_lb_policy', '',
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
current_test_subprocess.communicate()
if current_test_subprocess.returncode != 0:
num_test_failures += 1
test_runner_log('Run test with target: %s' % 'ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.')
current_test_subprocess = subprocess.Popen([
args.test_bin_path,
'--target_name', 'ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.',
'--expected_addrs', '1.2.3.4:443,False',
'--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooThree","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFour","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFive","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSix","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSeven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEight","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooNine","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTen","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEleven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]}]}',
'--expected_lb_policy', '',
'--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
current_test_subprocess.communicate()
if current_test_subprocess.returncode != 0:
num_test_failures += 1
test_runner_log('now kill DNS server')
dns_server_subprocess.kill()
dns_server_subprocess.wait()
test_runner_log('%d tests failed.' % num_test_failures)
sys.exit(num_test_failures)

@ -1,187 +0,0 @@
#!/bin/bash
# Copyright 2015 gRPC authors.
#
# Licensed 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.
# This file is auto-generated
set -ex
# all command args required in this set order
FLAGS_test_bin_path=$(echo "$1" | grep '\--test_bin_path=' | sed 's/^--test_bin_path=//')
FLAGS_dns_server_bin_path=$(echo "$2" | grep '\--dns_server_bin_path=' | sed 's/^--dns_server_bin_path=//')
FLAGS_records_config_path=$(echo "$3" | grep '\--records_config_path=' | sed 's/^--records_config_path=//')
FLAGS_dns_server_port=$(echo "$4" | grep '\--dns_server_port=' | sed 's/^--dns_server_port=//')
FLAGS_dns_resolver_bin_path=$(echo "$5" | grep '\--dns_resolver_bin_path=' | sed 's/^--dns_resolver_bin_path=//')
FLAGS_tcp_connect_bin_path=$(echo "$6" | grep '\--tcp_connect_bin_path=' | sed 's/^--tcp_connect_bin_path=//')
for cmd_arg in "$FLAGS_test_bin_path" "$FLAGS_dns_server_bin_path" "$FLAGS_records_config_path" "$FLAGS_dns_server_port" "$FLAGS_dns_resolver_bin_path" "$FLAGS_tcp_connect_bin_path"; do
if [[ "$cmd_arg" == "" ]]; then
echo "Missing a CMD arg" && exit 1
fi
done
if [[ "$GRPC_DNS_RESOLVER" != "" && "$GRPC_DNS_RESOLVER" != ares ]]; then
echo "This test only works under GRPC_DNS_RESOLVER=ares. Have GRPC_DNS_RESOLVER=$GRPC_DNS_RESOLVER" && exit 1
fi
export GRPC_DNS_RESOLVER=ares
DNS_SERVER_LOG="$(mktemp)"
"$FLAGS_dns_server_bin_path" --records_config_path="$FLAGS_records_config_path" --port="$FLAGS_dns_server_port" > "$DNS_SERVER_LOG" 2>&1 &
DNS_SERVER_PID=$!
echo "Local DNS server started. PID: $DNS_SERVER_PID"
# Health check local DNS server TCP and UDP ports
for ((i=0;i<30;i++));
do
echo "Retry health-check local DNS server by attempting a DNS query and TCP handshake"
RETRY=0
$FLAGS_dns_resolver_bin_path -s 127.0.0.1 -p "$FLAGS_dns_server_port" -n health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp. -t 1 | grep '123.123.123.123' || RETRY=1
$FLAGS_tcp_connect_bin_path -s 127.0.0.1 -p "$FLAGS_dns_server_port" -t 1 || RETRY=1
if [[ "$RETRY" == 0 ]]; then
break
fi;
sleep 0.1
done
if [[ $RETRY == 1 ]]; then
echo "FAILED TO START LOCAL DNS SERVER"
kill -SIGTERM "$DNS_SERVER_PID" || true
wait
echo "========== DNS server log (merged stdout and stderr) ========="
cat "$DNS_SERVER_LOG"
echo "========== end DNS server log ================================"
exit 1
fi
function terminate_all {
echo "Received signal. Terminating $! and $DNS_SERVER_PID"
kill -SIGTERM "$!" || true
kill -SIGTERM "$DNS_SERVER_PID" || true
wait
exit 1
}
trap terminate_all SIGTERM SIGINT
EXIT_CODE=0
# TODO: this test should check for GCE residency and skip tests using _grpclb._tcp.* SRV records once GCE residency checks are made
# in the resolver.
$FLAGS_test_bin_path \
--target_name='srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.' \
--expected_addrs='1.2.3.4:1234,True' \
--expected_chosen_service_config='' \
--expected_lb_policy='' \
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
wait "$!" || EXIT_CODE=1
$FLAGS_test_bin_path \
--target_name='srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.' \
--expected_addrs='1.2.3.5:1234,True;1.2.3.6:1234,True;1.2.3.7:1234,True' \
--expected_chosen_service_config='' \
--expected_lb_policy='' \
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
wait "$!" || EXIT_CODE=1
$FLAGS_test_bin_path \
--target_name='srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.' \
--expected_addrs='[2607:f8b0:400a:801::1001]:1234,True' \
--expected_chosen_service_config='' \
--expected_lb_policy='' \
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
wait "$!" || EXIT_CODE=1
$FLAGS_test_bin_path \
--target_name='srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.' \
--expected_addrs='[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1003]:1234,True;[2607:f8b0:400a:801::1004]:1234,True' \
--expected_chosen_service_config='' \
--expected_lb_policy='' \
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
wait "$!" || EXIT_CODE=1
$FLAGS_test_bin_path \
--target_name='srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.' \
--expected_addrs='1.2.3.4:1234,True' \
--expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}' \
--expected_lb_policy='round_robin' \
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
wait "$!" || EXIT_CODE=1
$FLAGS_test_bin_path \
--target_name='ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.' \
--expected_addrs='1.2.3.4:443,False' \
--expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}' \
--expected_lb_policy='round_robin' \
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
wait "$!" || EXIT_CODE=1
$FLAGS_test_bin_path \
--target_name='ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.' \
--expected_addrs='1.2.3.4:443,False' \
--expected_chosen_service_config='' \
--expected_lb_policy='' \
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
wait "$!" || EXIT_CODE=1
$FLAGS_test_bin_path \
--target_name='ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.' \
--expected_addrs='1.2.3.4:443,False' \
--expected_chosen_service_config='' \
--expected_lb_policy='' \
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
wait "$!" || EXIT_CODE=1
$FLAGS_test_bin_path \
--target_name='ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.' \
--expected_addrs='1.2.3.4:443,False' \
--expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}' \
--expected_lb_policy='round_robin' \
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
wait "$!" || EXIT_CODE=1
$FLAGS_test_bin_path \
--target_name='ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.' \
--expected_addrs='1.2.3.4:443,False' \
--expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}' \
--expected_lb_policy='round_robin' \
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
wait "$!" || EXIT_CODE=1
$FLAGS_test_bin_path \
--target_name='srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.' \
--expected_addrs='1.2.3.4:1234,True;1.2.3.4:443,False' \
--expected_chosen_service_config='' \
--expected_lb_policy='' \
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
wait "$!" || EXIT_CODE=1
$FLAGS_test_bin_path \
--target_name='srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.' \
--expected_addrs='[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1002]:443,False' \
--expected_chosen_service_config='' \
--expected_lb_policy='' \
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
wait "$!" || EXIT_CODE=1
$FLAGS_test_bin_path \
--target_name='ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.' \
--expected_addrs='1.2.3.4:443,False' \
--expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooThree","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFour","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFive","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSix","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSeven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEight","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooNine","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTen","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEleven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]}]}' \
--expected_lb_policy='' \
--local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
wait "$!" || EXIT_CODE=1
kill -SIGTERM "$DNS_SERVER_PID" || true
wait
exit $EXIT_CODE

@ -184,7 +184,7 @@ int main(int argc, char** argv) {
std::string const bin_dir = my_bin.substr(0, my_bin.rfind('/')); std::string const bin_dir = my_bin.substr(0, my_bin.rfind('/'));
// Invoke the .sh and .py scripts directly where they are in source code. // Invoke the .sh and .py scripts directly where they are in source code.
grpc::testing::InvokeResolverComponentTestsRunner( grpc::testing::InvokeResolverComponentTestsRunner(
"test/cpp/naming/resolver_component_tests_runner.sh", "test/cpp/naming/resolver_component_tests_runner.py",
bin_dir + "/" + FLAGS_test_bin_name, bin_dir + "/" + FLAGS_test_bin_name,
"test/cpp/naming/utils/dns_server.py", "test/cpp/naming/utils/dns_server.py",
"test/cpp/naming/resolver_test_record_groups.yaml", "test/cpp/naming/resolver_test_record_groups.yaml",

@ -16,9 +16,12 @@
"""Makes DNS queries for A records to specified servers""" """Makes DNS queries for A records to specified servers"""
import argparse import argparse
import signal import threading
import time
import twisted.internet.task as task import twisted.internet.task as task
import twisted.names.client as client import twisted.names.client as client
import twisted.internet.reactor as reactor
def main(): def main():
argp = argparse.ArgumentParser(description='Make DNS queries for A records') argp = argparse.ArgumentParser(description='Make DNS queries for A records')
@ -31,7 +34,6 @@ def main():
argp.add_argument('-t', '--timeout', default=1, type=int, argp.add_argument('-t', '--timeout', default=1, type=int,
help=('Force process exit after this number of seconds.')) help=('Force process exit after this number of seconds.'))
args = argp.parse_args() args = argp.parse_args()
signal.alarm(args.timeout)
def OnResolverResultAvailable(result): def OnResolverResultAvailable(result):
answers, authority, additional = result answers, authority, additional = result
for a in answers: for a in answers:

@ -20,6 +20,8 @@ import sys
import yaml import yaml
import signal import signal
import os import os
import threading
import time
import twisted import twisted
import twisted.internet import twisted.internet
@ -33,6 +35,7 @@ import twisted.names.dns
import twisted.names.server import twisted.names.server
from twisted.names import client, server, common, authority, dns from twisted.names import client, server, common, authority, dns
import argparse import argparse
import platform
_SERVER_HEALTH_CHECK_RECORD_NAME = 'health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp' # missing end '.' for twisted syntax _SERVER_HEALTH_CHECK_RECORD_NAME = 'health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp' # missing end '.' for twisted syntax
_SERVER_HEALTH_CHECK_RECORD_DATA = '123.123.123.123' _SERVER_HEALTH_CHECK_RECORD_DATA = '123.123.123.123'
@ -115,6 +118,18 @@ def _quit_on_signal(signum, _frame):
sys.stdout.flush() sys.stdout.flush()
sys.exit(0) sys.exit(0)
def flush_stdout_loop():
num_timeouts_so_far = 0
sleep_time = 1
# Prevent zombies. Tests that use this server are short-lived.
max_timeouts = 60 * 2
while num_timeouts_so_far < max_timeouts:
sys.stdout.flush()
time.sleep(sleep_time)
num_timeouts_so_far += 1
print('Process timeout reached, or cancelled. Exitting 0.')
os.kill(os.getpid(), signal.SIGTERM)
def main(): def main():
argp = argparse.ArgumentParser(description='Local DNS Server for resolver tests') argp = argparse.ArgumentParser(description='Local DNS Server for resolver tests')
argp.add_argument('-p', '--port', default=None, type=int, argp.add_argument('-p', '--port', default=None, type=int,
@ -123,11 +138,11 @@ def main():
help=('Directory of resolver_test_record_groups.yaml file. ' help=('Directory of resolver_test_record_groups.yaml file. '
'Defauls to path needed when the test is invoked as part of run_tests.py.')) 'Defauls to path needed when the test is invoked as part of run_tests.py.'))
args = argp.parse_args() args = argp.parse_args()
signal.signal(signal.SIGALRM, _quit_on_signal)
signal.signal(signal.SIGTERM, _quit_on_signal) signal.signal(signal.SIGTERM, _quit_on_signal)
signal.signal(signal.SIGINT, _quit_on_signal) signal.signal(signal.SIGINT, _quit_on_signal)
# Prevent zombies. Tests that use this server are short-lived. output_flush_thread = threading.Thread(target=flush_stdout_loop)
signal.alarm(2 * 60) output_flush_thread.setDaemon(True)
output_flush_thread.start()
start_local_dns_server(args) start_local_dns_server(args)
if __name__ == '__main__': if __name__ == '__main__':

@ -16,8 +16,11 @@
"""Opens a TCP connection to a specified server and then exits.""" """Opens a TCP connection to a specified server and then exits."""
import argparse import argparse
import signal
import socket import socket
import threading
import time
import sys
def main(): def main():
argp = argparse.ArgumentParser(description='Open a TCP handshake to a server') argp = argparse.ArgumentParser(description='Open a TCP handshake to a server')
@ -28,7 +31,6 @@ def main():
argp.add_argument('-t', '--timeout', default=1, type=int, argp.add_argument('-t', '--timeout', default=1, type=int,
help='Force process exit after this number of seconds.') help='Force process exit after this number of seconds.')
args = argp.parse_args() args = argp.parse_args()
signal.alarm(args.timeout)
socket.create_connection([args.server_host, args.server_port]) socket.create_connection([args.server_host, args.server_port])
if __name__ == '__main__': if __name__ == '__main__':

Loading…
Cancel
Save