#!/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.

"""Run interop (cross-language) tests in parallel."""

from __future__ import print_function

import argparse
import atexit
import itertools
import json
import multiprocessing
import os
import re
import subprocess
import sys
import tempfile
import time
import uuid
import six
import traceback

import python_utils.dockerjob as dockerjob
import python_utils.jobset as jobset
import python_utils.report_utils as report_utils
# It's ok to not import because this is only necessary to upload results to BQ.
try:
  from python_utils.upload_test_results import upload_interop_results_to_bq
except ImportError as e:
  print(e)

# Docker doesn't clean up after itself, so we do it on exit.
atexit.register(lambda: subprocess.call(['stty', 'echo']))

ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
os.chdir(ROOT)

_DEFAULT_SERVER_PORT=8080

_SKIP_CLIENT_COMPRESSION = ['client_compressed_unary',
                            'client_compressed_streaming']

_SKIP_SERVER_COMPRESSION = ['server_compressed_unary',
                            'server_compressed_streaming']

_SKIP_COMPRESSION = _SKIP_CLIENT_COMPRESSION + _SKIP_SERVER_COMPRESSION

_SKIP_ADVANCED = ['status_code_and_message',
                  'custom_metadata',
                  'unimplemented_method',
                  'unimplemented_service']

_TEST_TIMEOUT = 3*60

# disable this test on core-based languages,
# see https://github.com/grpc/grpc/issues/9779
_SKIP_DATA_FRAME_PADDING = ['data_frame_padding']

# report suffix is important for reports to get picked up by internal CI
_INTERNAL_CL_XML_REPORT = 'sponge_log.xml'

# report suffix is important for reports to get picked up by internal CI
_XML_REPORT = 'report.xml'


class CXXLanguage:

  def __init__(self):
    self.client_cwd = None
    self.server_cwd = None
    self.http2_cwd = None
    self.safename = 'cxx'

  def client_cmd(self, args):
    return ['bins/opt/interop_client'] + args

  def client_cmd_http2interop(self, args):
    return ['bins/opt/http2_client'] + args

  def cloud_to_prod_env(self):
    return {}

  def server_cmd(self, args):
    return ['bins/opt/interop_server'] + args

  def global_env(self):
    return {}

  def unimplemented_test_cases(self):
    return _SKIP_DATA_FRAME_PADDING

  def unimplemented_test_cases_server(self):
    return []

  def __str__(self):
    return 'c++'


class CSharpLanguage:

  def __init__(self):
    self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/net45'
    self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/net45'
    self.safename = str(self)

  def client_cmd(self, args):
    return ['mono', 'Grpc.IntegrationTesting.Client.exe'] + args

  def cloud_to_prod_env(self):
    return {}

  def server_cmd(self, args):
    return ['mono', 'Grpc.IntegrationTesting.Server.exe'] + args

  def global_env(self):
    return {}

  def unimplemented_test_cases(self):
    return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING

  def unimplemented_test_cases_server(self):
    return _SKIP_COMPRESSION

  def __str__(self):
    return 'csharp'


class CSharpCoreCLRLanguage:

  def __init__(self):
    self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0'
    self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/netcoreapp1.0'
    self.safename = str(self)

  def client_cmd(self, args):
    return ['dotnet', 'exec', 'Grpc.IntegrationTesting.Client.dll'] + args

  def cloud_to_prod_env(self):
    return {}

  def server_cmd(self, args):
    return ['dotnet', 'exec', 'Grpc.IntegrationTesting.Server.dll'] + args

  def global_env(self):
    return {}

  def unimplemented_test_cases(self):
    return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING

  def unimplemented_test_cases_server(self):
    return _SKIP_COMPRESSION

  def __str__(self):
    return 'csharpcoreclr'


class JavaLanguage:

  def __init__(self):
    self.client_cwd = '../grpc-java'
    self.server_cwd = '../grpc-java'
    self.http2_cwd = '../grpc-java'
    self.safename = str(self)

  def client_cmd(self, args):
    return ['./run-test-client.sh'] + args

  def client_cmd_http2interop(self, args):
    return ['./interop-testing/build/install/grpc-interop-testing/bin/http2-client'] + args

  def cloud_to_prod_env(self):
    return {}

  def server_cmd(self, args):
    return ['./run-test-server.sh'] + args

  def global_env(self):
    return {}

  def unimplemented_test_cases(self):
    return []

  def unimplemented_test_cases_server(self):
    return _SKIP_COMPRESSION

  def __str__(self):
    return 'java'


class JavaOkHttpClient:

  def __init__(self):
    self.client_cwd = '../grpc-java'
    self.safename = 'java'

  def client_cmd(self, args):
    return ['./run-test-client.sh', '--use_okhttp=true'] + args

  def cloud_to_prod_env(self):
    return {}

  def global_env(self):
    return {}

  def unimplemented_test_cases(self):
    return _SKIP_DATA_FRAME_PADDING

  def __str__(self):
    return 'javaokhttp'


