#
#
# 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.
#
#
"""
Driver for running the tests on Windows.

For a list of options, run this script with the --help option.
"""

# $HeadURL$
# $LastChangedRevision$

import os, sys, subprocess
import filecmp
import shutil
import traceback
import logging
import re
try:
  # Python >=3.0
  import configparser
except ImportError:
  # Python <3.0
  import ConfigParser as configparser
import string
import random

import getopt
try:
    my_getopt = getopt.gnu_getopt
except AttributeError:
    my_getopt = getopt.getopt

def _usage_exit():
  "print usage, exit the script"

  print("Driver for running the tests on Windows.")
  print("Usage: python win-tests.py [option] [test-path]")
  print("")
  print("Valid options:")
  print("  -r, --release          : test the Release configuration")
  print("  -d, --debug            : test the Debug configuration (default)")
  print("  --bin=PATH             : use the svn binaries installed in PATH")
  print("  -u URL, --url=URL      : run ra_dav or ra_svn tests against URL;")
  print("                           will start svnserve for ra_svn tests")
  print("  -v, --verbose          : talk more")
  print("  -f, --fs-type=type     : filesystem type to use (fsfs is default)")
  print("  -c, --cleanup          : cleanup after running a test")
  print("  -t, --test=TEST        : Run the TEST test (all is default); use")
  print("                           TEST#n to run a particular test number,")
  print("                           multiples also accepted e.g. '2,4-7'")
  print("  --log-level=LEVEL      : Set log level to LEVEL (E.g. DEBUG)")
  print("  --log-to-stdout        : Write log results to stdout")

  print("  --svnserve-args=list   : comma-separated list of arguments for")
  print("                           svnserve")
  print("                           default is '-d,-r,<test-path-root>'")
  print("  --asp.net-hack         : use '_svn' instead of '.svn' for the admin")
  print("                           dir name")
  print("  --httpd-dir            : location where Apache HTTPD is installed")
  print("  --httpd-port           : port for Apache HTTPD; random port number")
  print("                           will be used, if not specified")
  print("  --httpd-daemon         : Run Apache httpd as daemon")
  print("  --httpd-service        : Run Apache httpd as Windows service (default)")
  print("  --httpd-no-log         : Disable httpd logging")
  print("  --http-short-circuit   : Use SVNPathAuthz short_circuit on HTTP server")
  print("  --disable-http-v2      : Do not advertise support for HTTPv2 on server")
  print("  --disable-bulk-updates : Disable bulk updates on HTTP server")
  print("  --ssl-cert             : Path to SSL server certificate to trust.")
  print("  --https                : Run Apache httpd with an https setup.")
  print("  --http2                : Enable http2 in Apache Httpd (>= 2.4.17).")
  print("  --mod-deflate          : Enable mod_deflate in Apache Httpd.")
  print("  --global-scheduler     : Enable global scheduler.")
  print("  --exclusive-wc-locks   : Enable exclusive working copy locks")
  print("  --memcached-dir=DIR    : Run memcached from dir")
  print("  --memcached-server=    : Enable usage of the specified memcached server")
  print("              <url:port>")
  print("  --skip-c-tests         : Skip all C tests")
  print("  --dump-load-cross-check: Run the dump load cross check after every test")

  print("  --javahl               : Run the javahl tests instead of the normal tests")
  print("  --swig=language        : Run the swig perl/python/ruby tests instead of")
  print("                           the normal tests")
  print("  --list                 : print test doc strings only")
  print("  --milestone-filter=RE  : RE is a regular expression pattern that (when")
  print("                           used with --list) limits the tests listed to")
  print("                           those with an associated issue in the tracker")
  print("                           which has a target milestone that matches RE.")
  print("  --mode-filter=TYPE     : limit tests to expected TYPE = XFAIL, SKIP, PASS,")
  print("                           or 'ALL' (default)")
  print("  --enable-sasl          : enable Cyrus SASL authentication for")
  print("                           svnserve")
  print("  -p, --parallel         : run multiple tests in parallel")
  print("  --server-minor-version : the minor version of the server being")
  print("                           tested")
  print("  --config-file          : Configuration file for tests")
  print("  --fsfs-sharding        : Specify shard size (for fsfs)")
  print("  --fsfs-packing         : Run 'svnadmin pack' automatically")
  print("  --fsfs-compression=VAL : Set compression type to VAL (for fsfs)")
  print("  -q, --quiet            : Deprecated; this is the default.")
  print("                           Use --set-log-level instead.")

  sys.exit(0)

CMDLINE_TEST_SCRIPT_PATH = 'subversion/tests/cmdline/'
CMDLINE_TEST_SCRIPT_NATIVE_PATH = CMDLINE_TEST_SCRIPT_PATH.replace('/', os.sep)

sys.path.insert(0, os.path.join('build', 'generator'))
sys.path.insert(1, 'build')

import gen_win_dependencies
import gen_base
version_header = os.path.join('subversion', 'include', 'svn_version.h')
cp = configparser.ConfigParser()
cp.read('gen-make.opts')
gen_obj = gen_win_dependencies.GenDependenciesBase('build.conf', version_header,
                                                   cp.items('options'))
opts, args = my_getopt(sys.argv[1:], 'hrdvqct:pu:f:',
                       ['release', 'debug', 'verbose', 'quiet', 'cleanup',
                        'test=', 'url=', 'svnserve-args=', 'fs-type=', 'asp.net-hack',
                        'httpd-dir=', 'httpd-port=', 'httpd-daemon', 'https',
                        'httpd-server', 'http-short-circuit', 'httpd-no-log',
                        'disable-http-v2', 'disable-bulk-updates', 'help',
                        'fsfs-packing', 'fsfs-sharding=', 'javahl', 'swig=',
                        'list', 'enable-sasl', 'bin=', 'parallel', 'http2',
                        'mod-deflate', 'global-scheduler',
                        'config-file=', 'server-minor-version=', 'log-level=',
                        'log-to-stdout', 'mode-filter=', 'milestone-filter=',
                        'ssl-cert=', 'exclusive-wc-locks', 'memcached-server=',
                        'skip-c-tests', 'dump-load-cross-check', 'memcached-dir=',
                        'fsfs-compression=',
                        ])
if len(args) > 1:
  print('Warning: non-option arguments after the first one will be ignored')

