#!/usr/bin/env ruby

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

# client is a testing tool that accesses a gRPC interop testing server and runs
# a test on it.
#
# Helps validate interoperation b/w different gRPC implementations.
#
# Usage: $ path/to/client.rb --server_host=<hostname> \
#                            --server_port=<port> \
#                            --test_case=<testcase_name>

# These lines are required for the generated files to load grpc
this_dir = File.expand_path(File.dirname(__FILE__))
lib_dir = File.join(File.dirname(File.dirname(this_dir)), 'lib')
pb_dir = File.dirname(this_dir)
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
$LOAD_PATH.unshift(pb_dir) unless $LOAD_PATH.include?(pb_dir)

require 'optparse'
require 'logger'

require_relative '../../lib/grpc'
require 'googleauth'
require 'google/protobuf'

require_relative '../src/proto/grpc/testing/empty_pb'
require_relative '../src/proto/grpc/testing/messages_pb'
require_relative '../src/proto/grpc/testing/test_services_pb'

AUTH_ENV = Google::Auth::CredentialsLoader::ENV_VAR

# RubyLogger defines a logger for gRPC based on the standard ruby logger.
module RubyLogger
  def logger
    LOGGER
  end

  LOGGER = Logger.new(STDOUT)
  LOGGER.level = Logger::INFO
end

# GRPC is the general RPC module
module GRPC
  # Inject the noop #logger if no module-level logger method has been injected.
  extend RubyLogger
end

# AssertionError is use to indicate interop test failures.
class AssertionError < RuntimeError; end

# Fails with AssertionError if the block does evaluate to true
def assert(msg = 'unknown cause')
  fail 'No assertion block provided' unless block_given?
  fail AssertionError, msg unless yield
end

# loads the certificates used to access the test server securely.
def load_test_certs
  this_dir = File.expand_path(File.dirname(__FILE__))
  data_dir = File.join(File.dirname(File.dirname(this_dir)), 'spec/testdata')
  files = ['ca.pem', 'server1.key', 'server1.pem']
  files.map { |f| File.open(File.join(data_dir, f)).read }
end

# creates SSL Credentials from the test certificates.
def test_creds
  certs = load_test_certs
  GRPC::Core::ChannelCredentials.new(certs[0])
end

# creates SSL Credentials from the production certificates.
def prod_creds
  GRPC::Core::ChannelCredentials.new()
end

# creates the SSL Credentials.
def ssl_creds(use_test_ca)
  return test_creds if use_test_ca
  prod_creds
end

# creates a test stub that accesses host:port securely.
def create_stub(opts)
  address = "#{opts.server_host}:#{opts.server_port}"

  # Provide channel args that request compression by default
  # for compression interop tests
  if ['client_compressed_unary',
      'client_compressed_streaming'].include?(opts.test_case)
    compression_options =
      GRPC::Core::CompressionOptions.new(default_algorithm: :gzip)
    compression_channel_args = compression_options.to_channel_arg_hash
  else
    compression_channel_args = {}
  end

  if opts.secure
    creds = ssl_creds(opts.use_test_ca)
    stub_opts = {
      channel_args: {}
    }
    unless opts.server_host_override.empty?
      stub_opts[:channel_args].merge!({
          GRPC::Core::Channel::SSL_TARGET => opts.server_host_override
      })
    end

    # Add service account creds if specified
    wants_creds = %w(all compute_engine_creds service_account_creds)
    if wants_creds.include?(opts.test_case)
      unless opts.oauth_scope.nil?
        auth_creds = Google::Auth.get_application_default(opts.oauth_scope)
        call_creds = GRPC::Core::CallCredentials.new(auth_creds.updater_proc)
        creds = creds.compose call_creds
      end
    end

    if opts.test_case == 'oauth2_auth_token'
      auth_creds = Google::Auth.get_application_default(opts.oauth_scope)
      kw = auth_creds.updater_proc.call({})  # gives as an auth token

      # use a metadata update proc that just adds the auth token.
      call_creds = GRPC::Core::CallCredentials.new(proc { |md| md.merge(kw) })
      creds = creds.compose call_creds
    end

    if opts.test_case == 'jwt_token_creds'  # don't use a scope
      auth_creds = Google::Auth.get_application_default
      call_creds = GRPC::Core::CallCredentials.new(auth_creds.updater_proc)
      creds = creds.compose call_creds
    end

    GRPC.logger.info("... connecting securely to #{address}")
    stub_opts[:channel_args].merge!(compression_channel_args)
    if opts.test_case == "unimplemented_service"
      Grpc::Testing::UnimplementedService::Stub.new(address, creds, **stub_opts)
    else
      Grpc::Testing::TestService::Stub.new(address, creds, **stub_opts)
    end
  else
    GRPC.logger.info("... connecting insecurely to #{address}")
    if opts.test_case == "unimplemented_service"
      Grpc::Testing::UnimplementedService::Stub.new(
        address,
        :this_channel_is_insecure,
        channel_args: compression_channel_args
      )
    else
      Grpc::Testing::TestService::Stub.new(
        address,
        :this_channel_is_insecure,
        channel_args: compression_channel_args
      )
    end
  end