class GoLanguage:

  def __init__(self):
    # TODO: this relies on running inside docker
    self.client_cwd = '/go/src/google.golang.org/grpc/interop/client'
    self.server_cwd = '/go/src/google.golang.org/grpc/interop/server'
    self.http2_cwd = '/go/src/google.golang.org/grpc/interop/http2'
    self.safename = str(self)

  def client_cmd(self, args):
    return ['go', 'run', 'client.go'] + args

  def client_cmd_http2interop(self, args):
    return ['go', 'run', 'negative_http2_client.go'] + args

  def cloud_to_prod_env(self):
    return {}

  def server_cmd(self, args):
    return ['go', 'run', 'server.go'] + args

  def global_env(self):
    return {}

  def unimplemented_test_cases(self):
    return _SKIP_COMPRESSION

  def unimplemented_test_cases_server(self):
    return _SKIP_COMPRESSION

  def __str__(self):
    return 'go'

class Http2Server:
  """Represents the HTTP/2 Interop Test server

  This pretends to be a language in order to be built and run, but really it
  isn't.
  """
  def __init__(self):
    self.server_cwd = None
    self.safename = str(self)

  def server_cmd(self, args):
    return ['python test/http2_test/http2_test_server.py']

  def cloud_to_prod_env(self):
    return {}

  def global_env(self):
    return {}

  def unimplemented_test_cases(self):
    return _TEST_CASES + _SKIP_DATA_FRAME_PADDING

  def unimplemented_test_cases_server(self):
    return _TEST_CASES

  def __str__(self):
    return 'http2'

class Http2Client:
  """Represents the HTTP/2 Interop Test

  This pretends to be a language in order to be built and run, but really it
  isn't.
  """
  def __init__(self):
    self.client_cwd = None
    self.safename = str(self)

  def client_cmd(self, args):
    return ['tools/http2_interop/http2_interop.test', '-test.v'] + args

  def cloud_to_prod_env(self):
    return {}

  def global_env(self):
    return {}

  def unimplemented_test_cases(self):
    return _TEST_CASES

  def unimplemented_test_cases_server(self):
    return _TEST_CASES

  def __str__(self):
    return 'http2'

class NodeLanguage:

  def __init__(self):
    self.client_cwd = '../grpc-node'
    self.server_cwd = '../grpc-node'
    self.safename = str(self)

  def client_cmd(self, args):
    return ['packages/grpc-native-core/deps/grpc/tools/run_tests/interop/with_nvm.sh',
            'node', '--require', './test/fixtures/native_native',
            'test/interop/interop_client.js'] + args

  def cloud_to_prod_env(self):
    return {}

  def server_cmd(self, args):
    return ['packages/grpc-native-core/deps/grpc/tools/run_tests/interop/with_nvm.sh',
            'node', '--require', './test/fixtures/native_native',
            'test/interop/interop_server.js'] + args

  def global_env(self):
    return {}

  def unimplemented_test_cases(self):
    return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING

  def unimplemented_test_cases_server(self):
    return _SKIP_COMPRESSION

  def __str__(self):
    return 'node'


class PHPLanguage:

  def __init__(self):
    self.client_cwd = None
    self.safename = str(self)

  def client_cmd(self, args):
    return ['src/php/bin/interop_client.sh'] + args

  def cloud_to_prod_env(self):
    return {}

  def global_env(self):
    return {}

  def unimplemented_test_cases(self):
    return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING

  def unimplemented_test_cases_server(self):
    return []

  def __str__(self):
    return 'php'


class PHP7Language:

  def __init__(self):
    self.client_cwd = None
    self.safename = str(self)

  def client_cmd(self, args):
    return ['src/php/bin/interop_client.sh'] + args

  def cloud_to_prod_env(self):
    return {}

  def global_env(self):
    return {}

  def unimplemented_test_cases(self):
    return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING

  def unimplemented_test_cases_server(self):
    return []

  def __str__(self):
    return 'php7'

class ObjcLanguage:

  def __init__(self):
    self.client_cwd = 'src/objective-c/tests'
    self.safename = str(self)

  def client_cmd(self, args):
    # from args, extract the server port and craft xcodebuild command out of it
    for arg in args:
      port = re.search('--server_port=(\d+)', arg)
      if port:
        portnum = port.group(1)
        cmdline = 'pod install && xcodebuild -workspace Tests.xcworkspace -scheme InteropTestsLocalSSL -destination name="iPhone 6" HOST_PORT_LOCALSSL=localhost:%s test'%portnum
        return [cmdline]

  def cloud_to_prod_env(self):
    return {}

  def global_env(self):
    return {}

  def unimplemented_test_cases(self):
    # ObjC test runs all cases with the same command. It ignores the testcase
    # cmdline argument. Here we return all but one test cases as unimplemented,
    # and depend upon ObjC test's behavior that it runs all cases even when
    # we tell it to run just one.
    return _TEST_CASES[1:] + _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING

  def unimplemented_test_cases_server(self):
    return _SKIP_COMPRESSION

  def __str__(self):
    return 'objc'

class RubyLanguage:

  def __init__(self):
    self.client_cwd = None
    self.server_cwd = None
    self.safename = str(self)

  def client_cmd(self, args):
    return ['tools/run_tests/interop/with_rvm.sh',
            'ruby', 'src/ruby/pb/test/client.rb'] + args

  def cloud_to_prod_env(self):
    return {}

  def server_cmd(self, args):
    return ['tools/run_tests/interop/with_rvm.sh',
            'ruby', 'src/ruby/pb/test/server.rb'] + args

  def global_env(self):
    return {}

  def unimplemented_test_cases(self):
    return _SKIP_SERVER_COMPRESSION + _SKIP_DATA_FRAME_PADDING

  def unimplemented_test_cases_server(self):
    return _SKIP_COMPRESSION

  def __str__(self):
    return 'ruby'

class PythonLanguage:

  def __init__(self):
    self.client_cwd = None
    self.server_cwd = None
    self.http2_cwd = None
    self.safename = str(self)

  def client_cmd(self, args):
    return [
        'py27/bin/python',
        'src/python/grpcio_tests/setup.py',
        'run_interop',
        '--client',
        '--args="{}"'.format(' '.join(args))
    ]

  def client_cmd_http2interop(self, args):
    return [ 'py27/bin/python',
              'src/python/grpcio_tests/tests/http2/negative_http2_client.py',
           ] + args

  def cloud_to_prod_env(self):
    return {}

  def server_cmd(self, args):
    return [
        'py27/bin/python',
        'src/python/grpcio_tests/setup.py',
        'run_interop',
        '--server',
        '--args="{}"'.format(' '.join(args))
    ]

  def global_env(self):
    return {'LD_LIBRARY_PATH': '{}/libs/opt'.format(DOCKER_WORKDIR_ROOT),
            'PYTHONPATH': '{}/src/python/gens'.format(DOCKER_WORKDIR_ROOT)}

  def unimplemented_test_cases(self):
    return _SKIP_COMPRESSION + _SKIP_DATA_FRAME_PADDING

  def unimplemented_test_cases_server(self):
    return _SKIP_COMPRESSION

  def __str__(self):
    return 'python'


_LANGUAGES = {
    'c++' : CXXLanguage(),
    'csharp' : CSharpLanguage(),
    'csharpcoreclr' : CSharpCoreCLRLanguage(),
    'go' : GoLanguage(),
    'java' : JavaLanguage(),
    'javaokhttp' : JavaOkHttpClient(),
    'node' : NodeLanguage(),
    'php' :  PHPLanguage(),
    'php7' :  PHP7Language(),
    'objc' : ObjcLanguage(),
    'ruby' : RubyLanguage(),
    'python' : PythonLanguage(),
}

# languages supported as cloud_to_cloud servers
_SERVERS = ['c++', 'node', 'csharp', 'csharpcoreclr', 'java', 'go', 'ruby', 'python']

_TEST_CASES = ['large_unary', 'empty_unary', 'ping_pong',
               'empty_stream', 'client_streaming', 'server_streaming',
               'cancel_after_begin', 'cancel_after_first_response',
               'timeout_on_sleeping_server', 'custom_metadata',
               'status_code_and_message', 'unimplemented_method',
               'client_compressed_unary', 'server_compressed_unary',
               'client_compressed_streaming', 'server_compressed_streaming',
               'unimplemented_service']

_AUTH_TEST_CASES = ['compute_engine_creds', 'jwt_token_creds',
                    'oauth2_auth_token', 'per_rpc_creds']

_HTTP2_TEST_CASES = ['tls', 'framing']

_HTTP2_SERVER_TEST_CASES = ['rst_after_header', 'rst_after_data', 'rst_during_data',
                               'goaway', 'ping', 'max_streams', 'data_frame_padding', 'no_df_padding_sanity_test']

_GRPC_CLIENT_TEST_CASES_FOR_HTTP2_SERVER_TEST_CASES = { 'data_frame_padding': 'large_unary', 'no_df_padding_sanity_test': 'large_unary' }

_HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS = _GRPC_CLIENT_TEST_CASES_FOR_HTTP2_SERVER_TEST_CASES.keys()

_LANGUAGES_WITH_HTTP2_CLIENTS_FOR_HTTP2_SERVER_TEST_CASES = ['java', 'go', 'python', 'c++']

DOCKER_WORKDIR_ROOT = '/var/local/git/grpc'

def docker_run_cmdline(cmdline, image, docker_args=[], cwd=None, environ=None):
  """Wraps given cmdline array to create 'docker run' cmdline from it."""
  docker_cmdline = ['docker', 'run', '-i', '--rm=true']

  # turn environ into -e docker args
  if environ:
    for k,v in environ.items():
      docker_cmdline += ['-e', '%s=%s' % (k,v)]

  # set working directory
  workdir = DOCKER_WORKDIR_ROOT
  if cwd:
    workdir = os.path.join(workdir, cwd)
  docker_cmdline += ['-w', workdir]

  docker_cmdline += docker_args + [image] + cmdline
  return docker_cmdline


def manual_cmdline(docker_cmdline, docker_image):
  """Returns docker cmdline adjusted for manual invocation."""
  print_cmdline = []
  for item in docker_cmdline:
    if item.startswith('--name='):
      continue
    if item == docker_image:
      item = "$docker_image"
    item = item.replace('"', '\\"')
    # add quotes when necessary
    if any(character.isspace() for character in item):
      item = "\"%s\"" % item
    print_cmdline.append(item)
  return ' '.join(print_cmdline)


def write_cmdlog_maybe(cmdlog, filename):
  """Returns docker cmdline adjusted for manual invocation."""
  if cmdlog:
    with open(filename, 'w') as logfile:
      logfile.write('#!/bin/bash\n')
      logfile.writelines("%s\n" % line for line in cmdlog)
    print('Command log written to file %s' % filename)