# Interpret the options and set parameters
base_url, fs_type, verbose, cleanup = None, None, None, None
global_scheduler = None
repo_loc = 'local repository.'
objdir = 'Debug'
log = 'tests.log'
faillog = 'fails.log'
run_svnserve = None
svnserve_args = None
run_httpd = None
httpd_port = None
httpd_service = None
httpd_no_log = None
use_ssl = False
use_http2 = False
use_mod_deflate = False
http_short_circuit = False
advertise_httpv2 = True
http_bulk_updates = True
list_tests = None
milestone_filter = None
test_javahl = None
test_swig = None
enable_sasl = None
svn_bin = None
parallel = None
fsfs_sharding = None
fsfs_packing = None
server_minor_version = None
config_file = None
log_to_stdout = None
mode_filter=None
tests_to_run = []
log_level = None
ssl_cert = None
exclusive_wc_locks = None
run_memcached = None
memcached_server = None
memcached_dir = None
skip_c_tests = None
dump_load_cross_check = None
fsfs_compression = None
fsfs_dir_deltification = None

for opt, val in opts:
  if opt in ('-h', '--help'):
    _usage_exit()
  elif opt in ('-u', '--url'):
    base_url = val
  elif opt in ('-f', '--fs-type'):
    fs_type = val
  elif opt in ('-v', '--verbose'):
    verbose = 1
    log_level = logging.DEBUG
  elif opt in ('-c', '--cleanup'):
    cleanup = 1
  elif opt in ('-t', '--test'):
    tests_to_run.append(val)
  elif opt in ['-r', '--release']:
    objdir = 'Release'
  elif opt in ['-d', '--debug']:
    objdir = 'Debug'
  elif opt == '--svnserve-args':
    svnserve_args = val.split(',')
    run_svnserve = 1
  elif opt == '--asp.net-hack':
    os.environ['SVN_ASP_DOT_NET_HACK'] = opt
  elif opt == '--httpd-dir':
    abs_httpd_dir = os.path.abspath(val)
    run_httpd = 1
  elif opt == '--httpd-port':
    httpd_port = int(val)
  elif opt == '--httpd-daemon':
    httpd_service = 0
  elif opt == '--httpd-service':
    httpd_service = 1
  elif opt == '--httpd-no-log':
    httpd_no_log = 1
  elif opt == '--https':
    use_ssl = 1
  elif opt == '--http2':
    use_http2 = 1
  elif opt == '--mod-deflate':
    use_mod_deflate = 1
  elif opt == '--http-short-circuit':
    http_short_circuit = True
  elif opt == '--disable-http-v2':
    advertise_httpv2 = False
  elif opt == '--disable-bulk-updates':
    http_bulk_updates = False
  elif opt == '--fsfs-sharding':
    fsfs_sharding = int(val)
  elif opt == '--fsfs-packing':
    fsfs_packing = 1
  elif opt == '--javahl':
    test_javahl = 1
  elif opt == '--global-scheduler':
    global_scheduler = 1
  elif opt == '--swig':
    if val not in ['perl', 'python', 'ruby']:
      sys.stderr.write('Running \'%s\' swig tests not supported (yet).\n'
                        % (val,))
    test_swig = val
  elif opt == '--list':
    list_tests = 1
  elif opt == '--milestone-filter':
    milestone_filter = val
  elif opt == '--mode-filter':
    mode_filter = val
  elif opt == '--enable-sasl':
    enable_sasl = 1
    base_url = "svn://localhost/"
  elif opt == '--server-minor-version':
    server_minor_version = int(val)
  elif opt == '--bin':
    svn_bin = val
  elif opt in ('-p', '--parallel'):
    parallel = 1
  elif opt in ('--config-file'):
    config_file = val
  elif opt == '--log-to-stdout':
    log_to_stdout = 1
  elif opt == '--log-level':
    log_level = getattr(logging, val, None) or int(val)
  elif opt == '--ssl-cert':
    ssl_cert = val
  elif opt == '--exclusive-wc-locks':
    exclusive_wc_locks = 1
  elif opt == '--memcached-server':
    memcached_server = val
  elif opt == '--skip-c-tests':
    skip_c_tests = 1
  elif opt == '--dump-load-cross-check':
    dump_load_cross_check = 1
  elif opt == '--memcached-dir':
    memcached_dir = val
    run_memcached = 1
  elif opt == '--fsfs-compression':
    fsfs_compression = val
  elif opt == '--fsfs-dir-deltification':
    fsfs_dir_deltification = val

# Calculate the source and test directory names
abs_srcdir = os.path.abspath("")
abs_objdir = os.path.join(abs_srcdir, objdir)
if len(args) == 0:
  abs_builddir = abs_objdir
  create_dirs = 0
else:
  abs_builddir = os.path.abspath(args[0])
  create_dirs = 1

# Default to fsfs explicitly
if not fs_type:
  fs_type = 'fsfs'

if fs_type == 'bdb':
  all_tests = gen_obj.test_progs + gen_obj.bdb_test_progs \
            + gen_obj.scripts + gen_obj.bdb_scripts
else:
  all_tests = gen_obj.test_progs + gen_obj.scripts

client_tests = [x for x in all_tests if x.startswith(CMDLINE_TEST_SCRIPT_PATH)]

if run_httpd:
  if not httpd_port:
    httpd_port = random.randrange(1024, 30000)
  if not base_url:
    if use_ssl:
      scheme = 'https'
    else:
      scheme = 'http'

    base_url = '%s://localhost:%d' % (scheme, httpd_port)

if base_url:
  repo_loc = 'remote repository ' + base_url + '.'
  if base_url[:4] == 'http':
    log = 'dav-tests.log'
    faillog = 'dav-fails.log'
  elif base_url[:3] == 'svn':
    log = 'svn-tests.log'
    faillog = 'svn-fails.log'
    run_svnserve = 1
  else:
    # Don't know this scheme, but who're we to judge whether it's
    # correct or not?
    log = 'url-tests.log'
    faillog = 'url-fails.log'

# Have to move the executables where the tests expect them to be
copied_execs = []   # Store copied exec files to avoid the final dir scan

def create_target_dir(dirname):
  tgt_dir = os.path.join(abs_builddir, dirname)
  if not os.path.exists(tgt_dir):
    if verbose:
      print("mkdir: %s" % tgt_dir)
    os.makedirs(tgt_dir)