end

# produces a string of null chars (\0) of length l.
def nulls(l)
  fail 'requires #{l} to be +ve' if l < 0
  [].pack('x' * l).force_encoding('ascii-8bit')
end

# a PingPongPlayer implements the ping pong bidi test.
class PingPongPlayer
  include Grpc::Testing
  include Grpc::Testing::PayloadType
  attr_accessor :queue
  attr_accessor :canceller_op

  # reqs is the enumerator over the requests
  def initialize(msg_sizes)
    @queue = Queue.new
    @msg_sizes = msg_sizes
    @canceller_op = nil  # used to cancel after the first response
  end

  def each_item
    return enum_for(:each_item) unless block_given?
    req_cls, p_cls = StreamingOutputCallRequest, ResponseParameters  # short
    count = 0
    @msg_sizes.each do |m|
      req_size, resp_size = m
      req = req_cls.new(payload: Payload.new(body: nulls(req_size)),
                        response_type: :COMPRESSABLE,
                        response_parameters: [p_cls.new(size: resp_size)])
      yield req
      resp = @queue.pop
      assert('payload type is wrong') { :COMPRESSABLE == resp.payload.type }
      assert("payload body #{count} has the wrong length") do
        resp_size == resp.payload.body.length
      end
      p "OK: ping_pong #{count}"
      count += 1
      unless @canceller_op.nil?
        canceller_op.cancel
        break
      end
    end
  end
end

class BlockingEnumerator
  include Grpc::Testing
  include Grpc::Testing::PayloadType

  def initialize(req_size, sleep_time)
    @req_size = req_size
    @sleep_time = sleep_time
  end

  def each_item
    return enum_for(:each_item) unless block_given?
    req_cls = StreamingOutputCallRequest
    req = req_cls.new(payload: Payload.new(body: nulls(@req_size)))
    yield req
    # Sleep until after the deadline should have passed
    sleep(@sleep_time)
  end
end

# Intended to be used to wrap a call_op, and to adjust
# the write flag of the call_op in between messages yielded to it.
class WriteFlagSettingStreamingInputEnumerable
  attr_accessor :call_op

  def initialize(requests_and_write_flags)
    @requests_and_write_flags = requests_and_write_flags
  end

  def each
    @requests_and_write_flags.each do |request_and_flag|
      @call_op.write_flag = request_and_flag[:write_flag]
      yield request_and_flag[:request]
    end
  end
end