def bash_cmdline(cmdline):
  """Creates bash -c cmdline from args list."""
  # Use login shell:
  # * makes error messages clearer if executables are missing
  return ['bash', '-c', ' '.join(cmdline)]


def auth_options(language, test_case):
  """Returns (cmdline, env) tuple with cloud_to_prod_auth test options."""

  language = str(language)
  cmdargs = []
  env = {}

  # TODO(jtattermusch): this file path only works inside docker
  key_filepath = '/root/service_account/GrpcTesting-726eb1347f15.json'
  oauth_scope_arg = '--oauth_scope=https://www.googleapis.com/auth/xapi.zoo'
  key_file_arg = '--service_account_key_file=%s' % key_filepath
  default_account_arg = '--default_service_account=830293263384-compute@developer.gserviceaccount.com'

  if test_case in ['jwt_token_creds', 'per_rpc_creds', 'oauth2_auth_token']:
    if language in ['csharp', 'csharpcoreclr', 'node', 'php', 'php7', 'python', 'ruby']:
      env['GOOGLE_APPLICATION_CREDENTIALS'] = key_filepath
    else:
      cmdargs += [key_file_arg]

  if test_case in ['per_rpc_creds', 'oauth2_auth_token']:
    cmdargs += [oauth_scope_arg]

  if test_case == 'oauth2_auth_token' and language == 'c++':
    # C++ oauth2 test uses GCE creds and thus needs to know the default account
    cmdargs += [default_account_arg]

  if test_case == 'compute_engine_creds':
    cmdargs += [oauth_scope_arg, default_account_arg]

  return (cmdargs, env)


def _job_kill_handler(job):
  if job._spec.container_name:
    dockerjob.docker_kill(job._spec.container_name)
    # When the job times out and we decide to kill it,
    # we need to wait a before restarting the job
    # to prevent "container name already in use" error.
    # TODO(jtattermusch): figure out a cleaner way to to this.
    time.sleep(2)


def cloud_to_prod_jobspec(language, test_case, server_host_name,
                          server_host_detail, docker_image=None, auth=False,
                          manual_cmd_log=None):
  """Creates jobspec for cloud-to-prod interop test"""
  container_name = None
  cmdargs = [
      '--server_host=%s' % server_host_detail[0],
      '--server_host_override=%s' % server_host_detail[1],
      '--server_port=443',
      '--use_tls=true',
      '--test_case=%s' % test_case]
  environ = dict(language.cloud_to_prod_env(), **language.global_env())
  if auth:
    auth_cmdargs, auth_env = auth_options(language, test_case)
    cmdargs += auth_cmdargs
    environ.update(auth_env)
  cmdline = bash_cmdline(language.client_cmd(cmdargs))
  cwd = language.client_cwd

  if docker_image:
    container_name = dockerjob.random_name('interop_client_%s' %
                                           language.safename)
    cmdline = docker_run_cmdline(cmdline,
                                 image=docker_image,
                                 cwd=cwd,
                                 environ=environ,
                                 docker_args=['--net=host',
                                              '--name=%s' % container_name])
    if manual_cmd_log is not None:
      if manual_cmd_log == []:
        manual_cmd_log.append('echo "Testing ${docker_image:=%s}"' % docker_image)
      manual_cmd_log.append(manual_cmdline(cmdline, docker_image))
    cwd = None
    environ = None

  suite_name='cloud_to_prod_auth' if auth else 'cloud_to_prod'
  test_job = jobset.JobSpec(
          cmdline=cmdline,
          cwd=cwd,
          environ=environ,
          shortname='%s:%s:%s:%s' % (suite_name, language, server_host_name,
                                     test_case),
          timeout_seconds=_TEST_TIMEOUT,
          flake_retries=4 if args.allow_flakes else 0,
          timeout_retries=2 if args.allow_flakes else 0,
          kill_handler=_job_kill_handler)
  if docker_image:
    test_job.container_name = container_name
  return test_job


def cloud_to_cloud_jobspec(language, test_case, server_name, server_host,
                           server_port, docker_image=None, insecure=False,
                           manual_cmd_log=None):
  """Creates jobspec for cloud-to-cloud interop test"""
  interop_only_options = [
      '--server_host_override=foo.test.google.fr',
      '--use_tls=%s' % ('false' if insecure else 'true'),
      '--use_test_ca=true',
  ]

  client_test_case = test_case
  if test_case in _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS:
    client_test_case = _GRPC_CLIENT_TEST_CASES_FOR_HTTP2_SERVER_TEST_CASES[test_case]
  if client_test_case in language.unimplemented_test_cases():
    print('asking client %s to run unimplemented test case %s' % (repr(language), client_test_case))
    sys.exit(1)

  common_options = [
      '--test_case=%s' % client_test_case,
      '--server_host=%s' % server_host,
      '--server_port=%s' % server_port,
  ]

  if test_case in _HTTP2_SERVER_TEST_CASES:
    if test_case in _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS:
      client_options = interop_only_options + common_options
      cmdline = bash_cmdline(language.client_cmd(client_options))
      cwd = language.client_cwd
    else:
      cmdline = bash_cmdline(language.client_cmd_http2interop(common_options))
      cwd = language.http2_cwd
  else:
    cmdline = bash_cmdline(language.client_cmd(common_options+interop_only_options))
    cwd = language.client_cwd

  environ = language.global_env()
  if docker_image and language.safename != 'objc':
    # we can't run client in docker for objc.
    container_name = dockerjob.random_name('interop_client_%s' % language.safename)
    cmdline = docker_run_cmdline(cmdline,
                                 image=docker_image,
                                 environ=environ,
                                 cwd=cwd,
                                 docker_args=['--net=host',
                                              '--name=%s' % container_name])
    if manual_cmd_log is not None:
      if manual_cmd_log == []:
        manual_cmd_log.append('echo "Testing ${docker_image:=%s}"' % docker_image)
      manual_cmd_log.append(manual_cmdline(cmdline, docker_image))
    cwd = None

  test_job = jobset.JobSpec(
          cmdline=cmdline,
          cwd=cwd,
          environ=environ,
          shortname='cloud_to_cloud:%s:%s_server:%s' % (language, server_name,
                                                        test_case),
          timeout_seconds=_TEST_TIMEOUT,
          flake_retries=4 if args.allow_flakes else 0,
          timeout_retries=2 if args.allow_flakes else 0,
          kill_handler=_job_kill_handler)
  if docker_image:
    test_job.container_name = container_name
  return test_job


