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

« back to all changes in this revision

Viewing changes to subversion/tests/cmdline/svnadmin_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:
26
26
 
27
27
# General modules
28
28
import os
 
29
import logging
29
30
import re
30
31
import shutil
31
32
import sys
32
33
import threading
33
 
import logging
 
34
import time
 
35
import gzip
34
36
 
35
37
logger = logging.getLogger()
36
38
 
48
50
Issues = svntest.testcase.Issues_deco
49
51
Issue = svntest.testcase.Issue_deco
50
52
Wimp = svntest.testcase.Wimp_deco
 
53
SkipDumpLoadCrossCheck = svntest.testcase.SkipDumpLoadCrossCheck_deco
51
54
Item = svntest.wc.StateItem
52
55
 
53
56
def check_hotcopy_bdb(src, dst):
61
64
  if origerr or backerr or origout != backout:
62
65
    raise svntest.Failure
63
66
 
64
 
def check_hotcopy_fsfs(src, dst):
65
 
    "Verify that the SRC FSFS repository has been correctly copied to DST."
 
67
def check_hotcopy_fsfs_fsx(src, dst):
66
68
    # Walk the source and compare all files to the destination
67
69
    for src_dirpath, src_dirs, src_files in os.walk(src):
68
70
      # Verify that the current directory exists in the destination
72
74
                              "destination" % dst_dirpath)
73
75
      # Verify that all dirents in the current directory also exist in source
74
76
      for dst_dirent in os.listdir(dst_dirpath):
 
77
        # Ignore auto-created empty lock files as they may or may not
 
78
        # be present and are neither required by nor do they harm to
 
79
        # the destination repository.
 
80
        if dst_dirent == 'pack-lock':
 
81
          continue
 
82
        if dst_dirent == 'write-lock':
 
83
          continue
 
84
 
 
85
        # Ignore auto-created rep-cache.db-journal file
 
86
        if dst_dirent == 'rep-cache.db-journal':
 
87
          continue
 
88
 
75
89
        src_dirent = os.path.join(src_dirpath, dst_dirent)
76
90
        if not os.path.exists(src_dirent):
77
91
          raise svntest.Failure("%s does not exist in hotcopy "
78
92
                                "source" % src_dirent)
79
93
      # Compare all files in this directory
80
94
      for src_file in src_files:
81
 
        # Exclude temporary files
82
 
        if src_file == 'rev-prop-atomics.shm':
83
 
          continue
84
 
        if src_file == 'rev-prop-atomics.mutex':
 
95
        # Ignore auto-created empty lock files as they may or may not
 
96
        # be present and are neither required by nor do they harm to
 
97
        # the destination repository.
 
98
        if src_file == 'pack-lock':
 
99
          continue
 
100
        if src_file == 'write-lock':
 
101
          continue
 
102
 
 
103
        # Ignore auto-created rep-cache.db-journal file
 
104
        if src_file == 'rep-cache.db-journal':
85
105
          continue
86
106
 
87
107
        src_path = os.path.join(src_dirpath, src_file)
90
110
          raise svntest.Failure("%s does not exist in hotcopy "
91
111
                                "destination" % dst_path)
92
112
 
 
113
        # Special case for db/uuid: Only the UUID in the first line needs
 
114
        # to match. Source and target must have the same number of lines
 
115
        # (due to having the same format).
 
116
        if src_path == os.path.join(src, 'db', 'uuid'):
 
117
          lines1 = open(src_path, 'rb').read().split("\n")
 
118
          lines2 = open(dst_path, 'rb').read().split("\n")
 
119
          if len(lines1) != len(lines2):
 
120
            raise svntest.Failure("%s differs in number of lines"
 
121
                                  % dst_path)
 
122
          if lines1[0] != lines2[0]:
 
123
            raise svntest.Failure("%s contains different uuid: '%s' vs. '%s'"
 
124
                                   % (dst_path, lines1[0], lines2[0]))
 
125
          continue
 
126
 
93
127
        # Special case for rep-cache: It will always differ in a byte-by-byte
94
128
        # comparison, so compare db tables instead.
95
129
        if src_file == 'rep-cache.db':
106
140
          for i in range(len(rows1)):
107
141
            if rows1[i] != rows2[i]:
108
142
              raise svntest.Failure("rep-cache row %i differs: '%s' vs. '%s'"
109
 
                                    % (row, rows1[i]))
 
143
                                    % (i, rows1[i], rows2[i]))
110
144
          continue
111
145
 
112
146
        # Special case for revprop-generation: It will always be zero in
113
147
        # the hotcopy destination (i.e. a fresh cache generation)
114
148
        if src_file == 'revprop-generation':
115
149
          f2 = open(dst_path, 'r')
116
 
          revprop_gen = int(f2.read().strip())
 
150
          revprop_gen = int(f2.read().strip().split()[1])
117
151
          if revprop_gen != 0:
118
152
              raise svntest.Failure("Hotcopy destination has non-zero " +
119
153
                                    "revprop generation")
146
180
        f1.close()
147
181
        f2.close()
148
182
 
 
183
def check_hotcopy_fsfs(src, dst):
 
184
    "Verify that the SRC FSFS repository has been correctly copied to DST."
 
185
    check_hotcopy_fsfs_fsx(src, dst)
 
186
 
 
187
def check_hotcopy_fsx(src, dst):
 
188
    "Verify that the SRC FSX repository has been correctly copied to DST."
 
189
    check_hotcopy_fsfs_fsx(src, dst)
 
190
 
149
191
#----------------------------------------------------------------------
150
192
 
151
193
# How we currently test 'svnadmin' --
189
231
 
190
232
  return txns
191
233
 
 
234
def patch_format(repo_dir, shard_size):
 
235
  """Rewrite the format of the FSFS or FSX repository REPO_DIR so
 
236
  that it would use sharding with SHARDS revisions per shard."""
 
237
 
 
238
  format_path = os.path.join(repo_dir, "db", "format")
 
239
  contents = open(format_path, 'rb').read()
 
240
  processed_lines = []
 
241
 
 
242
  for line in contents.split("\n"):
 
243
    if line.startswith("layout "):
 
244
      processed_lines.append("layout sharded %d" % shard_size)
 
245
    else:
 
246
      processed_lines.append(line)
 
247
 
 
248
  new_contents = "\n".join(processed_lines)
 
249
  os.chmod(format_path, 0666)
 
250
  open(format_path, 'wb').write(new_contents)
 
251
 
192
252
def load_and_verify_dumpstream(sbox, expected_stdout, expected_stderr,
193
253
                               revs, check_props, dump, *varargs):
194
254
  """Load the array of lines passed in DUMP into the current tests'
225
285
  if revs:
226
286
    # verify revs as wc states
227
287
    for rev in range(len(revs)):
228
 
      svntest.actions.run_and_verify_svn("Updating to r%s" % (rev+1),
229
 
                                         svntest.verify.AnyOutput, [],
 
288
      svntest.actions.run_and_verify_svn(svntest.verify.AnyOutput, [],
230
289
                                         "update", "-r%s" % (rev+1),
231
290
                                         sbox.wc_dir)
232
291
 
238
297
  return load_and_verify_dumpstream(sbox, None, None, None, False, dump,
239
298
                                    *varargs)
240
299
 
 
300
class FSFS_Index:
 
301
  """Manages indexes of a rev file in a FSFS format 7 repository.
 
302
  The interface returns P2L information and allows for item offsets
 
303
  and lengths to be modified. """
 
304
 
 
305
  def __init__(self, sbox, revision):
 
306
    self.by_item = { }
 
307
    self.revision = revision
 
308
    self.repo_dir = sbox.repo_dir
 
309
 
 
310
    self._read()
 
311
 
 
312
  def _read(self):
 
313
    """ Read P2L index using svnfsfs. """
 
314
    exit_code, output, errput = svntest.main.run_svnfsfs('dump-index',
 
315
                                                  '-r' + str(self.revision),
 
316
                                                  self.repo_dir)
 
317
    svntest.verify.verify_outputs("Error while dumping index",
 
318
                                  [], errput, [], [])
 
319
    svntest.verify.verify_exit_code(None, exit_code, 0)
 
320
 
 
321
    self.by_item.clear()
 
322
    for line in output:
 
323
      values = line.split()
 
324
      if len(values) >= 4 and values[0] != 'Start':
 
325
        item = long(values[4])
 
326
        self.by_item[item] = values
 
327
 
 
328
  def _write(self):
 
329
    """ Rewrite indexes using svnfsfs. """
 
330
    by_offset = {}
 
331
    for values in self.by_item.itervalues():
 
332
      by_offset[long(values[0], 16)] = values
 
333
 
 
334
    lines = []
 
335
    for (offset, values) in sorted(by_offset.items()):
 
336
      values = by_offset[offset]
 
337
      line = values[0] + ' ' + values[1] + ' ' + values[2] + ' ' + \
 
338
             values[3] + ' ' + values[4] + '\n';
 
339
      lines.append(line)
 
340
 
 
341
    exit_code, output, errput = svntest.main.run_command_stdin(
 
342
      svntest.main.svnfsfs_binary, 0, 0, True, lines,
 
343
      'load-index', self.repo_dir)
 
344
 
 
345
    svntest.verify.verify_outputs("Error while rewriting index",
 
346
                                  output, errput, [], [])
 
347
    svntest.verify.verify_exit_code(None, exit_code, 0)
 
348
 
 
349
  def get_item(self, item):
 
350
    """ Return offset, length and type of ITEM. """
 
351
    values = self.by_item[item]
 
352
 
 
353
    offset = long(values[0], 16)
 
354
    len = long(values[1], 16)
 
355
    type = values[2]
 
356
 
 
357
    return (offset, len, type)
 
358
 
 
359
  def modify_item(self, item, offset, len):
 
360
    """ Modify offset and length of ITEM. """
 
361
    values = self.by_item[item]
 
362
 
 
363
    values[0] = '%x' % offset
 
364
    values[1] = '%x' % len
 
365
 
 
366
    self._write()
 
367
 
 
368
def repo_format(sbox):
 
369
  """ Return the repository format number for SBOX."""
 
370
 
 
371
  format_file = open(os.path.join(sbox.repo_dir, "db", "format"))
 
372
  format = int(format_file.read()[:1])
 
373
  format_file.close()
 
374
 
 
375
  return format
 
376
 
 
377
def set_changed_path_list(sbox, revision, changes):
 
378
  """ Replace the changed paths list in the revision file REVISION in SBOX
 