def copy_changed_file(src, tgt=None, to_dir=None, cleanup=True):
  if not os.path.isfile(src):
    print('Could not find ' + src)
    sys.exit(1)

  if to_dir and not tgt:
    tgt = os.path.join(to_dir, os.path.basename(src))
  elif not tgt or (tgt and to_dir):
    raise RuntimeError("Using 'tgt' *or* 'to_dir' is required" % (tgt,))
  elif tgt and os.path.isdir(tgt):
    raise RuntimeError("'%s' is a directory. Use to_dir=" % (tgt,))

  if os.path.exists(tgt):
    assert os.path.isfile(tgt)
    if filecmp.cmp(src, tgt):
      if verbose:
        print("same: %s" % src)
        print(" and: %s" % tgt)
      return 0
  if verbose:
    print("copy: %s" % src)
    print("  to: %s" % tgt)
  shutil.copy(src, tgt)

  if cleanup:
    copied_execs.append(tgt)

def locate_libs():
  "Move DLLs to a known location and set env vars"

  debug = (objdir == 'Debug')

  for lib in gen_obj._libraries.values():

    if debug:
      name, dir = lib.debug_dll_name, lib.debug_dll_dir
    else:
      name, dir = lib.dll_name, lib.dll_dir

    if name and dir:
      src = os.path.join(dir, name)
      if os.path.exists(src):
        copy_changed_file(src, to_dir=abs_builddir, cleanup=False)

    for name in lib.extra_bin:
      src = os.path.join(dir, name)
      copy_changed_file(src, to_dir=abs_builddir)


  # Copy the Subversion library DLLs
  for i in gen_obj.graph.get_all_sources(gen_base.DT_INSTALL):
    if isinstance(i, gen_base.TargetLib) and i.msvc_export:
      src = os.path.join(abs_objdir, i.filename)
      if os.path.isfile(src):
        copy_changed_file(src, to_dir=abs_builddir,
                          cleanup=False)

  # Copy the Apache modules
  if run_httpd and cp.has_option('options', '--with-httpd'):
    mod_dav_svn_path = os.path.join(abs_objdir, 'subversion',
                                    'mod_dav_svn', 'mod_dav_svn.so')
    mod_authz_svn_path = os.path.join(abs_objdir, 'subversion',
                                      'mod_authz_svn', 'mod_authz_svn.so')
    mod_dontdothat_path = os.path.join(abs_objdir, 'tools', 'server-side',
                                        'mod_dontdothat', 'mod_dontdothat.so')

    copy_changed_file(mod_dav_svn_path, to_dir=abs_builddir, cleanup=False)
    copy_changed_file(mod_authz_svn_path, to_dir=abs_builddir, cleanup=False)
    copy_changed_file(mod_dontdothat_path, to_dir=abs_builddir, cleanup=False)

  os.environ['PATH'] = abs_builddir + os.pathsep + os.environ['PATH']

def fix_case(path):
    path = os.path.normpath(path)
    parts = path.split(os.path.sep)
    drive = parts[0].upper()
    parts = parts[1:]
    path = drive + os.path.sep
    for part in parts:
        dirs = os.listdir(path)
        for dir in dirs:
            if dir.lower() == part.lower():
                path = os.path.join(path, dir)
                break
    return path

class Svnserve:
  "Run svnserve for ra_svn tests"
  def __init__(self, svnserve_args, objdir, abs_objdir, abs_builddir):
    self.args = svnserve_args
    self.name = 'svnserve.exe'
    self.kind = objdir
    self.path = os.path.join(abs_objdir,
                             'subversion', 'svnserve', self.name)
    self.root = os.path.join(abs_builddir, CMDLINE_TEST_SCRIPT_NATIVE_PATH)
    self.proc = None

  def __del__(self):
    "Stop svnserve when the object is deleted"
    self.stop()

  def _quote(self, arg):
    if ' ' in arg:
      return '"' + arg + '"'
    else:
      return arg

  def start(self):
    if not self.args:
      args = [self.name, '-d', '-r', self.root]
    else:
      args = [self.name] + self.args
    print('Starting %s %s' % (self.kind, self.name))

    env = os.environ.copy()
    env['SVN_DBG_STACKTRACES_TO_STDERR'] = 'y'
    self.proc = subprocess.Popen([self.path] + args[1:], env=env)

  def stop(self):
    if self.proc is not None:
      try:
        print('Stopping %s' % self.name)
        self.proc.poll();
        if self.proc.returncode is None:
          self.proc.kill();
        return
      except AttributeError:
        pass
    print('Svnserve.stop not implemented')