def server_jobspec(language, docker_image, insecure=False, manual_cmd_log=None):
  """Create jobspec for running a server"""
  container_name = dockerjob.random_name('interop_server_%s' % language.safename)
  cmdline = bash_cmdline(
      language.server_cmd(['--port=%s' % _DEFAULT_SERVER_PORT,
                           '--use_tls=%s' % ('false' if insecure else 'true')]))
  environ = language.global_env()
  docker_args = ['--name=%s' % container_name]
  if language.safename == 'http2':
    # we are running the http2 interop server. Open next N ports beginning
    # with the server port. These ports are used for http2 interop test
    # (one test case per port).
    docker_args += list(
        itertools.chain.from_iterable(('-p', str(_DEFAULT_SERVER_PORT + i))
                                      for i in range(
                                          len(_HTTP2_SERVER_TEST_CASES))))
    # Enable docker's healthcheck mechanism.
    # This runs a Python script inside the container every second. The script
    # pings the http2 server to verify it is ready. The 'health-retries' flag
    # specifies the number of consecutive failures before docker will report
    # the container's status as 'unhealthy'. Prior to the first 'health_retries'
    # failures or the first success, the status will be 'starting'. 'docker ps'
    # or 'docker inspect' can be used to see the health of the container on the
    # command line.
    docker_args += [
        '--health-cmd=python test/http2_test/http2_server_health_check.py '
        '--server_host=%s --server_port=%d'
        % ('localhost', _DEFAULT_SERVER_PORT),
        '--health-interval=1s',
        '--health-retries=5',
        '--health-timeout=10s',
    ]

  else:
    docker_args += ['-p', str(_DEFAULT_SERVER_PORT)]

  docker_cmdline = docker_run_cmdline(cmdline,
                                      image=docker_image,
                                      cwd=language.server_cwd,
                                      environ=environ,
                                      docker_args=docker_args)
  if manual_cmd_log is not None:
      if manual_cmd_log == []:
        manual_cmd_log.append('echo "Testing ${docker_image:=%s}"' % docker_image)
      manual_cmd_log.append(manual_cmdline(docker_cmdline, docker_image))
  server_job = jobset.JobSpec(
          cmdline=docker_cmdline,
          environ=environ,
          shortname='interop_server_%s' % language,
          timeout_seconds=30*60)
  server_job.container_name = container_name
  return server_job


def build_interop_image_jobspec(language, tag=None):
  """Creates jobspec for building interop docker image for a language"""
  if not tag:
    tag = 'grpc_interop_%s:%s' % (language.safename, uuid.uuid4())
  env = {'INTEROP_IMAGE': tag,
         'BASE_NAME': 'grpc_interop_%s' % language.safename}
  if not args.travis:
    env['TTY_FLAG'] = '-t'
  # This env variable is used to get around the github rate limit
  # error when running the PHP `composer install` command
  host_file = '%s/.composer/auth.json' % os.environ['HOME']
  if language.safename == 'php' and os.path.exists(host_file):
    env['BUILD_INTEROP_DOCKER_EXTRA_ARGS'] = \
      '-v %s:/root/.composer/auth.json:ro' % host_file
  build_job = jobset.JobSpec(
          cmdline=['tools/run_tests/dockerize/build_interop_image.sh'],
          environ=env,
          shortname='build_docker_%s' % (language),
          timeout_seconds=30*60)
  build_job.tag = tag
  return build_job


def aggregate_http2_results(stdout):
  match = re.search(r'\{"cases[^\]]*\]\}', stdout)
  if not match:
    return None

  results = json.loads(match.group(0))
  skipped = 0
  passed = 0
  failed = 0
  failed_cases = []
  for case in results['cases']:
    if case.get('skipped', False):
      skipped += 1
    else:
      if case.get('passed', False):
        passed += 1
      else:
        failed += 1
        failed_cases.append(case.get('name', "NONAME"))
  return {
    'passed': passed,
    'failed': failed,
    'skipped': skipped,
    'failed_cases': ', '.join(failed_cases),
    'percent': 1.0 * passed / (passed + failed)
  }

