#
#
# 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
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("  -q, --quiet            : talk less")
  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("  --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")

  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',
                        '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',
                        'config-file=', 'server-minor-version=', 'log-level=',
                        'log-to-stdout', 'mode-filter=', 'milestone-filter=',
                        'ssl-cert='])
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, quiet, cleanup = None, None, None, None, 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
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

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
  elif opt in ('-q', '--quiet'):
    quiet = 1
  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 == '--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 == '--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 = 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 = val
  elif opt == '--ssl-cert':
    ssl_cert = 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:
    base_url = 'http://localhost:' + str(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))

    self.proc = subprocess.Popen([self.path] + args[1:])

  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, httpd_port,
               service, 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.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.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()

    # 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)
    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
    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'))

    # 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,
                                    '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 _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')
    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/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()

  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')

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

daemon = None
# Run the tests

# No need to start any servers if we are only listing the tests.
if not list_tests:
  if run_svnserve:
    daemon = Svnserve(svnserve_args, objdir, abs_objdir, abs_builddir)

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

  # 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
  th = run_tests.TestHarness(abs_srcdir, abs_builddir,
                             log_file,
                             fail_log_file,
                             base_url, fs_type, 'serf',
                             server_minor_version, not quiet,
                             cleanup, enable_sasl, parallel, config_file,
                             fsfs_sharding, fsfs_packing,
                             list_tests, svn_bin, mode_filter,
                             milestone_filter,
                             httpd_version=httpd_version,
                             set_log_level=log_level, ssl_cert=ssl_cert)
  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',)

    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)
      copy_changed_file(src, to_dir=swig_py_libsvn)

  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 = 'python.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

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

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