class Httpd:
  "Run httpd for DAV tests"
  def __init__(self, abs_httpd_dir, abs_objdir, abs_builddir, abs_srcdir,
               httpd_port, service, use_ssl, use_http2, use_mod_deflate,
               no_log, httpv2, short_circuit, bulk_updates):
    self.name = 'apache.exe'
    self.httpd_port = httpd_port
    self.httpd_dir = abs_httpd_dir

    if httpv2:
      self.httpv2_option = 'on'
    else:
      self.httpv2_option = 'off'

    if bulk_updates:
      self.bulkupdates_option = 'on'
    else:
      self.bulkupdates_option = 'off'

    self.service = service
    self.proc = None
    self.path = os.path.join(self.httpd_dir, 'bin', self.name)

    if short_circuit:
      self.path_authz_option = 'short_circuit'
    else:
      self.path_authz_option = 'on'

    if not os.path.exists(self.path):
      self.name = 'httpd.exe'
      self.path = os.path.join(self.httpd_dir, 'bin', self.name)
      if not os.path.exists(self.path):
        raise RuntimeError("Could not find a valid httpd binary!")

    self.root_dir = os.path.join(CMDLINE_TEST_SCRIPT_NATIVE_PATH, 'httpd')
    self.root = os.path.join(abs_builddir, self.root_dir)
    self.authz_file = os.path.join(abs_builddir,
                                   CMDLINE_TEST_SCRIPT_NATIVE_PATH,
                                   'svn-test-work', 'authz')
    self.dontdothat_file = os.path.join(abs_builddir,
                                         CMDLINE_TEST_SCRIPT_NATIVE_PATH,
                                         'svn-test-work', 'dontdothat')
    self.certfile = os.path.join(abs_builddir,
                                 CMDLINE_TEST_SCRIPT_NATIVE_PATH,
                                 'svn-test-work', 'cert.pem')
    self.certkeyfile = os.path.join(abs_builddir,
                                     CMDLINE_TEST_SCRIPT_NATIVE_PATH,
                                     'svn-test-work', 'cert-key.pem')
    self.httpd_config = os.path.join(self.root, 'httpd.conf')
    self.httpd_users = os.path.join(self.root, 'users')
    self.httpd_mime_types = os.path.join(self.root, 'mime.types')
    self.httpd_groups = os.path.join(self.root, 'groups')
    self.abs_builddir = abs_builddir
    self.abs_objdir = abs_objdir
    self.abs_srcdir = abs_srcdir
    self.service_name = 'svn-test-httpd-' + str(httpd_port)

    if self.service:
      self.httpd_args = [self.name, '-n', self._quote(self.service_name),
                         '-f', self._quote(self.httpd_config)]
    else:
      self.httpd_args = [self.name, '-f', self._quote(self.httpd_config)]

    create_target_dir(self.root_dir)

    self._create_users_file()
    self._create_groups_file()
    self._create_mime_types_file()
    self._create_dontdothat_file()

    if use_ssl:
      self._create_cert_files()

    # Obtain version.
    version_vals = gen_obj._libraries['httpd'].version.split('.')
    self.httpd_ver = float('%s.%s' % (version_vals[0], version_vals[1]))

    # Create httpd config file
    fp = open(self.httpd_config, 'w')

    # Limit the number of threads (default = 64)
    if not use_http2:
      fp.write('<IfModule mpm_winnt.c>\n')
      fp.write('ThreadsPerChild 16\n')
      fp.write('</IfModule>\n')

    # Global Environment
    fp.write('ServerRoot   ' + self._quote(self.root) + '\n')
    fp.write('DocumentRoot ' + self._quote(self.root) + '\n')
    fp.write('ServerName   localhost\n')
    fp.write('PidFile      pid\n')
    fp.write('ErrorLog     log\n')
    fp.write('Listen       ' + str(self.httpd_port) + '\n')

    if not no_log:
      fp.write('LogFormat    "%h %l %u %t \\"%r\\" %>s %b" common\n')
      fp.write('Customlog    log common\n')
      fp.write('LogLevel     Debug\n')
    else:
      fp.write('LogLevel     Crit\n')

    # Write LoadModule for minimal system module
    if use_ssl:
      fp.write(self._sys_module('ssl_module', 'mod_ssl.so'))
    if use_http2:
      fp.write(self._sys_module('http2_module', 'mod_http2.so'))
    if use_mod_deflate:
      fp.write(self._sys_module('deflate_module', 'mod_deflate.so'))
    fp.write(self._sys_module('dav_module', 'mod_dav.so'))
    if self.httpd_ver >= 2.3:
      fp.write(self._sys_module('access_compat_module', 'mod_access_compat.so'))
      fp.write(self._sys_module('authz_core_module', 'mod_authz_core.so'))
      fp.write(self._sys_module('authz_user_module', 'mod_authz_user.so'))
      fp.write(self._sys_module('authn_core_module', 'mod_authn_core.so'))
    if self.httpd_ver >= 2.2:
      fp.write(self._sys_module('auth_basic_module', 'mod_auth_basic.so'))
      fp.write(self._sys_module('authn_file_module', 'mod_authn_file.so'))
      fp.write(self._sys_module('authz_groupfile_module', 'mod_authz_groupfile.so'))
      fp.write(self._sys_module('authz_host_module', 'mod_authz_host.so'))
    else:
      fp.write(self._sys_module('auth_module', 'mod_auth.so'))
    fp.write(self._sys_module('alias_module', 'mod_alias.so'))
    fp.write(self._sys_module('mime_module', 'mod_mime.so'))
    fp.write(self._sys_module('log_config_module', 'mod_log_config.so'))

    # Write LoadModule for Subversion modules
    fp.write(self._svn_module('dav_svn_module', 'mod_dav_svn.so'))
    fp.write(self._svn_module('authz_svn_module', 'mod_authz_svn.so'))

    # And for mod_dontdothat
    fp.write(self._svn_module('dontdothat_module', 'mod_dontdothat.so'))

    if use_ssl:
      fp.write('SSLEngine on\n')
      fp.write('SSLProtocol All -SSLv2 -SSLv3\n')
      fp.write('SSLCertificateFile %s\n' % self._quote(self.certfile))
      fp.write('SSLCertificateKeyFile %s\n' % self._quote(self.certkeyfile))

    if use_ssl and use_http2:
      fp.write('Protocols h2 http/1.1\n')
    elif use_http2:
      fp.write('Protocols h2c http/1.1\n')
      fp.write('H2Direct on\n')

    if use_mod_deflate:
      fp.write('SetOutputFilter DEFLATE\n')

    # Don't handle .htaccess, symlinks, etc.
    fp.write('<Directory />\n')
    fp.write('AllowOverride None\n')
    fp.write('Options None\n')
    fp.write('</Directory>\n\n')

    # Define two locations for repositories
    fp.write(self._svn_repo('repositories'))
    fp.write(self._svn_repo('local_tmp'))
    fp.write(self._svn_authz_repo())

    # And two redirects for the redirect tests
    fp.write('RedirectMatch permanent ^/svn-test-work/repositories/'
             'REDIRECT-PERM-(.*)$ /svn-test-work/repositories/$1\n')
    fp.write('RedirectMatch           ^/svn-test-work/repositories/'
             'REDIRECT-TEMP-(.*)$ /svn-test-work/repositories/$1\n')

    fp.write('TypesConfig     ' + self._quote(self.httpd_mime_types) + '\n')
    fp.write('HostNameLookups Off\n')

    fp.close()

  def __del__(self):
    "Stop httpd when the object is deleted"
    self.stop()

  def _quote(self, arg):
    if ' ' in arg:
      return '"' + arg + '"'
    else:
      return arg

  def _create_users_file(self):
    "Create users file"
    htpasswd = os.path.join(self.httpd_dir, 'bin', 'htpasswd.exe')
    # Create the cheapest to compare password form for our testsuite
    os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bcp', self.httpd_users,
                                    'jrandom', 'rayjandom'])
    os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp',  self.httpd_users,
                                    'jconstant', 'rayjandom'])
    os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp',  self.httpd_users,
                                    '__dumpster__', '__loadster__'])
    os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp',  self.httpd_users,
                                    'JRANDOM', 'rayjandom'])
    os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp',  self.httpd_users,
                                    'JCONSTANT', 'rayjandom'])

  def _create_groups_file(self):
    "Create groups for mod_authz_svn tests"
    fp = open(self.httpd_groups, 'w')
    fp.write('random: jrandom\n')
    fp.write('constant: jconstant\n')
    fp.close()

  def _create_mime_types_file(self):
    "Create empty mime.types file"
    fp = open(self.httpd_mime_types, 'w')
    fp.close()

  def _create_dontdothat_file(self):
    "Create empty mime.types file"
    # If the tests have not previously been run or were cleaned
    # up, then 'svn-test-work' does not exist yet.
    parent_dir = os.path.dirname(self.dontdothat_file)
    if not os.path.exists(parent_dir):
      os.makedirs(parent_dir)

    fp = open(self.dontdothat_file, 'w')
    fp.write('[recursive-actions]\n')
    fp.write('/ = deny\n')
    fp.close()

  def _create_cert_files(self):
    "Create certificate files"
    # The unix build uses certificates encoded in davautocheck.sh
    # Let's just read them from there

    sh_path = os.path.join(self.abs_srcdir, 'subversion', 'tests', 'cmdline',
                           'davautocheck.sh')
    sh = open(sh_path).readlines()

    def cert_extract(lines, what):
      r = []
      pattern = r'cat\s*\>\s*' + re.escape(what) + r'\s*\<\<([A-Z_a-z0-9]+)'
      exit_marker = None
      for i in lines:
        if exit_marker:
          if i.startswith(exit_marker):
            return r
          r.append(i)
        else:
          m = re.match(pattern, i)
          if m:
            exit_marker = m.groups(1)

    cert_file = cert_extract(sh, '"$SSL_CERTIFICATE_FILE"')
    cert_key = cert_extract(sh, '"$SSL_CERTIFICATE_KEY_FILE"')
    open(self.certfile, 'w').write(''.join(cert_file))
    open(self.certkeyfile, 'w').write(''.join(cert_key))

  def _sys_module(self, name, path):
    full_path = os.path.join(self.httpd_dir, 'modules', path)
    return 'LoadModule ' + name + " " + self._quote(full_path) + '\n'

  def _svn_module(self, name, path):
    full_path = os.path.join(self.abs_builddir, path)
    return 'LoadModule ' + name + ' ' + self._quote(full_path) + '\n'

  def _svn_repo(self, name):
    path = os.path.join(self.abs_builddir,
                        CMDLINE_TEST_SCRIPT_NATIVE_PATH,
                        'svn-test-work', name)
    location = '/svn-test-work/' + name
    ddt_location = '/ddt-test-work/' + name
    return \
      '<Location ' + location + '>\n' \
      '  DAV             svn\n' \
      '  SVNParentPath   ' + self._quote(path) + '\n' \
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
      '  SVNAllowBulkUpdates ' + self.bulkupdates_option + '\n' \
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
      '  AuthType        Basic\n' \
      '  AuthName        "Subversion Repository"\n' \
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
      '  Require         valid-user\n' \
      '</Location>\n' \
      '<Location ' + ddt_location + '>\n' \
      '  DAV             svn\n' \
      '  SVNParentPath   ' + self._quote(path) + '\n' \
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
      '  SVNAllowBulkUpdates ' + self.bulkupdates_option + '\n' \
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
      '  AuthType        Basic\n' \
      '  AuthName        "Subversion Repository"\n' \
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
      '  Require         valid-user\n' \
      '  DontDoThatConfigFile ' + self._quote(self.dontdothat_file) + '\n' \
      '</Location>\n'

  def _svn_authz_repo(self):
    local_tmp = os.path.join(self.abs_builddir,
                             CMDLINE_TEST_SCRIPT_NATIVE_PATH,
                             'svn-test-work', 'local_tmp')
    repositories = os.path.join(self.abs_builddir,
                                CMDLINE_TEST_SCRIPT_NATIVE_PATH,
                                'svn-test-work', 'repositories')
    return \
      '<Location /authz-test-work/anon>' + '\n' \
      '  DAV               svn' + '\n' \
      '  SVNParentPath     ' + local_tmp + '\n' \
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
      '  SVNListParentPath On' + '\n' \
      '  <IfModule mod_authz_core.c>' + '\n' \
      '    Require all granted' + '\n' \
      '  </IfModule>' + '\n' \
      '  <IfModule !mod_authz_core.c>' + '\n' \
      '    Allow from all' + '\n' \
      '  </IfModule>' + '\n' \
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
      '</Location>' + '\n' \
      '<Location /authz-test-work/in-repos-authz>' + '\n' \
      '  DAV               svn' + '\n' \
      '  SVNParentPath     ' + repositories + '\n' \
      '  AuthzSVNReposRelativeAccessFile "^/authz"\n' \
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
      '  AuthType          Basic' + '\n' \
      '  AuthName          "Subversion Repository"' + '\n' \
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
      '  Require           valid-user' + '\n' \
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
      '</Location>' + '\n' \
      '<Location /authz-test-work/mixed>' + '\n' \
      '  DAV               svn' + '\n' \
      '  SVNParentPath     ' + local_tmp + '\n' \
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
      '  SVNListParentPath On' + '\n' \
      '  AuthType          Basic' + '\n' \
      '  AuthName          "Subversion Repository"' + '\n' \
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
      '  Require           valid-user' + '\n' \
      '  Satisfy Any' + '\n' \
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
      '</Location>' + '\n' \
      '<Location /authz-test-work/mixed-noauthwhenanon>' + '\n' \
      '  DAV               svn' + '\n' \
      '  SVNParentPath     ' + local_tmp + '\n' \
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
      '  SVNListParentPath On' + '\n' \
      '  AuthType          Basic' + '\n' \
      '  AuthName          "Subversion Repository"' + '\n' \
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
      '  Require           valid-user' + '\n' \
      '  AuthzSVNNoAuthWhenAnonymousAllowed On' + '\n' \
      '  SVNPathAuthz On' + '\n' \
      '</Location>' + '\n' \
      '<Location /authz-test-work/authn>' + '\n' \
      '  DAV               svn' + '\n' \
      '  SVNParentPath     ' + local_tmp + '\n' \
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
      '  SVNListParentPath On' + '\n' \
      '  AuthType          Basic' + '\n' \
      '  AuthName          "Subversion Repository"' + '\n' \
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
      '  Require           valid-user' + '\n' \
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
      '</Location>' + '\n' \
      '<Location /authz-test-work/authn-anonoff>' + '\n' \
      '  DAV               svn' + '\n' \
      '  SVNParentPath     ' + local_tmp + '\n' \
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
      '  SVNListParentPath On' + '\n' \
      '  AuthType          Basic' + '\n' \
      '  AuthName          "Subversion Repository"' + '\n' \
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
      '  Require           valid-user' + '\n' \
      '  AuthzSVNAnonymous Off' + '\n' \
      '  SVNPathAuthz On' + '\n' \
      '</Location>' + '\n' \
      '<Location /authz-test-work/authn-lcuser>' + '\n' \
      '  DAV               svn' + '\n' \
      '  SVNParentPath     ' + local_tmp + '\n' \
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
      '  SVNListParentPath On' + '\n' \
      '  AuthType          Basic' + '\n' \
      '  AuthName          "Subversion Repository"' + '\n' \
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
      '  Require           valid-user' + '\n' \
      '  AuthzForceUsernameCase Lower' + '\n' \
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
      '</Location>' + '\n' \
      '<Location /authz-test-work/authn-lcuser>' + '\n' \
      '  DAV               svn' + '\n' \
      '  SVNParentPath     ' + local_tmp + '\n' \
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
      '  SVNListParentPath On' + '\n' \
      '  AuthType          Basic' + '\n' \
      '  AuthName          "Subversion Repository"' + '\n' \
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
      '  Require           valid-user' + '\n' \
      '  AuthzForceUsernameCase Lower' + '\n' \
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
      '</Location>' + '\n' \
      '<Location /authz-test-work/authn-group>' + '\n' \
      '  DAV               svn' + '\n' \
      '  SVNParentPath     ' + local_tmp + '\n' \
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
      '  SVNListParentPath On' + '\n' \
      '  AuthType          Basic' + '\n' \
      '  AuthName          "Subversion Repository"' + '\n' \
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
      '  AuthGroupFile    ' + self._quote(self.httpd_groups) + '\n' \
      '  Require           group random' + '\n' \
      '  AuthzSVNAuthoritative Off' + '\n' \
      '  SVNPathAuthz On' + '\n' \
      '</Location>' + '\n' \
      '<IfModule mod_authz_core.c>' + '\n' \
      '<Location /authz-test-work/sallrany>' + '\n' \
      '  DAV               svn' + '\n' \
      '  SVNParentPath     ' + local_tmp + '\n' \
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
      '  SVNListParentPath On' + '\n' \
      '  AuthType          Basic' + '\n' \
      '  AuthName          "Subversion Repository"' + '\n' \
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
      '  AuthzSendForbiddenOnFailure On' + '\n' \
      '  Satisfy All' + '\n' \
      '  <RequireAny>' + '\n' \
      '    Require valid-user' + '\n' \
      '    Require expr req(\'ALLOW\') == \'1\'' + '\n' \
      '  </RequireAny>' + '\n' \
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
      '</Location>' + '\n' \
      '<Location /authz-test-work/sallrall>'+ '\n' \
      '  DAV               svn' + '\n' \
      '  SVNParentPath     ' + local_tmp + '\n' \
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
      '  SVNListParentPath On' + '\n' \
      '  AuthType          Basic' + '\n' \
      '  AuthName          "Subversion Repository"' + '\n' \
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
      '  AuthzSendForbiddenOnFailure On' + '\n' \
      '  Satisfy All' + '\n' \
      '  <RequireAll>' + '\n' \
      '    Require valid-user' + '\n' \
      '    Require expr req(\'ALLOW\') == \'1\'' + '\n' \
      '  </RequireAll>' + '\n' \
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
      '</Location>' + '\n' \
      '</IfModule>' + '\n' \

  def start(self):
    if self.service:
      self._start_service()
    else:
      self._start_daemon()

    # Avoid output from starting and preparing between test results
    sys.stderr.flush()
    sys.stdout.flush()

  def stop(self):
    if self.service:
      self._stop_service()
    else:
      self._stop_daemon()

  def _start_service(self):
    "Install and start HTTPD service"
    print('Installing service %s' % self.service_name)
    os.spawnv(os.P_WAIT, self.path, self.httpd_args + ['-k', 'install'])
    print('Starting service %s' % self.service_name)
    os.spawnv(os.P_WAIT, self.path, self.httpd_args + ['-k', 'start'])

  def _stop_service(self):
    "Stop and uninstall HTTPD service"
    os.spawnv(os.P_WAIT, self.path, self.httpd_args + ['-k', 'stop'])
    os.spawnv(os.P_WAIT, self.path, self.httpd_args + ['-k', 'uninstall'])

  def _start_daemon(self):
    "Start HTTPD as daemon"
    print('Starting httpd as daemon')
    print(self.httpd_args)
    self.proc = subprocess.Popen([self.path] + self.httpd_args[1:])

  def _stop_daemon(self):
    "Stop the HTTPD daemon"
    if self.proc is not None:
      try:
        print('Stopping %s' % self.name)
        self.proc.poll();
        if self.proc.returncode is None:
          self.proc.kill();
        return
      except AttributeError:
        pass
    print('Httpd.stop_daemon not implemented')