# A dictionary of prod servers to test.
# Format: server_name: (server_host, server_host_override, errors_allowed)
# TODO(adelez): implement logic for errors_allowed where if the indicated tests
# fail, they don't impact the overall test result.
prod_servers = {
    'default': ('216.239.32.254',
                'grpc-test.sandbox.googleapis.com', False),
    'gateway_v2': ('216.239.32.254',
                   'grpc-test2.sandbox.googleapis.com', True),
    'cloud_gateway': ('216.239.32.255', 'grpc-test.sandbox.googleapis.com',
                      False),
    'cloud_gateway_v2': ('216.239.32.255', 'grpc-test2.sandbox.googleapis.com',
                         True),
    'gateway_v4': ('216.239.32.254',
                   'grpc-test4.sandbox.googleapis.com', True),
    'cloud_gateway_v4': ('216.239.32.255', 'grpc-test4.sandbox.googleapis.com',
                         True),
}

argp = argparse.ArgumentParser(description='Run interop tests.')
argp.add_argument('-l', '--language',
                  choices=['all'] + sorted(_LANGUAGES),
                  nargs='+',
                  default=['all'],
                  help='Clients to run. Objc client can be only run on OSX.')
argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int)
argp.add_argument('--cloud_to_prod',
                  default=False,
                  action='store_const',
                  const=True,
                  help='Run cloud_to_prod tests.')
argp.add_argument('--cloud_to_prod_auth',
                  default=False,
                  action='store_const',
                  const=True,
                  help='Run cloud_to_prod_auth tests.')
argp.add_argument('--prod_servers',
                  choices=prod_servers.keys(),
                  default=['default'],
                  nargs='+',
                  help=('The servers to run cloud_to_prod and '
                        'cloud_to_prod_auth tests against.'))
argp.add_argument('-s', '--server',
                  choices=['all'] + sorted(_SERVERS),
                  nargs='+',
                  help='Run cloud_to_cloud servers in a separate docker ' +
                       'image. Servers can only be started automatically if ' +
                       '--use_docker option is enabled.',
                  default=[])
argp.add_argument('--override_server',
                  action='append',
                  type=lambda kv: kv.split('='),
                  help='Use servername=HOST:PORT to explicitly specify a server. E.g. csharp=localhost:50000',
                  default=[])
argp.add_argument('-t', '--travis',
                  default=False,
                  action='store_const',
                  const=True)
argp.add_argument('-v', '--verbose',
                  default=False,
                  action='store_const',
                  const=True)
argp.add_argument('--use_docker',
                  default=False,
                  action='store_const',
                  const=True,
                  help='Run all the interop tests under docker. That provides ' +
                  'additional isolation and prevents the need to install ' +
                  'language specific prerequisites. Only available on Linux.')
argp.add_argument('--allow_flakes',
                  default=False,
                  action='store_const',
                  const=True,
                  help='Allow flaky tests to show as passing (re-runs failed tests up to five times)')
argp.add_argument('--manual_run',
                  default=False,
                  action='store_const',
                  const=True,
                  help='Prepare things for running interop tests manually. ' +
                  'Preserve docker images after building them and skip '
                  'actually running the tests. Only print commands to run by ' +
                  'hand.')
argp.add_argument('--http2_interop',
                  default=False,
                  action='store_const',
                  const=True,
                  help='Enable HTTP/2 client edge case testing. (Bad client, good server)')
argp.add_argument('--http2_server_interop',
                  default=False,
                  action='store_const',
                  const=True,
                  help='Enable HTTP/2 server edge case testing. (Includes positive and negative tests')
argp.add_argument('--insecure',
                  default=False,
                  action='store_const',
                  const=True,
                  help='Whether to use secure channel.')
argp.add_argument('--internal_ci',
                  default=False,
                  action='store_const',
                  const=True,
                  help=('Put reports into subdirectories to improve '
                        'presentation of results by Internal CI.'))
argp.add_argument('--bq_result_table',
                  default='',
                  type=str,
                  nargs='?',
                  help='Upload test results to a specified BQ table.')
args = argp.parse_args()

servers = set(s for s in itertools.chain.from_iterable(_SERVERS
                                                       if x == 'all' else [x]
                                                       for x in args.server))

if args.use_docker:
  if not args.travis:
    print('Seen --use_docker flag, will run interop tests under docker.')
    print('')
    print('IMPORTANT: The changes you are testing need to be locally committed')
    print('because only the committed changes in the current branch will be')
    print('copied to the docker environment.')
    time.sleep(5)

if args.manual_run and not args.use_docker:
  print('--manual_run is only supported with --use_docker option enabled.')
  sys.exit(1)

if not args.use_docker and servers:
  print('Running interop servers is only supported with --use_docker option enabled.')
  sys.exit(1)


# we want to include everything but objc in 'all'
# because objc won't run on non-mac platforms
all_but_objc = set(six.iterkeys(_LANGUAGES)) - set(['objc'])
languages = set(_LANGUAGES[l]
                for l in itertools.chain.from_iterable(
                    all_but_objc if x == 'all' else [x]
                    for x in args.language))

