3 # Licensed to the Apache Software Foundation (ASF) under one
4 # or more contributor license agreements. See the NOTICE file
5 # distributed with this work for additional information
6 # regarding copyright ownership. The ASF licenses this file
7 # to you under the Apache License, Version 2.0 (the
8 # "License"); you may not use this file except in compliance
9 # with the License. You may obtain a copy of the License at
11 # http://www.apache.org/licenses/LICENSE-2.0
13 # Unless required by applicable law or agreed to in writing,
14 # software distributed under the License is distributed on an
15 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 # KIND, either express or implied. See the License for the
17 # specific language governing permissions and limitations
22 Driver for running the tests on Windows.
24 For a list of options, run this script with the --help option.
27 # $HeadURL: http://svn.apache.org/repos/asf/subversion/branches/1.8.x/win-tests.py $
28 # $LastChangedRevision: 1692801 $
30 import os, sys, subprocess
39 import ConfigParser as configparser
45 my_getopt = getopt.gnu_getopt
46 except AttributeError:
47 my_getopt = getopt.getopt
50 "print usage, exit the script"
52 print("Driver for running the tests on Windows.")
53 print("Usage: python win-tests.py [option] [test-path]")
55 print("Valid options:")
56 print(" -r, --release : test the Release configuration")
57 print(" -d, --debug : test the Debug configuration (default)")
58 print(" --bin=PATH : use the svn binaries installed in PATH")
59 print(" -u URL, --url=URL : run ra_dav or ra_svn tests against URL;")
60 print(" will start svnserve for ra_svn tests")
61 print(" -v, --verbose : talk more")
62 print(" -q, --quiet : talk less")
63 print(" -f, --fs-type=type : filesystem type to use (fsfs is default)")
64 print(" -c, --cleanup : cleanup after running a test")
65 print(" -t, --test=TEST : Run the TEST test (all is default); use")
66 print(" TEST#n to run a particular test number,")
67 print(" multiples also accepted e.g. '2,4-7'")
68 print(" --log-level=LEVEL : Set log level to LEVEL (E.g. DEBUG)")
69 print(" --log-to-stdout : Write log results to stdout")
71 print(" --svnserve-args=list : comma-separated list of arguments for")
73 print(" default is '-d,-r,<test-path-root>'")
74 print(" --asp.net-hack : use '_svn' instead of '.svn' for the admin")
76 print(" --httpd-dir : location where Apache HTTPD is installed")
77 print(" --httpd-port : port for Apache HTTPD; random port number")
78 print(" will be used, if not specified")
79 print(" --httpd-daemon : Run Apache httpd as daemon")
80 print(" --httpd-service : Run Apache httpd as Windows service (default)")
81 print(" --httpd-no-log : Disable httpd logging")
82 print(" --http-short-circuit : Use SVNPathAuthz short_circuit on HTTP server")
83 print(" --disable-http-v2 : Do not advertise support for HTTPv2 on server")
84 print(" --disable-bulk-updates : Disable bulk updates on HTTP server")
85 print(" --ssl-cert : Path to SSL server certificate to trust.")
86 print(" --javahl : Run the javahl tests instead of the normal tests")
87 print(" --list : print test doc strings only")
88 print(" --milestone-filter=RE : RE is a regular expression pattern that (when")
89 print(" used with --list) limits the tests listed to")
90 print(" those with an associated issue in the tracker")
91 print(" which has a target milestone that matches RE.")
92 print(" --mode-filter=TYPE : limit tests to expected TYPE = XFAIL, SKIP, PASS,")
93 print(" or 'ALL' (default)")
94 print(" --enable-sasl : enable Cyrus SASL authentication for")
96 print(" -p, --parallel : run multiple tests in parallel")
97 print(" --server-minor-version : the minor version of the server being")
99 print(" --config-file : Configuration file for tests")
100 print(" --fsfs-sharding : Specify shard size (for fsfs)")
101 print(" --fsfs-packing : Run 'svnadmin pack' automatically")
105 CMDLINE_TEST_SCRIPT_PATH = 'subversion/tests/cmdline/'
106 CMDLINE_TEST_SCRIPT_NATIVE_PATH = CMDLINE_TEST_SCRIPT_PATH.replace('/', os.sep)
108 sys.path.insert(0, os.path.join('build', 'generator'))
109 sys.path.insert(1, 'build')
112 version_header = os.path.join('subversion', 'include', 'svn_version.h')
113 cp = configparser.ConfigParser()
114 cp.read('gen-make.opts')
115 gen_obj = gen_win.GeneratorBase('build.conf', version_header,
117 all_tests = gen_obj.test_progs + gen_obj.bdb_test_progs \
118 + gen_obj.scripts + gen_obj.bdb_scripts
119 client_tests = [x for x in all_tests if x.startswith(CMDLINE_TEST_SCRIPT_PATH)]
122 for section in gen_obj.sections.values():
123 if section.options.get("msvc-export"):
124 dll_basename = section.name + "-" + str(gen_obj.version) + ".dll"
125 svn_dlls.append(os.path.join("subversion", section.name, dll_basename))
127 opts, args = my_getopt(sys.argv[1:], 'hrdvqct:pu:f:',
128 ['release', 'debug', 'verbose', 'quiet', 'cleanup',
129 'test=', 'url=', 'svnserve-args=', 'fs-type=', 'asp.net-hack',
130 'httpd-dir=', 'httpd-port=', 'httpd-daemon',
131 'httpd-server', 'http-short-circuit', 'httpd-no-log',
132 'disable-http-v2', 'disable-bulk-updates', 'help',
133 'fsfs-packing', 'fsfs-sharding=', 'javahl',
134 'list', 'enable-sasl', 'bin=', 'parallel',
135 'config-file=', 'server-minor-version=', 'log-level=',
136 'log-to-stdout', 'mode-filter=', 'milestone-filter=',
139 print('Warning: non-option arguments after the first one will be ignored')
141 # Interpret the options and set parameters
142 base_url, fs_type, verbose, quiet, cleanup = None, None, None, None, None
143 repo_loc = 'local repository.'
146 faillog = 'fails.log'
153 http_short_circuit = False
154 advertise_httpv2 = True
155 http_bulk_updates = True
157 milestone_filter = None
164 server_minor_version = None
172 for opt, val in opts:
173 if opt in ('-h', '--help'):
175 elif opt in ('-u', '--url'):
177 elif opt in ('-f', '--fs-type'):
179 elif opt in ('-v', '--verbose'):
181 elif opt in ('-q', '--quiet'):
183 elif opt in ('-c', '--cleanup'):
185 elif opt in ('-t', '--test'):
186 tests_to_run.append(val)
187 elif opt in ['-r', '--release']:
189 elif opt in ['-d', '--debug']:
191 elif opt == '--svnserve-args':
192 svnserve_args = val.split(',')
194 elif opt == '--asp.net-hack':
195 os.environ['SVN_ASP_DOT_NET_HACK'] = opt
196 elif opt == '--httpd-dir':
197 abs_httpd_dir = os.path.abspath(val)
199 elif opt == '--httpd-port':
200 httpd_port = int(val)
201 elif opt == '--httpd-daemon':
203 elif opt == '--httpd-service':
205 elif opt == '--httpd-no-log':
207 elif opt == '--http-short-circuit':
208 http_short_circuit = True
209 elif opt == '--disable-http-v2':
210 advertise_httpv2 = False
211 elif opt == '--disable-bulk-updates':
212 http_bulk_updates = False
213 elif opt == '--fsfs-sharding':
214 fsfs_sharding = int(val)
215 elif opt == '--fsfs-packing':
217 elif opt == '--javahl':
219 elif opt == '--list':
221 elif opt == '--milestone-filter':
222 milestone_filter = val
223 elif opt == '--mode-filter':
225 elif opt == '--enable-sasl':
227 base_url = "svn://localhost/"
228 elif opt == '--server-minor-version':
229 server_minor_version = val
232 elif opt in ('-p', '--parallel'):
234 elif opt in ('--config-file'):
236 elif opt == '--log-to-stdout':
238 elif opt == '--log-level':
240 elif opt == '--ssl-cert':
243 # Calculate the source and test directory names
244 abs_srcdir = os.path.abspath("")
245 abs_objdir = os.path.join(abs_srcdir, objdir)
247 abs_builddir = abs_objdir
250 abs_builddir = os.path.abspath(args[0])
253 # Default to fsfs explicitly
257 # Don't run bdb tests if they want to test fsfs
258 if fs_type == 'fsfs':
259 all_tests = gen_obj.test_progs + gen_obj.scripts
263 httpd_port = random.randrange(1024, 30000)
265 base_url = 'http://localhost:' + str(httpd_port)
268 repo_loc = 'remote repository ' + base_url + '.'
269 if base_url[:4] == 'http':
270 log = 'dav-tests.log'
271 faillog = 'dav-fails.log'
272 elif base_url[:3] == 'svn':
273 log = 'svn-tests.log'
274 faillog = 'svn-fails.log'
277 # Don't know this scheme, but who're we to judge whether it's
279 log = 'url-tests.log'
280 faillog = 'url-fails.log'
282 # Have to move the executables where the tests expect them to be
283 copied_execs = [] # Store copied exec files to avoid the final dir scan
285 def create_target_dir(dirname):
286 tgt_dir = os.path.join(abs_builddir, dirname)
287 if not os.path.exists(tgt_dir):
289 print("mkdir: %s" % tgt_dir)
292 def copy_changed_file(src, tgt):
293 if not os.path.isfile(src):
294 print('Could not find ' + src)
296 if os.path.isdir(tgt):
297 tgt = os.path.join(tgt, os.path.basename(src))
298 if os.path.exists(tgt):
299 assert os.path.isfile(tgt)
300 if filecmp.cmp(src, tgt):
302 print("same: %s" % src)
303 print(" and: %s" % tgt)
306 print("copy: %s" % src)
307 print(" to: %s" % tgt)
308 shutil.copy(src, tgt)
311 def copy_execs(baton, dirname, names):
314 if not name.endswith('.exe'):
316 src = os.path.join(dirname, name)
317 tgt = os.path.join(abs_builddir, dirname, name)
318 create_target_dir(dirname)
319 if copy_changed_file(src, tgt):
320 copied_execs.append(tgt)
323 "Move DLLs to a known location and set env vars"
327 # look for APR 1.x dll's and use those if found
328 apr_test_path = os.path.join(gen_obj.apr_path, objdir, 'libapr-1.dll')
329 if os.path.exists(apr_test_path):
334 if cp.has_option('options', '--with-static-apr'):
335 dlls.append(os.path.join(gen_obj.apr_path, objdir,
336 'libapr%s.dll' % (suffix)))
337 dlls.append(os.path.join(gen_obj.apr_util_path, objdir,
338 'libaprutil%s.dll' % (suffix)))
340 if gen_obj.libintl_path is not None:
341 dlls.append(os.path.join(gen_obj.libintl_path, 'bin', 'intl3_svn.dll'))
343 if gen_obj.bdb_lib is not None:
344 partial_path = os.path.join(gen_obj.bdb_path, 'bin', gen_obj.bdb_lib)
345 if objdir == 'Debug':
346 dlls.append(partial_path + 'd.dll')
348 dlls.append(partial_path + '.dll')
350 if gen_obj.sasl_path is not None:
351 dlls.append(os.path.join(gen_obj.sasl_path, 'lib', 'libsasl.dll'))
354 copy_changed_file(dll, abs_objdir)
356 # Copy the Subversion library DLLs
357 if not cp.has_option('options', '--disable-shared'):
358 for svn_dll in svn_dlls:
359 copy_changed_file(os.path.join(abs_objdir, svn_dll), abs_objdir)
361 # Copy the Apache modules
362 if run_httpd and cp.has_option('options', '--with-httpd'):
363 mod_dav_svn_path = os.path.join(abs_objdir, 'subversion',
364 'mod_dav_svn', 'mod_dav_svn.so')
365 mod_authz_svn_path = os.path.join(abs_objdir, 'subversion',
366 'mod_authz_svn', 'mod_authz_svn.so')
367 mod_dontdothat_path = os.path.join(abs_objdir, 'tools', 'server-side',
368 'mod_dontdothat', 'mod_dontdothat.so')
370 copy_changed_file(mod_dav_svn_path, abs_objdir)
371 copy_changed_file(mod_authz_svn_path, abs_objdir)
372 copy_changed_file(mod_dontdothat_path, abs_objdir)
374 os.environ['PATH'] = abs_objdir + os.pathsep + os.environ['PATH']
377 path = os.path.normpath(path)
378 parts = path.split(os.path.sep)
379 drive = parts[0].upper()
381 path = drive + os.path.sep
383 dirs = os.listdir(path)
385 if dir.lower() == part.lower():
386 path = os.path.join(path, dir)
391 "Run svnserve for ra_svn tests"
392 def __init__(self, svnserve_args, objdir, abs_objdir, abs_builddir):
393 self.args = svnserve_args
394 self.name = 'svnserve.exe'
396 self.path = os.path.join(abs_objdir,
397 'subversion', 'svnserve', self.name)
398 self.root = os.path.join(abs_builddir, CMDLINE_TEST_SCRIPT_NATIVE_PATH)
399 self.proc_handle = None
402 "Stop svnserve when the object is deleted"
405 def _quote(self, arg):
407 return '"' + arg + '"'
413 args = [self.name, '-d', '-r', self.root]
415 args = [self.name] + self.args
416 print('Starting %s %s' % (self.kind, self.name))
420 args = ' '.join([self._quote(x) for x in args])
422 win32process.CreateProcess(self._quote(self.path), args,
424 win32con.CREATE_NEW_CONSOLE,
425 None, None, win32process.STARTUPINFO()))[0]
427 os.spawnv(os.P_NOWAIT, self.path, args)
430 if self.proc_handle is not None:
433 print('Stopping %s' % self.name)
434 win32process.TerminateProcess(self.proc_handle, 0)
438 print('Svnserve.stop not implemented')
441 "Run httpd for DAV tests"
442 def __init__(self, abs_httpd_dir, abs_objdir, abs_builddir, httpd_port,
443 service, no_log, httpv2, short_circuit, bulk_updates):
444 self.name = 'apache.exe'
445 self.httpd_port = httpd_port
446 self.httpd_dir = abs_httpd_dir
449 self.httpv2_option = 'on'
451 self.httpv2_option = 'off'
454 self.bulkupdates_option = 'on'
456 self.bulkupdates_option = 'off'
458 self.service = service
459 self.proc_handle = None
460 self.path = os.path.join(self.httpd_dir, 'bin', self.name)
463 self.path_authz_option = 'short_circuit'
465 self.path_authz_option = 'on'
467 if not os.path.exists(self.path):
468 self.name = 'httpd.exe'
469 self.path = os.path.join(self.httpd_dir, 'bin', self.name)
470 if not os.path.exists(self.path):
471 raise RuntimeError("Could not find a valid httpd binary!")
473 self.root_dir = os.path.join(CMDLINE_TEST_SCRIPT_NATIVE_PATH, 'httpd')
474 self.root = os.path.join(abs_builddir, self.root_dir)
475 self.authz_file = os.path.join(abs_builddir,
476 CMDLINE_TEST_SCRIPT_NATIVE_PATH,
477 'svn-test-work', 'authz')
478 self.dontdothat_file = os.path.join(abs_builddir,
479 CMDLINE_TEST_SCRIPT_NATIVE_PATH,
480 'svn-test-work', 'dontdothat')
481 self.httpd_config = os.path.join(self.root, 'httpd.conf')
482 self.httpd_users = os.path.join(self.root, 'users')
483 self.httpd_mime_types = os.path.join(self.root, 'mime.types')
484 self.httpd_groups = os.path.join(self.root, 'groups')
485 self.abs_builddir = abs_builddir
486 self.abs_objdir = abs_objdir
487 self.service_name = 'svn-test-httpd-' + str(httpd_port)
490 self.httpd_args = [self.name, '-n', self._quote(self.service_name),
491 '-f', self._quote(self.httpd_config)]
493 self.httpd_args = [self.name, '-f', self._quote(self.httpd_config)]
495 create_target_dir(self.root_dir)
497 self._create_users_file()
498 self._create_groups_file()
499 self._create_mime_types_file()
500 self._create_dontdothat_file()
503 if os.path.exists(os.path.join(self.httpd_dir,
504 'modules', 'mod_access_compat.so')):
506 elif os.path.exists(os.path.join(self.httpd_dir,
507 'modules', 'mod_auth_basic.so')):
512 # Create httpd config file
513 fp = open(self.httpd_config, 'w')
515 # Limit the number of threads (default = 64)
516 fp.write('<IfModule mpm_winnt.c>\n')
517 fp.write('ThreadsPerChild 16\n')
518 fp.write('</IfModule>\n')
521 fp.write('ServerRoot ' + self._quote(self.root) + '\n')
522 fp.write('DocumentRoot ' + self._quote(self.root) + '\n')
523 fp.write('ServerName localhost\n')
524 fp.write('PidFile pid\n')
525 fp.write('ErrorLog log\n')
526 fp.write('Listen ' + str(self.httpd_port) + '\n')
529 fp.write('LogFormat "%h %l %u %t \\"%r\\" %>s %b" common\n')
530 fp.write('Customlog log common\n')
531 fp.write('LogLevel Debug\n')
533 fp.write('LogLevel Crit\n')
535 # Write LoadModule for minimal system module
536 fp.write(self._sys_module('dav_module', 'mod_dav.so'))
537 if self.httpd_ver >= 2.3:
538 fp.write(self._sys_module('access_compat_module', 'mod_access_compat.so'))
539 fp.write(self._sys_module('authz_core_module', 'mod_authz_core.so'))
540 fp.write(self._sys_module('authz_user_module', 'mod_authz_user.so'))
541 fp.write(self._sys_module('authn_core_module', 'mod_authn_core.so'))
542 if self.httpd_ver >= 2.2:
543 fp.write(self._sys_module('auth_basic_module', 'mod_auth_basic.so'))
544 fp.write(self._sys_module('authn_file_module', 'mod_authn_file.so'))
545 fp.write(self._sys_module('authz_groupfile_module', 'mod_authz_groupfile.so'))
546 fp.write(self._sys_module('authz_host_module', 'mod_authz_host.so'))
548 fp.write(self._sys_module('auth_module', 'mod_auth.so'))
549 fp.write(self._sys_module('alias_module', 'mod_alias.so'))
550 fp.write(self._sys_module('mime_module', 'mod_mime.so'))
551 fp.write(self._sys_module('log_config_module', 'mod_log_config.so'))
553 # Write LoadModule for Subversion modules
554 fp.write(self._svn_module('dav_svn_module', 'mod_dav_svn.so'))
555 fp.write(self._svn_module('authz_svn_module', 'mod_authz_svn.so'))
557 # And for mod_dontdothat
558 fp.write(self._svn_module('dontdothat_module', 'mod_dontdothat.so'))
560 # Don't handle .htaccess, symlinks, etc.
561 fp.write('<Directory />\n')
562 fp.write('AllowOverride None\n')
563 fp.write('Options None\n')
564 fp.write('</Directory>\n\n')
566 # Define two locations for repositories
567 fp.write(self._svn_repo('repositories'))
568 fp.write(self._svn_repo('local_tmp'))
569 fp.write(self._svn_authz_repo())
571 # And two redirects for the redirect tests
572 fp.write('RedirectMatch permanent ^/svn-test-work/repositories/'
573 'REDIRECT-PERM-(.*)$ /svn-test-work/repositories/$1\n')
574 fp.write('RedirectMatch ^/svn-test-work/repositories/'
575 'REDIRECT-TEMP-(.*)$ /svn-test-work/repositories/$1\n')
577 fp.write('TypesConfig ' + self._quote(self.httpd_mime_types) + '\n')
578 fp.write('HostNameLookups Off\n')
583 "Stop httpd when the object is deleted"
586 def _quote(self, arg):
588 return '"' + arg + '"'
592 def _create_users_file(self):
594 htpasswd = os.path.join(self.httpd_dir, 'bin', 'htpasswd.exe')
595 # Create the cheapest to compare password form for our testsuite
596 os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bcp', self.httpd_users,
597 'jrandom', 'rayjandom'])
598 os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp', self.httpd_users,
599 'jconstant', 'rayjandom'])
600 os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp', self.httpd_users,
601 'JRANDOM', 'rayjandom'])
602 os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp', self.httpd_users,
603 'JCONSTANT', 'rayjandom'])
605 def _create_groups_file(self):
606 "Create groups for mod_authz_svn tests"
607 fp = open(self.httpd_groups, 'w')
608 fp.write('random: jrandom\n')
609 fp.write('constant: jconstant\n')
612 def _create_mime_types_file(self):
613 "Create empty mime.types file"
614 fp = open(self.httpd_mime_types, 'w')
617 def _create_dontdothat_file(self):
618 "Create empty mime.types file"
619 # If the tests have not previously been run or were cleaned
620 # up, then 'svn-test-work' does not exist yet.
621 parent_dir = os.path.dirname(self.dontdothat_file)
622 if not os.path.exists(parent_dir):
623 os.makedirs(parent_dir)
625 fp = open(self.dontdothat_file, 'w')
626 fp.write('[recursive-actions]\n')
627 fp.write('/ = deny\n')
630 def _sys_module(self, name, path):
631 full_path = os.path.join(self.httpd_dir, 'modules', path)
632 return 'LoadModule ' + name + " " + self._quote(full_path) + '\n'
634 def _svn_module(self, name, path):
635 full_path = os.path.join(self.abs_objdir, path)
636 return 'LoadModule ' + name + ' ' + self._quote(full_path) + '\n'
638 def _svn_repo(self, name):
639 path = os.path.join(self.abs_builddir,
640 CMDLINE_TEST_SCRIPT_NATIVE_PATH,
641 'svn-test-work', name)
642 location = '/svn-test-work/' + name
643 ddt_location = '/ddt-test-work/' + name
645 '<Location ' + location + '>\n' \
647 ' SVNParentPath ' + self._quote(path) + '\n' \
648 ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
649 ' SVNPathAuthz ' + self.path_authz_option + '\n' \
650 ' SVNAllowBulkUpdates ' + self.bulkupdates_option + '\n' \
651 ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
652 ' AuthType Basic\n' \
653 ' AuthName "Subversion Repository"\n' \
654 ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
655 ' Require valid-user\n' \
657 '<Location ' + ddt_location + '>\n' \
659 ' SVNParentPath ' + self._quote(path) + '\n' \
660 ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
661 ' SVNPathAuthz ' + self.path_authz_option + '\n' \
662 ' SVNAllowBulkUpdates ' + self.bulkupdates_option + '\n' \
663 ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
664 ' AuthType Basic\n' \
665 ' AuthName "Subversion Repository"\n' \
666 ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
667 ' Require valid-user\n' \
668 ' DontDoThatConfigFile ' + self._quote(self.dontdothat_file) + '\n' \
671 def _svn_authz_repo(self):
672 local_tmp = os.path.join(self.abs_builddir,
673 CMDLINE_TEST_SCRIPT_NATIVE_PATH,
674 'svn-test-work', 'local_tmp')
676 '<Location /authz-test-work/anon>' + '\n' \
678 ' SVNParentPath ' + local_tmp + '\n' \
679 ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
680 ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
681 ' SVNListParentPath On' + '\n' \
682 ' <IfModule mod_authz_core.c>' + '\n' \
683 ' Require all granted' + '\n' \
684 ' </IfModule>' + '\n' \
685 ' <IfModule !mod_authz_core.c>' + '\n' \
686 ' Allow from all' + '\n' \
687 ' </IfModule>' + '\n' \
688 ' SVNPathAuthz ' + self.path_authz_option + '\n' \
689 '</Location>' + '\n' \
690 '<Location /authz-test-work/mixed>' + '\n' \
692 ' SVNParentPath ' + local_tmp + '\n' \
693 ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
694 ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
695 ' SVNListParentPath On' + '\n' \
696 ' AuthType Basic' + '\n' \
697 ' AuthName "Subversion Repository"' + '\n' \
698 ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
699 ' Require valid-user' + '\n' \
700 ' Satisfy Any' + '\n' \
701 ' SVNPathAuthz ' + self.path_authz_option + '\n' \
702 '</Location>' + '\n' \
703 '<Location /authz-test-work/mixed-noauthwhenanon>' + '\n' \
705 ' SVNParentPath ' + local_tmp + '\n' \
706 ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
707 ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
708 ' SVNListParentPath On' + '\n' \
709 ' AuthType Basic' + '\n' \
710 ' AuthName "Subversion Repository"' + '\n' \
711 ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
712 ' Require valid-user' + '\n' \
713 ' AuthzSVNNoAuthWhenAnonymousAllowed On' + '\n' \
714 ' SVNPathAuthz On' + '\n' \
715 '</Location>' + '\n' \
716 '<Location /authz-test-work/authn>' + '\n' \
718 ' SVNParentPath ' + local_tmp + '\n' \
719 ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
720 ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
721 ' SVNListParentPath On' + '\n' \
722 ' AuthType Basic' + '\n' \
723 ' AuthName "Subversion Repository"' + '\n' \
724 ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
725 ' Require valid-user' + '\n' \
726 ' SVNPathAuthz ' + self.path_authz_option + '\n' \
727 '</Location>' + '\n' \
728 '<Location /authz-test-work/authn-anonoff>' + '\n' \
730 ' SVNParentPath ' + local_tmp + '\n' \
731 ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
732 ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
733 ' SVNListParentPath On' + '\n' \
734 ' AuthType Basic' + '\n' \
735 ' AuthName "Subversion Repository"' + '\n' \
736 ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
737 ' Require valid-user' + '\n' \
738 ' AuthzSVNAnonymous Off' + '\n' \
739 ' SVNPathAuthz On' + '\n' \
740 '</Location>' + '\n' \
741 '<Location /authz-test-work/authn-lcuser>' + '\n' \
743 ' SVNParentPath ' + local_tmp + '\n' \
744 ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
745 ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
746 ' SVNListParentPath On' + '\n' \
747 ' AuthType Basic' + '\n' \
748 ' AuthName "Subversion Repository"' + '\n' \
749 ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
750 ' Require valid-user' + '\n' \
751 ' AuthzForceUsernameCase Lower' + '\n' \
752 ' SVNPathAuthz ' + self.path_authz_option + '\n' \
753 '</Location>' + '\n' \
754 '<Location /authz-test-work/authn-lcuser>' + '\n' \
756 ' SVNParentPath ' + local_tmp + '\n' \
757 ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
758 ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
759 ' SVNListParentPath On' + '\n' \
760 ' AuthType Basic' + '\n' \
761 ' AuthName "Subversion Repository"' + '\n' \
762 ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
763 ' Require valid-user' + '\n' \
764 ' AuthzForceUsernameCase Lower' + '\n' \
765 ' SVNPathAuthz ' + self.path_authz_option + '\n' \
766 '</Location>' + '\n' \
767 '<Location /authz-test-work/authn-group>' + '\n' \
769 ' SVNParentPath ' + local_tmp + '\n' \
770 ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
771 ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
772 ' SVNListParentPath On' + '\n' \
773 ' AuthType Basic' + '\n' \
774 ' AuthName "Subversion Repository"' + '\n' \
775 ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
776 ' AuthGroupFile ' + self._quote(self.httpd_groups) + '\n' \
777 ' Require group random' + '\n' \
778 ' AuthzSVNAuthoritative Off' + '\n' \
779 ' SVNPathAuthz On' + '\n' \
780 '</Location>' + '\n' \
781 '<IfModule mod_authz_core.c>' + '\n' \
782 '<Location /authz-test-work/sallrany>' + '\n' \
784 ' SVNParentPath ' + local_tmp + '\n' \
785 ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
786 ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
787 ' SVNListParentPath On' + '\n' \
788 ' AuthType Basic' + '\n' \
789 ' AuthName "Subversion Repository"' + '\n' \
790 ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
791 ' AuthzSendForbiddenOnFailure On' + '\n' \
792 ' Satisfy All' + '\n' \
793 ' <RequireAny>' + '\n' \
794 ' Require valid-user' + '\n' \
795 ' Require expr req(\'ALLOW\') == \'1\'' + '\n' \
796 ' </RequireAny>' + '\n' \
797 ' SVNPathAuthz ' + self.path_authz_option + '\n' \
798 '</Location>' + '\n' \
799 '<Location /authz-test-work/sallrall>'+ '\n' \
801 ' SVNParentPath ' + local_tmp + '\n' \
802 ' AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
803 ' SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
804 ' SVNListParentPath On' + '\n' \
805 ' AuthType Basic' + '\n' \
806 ' AuthName "Subversion Repository"' + '\n' \
807 ' AuthUserFile ' + self._quote(self.httpd_users) + '\n' \
808 ' AuthzSendForbiddenOnFailure On' + '\n' \
809 ' Satisfy All' + '\n' \
810 ' <RequireAll>' + '\n' \
811 ' Require valid-user' + '\n' \
812 ' Require expr req(\'ALLOW\') == \'1\'' + '\n' \
813 ' </RequireAll>' + '\n' \
814 ' SVNPathAuthz ' + self.path_authz_option + '\n' \
815 '</Location>' + '\n' \
816 '</IfModule>' + '\n' \
820 self._start_service()
830 def _start_service(self):
831 "Install and start HTTPD service"
832 print('Installing service %s' % self.service_name)
833 os.spawnv(os.P_WAIT, self.path, self.httpd_args + ['-k', 'install'])
834 print('Starting service %s' % self.service_name)
835 os.spawnv(os.P_WAIT, self.path, self.httpd_args + ['-k', 'start'])
837 def _stop_service(self):
838 "Stop and uninstall HTTPD service"
839 os.spawnv(os.P_WAIT, self.path, self.httpd_args + ['-k', 'stop'])
840 os.spawnv(os.P_WAIT, self.path, self.httpd_args + ['-k', 'uninstall'])
842 def _start_daemon(self):
843 "Start HTTPD as daemon"
844 print('Starting httpd as daemon')
845 print(self.httpd_args)
849 args = ' '.join([self._quote(x) for x in self.httpd_args])
851 win32process.CreateProcess(self._quote(self.path), args,
853 win32con.CREATE_NEW_CONSOLE,
854 None, None, win32process.STARTUPINFO()))[0]
856 os.spawnv(os.P_NOWAIT, self.path, self.httpd_args)
858 def _stop_daemon(self):
859 "Stop the HTTPD daemon"
860 if self.proc_handle is not None:
863 print('Stopping %s' % self.name)
864 win32process.TerminateProcess(self.proc_handle, 0)
868 print('Httpd.stop_daemon not implemented')
870 # Move the binaries to the test directory
873 old_cwd = os.getcwd()
877 for dirpath, dirs, files in os.walk('subversion'):
878 copy_execs(baton, dirpath, files)
879 for dirpath, dirs, files in os.walk('tools/server-side'):
880 copy_execs(baton, dirpath, files)
887 # Create the base directory for Python tests
888 create_target_dir(CMDLINE_TEST_SCRIPT_NATIVE_PATH)
890 # Ensure the tests directory is correctly cased
891 abs_builddir = fix_case(abs_builddir)
896 # No need to start any servers if we are only listing the tests.
899 daemon = Svnserve(svnserve_args, objdir, abs_objdir, abs_builddir)
902 daemon = Httpd(abs_httpd_dir, abs_objdir, abs_builddir, httpd_port,
903 httpd_service, httpd_no_log,
904 advertise_httpv2, http_short_circuit,
907 # Start service daemon, if any
911 # Find the full path and filename of any test that is specified just by
913 if len(tests_to_run) != 0:
915 for t in tests_to_run:
918 t, tns = t.split('#')
920 test = [x for x in all_tests if x.split('/')[-1] == t]
921 if not test and not (t.endswith('-test.exe') or t.endswith('_tests.py')):
922 # The lengths of '-test.exe' and of '_tests.py' are both 9.
923 test = [x for x in all_tests if x.split('/')[-1][:-9] == t]
926 print("Skipping test '%s', test not found." % t)
928 tests.append('%s#%s' % (test[0], tns))
934 tests_to_run = all_tests
938 print('Listing %s configuration on %s' % (objdir, repo_loc))
940 print('Testing %s configuration on %s' % (objdir, repo_loc))
941 sys.path.insert(0, os.path.join(abs_srcdir, 'build'))
949 log_file = os.path.join(abs_builddir, log)
950 fail_log_file = os.path.join(abs_builddir, faillog)
953 httpd_version = "%.1f" % daemon.httpd_ver
956 th = run_tests.TestHarness(abs_srcdir, abs_builddir,
959 base_url, fs_type, 'serf',
960 server_minor_version, not quiet,
961 cleanup, enable_sasl, parallel, config_file,
962 fsfs_sharding, fsfs_packing,
963 list_tests, svn_bin, mode_filter,
965 httpd_version=httpd_version,
966 set_log_level=log_level, ssl_cert=ssl_cert)
967 old_cwd = os.getcwd()
969 os.chdir(abs_builddir)
970 failed = th.run(tests_to_run)
980 '-Dtest.rootdir=' + os.path.join(abs_builddir, 'javahl'),
981 '-Dtest.srcdir=' + os.path.join(abs_srcdir,
982 'subversion/bindings/javahl'),
984 '-Dtest.fstype=' + fs_type ,
987 '-Djava.library.path='
988 + os.path.join(abs_objdir,
989 'subversion/bindings/javahl/native'),
991 os.path.join(abs_srcdir, 'subversion/bindings/javahl/classes') +';' +
996 print('Running org.apache.subversion tests:')
999 r = subprocess.call(args + tuple(['org.apache.subversion.javahl.RunTests']))
1003 print('[Test runner reported failure]')
1006 print('Running org.tigris.subversion tests:')
1008 r = subprocess.call(args + tuple(['org.tigris.subversion.javahl.RunTests']))
1012 print('[Test runner reported failure]')
1015 # Stop service daemon, if any
1019 # Remove the execs again
1020 for tgt in copied_execs:
1022 if os.path.isfile(tgt):
1024 print("kill: %s" % tgt)
1027 traceback.print_exc(file=sys.stdout)