379
      with the text CHANGES."""
 
380
 
 
381
  idx = None
 
382
 
 
383
  # read full file
 
384
  fp = open(fsfs_file(sbox.repo_dir, 'revs', str(revision)), 'r+b')
 
385
  contents = fp.read()
 
386
  length = len(contents)
 
387
 
 
388
  if repo_format(sbox) < 7:
 
389
    # replace the changed paths list
 
390
    header = contents[contents.rfind('\n', length - 64, length - 1):]
 
391
    body_len = long(header.split(' ')[1])
 
392
 
 
393
  else:
 
394
    # read & parse revision file footer
 
395
    footer_length = ord(contents[length-1]);
 
396
    footer = contents[length - footer_length - 1:length-1]
 
397
    l2p_offset = long(footer.split(' ')[0])
 
398
    l2p_checksum = footer.split(' ')[1]
 
399
    p2l_offset = long(footer.split(' ')[2])
 
400
    p2l_checksum = footer.split(' ')[3]
 
401
 
 
402
    idx = FSFS_Index(sbox, revision)
 
403
    (offset, item_len, item_type) = idx.get_item(1)
 
404
 
 
405
    # split file contents
 
406
    body_len = offset
 
407
    indexes = contents[l2p_offset:length - footer_length - 1]
 
408
 
 
409
    # construct new footer, include indexes as are
 
410
    file_len = body_len + len(changes) + 1
 
411
    p2l_offset += file_len - l2p_offset
 
412
 
 
413
    header = str(file_len) + ' ' + l2p_checksum + ' ' \
 
414
           + str(p2l_offset) + ' ' + p2l_checksum
 
415
    header += chr(len(header))
 
416
    header = '\n' + indexes + header
 
417
 
 
418
  contents = contents[:body_len] + changes + header
 
419
 
 
420
  # set new contents
 
421
  fp.seek(0)
 
422
  fp.write(contents)
 
423
  fp.truncate()
 
424
  fp.close()
 
425
 
 
426
  if repo_format(sbox) >= 7:
 
427
    idx.modify_item(1, offset, len(changes) + 1)
 
428
 
241
429
######################################################################
242
430
# Tests
243
431
 
244
432
 
245
433
#----------------------------------------------------------------------
246
434
 
247
 
def test_create(sbox):
248
 
  "'svnadmin create'"
249
 
 
250
 
 
251
 
  repo_dir = sbox.repo_dir
252
 
  wc_dir = sbox.wc_dir
253
 
 
254
 
  svntest.main.safe_rmtree(repo_dir, 1)
255
 
  svntest.main.safe_rmtree(wc_dir)
256
 
 
257
 
  svntest.main.create_repos(repo_dir)
258
 
 
259
 
  svntest.actions.run_and_verify_svn("Creating rev 0 checkout",
260
 
                                     ["Checked out revision 0.\n"], [],
261
 
                                     "checkout",
262
 
                                     sbox.repo_url, wc_dir)
263
 
 
264
 
 
265
 
  svntest.actions.run_and_verify_svn(
266
 
    "Running status",
267
 
    [], [],
268
 
    "status", wc_dir)
269
 
 
270
 
  svntest.actions.run_and_verify_svn(
271
 
    "Running verbose status",
272
 
    ["                 0        0  ?           %s\n" % wc_dir], [],
273
 
    "status", "--verbose", wc_dir)
274
 
 
275
 
  # success
276
 
 
277
 
 
278
435
# dump stream tests need a dump file
279
436
 
280
437
def clean_dumpfile():
306
463
def extra_headers(sbox):
307
464
  "loading of dumpstream with extra headers"
308
465
 
309
 
  test_create(sbox)
 
466
  sbox.build(empty=True)
310
467
 
311
468
  dumpfile = clean_dumpfile()
312
469
 
321
478
def extra_blockcontent(sbox):
322
479
  "load success on oversized Content-length"
323
480
 
324
 
  test_create(sbox)
 
481
  sbox.build(empty=True)
325
482
 
326
483
  dumpfile = clean_dumpfile()
327
484
 
339
496
def inconsistent_headers(sbox):
340
497
  "load failure on undersized Content-length"
341
498
 
342
 
  test_create(sbox)
 
499
  sbox.build(empty=True)
343
500
 
344
501
  dumpfile = clean_dumpfile()
345
502
 
355
512
def empty_date(sbox):
356
513
  "preserve date-less revisions in load"
357
514
 
358
 
  test_create(sbox)
 
515
  sbox.build(empty=True)
359
516
 
360
517
  dumpfile = clean_dumpfile()
361
518
 
370
527
                             '--ignore-uuid')
371
528
 
372
529
  # Verify that the revision still lacks the svn:date property.
373
 
  svntest.actions.run_and_verify_svn(None, [], [], "propget",
374
 
                                     "--revprop", "-r1", "svn:date",
 
530
  svntest.actions.run_and_verify_svn([], '.*(E195011|E200017).*svn:date',
 
531
                                     "propget", "--revprop", "-r1", "svn:date",
375
532
                                     sbox.wc_dir)
376
533
 
377
534
#----------------------------------------------------------------------
386
543
  old_C_path = os.path.join(wc_dir, 'A', 'C')
387
544
  new_C_path = os.path.join(wc_dir, 'A', 'B', 'C')
388
545
  svntest.main.run_svn(None, 'cp', old_C_path, new_C_path)
389
 
  svntest.main.run_svn(None, 'ci', wc_dir, '--quiet',
390
 
                       '-m', 'log msg')
 
546
  sbox.simple_commit(message='log msg')
391
547
 
392
548
  exit_code, output, errput = svntest.main.run_svnadmin("dump", repo_dir)
393
549
  if svntest.verify.compare_and_display_lines(
410
566
  Q_path = os.path.join(wc_dir, 'A', 'Q')
411
567
  svntest.main.run_svn(None, 'cp', B_path, Q_path)
412
568
  svntest.main.file_append(os.path.join(Q_path, 'lambda'), 'hello')
413
 
  svntest.main.run_svn(None, 'ci', wc_dir, '--quiet',
414
 
                       '-m', 'log msg')
 
569
  sbox.simple_commit(message='log msg')
415
570
  exit_code, output, errput = svntest.main.run_svnadmin("dump", repo_dir)
416
571
  svntest.verify.compare_and_display_lines(
417
572
    "Output of 'svnadmin dump' is unexpected.",
452
607
 
453
608
  os.chdir(backup_dir)
454
609
  svntest.actions.run_and_verify_svnadmin(
455
 
    None, None, [],
 
610
    None, [],
456
611
    "hotcopy", os.path.join(cwd, sbox.repo_dir), '.')
457
612
 
458
613
  os.chdir(cwd)
459
614
 
460
615
  if svntest.main.is_fs_type_fsfs():
461
616
    check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
462
 
  else:
 
617
  if svntest.main.is_fs_type_bdb():
463
618
    check_hotcopy_bdb(sbox.repo_dir, backup_dir)
 
619
  if svntest.main.is_fs_type_fsx():
 
620
    check_hotcopy_fsx(sbox.repo_dir, backup_dir)
464
621
 
465
622
#----------------------------------------------------------------------
466
623
 
495
652
#----------------------------------------------------------------------
496
653
 
497
654
def setrevprop(sbox):
498
 
  "'setlog' and 'setrevprop', bypassing hooks'"
 
655
  "setlog, setrevprop, delrevprop; bypass hooks"
499
656
  sbox.build()
500
657
 
501
658
  # Try a simple log property modification.
502
659
  iota_path = os.path.join(sbox.wc_dir, "iota")
503
 
  exit_code, output, errput = svntest.main.run_svnadmin("setlog",
504
 
                                                        sbox.repo_dir,
505
 
                                                        "-r0",
506
 
                                                        "--bypass-hooks",
507
 
                                                        iota_path)
508
 
  if errput:
509
 
    logger.warn("Error: 'setlog' failed")
510
 
    raise svntest.Failure
 
660
  mu_path = sbox.ospath('A/mu')
 
661
  svntest.actions.run_and_verify_svnadmin([], [],
 
662
                                          "setlog", sbox.repo_dir, "-r0",
 
663
                                          "--bypass-hooks",
 
664
                                          iota_path)
 
665
 
 
666
  # Make sure it fails without --bypass-hooks.  (We haven't called
 
667
  # svntest.actions.enable_revprop_changes().)
 
668
  #
 
669
  # Note that we attempt to set the log message to a different value than the
 
670
  # successful call.
 
671
  svntest.actions.run_and_verify_svnadmin([], svntest.verify.AnyOutput,
 
672
                                          "setlog", sbox.repo_dir, "-r0",
 
673
                                          mu_path)
511
674
 
512
675
  # Verify that the revprop value matches what we set when retrieved
513
676
  # through the client.
514
 
  svntest.actions.run_and_verify_svn(None,
515
 
                                     [ "This is the file 'iota'.\n", "\n" ],
 
677
  svntest.actions.run_and_verify_svn([ "This is the file 'iota'.\n", "\n" ],
516
678
                                     [], "propget", "--revprop", "-r0",
517
679
                                     "svn:log", sbox.wc_dir)
518
680
 
530
692
 
531
693
  # Verify that the revprop value matches what we set when retrieved
532
694
  # through the client.
533
 
  svntest.actions.run_and_verify_svn(None, [ "foo\n" ], [], "propget",
 
695
  svntest.actions.run_and_verify_svn([ "foo\n" ], [], "propget",
534
696
                                     "--revprop", "-r0", "svn:author",
535
697
                                     sbox.wc_dir)
536
698
 
 
699
  # Delete the property.
 
700
  svntest.actions.run_and_verify_svnadmin([], [],
 
701
                                          "delrevprop", "-r0", sbox.repo_dir,
 
702
                                          "svn:author")
 
703
  svntest.actions.run_and_verify_svnlook([], ".*E200017.*svn:author.*",
 
704
                                         "propget", "--revprop", "-r0",
 
705
                                         sbox.repo_dir, "svn:author")
 
706
 
537
707
def verify_windows_paths_in_repos(sbox):
538
708
  "verify a repository containing paths like 'c:hi'"
539
709
 
542
712
  repo_url       = sbox.repo_url
543
713
  chi_url = sbox.repo_url + '/c:hi'
544
714
 
545
 
  svntest.actions.run_and_verify_svn(None, None, [],
 
715
  svntest.actions.run_and_verify_svn(None, [],
546
716
                                     'mkdir', '-m', 'log_msg',
547
717
                                     chi_url)
548
718
 
549
719
  exit_code, output, errput = svntest.main.run_svnadmin("verify",
550
720
                                                        sbox.repo_dir)
 
721
  if errput:
 
722
    raise SVNUnexpectedStderr(errput)
551
723
 
552
 
  # unfortunately, FSFS needs to do more checks than BDB resulting in
553
 
  # different progress output
554
 
  if svntest.main.is_fs_type_fsfs():
555
 
    svntest.verify.compare_and_display_lines(
556
 
      "Error while running 'svnadmin verify'.",
557
 
      'STDERR', ["* Verifying repository metadata ...\n",
558
 
                 "* Verified revision 0.\n",
559
 
                 "* Verified revision 1.\n",
560
 
                 "* Verified revision 2.\n"], errput)
 
724
  # unfortunately, some backends needs to do more checks than other
 
725
  # resulting in different progress output
 
726
  if svntest.main.is_fs_log_addressing():
 
727
    svntest.verify.compare_and_display_lines(
 
728
      "Error while running 'svnadmin verify'.",
 
729
      'STDOUT', ["* Verifying metadata at revision 0 ...\n",
 
730
                 "* Verifying repository metadata ...\n",
 
731
                 "* Verified revision 0.\n",
 
732
                 "* Verified revision 1.\n",
 
733
                 "* Verified revision 2.\n"], output)
 
734
  elif svntest.main.fs_has_rep_sharing():
 
735
    svntest.verify.compare_and_display_lines(
 
736
      "Error while running 'svnadmin verify'.",
 
737
      'STDOUT', ["* Verifying repository metadata ...\n",
 
738
                 "* Verified revision 0.\n",
 
739
                 "* Verified revision 1.\n",
 
740
                 "* Verified revision 2.\n"], output)
561
741
  else:
562
742
    svntest.verify.compare_and_display_lines(
563
743
      "Error while running 'svnadmin verify'.",
564
 
      'STDERR', ["* Verified revision 0.\n",
 
744
      'STDOUT', ["* Verified revision 0.\n",
565
745
                 "* Verified revision 1.\n",
566
 
                 "* Verified revision 2.\n"], errput)
 
746
                 "* Verified revision 2.\n"], output)
567
747
 
568
748
#----------------------------------------------------------------------
569
749
 
596
776
  """svnadmin verify detects corruption dump can't"""
597
777
 
598
778
  # setup a repo with a directory 'c:hi'
599
 
  sbox.build(create_wc = False)
 
779
  # use physical addressing as this is hard to provoke with logical addressing
 
780
  sbox.build(create_wc = False,
 
781
             minor_version = min(svntest.main.options.server_minor_version,8))
600
782
  repo_url = sbox.repo_url
601
783
  E_url = sbox.repo_url + '/A/B/E'
602
784
 
603
785
  # Create A/B/E/bravo in r2.