languages_http2_clients_for_http2_server_interop = set()
if args.http2_server_interop:
  languages_http2_clients_for_http2_server_interop = set(
      _LANGUAGES[l] for l in _LANGUAGES_WITH_HTTP2_CLIENTS_FOR_HTTP2_SERVER_TEST_CASES
      if 'all' in args.language or l in args.language)

http2Interop = Http2Client() if args.http2_interop else None
http2InteropServer = Http2Server() if args.http2_server_interop else None

docker_images={}
if args.use_docker:
  # languages for which to build docker images
  languages_to_build = set(
      _LANGUAGES[k] for k in set([str(l) for l in languages] + [s for s in servers]))
  languages_to_build = languages_to_build | languages_http2_clients_for_http2_server_interop

  if args.http2_interop:
    languages_to_build.add(http2Interop)

  if args.http2_server_interop:
    languages_to_build.add(http2InteropServer)

  build_jobs = []
  for l in languages_to_build:
    if str(l) == 'objc':
      # we don't need to build a docker image for objc
      continue
    job = build_interop_image_jobspec(l)
    docker_images[str(l)] = job.tag
    build_jobs.append(job)

  if build_jobs:
    jobset.message('START', 'Building interop docker images.', do_newline=True)
    if args.verbose:
      print('Jobs to run: \n%s\n' % '\n'.join(str(j) for j in build_jobs))

    num_failures, _ = jobset.run(
        build_jobs, newline_on_success=True, maxjobs=args.jobs)
    if num_failures == 0:
      jobset.message('SUCCESS', 'All docker images built successfully.',
                     do_newline=True)
    else:
      jobset.message('FAILED', 'Failed to build interop docker images.',
                     do_newline=True)
      for image in six.itervalues(docker_images):
        dockerjob.remove_image(image, skip_nonexistent=True)
      sys.exit(1)

server_manual_cmd_log = [] if args.manual_run else None
client_manual_cmd_log = [] if args.manual_run else None