class Memcached:
  "Run memcached for tests"
  def __init__(self, abs_memcached_dir, memcached_server):
    self.name = 'memcached.exe'

    self.memcached_host, self.memcached_port = memcached_server.split(':')
    self.memcached_dir = abs_memcached_dir

    self.proc = None
    self.path = os.path.join(self.memcached_dir, self.name)

    self.memcached_args = [
                            self.name,
                            '-p', self.memcached_port,
                            '-l', self.memcached_host
                          ]

  def __del__(self):
    "Stop memcached when the object is deleted"
    self.stop()

  def start(self):
    "Start memcached as daemon"
    print('Starting %s as daemon' % self.name)
    print(self.memcached_args)
    self.proc = subprocess.Popen([self.path] + self.memcached_args)

  def stop(self):
    "Stop memcached"
    if self.proc is not None:
      try:
        print('Stopping %s' % self.name)
        self.proc.poll();
        if self.proc.returncode is None:
          self.proc.kill();
        return
      except AttributeError:
        pass

# Move the binaries to the test directory
create_target_dir(abs_builddir)
locate_libs()
if create_dirs:
  for i in gen_obj.graph.get_all_sources(gen_base.DT_INSTALL):
    if isinstance(i, gen_base.TargetExe):
      src = os.path.join(abs_objdir, i.filename)

      if os.path.isfile(src):
        dst = os.path.join(abs_builddir, i.filename)
        create_target_dir(os.path.dirname(dst))
        copy_changed_file(src, dst)