604
 
  svntest.actions.run_and_verify_svn(None, None, [],
 
786
  svntest.actions.run_and_verify_svn(None, [],
605
787
                                     'mkdir', '-m', 'log_msg',
606
788
                                     E_url + '/bravo')
607
789
  # Corrupt r2's reference to A/C by replacing "dir 7-1.0.r1/1568" with
834
1016
  "'svnadmin load --parent-dir' reparents mergeinfo"
835
1017
 
836
1018
  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2983. ##
837
 
  test_create(sbox)
 
1019
  sbox.build(empty=True)
838
1020
 
839
1021
  dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
840
1022
                                   'svnadmin_tests_data',
842
1024
  dumpfile = open(dumpfile_location).read()
843
1025
 
844
1026
  # Create 'sample' dir in sbox.repo_url, and load the dump stream there.
845
 
  svntest.actions.run_and_verify_svn(None,
846
 
                                     ['\n', 'Committed revision 1.\n'],
 
1027
  svntest.actions.run_and_verify_svn(['Committing transaction...\n',
 
1028
                                      'Committed revision 1.\n'],
847
1029
                                     [], "mkdir", sbox.repo_url + "/sample",
848
1030
                                     "-m", "Create sample dir")
849
1031
  load_dumpstream(sbox, dumpfile, '--parent-dir', '/sample')
850
1032
 
851
1033
  # Verify the svn:mergeinfo properties for '--parent-dir'
852
 
  svntest.actions.run_and_verify_svn(None,
853
 
                                     [sbox.repo_url +
 
1034
  svntest.actions.run_and_verify_svn([sbox.repo_url +
854
1035
                                      "/sample/branch - /sample/trunk:5-7\n"],
855
1036
                                     [], 'propget', 'svn:mergeinfo', '-R',
856
1037
                                     sbox.repo_url + '/sample/branch')
857
 
  svntest.actions.run_and_verify_svn(None,
858
 
                                     [sbox.repo_url +
 
1038
  svntest.actions.run_and_verify_svn([sbox.repo_url +
859
1039
                                      "/sample/branch1 - " +
860
1040
                                      "/sample/branch:6-9\n"],
861
1041
                                     [], 'propget', 'svn:mergeinfo', '-R',
864
1044
  # Create 'sample-2' dir in sbox.repo_url, and load the dump stream again.
865
1045
  # This time, don't include a leading slash on the --parent-dir argument.
866
1046
  # See issue #3547.
867
 
  svntest.actions.run_and_verify_svn(None,
868
 
                                     ['\n', 'Committed revision 11.\n'],
 
1047
  svntest.actions.run_and_verify_svn(['Committing transaction...\n',
 
1048
                                      'Committed revision 11.\n'],
869
1049
                                     [], "mkdir", sbox.repo_url + "/sample-2",
870
1050
                                     "-m", "Create sample-2 dir")
871
1051
  load_dumpstream(sbox, dumpfile, '--parent-dir', 'sample-2')
872
1052
 
873
1053
  # Verify the svn:mergeinfo properties for '--parent-dir'.
874
 
  svntest.actions.run_and_verify_svn(None,
875
 
                                     [sbox.repo_url +
 
1054
  svntest.actions.run_and_verify_svn([sbox.repo_url +
876
1055
                                      "/sample-2/branch - " +
877
1056
                                      "/sample-2/trunk:15-17\n"],
878
1057
                                     [], 'propget', 'svn:mergeinfo', '-R',
879
1058
                                     sbox.repo_url + '/sample-2/branch')
880
 
  svntest.actions.run_and_verify_svn(None,
881
 
                                     [sbox.repo_url +
 
1059
  svntest.actions.run_and_verify_svn([sbox.repo_url +
882
1060
                                      "/sample-2/branch1 - " +
883
1061
                                      "/sample-2/branch:16-19\n"],
884
1062
                                     [], 'propget', 'svn:mergeinfo', '-R',
898
1076
  orig_uuid = output[0].rstrip()
899
1077
 
900
1078
  # Try setting a new, bogus UUID.
901
 
  svntest.actions.run_and_verify_svnadmin(None, None, '^.*Malformed UUID.*$',
 
1079
  svntest.actions.run_and_verify_svnadmin(None, '^.*Malformed UUID.*$',
902
1080
                                          'setuuid', sbox.repo_dir, 'abcdef')
903
1081
 
904
1082
  # Try generating a brand new UUID.
905
 
  svntest.actions.run_and_verify_svnadmin(None, [], None,
 
1083
  svntest.actions.run_and_verify_svnadmin([], None,
906
1084
                                          'setuuid', sbox.repo_dir)
907
1085
  exit_code, output, errput = svntest.main.run_svnlook('uuid', sbox.repo_dir)
908
1086
  if errput:
913
1091
    raise svntest.Failure
914
1092
 
915
1093
  # Now, try setting the UUID back to the original value.
916
 
  svntest.actions.run_and_verify_svnadmin(None, [], None,
 
1094
  svntest.actions.run_and_verify_svnadmin([], None,
917
1095
                                          'setuuid', sbox.repo_dir, orig_uuid)
918
1096
  exit_code, output, errput = svntest.main.run_svnlook('uuid', sbox.repo_dir)
919
1097
  if errput:
930
1108
 
931
1109
  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3020. ##
932
1110
 
933
 
  test_create(sbox)
 
1111
  sbox.build(empty=True)
934
1112
 
935
1113
  dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
936
1114
                                   'svndumpfilter_tests_data',
938
1116
  dumpfile = open(dumpfile_location).read()
939
1117
 
940
1118
  # Create 'toplevel' dir in sbox.repo_url
941
 
  svntest.actions.run_and_verify_svn(None, ['\n', 'Committed revision 1.\n'],
 
1119
  svntest.actions.run_and_verify_svn(['Committing transaction...\n',
 
1120
                                            'Committed revision 1.\n'],
942
1121
                                     [], "mkdir", sbox.repo_url + "/toplevel",
943
1122
                                     "-m", "Create toplevel dir")
944
1123
 
954
1133
    url + "/trunk - /branch1:5-9\n",
955
1134
    url + "/toplevel/trunk - /toplevel/branch1:14-18\n",
956
1135
    ])
957
 
  svntest.actions.run_and_verify_svn(None, expected_output, [],
 
1136
  svntest.actions.run_and_verify_svn(expected_output, [],
958
1137
                                     'propget', 'svn:mergeinfo', '-R',
959
1138
                                     sbox.repo_url)
960
1139
 
969
1148
 
970
1149
  # Commit up to r3, so we can test various recovery scenarios.
971
1150
  svntest.main.file_append(os.path.join(sbox.wc_dir, 'iota'), 'newer line\n')
972
 
  svntest.main.run_svn(None, 'ci', sbox.wc_dir, '--quiet', '-m', 'log msg')
 
1151
  sbox.simple_commit(message='log msg')
973
1152
 
974
1153
  svntest.main.file_append(os.path.join(sbox.wc_dir, 'iota'), 'newest line\n')
975
 
  svntest.main.run_svn(None, 'ci', sbox.wc_dir, '--quiet', '-m', 'log msg')
 
1154
  sbox.simple_commit(message='log msg')
976
1155
 
977
1156
  rev_3 = fsfs_file(sbox.repo_dir, 'revs', '3')
978
1157
  rev_was_3 = rev_3 + '.was'
1029
1208
    ".*Revision 3 has a non-file where its revprops file should be.*"):
1030
1209
    raise svntest.Failure
1031
1210
 
 
1211
  # Restore the r3 revprops file, thus repairing the repository.
 
1212
  os.rmdir(revprop_3)
 
1213
  os.rename(revprop_was_3, revprop_3)
 
1214
 
1032
1215
 
1033
1216
#----------------------------------------------------------------------
1034
1217
 
 
1218
@Skip(svntest.main.tests_use_prepacakaged_repository)
1035
1219
def create_in_repo_subdir(sbox):
1036
1220
  "'svnadmin create /path/to/repo/subdir'"
1037
1221
 
 
1222
  sbox.build(create_wc=False, empty=True)
1038
1223
  repo_dir = sbox.repo_dir
1039
 
  wc_dir = sbox.wc_dir
1040
 
 
1041
 
  svntest.main.safe_rmtree(repo_dir, 1)
1042
 
  svntest.main.safe_rmtree(wc_dir)
1043
 
 
1044
 
  # This should succeed
1045
 
  svntest.main.create_repos(repo_dir)
1046
1224
 
1047
1225
  success = False
1048
1226
  try:
1070
1248
 
1071
1249
 
1072
1250
@SkipUnless(svntest.main.is_fs_type_fsfs)
 
1251
@SkipDumpLoadCrossCheck()
1073
1252
def verify_with_invalid_revprops(sbox):
1074
1253
  "svnadmin verify detects invalid revprops file"
1075
1254
 
 
1255
  sbox.build(create_wc=False, empty=True)
1076
1256
  repo_dir = sbox.repo_dir
1077
1257
 
1078
 
  svntest.main.safe_rmtree(repo_dir, 1)
1079
 
 
1080
 
  # This should succeed
1081
 
  svntest.main.create_repos(repo_dir)
1082
 
 
1083
1258
  # Run a test verify
1084
1259
  exit_code, output, errput = svntest.main.run_svnadmin("verify",
1085
1260
                                                        sbox.repo_dir)
1086
1261
 
 
1262
  if errput:
 
1263
    raise SVNUnexpectedStderr(errput)
1087
1264
  if svntest.verify.verify_outputs(
1088
 
    "Output of 'svnadmin verify' is unexpected.", None, errput, None,
 
1265
    "Output of 'svnadmin verify' is unexpected.", None, output, None,
1089
1266
    ".*Verified revision 0*"):
1090
1267
    raise svntest.Failure
1091
1268
 
1127
1304
  "don't filter mergeinfo revs from incremental dump"
1128
1305
 
1129
1306
  # Create an empty repos.
1130
 
  test_create(sbox)
 
1307
  sbox.build(empty=True)
1131
1308
 
1132
1309
  # PART 1: Load a full dump to an empty repository.
1133
1310
  #
1139
1316
  #                      |            |                            |     |
1140
1317
  # trunk---r2---r3-----r5---r6-------r8---r9--------------->      |     |
1141
1318
  #   r1             |        |     |       |                      |     |
1142
 
  # intial           |        |     |       |______                |     |
 
1319
  # initial          |        |     |       |______                |     |
1143
1320
  # import         copy       |   copy             |            merge   merge
1144
1321
  #                  |        |     |            merge           (r5)   (r8)
1145
1322
  #                  |        |     |            (r9)              |     |
1187
1364
    url + "B2 - /trunk:9\n",
1188
1365
    url + "B1/B/E - /branches/B2/B/E:11-12\n",
1189
1366
    "/trunk/B/E:5-6,8-9\n"])
1190
 
  svntest.actions.run_and_verify_svn(None, expected_output, [],
 
1367
  svntest.actions.run_and_verify_svn(expected_output, [],
1191
1368
                                     'propget', 'svn:mergeinfo', '-R',
1192
1369
                                     sbox.repo_url)
1193
1370
 
1216
1393
  dump_fp.close()
1217
1394
 
1218
1395
  # Blow away the current repos and create an empty one in its place.
1219
 
  test_create(sbox)
 
1396
  sbox.build(empty=True)
1220
1397
 
1221
1398
  # Load the three incremental dump files in sequence.
1222
1399
  load_dumpstream(sbox, open(dump_file_r1_10).read(), '--ignore-uuid')
1226
1403
  # Check the mergeinfo, we use the same expected output as before,
1227
1404
  # as it (duh!) should be exactly the same as when we loaded the
1228
1405
  # repos in one shot.
1229
 
  svntest.actions.run_and_verify_svn(None, expected_output, [],
 
1406
  svntest.actions.run_and_verify_svn(expected_output, [],
1230
1407
                                     'propget', 'svn:mergeinfo', '-R',
1231
1408
                                     sbox.repo_url)
1232
1409
 
1236
1413
  # PART 3: Load a full dump to an non-empty repository.
1237
1414
  #
1238
1415
  # Reset our sandbox.
1239
 
  test_create(sbox)
 
1416
  sbox.build(empty=True)
1240
1417
 
1241
1418
  # Load this skeleton repos into the empty target:
1242
1419
  #
1280
1457
    url + "B2 - /Projects/Project-X/trunk:15\n",
1281
1458
    url + "B1/B/E - /Projects/Project-X/branches/B2/B/E:17-18\n",
1282
1459
    "/Projects/Project-X/trunk/B/E:11-12,14-15\n"])
1283
 
  svntest.actions.run_and_verify_svn(None, expected_output, [],
 
1460
  svntest.actions.run_and_verify_svn(expected_output, [],
1284
1461
                                     'propget', 'svn:mergeinfo', '-R',
1285
1462
                                     sbox.repo_url)
1286
1463
 
1287
1464
  # PART 4: Load a a series of incremental dumps to an non-empty repository.
1288
1465
  #
1289
1466
  # Reset our sandbox.
1290
 
  test_create(sbox)
 
1467
  sbox.build(empty=True)
1291
1468
 
1292
1469
  # Load this skeleton repos into the empty target:
1293
1470
  load_dumpstream(sbox, dumpfile_skeleton, '--ignore-uuid')
1303
1480
  # Check the resulting mergeinfo.  We expect the exact same results
1304
1481
  # as Part 3.
1305
1482
  # See http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16.
1306
 
  svntest.actions.run_and_verify_svn(None, expected_output, [],
 
1483
  svntest.actions.run_and_verify_svn(expected_output, [],
1307
1484
                                     'propget', 'svn:mergeinfo', '-R',
1308
1485
                                     sbox.repo_url)
1309
1486
 
1315
1492
 
1316
1493
  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2591. ##
1317
1494
 
 
1495
  # Create a repository.
 
1496
  sbox.build(create_wc=False, empty=True)
1318
1497
  original_repo = sbox.repo_dir
1319
1498
 
1320
1499
  hotcopy_repo, hotcopy_url = sbox.add_repo_path('hotcopy')
1321
1500
 
1322
 
  # Create a repository.
1323
 
  svntest.main.safe_rmtree(original_repo, 1)
1324
 
  svntest.main.create_repos(original_repo)
1325
 
 
1326
1501
  # Create a file, a dir and a missing path outside the repoitory.
1327
1502
  svntest.main.safe_rmtree(sbox.wc_dir, 1)
1328
1503
  os.mkdir(sbox.wc_dir)
1355
1530
    os.symlink(target_abspath, symlink_path + '_abs')
1356
1531
 
1357
1532
  svntest.actions.run_and_verify_svnadmin(
1358
 
    None, None, [],
 
1533
    None, [],
1359
1534
    "hotcopy", original_repo, hotcopy_repo)
1360
1535
 
1361
1536
  # Check if the symlinks were copied correctly.
1418
1593
 
1419
1594
 
1420
1595
"""
1421
 
  test_create(sbox)
 
1596
  sbox.build(empty=True)
1422
1597
 
1423
1598
  # Try to load the dumpstream, expecting a failure (because of mixed EOLs).
1424
1599
  load_and_verify_dumpstream(sbox, [], svntest.verify.AnyOutput,
1440
1615
  "svnadmin verify with non-UTF-8 paths"
1441
1616
 
1442
1617
  dumpfile = clean_dumpfile()
1443
 
  test_create(sbox)
 
1618
 
 
1619
  # Corruption only possible in physically addressed revisions created
 
1620
  # with pre-1.6 servers.
 
1621
  sbox.build(empty=True,
 
1622
             minor_version=min(svntest.main.options.server_minor_version,8))
1444
1623
 
1445
1624
  # Load the dumpstream
1446
1625
  load_and_verify_dumpstream(sbox, [], [], dumpfile_revisions, False,
1457
1636
    if line == "A\n":
1458
1637
      # replace 'A' with a latin1 character -- the new path is not valid UTF-8
1459
1638
      fp_new.write("\xE6\n")
1460
 
    elif line == "text: 1 279 32 0 d63ecce65d8c428b86f4f8b0920921fe\n":
1461
 
      # fix up the representation checksum
1462
 
      fp_new.write("text: 1 279 32 0 b50b1d5ed64075b5f632f3b8c30cd6b2\n")
1463
 
    elif line == "text: 1 280 32 32 d63ecce65d8c428b86f4f8b0920921fe\n":
1464
 
      # fix up the representation checksum
1465
 
      fp_new.write("text: 1 280 32 32 b50b1d5ed64075b5f632f3b8c30cd6b2\n")
 
1639
    elif line == "text: 1 279 32 32 d63ecce65d8c428b86f4f8b0920921fe\n":
 
1640
      # phys, PLAIN directories: fix up the representation checksum
 
1641
      fp_new.write("text: 1 279 32 32 b50b1d5ed64075b5f632f3b8c30cd6b2\n")
1466
1642
    elif line == "text: 1 292 44 32 a6be7b4cf075fd39e6a99eb69a31232b\n":
1467
 
      # fix up the representation checksum
 
1643
      # phys, deltified directories: fix up the representation checksum
1468
1644
      fp_new.write("text: 1 292 44 32 f2e93e73272cac0f18fccf16f224eb93\n")
 
1645
    elif line == "text: 1 6 31 31 90f306aa9bfd72f456072076a2bd94f7\n":
 
1646
      # log addressing: fix up the representation checksum
 
1647
      fp_new.write("text: 1 6 31 31 db2d4a0bad5dff0aea9a288dec02f1fb\n")
1469
1648
    elif line == "cpath: /A\n":
1470
1649
      # also fix up the 'created path' field
1471
1650
      fp_new.write("cpath: /\xE6\n")
1491
1670
  expected_stderr = [
1492
1671
    "* Dumped revision 0.\n",
1493
1672
    "WARNING 0x0002: E160005: "
1494
 
      "While validating fspath '?\\230': "
1495
 
      "Path '?\\230' is not in UTF-8"
 
1673
      "While validating fspath '?\\E6': "
 
1674
      "Path '?\\E6' is not in UTF-8"
1496
1675
      "\n",
1497
1676
    "* Dumped revision 1.\n",
1498
1677
    ]
1515
1694
  if exit_code or errput or output:
1516
1695
    raise svntest.Failure("Error: 'lslocks' failed")
1517
1696
 
1518
 
  expected_output = UnorderedOutput(
1519
 
    ["'A/B/lambda' locked by user 'jrandom'.\n",
1520
 
     "'iota' locked by user 'jrandom'.\n"])
 
1697
  expected_output = svntest.verify.UnorderedRegexListOutput(
 
1698
    ["'.*lambda' locked by user 'jrandom'.\n",
 
1699
     "'.*iota' locked by user 'jrandom'.\n"])
1521
1700
 
1522
1701
  # Lock iota and A/B/lambda using svn client
1523
 
  svntest.actions.run_and_verify_svn(None, expected_output,
 
1702
  svntest.actions.run_and_verify_svn(expected_output,
1524
1703
                                     [], "lock", "-m", "Locking files",
1525
1704
                                     iota_url, lambda_url)
1526
1705
 
1582
1761
  "'svnadmin load --revision X:Y'"
1583
1762
 
1584
1763
  ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3734. ##
1585
 
  test_create(sbox)
 
1764
  sbox.build(empty=True)
1586
1765
 
1587
1766
  dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
1588
1767
                                   'svnadmin_tests_data',
1593
1772
  # Load our dumpfile, 2 revisions at a time, verifying that we have
1594
1773
  # the correct youngest revision after each load.
1595
1774
  load_dumpstream(sbox, dumpdata, '-r0:2')
1596
 
  svntest.actions.run_and_verify_svnlook("Unexpected output", ['2\n'],
 
1775
  svntest.actions.run_and_verify_svnlook(['2\n'],
1597
1776
                                         None, 'youngest', sbox.repo_dir)
1598
1777
  load_dumpstream(sbox, dumpdata, '-r3:4')
1599
 
  svntest.actions.run_and_verify_svnlook("Unexpected output", ['4\n'],
 
1778
  svntest.actions.run_and_verify_svnlook(['4\n'],
1600
1779
                                         None, 'youngest', sbox.repo_dir)
1601
1780
  load_dumpstream(sbox, dumpdata, '-r5:6')
1602
 
  svntest.actions.run_and_verify_svnlook("Unexpected output", ['6\n'],
 
1781
  svntest.actions.run_and_verify_svnlook(['6\n'],
1603
1782
                                         None, 'youngest', sbox.repo_dir)
1604
1783
 
1605
1784
  # There are ordering differences in the property blocks.
1606
 
  expected_dump = UnorderedOutput(dumplines)
 
1785
  if (svntest.main.options.server_minor_version < 6):
 
1786
    temp = []
 
1787
 
 
1788
    for line in dumplines:
 
1789
      if not "Text-content-sha1:" in line:
 
1790
        temp.append(line)
 
1791
 
 
1792
    expected_dump = UnorderedOutput(temp)
 
1793
  else:
 
1794
    expected_dump = UnorderedOutput(dumplines)
 
1795
 
1607
1796
  new_dumpdata = svntest.actions.run_and_verify_dump(sbox.repo_dir)
1608
1797
  svntest.verify.compare_and_display_lines("Dump files", "DUMP",
1609
1798
                                           expected_dump, new_dumpdata)
1620
1809
  for i in [1, 2, 3]:
1621
1810
    os.chdir(backup_dir)
1622
1811
    svntest.actions.run_and_verify_svnadmin(
1623
 
      None, None, [],
 
1812
      None, [],
1624
1813
      "hotcopy", "--incremental", os.path.join(cwd, sbox.repo_dir), '.')
1625
1814
 
1626
1815
    os.chdir(cwd)
1632
1821
      sbox.simple_commit()
1633
1822
 
1634
1823
@SkipUnless(svntest.main.is_fs_type_fsfs)
 
1824
@SkipUnless(svntest.main.fs_has_pack)
1635
1825
def hotcopy_incremental_packed(sbox):
1636
1826
  "'svnadmin hotcopy --incremental' with packing"
 
1827
 
 
1828
  # Configure two files per shard to trigger packing.
1637
1829
  sbox.build()
 
1830
  patch_format(sbox.repo_dir, shard_size=2)
1638
1831
 
1639
1832
  backup_dir, backup_url = sbox.add_repo_path('backup')
1640
1833
  os.mkdir(backup_dir)
1641
1834
  cwd = os.getcwd()
1642
 
  # Configure two files per shard to trigger packing
1643
 
  format_file = open(os.path.join(sbox.repo_dir, 'db', 'format'), 'wb')
1644
 
  format_file.write("6\nlayout sharded 2\n")
1645
 
  format_file.close()
1646
1835
 
1647
 
  # Pack revisions 0 and 1.
1648
 
  svntest.actions.run_and_verify_svnadmin(
1649
 
    None, ['Packing revisions in shard 0...done.\n'], [], "pack",
1650
 
    os.path.join(cwd, sbox.repo_dir))
 
1836
  # Pack revisions 0 and 1 if not already packed.
 
1837
  if not (svntest.main.is_fs_type_fsfs and svntest.main.options.fsfs_packing
 
1838
          and svntest.main.options.fsfs_sharding == 2):
 
1839
    svntest.actions.run_and_verify_svnadmin(
 
1840
      ['Packing revisions in shard 0...done.\n'], [], "pack",
 
1841
      os.path.join(cwd, sbox.repo_dir))
1651
1842
 
1652
1843
  # Commit 5 more revs, hotcopy and pack after each commit.
1653
1844
  for i in [1, 2, 3, 4, 5]:
1654
1845
    os.chdir(backup_dir)
1655
1846
    svntest.actions.run_and_verify_svnadmin(
1656
 
      None, None, [],
 
1847
      None, [],
1657
1848
      "hotcopy", "--incremental", os.path.join(cwd, sbox.repo_dir), '.')
1658
1849
 
1659
1850
    os.chdir(cwd)
1663
1854
    if i < 5:
1664
1855
      sbox.simple_mkdir("newdir-%i" % i)
1665
1856
      sbox.simple_commit()
1666
 
      if not i % 2:
 
1857
      if (svntest.main.is_fs_type_fsfs and not svntest.main.options.fsfs_packing
 
1858
          and not i % 2):
1667
1859
        expected_output = ['Packing revisions in shard %d...done.\n' % (i/2)]
1668
1860
      else:
1669
1861
        expected_output = []
1670
1862
      svntest.actions.run_and_verify_svnadmin(
1671
 
        None, expected_output, [], "pack", os.path.join(cwd, sbox.repo_dir))
 
1863
        expected_output, [], "pack", os.path.join(cwd, sbox.repo_dir))
1672
1864
 
1673
1865
 
1674
1866
def locking(sbox):
1683
1875
 
1684
1876
  # Test illegal character in comment file.
1685
1877
  expected_error = ".*svnadmin: E130004:.*"
1686
 
  svntest.actions.run_and_verify_svnadmin(None, None,
 
1878
  svntest.actions.run_and_verify_svnadmin(None,
1687
1879
                                          expected_error, "lock",
1688
1880
                                          sbox.repo_dir,
1689
1881
                                          "iota", "jrandom",
1691
1883
 
1692
1884
  # Test locking path with --bypass-hooks
1693
1885
  expected_output = "'iota' locked by user 'jrandom'."
1694
 
  svntest.actions.run_and_verify_svnadmin(None, expected_output,
 
1886
  svntest.actions.run_and_verify_svnadmin(expected_output,
1695
1887
                                          None, "lock",
1696
1888
                                          sbox.repo_dir,
1697
1889
                                          "iota", "jrandom",
1699
1891
                                          "--bypass-hooks")
1700
1892
 
1701
1893
  # Remove lock
1702
 
  svntest.actions.run_and_verify_svnadmin(None, None,
 
1894
  svntest.actions.run_and_verify_svnadmin(None,
1703
1895
                                          None, "rmlocks",
1704
1896
                                          sbox.repo_dir, "iota")
1705
1897
 
1706
1898
  # Test locking path without --bypass-hooks
1707
1899
  expected_output = "'iota' locked by user 'jrandom'."
1708
 
  svntest.actions.run_and_verify_svnadmin(None, expected_output,
 
1900
  svntest.actions.run_and_verify_svnadmin(expected_output,
1709
1901
                                          None, "lock",
1710
1902
                                          sbox.repo_dir,
1711
1903
                                          "iota", "jrandom",
1713
1905
 
1714
1906
  # Test locking already locked path.
1715
1907
  expected_error = ".*svnadmin: E160035:.*"
1716
 
  svntest.actions.run_and_verify_svnadmin(None, None,
 
1908
  svntest.actions.run_and_verify_svnadmin(None,
1717
1909
                                          expected_error, "lock",
1718
1910
                                          sbox.repo_dir,
1719
1911
                                          "iota", "jrandom",
1721
1913
 
1722
1914
  # Test locking non-existent path.
1723
1915
  expected_error = ".*svnadmin: E160013:.*"
1724
 
  svntest.actions.run_and_verify_svnadmin(None, None,
 
1916
  svntest.actions.run_and_verify_svnadmin(None,
1725
1917
                                          expected_error, "lock",
1726
1918
                                          sbox.repo_dir,
1727
1919
                                          "non-existent", "jrandom",
1730
1922
  # Test locking a path while specifying a lock token.
1731
1923
  expected_output = "'A/D/G/rho' locked by user 'jrandom'."
1732
1924
  lock_token = "opaquelocktoken:01234567-89ab-cdef-89ab-cdef01234567"
1733
 
  svntest.actions.run_and_verify_svnadmin(None, expected_output,
 
1925
  svntest.actions.run_and_verify_svnadmin(expected_output,
1734
1926
                                          None, "lock",
1735
1927
                                          sbox.repo_dir,
1736
1928
                                          "A/D/G/rho", "jrandom",
1739
1931
  # Test unlocking a path, but provide the wrong lock token.
1740
1932
  expected_error = ".*svnadmin: E160040:.*"
1741
1933
  wrong_lock_token = "opaquelocktoken:12345670-9ab8-defc-9ab8-def01234567c"
1742
 
  svntest.actions.run_and_verify_svnadmin(None, None,
 
1934
  svntest.actions.run_and_verify_svnadmin(None,
1743
1935
                                          expected_error, "unlock",
1744
1936
                                          sbox.repo_dir,
1745
1937
                                          "A/D/G/rho", "jrandom",
1748
1940
  # Test unlocking the path again, but this time provide the correct
1749
1941
  # lock token.
1750
1942
  expected_output = "'A/D/G/rho' unlocked."
1751
 
  svntest.actions.run_and_verify_svnadmin(None, expected_output,
 
1943
  svntest.actions.run_and_verify_svnadmin(expected_output,
1752
1944
                                          None, "unlock",
1753
1945
                                          sbox.repo_dir,
1754
1946
                                          "A/D/G/rho", "jrandom",
1763
1955
  # Test locking a path.  Don't use --bypass-hooks, though, as we wish
1764
1956
  # to verify that hook script is really getting executed.
1765
1957
  expected_error = ".*svnadmin: E165001:.*"
1766
 
  svntest.actions.run_and_verify_svnadmin(None, None,
 
1958
  svntest.actions.run_and_verify_svnadmin(None,
1767
1959
                                          expected_error, "lock",
1768
1960
                                          sbox.repo_dir,
1769
1961
                                          "iota", "jrandom",
1785
1977
  # Try to unlock a path while providing the correct lock token but
1786
1978
  # with a preventative hook in place.
1787
1979
  expected_error = ".*svnadmin: E165001:.*"
1788
 
  svntest.actions.run_and_verify_svnadmin(None, None,
 
1980
  svntest.actions.run_and_verify_svnadmin(None,
1789
1981
                                          expected_error, "unlock",
1790
1982
                                          sbox.repo_dir,
1791
1983
                                          "iota", "jrandom",
1794
1986
  # Finally, use --bypass-hooks to unlock the path (again using the
1795
1987
  # correct lock token).
1796
1988
  expected_output = "'iota' unlocked."
1797
 
  svntest.actions.run_and_verify_svnadmin(None, expected_output,
 
1989
  svntest.actions.run_and_verify_svnadmin(expected_output,
1798
1990
                                          None, "unlock",
1799
1991
                                          "--bypass-hooks",
1800
1992
                                          sbox.repo_dir,
1842
2034
 
1843
2035
 
1844
2036
@Issue(4213)
 
2037
@Skip(svntest.main.is_fs_type_fsx)
1845
2038
def recover_old_empty(sbox):
1846
2039
  "recover empty --compatible-version=1.3"
1847
 
  svntest.main.safe_rmtree(sbox.repo_dir, 1)
1848
 
  svntest.main.create_repos(sbox.repo_dir, minor_version=3)
1849
 
  svntest.actions.run_and_verify_svnadmin(None, None, [],
 
2040
  sbox.build(create_wc=False, empty=True, minor_version=3)
 
2041
  svntest.actions.run_and_verify_svnadmin(None, [],
1850
2042
                                          "recover", sbox.repo_dir)
1851
2043
 
1852
2044
 
1853
2045
@SkipUnless(svntest.main.is_fs_type_fsfs)
 
2046
def verify_keep_going(sbox):
 
2047
  "svnadmin verify --keep-going test"
 
2048
 
 
2049
  sbox.build(create_wc = False)
 
2050
  repo_url = sbox.repo_url
 
2051
  B_url = sbox.repo_url + '/B'
 
2052
  C_url = sbox.repo_url + '/C'
 
2053
 
 
2054
  # Create A/B/E/bravo in r2.
 
2055
  svntest.actions.run_and_verify_svn(None, [],
 
2056
                                     'mkdir', '-m', 'log_msg',
 
2057
                                     B_url)
 
2058
 
 
2059
  svntest.actions.run_and_verify_svn(None, [],
 
2060
                                     'mkdir', '-m', 'log_msg',
 
2061
                                     C_url)
 
2062
 
 
2063
  r2 = fsfs_file(sbox.repo_dir, 'revs', '2')
 
2064
  fp = open(r2, 'r+b')
 
2065
  fp.write("""inserting junk to corrupt the rev""")
 
2066
  fp.close()
 
2067
  exit_code, output, errput = svntest.main.run_svnadmin("verify",
 
2068
                                                        "--keep-going",
 
2069
                                                        sbox.repo_dir)
 
2070
 
 
2071
  exp_out = svntest.verify.RegexListOutput([".*Verified revision 0.",
 
2072
                                            ".*Verified revision 1.",
 
2073
                                            ".*",
 
2074
                                            ".*Summary.*",
 
2075
                                            ".*r2: E160004:.*",
 
2076
                                            ".*r2: E160004:.*",
 
2077
                                            ".*r3: E160004:.*",
 
2078
                                            ".*r3: E160004:.*"])
 
2079
 
 
2080
  if (svntest.main.fs_has_rep_sharing()):
 
2081
    exp_out.insert(0, ".*Verifying.*metadata.*")
 
2082
 
 
2083
  exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
 
2084
                                            "svnadmin: E160004:.*",
 
2085
                                            "svnadmin: E160004:.*",
 
2086
                                            ".*Error verifying revision 3.",
 
2087
                                            "svnadmin: E160004:.*",
 
2088
                                            "svnadmin: E160004:.*",
 
2089
                                            "svnadmin: E205012:.*"], False)
 
2090
 
 
2091
  if (svntest.main.is_fs_log_addressing()):
 
2092
    exp_err.insert(0, ".*Error verifying repository metadata.")
 
2093
    exp_err.insert(1, "svnadmin: E160004:.*")
 
2094
 
 
2095
  if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
 
2096
                                   output, errput, exp_out, exp_err):
 
2097
    raise svntest.Failure
 
2098
 
 
2099
  exit_code, output, errput = svntest.main.run_svnadmin("verify",
 
2100
                                                        sbox.repo_dir)
 
2101
 
 
2102
  if (svntest.main.is_fs_log_addressing()):
 
2103
    exp_out = svntest.verify.RegexListOutput([".*Verifying metadata at revision 0"])
 
2104
  else:
 
2105
    exp_out = svntest.verify.RegexListOutput([".*Verified revision 0.",
 
2106
                                              ".*Verified revision 1."])
 
2107
    if (svntest.main.fs_has_rep_sharing()):
 
2108
      exp_out.insert(0, ".*Verifying repository metadata.*")
 
2109
 
 
2110
  if (svntest.main.is_fs_log_addressing()):
 
2111
    exp_err = svntest.verify.RegexListOutput([
 
2112
                                     ".*Error verifying repository metadata.",
 
2113
                                     "svnadmin: E160004:.*"], False)
 
2114
  else:
 
2115
    exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
 
2116
                                              "svnadmin: E160004:.*",
 
2117
                                              "svnadmin: E160004:.*"], False)
 
2118
 
 
2119
  if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
 
2120
                                   output, errput, exp_out, exp_err):
 
2121
    raise svntest.Failure
 
2122
 
 
2123
 
 
2124
  exit_code, output, errput = svntest.main.run_svnadmin("verify",
 
2125
                                                        "--quiet",
 
2126
                                                        sbox.repo_dir)
 
2127
 
 
2128
  if (svntest.main.is_fs_log_addressing()):
 
2129
    exp_err = svntest.verify.RegexListOutput([
 
2130
                                      ".*Error verifying repository metadata.",
 
2131
                                      "svnadmin: E160004:.*"], False)
 
2132
  else:
 
2133
    exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
 
2134
                                              "svnadmin: E160004:.*",
 
2135
                                              "svnadmin: E160004:.*"], False)
 
2136
 
 
2137
  if svntest.verify.verify_outputs("Output of 'svnadmin verify' is unexpected.",
 
2138
                                   None, errput, None, exp_err):
 
2139
    raise svntest.Failure
 
2140
 
 
2141
  # Don't leave a corrupt repository
 
2142
  svntest.main.safe_rmtree(sbox.repo_dir, True)
 
2143
 
 
2144
 
 
2145
@SkipUnless(svntest.main.is_fs_type_fsfs)
 
2146
def verify_keep_going_quiet(sbox):
 
2147
  "svnadmin verify --keep-going --quiet test"
 
2148
 
 
2149
  sbox.build(create_wc = False)
 
2150
  repo_url = sbox.repo_url
 
2151
  B_url = sbox.repo_url + '/B'
 
2152
  C_url = sbox.repo_url + '/C'
 
2153
 
 
2154
  # Create A/B/E/bravo in r2.
 
2155
  svntest.actions.run_and_verify_svn(None, [],
 
2156
                                     'mkdir', '-m', 'log_msg',
 
2157
                                     B_url)
 
2158
 
 
2159
  svntest.actions.run_and_verify_svn(None, [],
 
2160
                                     'mkdir', '-m', 'log_msg',
 
2161
                                     C_url)
 
2162
 
 
2163
  r2 = fsfs_file(sbox.repo_dir, 'revs', '2')
 
2164
  fp = open(r2, 'r+b')
 
2165
  fp.write("""inserting junk to corrupt the rev""")
 
2166
  fp.close()
 
2167
 
 
2168
  exit_code, output, errput = svntest.main.run_svnadmin("verify",
 
2169
                                                        "--keep-going",
 
2170
                                                        "--quiet",
 
2171
                                                        sbox.repo_dir)
 
2172
 
 
2173
  exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
 
2174
                                            "svnadmin: E160004:.*",
 
2175
                                            "svnadmin: E160004:.*",
 
2176
                                            ".*Error verifying revision 3.",
 
2177
                                            "svnadmin: E160004:.*",
 
2178
                                            "svnadmin: E160004:.*",
 
2179
                                            "svnadmin: E205012:.*"], False)
 
2180
 
 
2181
  # Insert another expected error from checksum verification
 
2182
  if (svntest.main.is_fs_log_addressing()):
 
2183
    exp_err.insert(0, ".*Error verifying repository metadata.")
 
2184
    exp_err.insert(1, "svnadmin: E160004:.*")
 
2185
 
 
2186
  if svntest.verify.verify_outputs(
 
2187
          "Unexpected error while running 'svnadmin verify'.",
 
2188
          output, errput, None, exp_err):
 
2189
    raise svntest.Failure
 
2190
 
 
2191
  # Don't leave a corrupt repository
 
2192
  svntest.main.safe_rmtree(sbox.repo_dir, True)
 
2193
 
 
2194
 
 
2195
@SkipUnless(svntest.main.is_fs_type_fsfs)
 
2196
def verify_invalid_path_changes(sbox):
 
2197
  "detect invalid changed path list entries"
 
2198
 
 
2199
  sbox.build(create_wc = False)
 
2200
  repo_url = sbox.repo_url
 
2201
 
 
2202
  # Create a number of revisions each adding a single path
 
2203
  for r in range(2,20):
 
2204
    svntest.actions.run_and_verify_svn(None, [],
 
2205
                                       'mkdir', '-m', 'log_msg',
 
2206
                                       sbox.repo_url + '/B' + str(r))
 
2207
 
 
2208
  # modify every other revision to make sure that errors are not simply
 
2209
  # "carried over" but that all corrupts we get detected independently
 
2210
 
 
2211
  # add existing node
 
2212
  set_changed_path_list(sbox, 2,
 
2213
                        "_0.0.t1-1 add-dir false false /A\n\n")
 
2214
 
 
2215
  # add into non-existent parent
 
2216
  set_changed_path_list(sbox, 4,
 
2217
                        "_0.0.t3-2 add-dir false false /C/X\n\n")
 
2218
 
 
2219
  # del non-existent node
 
2220
  set_changed_path_list(sbox, 6,
 
2221
                        "_0.0.t5-2 delete-dir false false /C\n\n")
 
2222
 
 
2223
  # del existent node of the wrong kind
 
2224
  #
 
2225
  # THIS WILL NOT BE DETECTED
 
2226
  # since dump mechanism and file don't care about the types of deleted nodes
 
2227
  set_changed_path_list(sbox, 8,
 
2228
                        "_0.0.t7-2 delete-file false false /B3\n\n")
 
2229
 
 
2230
  # copy from non-existent node
 
2231
  set_changed_path_list(sbox, 10,
 
2232
                        "_0.0.t9-2 add-dir false false /B10\n"
 
2233
                        "6 /B8\n")
 
2234
 
 
2235
  # copy from existing node of the wrong kind
 
2236
  set_changed_path_list(sbox, 12,
 
2237
                        "_0.0.t11-2 add-file false false /B12\n"
 
2238
                        "9 /B8\n")
 
2239
 
 
2240
  # modify non-existent node
 
2241
  set_changed_path_list(sbox, 14,
 
2242
                        "_0.0.t13-2 modify-file false false /A/D/H/foo\n\n")
 
2243
 
 
2244
  # modify existent node of the wrong kind
 
2245
  set_changed_path_list(sbox, 16,
 
2246
                        "_0.0.t15-2 modify-file false false /B12\n\n")
 
2247
 
 
2248
  # replace non-existent node
 
2249
  set_changed_path_list(sbox, 18,
 
2250
                        "_0.0.t17-2 replace-file false false /A/D/H/foo\n\n")
 
2251
 
 
2252
  # find corruptions
 
2253
  exit_code, output, errput = svntest.main.run_svnadmin("verify",
 
2254
                                                        "--keep-going",
 
2255
                                                        sbox.repo_dir)
 
2256
 
 
2257
  exp_out = svntest.verify.RegexListOutput([".*Verified revision 0.",
 
2258
                                           ".*Verified revision 1.",
 
2259
                                           ".*Verified revision 3.",
 
2260
                                           ".*Verified revision 5.",
 
2261
                                           ".*Verified revision 7.",
 
2262
                                           ".*Verified revision 8.",
 
2263
                                           ".*Verified revision 9.",
 
2264
                                           ".*Verified revision 11.",
 
2265
                                           ".*Verified revision 13.",
 
2266
                                           ".*Verified revision 15.",
 
2267
                                           ".*Verified revision 17.",
 
2268
                                           ".*Verified revision 19.",
 
2269
                                           ".*",
 
2270
                                           ".*Summary.*",
 
2271
                                           ".*r2: E160020:.*",
 
2272
                                           ".*r2: E160020:.*",
 
2273
                                           ".*r4: E160013:.*",
 
2274
                                           ".*r6: E160013:.*",
 
2275
                                           ".*r6: E160013:.*",
 
2276
                                           ".*r10: E160013:.*",
 
2277
                                           ".*r10: E160013:.*",
 
2278
                                           ".*r12: E145001:.*",
 
2279
                                           ".*r12: E145001:.*",
 
2280
                                           ".*r14: E160013:.*",
 
2281
                                           ".*r14: E160013:.*",
 
2282
                                           ".*r16: E145001:.*",
 
2283
                                           ".*r16: E145001:.*",
 
2284
                                           ".*r18: E160013:.*",
 
2285
                                           ".*r18: E160013:.*"])
 
2286
  if (svntest.main.fs_has_rep_sharing()):
 
2287
    exp_out.insert(0, ".*Verifying.*metadata.*")
 
2288
    if svntest.main.is_fs_log_addressing():
 
2289
      exp_out.insert(1, ".*Verifying.*metadata.*")
 
2290
 
 
2291
  exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
 
2292
                                            "svnadmin: E160020:.*",
 
2293
                                            "svnadmin: E160020:.*",
 
2294
                                            ".*Error verifying revision 4.",
 
2295
                                            "svnadmin: E160013:.*",
 
2296
                                            ".*Error verifying revision 6.",
 
2297
                                            "svnadmin: E160013:.*",
 
2298
                                            "svnadmin: E160013:.*",
 
2299
                                            ".*Error verifying revision 10.",
 
2300
                                            "svnadmin: E160013:.*",
 
2301
                                            "svnadmin: E160013:.*",
 
2302
                                            ".*Error verifying revision 12.",
 
2303
                                            "svnadmin: E145001:.*",
 
2304
                                            "svnadmin: E145001:.*",
 
2305
                                            ".*Error verifying revision 14.",
 
2306
                                            "svnadmin: E160013:.*",
 
2307
                                            "svnadmin: E160013:.*",
 
2308
                                            ".*Error verifying revision 16.",
 
2309
                                            "svnadmin: E145001:.*",
 
2310
                                            "svnadmin: E145001:.*",
 
2311
                                            ".*Error verifying revision 18.",
 
2312
                                            "svnadmin: E160013:.*",
 
2313
                                            "svnadmin: E160013:.*",
 
2314
                                            "svnadmin: E205012:.*"], False)
 
2315
 
 
2316
 
 
2317
  if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
 
2318
                                   output, errput, exp_out, exp_err):
 
2319
    raise svntest.Failure
 
2320
 
 
2321
  exit_code, output, errput = svntest.main.run_svnadmin("verify",
 
2322
                                                        sbox.repo_dir)
 
2323
 
 
2324
  exp_out = svntest.verify.RegexListOutput([".*Verified revision 0.",
 
2325
                                            ".*Verified revision 1."])
 
2326
  exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
 
2327
                                            "svnadmin: E160020:.*",
 
2328
                                            "svnadmin: E160020:.*"], False)
 
2329
 
 
2330
  if (svntest.main.fs_has_rep_sharing()):
 
2331
    exp_out.insert(0, ".*Verifying.*metadata.*")
 
2332
    if svntest.main.is_fs_log_addressing():
 
2333
      exp_out.insert(1, ".*Verifying.*metadata.*")
 
2334
  if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
 
2335
                                   output, errput, exp_out, exp_err):
 
2336
    raise svntest.Failure
 
2337
 
 
2338
 
 
2339
  exit_code, output, errput = svntest.main.run_svnadmin("verify",
 
2340
                                                        "--quiet",
 
2341
                                                        sbox.repo_dir)
 
2342
 
 
2343
  exp_out = []
 
2344
  exp_err = svntest.verify.RegexListOutput([".*Error verifying revision 2.",
 
2345
                                            "svnadmin: E160020:.*",
 
2346
                                            "svnadmin: E160020:.*"], False)
 
2347
 
 
2348
  if svntest.verify.verify_outputs("Output of 'svnadmin verify' is unexpected.",
 
2349
                                   output, errput, exp_out, exp_err):
 
2350
    raise svntest.Failure
 
2351
 
 
2352
  # Don't leave a corrupt repository
 
2353
  svntest.main.safe_rmtree(sbox.repo_dir, True)
 
2354
 
 
2355
 
 
2356
def verify_denormalized_names(sbox):
 
2357
  "detect denormalized names and name collisions"
 
2358
 
 
2359
  sbox.build(create_wc=False, empty=True)
 
2360
 
 
2361
  dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
 
2362
                                   'svnadmin_tests_data',
 
2363
                                   'normalization_check.dump')
 
2364
  load_dumpstream(sbox, open(dumpfile_location).read())
 
2365
 
 
2366
  exit_code, output, errput = svntest.main.run_svnadmin(
 
2367
    "verify", "--check-normalization", sbox.repo_dir)
 
2368
 
 
2369
  expected_output_regex_list = [
 
2370
    ".*Verified revision 0.",
 
2371
    ".*Verified revision 1.",
 
2372
    ".*Verified revision 2.",
 
2373
    ".*Verified revision 3.",
 
2374
                                           # A/{Eacute}/{aring}lpha
 
2375
    "WARNING 0x0003: Duplicate representation of path 'A/.*/.*lpha'",
 
2376
    ".*Verified revision 4.",
 
2377
    ".*Verified revision 5.",
 
2378
                                                      # Q/{aring}lpha
 
2379
    "WARNING 0x0004: Duplicate representation of path '/Q/.*lpha'"
 
2380
                                  # A/{Eacute}
 
2381
    " in svn:mergeinfo property of 'A/.*'",
 
2382
    ".*Verified revision 6.",
 
2383
    ".*Verified revision 7."]
 
2384
 
 
2385
  # The BDB backend doesn't do global metadata verification.
 
2386
  if (svntest.main.fs_has_rep_sharing()):
 
2387
    expected_output_regex_list.insert(0, ".*Verifying repository metadata.*")
 
2388
 
 
2389
  if svntest.main.is_fs_log_addressing():
 
2390
    expected_output_regex_list.insert(0, ".* Verifying metadata at revision 0.*")
 
2391
 
 
2392
  exp_out = svntest.verify.RegexListOutput(expected_output_regex_list)
 
2393
  exp_err = svntest.verify.ExpectedOutput([])
 
2394
 
 
2395
  svntest.verify.verify_outputs(
 
2396
    "Unexpected error while running 'svnadmin verify'.",
 
2397
    output, errput, exp_out, exp_err)
 
2398
 
 
2399
 
 
2400
@SkipUnless(svntest.main.is_fs_type_fsfs)
1854
2401
def fsfs_recover_old_non_empty(sbox):
1855
2402
  "fsfs recover non-empty --compatible-version=1.3"
1856
2403
 
1859
2406
  # svnadmin: E200002: Serialized hash missing terminator
1860
2407
 
1861
2408
  sbox.build(create_wc=False, minor_version=3)
1862
 
  svntest.actions.run_and_verify_svnadmin(None, None, [], "recover",
 
2409
  svntest.actions.run_and_verify_svnadmin(None, [], "recover",
1863
2410
                                          sbox.repo_dir)
1864
2411
 
1865
2412
 
1873
2420
 
1874
2421
  sbox.build(create_wc=False, minor_version=3)
1875
2422
  backup_dir, backup_url = sbox.add_repo_path('backup')
1876
 
  svntest.actions.run_and_verify_svnadmin(None, None, [], "hotcopy",
1877
 
                                          sbox.repo_dir, backup_dir)
1878
 
 
1879
 
  check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
1880
 
 
 
2423
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2424
                                          sbox.repo_dir, backup_dir)
 
2425
 
 
2426
  check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
 
2427
 
 
2428
 
 
2429
def load_ignore_dates(sbox):
 
2430
  "svnadmin load --ignore-dates"
 
2431
 
 
2432
  # All revisions in the loaded repository should come after this time.
 
2433
  start_time = time.localtime()
 
2434
  time.sleep(1)
 
2435
 
 
2436
  sbox.build(create_wc=False, empty=True)
 
2437
 
 
2438
  dumpfile_skeleton = open(os.path.join(os.path.dirname(sys.argv[0]),
 
2439
                                        'svnadmin_tests_data',
 
2440
                                        'skeleton_repos.dump')).read()
 
2441
 
 
2442
  load_dumpstream(sbox, dumpfile_skeleton, '--ignore-dates')
 
2443
  svntest.actions.run_and_verify_svnlook(['6\n'],
 
2444
                                         None, 'youngest', sbox.repo_dir)
 
2445
  for rev in range(1, 6):
 
2446
    exit_code, output, errput = svntest.main.run_svnlook('date', '-r', rev,
 
2447
                                                         sbox.repo_dir)
 
2448
    if errput:
 
2449
      raise SVNUnexpectedStderr(errput)
 
2450
    rev_time = time.strptime(output[0].rstrip()[:19], '%Y-%m-%d %H:%M:%S')
 
2451
    if rev_time < start_time:
 
2452
      raise svntest.Failure("Revision time for r%d older than load start time\n"
 
2453
                            "    rev_time: %s\n"
 
2454
                            "  start_time: %s"
 
2455
                            % (rev, str(rev_time), str(start_time)))
 
2456
 
 
2457
 
 
2458
@SkipUnless(svntest.main.is_fs_type_fsfs)
 
2459
def fsfs_hotcopy_old_with_id_changes(sbox):
 
2460
  "fsfs hotcopy old with node-id and copy-id changes"
 
2461
 
 
2462
  # Around trunk@1573728, running 'svnadmin hotcopy' for the
 
2463
  # --compatible-version=1.3 repository with certain node-id and copy-id
 
2464
  # changes ended with mismatching db/current in source and destination:
 
2465
  #
 
2466
  #   source: "2 l 1"  destination: "2 k 1",
 
2467
  #           "3 l 2"               "3 4 2"
 
2468
  #           (and so on...)
 
2469
  #
 
2470
  # We test this case by creating a --compatible-version=1.3 repository
 
2471
  # and committing things that result in node-id and copy-id changes.
 
2472
  # After every commit, we hotcopy the repository to a new destination
 
2473
  # and check whether the source of the backup and the backup itself are
 
2474
  # identical.  We also maintain a separate --incremental backup, which
 
2475
  # is updated and checked after every commit.
 
2476
  sbox.build(create_wc=True, minor_version=3)
 
2477
 
 
2478
  inc_backup_dir, inc_backup_url = sbox.add_repo_path('incremental-backup')
 
2479
 
 
2480
  # r1 = Initial greek tree sandbox.
 
2481
  backup_dir, backup_url = sbox.add_repo_path('backup-after-r1')
 
2482
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2483
                                          sbox.repo_dir, backup_dir)
 
2484
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2485
                                          "--incremental",
 
2486
                                          sbox.repo_dir, inc_backup_dir)
 
2487
  check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
 
2488
  check_hotcopy_fsfs(sbox.repo_dir, inc_backup_dir)
 
2489
 
 
2490
  # r2 = Add a new property.
 
2491
  sbox.simple_propset('foo', 'bar', 'A/mu')
 
2492
  sbox.simple_commit(message='r2')
 
2493
 
 
2494
  backup_dir, backup_url = sbox.add_repo_path('backup-after-r2')
 
2495
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2496
                                          sbox.repo_dir, backup_dir)
 
2497
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2498
                                          "--incremental",
 
2499
                                          sbox.repo_dir, inc_backup_dir)
 
2500
  check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
 
2501
  check_hotcopy_fsfs(sbox.repo_dir, inc_backup_dir)
 
2502
 
 
2503
  # r3 = Copy a file.
 
2504
  sbox.simple_copy('A/B/E', 'A/B/E1')
 
2505
  sbox.simple_commit(message='r3')
 
2506
 
 
2507
  backup_dir, backup_url = sbox.add_repo_path('backup-after-r3')
 
2508
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2509
                                          sbox.repo_dir, backup_dir)
 
2510
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2511
                                          "--incremental",
 
2512
                                          sbox.repo_dir, inc_backup_dir)
 
2513
  check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
 
2514
  check_hotcopy_fsfs(sbox.repo_dir, inc_backup_dir)
 
2515
 
 
2516
  # r4 = Remove an existing file ...
 
2517
  sbox.simple_rm('A/D/gamma')
 
2518
  sbox.simple_commit(message='r4')
 
2519
 
 
2520
  backup_dir, backup_url = sbox.add_repo_path('backup-after-r4')
 
2521
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2522
                                          sbox.repo_dir, backup_dir)
 
2523
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2524
                                          "--incremental",
 
2525
                                          sbox.repo_dir, inc_backup_dir)
 
2526
  check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
 
2527
  check_hotcopy_fsfs(sbox.repo_dir, inc_backup_dir)
 
2528
 
 
2529
  # r5 = ...and replace it with a new file here.
 
2530
  sbox.simple_add_text("This is the replaced file.\n", 'A/D/gamma')
 
2531
  sbox.simple_commit(message='r5')
 
2532
 
 
2533
  backup_dir, backup_url = sbox.add_repo_path('backup-after-r5')
 
2534
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2535
                                          sbox.repo_dir, backup_dir)
 
2536
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2537
                                          "--incremental",
 
2538
                                          sbox.repo_dir, inc_backup_dir)
 
2539
  check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
 
2540
  check_hotcopy_fsfs(sbox.repo_dir, inc_backup_dir)
 
2541
 
 
2542
  # r6 = Add an entirely new file.
 
2543
  sbox.simple_add_text('This is an entirely new file.\n', 'A/C/mu1')
 
2544
  sbox.simple_commit(message='r6')
 
2545
 
 
2546
  backup_dir, backup_url = sbox.add_repo_path('backup-after-r6')
 
2547
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2548
                                          sbox.repo_dir, backup_dir)
 
2549
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2550
                                          "--incremental",
 
2551
                                          sbox.repo_dir, inc_backup_dir)
 
2552
  check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
 
2553
  check_hotcopy_fsfs(sbox.repo_dir, inc_backup_dir)
 
2554
 
 
2555
  # r7 = Change the content of the existing file (this changeset does
 
2556
  #      not bump the next-id and copy-id counters in the repository).
 
2557
  sbox.simple_append('A/mu', 'This is change in the existing file.\n')
 
2558
  sbox.simple_commit(message='r7')
 
2559
 
 
2560
  backup_dir, backup_url = sbox.add_repo_path('backup-after-r7')
 
2561
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2562
                                          sbox.repo_dir, backup_dir)
 
2563
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2564
                                          "--incremental",
 
2565
                                          sbox.repo_dir, inc_backup_dir)
 
2566
  check_hotcopy_fsfs(sbox.repo_dir, backup_dir)
 
2567
  check_hotcopy_fsfs(sbox.repo_dir, inc_backup_dir)
 
2568
 
 
2569
 
 
2570
@SkipUnless(svntest.main.fs_has_pack)
 
2571
def verify_packed(sbox):
 
2572
  "verify packed with small shards"
 
2573
 
 
2574
  # Configure two files per shard to trigger packing.
 
2575
  sbox.build()
 
2576
  patch_format(sbox.repo_dir, shard_size=2)
 
2577
 
 
2578
  # Play with our greek tree.  These changesets fall into two
 
2579
  # separate shards with r2 and r3 being in shard 1 ...
 
2580
  sbox.simple_append('iota', "Line.\n")
 
2581
  sbox.simple_append('A/D/gamma', "Another line.\n")
 
2582
  sbox.simple_commit(message='r2')
 
2583
  sbox.simple_propset('foo', 'bar', 'iota')
 
2584
  sbox.simple_propset('foo', 'baz', 'A/mu')
 
2585
  sbox.simple_commit(message='r3')
 
2586
 
 
2587
  # ...and r4 and r5 being in shard 2.
 
2588
  sbox.simple_rm('A/C')
 
2589
  sbox.simple_copy('A/B/E', 'A/B/E1')
 
2590
  sbox.simple_move('A/mu', 'A/B/mu')
 
2591
  sbox.simple_commit(message='r4')
 
2592
  sbox.simple_propdel('foo', 'A/B/mu')
 
2593
  sbox.simple_commit(message='r5')
 
2594
 
 
2595
  if svntest.main.is_fs_type_fsfs and svntest.main.options.fsfs_packing:
 
2596
    # With --fsfs-packing, everything is already packed and we
 
2597
    # can skip this part.
 
2598
    pass
 
2599
  else:
 
2600
    expected_output = ["Packing revisions in shard 0...done.\n",
 
2601
                       "Packing revisions in shard 1...done.\n",
 
2602
                       "Packing revisions in shard 2...done.\n"]
 
2603
    svntest.actions.run_and_verify_svnadmin(expected_output, [],
 
2604
                                            "pack", sbox.repo_dir)
 
2605
 
 
2606
  if svntest.main.is_fs_log_addressing():
 
2607
    expected_output = ["* Verifying metadata at revision 0 ...\n",
 
2608
                       "* Verifying metadata at revision 2 ...\n",
 
2609
                       "* Verifying metadata at revision 4 ...\n",
 
2610
                       "* Verifying repository metadata ...\n",
 
2611
                       "* Verified revision 0.\n",
 
2612
                       "* Verified revision 1.\n",
 
2613
                       "* Verified revision 2.\n",
 
2614
                       "* Verified revision 3.\n",
 
2615
                       "* Verified revision 4.\n",
 
2616
                       "* Verified revision 5.\n"]
 
2617
  else:
 
2618
    expected_output = ["* Verifying repository metadata ...\n",
 
2619
                       "* Verified revision 0.\n",
 
2620
                       "* Verified revision 1.\n",
 
2621
                       "* Verified revision 2.\n",
 
2622
                       "* Verified revision 3.\n",
 
2623
                       "* Verified revision 4.\n",
 
2624
                       "* Verified revision 5.\n"]
 
2625
 
 
2626
  svntest.actions.run_and_verify_svnadmin(expected_output, [],
 
2627
                                          "verify", sbox.repo_dir)
 
2628
 
 
2629
# Test that 'svnadmin freeze' is nestable.  (For example, this ensures it
 
2630
# won't take system-global locks, only repository-scoped ones.)
 
2631
#
 
2632
# This could be useful to easily freeze a small number of repositories at once.
 
2633
#
 
2634
# ### We don't actually test that freeze takes a write lock anywhere (not even
 
2635
# ### in C tests.)
 
2636
def freeze_freeze(sbox):
 
2637
  "svnadmin freeze svnadmin freeze (some-cmd)"
 
2638
 
 
2639
  sbox.build(create_wc=False, read_only=True)
 
2640
  second_repo_dir, _ = sbox.add_repo_path('backup')
 
2641
  svntest.actions.run_and_verify_svnadmin(None, [], "hotcopy",
 
2642
                                          sbox.repo_dir, second_repo_dir)
 
2643
 
 
2644
  if svntest.main.is_fs_type_fsx() or \
 
2645
     (svntest.main.is_fs_type_fsfs() and \
 
2646
      svntest.main.options.server_minor_version < 9):
 
2647
    # FSFS repositories created with --compatible-version=1.8 and less
 
2648
    # erroneously share the filesystem data (locks, shared transaction
 
2649
    # data, ...) between hotcopy source and destination.  This is fixed
 
2650
    # for new FS formats, but in order to avoid a deadlock for old formats,
 
2651
    # we have to manually assign a new UUID for the hotcopy destination.
 
2652
    # As of trunk@1618024, the same applies to FSX repositories.
 
2653
    svntest.actions.run_and_verify_svnadmin([], None,
 
2654
                                            'setuuid', second_repo_dir)
 
2655
 
 
2656
  svntest.actions.run_and_verify_svnadmin(None, [],
 
2657
                 'freeze', '--', sbox.repo_dir,
 
2658
                 svntest.main.svnadmin_binary, 'freeze', '--', second_repo_dir,
 
2659
                 sys.executable, '-c', 'True')
 
2660
 
 
2661
  arg_file = sbox.get_tempname()
 
2662
  svntest.main.file_write(arg_file,
 
2663
                          "%s\n%s\n" % (sbox.repo_dir, second_repo_dir))
 
2664
 
 
2665
  svntest.actions.run_and_verify_svnadmin(None, [],
 
2666
                                          'freeze', '-F', arg_file, '--',
 
2667
                                          sys.executable, '-c', 'True')
 
2668
 
 
2669
def verify_metadata_only(sbox):
 
2670
  "verify metadata only"
 
2671
 
 
2672
  sbox.build(create_wc = False)
 
2673
  exit_code, output, errput = svntest.main.run_svnadmin("verify",
 
2674
                                                        sbox.repo_dir,
 
2675
                                                        "--metadata-only")
 
2676
  if errput:
 
2677
    raise SVNUnexpectedStderr(errput)
 
2678
 
 
2679
  # Unfortunately, older formats won't test as thoroughly than newer ones
 
2680
  # resulting in different progress output. BDB will do a full check but
 
2681
  # not produce any output.
 
2682
  if svntest.main.is_fs_log_addressing():
 
2683
    svntest.verify.compare_and_display_lines(
 
2684
      "Unexpected error while running 'svnadmin verify'.",
 
2685
      'STDOUT', ["* Verifying metadata at revision 0 ...\n",
 
2686
                 "* Verifying repository metadata ...\n"], output)
 
2687
  elif svntest.main.fs_has_rep_sharing() \
 
2688
       and not svntest.main.is_fs_type_bdb():
 
2689
    svntest.verify.compare_and_display_lines(
 
2690
      "Unexpected error while running 'svnadmin verify'.",
 
2691
      'STDOUT', ["* Verifying repository metadata ...\n"], output)
 
2692
  else:
 
2693
    svntest.verify.compare_and_display_lines(
 
2694
      "Unexpected error while running 'svnadmin verify'.",
 
2695
      'STDOUT', [], output)
 
2696
 
 
2697
 
 
2698
@Skip(svntest.main.is_fs_type_bdb)
 
2699
def verify_quickly(sbox):
 
2700
  "verify quickly using metadata"
 
2701
 
 
2702
  sbox.build(create_wc = False)
 
2703
  rev_file = open(fsfs_file(sbox.repo_dir, 'revs', '1'), 'r+b')
 
2704
 
 
2705
  # set new contents
 
2706
  rev_file.seek(8)
 
2707
  rev_file.write('#')
 
2708
  rev_file.close()
 
2709
 
 
2710
  exit_code, output, errput = svntest.main.run_svnadmin("verify",
 
2711
                                                        sbox.repo_dir,
 
2712
                                                        "--metadata-only")
 
2713
 
 
2714
  # unfortunately, some backends needs to do more checks than other
 
2715
  # resulting in different progress output
 
2716
  if svntest.main.is_fs_log_addressing():
 
2717
    exp_out = svntest.verify.RegexListOutput([])
 
2718
    exp_err = svntest.verify.RegexListOutput(["svnadmin: E160004:.*"], False)
 
2719
  else:
 
2720
    exp_out = svntest.verify.RegexListOutput([])
 
2721
    exp_err = svntest.verify.RegexListOutput([])
 
2722
 
 
2723
  if (svntest.main.fs_has_rep_sharing()):
 
2724
    exp_out.insert(0, ".*Verifying.*metadata.*")
 
2725
  if svntest.verify.verify_outputs("Unexpected error while running 'svnadmin verify'.",
 
2726
                                   output, errput, exp_out, exp_err):
 
2727
    raise svntest.Failure
 
2728
 
 
2729
  # Don't leave a corrupt repository
 
2730
  svntest.main.safe_rmtree(sbox.repo_dir, True)
 
2731
 
 
2732
 
 
2733
@SkipUnless(svntest.main.is_fs_type_fsfs)
 
2734
@SkipUnless(svntest.main.fs_has_pack)
 
2735
def fsfs_hotcopy_progress(sbox):
 
2736
  "hotcopy progress reporting"
 
2737
 
 
2738
  # Check how 'svnadmin hotcopy' reports progress for non-incremental
 
2739
  # and incremental scenarios.  The progress output can be affected by
 
2740
  # the --fsfs-packing option, so skip the test if that is the case.
 
2741
  if svntest.main.options.fsfs_packing:
 
2742
    raise svntest.Skip
 
2743
 
 
2744
  # Create an empty repository, configure three files per shard.
 
2745
  sbox.build(create_wc=False, empty=True)
 
2746
  patch_format(sbox.repo_dir, shard_size=3)
 
2747
 
 
2748
  inc_backup_dir, inc_backup_url = sbox.add_repo_path('incremental-backup')
 
2749
 
 
2750
  # Nothing really exciting for the empty repository.
 
2751
  expected_full = [
 
2752
    "* Copied revision 0.\n"
 
2753
    ]
 
2754
  expected_incremental = [
 
2755
    "* Copied revision 0.\n",
 
2756
    ]
 
2757
 
 
2758
  backup_dir, backup_url = sbox.add_repo_path('backup-0')
 
2759
  svntest.actions.run_and_verify_svnadmin(expected_full, [],
 
2760
                                          'hotcopy',
 
2761
                                          sbox.repo_dir, backup_dir)
 
2762
  svntest.actions.run_and_verify_svnadmin(expected_incremental, [],
 
2763
                                          'hotcopy', '--incremental',
 
2764
                                          sbox.repo_dir, inc_backup_dir)
 
2765
 
 
2766
  # Commit three revisions.  After this step we have a full shard
 
2767
  # (r0, r1, r2) and the second shard (r3) with a single revision.
 
2768
  for i in range(3):
 
2769
    svntest.actions.run_and_verify_svn(None, [], 'mkdir',
 
2770
                                       '-m', svntest.main.make_log_msg(),
 
2771
                                       sbox.repo_url + '/dir-%i' % i)
 
2772
  expected_full = [
 
2773
    "* Copied revision 0.\n",
 
2774
    "* Copied revision 1.\n",
 
2775
    "* Copied revision 2.\n",
 
2776
    "* Copied revision 3.\n",
 
2777
    ]
 
2778
  expected_incremental = [
 
2779
    "* Copied revision 1.\n",
 
2780
    "* Copied revision 2.\n",
 
2781
    "* Copied revision 3.\n",
 
2782
    ]
 
2783
 
 
2784
  backup_dir, backup_url = sbox.add_repo_path('backup-1')
 
2785
  svntest.actions.run_and_verify_svnadmin(expected_full, [],
 
2786
                                          'hotcopy',
 
2787
                                          sbox.repo_dir, backup_dir)
 
2788
  svntest.actions.run_and_verify_svnadmin(expected_incremental, [],
 
2789
                                          'hotcopy', '--incremental',
 
2790
                                          sbox.repo_dir, inc_backup_dir)
 
2791
 
 
2792
  # Pack everything (r3 is still unpacked) and hotcopy again.  In this case,
 
2793
  # the --incremental output should track the incoming (r0, r1, r2) pack and
 
2794
  # should not mention r3, because it is already a part of the destination
 
2795
  # and is *not* a part of the incoming pack.
 
2796
  svntest.actions.run_and_verify_svnadmin(None, [], 'pack',
 
2797
                                          sbox.repo_dir)
 
2798
  expected_full = [
 
2799
    "* Copied revisions from 0 to 2.\n",
 
2800
    "* Copied revision 3.\n",
 
2801
    ]
 
2802
  expected_incremental = [
 
2803
    "* Copied revisions from 0 to 2.\n",
 
2804
    ]
 
2805
 
 
2806
  backup_dir, backup_url = sbox.add_repo_path('backup-2')
 
2807
  svntest.actions.run_and_verify_svnadmin(expected_full, [],
 
2808
                                          'hotcopy',
 
2809
                                          sbox.repo_dir, backup_dir)
 
2810
  svntest.actions.run_and_verify_svnadmin(expected_incremental, [],
 
2811
                                          'hotcopy', '--incremental',
 
2812
                                          sbox.repo_dir, inc_backup_dir)
 
2813
 
 
2814
  # Fill the second shard, pack again, commit several unpacked revisions
 
2815
  # on top of it.  Rerun the hotcopy and check the progress output.
 
2816
  for i in range(4, 6):
 
2817
    svntest.actions.run_and_verify_svn(None, [], 'mkdir',
 
2818
                                       '-m', svntest.main.make_log_msg(),
 
2819
                                       sbox.repo_url + '/dir-%i' % i)
 
2820
 
 
2821
  svntest.actions.run_and_verify_svnadmin(None, [], 'pack',
 
2822
                                          sbox.repo_dir)
 
2823
 
 
2824
  for i in range(6, 8):
 
2825
    svntest.actions.run_and_verify_svn(None, [], 'mkdir',
 
2826
                                       '-m', svntest.main.make_log_msg(),
 
2827
                                       sbox.repo_url + '/dir-%i' % i)
 
2828
  expected_full = [
 
2829
    "* Copied revisions from 0 to 2.\n",
 
2830
    "* Copied revisions from 3 to 5.\n",
 
2831
    "* Copied revision 6.\n",
 
2832
    "* Copied revision 7.\n",
 
2833
    ]
 
2834
  expected_incremental = [
 
2835
    "* Copied revisions from 3 to 5.\n",
 
2836
    "* Copied revision 6.\n",
 
2837
    "* Copied revision 7.\n",
 
2838
    ]
 
2839
 
 
2840
  backup_dir, backup_url = sbox.add_repo_path('backup-3')
 
2841
  svntest.actions.run_and_verify_svnadmin(expected_full, [],
 
2842
                                          'hotcopy',
 
2843
                                          sbox.repo_dir, backup_dir)
 
2844
  svntest.actions.run_and_verify_svnadmin(expected_incremental, [],
 
2845
                                          'hotcopy', '--incremental',
 
2846
                                          sbox.repo_dir, inc_backup_dir)
 
2847
 
 
2848
 
 
2849
@SkipUnless(svntest.main.is_fs_type_fsfs)
 
2850
def fsfs_hotcopy_progress_with_revprop_changes(sbox):
 
2851
  "incremental hotcopy progress with changed revprops"
 
2852
 
 
2853
  # The progress output can be affected by the --fsfs-packing
 
2854
  # option, so skip the test if that is the case.
 
2855
  if svntest.main.options.fsfs_packing:
 
2856
    raise svntest.Skip
 
2857
 
 
2858
  # Create an empty repository, commit several revisions and hotcopy it.
 
2859
  sbox.build(create_wc=False, empty=True)
 
2860
 
 
2861
  for i in range(6):
 
2862
    svntest.actions.run_and_verify_svn(None, [], 'mkdir',
 
2863
                                       '-m', svntest.main.make_log_msg(),
 
2864
                                       sbox.repo_url + '/dir-%i' % i)
 
2865
  expected_output = [
 
2866
    "* Copied revision 0.\n",
 
2867
    "* Copied revision 1.\n",
 
2868
    "* Copied revision 2.\n",
 
2869
    "* Copied revision 3.\n",
 
2870
    "* Copied revision 4.\n",
 
2871
    "* Copied revision 5.\n",
 
2872
    "* Copied revision 6.\n",
 
2873
    ]
 
2874
 
 
2875
  backup_dir, backup_url = sbox.add_repo_path('backup')
 
2876
  svntest.actions.run_and_verify_svnadmin(expected_output, [],
 
2877
                                          'hotcopy',
 
2878
                                          sbox.repo_dir, backup_dir)
 
2879
 
 
2880
  # Amend a few log messages in the source, run the --incremental hotcopy.
 
2881
  # The progress output should only mention the corresponding revisions.
 
2882
  revprop_file = sbox.get_tempname()
 
2883
  svntest.main.file_write(revprop_file, "Modified log message.")
 
2884
 
 
2885
  for i in [1, 3, 6]:
 
2886
    svntest.actions.run_and_verify_svnadmin(None, [],
 
2887
                                            'setrevprop',
 
2888
                                            sbox.repo_dir, '-r', i,
 
2889
                                            'svn:log', revprop_file)
 
2890
  expected_output = [
 
2891
    "* Copied revision 1.\n",
 
2892
    "* Copied revision 3.\n",
 
2893
    "* Copied revision 6.\n",
 
2894
    ]
 
2895
  svntest.actions.run_and_verify_svnadmin(expected_output, [],
 
2896
                                          'hotcopy', '--incremental',
 
2897
                                          sbox.repo_dir, backup_dir)
 
2898
 
 
2899
 
 
2900
@SkipUnless(svntest.main.is_fs_type_fsfs)
 
2901
def fsfs_hotcopy_progress_old(sbox):
 
2902
  "hotcopy --compatible-version=1.3 progress"
 
2903
 
 
2904
  sbox.build(create_wc=False, empty=True, minor_version=3)
 
2905
 
 
2906
  inc_backup_dir, inc_backup_url = sbox.add_repo_path('incremental-backup')
 
2907
 
 
2908
  # Nothing really exciting for the empty repository.
 
2909
  expected_full = [
 
2910
    "* Copied revision 0.\n"
 
2911
    ]
 
2912
  expected_incremental = [
 
2913
    "* Copied revision 0.\n",
 
2914
    ]
 
2915
 
 
2916
  backup_dir, backup_url = sbox.add_repo_path('backup-0')
 
2917
  svntest.actions.run_and_verify_svnadmin(expected_full, [],
 
2918
                                          'hotcopy',
 
2919
                                          sbox.repo_dir, backup_dir)
 
2920
  svntest.actions.run_and_verify_svnadmin(expected_incremental, [],
 
2921
                                          'hotcopy', '--incremental',
 
2922
                                          sbox.repo_dir, inc_backup_dir)
 
2923
 
 
2924
  # Commit three revisions, hotcopy and check the progress output.
 
2925
  for i in range(3):
 
2926
    svntest.actions.run_and_verify_svn(None, [], 'mkdir',
 
2927
                                       '-m', svntest.main.make_log_msg(),
 
2928
                                       sbox.repo_url + '/dir-%i' % i)
 
2929
 
 
2930
  expected_full = [
 
2931
    "* Copied revision 0.\n",
 
2932
    "* Copied revision 1.\n",
 
2933
    "* Copied revision 2.\n",
 
2934
    "* Copied revision 3.\n",
 
2935
    ]
 
2936
  expected_incremental = [
 
2937
    "* Copied revision 1.\n",
 
2938
    "* Copied revision 2.\n",
 
2939
    "* Copied revision 3.\n",
 
2940
    ]
 
2941
 
 
2942
  backup_dir, backup_url = sbox.add_repo_path('backup-1')
 
2943
  svntest.actions.run_and_verify_svnadmin(expected_full, [],
 
2944
                                          'hotcopy',
 
2945
                                          sbox.repo_dir, backup_dir)
 
2946
  svntest.actions.run_and_verify_svnadmin(expected_incremental, [],
 
2947
                                          'hotcopy', '--incremental',
 
2948
                                          sbox.repo_dir, inc_backup_dir)
 
2949
 
 
2950
 
 
2951
@SkipUnless(svntest.main.fs_has_unique_freeze)
 
2952
def freeze_same_uuid(sbox):
 
2953
  "freeze multiple repositories with same UUID"
 
2954
 
 
2955
  sbox.build(create_wc=False)
 
2956
 
 
2957
  first_repo_dir, _ = sbox.add_repo_path('first')
 
2958
  second_repo_dir, _ = sbox.add_repo_path('second')
 
2959
 
 
2960
  # Test that 'svnadmin freeze A (svnadmin freeze B)' does not deadlock for
 
2961
  # new FSFS formats, even if 'A' and 'B' share the same UUID.  Create two
 
2962
  # repositories by loading the same dump file, ...
 
2963
  svntest.main.create_repos(first_repo_dir)
 
2964
  svntest.main.create_repos(second_repo_dir)
 
2965
 
 
2966
  dump_path = os.path.join(os.path.dirname(sys.argv[0]),
 
2967
                                           'svnadmin_tests_data',
 
2968
                                           'skeleton_repos.dump')
 
2969
  dump_contents = open(dump_path, 'rb').readlines()
 
2970
  svntest.actions.run_and_verify_load(first_repo_dir, dump_contents)
 
2971
  svntest.actions.run_and_verify_load(second_repo_dir, dump_contents)
 
2972
 
 
2973
  # ...and execute the 'svnadmin freeze -F' command.
 
2974
  arg_file = sbox.get_tempname()
 
2975
  svntest.main.file_write(arg_file,
 
2976
                          "%s\n%s\n" % (first_repo_dir, second_repo_dir))
 
2977
 
 
2978
  svntest.actions.run_and_verify_svnadmin(None, None,
 
2979
                                          'freeze', '-F', arg_file, '--',
 
2980
                                          sys.executable, '-c', 'True')
 
2981
 
 
2982
 
 
2983
@Skip(svntest.main.is_fs_type_fsx)
 
2984
def upgrade(sbox):
 
2985
  "upgrade --compatible-version=1.3"
 
2986
 
 
2987
  sbox.build(create_wc=False, minor_version=3)
 
2988
  svntest.actions.run_and_verify_svnadmin(None, [], "upgrade",
 
2989
                                          sbox.repo_dir)
 
2990
  # Does the repository work after upgrade?
 
2991
  svntest.actions.run_and_verify_svn(['Committing transaction...\n',
 
2992
                                     'Committed revision 2.\n'], [], 'mkdir',
 
2993
                                     '-m', svntest.main.make_log_msg(),
 
2994
                                     sbox.repo_url + '/dir')
 
2995
 
 
2996
def load_txdelta(sbox):
 
2997
  "exercising svn_txdelta_target on BDB"
 
2998
 
 
2999
  sbox.build(empty=True)
 
3000
 
 
3001
  # This dumpfile produced a BDB repository that generated cheksum
 
3002
  # mismatches on read caused by the improper handling of
 
3003
  # svn_txdelta_target ops.  The bug was fixed by r1640832.
 
3004
 
 
3005
  dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
 
3006
                                   'svnadmin_tests_data',
 
3007
                                   'load_txdelta.dump.gz')
 
3008
  dumpfile = gzip.open(dumpfile_location).read()
 
3009
 
 
3010
  load_dumpstream(sbox, dumpfile)
 
3011
 
 
3012
  # Verify would fail with a checksum mismatch:
 
3013
  # * Error verifying revision 14.
 
3014
  # svnadmin: E200014: MD5 checksum mismatch on representation 'r':
 
3015
  #    expected:  5182e8876ed894dc7fe28f6ff5b2fee6
 
3016
  #      actual:  5121f82875508863ad70daa8244e6947
 
3017
 
 
3018
  exit_code, output, errput = svntest.main.run_svnadmin("verify", sbox.repo_dir)
 
3019
  if errput:
 
3020
    raise SVNUnexpectedStderr(errput)
 
3021
  if svntest.verify.verify_outputs(
 
3022
    "Output of 'svnadmin verify' is unexpected.", None, output, None,
 
3023
    ".*Verified revision *"):
 
3024
    raise svntest.Failure
 
3025
 
 
3026
@Issues(4563)
 
3027
def load_no_svndate_r0(sbox):
 
3028
  "load without svn:date on r0"
 
3029
 
 
3030
  sbox.build(create_wc=False, empty=True)
 
3031
 
 
3032
  # svn:date exits
 
3033
  svntest.actions.run_and_verify_svnlook(['  svn:date\n'], [],
 
3034
                                         'proplist', '--revprop', '-r0',
 
3035
                                         sbox.repo_dir)
 
3036
 
 
3037
  dump_old = ["SVN-fs-dump-format-version: 2\n", "\n",
 
3038
              "UUID: bf52886d-358d-4493-a414-944a6e5ad4f5\n", "\n",
 
3039
              "Revision-number: 0\n",
 
3040
              "Prop-content-length: 10\n",
 
3041
              "Content-length: 10\n", "\n",
 
3042
              "PROPS-END\n", "\n"]
 
3043
  svntest.actions.run_and_verify_load(sbox.repo_dir, dump_old)
 
3044
  
 
3045
  # svn:date should have been removed
 
3046
  svntest.actions.run_and_verify_svnlook([], [],
 
3047
                                         'proplist', '--revprop', '-r0',
 
3048
                                         sbox.repo_dir)
 
3049
 
 
3050
# This is only supported for FSFS
 
3051
# The port to FSX is still pending, BDB won't support it.
 
3052
@SkipUnless(svntest.main.is_fs_type_fsfs)
 
3053
def hotcopy_read_only(sbox):
 
3054
  "'svnadmin hotcopy' a read-only source repository"
 
3055
  sbox.build()
 
3056
  svntest.main.chmod_tree(sbox.repo_dir, 0, 0222)
 
3057
 
 
3058
  backup_dir, backup_url = sbox.add_repo_path('backup')
 
3059
  exit_code, output, errput = svntest.main.run_svnadmin("hotcopy",
 
3060
                                                        sbox.repo_dir,
 
3061
                                                        backup_dir)
 
3062
 
 
3063
  # r/o repos are hard to clean up. Make it writable again.
 
3064
  svntest.main.chmod_tree(sbox.repo_dir, 0222, 0222)
 
3065
  if errput:
 
3066
    logger.warn("Error: hotcopy failed")
 
3067
    raise SVNUnexpectedStderr(errput)
1881
3068
 
1882
3069
########################################################################
1883
3070
# Run the tests
1916
3103
              locking,
1917
3104
              mergeinfo_race,
1918
3105
              recover_old_empty,
 
3106
              verify_keep_going,
 
3107
              verify_keep_going_quiet,
 
3108
              verify_invalid_path_changes,
 
3109
              verify_denormalized_names,
1919
3110
              fsfs_recover_old_non_empty,
1920
3111
              fsfs_hotcopy_old_non_empty,
 
3112
              load_ignore_dates,
 
3113
              fsfs_hotcopy_old_with_id_changes,
 
3114
              verify_packed,
 
3115
              freeze_freeze,
 
3116
              verify_metadata_only,
 
3117
              verify_quickly,
 
3118
              fsfs_hotcopy_progress,
 
3119
              fsfs_hotcopy_progress_with_revprop_changes,
 
3120
              fsfs_hotcopy_progress_old,
 
3121
              freeze_same_uuid,
 
3122
              upgrade,
 
3123
              load_txdelta,
 
3124
              load_no_svndate_r0,
 
3125
              hotcopy_read_only,
1921
3126
             ]
1922
3127
 
1923
3128
if __name__ == '__main__':