# Start interop servers.
server_jobs = {}
server_addresses = {}
try:
  for s in servers:
    lang = str(s)
    spec = server_jobspec(_LANGUAGES[lang], docker_images.get(lang),
                          args.insecure, manual_cmd_log=server_manual_cmd_log)
    if not args.manual_run:
      job = dockerjob.DockerJob(spec)
      server_jobs[lang] = job
      server_addresses[lang] = ('localhost', job.mapped_port(_DEFAULT_SERVER_PORT))
    else:
      # don't run the server, set server port to a placeholder value
      server_addresses[lang] = ('localhost', '${SERVER_PORT}')

  http2_server_job = None
  if args.http2_server_interop:
    # launch a HTTP2 server emulator that creates edge cases
    lang = str(http2InteropServer)
    spec = server_jobspec(http2InteropServer, docker_images.get(lang),
                          manual_cmd_log=server_manual_cmd_log)
    if not args.manual_run:
      http2_server_job = dockerjob.DockerJob(spec)
      server_jobs[lang] = http2_server_job
    else:
      # don't run the server, set server port to a placeholder value
      server_addresses[lang] = ('localhost', '${SERVER_PORT}')

  jobs = []
  if args.cloud_to_prod:
    if args.insecure:
      print('TLS is always enabled for cloud_to_prod scenarios.')
    for server_host_name in args.prod_servers:
      for language in languages:
        for test_case in _TEST_CASES:
          if not test_case in language.unimplemented_test_cases():
            if not test_case in _SKIP_ADVANCED + _SKIP_COMPRESSION:
              test_job = cloud_to_prod_jobspec(
                  language, test_case, server_host_name,
                  prod_servers[server_host_name],
                  docker_image=docker_images.get(str(language)),
                  manual_cmd_log=client_manual_cmd_log)
              jobs.append(test_job)

      if args.http2_interop:
        for test_case in _HTTP2_TEST_CASES:
          test_job = cloud_to_prod_jobspec(
              http2Interop, test_case, server_host_name,
              prod_servers[server_host_name],
              docker_image=docker_images.get(str(http2Interop)),
              manual_cmd_log=client_manual_cmd_log)
          jobs.append(test_job)

  if args.cloud_to_prod_auth:
    if args.insecure:
      print('TLS is always enabled for cloud_to_prod scenarios.')
    for server_host_name in args.prod_servers:
      for language in languages:
        for test_case in _AUTH_TEST_CASES:
          if not test_case in language.unimplemented_test_cases():
            test_job = cloud_to_prod_jobspec(
                language, test_case, server_host_name,
                prod_servers[server_host_name],
                docker_image=docker_images.get(str(language)), auth=True,
                manual_cmd_log=client_manual_cmd_log)
            jobs.append(test_job)

  for server in args.override_server:
    server_name = server[0]
    (server_host, server_port) = server[1].split(':')
    server_addresses[server_name] = (server_host, server_port)

  for server_name, server_address in server_addresses.items():
    (server_host, server_port) = server_address
    server_language = _LANGUAGES.get(server_name, None)
    skip_server = []  # test cases unimplemented by server
    if server_language:
      skip_server = server_language.unimplemented_test_cases_server()
    for language in languages:
      for test_case in _TEST_CASES:
        if not test_case in language.unimplemented_test_cases():
          if not test_case in skip_server:
            test_job = cloud_to_cloud_jobspec(language,
                                              test_case,
                                              server_name,
                                              server_host,
                                              server_port,
                                              docker_image=docker_images.get(str(language)),
                                              insecure=args.insecure,
                                              manual_cmd_log=client_manual_cmd_log)
            jobs.append(test_job)

    if args.http2_interop:
      for test_case in _HTTP2_TEST_CASES:
        if server_name == "go":
          # TODO(carl-mastrangelo): Reenable after https://github.com/grpc/grpc-go/issues/434
          continue
        test_job = cloud_to_cloud_jobspec(http2Interop,
                                          test_case,
                                          server_name,
                                          server_host,
                                          server_port,
                                          docker_image=docker_images.get(str(http2Interop)),
                                          insecure=args.insecure,
                                          manual_cmd_log=client_manual_cmd_log)
        jobs.append(test_job)

  if args.http2_server_interop:
    if not args.manual_run:
      http2_server_job.wait_for_healthy(timeout_seconds=600)
    for language in languages_http2_clients_for_http2_server_interop:
      for test_case in set(_HTTP2_SERVER_TEST_CASES) - set(_HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS):
        offset = sorted(_HTTP2_SERVER_TEST_CASES).index(test_case)
        server_port = _DEFAULT_SERVER_PORT+offset
        if not args.manual_run:
          server_port = http2_server_job.mapped_port(server_port)
        test_job = cloud_to_cloud_jobspec(language,
                                          test_case,
                                          str(http2InteropServer),
                                          'localhost',
                                          server_port,
                                          docker_image=docker_images.get(str(language)),
                                          manual_cmd_log=client_manual_cmd_log)
        jobs.append(test_job)
    for language in languages:
      # HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS is a subset of
      # HTTP_SERVER_TEST_CASES, in which clients use their gRPC interop clients rather
      # than specialized http2 clients, reusing existing test implementations.
      # For example, in the "data_frame_padding" test, use language's gRPC
      # interop clients and make them think that theyre running "large_unary"
      # test case. This avoids implementing a new test case in each language.
      for test_case in _HTTP2_SERVER_TEST_CASES_THAT_USE_GRPC_CLIENTS:
        if test_case not in language.unimplemented_test_cases():
          offset = sorted(_HTTP2_SERVER_TEST_CASES).index(test_case)
          server_port = _DEFAULT_SERVER_PORT+offset
          if not args.manual_run:
            server_port = http2_server_job.mapped_port(server_port)
          if not args.insecure:
            print(('Creating grpc cient to http2 server test case with insecure connection, even though'
                   ' args.insecure is False. Http2 test server only supports insecure connections.'))
          test_job = cloud_to_cloud_jobspec(language,
                                            test_case,
                                            str(http2InteropServer),
                                            'localhost',
                                            server_port,
                                            docker_image=docker_images.get(str(language)),
                                            insecure=True,
                                            manual_cmd_log=client_manual_cmd_log)
          jobs.append(test_job)

  if not jobs:
    print('No jobs to run.')
    for image in six.itervalues(docker_images):
      dockerjob.remove_image(image, skip_nonexistent=True)
    sys.exit(1)

  if args.manual_run:
    print('All tests will skipped --manual_run option is active.')

  if args.verbose:
    print('Jobs to run: \n%s\n' % '\n'.join(str(job) for job in jobs))

  num_failures, resultset = jobset.run(jobs, newline_on_success=True,
                                       maxjobs=args.jobs,
                                       skip_jobs=args.manual_run)
  if args.bq_result_table and resultset:
    upload_interop_results_to_bq(resultset, args.bq_result_table, args)
  if num_failures:
    jobset.message('FAILED', 'Some tests failed', do_newline=True)
  else:
    jobset.message('SUCCESS', 'All tests passed', do_newline=True)

  write_cmdlog_maybe(server_manual_cmd_log, 'interop_server_cmds.sh')
  write_cmdlog_maybe(client_manual_cmd_log, 'interop_client_cmds.sh')

  xml_report_name = _XML_REPORT
  if args.internal_ci:
    xml_report_name = _INTERNAL_CL_XML_REPORT
  report_utils.render_junit_xml_report(resultset, xml_report_name)

  for name, job in resultset.items():
    if "http2" in name:
      job[0].http2results = aggregate_http2_results(job[0].message)

  http2_server_test_cases = (
      _HTTP2_SERVER_TEST_CASES if args.http2_server_interop else [])

  report_utils.render_interop_html_report(
      set([str(l) for l in languages]), servers, _TEST_CASES, _AUTH_TEST_CASES,
      _HTTP2_TEST_CASES, http2_server_test_cases, resultset, num_failures,
      args.cloud_to_prod_auth or args.cloud_to_prod, args.prod_servers,
      args.http2_interop)

  if num_failures:
    sys.exit(1)
  else:
    sys.exit(0)
except Exception as e:
  print('exception occurred:')
  traceback.print_exc(file=sys.stdout)
finally:
  # Check if servers are still running.
  for server, job in server_jobs.items():
    if not job.is_running():
      print('Server "%s" has exited prematurely.' % server)

  dockerjob.finish_jobs([j for j in six.itervalues(server_jobs)])

  for image in six.itervalues(docker_images):
    if not args.manual_run:
      print('Removing docker image %s' % image)
      dockerjob.remove_image(image)
    else:
      print('Preserving docker image: %s' % image)