# Create the base directory for Python tests
create_target_dir(CMDLINE_TEST_SCRIPT_NATIVE_PATH)

# Ensure the tests directory is correctly cased
abs_builddir = fix_case(abs_builddir)

failed = None
daemon = None
memcached = None
# Run the tests

# No need to start any servers if we are only listing the tests.
if not list_tests:
  if run_memcached:
    memcached = Memcached(memcached_dir, memcached_server)
    memcached.start()

  if run_svnserve:
    daemon = Svnserve(svnserve_args, objdir, abs_objdir, abs_builddir)

  if run_httpd:
    daemon = Httpd(abs_httpd_dir, abs_objdir, abs_builddir, abs_srcdir,
                   httpd_port, httpd_service, use_ssl, use_http2,
                   use_mod_deflate, httpd_no_log, advertise_httpv2,
                   http_short_circuit, http_bulk_updates)

    if use_ssl and not ssl_cert:
      ssl_cert = daemon.certfile

  # Start service daemon, if any
  if daemon:
    daemon.start()

# Find the full path and filename of any test that is specified just by
# its base name.
if len(tests_to_run) != 0:
  tests = []
  for t in tests_to_run:
    tns = None
    if '#' in t:
      t, tns = t.split('#')

    test = [x for x in all_tests if x.split('/')[-1] == t]
    if not test and not (t.endswith('-test.exe') or t.endswith('_tests.py')):
      # The lengths of '-test.exe' and of '_tests.py' are both 9.
      test = [x for x in all_tests if x.split('/')[-1][:-9] == t]

    if not test:
      print("Skipping test '%s', test not found." % t)
    elif tns:
      tests.append('%s#%s' % (test[0], tns))
    else:
      tests.extend(test)

  tests_to_run = tests