# defines methods corresponding to each interop test case.
class NamedTests
  include Grpc::Testing
  include Grpc::Testing::PayloadType
  include GRPC::Core::MetadataKeys

  def initialize(stub, args)
    @stub = stub
    @args = args
  end

  def empty_unary
    resp = @stub.empty_call(Empty.new)
    assert('empty_unary: invalid response') { resp.is_a?(Empty) }
  end

  def large_unary
    perform_large_unary
  end

  def client_compressed_unary
    # first request used also for the probe
    req_size, wanted_response_size = 271_828, 314_159
    expect_compressed = BoolValue.new(value: true)
    payload = Payload.new(type: :COMPRESSABLE, body: nulls(req_size))
    req = SimpleRequest.new(response_type: :COMPRESSABLE,
                            response_size: wanted_response_size,
                            payload: payload,
                            expect_compressed: expect_compressed)

    # send a probe to see if CompressedResponse is supported on the server
    send_probe_for_compressed_request_support do
      request_uncompressed_args = {
        COMPRESSION_REQUEST_ALGORITHM => 'identity'
      }
      @stub.unary_call(req, metadata: request_uncompressed_args)
    end

    # make a call with a compressed message
    resp = @stub.unary_call(req)
    assert('Expected second unary call with compression to work') do
      resp.payload.body.length == wanted_response_size
    end

    # make a call with an uncompressed message
    stub_options = {
      COMPRESSION_REQUEST_ALGORITHM => 'identity'
    }

    req = SimpleRequest.new(
      response_type: :COMPRESSABLE,
      response_size: wanted_response_size,
      payload: payload,
      expect_compressed: BoolValue.new(value: false)
    )

    resp = @stub.unary_call(req, metadata: stub_options)
    assert('Expected second unary call with compression to work') do
      resp.payload.body.length == wanted_response_size
    end
  end

  def service_account_creds
    # ignore this test if the oauth options are not set
    if @args.oauth_scope.nil?
      p 'NOT RUN: service_account_creds; no service_account settings'
      return
    end
    json_key = File.read(ENV[AUTH_ENV])
    wanted_email = MultiJson.load(json_key)['client_email']
    resp = perform_large_unary(fill_username: true,
                               fill_oauth_scope: true)
    assert("#{__callee__}: bad username") { wanted_email == resp.username }
    assert("#{__callee__}: bad oauth scope") do
      @args.oauth_scope.include?(resp.oauth_scope)
    end
  end

  def jwt_token_creds
    json_key = File.read(ENV[AUTH_ENV])
    wanted_email = MultiJson.load(json_key)['client_email']
    resp = perform_large_unary(fill_username: true)
    assert("#{__callee__}: bad username") { wanted_email == resp.username }
  end

  def compute_engine_creds
    resp = perform_large_unary(fill_username: true,
                               fill_oauth_scope: true)
    assert("#{__callee__}: bad username") do
      @args.default_service_account == resp.username
    end
  end

  def oauth2_auth_token
    resp = perform_large_unary(fill_username: true,
                               fill_oauth_scope: true)
    json_key = File.read(ENV[AUTH_ENV])
    wanted_email = MultiJson.load(json_key)['client_email']
    assert("#{__callee__}: bad username") { wanted_email == resp.username }
    assert("#{__callee__}: bad oauth scope") do
      @args.oauth_scope.include?(resp.oauth_scope)
    end
  end

  def per_rpc_creds
    auth_creds = Google::Auth.get_application_default(@args.oauth_scope)
    update_metadata = proc do |md|
      kw = auth_creds.updater_proc.call({})
    end

    call_creds = GRPC::Core::CallCredentials.new(update_metadata)

    resp = perform_large_unary(fill_username: true,
                               fill_oauth_scope: true,
                               credentials: call_creds)
    json_key = File.read(ENV[AUTH_ENV])
    wanted_email = MultiJson.load(json_key)['client_email']
    assert("#{__callee__}: bad username") { wanted_email == resp.username }
    assert("#{__callee__}: bad oauth scope") do
      @args.oauth_scope.include?(resp.oauth_scope)
    end
  end

  def client_streaming
    msg_sizes = [27_182, 8, 1828, 45_904]
    wanted_aggregate_size = 74_922
    reqs = msg_sizes.map do |x|
      req = Payload.new(body: nulls(x))
      StreamingInputCallRequest.new(payload: req)
    end
    resp = @stub.streaming_input_call(reqs)
    assert("#{__callee__}: aggregate payload size is incorrect") do
      wanted_aggregate_size == resp.aggregated_payload_size
    end
  end

  def client_compressed_streaming
    # first request used also by the probe
    first_request = StreamingInputCallRequest.new(
      payload: Payload.new(type: :COMPRESSABLE, body: nulls(27_182)),
      expect_compressed: BoolValue.new(value: true)
    )

    # send a probe to see if CompressedResponse is supported on the server
    send_probe_for_compressed_request_support do
      request_uncompressed_args = {
        COMPRESSION_REQUEST_ALGORITHM => 'identity'
      }
      @stub.streaming_input_call([first_request],
                                 metadata: request_uncompressed_args)
    end

    second_request = StreamingInputCallRequest.new(
      payload: Payload.new(type: :COMPRESSABLE, body: nulls(45_904)),
      expect_compressed: BoolValue.new(value: false)
    )

    # Create the requests messages and the corresponding write flags
    # for each message
    requests = WriteFlagSettingStreamingInputEnumerable.new([
      { request: first_request,
        write_flag: 0 },
      { request: second_request,
        write_flag: GRPC::Core::WriteFlags::NO_COMPRESS }
    ])

    # Create the call_op, pass it to the requests enumerable, and
    # run the call
    call_op = @stub.streaming_input_call(requests,
                                         return_op: true)
    requests.call_op = call_op
    resp = call_op.execute

    wanted_aggregate_size = 73_086

    assert("#{__callee__}: aggregate payload size is incorrect") do
      wanted_aggregate_size == resp.aggregated_payload_size
    end
  end

  def server_streaming
    msg_sizes = [31_415, 9, 2653, 58_979]
    response_spec = msg_sizes.map { |s| ResponseParameters.new(size: s) }
    req = StreamingOutputCallRequest.new(response_type: :COMPRESSABLE,
                                         response_parameters: response_spec)
    resps = @stub.streaming_output_call(req)
    resps.each_with_index do |r, i|
      assert("#{__callee__}: too many responses") { i < msg_sizes.length }
      assert("#{__callee__}: payload body #{i} has the wrong length") do
        msg_sizes[i] == r.payload.body.length
      end
      assert("#{__callee__}: payload type is wrong") do
        :COMPRESSABLE == r.payload.type
      end
    end
  end

  def ping_pong
    msg_sizes = [[27_182, 31_415], [8, 9], [1828, 2653], [45_904, 58_979]]
    ppp = PingPongPlayer.new(msg_sizes)
    resps = @stub.full_duplex_call(ppp.each_item)
    resps.each { |r| ppp.queue.push(r) }
  end

  def timeout_on_sleeping_server
    enum = BlockingEnumerator.new(27_182, 2)
    deadline = GRPC::Core::TimeConsts::from_relative_time(1)
    resps = @stub.full_duplex_call(enum.each_item, deadline: deadline)
    resps.each { } # wait to receive each request (or timeout)
    fail 'Should have raised GRPC::DeadlineExceeded'
  rescue GRPC::DeadlineExceeded
  end

  def empty_stream
    ppp = PingPongPlayer.new([])
    resps = @stub.full_duplex_call(ppp.each_item)
    count = 0
    resps.each do |r|
      ppp.queue.push(r)
      count += 1
    end
    assert("#{__callee__}: too many responses expected 0") do
      count == 0
    end
  end

  def cancel_after_begin
    msg_sizes = [27_182, 8, 1828, 45_904]
    reqs = msg_sizes.map do |x|
      req = Payload.new(body: nulls(x))
      StreamingInputCallRequest.new(payload: req)
    end
    op = @stub.streaming_input_call(reqs, return_op: true)
    op.cancel
    op.execute
    fail 'Should have raised GRPC:Cancelled'
  rescue GRPC::Cancelled
    assert("#{__callee__}: call operation should be CANCELLED") { op.cancelled? }
  end

  def cancel_after_first_response
    msg_sizes = [[27_182, 31_415], [8, 9], [1828, 2653], [45_904, 58_979]]
    ppp = PingPongPlayer.new(msg_sizes)
    op = @stub.full_duplex_call(ppp.each_item, return_op: true)
    ppp.canceller_op = op  # causes ppp to cancel after the 1st message
    op.execute.each { |r| ppp.queue.push(r) }
    fail 'Should have raised GRPC:Cancelled'
  rescue GRPC::Cancelled
    assert("#{__callee__}: call operation should be CANCELLED") { op.cancelled? }
    op.wait
  end

  def unimplemented_method
    begin
      resp = @stub.unimplemented_call(Empty.new)
    rescue GRPC::Unimplemented => e
      return
    rescue Exception => e
      fail AssertionError, "Expected BadStatus. Received: #{e.inspect}"
    end
    fail AssertionError, "GRPC::Unimplemented should have been raised. Was not."
  end

  def unimplemented_service
    begin
      resp = @stub.unimplemented_call(Empty.new)
    rescue GRPC::Unimplemented => e
      return
    rescue Exception => e
      fail AssertionError, "Expected BadStatus. Received: #{e.inspect}"
    end
    fail AssertionError, "GRPC::Unimplemented should have been raised. Was not."
  end

  def status_code_and_message

    # Function wide constants.
    message = "test status method"
    code = GRPC::Core::StatusCodes::UNKNOWN

    # Testing with UnaryCall.
    payload = Payload.new(type: :COMPRESSABLE, body: nulls(1))
    echo_status = EchoStatus.new(code: code, message: message)
    req = SimpleRequest.new(response_type: :COMPRESSABLE,
			    response_size: 1,
			    payload: payload,
			    response_status: echo_status)
    seen_correct_exception = false
    begin
      resp = @stub.unary_call(req)
    rescue GRPC::Unknown => e
      if e.details != message
	      fail AssertionError,
	        "Expected message #{message}. Received: #{e.details}"
      end
      seen_correct_exception = true
    rescue Exception => e
      fail AssertionError, "Expected BadStatus. Received: #{e.inspect}"
    end

    if not seen_correct_exception
      fail AssertionError, "Did not see expected status from UnaryCall"
    end

    # testing with FullDuplex
    req_cls, p_cls = StreamingOutputCallRequest, ResponseParameters
    duplex_req = req_cls.new(payload: Payload.new(body: nulls(1)),
                  response_type: :COMPRESSABLE,
                  response_parameters: [p_cls.new(size: 1)],
                  response_status: echo_status)
    seen_correct_exception = false
    begin
      resp = @stub.full_duplex_call([duplex_req])
      resp.each { |r| }
    rescue GRPC::Unknown => e
      if e.details != message
        fail AssertionError,
          "Expected message #{message}. Received: #{e.details}"
      end
      seen_correct_exception = true
    rescue Exception => e
      fail AssertionError, "Expected BadStatus. Received: #{e.inspect}"
    end

    if not seen_correct_exception
      fail AssertionError, "Did not see expected status from FullDuplexCall"
    end

  end


  def custom_metadata

    # Function wide constants
    req_size, wanted_response_size = 271_828, 314_159
    initial_metadata_key = "x-grpc-test-echo-initial"
    initial_metadata_value = "test_initial_metadata_value"
    trailing_metadata_key = "x-grpc-test-echo-trailing-bin"
    trailing_metadata_value = "\x0a\x0b\x0a\x0b\x0a\x0b"

    metadata = {
      initial_metadata_key => initial_metadata_value,
      trailing_metadata_key => trailing_metadata_value
    }

    # Testing with UnaryCall
    payload = Payload.new(type: :COMPRESSABLE, body: nulls(req_size))
    req = SimpleRequest.new(response_type: :COMPRESSABLE,
			    response_size: wanted_response_size,
			    payload: payload)

    op = @stub.unary_call(req, metadata: metadata, return_op: true)
    op.execute
    if not op.metadata.has_key?(initial_metadata_key)
      fail AssertionError, "Expected initial metadata. None received"
    elsif op.metadata[initial_metadata_key] != metadata[initial_metadata_key]
      fail AssertionError,
             "Expected initial metadata: #{metadata[initial_metadata_key]}. "\
             "Received: #{op.metadata[initial_metadata_key]}"
    end
    if not op.trailing_metadata.has_key?(trailing_metadata_key)
      fail AssertionError, "Expected trailing metadata. None received"
    elsif op.trailing_metadata[trailing_metadata_key] !=
          metadata[trailing_metadata_key]
      fail AssertionError,
            "Expected trailing metadata: #{metadata[trailing_metadata_key]}. "\
            "Received: #{op.trailing_metadata[trailing_metadata_key]}"
    end

    # Testing with FullDuplex
    req_cls, p_cls = StreamingOutputCallRequest, ResponseParameters
    duplex_req = req_cls.new(payload: Payload.new(body: nulls(req_size)),
                  response_type: :COMPRESSABLE,
                  response_parameters: [p_cls.new(size: wanted_response_size)])

    duplex_op = @stub.full_duplex_call([duplex_req], metadata: metadata,
                                        return_op: true)
    resp = duplex_op.execute
    resp.each { |r| } # ensures that the server sends trailing data
    duplex_op.wait
    if not duplex_op.metadata.has_key?(initial_metadata_key)
      fail AssertionError, "Expected initial metadata. None received"
    elsif duplex_op.metadata[initial_metadata_key] !=
          metadata[initial_metadata_key]
      fail AssertionError,
             "Expected initial metadata: #{metadata[initial_metadata_key]}. "\
             "Received: #{duplex_op.metadata[initial_metadata_key]}"
    end
    if not duplex_op.trailing_metadata[trailing_metadata_key]
      fail AssertionError, "Expected trailing metadata. None received"
    elsif duplex_op.trailing_metadata[trailing_metadata_key] !=
          metadata[trailing_metadata_key]
      fail AssertionError,
          "Expected trailing metadata: #{metadata[trailing_metadata_key]}. "\
          "Received: #{duplex_op.trailing_metadata[trailing_metadata_key]}"
    end

  end

  def special_status_message
    code = GRPC::Core::StatusCodes::UNKNOWN
    message = "\t\ntest with whitespace\r\nand Unicode BMP ☺ and non-BMP 😈\t\n"
    req = SimpleRequest.new(
      response_status: EchoStatus.new(code: code, message: message))
    begin
      resp = @stub.unary_call(req)
      fail AssertionError, "GRPC::Unknown should have been raised."
    rescue GRPC::Unknown => e
      if e.details.force_encoding("UTF-8") != message
        fail AssertionError,
          "Expected message #{message}. Received: #{e.details}"
      end
    end
  end

  def all
    all_methods = NamedTests.instance_methods(false).map(&:to_s)
    all_methods.each do |m|
      next if m == 'all' || m.start_with?('assert')
      p "TESTCASE: #{m}"
      method(m).call
    end
  end

  private

  def perform_large_unary(fill_username: false, fill_oauth_scope: false, **kw)
    req_size, wanted_response_size = 271_828, 314_159
    payload = Payload.new(type: :COMPRESSABLE, body: nulls(req_size))
    req = SimpleRequest.new(response_type: :COMPRESSABLE,
                            response_size: wanted_response_size,
                            payload: payload)
    req.fill_username = fill_username
    req.fill_oauth_scope = fill_oauth_scope
    resp = @stub.unary_call(req, **kw)
    assert('payload type is wrong') do
      :COMPRESSABLE == resp.payload.type
    end
    assert('payload body has the wrong length') do
      wanted_response_size == resp.payload.body.length
    end
    assert('payload body is invalid') do
      nulls(wanted_response_size) == resp.payload.body
    end
    resp
  end

  # Send probing message for compressed request on the server, to see
  # if it's implemented.
  def send_probe_for_compressed_request_support(&send_probe)
    bad_status_occurred = false

    begin
      send_probe.call
    rescue GRPC::BadStatus => e
      if e.code == GRPC::Core::StatusCodes::INVALID_ARGUMENT
        bad_status_occurred = true
      else
        fail AssertionError, "Bad status received but code is #{e.code}"
      end
    rescue Exception => e
      fail AssertionError, "Expected BadStatus. Received: #{e.inspect}"
    end

    assert('CompressedRequest probe failed') do
      bad_status_occurred
    end
  end

