Skip some mergeinfo-related tests in merge_authz, switch, and update
[svn.git] / subversion / tests / cmdline / svnadmin_tests.py
blob5a77b13f785ef63da97e1c93e3b11349d792248f
1 #!/usr/bin/env python
3 # svnadmin_tests.py: testing the 'svnadmin' tool.
5 # Subversion is a tool for revision control.
6 # See http://subversion.tigris.org for more information.
8 # ====================================================================
9 # Copyright (c) 2000-2006 CollabNet. All rights reserved.
11 # This software is licensed as described in the file COPYING, which
12 # you should have received as part of this distribution. The terms
13 # are also available at http://subversion.tigris.org/license-1.html.
14 # If newer versions of this license are posted there, you may use a
15 # newer version instead, at your option.
17 ######################################################################
19 # General modules
20 import os
21 import shutil
22 import sys
24 # Our testing module
25 import svntest
26 from svntest.verify import SVNExpectedStdout, SVNExpectedStderr
27 from svntest.verify import SVNUnexpectedStderr
29 # (abbreviation)
30 Skip = svntest.testcase.Skip
31 SkipUnless = svntest.testcase.SkipUnless
32 XFail = svntest.testcase.XFail
33 Item = svntest.wc.StateItem
36 #----------------------------------------------------------------------
38 # How we currently test 'svnadmin' --
40 # 'svnadmin create': Create an empty repository, test that the
41 # root node has a proper created-revision,
42 # because there was once a bug where it
43 # didn't.
45 # Note also that "svnadmin create" is tested
46 # implicitly every time we run a python test
47 # script. (An empty repository is always
48 # created and then imported into; if this
49 # subcommand failed catastrophically, every
50 # test would fail and we would know instantly.)
52 # 'svnadmin createtxn'
53 # 'svnadmin rmtxn': See below.
55 # 'svnadmin lstxns': We don't care about the contents of transactions;
56 # we only care that they exist or not.
57 # Therefore, we can simply parse transaction headers.
59 # 'svnadmin dump': A couple regression tests that ensure dump doesn't
60 # error out, and one to check that the --quiet option
61 # really does what it's meant to do. The actual
62 # contents of the dump aren't verified at all.
64 # ### TODO: someday maybe we could parse the contents of trees too.
66 ######################################################################
67 # Helper routines
70 def get_txns(repo_dir):
71 "Get the txn names using 'svnadmin lstxns'."
73 exit_code, output_lines, error_lines = svntest.main.run_svnadmin('lstxns',
74 repo_dir)
75 txns = map(output_lines.strip, output_lines)
77 # sort, just in case
78 txns.sort()
80 return txns
82 def load_and_verify_dumpstream(sbox, expected_stdout, expected_stderr,
83 revs, dump, *varargs):
84 """Load the array of lines passed in 'dump' into the
85 current tests' repository and verify the repository content
86 using the array of wc.States passed in revs. VARARGS are optional
87 arguments passed to the 'load' command"""
89 if type(dump) is type(""):
90 dump = [ dump ]
92 exit_code, output, errput = svntest.main.run_command_stdin(
93 svntest.main.svnadmin_binary, expected_stderr, 1, dump,
94 'load', '--quiet', sbox.repo_dir, *varargs)
96 if expected_stdout:
97 if expected_stdout == svntest.verify.AnyOutput:
98 if len(output) == 0:
99 raise SVNExpectedStdout
100 else:
101 svntest.verify.compare_and_display_lines(
102 "Standard output", "STDOUT:", expected_stdout, output)
104 if expected_stderr:
105 if expected_stderr == svntest.verify.AnyOutput:
106 if len(errput) == 0:
107 raise SVNExpectedStderr
108 else:
109 svntest.verify.compare_and_display_lines(
110 "Standard error output", "STDERR:", expected_stderr, errput)
111 # The expected error occurred, so don't try to verify the result
112 return
114 if revs:
115 # verify revs as wc states
116 for rev in xrange(len(revs)):
117 svntest.actions.run_and_verify_svn("Updating to r%s" % (rev+1),
118 svntest.verify.AnyOutput, [],
119 "update", "-r%s" % (rev+1),
120 sbox.wc_dir)
122 wc_tree = svntest.tree.build_tree_from_wc(sbox.wc_dir)
123 rev_tree = revs[rev].old_tree()
125 try:
126 svntest.tree.compare_trees ("rev/disk", rev_tree, wc_tree)
127 except svntest.tree.SVNTreeError:
128 svntest.verify.display_trees(None, 'WC TREE', wc_tree, rev_tree)
129 raise
132 ######################################################################
133 # Tests
136 #----------------------------------------------------------------------
138 def test_create(sbox):
139 "'svnadmin create'"
142 repo_dir = sbox.repo_dir
143 wc_dir = sbox.wc_dir
145 svntest.main.safe_rmtree(repo_dir, 1)
146 svntest.main.safe_rmtree(wc_dir)
148 svntest.main.create_repos(repo_dir)
150 svntest.actions.run_and_verify_svn("Creating rev 0 checkout",
151 ["Checked out revision 0.\n"], [],
152 "checkout",
153 sbox.repo_url, wc_dir)
156 svntest.actions.run_and_verify_svn(
157 "Running status",
158 [], [],
159 "status", wc_dir)
161 svntest.actions.run_and_verify_svn(
162 "Running verbose status",
163 [" 0 0 ? %s\n" % wc_dir], [],
164 "status", "--verbose", wc_dir)
166 # success
169 # dump stream tests need a dump file
171 def clean_dumpfile():
172 return \
173 [ "SVN-fs-dump-format-version: 2\n\n",
174 "UUID: 668cc64a-31ed-0310-8ccb-b75d75bb44e3\n\n",
175 "Revision-number: 0\n",
176 "Prop-content-length: 56\n",
177 "Content-length: 56\n\n",
178 "K 8\nsvn:date\nV 27\n2005-01-08T21:48:13.838745Z\nPROPS-END\n\n\n",
179 "Revision-number: 1\n",
180 "Prop-content-length: 98\n",
181 "Content-length: 98\n\n",
182 "K 7\nsvn:log\nV 0\n\nK 10\nsvn:author\nV 4\nerik\n",
183 "K 8\nsvn:date\nV 27\n2005-01-08T21:51:16.313791Z\nPROPS-END\n\n\n",
184 "Node-path: A\n",
185 "Node-kind: file\n",
186 "Node-action: add\n",
187 "Prop-content-length: 35\n",
188 "Text-content-length: 5\n",
189 "Text-content-md5: e1cbb0c3879af8347246f12c559a86b5\n",
190 "Content-length: 40\n\n",
191 "K 12\nsvn:keywords\nV 2\nId\nPROPS-END\ntext\n\n\n"]
193 dumpfile_revisions = \
194 [ svntest.wc.State('', { 'A' : svntest.wc.StateItem(contents="text\n") }) ]
196 #----------------------------------------------------------------------
197 def extra_headers(sbox):
198 "loading of dumpstream with extra headers"
200 test_create(sbox)
202 dumpfile = clean_dumpfile()
204 dumpfile[3:3] = \
205 [ "X-Comment-Header: Ignored header normally not in dump stream\n" ]
207 load_and_verify_dumpstream(sbox,[],[], dumpfile_revisions, dumpfile)
209 #----------------------------------------------------------------------
210 # Ensure loading continues after skipping a bit of unknown extra content.
211 def extra_blockcontent(sbox):
212 "load success on oversized Content-length"
214 test_create(sbox)
216 dumpfile = clean_dumpfile()
218 # Replace "Content-length" line with two lines
219 dumpfile[8:9] = \
220 [ "Extra-content-length: 10\n",
221 "Content-length: 108\n\n" ]
222 # Insert the extra content after "PROPS-END\n"
223 dumpfile[11] = dumpfile[11][:-2] + "extra text\n\n\n"
225 load_and_verify_dumpstream(sbox,[],[], dumpfile_revisions, dumpfile)
227 #----------------------------------------------------------------------
228 def inconsistent_headers(sbox):
229 "load failure on undersized Content-length"
231 test_create(sbox)
233 dumpfile = clean_dumpfile()
235 dumpfile[-2] = "Content-length: 30\n\n"
237 load_and_verify_dumpstream(sbox, [], svntest.verify.AnyOutput,
238 dumpfile_revisions, dumpfile)
240 #----------------------------------------------------------------------
241 # Test for issue #2729: Datestamp-less revisions in dump streams do
242 # not remain so after load
243 def empty_date(sbox):
244 "preserve date-less revisions in load (issue #2729)"
246 test_create(sbox)
248 dumpfile = clean_dumpfile()
250 # Replace portions of the revision data to drop the svn:date revprop.
251 dumpfile[7:11] = \
252 [ "Prop-content-length: 52\n",
253 "Content-length: 52\n\n",
254 "K 7\nsvn:log\nV 0\n\nK 10\nsvn:author\nV 4\nerik\nPROPS-END\n\n\n"
257 load_and_verify_dumpstream(sbox,[],[], dumpfile_revisions, dumpfile)
259 # Verify that the revision still lacks the svn:date property.
260 svntest.actions.run_and_verify_svn(None, [], [], "propget",
261 "--revprop", "-r1", "svn:date",
262 sbox.wc_dir)
264 #----------------------------------------------------------------------
266 def dump_copied_dir(sbox):
267 "'svnadmin dump' on copied directory"
269 sbox.build()
270 wc_dir = sbox.wc_dir
271 repo_dir = sbox.repo_dir
273 old_C_path = os.path.join(wc_dir, 'A', 'C')
274 new_C_path = os.path.join(wc_dir, 'A', 'B', 'C')
275 svntest.main.run_svn(None, 'cp', old_C_path, new_C_path)
276 svntest.main.run_svn(None, 'ci', wc_dir, '--quiet',
277 '-m', 'log msg')
279 exit_code, output, errput = svntest.main.run_svnadmin("dump", repo_dir)
280 if svntest.verify.compare_and_display_lines(
281 "Output of 'svnadmin dump' is unexpected.",
282 'STDERR', ["* Dumped revision 0.\n",
283 "* Dumped revision 1.\n",
284 "* Dumped revision 2.\n"], errput):
285 raise svntest.Failure
287 #----------------------------------------------------------------------
289 def dump_move_dir_modify_child(sbox):
290 "'svnadmin dump' on modified child of copied dir"
292 sbox.build()
293 wc_dir = sbox.wc_dir
294 repo_dir = sbox.repo_dir
296 B_path = os.path.join(wc_dir, 'A', 'B')
297 Q_path = os.path.join(wc_dir, 'A', 'Q')
298 svntest.main.run_svn(None, 'cp', B_path, Q_path)
299 svntest.main.file_append(os.path.join(Q_path, 'lambda'), 'hello')
300 svntest.main.run_svn(None, 'ci', wc_dir, '--quiet',
301 '-m', 'log msg')
302 exit_code, output, errput = svntest.main.run_svnadmin("dump", repo_dir)
303 svntest.verify.compare_and_display_lines(
304 "Output of 'svnadmin dump' is unexpected.",
305 'STDERR', ["* Dumped revision 0.\n",
306 "* Dumped revision 1.\n",
307 "* Dumped revision 2.\n"], errput)
309 exit_code, output, errput = svntest.main.run_svnadmin("dump", "-r",
310 "0:HEAD", repo_dir)
311 svntest.verify.compare_and_display_lines(
312 "Output of 'svnadmin dump' is unexpected.",
313 'STDERR', ["* Dumped revision 0.\n",
314 "* Dumped revision 1.\n",
315 "* Dumped revision 2.\n"], errput)
317 #----------------------------------------------------------------------
319 def dump_quiet(sbox):
320 "'svnadmin dump --quiet'"
322 sbox.build(create_wc = False)
324 exit_code, output, errput = svntest.main.run_svnadmin("dump", sbox.repo_dir,
325 '--quiet')
326 svntest.verify.compare_and_display_lines(
327 "Output of 'svnadmin dump --quiet' is unexpected.",
328 'STDERR', [], errput)
330 #----------------------------------------------------------------------
332 def hotcopy_dot(sbox):
333 "'svnadmin hotcopy PATH .'"
334 sbox.build()
336 backup_dir, backup_url = sbox.add_repo_path('backup')
337 os.mkdir(backup_dir)
338 cwd = os.getcwd()
340 os.chdir(backup_dir)
341 exit_code, output, errput = svntest.main.run_svnadmin(
342 "hotcopy", os.path.join(cwd, sbox.repo_dir), '.')
344 if errput:
345 raise svntest.Failure
347 os.chdir(cwd)
349 exit_code, origout, origerr = svntest.main.run_svnadmin("dump",
350 sbox.repo_dir,
351 '--quiet')
352 exit_code, backout, backerr = svntest.main.run_svnadmin("dump",
353 backup_dir,
354 '--quiet')
355 if origerr or backerr or origout != backout:
356 raise svntest.Failure
358 #----------------------------------------------------------------------
360 def hotcopy_format(sbox):
361 "'svnadmin hotcopy' checking db/format file"
362 sbox.build()
364 backup_dir, backup_url = sbox.add_repo_path('backup')
365 exit_code, output, errput = svntest.main.run_svnadmin("hotcopy",
366 sbox.repo_dir,
367 backup_dir)
368 if errput:
369 print "Error: hotcopy failed"
370 raise svntest.Failure
372 # verify that the db/format files are the same
373 fp = open(os.path.join(sbox.repo_dir, "db", "format"))
374 contents1 = fp.read()
375 fp.close()
377 fp2 = open(os.path.join(backup_dir, "db", "format"))
378 contents2 = fp2.read()
379 fp2.close()
381 if contents1 != contents2:
382 print "Error: db/format file contents do not match after hotcopy"
383 raise svntest.Failure
385 #----------------------------------------------------------------------
387 def setrevprop(sbox):
388 "'setlog' and 'setrevprop', bypassing hooks'"
389 sbox.build()
391 # Try a simple log property modification.
392 iota_path = os.path.join(sbox.wc_dir, "iota")
393 exit_code, output, errput = svntest.main.run_svnadmin("setlog",
394 sbox.repo_dir,
395 "-r0",
396 "--bypass-hooks",
397 iota_path)
398 if errput:
399 print "Error: 'setlog' failed"
400 raise svntest.Failure
402 # Verify that the revprop value matches what we set when retrieved
403 # through the client.
404 svntest.actions.run_and_verify_svn(None,
405 [ "This is the file 'iota'.\n", "\n" ],
406 [], "propget", "--revprop", "-r0",
407 "svn:log", sbox.wc_dir)
409 # Try an author property modification.
410 foo_path = os.path.join(sbox.wc_dir, "foo")
411 svntest.main.file_write(foo_path, "foo")
413 exit_code, output, errput = svntest.main.run_svnadmin("setrevprop",
414 sbox.repo_dir,
415 "-r0", "svn:author",
416 foo_path)
417 if errput:
418 print "Error: 'setrevprop' failed"
419 raise svntest.Failure
421 # Verify that the revprop value matches what we set when retrieved
422 # through the client.
423 svntest.actions.run_and_verify_svn(None, [ "foo\n" ], [], "propget",
424 "--revprop", "-r0", "svn:author",
425 sbox.wc_dir)
427 def verify_windows_paths_in_repos(sbox):
428 "verify a repository containing paths like 'c:hi'"
430 # setup a repo with a directory 'c:hi'
431 sbox.build(create_wc = False)
432 repo_url = sbox.repo_url
433 chi_url = sbox.repo_url + '/c:hi'
435 svntest.actions.run_and_verify_svn(None, None, [],
436 'mkdir', '-m', 'log_msg',
437 chi_url)
439 exit_code, output, errput = svntest.main.run_svnadmin("verify",
440 sbox.repo_dir)
441 svntest.verify.compare_and_display_lines(
442 "Error while running 'svnadmin verify'.",
443 'STDERR', ["* Verified revision 0.\n",
444 "* Verified revision 1.\n",
445 "* Verified revision 2.\n"], errput)
447 #----------------------------------------------------------------------
449 # Returns the filename of the rev or revprop file (according to KIND)
450 # numbered REV in REPO_DIR, which must be in the first shard if we're
451 # using a sharded repository.
452 def fsfs_file(repo_dir, kind, rev):
453 if svntest.main.server_minor_version >= 5:
454 return os.path.join(repo_dir, 'db', kind, '0', rev)
455 else:
456 return os.path.join(repo_dir, 'db', kind, rev)
459 def verify_incremental_fsfs(sbox):
460 """svnadmin verify detects corruption dump can't"""
462 # setup a repo with a directory 'c:hi'
463 sbox.build(create_wc = False)
464 repo_url = sbox.repo_url
465 E_url = sbox.repo_url + '/A/B/E'
467 # Create A/B/E/bravo in r2.
468 svntest.actions.run_and_verify_svn(None, None, [],
469 'mkdir', '-m', 'log_msg',
470 E_url + '/bravo')
471 # Corrupt r2's reference to A/C by replacing "dir 7-1.0.r1/1568" with
472 # "dir 7-1.0.r1/1569" (increment offset) and updating the checksum for
473 # this directory listing to "c9b5a2d26473a4e28088673dda9df804" so that
474 # the listing itself is valid.
475 r2 = fsfs_file(sbox.repo_dir, 'revs', '2')
476 fp = open(r2, 'wb')
477 fp.write("""id: 0-2.0.r2/0
478 type: dir
479 count: 0
480 cpath: /A/B/E/bravo
481 copyroot: 0 /
483 PLAIN
485 alpha
486 V 17
487 file 3-1.0.r1/719
489 beta
490 V 17
491 file 4-1.0.r1/840
493 bravo
494 V 14
495 dir 0-2.0.r2/0
497 ENDREP
498 id: 2-1.0.r2/181
499 type: dir
500 pred: 2-1.0.r1/1043
501 count: 1
502 text: 2 69 99 99 f63001f7fddd1842d8891474d0982111
503 cpath: /A/B/E
504 copyroot: 0 /
506 PLAIN
509 V 16
510 dir 2-1.0.r2/181
513 V 17
514 dir 5-1.0.r1/1160
516 lambda
517 V 17
518 file 6-1.0.r1/597
520 ENDREP
521 id: 1-1.0.r2/424
522 type: dir
523 pred: 1-1.0.r1/1335
524 count: 1
525 text: 2 316 95 95 bccb66379b4f825dac12b50d80211bae
526 cpath: /A/B
527 copyroot: 0 /
529 PLAIN
532 V 16
533 dir 1-1.0.r2/424
536 V 17
537 dir 7-1.0.r1/1569
540 V 17
541 dir 8-1.0.r1/3061
544 V 18
545 file i-1.0.r1/1451
547 ENDREP
548 id: 0-1.0.r2/692
549 type: dir
550 pred: 0-1.0.r1/3312
551 count: 1
552 text: 2 558 121 121 c9b5a2d26473a4e28088673dda9df804
553 cpath: /A
554 copyroot: 0 /
556 PLAIN
559 V 16
560 dir 0-1.0.r2/692
562 iota
563 V 18
564 file j-1.0.r1/3428
566 ENDREP
567 id: 0.0.r2/904
568 type: dir
569 pred: 0.0.r1/3624
570 count: 2
571 text: 2 826 65 65 e44e4151d0d124533338619f082c8c9a
572 cpath: /
573 copyroot: 0 /
575 _0.0.t1-1 add false false /A/B/E/bravo
578 904 1031
579 """)
580 fp.close()
582 exit_code, output, errput = svntest.main.run_svnadmin("verify", "-r2",
583 sbox.repo_dir)
584 svntest.verify.verify_outputs(
585 message=None, actual_stdout=output, actual_stderr=errput,
586 expected_stdout=None,
587 expected_stderr=".*Missing id field in node-rev")
589 #----------------------------------------------------------------------
591 def recover_fsfs(sbox):
592 "recover a repository (FSFS only)"
593 sbox.build()
594 current_path = os.path.join(sbox.repo_dir, 'db', 'current')
596 # Commit up to r3, so we can test various recovery scenarios.
597 svntest.main.file_append(os.path.join(sbox.wc_dir, 'iota'), 'newer line\n')
598 svntest.main.run_svn(None, 'ci', sbox.wc_dir, '--quiet', '-m', 'log msg')
600 svntest.main.file_append(os.path.join(sbox.wc_dir, 'iota'), 'newest line\n')
601 svntest.main.run_svn(None, 'ci', sbox.wc_dir, '--quiet', '-m', 'log msg')
603 # Remember the contents of the db/current file.
604 expected_current_contents = svntest.main.file_read(current_path)
606 # Move aside the current file for r3.
607 os.rename(os.path.join(sbox.repo_dir, 'db','current'),
608 os.path.join(sbox.repo_dir, 'db','was_current'));
610 # Run 'svnadmin recover' and check that the current file is recreated.
611 exit_code, output, errput = svntest.main.run_svnadmin("recover",
612 sbox.repo_dir)
613 if errput:
614 raise SVNUnexpectedStderr(errput)
616 actual_current_contents = svntest.main.file_read(current_path)
617 svntest.verify.compare_and_display_lines(
618 "Contents of db/current is unexpected.",
619 'db/current', expected_current_contents, actual_current_contents)
621 # Now try writing db/current to be one rev lower than it should be.
622 svntest.main.file_write(current_path, '2\n')
624 # Run 'svnadmin recover' and check that the current file is fixed.
625 exit_code, output, errput = svntest.main.run_svnadmin("recover",
626 sbox.repo_dir)
627 if errput:
628 raise SVNUnexpectedStderr(errput)
630 actual_current_contents = svntest.main.file_read(current_path)
631 svntest.verify.compare_and_display_lines(
632 "Contents of db/current is unexpected.",
633 'db/current', expected_current_contents, actual_current_contents)
635 # Now try writing db/current to be *two* revs lower than it should be.
636 svntest.main.file_write(current_path, '1\n')
638 # Run 'svnadmin recover' and check that the current file is fixed.
639 exit_code, output, errput = svntest.main.run_svnadmin("recover",
640 sbox.repo_dir)
641 if errput:
642 raise SVNUnexpectedStderr(errput)
644 actual_current_contents = svntest.main.file_read(current_path)
645 svntest.verify.compare_and_display_lines(
646 "Contents of db/current is unexpected.",
647 'db/current', expected_current_contents, actual_current_contents)
649 # Now try writing db/current to be fish revs lower than it should be.
651 # Note: I'm not actually sure it's wise to recover from this, but
652 # detecting it would require rewriting fs_fs.c:get_youngest() to
653 # check the actual contents of its buffer, since atol() will happily
654 # convert "fish" to 0.
655 svntest.main.file_write(current_path, 'fish\n')
657 # Run 'svnadmin recover' and check that the current file is fixed.
658 exit_code, output, errput = svntest.main.run_svnadmin("recover",
659 sbox.repo_dir)
660 if errput:
661 raise SVNUnexpectedStderr(errput)
663 actual_current_contents = svntest.main.file_read(current_path)
664 svntest.verify.compare_and_display_lines(
665 "Contents of db/current is unexpected.",
666 'db/current', expected_current_contents, actual_current_contents)
668 #----------------------------------------------------------------------
670 def load_with_parent_dir(sbox):
671 "'svnadmin load --parent-dir' reparents mergeinfo"
673 ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2983. ##
674 test_create(sbox)
676 dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
677 'svnadmin_tests_data',
678 'mergeinfo_included.dump')
679 dumpfile = svntest.main.file_read(dumpfile_location)
681 # Create 'sample' dir in sbox.repo_url
682 svntest.actions.run_and_verify_svn(None,
683 ['\n', 'Committed revision 1.\n'],
684 [], "mkdir", sbox.repo_url + "/sample",
685 "-m", "Create sample dir")
687 # Load the dump stream
688 load_and_verify_dumpstream(sbox,[],[], None, dumpfile, '--parent-dir',
689 '/sample')
691 # Verify the svn:mergeinfo properties for '--parent-dir'
692 svntest.actions.run_and_verify_svn(None,
693 [sbox.repo_url +
694 "/sample/branch - /sample/trunk:5-7\n"],
695 [], 'propget', 'svn:mergeinfo', '-R',
696 sbox.repo_url + '/sample/branch')
697 svntest.actions.run_and_verify_svn(None,
698 [sbox.repo_url +
699 "/sample/branch1 - " +
700 "/sample/branch:6-9\n"],
701 [], 'propget', 'svn:mergeinfo', '-R',
702 sbox.repo_url + '/sample/branch1')
704 #----------------------------------------------------------------------
706 def set_uuid(sbox):
707 "test 'svnadmin setuuid'"
709 sbox.build(create_wc=False)
711 # Squirrel away the original repository UUID.
712 exit_code, output, errput = svntest.main.run_svnlook('uuid', sbox.repo_dir)
713 if errput:
714 raise SVNUnexpectedStderr(errput)
715 orig_uuid = output[0].rstrip()
717 # Try setting a new, bogus UUID.
718 svntest.actions.run_and_verify_svnadmin(None, None, '^.*Malformed UUID.*$',
719 'setuuid', sbox.repo_dir, 'abcdef')
721 # Try generating a brand new UUID.
722 svntest.actions.run_and_verify_svnadmin(None, [], None,
723 'setuuid', sbox.repo_dir)
724 exit_code, output, errput = svntest.main.run_svnlook('uuid', sbox.repo_dir)
725 if errput:
726 raise SVNUnexpectedStderr(errput)
727 new_uuid = output[0].rstrip()
728 if new_uuid == orig_uuid:
729 print "Error: new UUID matches the original one"
730 raise svntest.Failure
732 # Now, try setting the UUID back to the original value.
733 svntest.actions.run_and_verify_svnadmin(None, [], None,
734 'setuuid', sbox.repo_dir, orig_uuid)
735 exit_code, output, errput = svntest.main.run_svnlook('uuid', sbox.repo_dir)
736 if errput:
737 raise SVNUnexpectedStderr(errput)
738 new_uuid = output[0].rstrip()
739 if new_uuid != orig_uuid:
740 print "Error: new UUID doesn't match the original one"
741 raise svntest.Failure
743 #----------------------------------------------------------------------
745 def reflect_dropped_renumbered_revs(sbox):
746 "reflect dropped renumbered revs in svn:mergeinfo"
748 ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3020. ##
750 test_create(sbox)
752 dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
753 'svndumpfilter_tests_data',
754 'with_merges.dump')
755 dumpfile = svntest.main.file_read(dumpfile_location)
757 # Create 'toplevel' dir in sbox.repo_url
758 svntest.actions.run_and_verify_svn(None, ['\n', 'Committed revision 1.\n'],
759 [], "mkdir", sbox.repo_url + "/toplevel",
760 "-m", "Create toplevel dir")
762 # Load the dump stream in sbox.repo_url
763 load_and_verify_dumpstream(sbox,[],[], None, dumpfile)
765 # Load the dump stream in toplevel dir
766 load_and_verify_dumpstream(sbox,[],[], None, dumpfile, '--parent-dir',
767 '/toplevel')
769 # Verify the svn:mergeinfo properties
770 svntest.actions.run_and_verify_svn(None, ["/trunk:1-4\n"],
771 [], 'propget', 'svn:mergeinfo',
772 sbox.repo_url + '/branch2')
773 svntest.actions.run_and_verify_svn(None, ["/branch1:5-9\n"],
774 [], 'propget', 'svn:mergeinfo',
775 sbox.repo_url + '/trunk')
776 svntest.actions.run_and_verify_svn(None, ["/toplevel/trunk:1-13\n"],
777 [], 'propget', 'svn:mergeinfo',
778 sbox.repo_url + '/toplevel/branch2')
779 svntest.actions.run_and_verify_svn(None, ["/toplevel/branch1:14-18\n"],
780 [], 'propget', 'svn:mergeinfo',
781 sbox.repo_url + '/toplevel/trunk')
782 svntest.actions.run_and_verify_svn(None, ["/toplevel/trunk:1-12\n"],
783 [], 'propget', 'svn:mergeinfo',
784 sbox.repo_url + '/toplevel/branch1')
785 svntest.actions.run_and_verify_svn(None, ["/trunk:1-3\n"],
786 [], 'propget', 'svn:mergeinfo',
787 sbox.repo_url + '/branch1')
789 #----------------------------------------------------------------------
791 def fsfs_recover_handle_missing_revs_or_revprops_file(sbox):
792 """fsfs recovery checks missing revs / revprops files"""
793 # Set up a repository containing the greek tree.
794 sbox.build()
796 # Commit up to r3, so we can test various recovery scenarios.
797 svntest.main.file_append(os.path.join(sbox.wc_dir, 'iota'), 'newer line\n')
798 svntest.main.run_svn(None, 'ci', sbox.wc_dir, '--quiet', '-m', 'log msg')
800 svntest.main.file_append(os.path.join(sbox.wc_dir, 'iota'), 'newest line\n')
801 svntest.main.run_svn(None, 'ci', sbox.wc_dir, '--quiet', '-m', 'log msg')
803 rev_3 = fsfs_file(sbox.repo_dir, 'revs', '3')
804 rev_was_3 = fsfs_file(sbox.repo_dir, 'revs', 'was_3')
806 # Move aside the revs file for r3.
807 os.rename(rev_3, rev_was_3)
809 # Verify 'svnadmin recover' fails when youngest has a revprops
810 # file but no revs file.
811 exit_code, output, errput = svntest.main.run_svnadmin("recover",
812 sbox.repo_dir)
814 if svntest.verify.verify_outputs(
815 "Output of 'svnadmin recover' is unexpected.", None, errput, None,
816 ".*Expected current rev to be <= 2 but found 3"):
817 raise svntest.Failure
819 # Restore the r3 revs file, thus repairing the repository.
820 os.rename(rev_was_3, rev_3)
822 revprop_3 = fsfs_file(sbox.repo_dir, 'revprops', '3')
823 revprop_was_3 = fsfs_file(sbox.repo_dir, 'revprops', 'was_3')
825 # Move aside the revprops file for r3.
826 os.rename(revprop_3, revprop_was_3)
828 # Verify 'svnadmin recover' fails when youngest has a revs file
829 # but no revprops file (issue #2992).
830 exit_code, output, errput = svntest.main.run_svnadmin("recover",
831 sbox.repo_dir)
833 if svntest.verify.verify_outputs(
834 "Output of 'svnadmin recover' is unexpected.", None, errput, None,
835 ".*Revision 3 has a revs file but no revprops file"):
836 raise svntest.Failure
838 # Restore the r3 revprops file, thus repairing the repository.
839 os.rename(revprop_was_3, revprop_3)
841 # Change revprops file to a directory for revision 3
842 os.rename(revprop_3, revprop_was_3)
843 os.mkdir(revprop_3)
845 # Verify 'svnadmin recover' fails when youngest has a revs file
846 # but revprops file is not a file (another aspect of issue #2992).
847 exit_code, output, errput = svntest.main.run_svnadmin("recover",
848 sbox.repo_dir)
850 if svntest.verify.verify_outputs(
851 "Output of 'svnadmin recover' is unexpected.", None, errput, None,
852 ".*Revision 3 has a non-file where its revprops file should be.*"):
853 raise svntest.Failure
855 ########################################################################
856 # Run the tests
859 # list all tests here, starting with None:
860 test_list = [ None,
861 extra_headers,
862 extra_blockcontent,
863 inconsistent_headers,
864 empty_date,
865 dump_copied_dir,
866 dump_move_dir_modify_child,
867 dump_quiet,
868 hotcopy_dot,
869 hotcopy_format,
870 setrevprop,
871 verify_windows_paths_in_repos,
872 SkipUnless(verify_incremental_fsfs, svntest.main.is_fs_type_fsfs),
873 SkipUnless(recover_fsfs, svntest.main.is_fs_type_fsfs),
874 load_with_parent_dir,
875 set_uuid,
876 reflect_dropped_renumbered_revs,
877 SkipUnless(fsfs_recover_handle_missing_revs_or_revprops_file,
878 svntest.main.is_fs_type_fsfs),
881 if __name__ == '__main__':
882 svntest.main.run_tests(test_list)
883 # NOTREACHED
886 ### End of file.