else:
  tests_to_run = all_tests


if list_tests:
  print('Listing %s configuration on %s' % (objdir, repo_loc))
else:
  print('Testing %s configuration on %s' % (objdir, repo_loc))
sys.path.insert(0, os.path.join(abs_srcdir, 'build'))

if not test_javahl and not test_swig:
  import run_tests
  if log_to_stdout:
    log_file = None
    fail_log_file = None
  else:
    log_file = os.path.join(abs_builddir, log)
    fail_log_file = os.path.join(abs_builddir, faillog)

  if run_httpd:
    httpd_version = gen_obj._libraries['httpd'].version
  else:
    httpd_version = None

  opts, args = run_tests.create_parser().parse_args([])
  opts.url = base_url
  opts.fs_type = fs_type
  opts.global_scheduler = global_scheduler
  opts.http_library = 'serf'
  opts.server_minor_version = server_minor_version
  opts.cleanup = cleanup
  opts.enable_sasl = enable_sasl
  opts.parallel = parallel
  opts.config_file = config_file
  opts.fsfs_sharding = fsfs_sharding
  opts.fsfs_packing = fsfs_packing
  opts.list_tests = list_tests
  opts.svn_bin = svn_bin
  opts.mode_filter = mode_filter
  opts.milestone_filter = milestone_filter
  opts.httpd_version = httpd_version
  opts.set_log_level = log_level
  opts.ssl_cert = ssl_cert
  opts.exclusive_wc_locks = exclusive_wc_locks
  opts.memcached_server = memcached_server
  opts.skip_c_tests = skip_c_tests
  opts.dump_load_cross_check = dump_load_cross_check
  opts.fsfs_compression = fsfs_compression
  opts.fsfs_dir_deltification = fsfs_dir_deltification
  th = run_tests.TestHarness(abs_srcdir, abs_builddir,
                             log_file, fail_log_file, opts)
  old_cwd = os.getcwd()
  try:
    os.chdir(abs_builddir)
    failed = th.run(tests_to_run)
  except:
    os.chdir(old_cwd)
    raise
  else:
    os.chdir(old_cwd)
elif test_javahl:
  failed = False

  java_exe = None

  for path in os.environ["PATH"].split(os.pathsep):
    if os.path.isfile(os.path.join(path, 'java.exe')):
      java_exe = os.path.join(path, 'java.exe')
      break

  if not java_exe and 'java_sdk' in gen_obj._libraries:
    jdk = gen_obj._libraries['java_sdk']

    if os.path.isfile(os.path.join(jdk.lib_dir, '../bin/java.exe')):
      java_exe = os.path.join(jdk.lib_dir, '../bin/java.exe')

  if not java_exe:
    print('Java not found. Skipping Java tests')
  else:
    args = (os.path.abspath(java_exe),)
    if (objdir == 'Debug'):
      args = args + ('-Xcheck:jni',)

    if cleanup:
      args = args + ('-Dtest.cleanup=1',)

    args = args + (
            '-Dtest.rootdir=' + os.path.join(abs_builddir, 'javahl'),
            '-Dtest.srcdir=' + os.path.join(abs_srcdir,
                                            'subversion/bindings/javahl'),
            '-Dtest.rooturl=',
            '-Dtest.fstype=' + fs_type ,
            '-Dtest.tests=',

            '-Djava.library.path='
                      + os.path.join(abs_objdir,
                                     'subversion/bindings/javahl/native'),
            '-classpath',
            os.path.join(abs_srcdir, 'subversion/bindings/javahl/classes') +';' +
              gen_obj.junit_path
           )

    sys.stderr.flush()
    print('Running org.apache.subversion tests:')
    sys.stdout.flush()

    r = subprocess.call(args + tuple(['org.apache.subversion.javahl.RunTests']))
    sys.stdout.flush()
    sys.stderr.flush()
    if (r != 0):
      print('[Test runner reported failure]')
      failed = True

    print('Running org.tigris.subversion tests:')
    sys.stdout.flush()
    r = subprocess.call(args + tuple(['org.tigris.subversion.javahl.RunTests']))
    sys.stdout.flush()
    sys.stderr.flush()
    if (r != 0):
      print('[Test runner reported failure]')
      failed = True
