Added --server-type argument to Ruby cross-tests integration server
diff --git a/test/rb/integration/TestServer.rb b/test/rb/integration/TestServer.rb
index 65d1285..d0ba1fe 100755
--- a/test/rb/integration/TestServer.rb
+++ b/test/rb/integration/TestServer.rb
@@ -25,6 +25,8 @@
 require 'thrift'
 require 'thrift_test'
 require 'thrift_test_types'
+require 'logger'
+require 'optparse'
 
 class SimpleHandler
   [:testVoid, :testString, :testBool, :testByte, :testI32, :testI64, :testDouble, :testBinary,
@@ -106,66 +108,105 @@
 
 end
 
-domain_socket = nil
-port = 9090
-protocol = "binary"
-@protocolFactory = nil
-ssl = false
-transport = "buffered"
-@transportFactory = nil
+options = {
+  domain_socket: nil,
+  port: 9090,
+  protocol: 'binary',
+  ssl: false,
+  transport: 'buffered',
+  server_type: 'threaded',
+  workers: nil,
+}
 
-ARGV.each do|a|
-  if a == "--help"
-    puts "Allowed options:"
-    puts "\t -h [ --help ] \t produce help message"
-    puts "\t--domain-socket arg (=) \t Unix domain socket path"
-    puts "\t--port arg (=9090) \t Port number to listen \t not valid with domain-socket"
-    puts "\t--protocol arg (=binary) \t protocol: accel, binary, compact, json, header"
-    puts "\t--ssl \t use ssl \t not valid with domain-socket"
-    puts "\t--transport arg (=buffered) transport: buffered, framed, header, http"
-    exit
-  elsif a.start_with?("--domain-socket")
-    domain_socket = a.split("=")[1]
-  elsif a.start_with?("--protocol")
-    protocol = a.split("=")[1]
-  elsif a == "--ssl"
-    ssl = true
-  elsif a.start_with?("--transport")
-    transport = a.split("=")[1]
-  elsif a.start_with?("--port")
-    port = a.split("=")[1].to_i
+server_type_map = {
+  'simple' => 'simple',
+  'threaded' => 'threaded',
+  'thread-pool' => 'thread-pool',
+  'thread_pool' => 'thread-pool',
+  'threadpool' => 'thread-pool',
+  'nonblocking' => 'nonblocking',
+  'tsimpleserver' => 'simple',
+  'tthreadedserver' => 'threaded',
+  'tthreadpoolserver' => 'thread-pool',
+  'tnonblockingserver' => 'nonblocking',
+}
+
+parser = OptionParser.new do |opts|
+  opts.banner = "Allowed options:"
+  opts.on('-h', '--help', 'produce help message') do
+    puts opts
+    exit 0
   end
+  opts.on('--domain-socket=PATH', String, 'Unix domain socket path') { |v| options[:domain_socket] = v }
+  opts.on('--port=PORT', Integer, 'Port number to listen (not valid with domain-socket)') { |v| options[:port] = v }
+  opts.on('--protocol=PROTO', String, 'protocol: accel, binary, compact, json, header') { |v| options[:protocol] = v }
+  opts.on('--ssl', 'use ssl (not valid with domain-socket)') { options[:ssl] = true }
+  opts.on('--transport=TRANSPORT', String, 'transport: buffered, framed, header') { |v| options[:transport] = v }
+  opts.on('--server-type=TYPE', String, 'type of server: simple, thread-pool, threaded, nonblocking') { |v| options[:server_type] = v }
+  opts.on('-n', '--workers=N', Integer, 'Number of workers (thread-pool/nonblocking)') { |v| options[:workers] = v }
 end
 
-if protocol == "binary" || protocol.to_s.strip.empty?
-  @protocolFactory = Thrift::BinaryProtocolFactory.new
-elsif protocol == "compact"
-  @protocolFactory = Thrift::CompactProtocolFactory.new
-elsif protocol == "json"
-  @protocolFactory = Thrift::JsonProtocolFactory.new
-elsif protocol == "accel"
-  @protocolFactory = Thrift::BinaryProtocolAcceleratedFactory.new
-elsif protocol == "header"
-  @protocolFactory = Thrift::HeaderProtocolFactory.new
+begin
+  parser.parse!(ARGV)
+  if ARGV.length > 1
+    raise OptionParser::InvalidOption, "Only one positional server type may be specified"
+  end
+rescue OptionParser::ParseError => e
+  warn e.message
+  warn parser
+  exit 1
+end
+
+# Accept Python-style server type positional arg for compatibility.
+options[:server_type] = ARGV.first unless ARGV.empty?
+normalized_server_type = server_type_map[options[:server_type].to_s.downcase]
+if normalized_server_type.nil?
+  warn "Unknown server type '#{options[:server_type]}'"
+  warn parser
+  exit 1
+end
+
+if options[:ssl] && !options[:domain_socket].to_s.strip.empty?
+  warn '--ssl is not valid with --domain-socket'
+  exit 1
+end
+
+protocol_factory = case options[:protocol].to_s.strip
+when '', 'binary'
+  Thrift::BinaryProtocolFactory.new
+when 'compact'
+  Thrift::CompactProtocolFactory.new
+when 'json'
+  Thrift::JsonProtocolFactory.new
+when 'accel'
+  Thrift::BinaryProtocolAcceleratedFactory.new
+when 'header'
+  Thrift::HeaderProtocolFactory.new
 else
-  raise 'Unknown protocol type'
+  raise "Unknown protocol type '#{options[:protocol]}'"
 end
 
-if transport == "buffered" || transport.to_s.strip.empty?
-  @transportFactory = Thrift::BufferedTransportFactory.new
-elsif transport == "framed"
-  @transportFactory = Thrift::FramedTransportFactory.new
-elsif transport == "header"
-  @transportFactory = Thrift::HeaderTransportFactory.new
+transport_factory = case options[:transport].to_s.strip
+when '', 'buffered'
+  Thrift::BufferedTransportFactory.new
+when 'framed'
+  Thrift::FramedTransportFactory.new
+when 'header'
+  Thrift::HeaderTransportFactory.new
 else
-  raise 'Unknown transport type'
+  raise "Unknown transport type '#{options[:transport]}'"
 end
 
-@handler = SimpleHandler.new
-@processor = Thrift::Test::ThriftTest::Processor.new(@handler)
-@transport = nil
-if domain_socket.to_s.strip.empty?
-  if ssl
+if normalized_server_type == 'nonblocking' && options[:transport] != 'framed'
+  raise 'server-type nonblocking requires transport of framed'
+end
+
+handler = SimpleHandler.new
+processor = Thrift::Test::ThriftTest::Processor.new(handler)
+
+transport = nil
+if options[:domain_socket].to_s.strip.empty?
+  if options[:ssl]
     # the working directory for ruby crosstest is test/rb/gen-rb
     keysDir = File.join(File.dirname(File.dirname(Dir.pwd)), "keys")
     ctx = OpenSSL::SSL::SSLContext.new
@@ -176,16 +217,28 @@
     ctx.key = OpenSSL::PKey::RSA.new(File.binread(File.join(keysDir, "server.key")))
     ctx.min_version = :TLS1_2
     ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
-    @transport = Thrift::SSLServerSocket.new(nil, port, ctx)
+    transport = Thrift::SSLServerSocket.new(nil, options[:port], ctx)
   else
-    @transport = Thrift::ServerSocket.new(port)
+    transport = Thrift::ServerSocket.new(options[:port])
   end
 else
-  @transport = Thrift::UNIXServerSocket.new(domain_socket)
+  transport = Thrift::UNIXServerSocket.new(options[:domain_socket])
 end
 
-@server = Thrift::ThreadedServer.new(@processor, @transport, @transportFactory, @protocolFactory)
+workers = options[:workers] || 20
+server = case normalized_server_type
+when 'simple'
+  Thrift::SimpleServer.new(processor, transport, transport_factory, protocol_factory)
+when 'threaded'
+  Thrift::ThreadedServer.new(processor, transport, transport_factory, protocol_factory)
+when 'thread-pool'
+  Thrift::ThreadPoolServer.new(processor, transport, transport_factory, protocol_factory, workers)
+when 'nonblocking'
+  logger = Logger.new(STDERR)
+  logger.level = Logger::WARN
+  Thrift::NonblockingServer.new(processor, transport, transport_factory, protocol_factory, workers, logger)
+end
 
-puts "Starting TestServer #{@server.to_s}"
-@server.serve
+puts "Starting TestServer #{server.to_s}"
+server.serve
 puts "done."