1#!/usr/bin/env python 2# 3# svndumpfilter_tests.py: testing the 'svndumpfilter' tool. 4# 5# Subversion is a tool for revision control. 6# See http://subversion.apache.org for more information. 7# 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 16# 17# http://www.apache.org/licenses/LICENSE-2.0 18# 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 24# under the License. 25###################################################################### 26 27# General modules 28import os 29import sys 30import tempfile 31 32# Our testing module 33import svntest 34from svntest.verify import SVNExpectedStdout, SVNExpectedStderr 35 36# Get some helper routines 37from svnadmin_tests import load_and_verify_dumpstream, load_dumpstream 38from svntest.main import run_svn, run_svnadmin 39 40# (abbreviation) 41Skip = svntest.testcase.Skip_deco 42SkipUnless = svntest.testcase.SkipUnless_deco 43XFail = svntest.testcase.XFail_deco 44Issues = svntest.testcase.Issues_deco 45Issue = svntest.testcase.Issue_deco 46Wimp = svntest.testcase.Wimp_deco 47Item = svntest.wc.StateItem 48 49 50###################################################################### 51# Helper routines 52 53 54def filter_and_return_output(dump, bufsize=0, *varargs): 55 """Filter the array of lines passed in 'dump' and return the output 56 and errput""" 57 58 if isinstance(dump, str): 59 dump = [ dump ] 60 61 # Does the caller want the stderr? 62 if '-q' in varargs or '--quiet' in varargs: 63 expected_errput = None # Stderr with -q or --quiet is a real error! 64 else: 65 expected_errput = svntest.verify.AnyOutput 66 ## TODO: Should we handle exit_code? 67 exit_code, output, errput = svntest.main.run_command_stdin( 68 svntest.main.svndumpfilter_binary, expected_errput, bufsize, True, 69 dump, *varargs) 70 71 # Since we call svntest.main.run_command_stdin() in binary mode, 72 # normalize the stderr line endings on Windows ourselves. 73 if sys.platform == 'win32': 74 errput = [x.replace('\r\n', '\n') for x in errput] 75 76 return output, errput 77 78 79###################################################################### 80# Tests 81 82@Issue(2982) 83def reflect_dropped_renumbered_revs(sbox): 84 "reflect dropped renumbered revs in svn:mergeinfo" 85 86 ## See https://issues.apache.org/jira/browse/SVN-2982. ## 87 88 # Test svndumpfilter with include option 89 sbox.build(empty=True) 90 dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 91 'svndumpfilter_tests_data', 92 'with_merges.dump') 93 dumpfile = svntest.actions.load_dumpfile(dumpfile_location) 94 95 filtered_out, filtered_err = filter_and_return_output( 96 dumpfile, 0, "include", 97 "trunk", "branch1", 98 "--skip-missing-merge-sources", 99 "--drop-empty-revs", 100 "--renumber-revs", "--quiet") 101 102 load_dumpstream(sbox, filtered_out, "--ignore-uuid") 103 104 # Verify the svn:mergeinfo properties 105 url = sbox.repo_url 106 expected_output = svntest.verify.UnorderedOutput([ 107 url + "/trunk - /branch1:4-5\n", 108 ]) 109 svntest.actions.run_and_verify_svn(expected_output, [], 110 'propget', 'svn:mergeinfo', '-R', 111 sbox.repo_url) 112 113 114 # Test svndumpfilter with exclude option 115 sbox.build(empty=True) 116 filtered_out, filtered_err = filter_and_return_output( 117 dumpfile, 0, "exclude", "branch1", 118 "--skip-missing-merge-sources", 119 "--drop-empty-revs", 120 "--renumber-revs", "--quiet") 121 122 load_dumpstream(sbox, filtered_out, "--ignore-uuid") 123 124 # Verify the svn:mergeinfo properties 125 expected_output = svntest.verify.UnorderedOutput([ 126 url + "/trunk - \n", 127 ]) 128 svntest.actions.run_and_verify_svn(expected_output, [], 129 'propget', 'svn:mergeinfo', '-R', 130 sbox.repo_url) 131 132@Issue(3181) 133def svndumpfilter_loses_mergeinfo(sbox): 134 "svndumpfilter loses mergeinfo" 135 #svndumpfilter loses mergeinfo if invoked without --renumber-revs 136 137 ## See https://issues.apache.org/jira/browse/SVN-3181. ## 138 139 sbox.build(empty=True) 140 dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 141 'svndumpfilter_tests_data', 142 'with_merges.dump') 143 dumpfile = svntest.actions.load_dumpfile(dumpfile_location) 144 145 filtered_out, filtered_err = filter_and_return_output(dumpfile, 0, "include", 146 "trunk", "branch1", 147 "--quiet") 148 load_dumpstream(sbox, filtered_out) 149 150 # Verify the svn:mergeinfo properties 151 url = sbox.repo_url 152 expected_output = svntest.verify.UnorderedOutput([ 153 url + "/trunk - /branch1:4-8\n", 154 ]) 155 svntest.actions.run_and_verify_svn(expected_output, [], 156 'propget', 'svn:mergeinfo', '-R', 157 sbox.repo_url) 158 159 160def _simple_dumpfilter_test(sbox, dumpfile, *dumpargs): 161 """Run svndumpfilter with arguments DUMPARGS, taking input from DUMPFILE. 162 Check that the output consists of the standard Greek tree excluding 163 all paths that start with 'A/B/E', 'A/D/G' or 'A/D/H'.""" 164 wc_dir = sbox.wc_dir 165 166 filtered_output, filtered_err = filter_and_return_output(dumpfile, 0, 167 '--quiet', 168 *dumpargs) 169 170 # Setup our expectations 171 load_dumpstream(sbox, filtered_output, '--ignore-uuid') 172 expected_disk = svntest.main.greek_state.copy() 173 expected_disk.remove('A/B/E/alpha') 174 expected_disk.remove('A/B/E/beta') 175 expected_disk.remove('A/B/E') 176 expected_disk.remove('A/D/H/chi') 177 expected_disk.remove('A/D/H/psi') 178 expected_disk.remove('A/D/H/omega') 179 expected_disk.remove('A/D/H') 180 expected_disk.remove('A/D/G/pi') 181 expected_disk.remove('A/D/G/rho') 182 expected_disk.remove('A/D/G/tau') 183 expected_disk.remove('A/D/G') 184 185 expected_output = svntest.wc.State(wc_dir, { 186 'A' : Item(status='A '), 187 'A/B' : Item(status='A '), 188 'A/B/lambda' : Item(status='A '), 189 'A/B/F' : Item(status='A '), 190 'A/mu' : Item(status='A '), 191 'A/C' : Item(status='A '), 192 'A/D' : Item(status='A '), 193 'A/D/gamma' : Item(status='A '), 194 'iota' : Item(status='A '), 195 }) 196 197 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 198 expected_status.remove('A/B/E/alpha') 199 expected_status.remove('A/B/E/beta') 200 expected_status.remove('A/B/E') 201 expected_status.remove('A/D/H/chi') 202 expected_status.remove('A/D/H/psi') 203 expected_status.remove('A/D/H/omega') 204 expected_status.remove('A/D/H') 205 expected_status.remove('A/D/G/pi') 206 expected_status.remove('A/D/G/rho') 207 expected_status.remove('A/D/G/tau') 208 expected_status.remove('A/D/G') 209 210 # Check that our paths really were excluded 211 svntest.actions.run_and_verify_update(wc_dir, 212 expected_output, 213 expected_disk, 214 expected_status) 215 216 217@Issue(2697) 218def dumpfilter_with_targets(sbox): 219 "svndumpfilter --targets blah" 220 ## See https://issues.apache.org/jira/browse/SVN-2697. ## 221 222 sbox.build(empty=True) 223 224 dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 225 'svndumpfilter_tests_data', 226 'greek_tree.dump') 227 dumpfile = svntest.actions.load_dumpfile(dumpfile_location) 228 229 (fd, targets_file) = tempfile.mkstemp(dir=svntest.main.temp_dir) 230 try: 231 targets = open(targets_file, 'w') 232 targets.write('/A/D/H\n') 233 targets.write('/A/D/G\n') 234 targets.close() 235 _simple_dumpfilter_test(sbox, dumpfile, 236 'exclude', '/A/B/E', '--targets', targets_file) 237 finally: 238 os.close(fd) 239 os.remove(targets_file) 240 241 242def dumpfilter_with_patterns(sbox): 243 "svndumpfilter --pattern PATH_PREFIX" 244 245 sbox.build(empty=True) 246 247 dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 248 'svndumpfilter_tests_data', 249 'greek_tree.dump') 250 dumpfile = svntest.actions.load_dumpfile(dumpfile_location) 251 _simple_dumpfilter_test(sbox, dumpfile, 252 'exclude', '--pattern', '/A/D/[GH]*', '/A/[B]/E*') 253 254#---------------------------------------------------------------------- 255# More testing for issue #3020 'Reflect dropped/renumbered revisions in 256# svn:mergeinfo data during svnadmin load' 257# 258# Specifically, test that svndumpfilter, when used with the 259# --skip-missing-merge-sources option, removes mergeinfo that refers to 260# revisions that are older than the oldest revision in the dump stream. 261@Issue(3020) 262def filter_mergeinfo_revs_outside_of_dump_stream(sbox): 263 "filter mergeinfo revs outside of dump stream" 264 265 sbox.build(empty=True) 266 267 # Load a partial dump into an existing repository. 268 # 269 # Picture == 1k words: 270 # 271 # The dump file we filter in this test, 'mergeinfo_included_partial.dump', is 272 # a dump of r6:HEAD of the following repos: 273 # 274 # __________________________________________ 275 # | | 276 # | ____________________________|_____ 277 # | | | | 278 # trunk---r2---r3-----r5---r6-------r8---r9---------------> | | 279 # r1 | | | | | | 280 # initial | | | |______ | | 281 # import copy | copy | merge merge 282 # | | | merge (r5) (r8) 283 # | | | (r9) | | 284 # | | | | | | 285 # | | V V | | 286 # | | branches/B2-------r11---r12----> | | 287 # | | r7 |____| | | 288 # | | | | | 289 # | merge |___ | | 290 # | (r6) | | | 291 # | |_________________ | | | 292 # | | merge | | 293 # | | (r11-12) | | 294 # | | | | | 295 # V V V | | 296 # branches/B1-------------------r10--------r13--> | | 297 # r4 | | 298 # | V V 299 # branches/B1/B/E------------------------------r14---r15-> 300 # 301 # 302 # The mergeinfo on the complete repos would look like this: 303 # 304 # Properties on 'branches/B1': 305 # svn:mergeinfo 306 # /branches/B2:11-12 307 # /trunk:6,9 308 # Properties on 'branches/B1/B/E': 309 # svn:mergeinfo 310 # /branches/B2/B/E:11-12 311 # /trunk/B/E:5-6,8-9 312 # Properties on 'branches/B2': 313 # svn:mergeinfo 314 # /trunk:9 315 # 316 # We will run the partial dump through svndumpfilter using the the 317 # --skip-missing-merge-soruces which should strip out any revisions < 6. 318 # Then we'll load the filtered result into an empty repository. This 319 # should offset the incoming mergeinfo by -5. In addition, any mergeinfo 320 # referring to the initial revision in the dump file (r6) should be 321 # removed because the change it refers to (r5:6) is not wholly within the 322 # dumpfile. The resulting mergeinfo should look like this: 323 # 324 # Properties on 'branches/B1': 325 # svn:mergeinfo 326 # /branches/B2:6-7 327 # /trunk:4 328 # Properties on 'branches/B1/B/E': 329 # svn:mergeinfo 330 # /branches/B2/B/E:6-7 331 # /trunk/B/E:3-4 332 # Properties on 'branches/B2': 333 # svn:mergeinfo 334 # /trunk:4 335 partial_dump = os.path.join(os.path.dirname(sys.argv[0]), 336 'svndumpfilter_tests_data', 337 'mergeinfo_included_partial.dump') 338 partial_dump_contents = svntest.actions.load_dumpfile(partial_dump) 339 filtered_dumpfile2, filtered_out = filter_and_return_output( 340 partial_dump_contents, 341 8192, # Set a sufficiently large bufsize to avoid a deadlock 342 "include", "trunk", "branches", 343 "--skip-missing-merge-sources", 344 "--quiet") 345 load_dumpstream(sbox, filtered_dumpfile2, '--ignore-uuid') 346 # Check the resulting mergeinfo. 347 url = sbox.repo_url + "/branches" 348 expected_output = svntest.verify.UnorderedOutput([ 349 url + "/B1 - /branches/B2:6-7\n", 350 "/trunk:4\n", 351 url + "/B2 - /trunk:4\n", 352 url + "/B1/B/E - /branches/B2/B/E:6-7\n", 353 "/trunk/B/E:3-4\n"]) 354 svntest.actions.run_and_verify_svn(expected_output, [], 355 'propget', 'svn:mergeinfo', '-R', 356 sbox.repo_url) 357 358 # Blow away the current repos, create an empty one in its place, and 359 # then load this skeleton repos into the empty target: 360 # 361 # Projects/ (Added r1) 362 # README (Added r2) 363 # Project-X (Added r3) 364 # Project-Y (Added r4) 365 # Project-Z (Added r5) 366 # docs/ (Added r6) 367 # README (Added r6). 368 sbox.build(empty=True) 369 skeleton_location = os.path.join(os.path.dirname(sys.argv[0]), 370 'svnadmin_tests_data', 371 'skeleton_repos.dump') 372 skeleton_dumpfile = svntest.actions.load_dumpfile(skeleton_location) 373 load_dumpstream(sbox, skeleton_dumpfile, '--ignore-uuid') 374 partial_dump2 = os.path.join(os.path.dirname(sys.argv[0]), 375 'svndumpfilter_tests_data', 376 'mergeinfo_included_partial.dump') 377 partial_dump_contents2 = svntest.actions.load_dumpfile(partial_dump2) 378 # Now use the partial dump file we used above, but this time exclude 379 # the B2 branch. Load the filtered dump into the /Projects/Project-X 380 # subtree of the skeleton repos. 381 filtered_dumpfile2, filtered_err = filter_and_return_output( 382 partial_dump_contents2, 383 8192, # Set a sufficiently large bufsize to avoid a deadlock 384 "exclude", "branches/B2", 385 "--skip-missing-merge-sources", 386 "--drop-empty-revs", 387 "--renumber-revs") 388 389 # Starting with the same expectation we had when loading into an empty 390 # repository, adjust each revision by +6 to account for the six revision 391 # already present in the target repos, that gives: 392 # 393 # Properties on 'branches/B1': 394 # svn:mergeinfo 395 # /branches/B2:12-13 396 # /trunk:10 397 # Properties on 'branches/B1/B/E': 398 # svn:mergeinfo 399 # /branches/B2/B/E:12-13 400 # /trunk/B/E:9-10 401 # Properties on 'branches/B2': 402 # svn:mergeinfo 403 # /trunk:10 404 # 405 # ...But /branches/B2 has been filtered out, so all references to 406 # that branch should be gone, leaving: 407 # 408 # Properties on 'branches/B1': 409 # svn:mergeinfo 410 # /trunk:10 411 # Properties on 'branches/B1/B/E': 412 # svn:mergeinfo 413 # /trunk/B/E:9-10 414 # 415 # ...But wait, there's more! Because we use the '--drop-empty-revs' 416 # option, when filtering out 'branches/B2' all the revisions that effect 417 # only that branch should be dropped (i.e. original revs r7, r11, and r12). 418 # In and of itself that has no effect, but we also specifiy the 419 # '--renumber-revs' option, so when r7 is dropped, r8 should map to r7, 420 # r9 to r8, and r10 to r9 (and so on). That should finally leave us with: 421 # 422 # Properties on 'branches/B1': 423 # svn:mergeinfo 424 # /trunk:9 425 # Properties on 'branches/B1/B/E': 426 # svn:mergeinfo 427 # /trunk/B/E:8-9 428 # 429 # This test currently fails with this mergeinfo: 430 # 431 # 432 # 433 # 434 # Check that all the blather above really happens. First does 435 # svndumpfilter report what we expect to stderr? 436 expected_err = [ 437 "Excluding (and dropping empty revisions for) prefixes:\n", 438 " '/branches/B2'\n", 439 "\n", 440 "Revision 6 committed as 6.\n", 441 "Revision 7 skipped.\n", # <-- DROP! 442 "Revision 8 committed as 7.\n", 443 "Revision 9 committed as 8.\n", 444 "Revision 10 committed as 9.\n", 445 "Revision 11 skipped.\n", # <-- DROP! 446 "Revision 12 skipped.\n", # <-- DROP! 447 "Revision 13 committed as 10.\n", 448 "Revision 14 committed as 11.\n", 449 "Revision 15 committed as 12.\n", 450 "\n", 451 "Dropped 3 revisions.\n", 452 "\n", 453 "Revisions renumbered as follows:\n", 454 " 15 => 12\n", 455 " 14 => 11\n", 456 " 13 => 10\n", 457 " 12 => (dropped)\n", # <-- DROP! 458 " 11 => (dropped)\n", # <-- DROP! 459 " 10 => 9\n", 460 " 9 => 8\n", 461 " 8 => 7\n", 462 " 7 => (dropped)\n", # <-- DROP! 463 " 6 => 6\n", 464 "\n", 465 "Dropped 2 nodes:\n", 466 " '/branches/B2'\n", 467 " '/branches/B2/D/H/chi'\n", 468 "\n"] 469 svntest.verify.verify_outputs( 470 "Actual svndumpfilter stderr does not agree with expected stderr", 471 None, filtered_err, None, expected_err) 472 473 # Now actually load the filtered dump into the skeleton repository 474 # and then check the resulting mergeinfo. 475 load_dumpstream(sbox, filtered_dumpfile2, 476 '--parent-dir', '/Projects/Project-X', '--ignore-uuid') 477 478 url = sbox.repo_url + "/Projects/Project-X/branches" 479 expected_output = svntest.verify.UnorderedOutput([ 480 url + "/B1 - /Projects/Project-X/trunk:9\n", 481 url + "/B1/B/E - /Projects/Project-X/trunk/B/E:8-9\n"]) 482 svntest.actions.run_and_verify_svn(expected_output, [], 483 'propget', 'svn:mergeinfo', '-R', 484 sbox.repo_url) 485 486#---------------------------------------------------------------------- 487# More testing for issue #3020 'Reflect dropped/renumbered revisions in 488# svn:mergeinfo data during svnadmin load' 489# 490# Using svndumpfilter with the --drop-empty-revs option, but without the 491# --renumber-revs option, can create a dump with non-contiguous revisions. 492# Such dumps should not interfere with the correct remapping of mergeinfo 493# source revisions. 494@Issue(3020) 495def dropped_but_not_renumbered_empty_revs(sbox): 496 "mergeinfo maps correctly when dropping revs" 497 498 sbox.build(empty=True) 499 500 # The dump file mergeinfo_included_full.dump represents this repository: 501 # 502 # 503 # __________________________________________ 504 # | | 505 # | ____________________________|_____ 506 # | | | | 507 # trunk---r2---r3-----r5---r6-------r8---r9---------------> | | 508 # r1 | | | | | | 509 # initial | | | |______ | | 510 # import copy | copy | merge merge 511 # | | | merge (r5) (r8) 512 # | | | (r9) | | 513 # | | | | | | 514 # | | V V | | 515 # | | branches/B2-------r11---r12----> | | 516 # | | r7 |____| | | 517 # | | | | | 518 # | merge |___ | | 519 # | (r6) | | | 520 # | |_________________ | | | 521 # | | merge | | 522 # | | (r11-12) | | 523 # | | | | | 524 # V V V | | 525 # branches/B1-------------------r10--------r13--> | | 526 # r4 | | 527 # | V V 528 # branches/B1/B/E------------------------------r14---r15-> 529 # 530 # 531 # The mergeinfo on mergeinfo_included_full.dump is: 532 # 533 # Properties on 'branches/B1': 534 # svn:mergeinfo 535 # /branches/B2:11-12 536 # /trunk:6,9 537 # Properties on 'branches/B1/B/E': 538 # svn:mergeinfo 539 # /branches/B2/B/E:11-12 540 # /trunk/B/E:5-6,8-9 541 # Properties on 'branches/B2': 542 # svn:mergeinfo 543 # /trunk:9 544 # 545 # Use svndumpfilter to filter mergeinfo_included_full.dump, excluding 546 # branches/B2, while dropping, but not renumbering, empty revisions. 547 # 548 # Load the filtered dump into an empty repository. Since we are excluding 549 # /branches/B2 and dropping empty revs, revisions 7, 11, and 12 won't be 550 # included in the filtered dump. 551 full_dump = os.path.join(os.path.dirname(sys.argv[0]), 552 'svnadmin_tests_data', 553 'mergeinfo_included_full.dump') 554 full_dump_contents = svntest.actions.load_dumpfile(full_dump) 555 filtered_dumpfile, filtered_out = filter_and_return_output( 556 full_dump_contents, 557 16384, # Set a sufficiently large bufsize to avoid a deadlock 558 "exclude", "branches/B2", 559 "--skip-missing-merge-sources", "--drop-empty-revs") 560 561 # Now load the filtered dump into an empty repository. 562 load_dumpstream(sbox, filtered_dumpfile, '--ignore-uuid') 563 564 # The mergeinfo in the newly loaded repos should have no references to the 565 # dropped branch and the remaining merge source revs should be remapped to 566 # reflect the fact that the loaded repository no longer has any empty 567 # revisions: 568 # 569 # Properties on 'branches/B1': 570 # svn:mergeinfo 571 # /trunk:6,8 572 # ^ 573 # With r7 dropped, r9 in the incoming 574 # dump becomes r8 in the loaded repos. 575 # 576 # Properties on 'branches/B1/B/E': 577 # svn:mergeinfo 578 # /trunk/B/E:5-8 579 # ^ 580 # With r7 dropped, r8 and r9 in the incoming 581 # dump becomes r7 and r8 in the loaded repos. 582 583 # Check the resulting mergeinfo. 584 url = sbox.repo_url + "/branches" 585 expected_output = svntest.verify.UnorderedOutput([ 586 url + "/B1 - /trunk:6,8\n", 587 url + "/B1/B/E - /trunk/B/E:5-8\n"]) 588 svntest.actions.run_and_verify_svn(expected_output, [], 589 'propget', 'svn:mergeinfo', '-R', 590 sbox.repo_url) 591 592#---------------------------------------------------------------------- 593def match_empty_prefix(sbox): 594 "svndumpfilter with an empty prefix" 595 596 dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 597 'svndumpfilter_tests_data', 598 'greek_tree.dump') 599 dumpfile = svntest.actions.load_dumpfile(dumpfile_location) 600 601 def test(sbox, dumpfile, *dumpargs): 602 """Run svndumpfilter with DUMPFILE as the input lines, load 603 the result and check it matches EXPECTED_DISK, EXPECTED_OUTPUT, 604 EXPECTED_STATUS.""" 605 606 # Filter the Greek tree dump 607 filtered_output, filtered_err = filter_and_return_output(dumpfile, 0, 608 '--quiet', 609 *dumpargs) 610 if filtered_err: 611 raise verify.UnexpectedStderr(filtered_err) 612 613 # Load the filtered dump into a repo and check the result 614 sbox.build(empty=True) 615 load_dumpstream(sbox, filtered_output, '--ignore-uuid') 616 svntest.actions.run_and_verify_update(sbox.wc_dir, 617 expected_output, 618 expected_disk, 619 expected_status) 620 621 # Test excluding everything 622 expected_disk = svntest.wc.State(sbox.wc_dir, {}) 623 expected_output = svntest.wc.State(sbox.wc_dir, {}) 624 expected_status = svntest.wc.State(sbox.wc_dir, { 625 '': Item(status=' ', wc_rev=1) }) 626 627 test(sbox, dumpfile, 'exclude', '') 628 629 # Test including everything 630 expected_disk = svntest.main.greek_state.copy() 631 expected_output = svntest.main.greek_state.copy().tweak(status='A ') 632 expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1) 633 634 test(sbox, dumpfile, 'include', '', '/A/D/G') 635 636 # Note: We also ought to test the '--pattern' option, including or 637 # excluding a pattern of '*'. However, passing a wildcard parameter 638 # is troublesome on Windows: it may be expanded, depending on whether 639 # the svndumpfilter executable was linked with 'setargv.obj', and there 640 # doesn't seem to be a consistent way to quote such an argument to 641 # prevent expansion. 642 643@Issue(2760) 644def accepts_deltas(sbox): 645 "accepts deltas in the input" 646 # Accept format v3 (as created by 'svnadmin --deltas' or svnrdump). 647 648 sbox.build(empty=True) 649 dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 650 'svndumpfilter_tests_data', 651 'simple_v3.dump') 652 dump_in = svntest.actions.load_dumpfile(dumpfile_location) 653 654 dump_out, err = filter_and_return_output(dump_in, 0, "include", 655 "trunk", "--quiet") 656 657 expected_revs = [ 658 svntest.wc.State('', { 659 'trunk' : svntest.wc.StateItem(props={'soup': 'No soup for you!'}), 660 'trunk/foo' : svntest.wc.StateItem("This is file 'foo'.\n"), 661 }), 662 svntest.wc.State('', { 663 'trunk' : svntest.wc.StateItem(props={'soup': 'No soup for you!'}), 664 'trunk/foo' : svntest.wc.StateItem("This is file 'foo'.\n"), 665 }), 666 svntest.wc.State('', { 667 'trunk' : svntest.wc.StateItem(props={'story': 'Yada yada yada...'}), 668 'trunk/foo' : svntest.wc.StateItem("This is file 'foo'.\n"), 669 }), 670 ] 671 672 load_and_verify_dumpstream(sbox, [], [], expected_revs, True, dump_out, 673 '--ignore-uuid') 674 675 676 677@Issue(4234) 678def dumpfilter_targets_expect_leading_slash_prefixes(sbox): 679 "dumpfilter targets expect leading '/' in prefixes" 680 ## See https://issues.apache.org/jira/browse/SVN-4234. ## 681 682 sbox.build(empty=True) 683 684 dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 685 'svndumpfilter_tests_data', 686 'greek_tree.dump') 687 dumpfile = svntest.actions.load_dumpfile(dumpfile_location) 688 689 (fd, targets_file) = tempfile.mkstemp(dir=svntest.main.temp_dir) 690 try: 691 targets = open(targets_file, 'w') 692 693 # Removing the leading slash in path prefixes should work. 694 targets.write('A/D/H\n') 695 targets.write('A/D/G\n') 696 targets.close() 697 _simple_dumpfilter_test(sbox, dumpfile, 698 'exclude', '/A/B/E', '--targets', targets_file) 699 finally: 700 os.close(fd) 701 os.remove(targets_file) 702 703@Issue(3681) 704def drop_all_empty_revisions(sbox): 705 "drop all empty revisions except revision 0" 706 707 dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), 708 'svndumpfilter_tests_data', 709 'empty_revisions.dump') 710 dump_contents = svntest.actions.load_dumpfile(dumpfile_location) 711 712 filtered_dumpfile, filtered_err = filter_and_return_output( 713 dump_contents, 714 8192, # Set a sufficiently large bufsize to avoid a deadlock 715 "include", "branch1", 716 "--drop-all-empty-revs") 717 718 expected_err = [ 719 "Including (and dropping empty revisions for) prefixes:\n", 720 " '/branch1'\n", 721 "\n", 722 "Revision 0 committed as 0.\n", 723 "Revision 1 skipped.\n", 724 "Revision 2 committed as 2.\n", 725 "Revision 3 skipped.\n", 726 "\n", 727 "Dropped 2 revisions.\n", 728 "\n"] 729 730 svntest.verify.verify_outputs( 731 "Actual svndumpfilter stderr does not agree with expected stderr", 732 None, filtered_err, None, expected_err) 733 734 # Test with --renumber-revs option. 735 filtered_dumpfile, filtered_err = filter_and_return_output( 736 dump_contents, 737 8192, # Set a sufficiently large bufsize to avoid a deadlock 738 "include", "branch1", 739 "--drop-all-empty-revs", 740 "--renumber-revs") 741 742 expected_err = [ 743 "Including (and dropping empty revisions for) prefixes:\n", 744 " '/branch1'\n", 745 "\n", 746 "Revision 0 committed as 0.\n", 747 "Revision 1 skipped.\n", 748 "Revision 2 committed as 1.\n", 749 "Revision 3 skipped.\n", 750 "\n", 751 "Dropped 2 revisions.\n", 752 "\n", 753 "Revisions renumbered as follows:\n", 754 " 3 => (dropped)\n", 755 " 2 => 1\n", 756 " 1 => (dropped)\n", 757 " 0 => 0\n", 758 "\n"] 759 760 svntest.verify.verify_outputs( 761 "Actual svndumpfilter stderr does not agree with expected stderr", 762 None, filtered_err, None, expected_err) 763 764 765######################################################################## 766# Run the tests 767 768 769# list all tests here, starting with None: 770test_list = [ None, 771 reflect_dropped_renumbered_revs, 772 svndumpfilter_loses_mergeinfo, 773 dumpfilter_with_targets, 774 dumpfilter_with_patterns, 775 filter_mergeinfo_revs_outside_of_dump_stream, 776 dropped_but_not_renumbered_empty_revs, 777 match_empty_prefix, 778 accepts_deltas, 779 dumpfilter_targets_expect_leading_slash_prefixes, 780 drop_all_empty_revisions, 781 ] 782 783if __name__ == '__main__': 784 svntest.main.run_tests(test_list) 785 # NOTREACHED 786 787 788### End of file. 789