elif test_swig == 'perl':
  failed = False
  swig_dir = os.path.join(abs_builddir, 'swig')
  swig_pl_dir = os.path.join(swig_dir, 'p5lib')
  swig_pl_svn = os.path.join(swig_pl_dir, 'SVN')
  swig_pl_auto_svn = os.path.join(swig_pl_dir, 'auto', 'SVN')

  create_target_dir(swig_pl_svn)

  for i in gen_obj.graph.get_all_sources(gen_base.DT_INSTALL):
    if isinstance(i, gen_base.TargetSWIG) and i.lang == 'perl':
      mod_dir = os.path.join(swig_pl_auto_svn, '_' + i.name[5:].capitalize())
      create_target_dir(mod_dir)
      copy_changed_file(os.path.join(abs_objdir, i.filename), to_dir=mod_dir)

    elif isinstance(i, gen_base.TargetSWIGLib) and i.lang == 'perl':
      copy_changed_file(os.path.join(abs_objdir, i.filename),
                        to_dir=abs_builddir)

  pm_src = os.path.join(abs_srcdir, 'subversion', 'bindings', 'swig', 'perl',
                        'native')

  tests = []

  for root, dirs, files in os.walk(pm_src):
    for name in files:
      if name.endswith('.pm'):
        fn = os.path.join(root, name)
        copy_changed_file(fn, to_dir=swig_pl_svn)
      elif name.endswith('.t'):
        tests.append(os.path.relpath(os.path.join(root, name), pm_src))

  perl5lib = swig_pl_dir
  if 'PERL5LIB' in os.environ:
    perl5lib += os.pathsep + os.environ['PERL5LIB']

  perl_exe = 'perl.exe'

  print('-- Running Swig Perl tests --')
  sys.stdout.flush()
  old_cwd = os.getcwd()
  try:
    os.chdir(pm_src)

    os.environ['PERL5LIB'] = perl5lib
    os.environ["SVN_DBG_NO_ABORT_ON_ERROR_LEAK"] = 'YES'

    r = subprocess.call([
              perl_exe,
              '-MExtUtils::Command::MM',
              '-e', 'test_harness()'
              ] + tests)
  finally:
    os.chdir(old_cwd)

  if (r != 0):
    print('[Test runner reported failure]')
    failed = True
elif test_swig == 'python':
  failed = False
  swig_dir = os.path.join(abs_builddir, 'swig')
  swig_py_dir = os.path.join(swig_dir, 'pylib')
  swig_py_libsvn = os.path.join(swig_py_dir, 'libsvn')
  swig_py_svn = os.path.join(swig_py_dir, 'svn')

  create_target_dir(swig_py_libsvn)
  create_target_dir(swig_py_svn)

  for i in gen_obj.graph.get_all_sources(gen_base.DT_INSTALL):
    if (isinstance(i, gen_base.TargetSWIG)
        or isinstance(i, gen_base.TargetSWIGLib)) and i.lang == 'python':

      src = os.path.join(abs_objdir, i.filename)
      basename = os.path.basename(src)
      if sys.version_info[:2] >= (3, 5) \
          and basename.endswith('.pyd') and objdir == 'Debug':
        basename = basename[:-4] + '_d.pyd'
      copy_changed_file(src, os.path.join(swig_py_libsvn, basename))

  py_src = os.path.join(abs_srcdir, 'subversion', 'bindings', 'swig', 'python')

  for py_file in os.listdir(py_src):
    if py_file.endswith('.py'):
      copy_changed_file(os.path.join(py_src, py_file),
                        to_dir=swig_py_libsvn)

  py_src_svn = os.path.join(py_src, 'svn')
  for py_file in os.listdir(py_src_svn):
    if py_file.endswith('.py'):
      copy_changed_file(os.path.join(py_src_svn, py_file),
                        to_dir=swig_py_svn)

  print('-- Running Swig Python tests --')
  sys.stdout.flush()

  pythonpath = swig_py_dir
  if 'PYTHONPATH' in os.environ:
    pythonpath += os.pathsep + os.environ['PYTHONPATH']

  python_exe = sys.executable if objdir != 'Debug' else \
               os.path.join(os.path.dirname(sys.executable), 'python_d.exe')
  old_cwd = os.getcwd()
  try:
    os.environ['PYTHONPATH'] = pythonpath

    r = subprocess.call([
              python_exe,
              os.path.join(py_src, 'tests', 'run_all.py')
              ])
  finally:
    os.chdir(old_cwd)

    if (r != 0):
      print('[Test runner reported failure]')
      failed = True

elif test_swig == 'ruby':
  failed = False

  if 'ruby' not in gen_obj._libraries:
    print('Ruby not found. Skipping Ruby tests')
  else:
    ruby_lib = gen_obj._libraries['ruby']

    ruby_exe = 'ruby.exe'
    ruby_subdir = os.path.join('subversion', 'bindings', 'swig', 'ruby')
    ruby_args = [
        '-I', os.path.join(abs_srcdir, ruby_subdir),
        os.path.join(abs_srcdir, ruby_subdir, 'test', 'run-test.rb'),
        '--verbose'
      ]

    print('-- Running Swig Ruby tests --')
    sys.stdout.flush()
    old_cwd = os.getcwd()
    try:
      os.chdir(ruby_subdir)

      os.environ["BUILD_TYPE"] = objdir
      os.environ["SVN_DBG_NO_ABORT_ON_ERROR_LEAK"] = 'YES'
      r = subprocess.call([ruby_exe] + ruby_args)
    finally:
      os.chdir(old_cwd)

    sys.stdout.flush()
    sys.stderr.flush()
    if (r != 0):
      print('[Test runner reported failure]')
      failed = True

elif test_swig:
  print('Unknown Swig binding type: ' + str(test_swig))
  failed = True

# Stop service daemon, if any
if daemon:
  del daemon

if memcached:
  del memcached

# Remove the execs again
for tgt in copied_execs:
  try:
    if os.path.isfile(tgt):
      if verbose:
        print("kill: %s" % tgt)
      os.unlink(tgt)
  except:
    traceback.print_exc(file=sys.stdout)
    pass


if failed:
  sys.exit(1)