end

# Args is used to hold the command line info.
Args = Struct.new(:default_service_account, :server_host, :server_host_override,
                  :oauth_scope, :server_port, :secure, :test_case,
                  :use_test_ca)

# validates the command line options, returning them as a Hash.
def parse_args
  args = Args.new
  args.server_host_override = ''
  OptionParser.new do |opts|
    opts.on('--oauth_scope scope',
            'Scope for OAuth tokens') { |v| args['oauth_scope'] = v }
    opts.on('--server_host SERVER_HOST', 'server hostname') do |v|
      args['server_host'] = v
    end
    opts.on('--default_service_account email_address',
            'email address of the default service account') do |v|
      args['default_service_account'] = v
    end
    opts.on('--server_host_override HOST_OVERRIDE',
            'override host via a HTTP header') do |v|
      args['server_host_override'] = v
    end
    opts.on('--server_port SERVER_PORT', 'server port') do |v|
      args['server_port'] = v
    end
    # instance_methods(false) gives only the methods defined in that class
    test_cases = NamedTests.instance_methods(false).map(&:to_s)
    test_case_list = test_cases.join(',')
    opts.on('--test_case CODE', test_cases, {}, 'select a test_case',
            "  (#{test_case_list})") { |v| args['test_case'] = v }
    opts.on('--use_tls USE_TLS', ['false', 'true'],
            'require a secure connection?') do |v|
      args['secure'] = v == 'true'
    end
    opts.on('--use_test_ca USE_TEST_CA', ['false', 'true'],
            'if secure, use the test certificate?') do |v|
      args['use_test_ca'] = v == 'true'
    end
  end.parse!
  _check_args(args)
end

def _check_args(args)
  %w(server_host server_port test_case).each do |a|
    if args[a].nil?
      fail(OptionParser::MissingArgument, "please specify --#{a}")
    end
  end
  args
end

def main
  opts = parse_args
  stub = create_stub(opts)
  NamedTests.new(stub, opts).method(opts['test_case']).call
  p "OK: #{opts['test_case']}"
end

if __FILE__ == $0
  main
end
