#!/usr/bin/env python

#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
#

from __future__ import division
import time
import socket
import subprocess
import sys
import os
import signal
from optparse import OptionParser

parser = OptionParser()
parser.add_option('--genpydirs', type='string', dest='genpydirs',
    default='default,slots,newstyle,newstyleslots,dynamic,dynamicslots',
    help='directory extensions for generated code, used as suffixes for \"gen-py-*\" added sys.path for individual tests')
parser.add_option("--port", type="int", dest="port", default=9090,
    help="port number for server to listen on")
parser.add_option('-v', '--verbose', action="store_const",
    dest="verbose", const=2,
    help="verbose output")
parser.add_option('-q', '--quiet', action="store_const",
    dest="verbose", const=0,
    help="minimal output")
parser.set_defaults(verbose=1)
options, args = parser.parse_args()

generated_dirs = []
for gp_dir in options.genpydirs.split(','):
  generated_dirs.append('gen-py-%s' % (gp_dir))

SCRIPTS = ['TSimpleJSONProtocolTest.py',
           'SerializationTest.py',
           'TestEof.py',
           'TestSyntax.py',
           'TestSocket.py']
FRAMED = ["TNonblockingServer"]
SKIP_ZLIB = ['TNonblockingServer', 'THttpServer']
SKIP_SSL = ['TNonblockingServer', 'THttpServer']
EXTRA_DELAY = dict(TProcessPoolServer=3.5)

PROTOS= [
    'accel',
    'binary',
    'compact']
# FIXME: add json
# disabled because json HTTP test hangs... why?

SERVERS = [
  "TSimpleServer",
  "TThreadedServer",
  "TThreadPoolServer",
  "TProcessPoolServer", # new!
  "TForkingServer",
  "TNonblockingServer",
  "THttpServer" ]

# Test for presence of multiprocessing module, and if it is not present, then
# remove it from the list of available servers.
try:
  import multiprocessing
except:
  print 'Warning: the multiprocessing module is unavailable. Skipping tests for TProcessPoolServer'
  SERVERS.remove('TProcessPoolServer')

try:
  import ssl
except:
  print 'Warning, no ssl module available. Skipping all SSL tests.'
  SKIP_SSL.extend(SERVERS)

# commandline permits a single class name to be specified to override SERVERS=[...]
if len(args) == 1:
  if args[0] in SERVERS:
    SERVERS = args
  else:
    print 'Unavailable server type "%s", please choose one of: %s' % (args[0], SERVERS)
    sys.exit(0)


def relfile(fname):
    return os.path.join(os.path.dirname(__file__), fname)

def runScriptTest(genpydir, script):
  script_args = [sys.executable, relfile(script) ]
  script_args.append('--genpydir=%s' % genpydir)
  serverproc = subprocess.Popen(script_args)
  print '\nTesting script: %s\n----' % (' '.join(script_args))
  ret = subprocess.call(script_args)
  if ret != 0:
    raise Exception("Script subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(script_args)))

def runServiceTest(genpydir, server_class, proto, port, use_zlib, use_ssl):
  # Build command line arguments
  server_args = [sys.executable, relfile('TestServer.py') ]
  cli_args = [sys.executable, relfile('TestClient.py') ]
  for which in (server_args, cli_args):
    which.append('--genpydir=%s' % genpydir)
    which.append('--protocol=%s' % proto) # accel, binary or compact
    which.append('--port=%d' % port) # default to 9090
    if use_zlib:
      which.append('--zlib')
    if use_ssl:
      which.append('--ssl')
    if options.verbose == 0:
      which.append('-q')
    if options.verbose == 2:
      which.append('-v')
  # server-specific option to select server class
  server_args.append(server_class)
  # client-specific cmdline options
  if server_class in FRAMED:
    cli_args.append('--transport=framed')
  else:
     cli_args.append('--transport=buffered')
  if server_class == 'THttpServer':
    cli_args.append('--http=/')
  if options.verbose > 0:
    print 'Testing server %s: %s' % (server_class, ' '.join(server_args))
  serverproc = subprocess.Popen(server_args)

  def ensureServerAlive():
    if serverproc.poll() is not None:
      print ('FAIL: Server process (%s) failed with retcode %d'
             % (' '.join(server_args), serverproc.returncode))
      raise Exception('Server subprocess %s died, args: %s'
                      % (server_class, ' '.join(server_args)))

  # Wait for the server to start accepting connections on the given port.
  sock = socket.socket()
  sleep_time = 0.1  # Seconds
  max_attempts = 100
  try:
    attempt = 0
    while sock.connect_ex(('127.0.0.1', port)) != 0:
      attempt += 1
      if attempt >= max_attempts:
        raise Exception("TestServer not ready on port %d after %.2f seconds"
                        % (port, sleep_time * attempt))
      ensureServerAlive()
      time.sleep(sleep_time)
  finally:
    sock.close()

  try:
    if options.verbose > 0:
      print 'Testing client: %s' % (' '.join(cli_args))
    ret = subprocess.call(cli_args)
    if ret != 0:
      raise Exception("Client subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(cli_args)))
  finally:
    # check that server didn't die
    ensureServerAlive()
    extra_sleep = EXTRA_DELAY.get(server_class, 0)
    if extra_sleep > 0 and options.verbose > 0:
      print ('Giving %s (proto=%s,zlib=%s,ssl=%s) an extra %d seconds for child'
             'processes to terminate via alarm'
             % (server_class, proto, use_zlib, use_ssl, extra_sleep))
      time.sleep(extra_sleep)
    os.kill(serverproc.pid, signal.SIGKILL)
    serverproc.wait()

test_count = 0
# run tests without a client/server first
print '----------------'
print ' Executing individual test scripts with various generated code directories'
print ' Directories to be tested: ' + ', '.join(generated_dirs)
print ' Scripts to be tested: ' + ', '.join(SCRIPTS)
print '----------------'
for genpydir in generated_dirs:
  for script in SCRIPTS:
    runScriptTest(genpydir, script)

print '----------------'
print ' Executing Client/Server tests with various generated code directories'
print ' Servers to be tested: ' + ', '.join(SERVERS)
print ' Directories to be tested: ' + ', '.join(generated_dirs)
print ' Protocols to be tested: ' + ', '.join(PROTOS)
print ' Options to be tested: ZLIB(yes/no), SSL(yes/no)'
print '----------------'
for try_server in SERVERS:
  for genpydir in generated_dirs:
    for try_proto in PROTOS:
      for with_zlib in (False, True):
        # skip any servers that don't work with the Zlib transport
        if with_zlib and try_server in SKIP_ZLIB:
          continue
        for with_ssl in (False, True):
          # skip any servers that don't work with SSL
          if with_ssl and try_server in SKIP_SSL:
            continue
          test_count += 1
          if options.verbose > 0:
            print '\nTest run #%d:  (includes %s) Server=%s,  Proto=%s,  zlib=%s,  SSL=%s' % (test_count, genpydir, try_server, try_proto, with_zlib, with_ssl)
          runServiceTest(genpydir, try_server, try_proto, options.port, with_zlib, with_ssl)
          if options.verbose > 0:
            print 'OK: Finished (includes %s)  %s / %s proto / zlib=%s / SSL=%s.   %d combinations tested.' % (genpydir, try_server, try_proto, with_zlib, with_ssl, test_count)
