61
60
######################################################################
64
def build_repos(sbox):
65
"""Build an empty sandbox repository"""
67
# Cleanup after the last run by removing any left-over repository.
68
svntest.main.safe_rmtree(sbox.repo_dir)
70
# Create an empty repository.
71
svntest.main.create_repos(sbox.repo_dir)
73
def compare_repos_dumps(svnrdump_sbox, svnadmin_dumpfile):
74
"""Compare two dumpfiles, one created from SVNRDUMP_SBOX, and other given
75
by SVNADMIN_DUMPFILE. The dumpfiles do not need to match linewise, as the
76
SVNADMIN_DUMPFILE contents will first be loaded into a repository and then
63
def compare_repos_dumps(sbox, other_dumpfile,
64
bypass_prop_validation=False):
65
"""Compare two dumpfiles, one created from SBOX, and other given
66
by OTHER_DUMPFILE. The dumpfiles do not need to match linewise, as the
67
OTHER_DUMPFILE contents will first be loaded into a repository and then
77
68
re-dumped to do the match, which should generate the same dumpfile as
78
dumping SVNRDUMP_SBOX."""
80
svnrdump_contents = svntest.actions.run_and_verify_dump(
81
svnrdump_sbox.repo_dir)
83
svnadmin_sbox = svnrdump_sbox.clone_dependent()
84
svntest.main.safe_rmtree(svnadmin_sbox.repo_dir)
85
svntest.main.create_repos(svnadmin_sbox.repo_dir)
87
svntest.actions.run_and_verify_load(svnadmin_sbox.repo_dir, svnadmin_dumpfile)
89
svnadmin_contents = svntest.actions.run_and_verify_dump(
90
svnadmin_sbox.repo_dir)
72
sbox_dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir)
74
# Load and dump the other dumpfile (using svnadmin)
75
other_sbox = sbox.clone_dependent()
76
other_sbox.build(create_wc=False, empty=True)
77
svntest.actions.run_and_verify_load(other_sbox.repo_dir, other_dumpfile,
78
bypass_prop_validation)
79
other_dumpfile = svntest.actions.run_and_verify_dump(other_sbox.repo_dir)
81
### This call kind-of assumes EXPECTED is first and ACTUAL is second.
92
82
svntest.verify.compare_dump_files(
93
"Dump files", "DUMP", svnadmin_contents, svnrdump_contents)
83
"Dump files", "DUMP", other_dumpfile, sbox_dumpfile)
95
85
def run_dump_test(sbox, dumpfile_name, expected_dumpfile_name = None,
96
86
subdir = None, bypass_prop_validation = False,
112
102
# Load the specified dump file into the sbox repository using
114
svnadmin_dumpfile = open(os.path.join(svnrdump_tests_dir,
104
original_dumpfile = open(os.path.join(svnrdump_tests_dir,
116
106
'rb').readlines()
118
svntest.actions.run_and_verify_load(sbox.repo_dir, svnadmin_dumpfile,
107
svntest.actions.run_and_verify_load(sbox.repo_dir, original_dumpfile,
119
108
bypass_prop_validation)
121
110
repo_url = sbox.repo_url
131
120
if expected_dumpfile_name:
132
svnadmin_dumpfile = open(os.path.join(svnrdump_tests_dir,
121
expected_dumpfile = open(os.path.join(svnrdump_tests_dir,
133
122
expected_dumpfile_name),
134
123
'rb').readlines()
135
124
# Compare the output from stdout
136
125
if ignore_base_checksums:
137
svnadmin_dumpfile = [l for l in svnadmin_dumpfile
126
expected_dumpfile = [l for l in expected_dumpfile
138
127
if not l.startswith('Text-delta-base-md5')]
139
128
svnrdump_dumpfile = [l for l in svnrdump_dumpfile
140
129
if not l.startswith('Text-delta-base-md5')]
141
svnadmin_dumpfile = [l for l in svnadmin_dumpfile
130
expected_dumpfile = [l for l in expected_dumpfile
142
131
if not mismatched_headers_re.match(l)]
143
132
svnrdump_dumpfile = [l for l in svnrdump_dumpfile
144
133
if not mismatched_headers_re.match(l)]
146
svnadmin_dumpfile = svntest.verify.UnorderedOutput(svnadmin_dumpfile)
135
expected_dumpfile = svntest.verify.UnorderedOutput(expected_dumpfile)
148
137
svntest.verify.compare_and_display_lines(
149
"Dump files", "DUMP", svnadmin_dumpfile, svnrdump_dumpfile,
138
"Dump files", "DUMP", expected_dumpfile, svnrdump_dumpfile,
153
compare_repos_dumps(sbox, svnadmin_dumpfile)
142
# The expected dumpfile is the result of dumping SBOX.
143
compare_repos_dumps(sbox, svnrdump_dumpfile, bypass_prop_validation)
155
145
def run_load_test(sbox, dumpfile_name, expected_dumpfile_name = None,
156
146
expect_deltas = True):
170
160
# Load the specified dump file into the sbox repository using
172
svnrdump_dumpfile = open(os.path.join(svnrdump_tests_dir,
162
original_dumpfile = open(os.path.join(svnrdump_tests_dir,
174
164
'rb').readlines()
176
166
# Set the UUID of the sbox repository to the UUID specified in the
177
167
# dumpfile ### RA layer doesn't have a set_uuid functionality
178
uuid = svnrdump_dumpfile[2].split(' ')[1][:-1]
179
svntest.actions.run_and_verify_svnadmin2("Setting UUID", None, None, 0,
168
uuid = original_dumpfile[2].split(' ')[1][:-1]
169
svntest.actions.run_and_verify_svnadmin2(None, None, 0,
180
170
'setuuid', sbox.repo_dir,
183
svntest.actions.run_and_verify_svnrdump(svnrdump_dumpfile,
173
svntest.actions.run_and_verify_svnrdump(original_dumpfile,
184
174
svntest.verify.AnyOutput,
185
175
[], 0, 'load', sbox.repo_url)
187
# Create a dump file using svnadmin dump
188
svnadmin_dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir,
177
# Re-dump the rdump-loaded repo using svnadmin dump
178
resulted_dumpfile = svntest.actions.run_and_verify_dump(sbox.repo_dir,
191
181
if expected_dumpfile_name:
192
svnrdump_dumpfile = open(os.path.join(svnrdump_tests_dir,
182
expected_dumpfile = open(os.path.join(svnrdump_tests_dir,
193
183
expected_dumpfile_name),
194
184
'rb').readlines()
196
186
# Compare the output from stdout
197
187
svntest.verify.compare_and_display_lines(
198
"Dump files", "DUMP", svnrdump_dumpfile, svnadmin_dumpfile)
188
"Dump files", "DUMP", expected_dumpfile, resulted_dumpfile)
201
compare_repos_dumps(sbox, svnrdump_dumpfile)
191
expected_dumpfile = original_dumpfile
192
compare_repos_dumps(sbox, expected_dumpfile)
203
194
######################################################################
432
423
# Create the 'toplevel' directory in repository and then load the same
433
424
# dumpfile into that subtree.
434
svntest.actions.run_and_verify_svn(None, ['\n', 'Committed revision 10.\n'],
425
svntest.actions.run_and_verify_svn(['Committing transaction...\n',
426
'Committed revision 10.\n'],
435
427
[], "mkdir", sbox.repo_url + "/toplevel",
436
428
"-m", "Create toplevel dir to load into")
437
429
svntest.actions.run_and_verify_svnrdump(svnrdump_dumpfile,
444
436
url + "/trunk - /branch1:4-8\n",
445
437
url + "/toplevel/trunk - /toplevel/branch1:14-18\n",
447
svntest.actions.run_and_verify_svn(None, expected_output, [],
439
svntest.actions.run_and_verify_svn(expected_output, [],
448
440
'propget', 'svn:mergeinfo', '-R',
542
534
url + "B2 - /trunk:9\n",
543
535
url + "B1/B/E - /branches/B2/B/E:11-12\n",
544
536
"/trunk/B/E:5-6,8-9\n"])
545
svntest.actions.run_and_verify_svn(None, expected_output, [],
537
svntest.actions.run_and_verify_svn(expected_output, [],
546
538
'propget', 'svn:mergeinfo', '-R',
604
597
# Check the mergeinfo, we use the same expected output as before,
605
598
# as it (duh!) should be exactly the same as when we loaded the
606
599
# repos in one shot.
607
svntest.actions.run_and_verify_svn(None, expected_output, [],
600
svntest.actions.run_and_verify_svn(expected_output, [],
608
601
'propget', 'svn:mergeinfo', '-R',
668
662
url + "B2 - /Projects/Project-X/trunk:15\n",
669
663
url + "B1/B/E - /Projects/Project-X/branches/B2/B/E:17-18\n",
670
664
"/Projects/Project-X/trunk/B/E:11-12,14-15\n"])
671
svntest.actions.run_and_verify_svn(None, expected_output, [],
665
svntest.actions.run_and_verify_svn(expected_output, [],
672
666
'propget', 'svn:mergeinfo', '-R',
675
669
# PART 4: Load a a series of incremental dumps to an non-empty repository.
677
671
# Reset our sandbox.
672
svntest.main.safe_rmtree(sbox.repo_dir, True) # Fix race with bdb in svnserve
673
sbox.build(empty=True)
680
675
# Create the revprop-change hook for this test
681
676
svntest.actions.enable_revprop_changes(sbox.repo_dir)
710
705
# Check the resulting mergeinfo. We expect the exact same results
712
707
# See http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16.
713
svntest.actions.run_and_verify_svn(None, expected_output, [],
708
svntest.actions.run_and_verify_svn(expected_output, [],
714
709
'propget', 'svn:mergeinfo', '-R',
720
715
"svnrdump load partial incremental dump"
722
717
# Create an empty sandbox repository
718
sbox.build(create_wc=False, empty=True)
725
720
# Create the revprop-change hook for this test
726
721
svntest.actions.enable_revprop_changes(sbox.repo_dir)
728
723
# Create the 'A' directory in repository and then load the partial
729
724
# incremental dump into the root of the repository.
730
svntest.actions.run_and_verify_svn(None, ['\n', 'Committed revision 1.\n'],
725
svntest.actions.run_and_verify_svn(['Committing transaction...\n',
726
'Committed revision 1.\n'],
731
727
[], "mkdir", sbox.repo_url + "/A",
732
728
"-m", "Create toplevel dir to load into")
770
766
#----------------------------------------------------------------------
769
def load_prop_change_in_non_deltas_dump(sbox):
770
"load: prop change in non-deltas dump"
771
# 'svnrdump load' crashed when processing a node record with a non-delta
772
# properties block if the node previously had any svn:* properties.
775
sbox.simple_propset('svn:eol-style', 'native', 'iota', 'A/mu', 'A/B/lambda')
778
# Any prop change on a node that had an svn:* prop triggered the crash,
779
# so test an svn:* prop deletion and also some other prop changes.
780
sbox.simple_propdel('svn:eol-style', 'iota')
781
sbox.simple_propset('svn:eol-style', 'LF', 'A/mu')
782
sbox.simple_propset('p1', 'v1', 'A/B/lambda')
785
# Create a non-deltas dump. Use 'svnadmin', as svnrdump doesn't have that
787
dump = svntest.actions.run_and_verify_dump(sbox.repo_dir, deltas=False)
789
# Try to load that dump.
790
sbox.build(create_wc=False, empty=True)
791
svntest.actions.enable_revprop_changes(sbox.repo_dir)
792
svntest.actions.run_and_verify_svnrdump(dump,
794
'-q', 'load', sbox.repo_url)
796
#----------------------------------------------------------------------
799
def dump_mergeinfo_contains_r0(sbox):
800
"dump: mergeinfo that contains r0"
801
### We pass the original dump file name as 'expected_dumpfile_name' because
802
### run_dump_test is currently broken when we don't.
803
run_dump_test(sbox, "mergeinfo-contains-r0.dump",
804
bypass_prop_validation=True)
806
#----------------------------------------------------------------------
810
def load_mergeinfo_contains_r0(sbox):
811
"load: mergeinfo that contains r0"
812
run_load_test(sbox, "mergeinfo-contains-r0.dump",
813
expected_dumpfile_name="mergeinfo-contains-r0.expected.dump")
772
815
#----------------------------------------------------------------------
774
817
# Regression test for issue 4551 "svnrdump load commits wrong properties,
870
913
actual = map(str.strip, out)
871
914
svntest.verify.compare_and_display_lines(None, 'PROPS', expected, actual)
916
# Regression test for issue #4552 "svnrdump writes duplicate headers for a
917
# replace-with-copy". 'svnrdump dump' wrote the Node-path and Node-kind
918
# headers twice for the 'delete' record of a replace-with-copy.
920
def dump_replace_with_copy(sbox):
921
"dump replace with copy"
924
# Copy file/dir, replacing something
925
sbox.simple_rm('A/D/gamma', 'A/C')
926
sbox.simple_copy('A/mu@1', 'A/D/gamma')
927
sbox.simple_copy('A/B@1', 'A/C')
930
# Dump with 'svnrdump'
931
dumpfile = svntest.actions.run_and_verify_svnrdump(
932
None, svntest.verify.AnyOutput, [], 0,
933
'dump', '--quiet', '--incremental', '-r2',
936
# Check the 'delete' record headers: expect this parse to fail if headers
938
svntest.verify.DumpParser(dumpfile).parse()
873
940
# Regression test for issue 4551 "svnrdump load commits wrong properties,
874
941
# or fails, on a non-deltas dumpfile". In this test, a node's props are
875
942
# modified, and the failure mode is that RA-serf would end up deleting
970
1037
only_trunk_range_dump,
971
1038
only_trunk_A_range_dump,
1039
load_prop_change_in_non_deltas_dump,
1040
dump_mergeinfo_contains_r0,
1041
load_mergeinfo_contains_r0,
972
1042
load_non_deltas_copy_with_props,
973
1043
load_non_deltas_replace_copy_with_props,
1044
dump_replace_with_copy,
974
1045
load_non_deltas_with_props,