~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to win-tests.py

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2015-08-07 21:32:47 UTC
  • mfrom: (0.2.15) (4.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20150807213247-ozyewtmgsr6tkewl
Tags: 1.9.0-1
* Upload to unstable
* New upstream release.
  + Security fixes
    - CVE-2015-3184: Mixed anonymous/authenticated path-based authz with
      httpd 2.4
    - CVE-2015-3187: svn_repos_trace_node_locations() reveals paths hidden
      by authz
* Add >= 2.7 requirement for python-all-dev Build-Depends, needed to run
  tests.
* Remove Build-Conflicts against ruby-test-unit.  (Closes: #791844)
* Remove patches/apache_module_dependency in favor of expressing the
  dependencies in authz_svn.load/dav_svn.load.
* Build-Depend on apache2-dev (>= 2.4.16) to ensure ap_some_authn_required()
  is available when building mod_authz_svn and Depend on apache2-bin (>=
  2.4.16) for runtime support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
For a list of options, run this script with the --help option.
25
25
"""
26
26
 
27
 
# $HeadURL: http://svn.apache.org/repos/asf/subversion/branches/1.8.x/win-tests.py $
28
 
# $LastChangedRevision: 1492044 $
 
27
# $HeadURL: http://svn.apache.org/repos/asf/subversion/branches/1.9.x/win-tests.py $
 
28
# $LastChangedRevision: 1692801 $
29
29
 
30
30
import os, sys, subprocess
31
31
import filecmp
84
84
  print("  --disable-bulk-updates : Disable bulk updates on HTTP server")
85
85
  print("  --ssl-cert             : Path to SSL server certificate to trust.")
86
86
  print("  --javahl               : Run the javahl tests instead of the normal tests")
 
87
  print("  --swig=language        : Run the swig perl/python/ruby tests instead of")
 
88
  print("                           the normal tests")
87
89
  print("  --list                 : print test doc strings only")
88
90
  print("  --milestone-filter=RE  : RE is a regular expression pattern that (when")
89
91
  print("                           used with --list) limits the tests listed to")
108
110
sys.path.insert(0, os.path.join('build', 'generator'))
109
111
sys.path.insert(1, 'build')
110
112
 
111
 
import gen_win
 
113
import gen_win_dependencies
 
114
import gen_base
112
115
version_header = os.path.join('subversion', 'include', 'svn_version.h')
113
116
cp = configparser.ConfigParser()
114
117
cp.read('gen-make.opts')
115
 
gen_obj = gen_win.GeneratorBase('build.conf', version_header,
116
 
                                cp.items('options'))
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)]
120
 
 
121
 
svn_dlls = []
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))
126
 
 
 
118
gen_obj = gen_win_dependencies.GenDependenciesBase('build.conf', version_header,
 
119
                                                   cp.items('options'))
127
120
opts, args = my_getopt(sys.argv[1:], 'hrdvqct:pu:f:',
128
121
                       ['release', 'debug', 'verbose', 'quiet', 'cleanup',
129
122
                        'test=', 'url=', 'svnserve-args=', 'fs-type=', 'asp.net-hack',
130
123
                        'httpd-dir=', 'httpd-port=', 'httpd-daemon',
131
124
                        'httpd-server', 'http-short-circuit', 'httpd-no-log',
132
125
                        'disable-http-v2', 'disable-bulk-updates', 'help',
133
 
                        'fsfs-packing', 'fsfs-sharding=', 'javahl',
 
126
                        'fsfs-packing', 'fsfs-sharding=', 'javahl', 'swig=',
134
127
                        'list', 'enable-sasl', 'bin=', 'parallel',
135
128
                        'config-file=', 'server-minor-version=', 'log-level=',
136
129
                        'log-to-stdout', 'mode-filter=', 'milestone-filter=',
156
149
list_tests = None
157
150
milestone_filter = None
158
151
test_javahl = None
 
152
test_swig = None
159
153
enable_sasl = None
160
154
svn_bin = None
161
155
parallel = None
216
210
    fsfs_packing = 1
217
211
  elif opt == '--javahl':
218
212
    test_javahl = 1
 
213
  elif opt == '--swig':
 
214
    if val not in ['perl', 'python', 'ruby']:
 
215
      sys.stderr.write('Running \'%s\' swig tests not supported (yet).\n'
 
216
                        % (val,))
 
217
    test_swig = val
219
218
  elif opt == '--list':
220
219
    list_tests = 1
221
220
  elif opt == '--milestone-filter':
254
253
if not fs_type:
255
254
  fs_type = 'fsfs'
256
255
 
257
 
# Don't run bdb tests if they want to test fsfs
258
 
if fs_type == 'fsfs':
 
256
if fs_type == 'bdb':
 
257
  all_tests = gen_obj.test_progs + gen_obj.bdb_test_progs \
 
258
            + gen_obj.scripts + gen_obj.bdb_scripts
 
259
else:
259
260
  all_tests = gen_obj.test_progs + gen_obj.scripts
260
261
 
 
262
client_tests = [x for x in all_tests if x.startswith(CMDLINE_TEST_SCRIPT_PATH)]
 
263
 
261
264
if run_httpd:
262
265
  if not httpd_port:
263
266
    httpd_port = random.randrange(1024, 30000)
289
292
      print("mkdir: %s" % tgt_dir)
290
293
    os.makedirs(tgt_dir)
291
294
 
292
 
def copy_changed_file(src, tgt):
 
295
def copy_changed_file(src, tgt=None, to_dir=None, cleanup=True):
293
296
  if not os.path.isfile(src):
294
297
    print('Could not find ' + src)
295
298
    sys.exit(1)
296
 
  if os.path.isdir(tgt):
297
 
    tgt = os.path.join(tgt, os.path.basename(src))
 
299
 
 
300
  if to_dir and not tgt:
 
301
    tgt = os.path.join(to_dir, os.path.basename(src))
 
302
  elif not tgt or (tgt and to_dir):
 
303
    raise RuntimeError("Using 'tgt' *or* 'to_dir' is required" % (tgt,))
 
304
  elif tgt and os.path.isdir(tgt):
 
305
    raise RuntimeError("'%s' is a directory. Use to_dir=" % (tgt,))
 
306
 
298
307
  if os.path.exists(tgt):
299
308
    assert os.path.isfile(tgt)
300
309
    if filecmp.cmp(src, tgt):
306
315
    print("copy: %s" % src)
307
316
    print("  to: %s" % tgt)
308
317
  shutil.copy(src, tgt)
309
 
  return 1
310
318
 
311
 
def copy_execs(baton, dirname, names):
312
 
  copied_execs = baton
313
 
  for name in names:
314
 
    if not name.endswith('.exe'):
315
 
      continue
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)
 
319
  if cleanup:
 
320
    copied_execs.append(tgt)
321
321
 
322
322
def locate_libs():
323
323
  "Move DLLs to a known location and set env vars"
324
324
 
325
 
  dlls = []
326
 
 
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):
330
 
    suffix = "-1"
331
 
  else:
332
 
    suffix = ""
333
 
 
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)))
339
 
 
340
 
  if gen_obj.libintl_path is not None:
341
 
    dlls.append(os.path.join(gen_obj.libintl_path, 'bin', 'intl3_svn.dll'))
342
 
 
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')
 
325
  debug = (objdir == 'Debug')
 
326
 
 
327
  for lib in gen_obj._libraries.values():
 
328
 
 
329
    if debug:
 
330
      name, dir = lib.debug_dll_name, lib.debug_dll_dir
347
331
    else:
348
 
      dlls.append(partial_path + '.dll')
349
 
 
350
 
  if gen_obj.sasl_path is not None:
351
 
    dlls.append(os.path.join(gen_obj.sasl_path, 'lib', 'libsasl.dll'))
352
 
 
353
 
  for dll in dlls:
354
 
    copy_changed_file(dll, abs_objdir)
 
332
      name, dir = lib.dll_name, lib.dll_dir
 
333
 
 
334
    if name and dir:
 
335
      src = os.path.join(dir, name)
 
336
      if os.path.exists(src):
 
337
        copy_changed_file(src, to_dir=abs_builddir, cleanup=False)
 
338
 
 
339
    for name in lib.extra_bin:
 
340
      src = os.path.join(dir, name)
 
341
      copy_changed_file(src, to_dir=abs_builddir)
 
342
 
355
343
 
356
344
  # 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)
 
345
  for i in gen_obj.graph.get_all_sources(gen_base.DT_INSTALL):
 
346
    if isinstance(i, gen_base.TargetLib) and i.msvc_export:
 
347
      src = os.path.join(abs_objdir, i.filename)
 
348
      if os.path.isfile(src):
 
349
        copy_changed_file(src, to_dir=abs_builddir,
 
350
                          cleanup=False)
360
351
 
361
352
  # Copy the Apache modules
362
353
  if run_httpd and cp.has_option('options', '--with-httpd'):
367
358
    mod_dontdothat_path = os.path.join(abs_objdir, 'tools', 'server-side',
368
359
                                        'mod_dontdothat', 'mod_dontdothat.so')
369
360
 
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)
 
361
    copy_changed_file(mod_dav_svn_path, to_dir=abs_builddir, cleanup=False)
 
362
    copy_changed_file(mod_authz_svn_path, to_dir=abs_builddir, cleanup=False)
 
363
    copy_changed_file(mod_dontdothat_path, to_dir=abs_builddir, cleanup=False)
373
364
 
374
 
  os.environ['PATH'] = abs_objdir + os.pathsep + os.environ['PATH']
 
365
  os.environ['PATH'] = abs_builddir + os.pathsep + os.environ['PATH']
375
366
 
376
367
def fix_case(path):
377
368
    path = os.path.normpath(path)
396
387
    self.path = os.path.join(abs_objdir,
397
388
                             'subversion', 'svnserve', self.name)
398
389
    self.root = os.path.join(abs_builddir, CMDLINE_TEST_SCRIPT_NATIVE_PATH)
399
 
    self.proc_handle = None
 
390
    self.proc = None
400
391
 
401
392
  def __del__(self):
402
393
    "Stop svnserve when the object is deleted"
414
405
    else:
415
406
      args = [self.name] + self.args
416
407
    print('Starting %s %s' % (self.kind, self.name))
417
 
    try:
418
 
      import win32process
419
 
      import win32con
420
 
      args = ' '.join([self._quote(x) for x in args])
421
 
      self.proc_handle = (
422
 
        win32process.CreateProcess(self._quote(self.path), args,
423
 
                                   None, None, 0,
424
 
                                   win32con.CREATE_NEW_CONSOLE,
425
 
                                   None, None, win32process.STARTUPINFO()))[0]
426
 
    except ImportError:
427
 
      os.spawnv(os.P_NOWAIT, self.path, args)
 
408
 
 
409
    self.proc = subprocess.Popen([self.path] + args[1:])
428
410
 
429
411
  def stop(self):
430
 
    if self.proc_handle is not None:
 
412
    if self.proc is not None:
431
413
      try:
432
 
        import win32process
433
414
        print('Stopping %s' % self.name)
434
 
        win32process.TerminateProcess(self.proc_handle, 0)
 
415
        self.proc.poll();
 
416
        if self.proc.returncode is None:
 
417
          self.proc.kill();
435
418
        return
436
 
      except ImportError:
 
419
      except AttributeError:
437
420
        pass
438
421
    print('Svnserve.stop not implemented')
439
422
 
456
439
      self.bulkupdates_option = 'off'
457
440
 
458
441
    self.service = service
459
 
    self.proc_handle = None
 
442
    self.proc = None
460
443
    self.path = os.path.join(self.httpd_dir, 'bin', self.name)
461
444
 
462
445
    if short_circuit:
481
464
    self.httpd_config = os.path.join(self.root, 'httpd.conf')
482
465
    self.httpd_users = os.path.join(self.root, 'users')
483
466
    self.httpd_mime_types = os.path.join(self.root, 'mime.types')
 
467
    self.httpd_groups = os.path.join(self.root, 'groups')
484
468
    self.abs_builddir = abs_builddir
485
469
    self.abs_objdir = abs_objdir
486
470
    self.service_name = 'svn-test-httpd-' + str(httpd_port)
494
478
    create_target_dir(self.root_dir)
495
479
 
496
480
    self._create_users_file()
 
481
    self._create_groups_file()
497
482
    self._create_mime_types_file()
498
483
    self._create_dontdothat_file()
499
484
 
500
 
    # Determine version.
501
 
    if os.path.exists(os.path.join(self.httpd_dir,
502
 
                                   'modules', 'mod_access_compat.so')):
503
 
      self.httpd_ver = 2.3
504
 
    elif os.path.exists(os.path.join(self.httpd_dir,
505
 
                                     'modules', 'mod_auth_basic.so')):
506
 
      self.httpd_ver = 2.2
507
 
    else:
508
 
      self.httpd_ver = 2.0
 
485
    # Obtain version.
 
486
    version_vals = gen_obj._libraries['httpd'].version.split('.')
 
487
    self.httpd_ver = float('%s.%s' % (version_vals[0], version_vals[1]))
509
488
 
510
489
    # Create httpd config file
511
490
    fp = open(self.httpd_config, 'w')
540
519
    if self.httpd_ver >= 2.2:
541
520
      fp.write(self._sys_module('auth_basic_module', 'mod_auth_basic.so'))
542
521
      fp.write(self._sys_module('authn_file_module', 'mod_authn_file.so'))
 
522
      fp.write(self._sys_module('authz_groupfile_module', 'mod_authz_groupfile.so'))
 
523
      fp.write(self._sys_module('authz_host_module', 'mod_authz_host.so'))
543
524
    else:
544
525
      fp.write(self._sys_module('auth_module', 'mod_auth.so'))
545
526
    fp.write(self._sys_module('alias_module', 'mod_alias.so'))
562
543
    # Define two locations for repositories
563
544
    fp.write(self._svn_repo('repositories'))
564
545
    fp.write(self._svn_repo('local_tmp'))
 
546
    fp.write(self._svn_authz_repo())
565
547
 
566
548
    # And two redirects for the redirect tests
567
549
    fp.write('RedirectMatch permanent ^/svn-test-work/repositories/'
592
574
                                    'jrandom', 'rayjandom'])
593
575
    os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp',  self.httpd_users,
594
576
                                    'jconstant', 'rayjandom'])
 
577
    os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp',  self.httpd_users,
 
578
                                    'JRANDOM', 'rayjandom'])
 
579
    os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp',  self.httpd_users,
 
580
                                    'JCONSTANT', 'rayjandom'])
 
581
 
 
582
  def _create_groups_file(self):
 
583
    "Create groups for mod_authz_svn tests"
 
584
    fp = open(self.httpd_groups, 'w')
 
585
    fp.write('random: jrandom\n')
 
586
    fp.write('constant: jconstant\n')
 
587
    fp.close()
595
588
 
596
589
  def _create_mime_types_file(self):
597
590
    "Create empty mime.types file"
616
609
    return 'LoadModule ' + name + " " + self._quote(full_path) + '\n'
617
610
 
618
611
  def _svn_module(self, name, path):
619
 
    full_path = os.path.join(self.abs_objdir, path)
 
612
    full_path = os.path.join(self.abs_builddir, path)
620
613
    return 'LoadModule ' + name + ' ' + self._quote(full_path) + '\n'
621
614
 
622
615
  def _svn_repo(self, name):
652
645
      '  DontDoThatConfigFile ' + self._quote(self.dontdothat_file) + '\n' \
653
646
      '</Location>\n'
654
647
 
 
648
  def _svn_authz_repo(self):
 
649
    local_tmp = os.path.join(self.abs_builddir,
 
650
                             CMDLINE_TEST_SCRIPT_NATIVE_PATH,
 
651
                             'svn-test-work', 'local_tmp')
 
652
    return \
 
653
      '<Location /authz-test-work/anon>' + '\n' \
 
654
      '  DAV               svn' + '\n' \
 
655
      '  SVNParentPath     ' + local_tmp + '\n' \
 
656
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
 
657
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
 
658
      '  SVNListParentPath On' + '\n' \
 
659
      '  <IfModule mod_authz_core.c>' + '\n' \
 
660
      '    Require all granted' + '\n' \
 
661
      '  </IfModule>' + '\n' \
 
662
      '  <IfModule !mod_authz_core.c>' + '\n' \
 
663
      '    Allow from all' + '\n' \
 
664
      '  </IfModule>' + '\n' \
 
665
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
 
666
      '</Location>' + '\n' \
 
667
      '<Location /authz-test-work/mixed>' + '\n' \
 
668
      '  DAV               svn' + '\n' \
 
669
      '  SVNParentPath     ' + local_tmp + '\n' \
 
670
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
 
671
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
 
672
      '  SVNListParentPath On' + '\n' \
 
673
      '  AuthType          Basic' + '\n' \
 
674
      '  AuthName          "Subversion Repository"' + '\n' \
 
675
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
 
676
      '  Require           valid-user' + '\n' \
 
677
      '  Satisfy Any' + '\n' \
 
678
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
 
679
      '</Location>' + '\n' \
 
680
      '<Location /authz-test-work/mixed-noauthwhenanon>' + '\n' \
 
681
      '  DAV               svn' + '\n' \
 
682
      '  SVNParentPath     ' + local_tmp + '\n' \
 
683
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
 
684
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
 
685
      '  SVNListParentPath On' + '\n' \
 
686
      '  AuthType          Basic' + '\n' \
 
687
      '  AuthName          "Subversion Repository"' + '\n' \
 
688
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
 
689
      '  Require           valid-user' + '\n' \
 
690
      '  AuthzSVNNoAuthWhenAnonymousAllowed On' + '\n' \
 
691
      '  SVNPathAuthz On' + '\n' \
 
692
      '</Location>' + '\n' \
 
693
      '<Location /authz-test-work/authn>' + '\n' \
 
694
      '  DAV               svn' + '\n' \
 
695
      '  SVNParentPath     ' + local_tmp + '\n' \
 
696
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
 
697
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
 
698
      '  SVNListParentPath On' + '\n' \
 
699
      '  AuthType          Basic' + '\n' \
 
700
      '  AuthName          "Subversion Repository"' + '\n' \
 
701
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
 
702
      '  Require           valid-user' + '\n' \
 
703
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
 
704
      '</Location>' + '\n' \
 
705
      '<Location /authz-test-work/authn-anonoff>' + '\n' \
 
706
      '  DAV               svn' + '\n' \
 
707
      '  SVNParentPath     ' + local_tmp + '\n' \
 
708
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
 
709
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
 
710
      '  SVNListParentPath On' + '\n' \
 
711
      '  AuthType          Basic' + '\n' \
 
712
      '  AuthName          "Subversion Repository"' + '\n' \
 
713
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
 
714
      '  Require           valid-user' + '\n' \
 
715
      '  AuthzSVNAnonymous Off' + '\n' \
 
716
      '  SVNPathAuthz On' + '\n' \
 
717
      '</Location>' + '\n' \
 
718
      '<Location /authz-test-work/authn-lcuser>' + '\n' \
 
719
      '  DAV               svn' + '\n' \
 
720
      '  SVNParentPath     ' + local_tmp + '\n' \
 
721
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
 
722
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
 
723
      '  SVNListParentPath On' + '\n' \
 
724
      '  AuthType          Basic' + '\n' \
 
725
      '  AuthName          "Subversion Repository"' + '\n' \
 
726
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
 
727
      '  Require           valid-user' + '\n' \
 
728
      '  AuthzForceUsernameCase Lower' + '\n' \
 
729
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
 
730
      '</Location>' + '\n' \
 
731
      '<Location /authz-test-work/authn-lcuser>' + '\n' \
 
732
      '  DAV               svn' + '\n' \
 
733
      '  SVNParentPath     ' + local_tmp + '\n' \
 
734
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
 
735
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
 
736
      '  SVNListParentPath On' + '\n' \
 
737
      '  AuthType          Basic' + '\n' \
 
738
      '  AuthName          "Subversion Repository"' + '\n' \
 
739
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
 
740
      '  Require           valid-user' + '\n' \
 
741
      '  AuthzForceUsernameCase Lower' + '\n' \
 
742
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
 
743
      '</Location>' + '\n' \
 
744
      '<Location /authz-test-work/authn-group>' + '\n' \
 
745
      '  DAV               svn' + '\n' \
 
746
      '  SVNParentPath     ' + local_tmp + '\n' \
 
747
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
 
748
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
 
749
      '  SVNListParentPath On' + '\n' \
 
750
      '  AuthType          Basic' + '\n' \
 
751
      '  AuthName          "Subversion Repository"' + '\n' \
 
752
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
 
753
      '  AuthGroupFile    ' + self._quote(self.httpd_groups) + '\n' \
 
754
      '  Require           group random' + '\n' \
 
755
      '  AuthzSVNAuthoritative Off' + '\n' \
 
756
      '  SVNPathAuthz On' + '\n' \
 
757
      '</Location>' + '\n' \
 
758
      '<IfModule mod_authz_core.c>' + '\n' \
 
759
      '<Location /authz-test-work/sallrany>' + '\n' \
 
760
      '  DAV               svn' + '\n' \
 
761
      '  SVNParentPath     ' + local_tmp + '\n' \
 
762
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
 
763
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
 
764
      '  SVNListParentPath On' + '\n' \
 
765
      '  AuthType          Basic' + '\n' \
 
766
      '  AuthName          "Subversion Repository"' + '\n' \
 
767
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
 
768
      '  AuthzSendForbiddenOnFailure On' + '\n' \
 
769
      '  Satisfy All' + '\n' \
 
770
      '  <RequireAny>' + '\n' \
 
771
      '    Require valid-user' + '\n' \
 
772
      '    Require expr req(\'ALLOW\') == \'1\'' + '\n' \
 
773
      '  </RequireAny>' + '\n' \
 
774
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
 
775
      '</Location>' + '\n' \
 
776
      '<Location /authz-test-work/sallrall>'+ '\n' \
 
777
      '  DAV               svn' + '\n' \
 
778
      '  SVNParentPath     ' + local_tmp + '\n' \
 
779
      '  AuthzSVNAccessFile ' + self._quote(self.authz_file) + '\n' \
 
780
      '  SVNAdvertiseV2Protocol ' + self.httpv2_option + '\n' \
 
781
      '  SVNListParentPath On' + '\n' \
 
782
      '  AuthType          Basic' + '\n' \
 
783
      '  AuthName          "Subversion Repository"' + '\n' \
 
784
      '  AuthUserFile    ' + self._quote(self.httpd_users) + '\n' \
 
785
      '  AuthzSendForbiddenOnFailure On' + '\n' \
 
786
      '  Satisfy All' + '\n' \
 
787
      '  <RequireAll>' + '\n' \
 
788
      '  Require valid-user' + '\n' \
 
789
      '  Require expr req(\'ALLOW\') == \'1\'' + '\n' \
 
790
      '</RequireAll>' + '\n' \
 
791
      '  SVNPathAuthz ' + self.path_authz_option + '\n' \
 
792
      '</Location>' + '\n' \
 
793
      '</IfModule>' + '\n' \
 
794
 
655
795
  def start(self):
656
796
    if self.service:
657
797
      self._start_service()
680
820
    "Start HTTPD as daemon"
681
821
    print('Starting httpd as daemon')
682
822
    print(self.httpd_args)
683
 
    try:
684
 
      import win32process
685
 
      import win32con
686
 
      args = ' '.join([self._quote(x) for x in self.httpd_args])
687
 
      self.proc_handle = (
688
 
        win32process.CreateProcess(self._quote(self.path), args,
689
 
                                   None, None, 0,
690
 
                                   win32con.CREATE_NEW_CONSOLE,
691
 
                                   None, None, win32process.STARTUPINFO()))[0]
692
 
    except ImportError:
693
 
      os.spawnv(os.P_NOWAIT, self.path, self.httpd_args)
 
823
    self.proc = subprocess.Popen([self.path] + self.httpd_args[1:])
694
824
 
695
825
  def _stop_daemon(self):
696
826
    "Stop the HTTPD daemon"
697
 
    if self.proc_handle is not None:
 
827
    if self.proc is not None:
698
828
      try:
699
 
        import win32process
700
829
        print('Stopping %s' % self.name)
701
 
        win32process.TerminateProcess(self.proc_handle, 0)
 
830
        self.proc.poll();
 
831
        if self.proc.returncode is None:
 
832
          self.proc.kill();
702
833
        return
703
 
      except ImportError:
 
834
      except AttributeError:
704
835
        pass
705
836
    print('Httpd.stop_daemon not implemented')
706
837
 
707
838
# Move the binaries to the test directory
 
839
create_target_dir(abs_builddir)
708
840
locate_libs()
709
841
if create_dirs:
710
 
  old_cwd = os.getcwd()
711
 
  try:
712
 
    os.chdir(abs_objdir)
713
 
    baton = copied_execs
714
 
    for dirpath, dirs, files in os.walk('subversion'):
715
 
      copy_execs(baton, dirpath, files)
716
 
    for dirpath, dirs, files in os.walk('tools/server-side'):
717
 
      copy_execs(baton, dirpath, files)
718
 
  except:
719
 
    os.chdir(old_cwd)
720
 
    raise
721
 
  else:
722
 
    os.chdir(old_cwd)
 
842
  for i in gen_obj.graph.get_all_sources(gen_base.DT_INSTALL):
 
843
    if isinstance(i, gen_base.TargetExe):
 
844
      src = os.path.join(abs_objdir, i.filename)
 
845
 
 
846
      if os.path.isfile(src):
 
847
        dst = os.path.join(abs_builddir, i.filename)
 
848
        create_target_dir(os.path.dirname(dst))
 
849
        copy_changed_file(src, dst)
723
850
 
724
851
# Create the base directory for Python tests
725
852
create_target_dir(CMDLINE_TEST_SCRIPT_NATIVE_PATH)
777
904
  print('Testing %s configuration on %s' % (objdir, repo_loc))
778
905
sys.path.insert(0, os.path.join(abs_srcdir, 'build'))
779
906
 
780
 
if not test_javahl:
 
907
if not test_javahl and not test_swig:
781
908
  import run_tests
782
909
  if log_to_stdout:
783
910
    log_file = None
786
913
    log_file = os.path.join(abs_builddir, log)
787
914
    fail_log_file = os.path.join(abs_builddir, faillog)
788
915
 
 
916
  if run_httpd:
 
917
    httpd_version = gen_obj._libraries['httpd'].version
 
918
  else:
 
919
    httpd_version = None
789
920
  th = run_tests.TestHarness(abs_srcdir, abs_builddir,
790
921
                             log_file,
791
922
                             fail_log_file,
795
926
                             fsfs_sharding, fsfs_packing,
796
927
                             list_tests, svn_bin, mode_filter,
797
928
                             milestone_filter,
 
929
                             httpd_version=httpd_version,
798
930
                             set_log_level=log_level, ssl_cert=ssl_cert)
799
931
  old_cwd = os.getcwd()
800
932
  try:
805
937
    raise
806
938
  else:
807
939
    os.chdir(old_cwd)
808
 
else:
809
 
  failed = False
810
 
  args = (
811
 
          'java.exe',
812
 
          '-Dtest.rootdir=' + os.path.join(abs_builddir, 'javahl'),
813
 
          '-Dtest.srcdir=' + os.path.join(abs_srcdir,
814
 
                                          'subversion/bindings/javahl'),
815
 
          '-Dtest.rooturl=',
816
 
          '-Dtest.fstype=' + fs_type ,
817
 
          '-Dtest.tests=',
818
 
 
819
 
          '-Djava.library.path='
820
 
                    + os.path.join(abs_objdir,
821
 
                                   'subversion/bindings/javahl/native'),
822
 
          '-classpath',
823
 
          os.path.join(abs_srcdir, 'subversion/bindings/javahl/classes') +';' +
824
 
            gen_obj.junit_path
825
 
         )
826
 
 
827
 
  sys.stderr.flush()
828
 
  print('Running org.apache.subversion tests:')
829
 
  sys.stdout.flush()
830
 
 
831
 
  r = subprocess.call(args + tuple(['org.apache.subversion.javahl.RunTests']))
832
 
  sys.stdout.flush()
833
 
  sys.stderr.flush()
834
 
  if (r != 0):
835
 
    print('[Test runner reported failure]')
836
 
    failed = True
837
 
 
838
 
  print('Running org.tigris.subversion tests:')
839
 
  sys.stdout.flush()
840
 
  r = subprocess.call(args + tuple(['org.tigris.subversion.javahl.RunTests']))
841
 
  sys.stdout.flush()
842
 
  sys.stderr.flush()
843
 
  if (r != 0):
844
 
    print('[Test runner reported failure]')
845
 
    failed = True
 
940
elif test_javahl:
 
941
  failed = False
 
942
 
 
943
  java_exe = None
 
944
 
 
945
  for path in os.environ["PATH"].split(os.pathsep):
 
946
    if os.path.isfile(os.path.join(path, 'java.exe')):
 
947
      java_exe = os.path.join(path, 'java.exe')
 
948
      break
 
949
 
 
950
  if not java_exe and 'java_sdk' in gen_obj._libraries:
 
951
    jdk = gen_obj._libraries['java_sdk']
 
952
 
 
953
    if os.path.isfile(os.path.join(jdk.lib_dir, '../bin/java.exe')):
 
954
      java_exe = os.path.join(jdk.lib_dir, '../bin/java.exe')
 
955
 
 
956
  if not java_exe:
 
957
    print('Java not found. Skipping Java tests')
 
958
  else:
 
959
    args = (os.path.abspath(java_exe),)
 
960
    if (objdir == 'Debug'):
 
961
      args = args + ('-Xcheck:jni',)
 
962
 
 
963
    args = args + (
 
964
            '-Dtest.rootdir=' + os.path.join(abs_builddir, 'javahl'),
 
965
            '-Dtest.srcdir=' + os.path.join(abs_srcdir,
 
966
                                            'subversion/bindings/javahl'),
 
967
            '-Dtest.rooturl=',
 
968
            '-Dtest.fstype=' + fs_type ,
 
969
            '-Dtest.tests=',
 
970
 
 
971
            '-Djava.library.path='
 
972
                      + os.path.join(abs_objdir,
 
973
                                     'subversion/bindings/javahl/native'),
 
974
            '-classpath',
 
975
            os.path.join(abs_srcdir, 'subversion/bindings/javahl/classes') +';' +
 
976
              gen_obj.junit_path
 
977
           )
 
978
 
 
979
    sys.stderr.flush()
 
980
    print('Running org.apache.subversion tests:')
 
981
    sys.stdout.flush()
 
982
 
 
983
    r = subprocess.call(args + tuple(['org.apache.subversion.javahl.RunTests']))
 
984
    sys.stdout.flush()
 
985
    sys.stderr.flush()
 
986
    if (r != 0):
 
987
      print('[Test runner reported failure]')
 
988
      failed = True
 
989
 
 
990
    print('Running org.tigris.subversion tests:')
 
991
    sys.stdout.flush()
 
992
    r = subprocess.call(args + tuple(['org.tigris.subversion.javahl.RunTests']))
 
993
    sys.stdout.flush()
 
994
    sys.stderr.flush()
 
995
    if (r != 0):
 
996
      print('[Test runner reported failure]')
 
997
      failed = True
 
998
elif test_swig == 'perl':
 
999
  failed = False
 
1000
  swig_dir = os.path.join(abs_builddir, 'swig')
 
1001
  swig_pl_dir = os.path.join(swig_dir, 'p5lib')
 
1002
  swig_pl_svn = os.path.join(swig_pl_dir, 'SVN')
 
1003
  swig_pl_auto_svn = os.path.join(swig_pl_dir, 'auto', 'SVN')
 
1004
 
 
1005
  create_target_dir(swig_pl_svn)
 
1006
 
 
1007
  for i in gen_obj.graph.get_all_sources(gen_base.DT_INSTALL):
 
1008
    if isinstance(i, gen_base.TargetSWIG) and i.lang == 'perl':
 
1009
      mod_dir = os.path.join(swig_pl_auto_svn, '_' + i.name[5:].capitalize())
 
1010
      create_target_dir(mod_dir)
 
1011
      copy_changed_file(os.path.join(abs_objdir, i.filename), to_dir=mod_dir)
 
1012
 
 
1013
    elif isinstance(i, gen_base.TargetSWIGLib) and i.lang == 'perl':
 
1014
      copy_changed_file(os.path.join(abs_objdir, i.filename),
 
1015
                        to_dir=abs_builddir)
 
1016
 
 
1017
  pm_src = os.path.join(abs_srcdir, 'subversion', 'bindings', 'swig', 'perl',
 
1018
                        'native')
 
1019
 
 
1020
  tests = []
 
1021
 
 
1022
  for root, dirs, files in os.walk(pm_src):
 
1023
    for name in files:
 
1024
      if name.endswith('.pm'):
 
1025
        fn = os.path.join(root, name)
 
1026
        copy_changed_file(fn, to_dir=swig_pl_svn)
 
1027
      elif name.endswith('.t'):
 
1028
        tests.append(os.path.relpath(os.path.join(root, name), pm_src))
 
1029
 
 
1030
  perl5lib = swig_pl_dir
 
1031
  if 'PERL5LIB' in os.environ:
 
1032
    perl5lib += os.pathsep + os.environ['PERL5LIB']
 
1033
 
 
1034
  perl_exe = 'perl.exe'
 
1035
 
 
1036
  print('-- Running Swig Perl tests --')
 
1037
  sys.stdout.flush()
 
1038
  old_cwd = os.getcwd()
 
1039
  try:
 
1040
    os.chdir(pm_src)
 
1041
 
 
1042
    os.environ['PERL5LIB'] = perl5lib
 
1043
    os.environ["SVN_DBG_NO_ABORT_ON_ERROR_LEAK"] = 'YES'
 
1044
 
 
1045
    r = subprocess.call([
 
1046
              perl_exe,
 
1047
              '-MExtUtils::Command::MM',
 
1048
              '-e', 'test_harness()'
 
1049
              ] + tests)
 
1050
  finally:
 
1051
    os.chdir(old_cwd)
 
1052
 
 
1053
  if (r != 0):
 
1054
    print('[Test runner reported failure]')
 
1055
    failed = True
 
1056
elif test_swig == 'python':
 
1057
  failed = False
 
1058
  swig_dir = os.path.join(abs_builddir, 'swig')
 
1059
  swig_py_dir = os.path.join(swig_dir, 'pylib')
 
1060
  swig_py_libsvn = os.path.join(swig_py_dir, 'libsvn')
 
1061
  swig_py_svn = os.path.join(swig_py_dir, 'svn')
 
1062
 
 
1063
  create_target_dir(swig_py_libsvn)
 
1064
  create_target_dir(swig_py_svn)
 
1065
 
 
1066
  for i in gen_obj.graph.get_all_sources(gen_base.DT_INSTALL):
 
1067
    if (isinstance(i, gen_base.TargetSWIG)
 
1068
        or isinstance(i, gen_base.TargetSWIGLib)) and i.lang == 'python':
 
1069
 
 
1070
      src = os.path.join(abs_objdir, i.filename)
 
1071
      copy_changed_file(src, to_dir=swig_py_libsvn)
 
1072
 
 
1073
  py_src = os.path.join(abs_srcdir, 'subversion', 'bindings', 'swig', 'python')
 
1074
 
 
1075
  for py_file in os.listdir(py_src):
 
1076
    if py_file.endswith('.py'):
 
1077
      copy_changed_file(os.path.join(py_src, py_file),
 
1078
                        to_dir=swig_py_libsvn)
 
1079
 
 
1080
  py_src_svn = os.path.join(py_src, 'svn')
 
1081
  for py_file in os.listdir(py_src_svn):
 
1082
    if py_file.endswith('.py'):
 
1083
      copy_changed_file(os.path.join(py_src_svn, py_file),
 
1084
                        to_dir=swig_py_svn)
 
1085
 
 
1086
  print('-- Running Swig Python tests --')
 
1087
  sys.stdout.flush()
 
1088
 
 
1089
  pythonpath = swig_py_dir
 
1090
  if 'PYTHONPATH' in os.environ:
 
1091
    pythonpath += os.pathsep + os.environ['PYTHONPATH']
 
1092
 
 
1093
  python_exe = 'python.exe'
 
1094
  old_cwd = os.getcwd()
 
1095
  try:
 
1096
    os.environ['PYTHONPATH'] = pythonpath
 
1097
 
 
1098
    r = subprocess.call([
 
1099
              python_exe,
 
1100
              os.path.join(py_src, 'tests', 'run_all.py')
 
1101
              ])
 
1102
  finally:
 
1103
    os.chdir(old_cwd)
 
1104
 
 
1105
    if (r != 0):
 
1106
      print('[Test runner reported failure]')
 
1107
      failed = True
 
1108
 
 
1109
elif test_swig == 'ruby':
 
1110
  failed = False
 
1111
 
 
1112
  if 'ruby' not in gen_obj._libraries:
 
1113
    print('Ruby not found. Skipping Ruby tests')
 
1114
  else:
 
1115
    ruby_lib = gen_obj._libraries['ruby']
 
1116
 
 
1117
    ruby_exe = 'ruby.exe'
 
1118
    ruby_subdir = os.path.join('subversion', 'bindings', 'swig', 'ruby')
 
1119
    ruby_args = [
 
1120
        '-I', os.path.join(abs_srcdir, ruby_subdir),
 
1121
        os.path.join(abs_srcdir, ruby_subdir, 'test', 'run-test.rb'),
 
1122
        '--verbose'
 
1123
      ]
 
1124
 
 
1125
    print('-- Running Swig Ruby tests --')
 
1126
    sys.stdout.flush()
 
1127
    old_cwd = os.getcwd()
 
1128
    try:
 
1129
      os.chdir(ruby_subdir)
 
1130
 
 
1131
      os.environ["BUILD_TYPE"] = objdir
 
1132
      os.environ["SVN_DBG_NO_ABORT_ON_ERROR_LEAK"] = 'YES'
 
1133
      r = subprocess.call([ruby_exe] + ruby_args)
 
1134
    finally:
 
1135
      os.chdir(old_cwd)
 
1136
 
 
1137
    sys.stdout.flush()
 
1138
    sys.stderr.flush()
 
1139
    if (r != 0):
 
1140
      print('[Test runner reported failure]')
 
1141
      failed = True
846
1142
 
847
1143
# Stop service daemon, if any
848
1144
if daemon: