|
|
@ -29,6 +29,9 @@ import time |
|
|
|
|
|
|
|
|
|
|
|
from oauth2client.client import GoogleCredentials |
|
|
|
from oauth2client.client import GoogleCredentials |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import python_utils.jobset as jobset |
|
|
|
|
|
|
|
import python_utils.report_utils as report_utils |
|
|
|
|
|
|
|
|
|
|
|
from src.proto.grpc.testing import messages_pb2 |
|
|
|
from src.proto.grpc.testing import messages_pb2 |
|
|
|
from src.proto.grpc.testing import test_pb2_grpc |
|
|
|
from src.proto.grpc.testing import test_pb2_grpc |
|
|
|
|
|
|
|
|
|
|
@ -38,6 +41,26 @@ formatter = logging.Formatter(fmt='%(asctime)s: %(levelname)-8s %(message)s') |
|
|
|
console_handler.setFormatter(formatter) |
|
|
|
console_handler.setFormatter(formatter) |
|
|
|
logger.addHandler(console_handler) |
|
|
|
logger.addHandler(console_handler) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_TEST_CASES = [ |
|
|
|
|
|
|
|
'backends_restart', |
|
|
|
|
|
|
|
'change_backend_service', |
|
|
|
|
|
|
|
'new_instance_group_receives_traffic', |
|
|
|
|
|
|
|
'ping_pong', |
|
|
|
|
|
|
|
'remove_instance_group', |
|
|
|
|
|
|
|
'round_robin', |
|
|
|
|
|
|
|
'secondary_locality_gets_no_requests_on_partial_primary_failure', |
|
|
|
|
|
|
|
'secondary_locality_gets_requests_on_primary_failure', |
|
|
|
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_test_cases(arg): |
|
|
|
|
|
|
|
if arg == 'all': |
|
|
|
|
|
|
|
return _TEST_CASES |
|
|
|
|
|
|
|
test_cases = arg.split(',') |
|
|
|
|
|
|
|
if all([test_case in _TEST_CASES for test_case in test_cases]): |
|
|
|
|
|
|
|
return test_cases |
|
|
|
|
|
|
|
raise Exception('Failed to parse test cases %s' % arg) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_port_range(port_arg): |
|
|
|
def parse_port_range(port_arg): |
|
|
|
try: |
|
|
|
try: |
|
|
@ -58,17 +81,9 @@ argp.add_argument( |
|
|
|
argp.add_argument( |
|
|
|
argp.add_argument( |
|
|
|
'--test_case', |
|
|
|
'--test_case', |
|
|
|
default='ping_pong', |
|
|
|
default='ping_pong', |
|
|
|
choices=[ |
|
|
|
type=parse_test_cases, |
|
|
|
'all', |
|
|
|
help='Comma-separated list of test cases to run, or \'all\' to run every ' |
|
|
|
'backends_restart', |
|
|
|
'test. Available tests: %s' % ' '.join(_TEST_CASES)) |
|
|
|
'change_backend_service', |
|
|
|
|
|
|
|
'new_instance_group_receives_traffic', |
|
|
|
|
|
|
|
'ping_pong', |
|
|
|
|
|
|
|
'remove_instance_group', |
|
|
|
|
|
|
|
'round_robin', |
|
|
|
|
|
|
|
'secondary_locality_gets_no_requests_on_partial_primary_failure', |
|
|
|
|
|
|
|
'secondary_locality_gets_requests_on_primary_failure', |
|
|
|
|
|
|
|
]) |
|
|
|
|
|
|
|
argp.add_argument( |
|
|
|
argp.add_argument( |
|
|
|
'--client_cmd', |
|
|
|
'--client_cmd', |
|
|
|
default=None, |
|
|
|
default=None, |
|
|
@ -183,6 +198,9 @@ _BASE_URL_MAP_NAME = 'test-map' |
|
|
|
_BASE_SERVICE_HOST = 'grpc-test' |
|
|
|
_BASE_SERVICE_HOST = 'grpc-test' |
|
|
|
_BASE_TARGET_PROXY_NAME = 'test-target-proxy' |
|
|
|
_BASE_TARGET_PROXY_NAME = 'test-target-proxy' |
|
|
|
_BASE_FORWARDING_RULE_NAME = 'test-forwarding-rule' |
|
|
|
_BASE_FORWARDING_RULE_NAME = 'test-forwarding-rule' |
|
|
|
|
|
|
|
_TEST_LOG_BASE_DIR = 'reports' |
|
|
|
|
|
|
|
_SPONGE_LOG_NAME = 'sponge_log.log' |
|
|
|
|
|
|
|
_SPONGE_XML_NAME = 'sponge_log.xml' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_client_stats(num_rpcs, timeout_sec): |
|
|
|
def get_client_stats(num_rpcs, timeout_sec): |
|
|
@ -905,8 +923,6 @@ if args.compute_discovery_document: |
|
|
|
else: |
|
|
|
else: |
|
|
|
compute = googleapiclient.discovery.build('compute', 'v1') |
|
|
|
compute = googleapiclient.discovery.build('compute', 'v1') |
|
|
|
|
|
|
|
|
|
|
|
client_process = None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
try: |
|
|
|
gcp = GcpState(compute, args.project_id) |
|
|
|
gcp = GcpState(compute, args.project_id) |
|
|
|
health_check_name = _BASE_HEALTH_CHECK_NAME + args.gcp_suffix |
|
|
|
health_check_name = _BASE_HEALTH_CHECK_NAME + args.gcp_suffix |
|
|
@ -1034,56 +1050,75 @@ try: |
|
|
|
server_uri = service_host_name |
|
|
|
server_uri = service_host_name |
|
|
|
else: |
|
|
|
else: |
|
|
|
server_uri = service_host_name + ':' + str(gcp.service_port) |
|
|
|
server_uri = service_host_name + ':' + str(gcp.service_port) |
|
|
|
cmd = args.client_cmd.format(server_uri=server_uri, |
|
|
|
with tempfile.NamedTemporaryFile(delete=False) as bootstrap_file: |
|
|
|
stats_port=args.stats_port, |
|
|
|
bootstrap_file.write( |
|
|
|
qps=args.qps) |
|
|
|
_BOOTSTRAP_TEMPLATE.format( |
|
|
|
client_process = start_xds_client(cmd) |
|
|
|
node_id=socket.gethostname()).encode('utf-8')) |
|
|
|
|
|
|
|
bootstrap_path = bootstrap_file.name |
|
|
|
if args.test_case == 'all': |
|
|
|
client_env = dict(os.environ, GRPC_XDS_BOOTSTRAP=bootstrap_path) |
|
|
|
test_backends_restart(gcp, backend_service, instance_group) |
|
|
|
client_cmd = shlex.split( |
|
|
|
test_change_backend_service(gcp, backend_service, instance_group, |
|
|
|
args.client_cmd.format(server_uri=server_uri, |
|
|
|
alternate_backend_service, |
|
|
|
stats_port=args.stats_port, |
|
|
|
same_zone_instance_group) |
|
|
|
qps=args.qps)) |
|
|
|
test_new_instance_group_receives_traffic(gcp, backend_service, |
|
|
|
|
|
|
|
instance_group, |
|
|
|
test_results = {} |
|
|
|
same_zone_instance_group) |
|
|
|
for test_case in args.test_case: |
|
|
|
test_ping_pong(gcp, backend_service, instance_group) |
|
|
|
result = jobset.JobResult() |
|
|
|
test_remove_instance_group(gcp, backend_service, instance_group, |
|
|
|
log_dir = os.path.join(_TEST_LOG_BASE_DIR, test_case) |
|
|
|
same_zone_instance_group) |
|
|
|
if not os.path.exists(log_dir): |
|
|
|
test_round_robin(gcp, backend_service, instance_group) |
|
|
|
os.makedirs(log_dir) |
|
|
|
test_secondary_locality_gets_no_requests_on_partial_primary_failure( |
|
|
|
test_log_file = open(os.path.join(log_dir, _SPONGE_LOG_NAME), 'w+') |
|
|
|
gcp, backend_service, instance_group, secondary_zone_instance_group) |
|
|
|
try: |
|
|
|
test_secondary_locality_gets_requests_on_primary_failure( |
|
|
|
client_process = subprocess.Popen(client_cmd, |
|
|
|
gcp, backend_service, instance_group, secondary_zone_instance_group) |
|
|
|
env=client_env, |
|
|
|
elif args.test_case == 'backends_restart': |
|
|
|
stderr=subprocess.STDOUT, |
|
|
|
test_backends_restart(gcp, backend_service, instance_group) |
|
|
|
stdout=test_log_file) |
|
|
|
elif args.test_case == 'change_backend_service': |
|
|
|
if test_case == 'backends_restart': |
|
|
|
test_change_backend_service(gcp, backend_service, instance_group, |
|
|
|
test_backends_restart(gcp, backend_service, instance_group) |
|
|
|
alternate_backend_service, |
|
|
|
elif test_case == 'change_backend_service': |
|
|
|
same_zone_instance_group) |
|
|
|
test_change_backend_service(gcp, backend_service, |
|
|
|
elif args.test_case == 'new_instance_group_receives_traffic': |
|
|
|
instance_group, |
|
|
|
test_new_instance_group_receives_traffic(gcp, backend_service, |
|
|
|
alternate_backend_service, |
|
|
|
instance_group, |
|
|
|
same_zone_instance_group) |
|
|
|
same_zone_instance_group) |
|
|
|
elif test_case == 'new_instance_group_receives_traffic': |
|
|
|
elif args.test_case == 'ping_pong': |
|
|
|
test_new_instance_group_receives_traffic( |
|
|
|
test_ping_pong(gcp, backend_service, instance_group) |
|
|
|
gcp, backend_service, instance_group, |
|
|
|
elif args.test_case == 'remove_instance_group': |
|
|
|
same_zone_instance_group) |
|
|
|
test_remove_instance_group(gcp, backend_service, instance_group, |
|
|
|
elif test_case == 'ping_pong': |
|
|
|
same_zone_instance_group) |
|
|
|
test_ping_pong(gcp, backend_service, instance_group) |
|
|
|
elif args.test_case == 'round_robin': |
|
|
|
elif test_case == 'remove_instance_group': |
|
|
|
test_round_robin(gcp, backend_service, instance_group) |
|
|
|
test_remove_instance_group(gcp, backend_service, instance_group, |
|
|
|
elif args.test_case == 'secondary_locality_gets_no_requests_on_partial_primary_failure': |
|
|
|
same_zone_instance_group) |
|
|
|
test_secondary_locality_gets_no_requests_on_partial_primary_failure( |
|
|
|
elif test_case == 'round_robin': |
|
|
|
gcp, backend_service, instance_group, secondary_zone_instance_group) |
|
|
|
test_round_robin(gcp, backend_service, instance_group) |
|
|
|
elif args.test_case == 'secondary_locality_gets_requests_on_primary_failure': |
|
|
|
elif test_case == 'secondary_locality_gets_no_requests_on_partial_primary_failure': |
|
|
|
test_secondary_locality_gets_requests_on_primary_failure( |
|
|
|
test_secondary_locality_gets_no_requests_on_partial_primary_failure( |
|
|
|
gcp, backend_service, instance_group, secondary_zone_instance_group) |
|
|
|
gcp, backend_service, instance_group, |
|
|
|
else: |
|
|
|
secondary_zone_instance_group) |
|
|
|
logger.error('Unknown test case: %s', args.test_case) |
|
|
|
elif test_case == 'secondary_locality_gets_requests_on_primary_failure': |
|
|
|
sys.exit(1) |
|
|
|
test_secondary_locality_gets_requests_on_primary_failure( |
|
|
|
|
|
|
|
gcp, backend_service, instance_group, |
|
|
|
|
|
|
|
secondary_zone_instance_group) |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
logger.error('Unknown test case: %s', test_case) |
|
|
|
|
|
|
|
sys.exit(1) |
|
|
|
|
|
|
|
result.state = 'PASSED' |
|
|
|
|
|
|
|
result.returncode = 0 |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
|
|
|
|
result.state = 'FAILED' |
|
|
|
|
|
|
|
result.message = str(e).encode('UTF-8') |
|
|
|
|
|
|
|
finally: |
|
|
|
|
|
|
|
if client_process: |
|
|
|
|
|
|
|
client_process.terminate() |
|
|
|
|
|
|
|
test_results[test_case] = [result] |
|
|
|
|
|
|
|
if not os.path.exists(_TEST_LOG_BASE_DIR): |
|
|
|
|
|
|
|
os.makedirs(_TEST_LOG_BASE_DIR) |
|
|
|
|
|
|
|
report_utils.render_junit_xml_report(test_results, |
|
|
|
|
|
|
|
os.path.join(_TEST_LOG_BASE_DIR, |
|
|
|
|
|
|
|
_SPONGE_XML_NAME), |
|
|
|
|
|
|
|
suite_name='xds_tests', |
|
|
|
|
|
|
|
multi_target=True) |
|
|
|
finally: |
|
|
|
finally: |
|
|
|
if client_process: |
|
|
|
|
|
|
|
client_process.terminate() |
|
|
|
|
|
|
|
if not args.keep_gcp_resources: |
|
|
|
if not args.keep_gcp_resources: |
|
|
|
logger.info('Cleaning up GCP resources. This may take some time.') |
|
|
|
logger.info('Cleaning up GCP resources. This may take some time.') |
|
|
|
clean_up(gcp) |
|
|
|
clean_up(gcp) |
|
|
|