mirror of https://github.com/grpc/grpc.git
commit
d4477c17e7
94 changed files with 3196 additions and 884 deletions
@ -0,0 +1,92 @@ |
|||||||
|
<%def name="resolver_component_tests(tests)">#!/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=' | cut -d "=" -f 2` |
||||||
|
FLAGS_dns_server_bin_path=`echo "$2" | grep '\--dns_server_bin_path=' | cut -d "=" -f 2` |
||||||
|
FLAGS_records_config_path=`echo "$3" | grep '\--records_config_path=' | cut -d "=" -f 2` |
||||||
|
FLAGS_test_dns_server_port=`echo "$4" | grep '\--test_dns_server_port=' | cut -d "=" -f 2` |
||||||
|
|
||||||
|
for cmd_arg in "$FLAGS_test_bin_path" "$FLAGS_dns_server_bin_path" "$FLAGS_records_config_path" "$FLAGS_test_dns_server_port"; 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 |
||||||
|
|
||||||
|
"$FLAGS_dns_server_bin_path" --records_config_path="$FLAGS_records_config_path" --port="$FLAGS_test_dns_server_port" 2>&1 > /dev/null & |
||||||
|
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 DNS query to local DNS server over tcp and udp" |
||||||
|
RETRY=0 |
||||||
|
dig A health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp. @localhost -p "$FLAGS_test_dns_server_port" +tries=1 +timeout=1 | grep '123.123.123.123' || RETRY=1 |
||||||
|
dig A health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp. @localhost -p "$FLAGS_test_dns_server_port" +tries=1 +timeout=1 +tcp | grep '123.123.123.123' || 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 |
||||||
|
wait |
||||||
|
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. |
||||||
|
|
||||||
|
% for test in tests: |
||||||
|
$FLAGS_test_bin_path \\ |
||||||
|
|
||||||
|
--target_name='${test['target_name']}' \\ |
||||||
|
|
||||||
|
--expected_addrs='${test['expected_addrs']}' \\ |
||||||
|
|
||||||
|
--expected_chosen_service_config='${test['expected_chosen_service_config']}' \\ |
||||||
|
|
||||||
|
--expected_lb_policy='${test['expected_lb_policy']}' \\ |
||||||
|
|
||||||
|
--local_dns_server_address=127.0.0.1:$FLAGS_test_dns_server_port & |
||||||
|
wait $! || EXIT_CODE=1 |
||||||
|
|
||||||
|
% endfor |
||||||
|
kill -SIGTERM $DNS_SERVER_PID || true |
||||||
|
wait |
||||||
|
exit $EXIT_CODE</%def> |
@ -0,0 +1,4 @@ |
|||||||
|
%YAML 1.2 |
||||||
|
--- | |
||||||
|
<%namespace file="resolver_component_tests_defs.include" import="*"/>\ |
||||||
|
${resolver_component_tests(resolver_component_test_cases)} |
@ -0,0 +1,49 @@ |
|||||||
|
# Copyright 2017 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. |
||||||
|
|
||||||
|
package( |
||||||
|
default_visibility = ["//visibility:public"], |
||||||
|
features = [ |
||||||
|
"-layering_check", |
||||||
|
"-parse_headers", |
||||||
|
], |
||||||
|
) |
||||||
|
|
||||||
|
licenses(["notice"]) # Apache v2 |
||||||
|
|
||||||
|
load("//bazel:grpc_build_system.bzl", "grpc_sh_binary", "grpc_py_binary") |
||||||
|
|
||||||
|
load(":generate_resolver_component_tests.bzl", "generate_resolver_component_tests") |
||||||
|
|
||||||
|
# Meant to be invoked only through the top-level shell script driver. |
||||||
|
grpc_sh_binary( |
||||||
|
name = "resolver_component_tests_runner", |
||||||
|
srcs = [ |
||||||
|
"resolver_component_tests_runner.sh", |
||||||
|
], |
||||||
|
) |
||||||
|
|
||||||
|
grpc_py_binary( |
||||||
|
name = "test_dns_server", |
||||||
|
srcs = ["test_dns_server.py"], |
||||||
|
data = [ |
||||||
|
"resolver_test_record_groups.yaml", |
||||||
|
], |
||||||
|
deps = [ |
||||||
|
"twisted", |
||||||
|
"yaml", |
||||||
|
] |
||||||
|
) |
||||||
|
|
||||||
|
generate_resolver_component_tests() |
@ -0,0 +1,99 @@ |
|||||||
|
#!/usr/bin/env python2.7 |
||||||
|
# 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. |
||||||
|
|
||||||
|
|
||||||
|
"""Generates the appropriate build.json data for all the naming tests.""" |
||||||
|
|
||||||
|
|
||||||
|
import yaml |
||||||
|
import collections |
||||||
|
import hashlib |
||||||
|
import json |
||||||
|
|
||||||
|
_LOCAL_DNS_SERVER_ADDRESS = '127.0.0.1:15353' |
||||||
|
|
||||||
|
def _append_zone_name(name, zone_name): |
||||||
|
return '%s.%s' % (name, zone_name) |
||||||
|
|
||||||
|
def _build_expected_addrs_cmd_arg(expected_addrs): |
||||||
|
out = [] |
||||||
|
for addr in expected_addrs: |
||||||
|
out.append('%s,%s' % (addr['address'], str(addr['is_balancer']))) |
||||||
|
return ';'.join(out) |
||||||
|
|
||||||
|
def main(): |
||||||
|
resolver_component_data = '' |
||||||
|
with open('test/cpp/naming/resolver_test_record_groups.yaml') as f: |
||||||
|
resolver_component_data = yaml.load(f) |
||||||
|
|
||||||
|
json = { |
||||||
|
'resolver_component_test_cases': [ |
||||||
|
{ |
||||||
|
'target_name': _append_zone_name(test_case['record_to_resolve'], |
||||||
|
resolver_component_data['resolver_component_tests_common_zone_name']), |
||||||
|
'expected_addrs': _build_expected_addrs_cmd_arg(test_case['expected_addrs']), |
||||||
|
'expected_chosen_service_config': (test_case['expected_chosen_service_config'] or ''), |
||||||
|
'expected_lb_policy': (test_case['expected_lb_policy'] or ''), |
||||||
|
} for test_case in resolver_component_data['resolver_component_tests'] |
||||||
|
], |
||||||
|
'targets': [ |
||||||
|
{ |
||||||
|
'name': 'resolver_component_test' + unsecure_build_config_suffix, |
||||||
|
'build': 'test', |
||||||
|
'language': 'c++', |
||||||
|
'gtest': False, |
||||||
|
'run': False, |
||||||
|
'src': ['test/cpp/naming/resolver_component_test.cc'], |
||||||
|
'platforms': ['linux', 'posix', 'mac'], |
||||||
|
'deps': [ |
||||||
|
'grpc++_test_util' + unsecure_build_config_suffix, |
||||||
|
'grpc_test_util' + unsecure_build_config_suffix, |
||||||
|
'gpr_test_util', |
||||||
|
'grpc++' + unsecure_build_config_suffix, |
||||||
|
'grpc' + unsecure_build_config_suffix, |
||||||
|
'gpr', |
||||||
|
'grpc++_test_config', |
||||||
|
], |
||||||
|
} for unsecure_build_config_suffix in ['_unsecure', ''] |
||||||
|
] + [ |
||||||
|
{ |
||||||
|
'name': 'resolver_component_tests_runner_invoker' + unsecure_build_config_suffix, |
||||||
|
'build': 'test', |
||||||
|
'language': 'c++', |
||||||
|
'gtest': False, |
||||||
|
'run': True, |
||||||
|
'src': ['test/cpp/naming/resolver_component_tests_runner_invoker.cc'], |
||||||
|
'platforms': ['linux', 'posix', 'mac'], |
||||||
|
'deps': [ |
||||||
|
'grpc++_test_util', |
||||||
|
'grpc_test_util', |
||||||
|
'gpr_test_util', |
||||||
|
'grpc++', |
||||||
|
'grpc', |
||||||
|
'gpr', |
||||||
|
'grpc++_test_config', |
||||||
|
], |
||||||
|
'args': [ |
||||||
|
'--test_bin_name=resolver_component_test%s' % unsecure_build_config_suffix, |
||||||
|
'--running_under_bazel=false', |
||||||
|
], |
||||||
|
} for unsecure_build_config_suffix in ['_unsecure', ''] |
||||||
|
] |
||||||
|
} |
||||||
|
|
||||||
|
print(yaml.dump(json)) |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
main() |
@ -0,0 +1,64 @@ |
|||||||
|
#!/usr/bin/env python2.7 |
||||||
|
# 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. |
||||||
|
|
||||||
|
load("//bazel:grpc_build_system.bzl", "grpc_sh_binary", "grpc_cc_test", "grpc_cc_binary") |
||||||
|
|
||||||
|
def generate_resolver_component_tests(): |
||||||
|
for unsecure_build_config_suffix in ['_unsecure', '']: |
||||||
|
# meant to be invoked only through the top-level shell script driver |
||||||
|
grpc_cc_binary( |
||||||
|
name = "resolver_component_test%s" % unsecure_build_config_suffix, |
||||||
|
testonly = 1, |
||||||
|
srcs = [ |
||||||
|
"resolver_component_test.cc", |
||||||
|
], |
||||||
|
external_deps = [ |
||||||
|
"gmock", |
||||||
|
], |
||||||
|
deps = [ |
||||||
|
"//test/cpp/util:test_util%s" % unsecure_build_config_suffix, |
||||||
|
"//test/core/util:grpc_test_util%s" % unsecure_build_config_suffix, |
||||||
|
"//test/core/util:gpr_test_util", |
||||||
|
"//:grpc++%s" % unsecure_build_config_suffix, |
||||||
|
"//:grpc%s" % unsecure_build_config_suffix, |
||||||
|
"//:gpr", |
||||||
|
"//test/cpp/util:test_config", |
||||||
|
], |
||||||
|
) |
||||||
|
grpc_cc_test( |
||||||
|
name = "resolver_component_tests_runner_invoker%s" % unsecure_build_config_suffix, |
||||||
|
srcs = [ |
||||||
|
"resolver_component_tests_runner_invoker.cc", |
||||||
|
], |
||||||
|
deps = [ |
||||||
|
"//test/cpp/util:test_util", |
||||||
|
"//test/core/util:grpc_test_util", |
||||||
|
"//test/core/util:gpr_test_util", |
||||||
|
"//:grpc++", |
||||||
|
"//:grpc", |
||||||
|
"//:gpr", |
||||||
|
"//test/cpp/util:test_config", |
||||||
|
], |
||||||
|
data = [ |
||||||
|
":resolver_component_tests_runner", |
||||||
|
":resolver_component_test%s" % unsecure_build_config_suffix, |
||||||
|
":test_dns_server", |
||||||
|
"resolver_test_record_groups.yaml", # include the transitive dependency so that the dns sever py binary can locate this |
||||||
|
], |
||||||
|
args = [ |
||||||
|
"--test_bin_name=resolver_component_test%s" % unsecure_build_config_suffix, |
||||||
|
"--running_under_bazel=true", |
||||||
|
] |
||||||
|
) |
@ -0,0 +1,323 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2017 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. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <grpc/grpc.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/host_port.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/string_util.h> |
||||||
|
#include <grpc/support/sync.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include <gflags/gflags.h> |
||||||
|
#include <gmock/gmock.h> |
||||||
|
#include <vector> |
||||||
|
|
||||||
|
#include "test/cpp/util/subprocess.h" |
||||||
|
#include "test/cpp/util/test_config.h" |
||||||
|
|
||||||
|
extern "C" { |
||||||
|
#include "src/core/ext/filters/client_channel/client_channel.h" |
||||||
|
#include "src/core/ext/filters/client_channel/resolver.h" |
||||||
|
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" |
||||||
|
#include "src/core/ext/filters/client_channel/resolver_registry.h" |
||||||
|
#include "src/core/lib/channel/channel_args.h" |
||||||
|
#include "src/core/lib/iomgr/combiner.h" |
||||||
|
#include "src/core/lib/iomgr/executor.h" |
||||||
|
#include "src/core/lib/iomgr/iomgr.h" |
||||||
|
#include "src/core/lib/iomgr/resolve_address.h" |
||||||
|
#include "src/core/lib/iomgr/sockaddr_utils.h" |
||||||
|
#include "src/core/lib/support/env.h" |
||||||
|
#include "src/core/lib/support/string.h" |
||||||
|
#include "test/core/util/port.h" |
||||||
|
#include "test/core/util/test_config.h" |
||||||
|
} |
||||||
|
|
||||||
|
using std::vector; |
||||||
|
using grpc::SubProcess; |
||||||
|
using testing::UnorderedElementsAreArray; |
||||||
|
|
||||||
|
// Hack copied from "test/cpp/end2end/server_crash_test_client.cc"!
|
||||||
|
// In some distros, gflags is in the namespace google, and in some others,
|
||||||
|
// in gflags. This hack is enabling us to find both.
|
||||||
|
namespace google {} |
||||||
|
namespace gflags {} |
||||||
|
using namespace google; |
||||||
|
using namespace gflags; |
||||||
|
|
||||||
|
DEFINE_string(target_name, "", "Target name to resolve."); |
||||||
|
DEFINE_string(expected_addrs, "", |
||||||
|
"Comma-separated list of expected " |
||||||
|
"'<ip0:port0>,<is_balancer0>;<ip1:port1>,<is_balancer1>;...' " |
||||||
|
"addresses of " |
||||||
|
"backend and/or balancers. 'is_balancer' should be bool, i.e. " |
||||||
|
"true or false."); |
||||||
|
DEFINE_string(expected_chosen_service_config, "", |
||||||
|
"Expected service config json string that gets chosen (no " |
||||||
|
"whitespace). Empty for none."); |
||||||
|
DEFINE_string( |
||||||
|
local_dns_server_address, "", |
||||||
|
"Optional. This address is placed as the uri authority if present."); |
||||||
|
DEFINE_string(expected_lb_policy, "", |
||||||
|
"Expected lb policy name that appears in resolver result channel " |
||||||
|
"arg. Empty for none."); |
||||||
|
|
||||||
|
namespace { |
||||||
|
|
||||||
|
class GrpcLBAddress final { |
||||||
|
public: |
||||||
|
GrpcLBAddress(std::string address, bool is_balancer) |
||||||
|
: is_balancer(is_balancer), address(address) {} |
||||||
|
|
||||||
|
bool operator==(const GrpcLBAddress &other) const { |
||||||
|
return this->is_balancer == other.is_balancer && |
||||||
|
this->address == other.address; |
||||||
|
} |
||||||
|
|
||||||
|
bool operator!=(const GrpcLBAddress &other) const { |
||||||
|
return !(*this == other); |
||||||
|
} |
||||||
|
|
||||||
|
bool is_balancer; |
||||||
|
std::string address; |
||||||
|
}; |
||||||
|
|
||||||
|
vector<GrpcLBAddress> ParseExpectedAddrs(std::string expected_addrs) { |
||||||
|
std::vector<GrpcLBAddress> out; |
||||||
|
while (expected_addrs.size() != 0) { |
||||||
|
// get the next <ip>,<port> (v4 or v6)
|
||||||
|
size_t next_comma = expected_addrs.find(","); |
||||||
|
if (next_comma == std::string::npos) { |
||||||
|
gpr_log( |
||||||
|
GPR_ERROR, |
||||||
|
"Missing ','. Expected_addrs arg should be a semi-colon-separated " |
||||||
|
"list of " |
||||||
|
"<ip-port>,<bool> pairs. Left-to-be-parsed arg is |%s|", |
||||||
|
expected_addrs.c_str()); |
||||||
|
abort(); |
||||||
|
} |
||||||
|
std::string next_addr = expected_addrs.substr(0, next_comma); |
||||||
|
expected_addrs = expected_addrs.substr(next_comma + 1, std::string::npos); |
||||||
|
// get the next is_balancer 'bool' associated with this address
|
||||||
|
size_t next_semicolon = expected_addrs.find(";"); |
||||||
|
bool is_balancer = |
||||||
|
gpr_is_true(expected_addrs.substr(0, next_semicolon).c_str()); |
||||||
|
out.emplace_back(GrpcLBAddress(next_addr, is_balancer)); |
||||||
|
if (next_semicolon == std::string::npos) { |
||||||
|
break; |
||||||
|
} |
||||||
|
expected_addrs = |
||||||
|
expected_addrs.substr(next_semicolon + 1, std::string::npos); |
||||||
|
} |
||||||
|
if (out.size() == 0) { |
||||||
|
gpr_log(GPR_ERROR, |
||||||
|
"expected_addrs arg should be a comma-separated list of " |
||||||
|
"<ip-port>,<bool> pairs"); |
||||||
|
abort(); |
||||||
|
} |
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
gpr_timespec TestDeadline(void) { |
||||||
|
return grpc_timeout_seconds_to_deadline(100); |
||||||
|
} |
||||||
|
|
||||||
|
struct ArgsStruct { |
||||||
|
gpr_event ev; |
||||||
|
gpr_atm done_atm; |
||||||
|
gpr_mu *mu; |
||||||
|
grpc_pollset *pollset; |
||||||
|
grpc_pollset_set *pollset_set; |
||||||
|
grpc_combiner *lock; |
||||||
|
grpc_channel_args *channel_args; |
||||||
|
vector<GrpcLBAddress> expected_addrs; |
||||||
|
std::string expected_service_config_string; |
||||||
|
std::string expected_lb_policy; |
||||||
|
}; |
||||||
|
|
||||||
|
void ArgsInit(grpc_exec_ctx *exec_ctx, ArgsStruct *args) { |
||||||
|
gpr_event_init(&args->ev); |
||||||
|
args->pollset = (grpc_pollset *)gpr_zalloc(grpc_pollset_size()); |
||||||
|
grpc_pollset_init(args->pollset, &args->mu); |
||||||
|
args->pollset_set = grpc_pollset_set_create(); |
||||||
|
grpc_pollset_set_add_pollset(exec_ctx, args->pollset_set, args->pollset); |
||||||
|
args->lock = grpc_combiner_create(); |
||||||
|
gpr_atm_rel_store(&args->done_atm, 0); |
||||||
|
args->channel_args = NULL; |
||||||
|
} |
||||||
|
|
||||||
|
void DoNothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {} |
||||||
|
|
||||||
|
void ArgsFinish(grpc_exec_ctx *exec_ctx, ArgsStruct *args) { |
||||||
|
GPR_ASSERT(gpr_event_wait(&args->ev, TestDeadline())); |
||||||
|
grpc_pollset_set_del_pollset(exec_ctx, args->pollset_set, args->pollset); |
||||||
|
grpc_pollset_set_destroy(exec_ctx, args->pollset_set); |
||||||
|
grpc_closure DoNothing_cb; |
||||||
|
GRPC_CLOSURE_INIT(&DoNothing_cb, DoNothing, NULL, grpc_schedule_on_exec_ctx); |
||||||
|
grpc_pollset_shutdown(exec_ctx, args->pollset, &DoNothing_cb); |
||||||
|
// exec_ctx needs to be flushed before calling grpc_pollset_destroy()
|
||||||
|
grpc_channel_args_destroy(exec_ctx, args->channel_args); |
||||||
|
grpc_exec_ctx_flush(exec_ctx); |
||||||
|
grpc_pollset_destroy(exec_ctx, args->pollset); |
||||||
|
gpr_free(args->pollset); |
||||||
|
GRPC_COMBINER_UNREF(exec_ctx, args->lock, NULL); |
||||||
|
} |
||||||
|
|
||||||
|
gpr_timespec NSecondDeadline(int seconds) { |
||||||
|
return gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), |
||||||
|
gpr_time_from_seconds(seconds, GPR_TIMESPAN)); |
||||||
|
} |
||||||
|
|
||||||
|
void PollPollsetUntilRequestDone(ArgsStruct *args) { |
||||||
|
gpr_timespec deadline = NSecondDeadline(10); |
||||||
|
while (true) { |
||||||
|
bool done = gpr_atm_acq_load(&args->done_atm) != 0; |
||||||
|
if (done) { |
||||||
|
break; |
||||||
|
} |
||||||
|
gpr_timespec time_left = |
||||||
|
gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME)); |
||||||
|
gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09d", done, |
||||||
|
time_left.tv_sec, time_left.tv_nsec); |
||||||
|
GPR_ASSERT(gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) >= 0); |
||||||
|
grpc_pollset_worker *worker = NULL; |
||||||
|
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
||||||
|
gpr_mu_lock(args->mu); |
||||||
|
GRPC_LOG_IF_ERROR( |
||||||
|
"pollset_work", |
||||||
|
grpc_pollset_work(&exec_ctx, args->pollset, &worker, |
||||||
|
gpr_now(GPR_CLOCK_REALTIME), NSecondDeadline(1))); |
||||||
|
gpr_mu_unlock(args->mu); |
||||||
|
grpc_exec_ctx_finish(&exec_ctx); |
||||||
|
} |
||||||
|
gpr_event_set(&args->ev, (void *)1); |
||||||
|
} |
||||||
|
|
||||||
|
void CheckServiceConfigResultLocked(grpc_channel_args *channel_args, |
||||||
|
ArgsStruct *args) { |
||||||
|
const grpc_arg *service_config_arg = |
||||||
|
grpc_channel_args_find(channel_args, GRPC_ARG_SERVICE_CONFIG); |
||||||
|
if (args->expected_service_config_string != "") { |
||||||
|
GPR_ASSERT(service_config_arg != NULL); |
||||||
|
GPR_ASSERT(service_config_arg->type == GRPC_ARG_STRING); |
||||||
|
EXPECT_EQ(service_config_arg->value.string, |
||||||
|
args->expected_service_config_string); |
||||||
|
} else { |
||||||
|
GPR_ASSERT(service_config_arg == NULL); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void CheckLBPolicyResultLocked(grpc_channel_args *channel_args, |
||||||
|
ArgsStruct *args) { |
||||||
|
const grpc_arg *lb_policy_arg = |
||||||
|
grpc_channel_args_find(channel_args, GRPC_ARG_LB_POLICY_NAME); |
||||||
|
if (args->expected_lb_policy != "") { |
||||||
|
GPR_ASSERT(lb_policy_arg != NULL); |
||||||
|
GPR_ASSERT(lb_policy_arg->type == GRPC_ARG_STRING); |
||||||
|
EXPECT_EQ(lb_policy_arg->value.string, args->expected_lb_policy); |
||||||
|
} else { |
||||||
|
GPR_ASSERT(lb_policy_arg == NULL); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void CheckResolverResultLocked(grpc_exec_ctx *exec_ctx, void *argsp, |
||||||
|
grpc_error *err) { |
||||||
|
ArgsStruct *args = (ArgsStruct *)argsp; |
||||||
|
grpc_channel_args *channel_args = args->channel_args; |
||||||
|
const grpc_arg *channel_arg = |
||||||
|
grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES); |
||||||
|
GPR_ASSERT(channel_arg != NULL); |
||||||
|
GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER); |
||||||
|
grpc_lb_addresses *addresses = |
||||||
|
(grpc_lb_addresses *)channel_arg->value.pointer.p; |
||||||
|
gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR, |
||||||
|
addresses->num_addresses, args->expected_addrs.size()); |
||||||
|
GPR_ASSERT(addresses->num_addresses == args->expected_addrs.size()); |
||||||
|
std::vector<GrpcLBAddress> found_lb_addrs; |
||||||
|
for (size_t i = 0; i < addresses->num_addresses; i++) { |
||||||
|
grpc_lb_address addr = addresses->addresses[i]; |
||||||
|
char *str; |
||||||
|
grpc_sockaddr_to_string(&str, &addr.address, 1 /* normalize */); |
||||||
|
gpr_log(GPR_INFO, "%s", str); |
||||||
|
found_lb_addrs.emplace_back( |
||||||
|
GrpcLBAddress(std::string(str), addr.is_balancer)); |
||||||
|
gpr_free(str); |
||||||
|
} |
||||||
|
if (args->expected_addrs.size() != found_lb_addrs.size()) { |
||||||
|
gpr_log(GPR_DEBUG, "found lb addrs size is: %" PRIdPTR |
||||||
|
". expected addrs size is %" PRIdPTR, |
||||||
|
found_lb_addrs.size(), args->expected_addrs.size()); |
||||||
|
abort(); |
||||||
|
} |
||||||
|
EXPECT_THAT(args->expected_addrs, UnorderedElementsAreArray(found_lb_addrs)); |
||||||
|
CheckServiceConfigResultLocked(channel_args, args); |
||||||
|
CheckLBPolicyResultLocked(channel_args, args); |
||||||
|
gpr_atm_rel_store(&args->done_atm, 1); |
||||||
|
gpr_mu_lock(args->mu); |
||||||
|
GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, NULL)); |
||||||
|
gpr_mu_unlock(args->mu); |
||||||
|
} |
||||||
|
|
||||||
|
TEST(ResolverComponentTest, TestResolvesRelevantRecords) { |
||||||
|
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
||||||
|
ArgsStruct args; |
||||||
|
ArgsInit(&exec_ctx, &args); |
||||||
|
args.expected_addrs = ParseExpectedAddrs(FLAGS_expected_addrs); |
||||||
|
args.expected_service_config_string = FLAGS_expected_chosen_service_config; |
||||||
|
args.expected_lb_policy = FLAGS_expected_lb_policy; |
||||||
|
// maybe build the address with an authority
|
||||||
|
char *whole_uri = NULL; |
||||||
|
GPR_ASSERT(asprintf(&whole_uri, "dns://%s/%s", |
||||||
|
FLAGS_local_dns_server_address.c_str(), |
||||||
|
FLAGS_target_name.c_str())); |
||||||
|
// create resolver and resolve
|
||||||
|
grpc_resolver *resolver = grpc_resolver_create(&exec_ctx, whole_uri, NULL, |
||||||
|
args.pollset_set, args.lock); |
||||||
|
gpr_free(whole_uri); |
||||||
|
grpc_closure on_resolver_result_changed; |
||||||
|
GRPC_CLOSURE_INIT(&on_resolver_result_changed, CheckResolverResultLocked, |
||||||
|
(void *)&args, grpc_combiner_scheduler(args.lock)); |
||||||
|
grpc_resolver_next_locked(&exec_ctx, resolver, &args.channel_args, |
||||||
|
&on_resolver_result_changed); |
||||||
|
grpc_exec_ctx_flush(&exec_ctx); |
||||||
|
PollPollsetUntilRequestDone(&args); |
||||||
|
GRPC_RESOLVER_UNREF(&exec_ctx, resolver, NULL); |
||||||
|
ArgsFinish(&exec_ctx, &args); |
||||||
|
grpc_exec_ctx_finish(&exec_ctx); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int main(int argc, char **argv) { |
||||||
|
grpc_init(); |
||||||
|
grpc_test_init(argc, argv); |
||||||
|
::testing::InitGoogleTest(&argc, argv); |
||||||
|
ParseCommandLineFlags(&argc, &argv, true); |
||||||
|
if (FLAGS_target_name == "") { |
||||||
|
gpr_log(GPR_ERROR, "Missing target_name param."); |
||||||
|
abort(); |
||||||
|
} |
||||||
|
if (FLAGS_local_dns_server_address != "") { |
||||||
|
gpr_log(GPR_INFO, "Specifying authority in uris to: %s", |
||||||
|
FLAGS_local_dns_server_address.c_str()); |
||||||
|
} |
||||||
|
auto result = RUN_ALL_TESTS(); |
||||||
|
grpc_shutdown(); |
||||||
|
return result; |
||||||
|
} |
@ -0,0 +1,173 @@ |
|||||||
|
#!/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=' | cut -d "=" -f 2` |
||||||
|
FLAGS_dns_server_bin_path=`echo "$2" | grep '\--dns_server_bin_path=' | cut -d "=" -f 2` |
||||||
|
FLAGS_records_config_path=`echo "$3" | grep '\--records_config_path=' | cut -d "=" -f 2` |
||||||
|
FLAGS_test_dns_server_port=`echo "$4" | grep '\--test_dns_server_port=' | cut -d "=" -f 2` |
||||||
|
|
||||||
|
for cmd_arg in "$FLAGS_test_bin_path" "$FLAGS_dns_server_bin_path" "$FLAGS_records_config_path" "$FLAGS_test_dns_server_port"; 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 |
||||||
|
|
||||||
|
"$FLAGS_dns_server_bin_path" --records_config_path="$FLAGS_records_config_path" --port="$FLAGS_test_dns_server_port" 2>&1 > /dev/null & |
||||||
|
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 DNS query to local DNS server over tcp and udp" |
||||||
|
RETRY=0 |
||||||
|
dig A health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp. @localhost -p "$FLAGS_test_dns_server_port" +tries=1 +timeout=1 | grep '123.123.123.123' || RETRY=1 |
||||||
|
dig A health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp. @localhost -p "$FLAGS_test_dns_server_port" +tries=1 +timeout=1 +tcp | grep '123.123.123.123' || 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 |
||||||
|
wait |
||||||
|
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.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_test_dns_server_port & |
||||||
|
wait $! || EXIT_CODE=1 |
||||||
|
|
||||||
|
$FLAGS_test_bin_path \ |
||||||
|
--target_name='srv-ipv4-multi-target.resolver-tests.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_test_dns_server_port & |
||||||
|
wait $! || EXIT_CODE=1 |
||||||
|
|
||||||
|
$FLAGS_test_bin_path \ |
||||||
|
--target_name='srv-ipv6-single-target.resolver-tests.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_test_dns_server_port & |
||||||
|
wait $! || EXIT_CODE=1 |
||||||
|
|
||||||
|
$FLAGS_test_bin_path \ |
||||||
|
--target_name='srv-ipv6-multi-target.resolver-tests.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_test_dns_server_port & |
||||||
|
wait $! || EXIT_CODE=1 |
||||||
|
|
||||||
|
$FLAGS_test_bin_path \ |
||||||
|
--target_name='srv-ipv4-simple-service-config.resolver-tests.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_test_dns_server_port & |
||||||
|
wait $! || EXIT_CODE=1 |
||||||
|
|
||||||
|
$FLAGS_test_bin_path \ |
||||||
|
--target_name='ipv4-no-srv-simple-service-config.resolver-tests.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_test_dns_server_port & |
||||||
|
wait $! || EXIT_CODE=1 |
||||||
|
|
||||||
|
$FLAGS_test_bin_path \ |
||||||
|
--target_name='ipv4-no-config-for-cpp.resolver-tests.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_test_dns_server_port & |
||||||
|
wait $! || EXIT_CODE=1 |
||||||
|
|
||||||
|
$FLAGS_test_bin_path \ |
||||||
|
--target_name='ipv4-cpp-config-has-zero-percentage.resolver-tests.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_test_dns_server_port & |
||||||
|
wait $! || EXIT_CODE=1 |
||||||
|
|
||||||
|
$FLAGS_test_bin_path \ |
||||||
|
--target_name='ipv4-second-language-is-cpp.resolver-tests.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_test_dns_server_port & |
||||||
|
wait $! || EXIT_CODE=1 |
||||||
|
|
||||||
|
$FLAGS_test_bin_path \ |
||||||
|
--target_name='ipv4-config-with-percentages.resolver-tests.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_test_dns_server_port & |
||||||
|
wait $! || EXIT_CODE=1 |
||||||
|
|
||||||
|
$FLAGS_test_bin_path \ |
||||||
|
--target_name='srv-ipv4-target-has-backend-and-balancer.resolver-tests.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_test_dns_server_port & |
||||||
|
wait $! || EXIT_CODE=1 |
||||||
|
|
||||||
|
$FLAGS_test_bin_path \ |
||||||
|
--target_name='srv-ipv6-target-has-backend-and-balancer.resolver-tests.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_test_dns_server_port & |
||||||
|
wait $! || EXIT_CODE=1 |
||||||
|
|
||||||
|
kill -SIGTERM $DNS_SERVER_PID || true |
||||||
|
wait |
||||||
|
exit $EXIT_CODE |
@ -0,0 +1,189 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2017 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. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <grpc/grpc.h> |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/string_util.h> |
||||||
|
#include <signal.h> |
||||||
|
#include <string.h> |
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <gflags/gflags.h> |
||||||
|
#include <string> |
||||||
|
#include <thread> |
||||||
|
#include <vector> |
||||||
|
|
||||||
|
#include "test/cpp/util/subprocess.h" |
||||||
|
#include "test/cpp/util/test_config.h" |
||||||
|
|
||||||
|
extern "C" { |
||||||
|
#include "src/core/lib/support/env.h" |
||||||
|
#include "test/core/util/port.h" |
||||||
|
} |
||||||
|
|
||||||
|
DEFINE_bool( |
||||||
|
running_under_bazel, false, |
||||||
|
"True if this test is running under bazel. " |
||||||
|
"False indicates that this test is running under run_tests.py. " |
||||||
|
"Child process test binaries are located differently based on this flag. "); |
||||||
|
|
||||||
|
DEFINE_string(test_bin_name, "", |
||||||
|
"Name, without the preceding path, of the test binary"); |
||||||
|
|
||||||
|
DEFINE_string(grpc_test_directory_relative_to_test_srcdir, "/__main__", |
||||||
|
"This flag only applies if runner_under_bazel is true. This " |
||||||
|
"flag is ignored if runner_under_bazel is false. " |
||||||
|
"Directory of the <repo-root>/test directory relative to bazel's " |
||||||
|
"TEST_SRCDIR environment variable"); |
||||||
|
|
||||||
|
using grpc::SubProcess; |
||||||
|
|
||||||
|
static volatile sig_atomic_t abort_wait_for_child = 0; |
||||||
|
|
||||||
|
static void sighandler(int sig) { abort_wait_for_child = 1; } |
||||||
|
|
||||||
|
static void register_sighandler() { |
||||||
|
struct sigaction act; |
||||||
|
memset(&act, 0, sizeof(act)); |
||||||
|
act.sa_handler = sighandler; |
||||||
|
sigaction(SIGINT, &act, NULL); |
||||||
|
sigaction(SIGTERM, &act, NULL); |
||||||
|
} |
||||||
|
|
||||||
|
namespace { |
||||||
|
|
||||||
|
const int kTestTimeoutSeconds = 60 * 2; |
||||||
|
|
||||||
|
void RunSigHandlingThread(SubProcess *test_driver, gpr_mu *test_driver_mu, |
||||||
|
gpr_cv *test_driver_cv, int *test_driver_done) { |
||||||
|
gpr_timespec overall_deadline = |
||||||
|
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), |
||||||
|
gpr_time_from_seconds(kTestTimeoutSeconds, GPR_TIMESPAN)); |
||||||
|
while (true) { |
||||||
|
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); |
||||||
|
if (gpr_time_cmp(now, overall_deadline) > 0 || abort_wait_for_child) break; |
||||||
|
gpr_mu_lock(test_driver_mu); |
||||||
|
if (*test_driver_done) { |
||||||
|
gpr_mu_unlock(test_driver_mu); |
||||||
|
return; |
||||||
|
} |
||||||
|
gpr_timespec wait_deadline = gpr_time_add( |
||||||
|
gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(1, GPR_TIMESPAN)); |
||||||
|
gpr_cv_wait(test_driver_cv, test_driver_mu, wait_deadline); |
||||||
|
gpr_mu_unlock(test_driver_mu); |
||||||
|
} |
||||||
|
gpr_log(GPR_DEBUG, |
||||||
|
"Test timeout reached or received signal. Interrupting test driver " |
||||||
|
"child process."); |
||||||
|
test_driver->Interrupt(); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
|
||||||
|
namespace testing { |
||||||
|
|
||||||
|
void InvokeResolverComponentTestsRunner(std::string test_runner_bin_path, |
||||||
|
std::string test_bin_path, |
||||||
|
std::string dns_server_bin_path, |
||||||
|
std::string records_config_path) { |
||||||
|
int test_dns_server_port = grpc_pick_unused_port_or_die(); |
||||||
|
|
||||||
|
SubProcess *test_driver = new SubProcess( |
||||||
|
{test_runner_bin_path, "--test_bin_path=" + test_bin_path, |
||||||
|
"--dns_server_bin_path=" + dns_server_bin_path, |
||||||
|
"--records_config_path=" + records_config_path, |
||||||
|
"--test_dns_server_port=" + std::to_string(test_dns_server_port)}); |
||||||
|
gpr_mu test_driver_mu; |
||||||
|
gpr_mu_init(&test_driver_mu); |
||||||
|
gpr_cv test_driver_cv; |
||||||
|
gpr_cv_init(&test_driver_cv); |
||||||
|
int test_driver_done = 0; |
||||||
|
register_sighandler(); |
||||||
|
std::thread sig_handling_thread(RunSigHandlingThread, test_driver, |
||||||
|
&test_driver_mu, &test_driver_cv, |
||||||
|
&test_driver_done); |
||||||
|
int status = test_driver->Join(); |
||||||
|
if (WIFEXITED(status)) { |
||||||
|
if (WEXITSTATUS(status)) { |
||||||
|
gpr_log(GPR_INFO, |
||||||
|
"Resolver component test test-runner exited with code %d", |
||||||
|
WEXITSTATUS(status)); |
||||||
|
abort(); |
||||||
|
} |
||||||
|
} else if (WIFSIGNALED(status)) { |
||||||
|
gpr_log(GPR_INFO, |
||||||
|
"Resolver component test test-runner ended from signal %d", |
||||||
|
WTERMSIG(status)); |
||||||
|
abort(); |
||||||
|
} else { |
||||||
|
gpr_log(GPR_INFO, |
||||||
|
"Resolver component test test-runner ended with unknown status %d", |
||||||
|
status); |
||||||
|
abort(); |
||||||
|
} |
||||||
|
gpr_mu_lock(&test_driver_mu); |
||||||
|
test_driver_done = 1; |
||||||
|
gpr_cv_signal(&test_driver_cv); |
||||||
|
gpr_mu_unlock(&test_driver_mu); |
||||||
|
sig_handling_thread.join(); |
||||||
|
delete test_driver; |
||||||
|
gpr_mu_destroy(&test_driver_mu); |
||||||
|
gpr_cv_destroy(&test_driver_cv); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
int main(int argc, char **argv) { |
||||||
|
grpc::testing::InitTest(&argc, &argv, true); |
||||||
|
grpc_init(); |
||||||
|
GPR_ASSERT(FLAGS_test_bin_name != ""); |
||||||
|
std::string my_bin = argv[0]; |
||||||
|
if (FLAGS_running_under_bazel) { |
||||||
|
GPR_ASSERT(FLAGS_grpc_test_directory_relative_to_test_srcdir != ""); |
||||||
|
// Use bazel's TEST_SRCDIR environment variable to locate the "test data"
|
||||||
|
// binaries.
|
||||||
|
std::string const bin_dir = |
||||||
|
gpr_getenv("TEST_SRCDIR") + |
||||||
|
FLAGS_grpc_test_directory_relative_to_test_srcdir + |
||||||
|
std::string("/test/cpp/naming"); |
||||||
|
// Invoke bazel's executeable links to the .sh and .py scripts (don't use
|
||||||
|
// the .sh and .py suffixes) to make
|
||||||
|
// sure that we're using bazel's test environment.
|
||||||
|
grpc::testing::InvokeResolverComponentTestsRunner( |
||||||
|
bin_dir + "/resolver_component_tests_runner", |
||||||
|
bin_dir + "/" + FLAGS_test_bin_name, bin_dir + "/test_dns_server", |
||||||
|
bin_dir + "/resolver_test_record_groups.yaml"); |
||||||
|
} else { |
||||||
|
// Get the current binary's directory relative to repo root to invoke the
|
||||||
|
// correct build config (asan/tsan/dbg, etc.).
|
||||||
|
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.
|
||||||
|
grpc::testing::InvokeResolverComponentTestsRunner( |
||||||
|
"test/cpp/naming/resolver_component_tests_runner.sh", |
||||||
|
bin_dir + "/" + FLAGS_test_bin_name, |
||||||
|
"test/cpp/naming/test_dns_server.py", |
||||||
|
"test/cpp/naming/resolver_test_record_groups.yaml"); |
||||||
|
} |
||||||
|
grpc_shutdown(); |
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,155 @@ |
|||||||
|
resolver_component_tests_common_zone_name: resolver-tests.grpctestingexp. |
||||||
|
resolver_component_tests: |
||||||
|
- expected_addrs: |
||||||
|
- {address: '1.2.3.4:1234', is_balancer: true} |
||||||
|
expected_chosen_service_config: null |
||||||
|
expected_lb_policy: null |
||||||
|
record_to_resolve: srv-ipv4-single-target |
||||||
|
records: |
||||||
|
_grpclb._tcp.srv-ipv4-single-target: |
||||||
|
- {TTL: '2100', data: 0 0 1234 ipv4-single-target, type: SRV} |
||||||
|
ipv4-single-target: |
||||||
|
- {TTL: '2100', data: 1.2.3.4, type: A} |
||||||
|
- expected_addrs: |
||||||
|
- {address: '1.2.3.5:1234', is_balancer: true} |
||||||
|
- {address: '1.2.3.6:1234', is_balancer: true} |
||||||
|
- {address: '1.2.3.7:1234', is_balancer: true} |
||||||
|
expected_chosen_service_config: null |
||||||
|
expected_lb_policy: null |
||||||
|
record_to_resolve: srv-ipv4-multi-target |
||||||
|
records: |
||||||
|
_grpclb._tcp.srv-ipv4-multi-target: |
||||||
|
- {TTL: '2100', data: 0 0 1234 ipv4-multi-target, type: SRV} |
||||||
|
ipv4-multi-target: |
||||||
|
- {TTL: '2100', data: 1.2.3.5, type: A} |
||||||
|
- {TTL: '2100', data: 1.2.3.6, type: A} |
||||||
|
- {TTL: '2100', data: 1.2.3.7, type: A} |
||||||
|
- expected_addrs: |
||||||
|
- {address: '[2607:f8b0:400a:801::1001]:1234', is_balancer: true} |
||||||
|
expected_chosen_service_config: null |
||||||
|
expected_lb_policy: null |
||||||
|
record_to_resolve: srv-ipv6-single-target |
||||||
|
records: |
||||||
|
_grpclb._tcp.srv-ipv6-single-target: |
||||||
|
- {TTL: '2100', data: 0 0 1234 ipv6-single-target, type: SRV} |
||||||
|
ipv6-single-target: |
||||||
|
- {TTL: '2100', data: '2607:f8b0:400a:801::1001', type: AAAA} |
||||||
|
- expected_addrs: |
||||||
|
- {address: '[2607:f8b0:400a:801::1002]:1234', is_balancer: true} |
||||||
|
- {address: '[2607:f8b0:400a:801::1003]:1234', is_balancer: true} |
||||||
|
- {address: '[2607:f8b0:400a:801::1004]:1234', is_balancer: true} |
||||||
|
expected_chosen_service_config: null |
||||||
|
expected_lb_policy: null |
||||||
|
record_to_resolve: srv-ipv6-multi-target |
||||||
|
records: |
||||||
|
_grpclb._tcp.srv-ipv6-multi-target: |
||||||
|
- {TTL: '2100', data: 0 0 1234 ipv6-multi-target, type: SRV} |
||||||
|
ipv6-multi-target: |
||||||
|
- {TTL: '2100', data: '2607:f8b0:400a:801::1002', type: AAAA} |
||||||
|
- {TTL: '2100', data: '2607:f8b0:400a:801::1003', type: AAAA} |
||||||
|
- {TTL: '2100', data: '2607:f8b0:400a:801::1004', type: AAAA} |
||||||
|
- expected_addrs: |
||||||
|
- {address: '1.2.3.4:1234', is_balancer: true} |
||||||
|
expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}' |
||||||
|
expected_lb_policy: round_robin |
||||||
|
record_to_resolve: srv-ipv4-simple-service-config |
||||||
|
records: |
||||||
|
_grpclb._tcp.srv-ipv4-simple-service-config: |
||||||
|
- {TTL: '2100', data: 0 0 1234 ipv4-simple-service-config, type: SRV} |
||||||
|
ipv4-simple-service-config: |
||||||
|
- {TTL: '2100', data: 1.2.3.4, type: A} |
||||||
|
srv-ipv4-simple-service-config: |
||||||
|
- {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}}]', |
||||||
|
type: TXT} |
||||||
|
- expected_addrs: |
||||||
|
- {address: '1.2.3.4:443', is_balancer: false} |
||||||
|
expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}' |
||||||
|
expected_lb_policy: round_robin |
||||||
|
record_to_resolve: ipv4-no-srv-simple-service-config |
||||||
|
records: |
||||||
|
ipv4-no-srv-simple-service-config: |
||||||
|
- {TTL: '2100', data: 1.2.3.4, type: A} |
||||||
|
- {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}}]', |
||||||
|
type: TXT} |
||||||
|
- expected_addrs: |
||||||
|
- {address: '1.2.3.4:443', is_balancer: false} |
||||||
|
expected_chosen_service_config: null |
||||||
|
expected_lb_policy: null |
||||||
|
record_to_resolve: ipv4-no-config-for-cpp |
||||||
|
records: |
||||||
|
ipv4-no-config-for-cpp: |
||||||
|
- {TTL: '2100', data: 1.2.3.4, type: A} |
||||||
|
- {TTL: '2100', data: 'grpc_config=[{"clientLanguage":["python"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"PythonService","waitForReady":true}]}]}}]', |
||||||
|
type: TXT} |
||||||
|
- expected_addrs: |
||||||
|
- {address: '1.2.3.4:443', is_balancer: false} |
||||||
|
expected_chosen_service_config: null |
||||||
|
expected_lb_policy: null |
||||||
|
record_to_resolve: ipv4-cpp-config-has-zero-percentage |
||||||
|
records: |
||||||
|
ipv4-cpp-config-has-zero-percentage: |
||||||
|
- {TTL: '2100', data: 1.2.3.4, type: A} |
||||||
|
- {TTL: '2100', data: 'grpc_config=[{"percentage":0,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}}]', |
||||||
|
type: TXT} |
||||||
|
- expected_addrs: |
||||||
|
- {address: '1.2.3.4:443', is_balancer: false} |
||||||
|
expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}' |
||||||
|
expected_lb_policy: round_robin |
||||||
|
record_to_resolve: ipv4-second-language-is-cpp |
||||||
|
records: |
||||||
|
ipv4-second-language-is-cpp: |
||||||
|
- {TTL: '2100', data: 1.2.3.4, type: A} |
||||||
|
- {TTL: '2100', data: 'grpc_config=[{"clientLanguage":["go"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"GoService","waitForReady":true}]}]}},{"clientLanguage":["c++"],"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}}]', |
||||||
|
type: TXT} |
||||||
|
- expected_addrs: |
||||||
|
- {address: '1.2.3.4:443', is_balancer: false} |
||||||
|
expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}' |
||||||
|
expected_lb_policy: round_robin |
||||||
|
record_to_resolve: ipv4-config-with-percentages |
||||||
|
records: |
||||||
|
ipv4-config-with-percentages: |
||||||
|
- {TTL: '2100', data: 1.2.3.4, type: A} |
||||||
|
- {TTL: '2100', data: 'grpc_config=[{"percentage":0,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NeverPickedService","waitForReady":true}]}]}},{"percentage":100,"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}}]', |
||||||
|
type: TXT} |
||||||
|
- expected_addrs: |
||||||
|
- {address: '1.2.3.4:1234', is_balancer: true} |
||||||
|
- {address: '1.2.3.4:443', is_balancer: false} |
||||||
|
expected_chosen_service_config: null |
||||||
|
expected_lb_policy: null |
||||||
|
record_to_resolve: srv-ipv4-target-has-backend-and-balancer |
||||||
|
records: |
||||||
|
_grpclb._tcp.srv-ipv4-target-has-backend-and-balancer: |
||||||
|
- {TTL: '2100', data: 0 0 1234 balancer-for-ipv4-has-backend-and-balancer, type: SRV} |
||||||
|
balancer-for-ipv4-has-backend-and-balancer: |
||||||
|
- {TTL: '2100', data: 1.2.3.4, type: A} |
||||||
|
srv-ipv4-target-has-backend-and-balancer: |
||||||
|
- {TTL: '2100', data: 1.2.3.4, type: A} |
||||||
|
- expected_addrs: |
||||||
|
- {address: '[2607:f8b0:400a:801::1002]:1234', is_balancer: true} |
||||||
|
- {address: '[2607:f8b0:400a:801::1002]:443', is_balancer: false} |
||||||
|
expected_chosen_service_config: null |
||||||
|
expected_lb_policy: null |
||||||
|
record_to_resolve: srv-ipv6-target-has-backend-and-balancer |
||||||
|
records: |
||||||
|
_grpclb._tcp.srv-ipv6-target-has-backend-and-balancer: |
||||||
|
- {TTL: '2100', data: 0 0 1234 balancer-for-ipv6-has-backend-and-balancer, type: SRV} |
||||||
|
balancer-for-ipv6-has-backend-and-balancer: |
||||||
|
- {TTL: '2100', data: '2607:f8b0:400a:801::1002', type: AAAA} |
||||||
|
srv-ipv6-target-has-backend-and-balancer: |
||||||
|
- {TTL: '2100', data: '2607:f8b0:400a:801::1002', type: AAAA} |
||||||
|
|
||||||
|
resolver_component_tests_TODO: |
||||||
|
- 'TODO: enable this large-txt-record test once working. (it is much longer than 512 |
||||||
|
bytes, likely to cause use of TCP even if max payload for UDP is changed somehow, |
||||||
|
e.g. via notes in RFC 2671)' |
||||||
|
- expected_addrs: |
||||||
|
- {address: '1.2.3.4:443', is_balancer: 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: null |
||||||
|
record_to_resolve: srv-ipv6-target-has-backend-and-balancer |
||||||
|
record_to_resolve: ipv4-config-causing-fallback-to-tcp |
||||||
|
records: |
||||||
|
ipv4-config-causing-fallback-to-tcp: |
||||||
|
- {TTL: '2100', data: 1.2.3.4, type: A} |
||||||
|
- {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"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}]}]}}]', |
||||||
|
type: TXT} |
@ -0,0 +1,134 @@ |
|||||||
|
#!/usr/bin/env python2.7 |
||||||
|
# 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. |
||||||
|
|
||||||
|
"""Starts a local DNS server for use in tests""" |
||||||
|
|
||||||
|
import argparse |
||||||
|
import sys |
||||||
|
import yaml |
||||||
|
import signal |
||||||
|
import os |
||||||
|
|
||||||
|
import twisted |
||||||
|
import twisted.internet |
||||||
|
import twisted.internet.reactor |
||||||
|
import twisted.internet.threads |
||||||
|
import twisted.internet.defer |
||||||
|
import twisted.internet.protocol |
||||||
|
import twisted.names |
||||||
|
import twisted.names.client |
||||||
|
import twisted.names.dns |
||||||
|
import twisted.names.server |
||||||
|
from twisted.names import client, server, common, authority, dns |
||||||
|
import argparse |
||||||
|
|
||||||
|
_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' |
||||||
|
|
||||||
|
class NoFileAuthority(authority.FileAuthority): |
||||||
|
def __init__(self, soa, records): |
||||||
|
# skip FileAuthority |
||||||
|
common.ResolverBase.__init__(self) |
||||||
|
self.soa = soa |
||||||
|
self.records = records |
||||||
|
|
||||||
|
def start_local_dns_server(args): |
||||||
|
all_records = {} |
||||||
|
def _push_record(name, r): |
||||||
|
print('pushing record: |%s|' % name) |
||||||
|
if all_records.get(name) is not None: |
||||||
|
all_records[name].append(r) |
||||||
|
return |
||||||
|
all_records[name] = [r] |
||||||
|
|
||||||
|
def _maybe_split_up_txt_data(name, txt_data, r_ttl): |
||||||
|
start = 0 |
||||||
|
txt_data_list = [] |
||||||
|
while len(txt_data[start:]) > 0: |
||||||
|
next_read = len(txt_data[start:]) |
||||||
|
if next_read > 255: |
||||||
|
next_read = 255 |
||||||
|
txt_data_list.append(txt_data[start:start+next_read]) |
||||||
|
start += next_read |
||||||
|
_push_record(name, dns.Record_TXT(*txt_data_list, ttl=r_ttl)) |
||||||
|
|
||||||
|
with open(args.records_config_path) as config: |
||||||
|
test_records_config = yaml.load(config) |
||||||
|
common_zone_name = test_records_config['resolver_component_tests_common_zone_name'] |
||||||
|
for group in test_records_config['resolver_component_tests']: |
||||||
|
for name in group['records'].keys(): |
||||||
|
for record in group['records'][name]: |
||||||
|
r_type = record['type'] |
||||||
|
r_data = record['data'] |
||||||
|
r_ttl = int(record['TTL']) |
||||||
|
record_full_name = '%s.%s' % (name, common_zone_name) |
||||||
|
assert record_full_name[-1] == '.' |
||||||
|
record_full_name = record_full_name[:-1] |
||||||
|
if r_type == 'A': |
||||||
|
_push_record(record_full_name, dns.Record_A(r_data, ttl=r_ttl)) |
||||||
|
if r_type == 'AAAA': |
||||||
|
_push_record(record_full_name, dns.Record_AAAA(r_data, ttl=r_ttl)) |
||||||
|
if r_type == 'SRV': |
||||||
|
p, w, port, target = r_data.split(' ') |
||||||
|
p = int(p) |
||||||
|
w = int(w) |
||||||
|
port = int(port) |
||||||
|
target_full_name = '%s.%s' % (target, common_zone_name) |
||||||
|
r_data = '%s %s %s %s' % (p, w, port, target_full_name) |
||||||
|
_push_record(record_full_name, dns.Record_SRV(p, w, port, target_full_name, ttl=r_ttl)) |
||||||
|
if r_type == 'TXT': |
||||||
|
_maybe_split_up_txt_data(record_full_name, r_data, r_ttl) |
||||||
|
# Server health check record |
||||||
|
_push_record(_SERVER_HEALTH_CHECK_RECORD_NAME, dns.Record_A(_SERVER_HEALTH_CHECK_RECORD_DATA, ttl=0)) |
||||||
|
soa_record = dns.Record_SOA(mname = common_zone_name) |
||||||
|
test_domain_com = NoFileAuthority( |
||||||
|
soa = (common_zone_name, soa_record), |
||||||
|
records = all_records, |
||||||
|
) |
||||||
|
server = twisted.names.server.DNSServerFactory( |
||||||
|
authorities=[test_domain_com], verbose=2) |
||||||
|
server.noisy = 2 |
||||||
|
twisted.internet.reactor.listenTCP(args.port, server) |
||||||
|
dns_proto = twisted.names.dns.DNSDatagramProtocol(server) |
||||||
|
dns_proto.noisy = 2 |
||||||
|
twisted.internet.reactor.listenUDP(args.port, dns_proto) |
||||||
|
print('starting local dns server on 127.0.0.1:%s' % args.port) |
||||||
|
print('starting twisted.internet.reactor') |
||||||
|
twisted.internet.reactor.suggestThreadPoolSize(1) |
||||||
|
twisted.internet.reactor.run() |
||||||
|
|
||||||
|
def _quit_on_signal(signum, _frame): |
||||||
|
print('Received SIGNAL %d. Quitting with exit code 0' % signum) |
||||||
|
twisted.internet.reactor.stop() |
||||||
|
sys.stdout.flush() |
||||||
|
sys.exit(0) |
||||||
|
|
||||||
|
def main(): |
||||||
|
argp = argparse.ArgumentParser(description='Local DNS Server for resolver tests') |
||||||
|
argp.add_argument('-p', '--port', default=None, type=int, |
||||||
|
help='Port for DNS server to listen on for TCP and UDP.') |
||||||
|
argp.add_argument('-r', '--records_config_path', default=None, type=str, |
||||||
|
help=('Directory of resolver_test_record_groups.yaml file. ' |
||||||
|
'Defauls to path needed when the test is invoked as part of run_tests.py.')) |
||||||
|
args = argp.parse_args() |
||||||
|
signal.signal(signal.SIGALRM, _quit_on_signal) |
||||||
|
signal.signal(signal.SIGTERM, _quit_on_signal) |
||||||
|
signal.signal(signal.SIGINT, _quit_on_signal) |
||||||
|
# Prevent zombies. Tests that use this server are short-lived. |
||||||
|
signal.alarm(2 * 60) |
||||||
|
start_local_dns_server(args) |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
main() |
@ -0,0 +1,38 @@ |
|||||||
|
#!/usr/bin/env bash |
||||||
|
# Copyright 2017 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 script is invoked by Jenkins and runs a diff on the microbenchmarks |
||||||
|
set -ex |
||||||
|
|
||||||
|
# List of benchmarks that provide good signal for analyzing performance changes in pull requests |
||||||
|
BENCHMARKS_TO_RUN="bm_fullstack_unary_ping_pong bm_fullstack_streaming_ping_pong bm_fullstack_streaming_pump bm_closure bm_cq bm_call_create bm_error bm_chttp2_hpack bm_chttp2_transport bm_pollset bm_metadata" |
||||||
|
|
||||||
|
# Enter the gRPC repo root |
||||||
|
cd $(dirname $0)/../../.. |
||||||
|
|
||||||
|
source tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc |
||||||
|
|
||||||
|
tools/run_tests/start_port_server.py |
||||||
|
tools/jenkins/run_c_cpp_test.sh tools/profiling/microbenchmarks/bm_diff/bm_main.py \ |
||||||
|
-d origin/$ghprbTargetBranch \ |
||||||
|
-b $BENCHMARKS_TO_RUN || FAILED="true" |
||||||
|
|
||||||
|
# kill port_server.py to prevent the build from hanging |
||||||
|
ps aux | grep port_server\\.py | awk '{print $2}' | xargs kill -9 |
||||||
|
|
||||||
|
if [ "$FAILED" != "" ] |
||||||
|
then |
||||||
|
exit 1 |
||||||
|
fi |
@ -0,0 +1,42 @@ |
|||||||
|
#!/usr/bin/env bash |
||||||
|
# Copyright 2017 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 script is invoked by Jenkins and runs a diff on the microbenchmarks |
||||||
|
set -ex |
||||||
|
|
||||||
|
# List of benchmarks that provide good signal for analyzing performance changes in pull requests |
||||||
|
BENCHMARKS_TO_RUN="cli_transport_stalls_per_iteration cli_stream_stalls_per_iteration svr_transport_stalls_per_iteration svr_stream_stalls_per_iteration" |
||||||
|
|
||||||
|
# Enter the gRPC repo root |
||||||
|
cd $(dirname $0)/../../.. |
||||||
|
|
||||||
|
source tools/internal_ci/helper_scripts/prepare_build_linux_perf_rc |
||||||
|
|
||||||
|
tools/run_tests/start_port_server.py |
||||||
|
tools/jenkins/run_c_cpp_test.sh tools/profiling/microbenchmarks/bm_diff/bm_main.py \ |
||||||
|
-d origin/$ghprbTargetBranch \ |
||||||
|
-b bm_fullstack_trickle \ |
||||||
|
-l 4 \ |
||||||
|
-t $BENCHMARKS_TO_RUN \ |
||||||
|
--no-counters \ |
||||||
|
--pr_comment_name trickle || FAILED="true" |
||||||
|
|
||||||
|
# kill port_server.py to prevent the build from hanging |
||||||
|
ps aux | grep port_server\\.py | awk '{print $2}' | xargs kill -9 |
||||||
|
|
||||||
|
if [ "$FAILED" != "" ] |
||||||
|
then |
||||||
|
exit 1 |
||||||
|
fi |
Loading…
Reference in new issue