1251881Speter# 2251881Speter# 3251881Speter# Licensed to the Apache Software Foundation (ASF) under one 4251881Speter# or more contributor license agreements. See the NOTICE file 5251881Speter# distributed with this work for additional information 6251881Speter# regarding copyright ownership. The ASF licenses this file 7251881Speter# to you under the Apache License, Version 2.0 (the 8251881Speter# "License"); you may not use this file except in compliance 9251881Speter# with the License. You may obtain a copy of the License at 10251881Speter# 11251881Speter# http://www.apache.org/licenses/LICENSE-2.0 12251881Speter# 13251881Speter# Unless required by applicable law or agreed to in writing, 14251881Speter# software distributed under the License is distributed on an 15251881Speter# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16251881Speter# KIND, either express or implied. See the License for the 17251881Speter# specific language governing permissions and limitations 18251881Speter# under the License. 19251881Speter# 20251881Speter# 21251881Speter""" 22251881SpeterDriver for running the tests on Windows. 23251881Speter 24251881SpeterFor a list of options, run this script with the --help option. 25251881Speter""" 26251881Speter 27251881Speter# $HeadURL: http://svn.apache.org/repos/asf/subversion/branches/1.8.x/win-tests.py $ 28253734Speter# $LastChangedRevision: 1492044 $ 29251881Speter 30251881Speterimport os, sys, subprocess 31251881Speterimport filecmp 32251881Speterimport shutil 33251881Speterimport traceback 34251881Spetertry: 35251881Speter # Python >=3.0 36251881Speter import configparser 37251881Speterexcept ImportError: 38251881Speter # Python <3.0 39251881Speter import ConfigParser as configparser 40251881Speterimport string 41251881Speterimport random 42251881Speter 43251881Speterimport getopt 44251881Spetertry: 45251881Speter my_getopt = getopt.gnu_getopt 46251881Speterexcept AttributeError: 47251881Speter my_getopt = getopt.getopt 48251881Speter 49251881Speterdef _usage_exit(): 50251881Speter "print usage, exit the script" 51251881Speter 52251881Speter print("Driver for running the tests on Windows.") 53251881Speter print("Usage: python win-tests.py [option] [test-path]") 54251881Speter print("") 55251881Speter print("Valid options:") 56251881Speter print(" -r, --release : test the Release configuration") 57251881Speter print(" -d, --debug : test the Debug configuration (default)") 58251881Speter print(" --bin=PATH : use the svn binaries installed in PATH") 59251881Speter print(" -u URL, --url=URL : run ra_dav or ra_svn tests against URL;") 60251881Speter print(" will start svnserve for ra_svn tests") 61251881Speter print(" -v, --verbose : talk more") 62251881Speter print(" -q, --quiet : talk less") 63251881Speter print(" -f, --fs-type=type : filesystem type to use (fsfs is default)") 64251881Speter print(" -c, --cleanup : cleanup after running a test") 65251881Speter print(" -t, --test=TEST : Run the TEST test (all is default); use") 66251881Speter print(" TEST#n to run a particular test number,") 67251881Speter print(" multiples also accepted e.g. '2,4-7'") 68251881Speter print(" --log-level=LEVEL : Set log level to LEVEL (E.g. DEBUG)") 69251881Speter print(" --log-to-stdout : Write log results to stdout") 70251881Speter 71251881Speter print(" --svnserve-args=list : comma-separated list of arguments for") 72251881Speter print(" svnserve") 73251881Speter print(" default is '-d,-r,<test-path-root>'") 74251881Speter print(" --asp.net-hack : use '_svn' instead of '.svn' for the admin") 75251881Speter print(" dir name") 76251881Speter print(" --httpd-dir : location where Apache HTTPD is installed") 77251881Speter print(" --httpd-port : port for Apache HTTPD; random port number") 78251881Speter print(" will be used, if not specified") 79251881Speter print(" --httpd-daemon : Run Apache httpd as daemon") 80251881Speter print(" --httpd-service : Run Apache httpd as Windows service (default)") 81251881Speter print(" --httpd-no-log : Disable httpd logging") 82251881Speter print(" --http-short-circuit : Use SVNPathAuthz short_circuit on HTTP server") 83251881Speter print(" --disable-http-v2 : Do not advertise support for HTTPv2 on server") 84251881Speter print(" --disable-bulk-updates : Disable bulk updates on HTTP server") 85251881Speter print(" --ssl-cert : Path to SSL server certificate to trust.") 86251881Speter print(" --javahl : Run the javahl tests instead of the normal tests") 87251881Speter print(" --list : print test doc strings only") 88251881Speter print(" --milestone-filter=RE : RE is a regular expression pattern that (when") 89251881Speter print(" used with --list) limits the tests listed to") 90251881Speter print(" those with an associated issue in the tracker") 91251881Speter print(" which has a target milestone that matches RE.") 92251881Speter print(" --mode-filter=TYPE : limit tests to expected TYPE = XFAIL, SKIP, PASS,") 93251881Speter print(" or 'ALL' (default)") 94251881Speter print(" --enable-sasl : enable Cyrus SASL authentication for") 95251881Speter print(" svnserve") 96251881Speter print(" -p, --parallel : run multiple tests in parallel") 97251881Speter print(" --server-minor-version : the minor version of the server being") 98251881Speter print(" tested") 99251881Speter print(" --config-file : Configuration file for tests") 100251881Speter print(" --fsfs-sharding : Specify shard size (for fsfs)") 101251881Speter print(" --fsfs-packing : Run 'svnadmin pack' automatically") 102251881Speter 103251881Speter sys.exit(0) 104251881Speter 105251881SpeterCMDLINE_TEST_SCRIPT_PATH = 'subversion/tests/cmdline/' 106251881SpeterCMDLINE_TEST_SCRIPT_NATIVE_PATH = CMDLINE_TEST_SCRIPT_PATH.replace('/', os.sep) 107251881Speter 108251881Spetersys.path.insert(0, os.path.join('build', 'generator')) 109251881Spetersys.path.insert(1, 'build') 110251881Speter 111251881Speterimport gen_win 112251881Speterversion_header = os.path.join('subversion', 'include', 'svn_version.h') 113251881Spetercp = configparser.ConfigParser() 114251881Spetercp.read('gen-make.opts') 115251881Spetergen_obj = gen_win.GeneratorBase('build.conf', version_header, 116251881Speter cp.items('options')) 117251881Speterall_tests = gen_obj.test_progs + gen_obj.bdb_test_progs \ 118251881Speter + gen_obj.scripts + gen_obj.bdb_scripts 119251881Speterclient_tests = [x for x in all_tests if x.startswith(CMDLINE_TEST_SCRIPT_PATH)] 120251881Speter 121251881Spetersvn_dlls = [] 122251881Speterfor section in gen_obj.sections.values(): 123251881Speter if section.options.get("msvc-export"): 124251881Speter dll_basename = section.name + "-" + str(gen_obj.version) + ".dll" 125251881Speter svn_dlls.append(os.path.join("subversion", section.name, dll_basename)) 126251881Speter 127251881Speteropts, args = my_getopt(sys.argv[1:], 'hrdvqct:pu:f:', 128251881Speter ['release', 'debug', 'verbose', 'quiet', 'cleanup', 129251881Speter 'test=', 'url=', 'svnserve-args=', 'fs-type=', 'asp.net-hack', 130251881Speter 'httpd-dir=', 'httpd-port=', 'httpd-daemon', 131251881Speter 'httpd-server', 'http-short-circuit', 'httpd-no-log', 132251881Speter 'disable-http-v2', 'disable-bulk-updates', 'help', 133251881Speter 'fsfs-packing', 'fsfs-sharding=', 'javahl', 134251881Speter 'list', 'enable-sasl', 'bin=', 'parallel', 135251881Speter 'config-file=', 'server-minor-version=', 'log-level=', 136251881Speter 'log-to-stdout', 'mode-filter=', 'milestone-filter=', 137251881Speter 'ssl-cert=']) 138251881Speterif len(args) > 1: 139251881Speter print('Warning: non-option arguments after the first one will be ignored') 140251881Speter 141251881Speter# Interpret the options and set parameters 142251881Speterbase_url, fs_type, verbose, quiet, cleanup = None, None, None, None, None 143251881Speterrepo_loc = 'local repository.' 144251881Speterobjdir = 'Debug' 145251881Speterlog = 'tests.log' 146251881Speterfaillog = 'fails.log' 147251881Speterrun_svnserve = None 148251881Spetersvnserve_args = None 149251881Speterrun_httpd = None 150251881Speterhttpd_port = None 151251881Speterhttpd_service = None 152251881Speterhttpd_no_log = None 153251881Speterhttp_short_circuit = False 154251881Speteradvertise_httpv2 = True 155251881Speterhttp_bulk_updates = True 156251881Speterlist_tests = None 157251881Spetermilestone_filter = None 158251881Spetertest_javahl = None 159251881Speterenable_sasl = None 160251881Spetersvn_bin = None 161251881Speterparallel = None 162251881Speterfsfs_sharding = None 163251881Speterfsfs_packing = None 164251881Speterserver_minor_version = None 165251881Speterconfig_file = None 166251881Speterlog_to_stdout = None 167251881Spetermode_filter=None 168251881Spetertests_to_run = [] 169251881Speterlog_level = None 170251881Speterssl_cert = None 171251881Speter 172251881Speterfor opt, val in opts: 173251881Speter if opt in ('-h', '--help'): 174251881Speter _usage_exit() 175251881Speter elif opt in ('-u', '--url'): 176251881Speter base_url = val 177251881Speter elif opt in ('-f', '--fs-type'): 178251881Speter fs_type = val 179251881Speter elif opt in ('-v', '--verbose'): 180251881Speter verbose = 1 181251881Speter elif opt in ('-q', '--quiet'): 182251881Speter quiet = 1 183251881Speter elif opt in ('-c', '--cleanup'): 184251881Speter cleanup = 1 185251881Speter elif opt in ('-t', '--test'): 186251881Speter tests_to_run.append(val) 187251881Speter elif opt in ['-r', '--release']: 188251881Speter objdir = 'Release' 189251881Speter elif opt in ['-d', '--debug']: 190251881Speter objdir = 'Debug' 191251881Speter elif opt == '--svnserve-args': 192251881Speter svnserve_args = val.split(',') 193251881Speter run_svnserve = 1 194251881Speter elif opt == '--asp.net-hack': 195251881Speter os.environ['SVN_ASP_DOT_NET_HACK'] = opt 196251881Speter elif opt == '--httpd-dir': 197251881Speter abs_httpd_dir = os.path.abspath(val) 198251881Speter run_httpd = 1 199251881Speter elif opt == '--httpd-port': 200251881Speter httpd_port = int(val) 201251881Speter elif opt == '--httpd-daemon': 202251881Speter httpd_service = 0 203251881Speter elif opt == '--httpd-service': 204251881Speter httpd_service = 1 205251881Speter elif opt == '--httpd-no-log': 206251881Speter httpd_no_log = 1 207251881Speter elif opt == '--http-short-circuit': 208251881Speter http_short_circuit = True 209251881Speter elif opt == '--disable-http-v2': 210251881Speter advertise_httpv2 = False 211251881Speter elif opt == '--disable-bulk-updates': 212251881Speter http_bulk_updates = False 213251881Speter elif opt == '--fsfs-sharding': 214251881Speter fsfs_sharding = int(val) 215251881Speter elif opt == '--fsfs-packing': 216251881Speter fsfs_packing = 1 217251881Speter elif opt == '--javahl': 218251881Speter test_javahl = 1 219251881Speter elif opt == '--list': 220251881Speter list_tests = 1 221251881Speter elif opt == '--milestone-filter': 222251881Speter milestone_filter = val 223251881Speter elif opt == '--mode-filter': 224251881Speter mode_filter = val 225251881Speter elif opt == '--enable-sasl': 226251881Speter enable_sasl = 1 227251881Speter base_url = "svn://localhost/" 228251881Speter elif opt == '--server-minor-version': 229251881Speter server_minor_version = val 230251881Speter elif opt == '--bin': 231251881Speter svn_bin = val 232251881Speter elif opt in ('-p', '--parallel'): 233251881Speter parallel = 1 234251881Speter elif opt in ('--config-file'): 235251881Speter config_file = val 236251881Speter elif opt == '--log-to-stdout': 237251881Speter log_to_stdout = 1 238251881Speter elif opt == '--log-level': 239251881Speter log_level = val 240251881Speter elif opt == '--ssl-cert': 241251881Speter ssl_cert = val 242251881Speter 243251881Speter# Calculate the source and test directory names 244251881Speterabs_srcdir = os.path.abspath("") 245251881Speterabs_objdir = os.path.join(abs_srcdir, objdir) 246251881Speterif len(args) == 0: 247251881Speter abs_builddir = abs_objdir 248251881Speter create_dirs = 0 249251881Speterelse: 250251881Speter abs_builddir = os.path.abspath(args[0]) 251251881Speter create_dirs = 1 252251881Speter 253251881Speter# Default to fsfs explicitly 254251881Speterif not fs_type: 255251881Speter fs_type = 'fsfs' 256251881Speter 257251881Speter# Don't run bdb tests if they want to test fsfs 258251881Speterif fs_type == 'fsfs': 259251881Speter all_tests = gen_obj.test_progs + gen_obj.scripts 260251881Speter 261251881Speterif run_httpd: 262251881Speter if not httpd_port: 263251881Speter httpd_port = random.randrange(1024, 30000) 264251881Speter if not base_url: 265251881Speter base_url = 'http://localhost:' + str(httpd_port) 266251881Speter 267251881Speterif base_url: 268251881Speter repo_loc = 'remote repository ' + base_url + '.' 269251881Speter if base_url[:4] == 'http': 270251881Speter log = 'dav-tests.log' 271251881Speter faillog = 'dav-fails.log' 272251881Speter elif base_url[:3] == 'svn': 273251881Speter log = 'svn-tests.log' 274251881Speter faillog = 'svn-fails.log' 275251881Speter run_svnserve = 1 276251881Speter else: 277251881Speter # Don't know this scheme, but who're we to judge whether it's 278251881Speter # correct or not? 279251881Speter log = 'url-tests.log' 280251881Speter faillog = 'url-fails.log' 281251881Speter 282251881Speter# Have to move the executables where the tests expect them to be 283251881Spetercopied_execs = [] # Store copied exec files to avoid the final dir scan 284251881Speter 285251881Speterdef create_target_dir(dirname): 286251881Speter tgt_dir = os.path.join(abs_builddir, dirname) 287251881Speter if not os.path.exists(tgt_dir): 288251881Speter if verbose: 289251881Speter print("mkdir: %s" % tgt_dir) 290251881Speter os.makedirs(tgt_dir) 291251881Speter 292251881Speterdef copy_changed_file(src, tgt): 293251881Speter if not os.path.isfile(src): 294251881Speter print('Could not find ' + src) 295251881Speter sys.exit(1) 296251881Speter if os.path.isdir(tgt): 297251881Speter tgt = os.path.join(tgt, os.path.basename(src)) 298251881Speter if os.path.exists(tgt): 299251881Speter assert os.path.isfile(tgt) 300251881Speter if filecmp.cmp(src, tgt): 301251881Speter if verbose: 302251881Speter print("same: %s" % src) 303251881Speter print(" and: %s" % tgt) 304251881Speter return 0 305251881Speter if verbose: 306251881Speter print("copy: %s" % src) 307251881Speter print(" to: %s" % tgt) 308251881Speter shutil.copy(src, tgt) 309251881Speter return 1 310251881Speter 311251881Speterdef copy_execs(baton, dirname, names): 312251881Speter copied_execs = baton 313251881Speter for name in names: 314251881Speter if not name.endswith('.exe'): 315251881Speter continue 316251881Speter src = os.path.join(dirname, name) 317251881Speter tgt = os.path.join(abs_builddir, dirname, name) 318251881Speter create_target_dir(dirname) 319251881Speter if copy_changed_file(src, tgt): 320251881Speter copied_execs.append(tgt) 321251881Speter 322251881Speterdef locate_libs(): 323251881Speter "Move DLLs to a known location and set env vars" 324251881Speter 325251881Speter dlls = [] 326251881Speter 327251881Speter # look for APR 1.x dll's and use those if found 328251881Speter apr_test_path = os.path.join(gen_obj.apr_path, objdir, 'libapr-1.dll') 329251881Speter if os.path.exists(apr_test_path): 330251881Speter suffix = "-1" 331251881Speter else: 332251881Speter suffix = "" 333251881Speter 334251881Speter if cp.has_option('options', '--with-static-apr'): 335251881Speter dlls.append(os.path.join(gen_obj.apr_path, objdir, 336251881Speter 'libapr%s.dll' % (suffix))) 337251881Speter dlls.append(os.path.join(gen_obj.apr_util_path, objdir, 338251881Speter 'libaprutil%s.dll' % (suffix))) 339251881Speter 340251881Speter if gen_obj.libintl_path is not None: 341251881Speter dlls.append(os.path.join(gen_obj.libintl_path, 'bin', 'intl3_svn.dll')) 342251881Speter 343251881Speter if gen_obj.bdb_lib is not None: 344251881Speter partial_path = os.path.join(gen_obj.bdb_path, 'bin', gen_obj.bdb_lib) 345251881Speter if objdir == 'Debug': 346251881Speter dlls.append(partial_path + 'd.dll') 347251881Speter else: 348251881Speter dlls.append(partial_path + '.dll') 349251881Speter 350251881Speter if gen_obj.sasl_path is not None: 351251881Speter dlls.append(os.path.join(gen_obj.sasl_path, 'lib', 'libsasl.dll')) 352251881Speter 353251881Speter for dll in dlls: 354251881Speter copy_changed_file(dll, abs_objdir) 355251881Speter 356251881Speter # Copy the Subversion library DLLs 357251881Speter if not cp.has_option('options', '--disable-shared'): 358251881Speter for svn_dll in svn_dlls: 359251881Speter copy_changed_file(os.path.join(abs_objdir, svn_dll), abs_objdir) 360251881Speter 361251881Speter # Copy the Apache modules 362251881Speter if run_httpd and cp.has_option('options', '--with-httpd'): 363251881Speter mod_dav_svn_path = os.path.join(abs_objdir, 'subversion', 364251881Speter 'mod_dav_svn', 'mod_dav_svn.so') 365251881Speter mod_authz_svn_path = os.path.join(abs_objdir, 'subversion', 366251881Speter 'mod_authz_svn', 'mod_authz_svn.so') 367251881Speter mod_dontdothat_path = os.path.join(abs_objdir, 'tools', 'server-side', 368251881Speter 'mod_dontdothat', 'mod_dontdothat.so') 369251881Speter 370251881Speter copy_changed_file(mod_dav_svn_path, abs_objdir) 371251881Speter copy_changed_file(mod_authz_svn_path, abs_objdir) 372251881Speter copy_changed_file(mod_dontdothat_path, abs_objdir) 373251881Speter 374251881Speter os.environ['PATH'] = abs_objdir + os.pathsep + os.environ['PATH'] 375251881Speter 376251881Speterdef fix_case(path): 377251881Speter path = os.path.normpath(path) 378251881Speter parts = path.split(os.path.sep) 379251881Speter drive = parts[0].upper() 380251881Speter parts = parts[1:] 381251881Speter path = drive + os.path.sep 382251881Speter for part in parts: 383251881Speter dirs = os.listdir(path) 384251881Speter for dir in dirs: 385251881Speter if dir.lower() == part.lower(): 386251881Speter path = os.path.join(path, dir) 387251881Speter break 388251881Speter return path 389251881Speter 390251881Speterclass Svnserve: 391251881Speter "Run svnserve for ra_svn tests" 392251881Speter def __init__(self, svnserve_args, objdir, abs_objdir, abs_builddir): 393251881Speter self.args = svnserve_args 394251881Speter self.name = 'svnserve.exe' 395251881Speter self.kind = objdir 396251881Speter self.path = os.path.join(abs_objdir, 397251881Speter 'subversion', 'svnserve', self.name) 398251881Speter self.root = os.path.join(abs_builddir, CMDLINE_TEST_SCRIPT_NATIVE_PATH) 399251881Speter self.proc_handle = None 400251881Speter 401251881Speter def __del__(self): 402251881Speter "Stop svnserve when the object is deleted" 403251881Speter self.stop() 404251881Speter 405251881Speter def _quote(self, arg): 406251881Speter if ' ' in arg: 407251881Speter return '"' + arg + '"' 408251881Speter else: 409251881Speter return arg 410251881Speter 411251881Speter def start(self): 412251881Speter if not self.args: 413251881Speter args = [self.name, '-d', '-r', self.root] 414251881Speter else: 415251881Speter args = [self.name] + self.args 416251881Speter print('Starting %s %s' % (self.kind, self.name)) 417251881Speter try: 418251881Speter import win32process 419251881Speter import win32con 420251881Speter args = ' '.join([self._quote(x) for x in args]) 421251881Speter self.proc_handle = ( 422251881Speter win32process.CreateProcess(self._quote(self.path), args, 423251881Speter None, None, 0, 424251881Speter win32con.CREATE_NEW_CONSOLE, 425251881Speter None, None, win32process.STARTUPINFO()))[0] 426251881Speter except ImportError: 427251881Speter os.spawnv(os.P_NOWAIT, self.path, args) 428251881Speter 429251881Speter def stop(self): 430251881Speter if self.proc_handle is not None: 431251881Speter try: 432251881Speter import win32process 433251881Speter print('Stopping %s' % self.name) 434251881Speter win32process.TerminateProcess(self.proc_handle, 0) 435251881Speter return 436251881Speter except ImportError: 437251881Speter pass 438251881Speter print('Svnserve.stop not implemented') 439251881Speter 440251881Speterclass Httpd: 441251881Speter "Run httpd for DAV tests" 442251881Speter def __init__(self, abs_httpd_dir, abs_objdir, abs_builddir, httpd_port, 443251881Speter service, no_log, httpv2, short_circuit, bulk_updates): 444251881Speter self.name = 'apache.exe' 445251881Speter self.httpd_port = httpd_port 446251881Speter self.httpd_dir = abs_httpd_dir 447251881Speter 448251881Speter if httpv2: 449251881Speter self.httpv2_option = 'on' 450251881Speter else: 451251881Speter self.httpv2_option = 'off' 452251881Speter 453251881Speter if bulk_updates: 454251881Speter self.bulkupdates_option = 'on' 455251881Speter else: 456251881Speter self.bulkupdates_option = 'off' 457251881Speter 458251881Speter self.service = service 459251881Speter self.proc_handle = None 460251881Speter self.path = os.path.join(self.httpd_dir, 'bin', self.name) 461251881Speter 462251881Speter if short_circuit: 463251881Speter self.path_authz_option = 'short_circuit' 464251881Speter else: 465251881Speter self.path_authz_option = 'on' 466251881Speter 467251881Speter if not os.path.exists(self.path): 468251881Speter self.name = 'httpd.exe' 469251881Speter self.path = os.path.join(self.httpd_dir, 'bin', self.name) 470251881Speter if not os.path.exists(self.path): 471251881Speter raise RuntimeError("Could not find a valid httpd binary!") 472251881Speter 473251881Speter self.root_dir = os.path.join(CMDLINE_TEST_SCRIPT_NATIVE_PATH, 'httpd') 474251881Speter self.root = os.path.join(abs_builddir, self.root_dir) 475251881Speter self.authz_file = os.path.join(abs_builddir, 476251881Speter CMDLINE_TEST_SCRIPT_NATIVE_PATH, 477251881Speter 'svn-test-work', 'authz') 478251881Speter self.dontdothat_file = os.path.join(abs_builddir, 479251881Speter CMDLINE_TEST_SCRIPT_NATIVE_PATH, 480251881Speter 'svn-test-work', 'dontdothat') 481251881Speter self.httpd_config = os.path.join(self.root, 'httpd.conf') 482251881Speter self.httpd_users = os.path.join(self.root, 'users') 483251881Speter self.httpd_mime_types = os.path.join(self.root, 'mime.types') 484251881Speter self.abs_builddir = abs_builddir 485251881Speter self.abs_objdir = abs_objdir 486251881Speter self.service_name = 'svn-test-httpd-' + str(httpd_port) 487251881Speter 488251881Speter if self.service: 489251881Speter self.httpd_args = [self.name, '-n', self._quote(self.service_name), 490251881Speter '-f', self._quote(self.httpd_config)] 491251881Speter else: 492251881Speter self.httpd_args = [self.name, '-f', self._quote(self.httpd_config)] 493251881Speter 494251881Speter create_target_dir(self.root_dir) 495251881Speter 496251881Speter self._create_users_file() 497251881Speter self._create_mime_types_file() 498251881Speter self._create_dontdothat_file() 499251881Speter 500251881Speter # Determine version. 501251881Speter if os.path.exists(os.path.join(self.httpd_dir, 502251881Speter 'modules', 'mod_access_compat.so')): 503251881Speter self.httpd_ver = 2.3 504251881Speter elif os.path.exists(os.path.join(self.httpd_dir, 505251881Speter 'modules', 'mod_auth_basic.so')): 506251881Speter self.httpd_ver = 2.2 507251881Speter else: 508251881Speter self.httpd_ver = 2.0 509251881Speter 510251881Speter # Create httpd config file 511251881Speter fp = open(self.httpd_config, 'w') 512251881Speter 513251881Speter # Limit the number of threads (default = 64) 514251881Speter fp.write('<IfModule mpm_winnt.c>\n') 515251881Speter fp.write('ThreadsPerChild 16\n') 516251881Speter fp.write('</IfModule>\n') 517251881Speter 518251881Speter # Global Environment 519251881Speter fp.write('ServerRoot ' + self._quote(self.root) + '\n') 520251881Speter fp.write('DocumentRoot ' + self._quote(self.root) + '\n') 521251881Speter fp.write('ServerName localhost\n') 522251881Speter fp.write('PidFile pid\n') 523251881Speter fp.write('ErrorLog log\n') 524251881Speter fp.write('Listen ' + str(self.httpd_port) + '\n') 525251881Speter 526251881Speter if not no_log: 527251881Speter fp.write('LogFormat "%h %l %u %t \\"%r\\" %>s %b" common\n') 528251881Speter fp.write('Customlog log common\n') 529251881Speter fp.write('LogLevel Debug\n') 530251881Speter else: 531251881Speter fp.write('LogLevel Crit\n') 532251881Speter 533251881Speter # Write LoadModule for minimal system module 534251881Speter fp.write(self._sys_module('dav_module', 'mod_dav.so')) 535251881Speter if self.httpd_ver >= 2.3: 536251881Speter fp.write(self._sys_module('access_compat_module', 'mod_access_compat.so')) 537251881Speter fp.write(self._sys_module('authz_core_module', 'mod_authz_core.so')) 538251881Speter fp.write(self._sys_module('authz_user_module', 'mod_authz_user.so')) 539251881Speter fp.write(self._sys_module('authn_core_module', 'mod_authn_core.so')) 540251881Speter if self.httpd_ver >= 2.2: 541251881Speter fp.write(self._sys_module('auth_basic_module', 'mod_auth_basic.so')) 542251881Speter fp.write(self._sys_module('authn_file_module', 'mod_authn_file.so')) 543251881Speter else: 544251881Speter fp.write(self._sys_module('auth_module', 'mod_auth.so')) 545251881Speter fp.write(self._sys_module('alias_module', 'mod_alias.so')) 546251881Speter fp.write(self._sys_module('mime_module', 'mod_mime.so')) 547251881Speter fp.write(self._sys_module('log_config_module', 'mod_log_config.so')) 548251881Speter 549251881Speter # Write LoadModule for Subversion modules 550251881Speter fp.write(self._svn_module('dav_svn_module', 'mod_dav_svn.so')) 551251881Speter fp.write(self._svn_module('authz_svn_module', 'mod_authz_svn.so')) 552251881Speter 553251881Speter # And for mod_dontdothat 554251881Speter fp.write(self._svn_module('dontdothat_module', 'mod_dontdothat.so')) 555251881Speter 556251881Speter # Don't handle .htaccess, symlinks, etc. 557251881Speter fp.write('<Directory />\n') 558251881Speter fp.write('AllowOverride None\n') 559251881Speter fp.write('Options None\n') 560251881Speter fp.write('</Directory>\n\n') 561251881Speter 562251881Speter # Define two locations for repositories 563251881Speter fp.write(self._svn_repo('repositories')) 564251881Speter fp.write(self._svn_repo('local_tmp')) 565251881Speter 566251881Speter # And two redirects for the redirect tests 567251881Speter fp.write('RedirectMatch permanent ^/svn-test-work/repositories/' 568251881Speter 'REDIRECT-PERM-(.*)$ /svn-test-work/repositories/$1\n') 569251881Speter fp.write('RedirectMatch ^/svn-test-work/repositories/' 570251881Speter 'REDIRECT-TEMP-(.*)$ /svn-test-work/repositories/$1\n') 571251881Speter 572251881Speter fp.write('TypesConfig ' + self._quote(self.httpd_mime_types) + '\n') 573251881Speter fp.write('HostNameLookups Off\n') 574251881Speter 575251881Speter fp.close() 576251881Speter 577251881Speter def __del__(self): 578251881Speter "Stop httpd when the object is deleted" 579251881Speter self.stop() 580251881Speter 581251881Speter def _quote(self, arg): 582251881Speter if ' ' in arg: 583251881Speter return '"' + arg + '"' 584251881Speter else: 585251881Speter return arg 586251881Speter 587251881Speter def _create_users_file(self): 588251881Speter "Create users file" 589251881Speter htpasswd = os.path.join(self.httpd_dir, 'bin', 'htpasswd.exe') 590251881Speter # Create the cheapest to compare password form for our testsuite 591251881Speter os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bcp', self.httpd_users, 592251881Speter 'jrandom', 'rayjandom']) 593251881Speter os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp', self.httpd_users, 594251881Speter 'jconstant', 'rayjandom']) 595251881Speter 596251881Speter def _create_mime_types_file(self): 597251881Speter "Create empty mime.types file" 598251881Speter fp = open(self.httpd_mime_types, 'w') 599251881Speter fp.close() 600251881Speter 601251881Speter def _create_dontdothat_file(self): 602251881Speter "Create empty mime.types file" 603253734Speter # If the tests have not previously been run or were cleaned 604253734Speter # up, then 'svn-test-work' does not exist yet. 605253734Speter parent_dir = os.path.dirname(self.dontdothat_file) 606253734Speter if not os.path.exists(parent_dir): 607253734Speter os.makedirs(parent_dir) 608253734Speter 609251881Speter fp = open(self.dontdothat_file, 'w') 610251881Speter fp.write('[recursive-actions]\n') 611251881Speter fp.write('/ = deny\n') 612251881Speter fp.close() 613251881Speter 614251881Speter def _sys_module(self, name, path): 615251881Speter full_path = os.path.join(self.httpd_dir, 'modules', path) 616251881Speter return 'LoadModule ' + name + " " + self._quote(full_path) + '\n' 617251881Speter 618251881Speter def _svn_module(self, name, path): 619251881Speter full_path = os.path.join(self.abs_objdir, path) 620251881Speter return 'LoadModule ' + name + ' ' + self._quote(full_path) + '\n' 621251881Speter 622251881Speter def _svn_repo(self, name): 623251881Speter path = os.path.join(self.abs_builddir, 624251881Speter CMDLINE_TEST_SCRIPT_NATIVE_PATH, 625251881Speter 'svn-test-work', name) 626251881Speter location = '/svn-test-work/' + name 627251881Speter ddt_location = '/ddt-test-work/' + name 628251881Speter return \ 629251881Speter '<Location ' + location + '>\n' \ 630251881Speter ' DAV svn\n' \ 631251881Speter ' SVNParentPath ' + self._quote(path) + '\n' \ 632251881Speter ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ 633251881Speter ' SVNPathAuthz ' + self.path_authz_option + '\n' \ 634251881Speter ' SVNAllowBulkUpdates ' + self.bulkupdates_option + '\n' \ 635251881Speter ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ 636251881Speter ' AuthType Basic\n' \ 637251881Speter ' AuthName "Subversion Repository"\n' \ 638251881Speter ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ 639251881Speter ' Require valid-user\n' \ 640251881Speter '</Location>\n' \ 641251881Speter '<Location ' + ddt_location + '>\n' \ 642251881Speter ' DAV svn\n' \ 643251881Speter ' SVNParentPath ' + self._quote(path) + '\n' \ 644251881Speter ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \ 645251881Speter ' SVNPathAuthz ' + self.path_authz_option + '\n' \ 646251881Speter ' SVNAllowBulkUpdates ' + self.bulkupdates_option + '\n' \ 647251881Speter ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \ 648251881Speter ' AuthType Basic\n' \ 649251881Speter ' AuthName "Subversion Repository"\n' \ 650251881Speter ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \ 651251881Speter ' Require valid-user\n' \ 652251881Speter ' DontDoThatConfigFile ' + self._quote(self.dontdothat_file) + '\n' \ 653251881Speter '</Location>\n' 654251881Speter 655251881Speter def start(self): 656251881Speter if self.service: 657251881Speter self._start_service() 658251881Speter else: 659251881Speter self._start_daemon() 660251881Speter 661251881Speter def stop(self): 662251881Speter if self.service: 663251881Speter self._stop_service() 664251881Speter else: 665251881Speter self._stop_daemon() 666251881Speter 667251881Speter def _start_service(self): 668251881Speter "Install and start HTTPD service" 669251881Speter print('Installing service %s' % self.service_name) 670251881Speter os.spawnv(os.P_WAIT, self.path, self.httpd_args + ['-k', 'install']) 671251881Speter print('Starting service %s' % self.service_name) 672251881Speter os.spawnv(os.P_WAIT, self.path, self.httpd_args + ['-k', 'start']) 673251881Speter 674251881Speter def _stop_service(self): 675251881Speter "Stop and uninstall HTTPD service" 676251881Speter os.spawnv(os.P_WAIT, self.path, self.httpd_args + ['-k', 'stop']) 677251881Speter os.spawnv(os.P_WAIT, self.path, self.httpd_args + ['-k', 'uninstall']) 678251881Speter 679251881Speter def _start_daemon(self): 680251881Speter "Start HTTPD as daemon" 681251881Speter print('Starting httpd as daemon') 682251881Speter print(self.httpd_args) 683251881Speter try: 684251881Speter import win32process 685251881Speter import win32con 686251881Speter args = ' '.join([self._quote(x) for x in self.httpd_args]) 687251881Speter self.proc_handle = ( 688251881Speter win32process.CreateProcess(self._quote(self.path), args, 689251881Speter None, None, 0, 690251881Speter win32con.CREATE_NEW_CONSOLE, 691251881Speter None, None, win32process.STARTUPINFO()))[0] 692251881Speter except ImportError: 693251881Speter os.spawnv(os.P_NOWAIT, self.path, self.httpd_args) 694251881Speter 695251881Speter def _stop_daemon(self): 696251881Speter "Stop the HTTPD daemon" 697251881Speter if self.proc_handle is not None: 698251881Speter try: 699251881Speter import win32process 700251881Speter print('Stopping %s' % self.name) 701251881Speter win32process.TerminateProcess(self.proc_handle, 0) 702251881Speter return 703251881Speter except ImportError: 704251881Speter pass 705251881Speter print('Httpd.stop_daemon not implemented') 706251881Speter 707251881Speter# Move the binaries to the test directory 708251881Speterlocate_libs() 709251881Speterif create_dirs: 710251881Speter old_cwd = os.getcwd() 711251881Speter try: 712251881Speter os.chdir(abs_objdir) 713251881Speter baton = copied_execs 714251881Speter for dirpath, dirs, files in os.walk('subversion'): 715251881Speter copy_execs(baton, dirpath, files) 716251881Speter for dirpath, dirs, files in os.walk('tools/server-side'): 717251881Speter copy_execs(baton, dirpath, files) 718251881Speter except: 719251881Speter os.chdir(old_cwd) 720251881Speter raise 721251881Speter else: 722251881Speter os.chdir(old_cwd) 723251881Speter 724251881Speter# Create the base directory for Python tests 725251881Spetercreate_target_dir(CMDLINE_TEST_SCRIPT_NATIVE_PATH) 726251881Speter 727251881Speter# Ensure the tests directory is correctly cased 728251881Speterabs_builddir = fix_case(abs_builddir) 729251881Speter 730251881Speterdaemon = None 731251881Speter# Run the tests 732251881Speter 733251881Speter# No need to start any servers if we are only listing the tests. 734251881Speterif not list_tests: 735251881Speter if run_svnserve: 736251881Speter daemon = Svnserve(svnserve_args, objdir, abs_objdir, abs_builddir) 737251881Speter 738251881Speter if run_httpd: 739251881Speter daemon = Httpd(abs_httpd_dir, abs_objdir, abs_builddir, httpd_port, 740251881Speter httpd_service, httpd_no_log, 741251881Speter advertise_httpv2, http_short_circuit, 742251881Speter http_bulk_updates) 743251881Speter 744251881Speter # Start service daemon, if any 745251881Speter if daemon: 746251881Speter daemon.start() 747251881Speter 748251881Speter# Find the full path and filename of any test that is specified just by 749251881Speter# its base name. 750251881Speterif len(tests_to_run) != 0: 751251881Speter tests = [] 752251881Speter for t in tests_to_run: 753251881Speter tns = None 754251881Speter if '#' in t: 755251881Speter t, tns = t.split('#') 756251881Speter 757251881Speter test = [x for x in all_tests if x.split('/')[-1] == t] 758251881Speter if not test and not (t.endswith('-test.exe') or t.endswith('_tests.py')): 759251881Speter # The lengths of '-test.exe' and of '_tests.py' are both 9. 760251881Speter test = [x for x in all_tests if x.split('/')[-1][:-9] == t] 761251881Speter 762251881Speter if not test: 763251881Speter print("Skipping test '%s', test not found." % t) 764251881Speter elif tns: 765251881Speter tests.append('%s#%s' % (test[0], tns)) 766251881Speter else: 767251881Speter tests.extend(test) 768251881Speter 769251881Speter tests_to_run = tests 770251881Speterelse: 771251881Speter tests_to_run = all_tests 772251881Speter 773251881Speter 774251881Speterif list_tests: 775251881Speter print('Listing %s configuration on %s' % (objdir, repo_loc)) 776251881Speterelse: 777251881Speter print('Testing %s configuration on %s' % (objdir, repo_loc)) 778251881Spetersys.path.insert(0, os.path.join(abs_srcdir, 'build')) 779251881Speter 780251881Speterif not test_javahl: 781251881Speter import run_tests 782251881Speter if log_to_stdout: 783251881Speter log_file = None 784251881Speter fail_log_file = None 785251881Speter else: 786251881Speter log_file = os.path.join(abs_builddir, log) 787251881Speter fail_log_file = os.path.join(abs_builddir, faillog) 788251881Speter 789251881Speter th = run_tests.TestHarness(abs_srcdir, abs_builddir, 790251881Speter log_file, 791251881Speter fail_log_file, 792251881Speter base_url, fs_type, 'serf', 793251881Speter server_minor_version, not quiet, 794251881Speter cleanup, enable_sasl, parallel, config_file, 795251881Speter fsfs_sharding, fsfs_packing, 796251881Speter list_tests, svn_bin, mode_filter, 797251881Speter milestone_filter, 798251881Speter set_log_level=log_level, ssl_cert=ssl_cert) 799251881Speter old_cwd = os.getcwd() 800251881Speter try: 801251881Speter os.chdir(abs_builddir) 802251881Speter failed = th.run(tests_to_run) 803251881Speter except: 804251881Speter os.chdir(old_cwd) 805251881Speter raise 806251881Speter else: 807251881Speter os.chdir(old_cwd) 808251881Speterelse: 809251881Speter failed = False 810251881Speter args = ( 811251881Speter 'java.exe', 812251881Speter '-Dtest.rootdir=' + os.path.join(abs_builddir, 'javahl'), 813251881Speter '-Dtest.srcdir=' + os.path.join(abs_srcdir, 814251881Speter 'subversion/bindings/javahl'), 815251881Speter '-Dtest.rooturl=', 816251881Speter '-Dtest.fstype=' + fs_type , 817251881Speter '-Dtest.tests=', 818251881Speter 819251881Speter '-Djava.library.path=' 820251881Speter + os.path.join(abs_objdir, 821251881Speter 'subversion/bindings/javahl/native'), 822251881Speter '-classpath', 823251881Speter os.path.join(abs_srcdir, 'subversion/bindings/javahl/classes') +';' + 824251881Speter gen_obj.junit_path 825251881Speter ) 826251881Speter 827251881Speter sys.stderr.flush() 828251881Speter print('Running org.apache.subversion tests:') 829251881Speter sys.stdout.flush() 830251881Speter 831251881Speter r = subprocess.call(args + tuple(['org.apache.subversion.javahl.RunTests'])) 832251881Speter sys.stdout.flush() 833251881Speter sys.stderr.flush() 834251881Speter if (r != 0): 835251881Speter print('[Test runner reported failure]') 836251881Speter failed = True 837251881Speter 838251881Speter print('Running org.tigris.subversion tests:') 839251881Speter sys.stdout.flush() 840251881Speter r = subprocess.call(args + tuple(['org.tigris.subversion.javahl.RunTests'])) 841251881Speter sys.stdout.flush() 842251881Speter sys.stderr.flush() 843251881Speter if (r != 0): 844251881Speter print('[Test runner reported failure]') 845251881Speter failed = True 846251881Speter 847251881Speter# Stop service daemon, if any 848251881Speterif daemon: 849251881Speter del daemon 850251881Speter 851251881Speter# Remove the execs again 852251881Speterfor tgt in copied_execs: 853251881Speter try: 854251881Speter if os.path.isfile(tgt): 855251881Speter if verbose: 856251881Speter print("kill: %s" % tgt) 857251881Speter os.unlink(tgt) 858251881Speter except: 859251881Speter traceback.print_exc(file=sys.stdout) 860251881Speter pass 861251881Speter 862251881Speter 863251881Speterif failed: 864251881Speter sys.exit(1) 865