3 # svnrdump_tests.py: Tests svnrdump's remote repository dumping capabilities.
5 # Subversion is a tool for revision control.
6 # See http://subversion.apache.org for more information.
8 # ====================================================================
9 # Licensed to the Apache Software Foundation (ASF) under one
10 # or more contributor license agreements. See the NOTICE file
11 # distributed with this work for additional information
12 # regarding copyright ownership. The ASF licenses this file
13 # to you under the Apache License, Version 2.0 (the
14 # "License"); you may not use this file except in compliance
15 # with the License. You may obtain a copy of the License at
17 # http://www.apache.org/licenses/LICENSE-2.0
19 # Unless required by applicable law or agreed to in writing,
20 # software distributed under the License is distributed on an
21 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
22 # KIND, either express or implied. See the License for the
23 # specific language governing permissions and limitations
25 ######################################################################
32 from svntest
.verify
import SVNUnexpectedStdout
, SVNUnexpectedStderr
33 from svntest
.verify
import SVNExpectedStderr
34 from svntest
.main
import write_restrictive_svnserve_conf
35 from svntest
.main
import server_has_partial_replay
38 Skip
= svntest
.testcase
.Skip
39 SkipUnless
= svntest
.testcase
.SkipUnless
40 XFail
= svntest
.testcase
.XFail
41 Item
= svntest
.wc
.StateItem
42 Wimp
= svntest
.testcase
.Wimp
44 ## Mismatched headers during dumping operation
45 # Text-copy-source-* and *-sha1 headers are not provided by the RA
46 # layer. `svnadmin dump` is able to provide them because it works on
47 # the FS layer. Also, svnrdump attaches "Prop-delta: true" with
48 # everything whether it's really a delta or a new prop (delta from
49 # /dev/null). This is really harmless, but `svnadmin dump` contains
50 # the logic for differentiating between these two cases.
52 mismatched_headers_re
= \
53 "Prop-delta: |Text-content-sha1: |Text-copy-source-md5: |" \
54 "Text-copy-source-sha1: |Text-delta-base-sha1: .*"
56 ######################################################################
59 def build_repos(sbox
):
60 """Build an empty sandbox repository"""
62 # Cleanup after the last run by removing any left-over repository.
63 svntest
.main
.safe_rmtree(sbox
.repo_dir
)
65 # Create an empty repository.
66 svntest
.main
.create_repos(sbox
.repo_dir
)
68 def run_dump_test(sbox
, dumpfile_name
, expected_dumpfile_name
= None,
70 """Load a dumpfile using 'svnadmin load', dump it with 'svnrdump
71 dump' and check that the same dumpfile is produced or that
72 expected_dumpfile_name is produced if provided. Additionally, the
73 subdir argument appends itself to the URL"""
75 # Create an empty sanbox repository
78 # This directory contains all the dump files
79 svnrdump_tests_dir
= os
.path
.join(os
.path
.dirname(sys
.argv
[0]),
80 'svnrdump_tests_data')
82 # Load the specified dump file into the sbox repository using
84 svnadmin_dumpfile
= open(os
.path
.join(svnrdump_tests_dir
,
88 svntest
.actions
.run_and_verify_load(sbox
.repo_dir
, svnadmin_dumpfile
)
90 repo_url
= sbox
.repo_url
92 repo_url
= repo_url
+ subdir
94 # Create a dump file using svnrdump
96 svntest
.actions
.run_and_verify_svnrdump(None, svntest
.verify
.AnyOutput
,
100 if expected_dumpfile_name
:
101 svnadmin_dumpfile
= open(os
.path
.join(svnrdump_tests_dir
,
102 expected_dumpfile_name
),
105 # Compare the output from stdout
106 svntest
.verify
.compare_and_display_lines(
107 "Dump files", "DUMP", svnadmin_dumpfile
, svnrdump_dumpfile
,
108 None, mismatched_headers_re
)
110 def run_load_test(sbox
, dumpfile_name
, expected_dumpfile_name
= None):
111 """Load a dumpfile using 'svnrdump load', dump it with 'svnadmin
112 dump' and check that the same dumpfile is produced"""
114 # Create an empty sanbox repository
117 # Create the revprop-change hook for this test
118 svntest
.actions
.enable_revprop_changes(sbox
.repo_dir
)
120 # This directory contains all the dump files
121 svnrdump_tests_dir
= os
.path
.join(os
.path
.dirname(sys
.argv
[0]),
122 'svnrdump_tests_data')
124 # Load the specified dump file into the sbox repository using
126 svnrdump_dumpfile
= open(os
.path
.join(svnrdump_tests_dir
,
130 # Set the UUID of the sbox repository to the UUID specified in the
131 # dumpfile ### RA layer doesn't have a set_uuid functionality
132 uuid
= svnrdump_dumpfile
[2].split(' ')[1][:-1]
133 svntest
.actions
.run_and_verify_svnadmin2("Setting UUID", None, None, 0,
134 'setuuid', sbox
.repo_dir
,
137 svntest
.actions
.run_and_verify_svnrdump(svnrdump_dumpfile
,
138 svntest
.verify
.AnyOutput
,
142 # Create a dump file using svnadmin dump
143 svnadmin_dumpfile
= svntest
.actions
.run_and_verify_dump(sbox
.repo_dir
, True)
145 if expected_dumpfile_name
:
146 svnrdump_dumpfile
= open(os
.path
.join(svnrdump_tests_dir
,
147 expected_dumpfile_name
),
150 # Compare the output from stdout
151 svntest
.verify
.compare_and_display_lines(
152 "Dump files", "DUMP", svnrdump_dumpfile
, svnadmin_dumpfile
)
154 ######################################################################
157 def basic_dump(sbox
):
158 "dump: standard sbox repos"
159 sbox
.build(read_only
= True, create_wc
= False)
162 svntest
.actions
.run_and_verify_svnrdump(None, svntest
.verify
.AnyOutput
,
166 if not out
[0].startswith('SVN-fs-dump-format-version:'):
167 raise svntest
.Failure('No valid output')
169 def revision_0_dump(sbox
):
170 "dump: revision zero"
171 run_dump_test(sbox
, "revision-0.dump")
173 def revision_0_load(sbox
):
174 "load: revision zero"
175 run_load_test(sbox
, "revision-0.dump")
177 # skeleton.dump repository layout
179 # Projects/ (Added r1)
181 # Project-X (Added r3)
182 # Project-Y (Added r4)
183 # Project-Z (Added r5)
187 def skeleton_dump(sbox
):
188 "dump: skeleton repository"
189 run_dump_test(sbox
, "skeleton.dump")
191 def skeleton_load(sbox
):
192 "load: skeleton repository"
193 run_load_test(sbox
, "skeleton.dump")
195 def copy_and_modify_dump(sbox
):
196 "dump: copy and modify"
197 run_dump_test(sbox
, "copy-and-modify.dump")
199 def copy_and_modify_load(sbox
):
200 "load: copy and modify"
201 run_load_test(sbox
, "copy-and-modify.dump")
203 def no_author_dump(sbox
):
204 "dump: copy revs with no svn:author revprops"
205 run_dump_test(sbox
, "no-author.dump")
207 def no_author_load(sbox
):
208 "load: copy revs with no svn:author revprops"
209 run_load_test(sbox
, "no-author.dump")
211 def copy_from_previous_version_and_modify_dump(sbox
):
212 "dump: copy from previous version and modify"
213 run_dump_test(sbox
, "copy-from-previous-version-and-modify.dump")
215 def copy_from_previous_version_and_modify_load(sbox
):
216 "load: copy from previous version and modify"
217 run_load_test(sbox
, "copy-from-previous-version-and-modify.dump")
219 def modified_in_place_dump(sbox
):
220 "dump: modified in place"
221 run_dump_test(sbox
, "modified-in-place.dump")
223 def modified_in_place_load(sbox
):
224 "load: modified in place"
225 run_load_test(sbox
, "modified-in-place.dump")
227 def move_and_modify_in_the_same_revision_dump(sbox
):
228 "dump: move parent & modify child file in same rev"
229 run_dump_test(sbox
, "move-and-modify.dump")
231 def move_and_modify_in_the_same_revision_load(sbox
):
232 "load: move parent & modify child file in same rev"
233 run_load_test(sbox
, "move-and-modify.dump")
235 def tag_empty_trunk_dump(sbox
):
236 "dump: tag empty trunk"
237 run_dump_test(sbox
, "tag-empty-trunk.dump")
239 def tag_empty_trunk_load(sbox
):
240 "load: tag empty trunk"
241 run_load_test(sbox
, "tag-empty-trunk.dump")
243 def tag_trunk_with_file_dump(sbox
):
244 "dump: tag trunk containing a file"
245 run_dump_test(sbox
, "tag-trunk-with-file.dump")
247 def tag_trunk_with_file_load(sbox
):
248 "load: tag trunk containing a file"
249 run_load_test(sbox
, "tag-trunk-with-file.dump")
251 def tag_trunk_with_file2_dump(sbox
):
252 "dump: tag trunk containing a file (#2)"
253 run_dump_test(sbox
, "tag-trunk-with-file2.dump")
255 def tag_trunk_with_file2_load(sbox
):
256 "load: tag trunk containing a file (#2)"
257 run_load_test(sbox
, "tag-trunk-with-file2.dump")
259 def dir_prop_change_dump(sbox
):
260 "dump: directory property changes"
261 run_dump_test(sbox
, "dir-prop-change.dump")
263 def dir_prop_change_load(sbox
):
264 "load: directory property changes"
265 run_load_test(sbox
, "dir-prop-change.dump")
267 def copy_parent_modify_prop_dump(sbox
):
268 "dump: copy parent and modify prop"
269 run_dump_test(sbox
, "copy-parent-modify-prop.dump")
271 def copy_parent_modify_prop_load(sbox
):
272 "load: copy parent and modify prop"
273 run_load_test(sbox
, "copy-parent-modify-prop.dump")
275 def copy_revprops_dump(sbox
):
276 "dump: copy revprops other than svn:*"
277 run_dump_test(sbox
, "revprops.dump")
279 def copy_revprops_load(sbox
):
280 "load: copy revprops other than svn:*"
281 run_load_test(sbox
, "revprops.dump")
283 def only_trunk_dump(sbox
):
285 run_dump_test(sbox
, "trunk-only.dump", subdir
="/trunk",
286 expected_dumpfile_name
="trunk-only.expected.dump")
288 def only_trunk_A_with_changes_dump(sbox
):
289 "dump: subdirectory with changes on root"
290 run_dump_test(sbox
, "trunk-A-changes.dump", subdir
="/trunk/A",
291 expected_dumpfile_name
="trunk-A-changes.expected.dump")
293 def url_encoding_dump(sbox
):
294 "dump: url encoding issues"
295 run_dump_test(sbox
, "url-encoding-bug.dump")
297 def url_encoding_load(sbox
):
298 "load: url encoding issues"
299 run_load_test(sbox
, "url-encoding-bug.dump")
301 def copy_bad_line_endings_dump(sbox
):
302 "dump: inconsistent line endings in svn:props"
303 run_dump_test(sbox
, "copy-bad-line-endings.dump",
304 expected_dumpfile_name
="copy-bad-line-endings.expected.dump")
306 def commit_a_copy_of_root_dump(sbox
):
307 "dump: commit a copy of root"
308 run_dump_test(sbox
, "repo-with-copy-of-root-dir.dump")
310 def commit_a_copy_of_root_load(sbox
):
311 "load: commit a copy of root"
312 run_load_test(sbox
, "repo-with-copy-of-root-dir.dump")
314 def descend_into_replace_dump(sbox
):
315 "dump: descending into replaced dir looks in src"
316 run_dump_test(sbox
, "descend-into-replace.dump", subdir
='/trunk/H',
317 expected_dumpfile_name
= "descend-into-replace.expected.dump")
319 ########################################################################
323 # list all tests here, starting with None:
330 copy_and_modify_dump
,
331 copy_and_modify_load
,
332 copy_from_previous_version_and_modify_dump
,
333 copy_from_previous_version_and_modify_load
,
334 modified_in_place_dump
,
335 modified_in_place_load
,
336 tag_empty_trunk_dump
,
337 tag_empty_trunk_load
,
338 tag_trunk_with_file_dump
,
339 tag_trunk_with_file_load
,
340 tag_trunk_with_file2_dump
,
341 tag_trunk_with_file2_load
,
342 dir_prop_change_dump
,
343 Wimp("TODO", dir_prop_change_load
, svntest
.main
.is_ra_type_dav
),
344 copy_parent_modify_prop_dump
,
345 copy_parent_modify_prop_load
,
351 only_trunk_A_with_changes_dump
,
354 move_and_modify_in_the_same_revision_dump
,
355 move_and_modify_in_the_same_revision_load
,
356 copy_bad_line_endings_dump
,
357 commit_a_copy_of_root_dump
,
358 commit_a_copy_of_root_load
,
359 descend_into_replace_dump
,
362 if __name__
== '__main__':
363 svntest
.main
.run_tests(test_list
)