1#!/usr/bin/env python 2# 3# svnlook_tests.py: testing the 'svnlook' 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 re, os, logging 29 30logger = logging.getLogger() 31 32# Our testing module 33import svntest 34 35from prop_tests import binary_mime_type_on_text_file_warning 36 37# (abbreviation) 38Skip = svntest.testcase.Skip_deco 39SkipUnless = svntest.testcase.SkipUnless_deco 40XFail = svntest.testcase.XFail_deco 41Issues = svntest.testcase.Issues_deco 42Issue = svntest.testcase.Issue_deco 43Wimp = svntest.testcase.Wimp_deco 44Item = svntest.wc.StateItem 45 46 47#---------------------------------------------------------------------- 48 49# Convenience functions to make writing more tests easier 50 51def run_svnlook(*varargs): 52 """Run svnlook with VARARGS, returns exit code as int; stdout, stderr as 53 list of lines (including line terminators). 54 Raises Failure if any stderr messages. 55 """ 56 exit_code, output, dummy_errput = svntest.main.run_command( 57 svntest.main.svnlook_binary, 0, False, *varargs) 58 59 return output 60 61 62def expect(tag, expected, got): 63 if expected != got: 64 logger.warn("When testing: %s", tag) 65 logger.warn("Expected: %s", expected) 66 logger.warn(" Got: %s", got) 67 raise svntest.Failure 68 69 70# Tests 71 72def test_misc(sbox): 73 "test miscellaneous svnlook features" 74 75 sbox.build() 76 wc_dir = sbox.wc_dir 77 repo_dir = sbox.repo_dir 78 79 # Make a couple of local mods to files 80 mu_path = os.path.join(wc_dir, 'A', 'mu') 81 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho') 82 svntest.main.file_append(mu_path, 'appended mu text') 83 svntest.main.file_append(rho_path, 'new appended text for rho') 84 85 # Created expected output tree for 'svn ci' 86 expected_output = svntest.wc.State(wc_dir, { 87 'A/mu' : Item(verb='Sending'), 88 'A/D/G/rho' : Item(verb='Sending'), 89 }) 90 91 # Create expected status tree; all local revisions should be at 1, 92 # but mu and rho should be at revision 2. 93 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 94 expected_status.tweak('A/mu', 'A/D/G/rho', wc_rev=2) 95 96 svntest.actions.run_and_verify_commit(wc_dir, 97 expected_output, 98 expected_status) 99 100 # give the repo a new UUID 101 uuid = b"01234567-89ab-cdef-89ab-cdef01234567" 102 svntest.main.run_command_stdin(svntest.main.svnadmin_binary, None, 0, True, 103 [b"SVN-fs-dump-format-version: 2\n", 104 b"\n", 105 b"UUID: ", uuid, b"\n", 106 ], 107 'load', '--force-uuid', repo_dir) 108 109 expect('youngest', [ '2\n' ], run_svnlook('youngest', repo_dir)) 110 111 expect('uuid', [ uuid.decode() + '\n' ], run_svnlook('uuid', repo_dir)) 112 113 # it would be nice to test the author too, but the current test framework 114 # does not pull a username when testing over ra_neon or ra_svn, 115 # so the commits have an empty author. 116 117 expect('log', [ 'log msg\n' ], run_svnlook('log', repo_dir)) 118 119 # check if the 'svnlook tree' output can be expanded to 120 # the 'svnlook tree --full-paths' output if demanding the whole repository 121 treelist = run_svnlook('tree', repo_dir) 122 treelistfull = run_svnlook('tree', '--full-paths', repo_dir) 123 124 path = '' 125 treelistexpand = [] 126 for entry in treelist: 127 len1 = len(entry) 128 len2 = len(entry.lstrip()) 129 path = path[0:2*(len1-len2)-1] + entry.strip() + '\n' 130 if path == '/\n': 131 treelistexpand.append(path) 132 else: 133 treelistexpand.append(path[1:]) 134 135 treelistexpand = svntest.verify.UnorderedOutput(treelistexpand) 136 svntest.verify.compare_and_display_lines('Unexpected result from tree', '', 137 treelistexpand, treelistfull) 138 139 # check if the 'svnlook tree' output is the ending of 140 # the 'svnlook tree --full-paths' output if demanding 141 # any part of the repository 142 treelist = run_svnlook('tree', repo_dir, '/A/B') 143 treelistfull = run_svnlook('tree', '--full-paths', repo_dir, '/A/B') 144 145 path = '' 146 treelistexpand = [] 147 for entry in treelist: 148 len1 = len(entry) 149 len2 = len(entry.lstrip()) 150 path = path[0:2*(len1-len2)] + entry.strip() + '\n' 151 treelistexpand.append('/A/' + path) 152 153 treelistexpand = svntest.verify.UnorderedOutput(treelistexpand) 154 svntest.verify.compare_and_display_lines('Unexpected result from tree', '', 155 treelistexpand, treelistfull) 156 157 treelist = run_svnlook('tree', repo_dir, '/') 158 if treelist[0] != '/\n': 159 raise svntest.Failure 160 161 expect('propget svn:log', [ 'log msg' ], 162 run_svnlook('propget', '--revprop', repo_dir, 'svn:log')) 163 164 165 proplist = run_svnlook('proplist', '--revprop', repo_dir) 166 proplist = sorted([prop.strip() for prop in proplist]) 167 168 # We cannot rely on svn:author's presence. ra_svn doesn't set it. 169 if not (proplist == [ 'svn:author', 'svn:date', 'svn:log' ] 170 or proplist == [ 'svn:date', 'svn:log' ]): 171 logger.warn("Unexpected result from proplist: %s", proplist) 172 raise svntest.Failure 173 174 prop_name = 'foo:bar-baz-quux' 175 exit_code, output, errput = svntest.main.run_svnlook('propget', 176 '--revprop', repo_dir, 177 prop_name) 178 179 expected_err = "Property '%s' not found on revision " % prop_name 180 for line in errput: 181 if line.find(expected_err) != -1: 182 break 183 else: 184 raise svntest.main.SVNUnmatchedError 185 186 exit_code, output, errput = svntest.main.run_svnlook('propget', 187 '-r1', repo_dir, 188 prop_name, '/') 189 190 expected_err = "Property '%s' not found on path '/' in revision " % prop_name 191 for line in errput: 192 if line.find(expected_err) != -1: 193 break 194 else: 195 raise svntest.main.SVNUnmatchedError 196 197#---------------------------------------------------------------------- 198# Issue 1089 199@Issue(1089) 200def delete_file_in_moved_dir(sbox): 201 "delete file in moved dir" 202 203 sbox.build() 204 wc_dir = sbox.wc_dir 205 repo_dir = sbox.repo_dir 206 207 # move E to E2 and delete E2/alpha 208 E_path = os.path.join(wc_dir, 'A', 'B', 'E') 209 E2_path = os.path.join(wc_dir, 'A', 'B', 'E2') 210 svntest.actions.run_and_verify_svn(None, [], 'mv', E_path, E2_path) 211 alpha_path = os.path.join(E2_path, 'alpha') 212 svntest.actions.run_and_verify_svn(None, [], 'rm', alpha_path) 213 214 # commit 215 expected_output = svntest.wc.State(wc_dir, { 216 'A/B/E' : Item(verb='Deleting'), 217 'A/B/E2' : Item(verb='Adding'), 218 'A/B/E2/alpha' : Item(verb='Deleting'), 219 }) 220 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 221 expected_status.remove('A/B/E', 'A/B/E/alpha', 'A/B/E/beta') 222 expected_status.add({ 223 'A/B/E2' : Item(status=' ', wc_rev=2), 224 'A/B/E2/beta' : Item(status=' ', wc_rev=2), 225 }) 226 ### this commit fails. the 'alpha' node is marked 'not-present' since it 227 ### is a deleted child of a move/copy. this is all well and proper. 228 ### however, during the commit, the parent node is committed down to just 229 ### the BASE node. at that point, 'alpha' has no parent in WORKING which 230 ### is a schema violation. there is a plan for committing in this kind of 231 ### situation, layed out in wc-ng-design. that needs to be implemented 232 ### in order to get this commit working again. 233 svntest.actions.run_and_verify_commit(wc_dir, 234 expected_output, 235 expected_status) 236 237 exit_code, output, errput = svntest.main.run_svnlook("dirs-changed", 238 repo_dir) 239 if errput: 240 raise svntest.Failure 241 242 # Okay. No failure, but did we get the right output? 243 if len(output) != 2: 244 raise svntest.Failure 245 if not ((output[0].strip() == 'A/B/') 246 and (output[1].strip() == 'A/B/E2/')): 247 raise svntest.Failure 248 249 250#---------------------------------------------------------------------- 251# Issue 1241 252@Issue(1241) 253def test_print_property_diffs(sbox): 254 "test the printing of property diffs" 255 256 sbox.build() 257 wc_dir = sbox.wc_dir 258 repo_dir = sbox.repo_dir 259 260 # Add a bogus property to iota 261 iota_path = os.path.join(wc_dir, 'iota') 262 svntest.actions.run_and_verify_svn(None, [], 'propset', 263 'bogus_prop', 'bogus_val', iota_path) 264 265 # commit the change 266 svntest.actions.run_and_verify_svn(None, [], 267 'ci', '-m', 'log msg', iota_path) 268 269 # Grab the diff 270 exit_code, expected_output, err = svntest.actions.run_and_verify_svn( 271 None, [], 'diff', '-r', 'PREV', iota_path) 272 273 exit_code, output, errput = svntest.main.run_svnlook("diff", repo_dir) 274 if errput: 275 raise svntest.Failure 276 277 # Okay. No failure, but did we get the right output? 278 if len(output) != len(expected_output): 279 raise svntest.Failure 280 281 canonical_iota_path = iota_path.replace(os.path.sep, '/') 282 283 # replace wcdir/iota with iota in expected_output 284 for i in range(len(expected_output)): 285 expected_output[i] = expected_output[i].replace(canonical_iota_path, 286 'iota') 287 288 # Check that the header filenames match. 289 if expected_output[2].split()[1] != output[2].split()[1]: 290 raise svntest.Failure 291 if expected_output[3].split()[1] != output[3].split()[1]: 292 raise svntest.Failure 293 294 svntest.verify.compare_and_display_lines('', '', 295 expected_output[4:], 296 output[4:]) 297 298#---------------------------------------------------------------------- 299# Check that svnlook info repairs allows inconsistent line endings in logs. 300 301def info_bad_newlines(sbox): 302 "svnlook info must allow inconsistent newlines" 303 304 dump_str = b"""SVN-fs-dump-format-version: 2 305 306UUID: dc40867b-38f6-0310-9f5f-f81aa277e06e 307 308Revision-number: 0 309Prop-content-length: 56 310Content-length: 56 311 312K 8 313svn:date 314V 27 3152005-05-03T19:09:41.129900Z 316PROPS-END 317 318Revision-number: 1 319Prop-content-length: 99 320Content-length: 99 321 322K 7 323svn:log 324V 3 325\n\r\n 326K 10 327svn:author 328V 2 329pl 330K 8 331svn:date 332V 27 3332005-05-03T19:10:19.975578Z 334PROPS-END 335 336Node-path: file 337Node-kind: file 338Node-action: add 339Prop-content-length: 10 340Text-content-length: 5 341Text-content-md5: e1cbb0c3879af8347246f12c559a86b5 342Content-length: 15 343 344PROPS-END 345text 346 347 348""" 349 350 # load dumpfile with inconsistent newlines into repos. 351 svntest.actions.load_repo(sbox, dump_str=dump_str, 352 bypass_prop_validation=True) 353 354 exit_code, output, errput = svntest.main.run_svnlook("info", 355 sbox.repo_dir, "-r1") 356 if errput: 357 raise svntest.Failure 358 359def changed_copy_info(sbox): 360 "test --copy-info flag on the changed command" 361 sbox.build() 362 wc_dir = sbox.wc_dir 363 repo_dir = sbox.repo_dir 364 365 # Copy alpha to /A/alpha2. 366 E_path = os.path.join(wc_dir, 'A', 'B', 'E') 367 alpha_path = os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') 368 alpha2_path = os.path.join(wc_dir, 'A', 'alpha2') 369 svntest.actions.run_and_verify_svn(None, [], 'cp', alpha_path, 370 alpha2_path) 371 372 # commit 373 expected_output = svntest.wc.State(wc_dir, { 374 'A/alpha2' : Item(verb='Adding'), 375 }) 376 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 377 expected_status.add({ 378 'A/alpha2' : Item(status=' ', wc_rev=2), 379 }) 380 svntest.actions.run_and_verify_commit(wc_dir, 381 expected_output, 382 expected_status) 383 384 exit_code, output, errput = svntest.main.run_svnlook("changed", repo_dir) 385 if errput: 386 raise svntest.Failure 387 388 expect("changed without --copy-info", ["A A/alpha2\n"], output) 389 390 exit_code, output, errput = svntest.main.run_svnlook("changed", 391 repo_dir, "--copy-info") 392 if errput: 393 raise svntest.Failure 394 395 expect("changed with --copy-info", 396 ["A + A/alpha2\n", 397 " (from A/B/E/alpha:r1)\n"], 398 output) 399 400#---------------------------------------------------------------------- 401# Issue 2663 402@Issue(2663) 403def tree_non_recursive(sbox): 404 "test 'svnlook tree --non-recursive'" 405 406 sbox.build() 407 repo_dir = sbox.repo_dir 408 409 expected_results_root = ('/', ' iota', ' A/') 410 expected_results_deep = ('B/', ' lambda', ' E/', ' F/') 411 412 # check the output of svnlook --non-recursive on the 413 # root of the repository 414 treelist = run_svnlook('tree', '--non-recursive', repo_dir) 415 for entry in treelist: 416 if not entry.rstrip() in expected_results_root: 417 logger.warn("Unexpected result from tree with --non-recursive:") 418 logger.warn(" entry : %s", entry.rstrip()) 419 raise svntest.Failure 420 if len(treelist) != len(expected_results_root): 421 logger.warn("Expected %i output entries, found %i", 422 len(expected_results_root), len(treelist)) 423 raise svntest.Failure 424 425 # check the output of svnlook --non-recursive on a 426 # subdirectory of the repository 427 treelist = run_svnlook('tree', '--non-recursive', repo_dir, '/A/B') 428 for entry in treelist: 429 if not entry.rstrip() in expected_results_deep: 430 logger.warn("Unexpected result from tree with --non-recursive:") 431 logger.warn(" entry : %s", entry.rstrip()) 432 raise svntest.Failure 433 if len(treelist) != len(expected_results_deep): 434 logger.warn("Expected %i output entries, found %i", 435 len(expected_results_deep), len(treelist)) 436 raise svntest.Failure 437 438#---------------------------------------------------------------------- 439def limit_history(sbox): 440 "history --limit" 441 sbox.build(create_wc=False) 442 repo_url = sbox.repo_url 443 svntest.actions.run_and_verify_svn(None, [], 444 'mv', '-m', 'log msg', 445 repo_url + "/iota", repo_url + "/iota2") 446 svntest.actions.run_and_verify_svn(None, [], 447 'mv', '-m', 'log msg', 448 repo_url + "/A/mu", repo_url + "/iota") 449 history = run_svnlook("history", "--limit=1", sbox.repo_dir) 450 # Ignore the two lines of header, and verify expected number of items. 451 if len(history[2:]) != 1: 452 raise svntest.Failure("Output not limited to expected number of items") 453 454#---------------------------------------------------------------------- 455def diff_ignore_whitespace(sbox): 456 "test 'svnlook diff -x -b' and 'svnlook diff -x -w'" 457 458 sbox.build() 459 repo_dir = sbox.repo_dir 460 wc_dir = sbox.wc_dir 461 462 # Make whitespace-only changes to mu 463 mu_path = os.path.join(wc_dir, 'A', 'mu') 464 svntest.main.file_write(mu_path, "This is the file 'mu'.\n", "wb") 465 466 # Created expected output tree for 'svn ci' 467 expected_output = svntest.wc.State(wc_dir, { 468 'A/mu' : Item(verb='Sending'), 469 }) 470 471 # Create expected status tree; all local revisions should be at 1, 472 # but mu should be at revision 2. 473 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 474 expected_status.tweak('A/mu', wc_rev=2) 475 476 svntest.actions.run_and_verify_commit(wc_dir, 477 expected_output, 478 expected_status) 479 480 # Check the output of 'svnlook diff -x --ignore-space-change' on mu. 481 # It should not print anything. 482 output = run_svnlook('diff', '-r2', '-x', '--ignore-space-change', 483 repo_dir) 484 if output != []: 485 raise svntest.Failure 486 487 # Check the output of 'svnlook diff -x --ignore-all-space' on mu. 488 # It should not print anything. 489 output = run_svnlook('diff', '-r2', '-x', '--ignore-all-space', 490 repo_dir) 491 if output != []: 492 raise svntest.Failure 493 494#---------------------------------------------------------------------- 495def diff_ignore_eolstyle(sbox): 496 "test 'svnlook diff -x --ignore-eol-style'" 497 498 sbox.build() 499 repo_dir = sbox.repo_dir 500 wc_dir = sbox.wc_dir 501 502 # CRLF is a string that will match a CRLF sequence read from a text file. 503 # ### On Windows, we assume CRLF will be read as LF, so it's a poor test. 504 if os.name == 'nt': 505 crlf = '\n' 506 else: 507 crlf = '\r\n' 508 509 mu_path = os.path.join(wc_dir, 'A', 'mu') 510 511 rev = 1 512 # do the --ignore-eol-style test for each eol-style 513 for eol, eolchar in zip(['CRLF', 'CR', 'native', 'LF'], 514 [crlf, '\015', '\n', '\012']): 515 # rewrite file mu and set the eol-style property. 516 svntest.main.file_write(mu_path, "This is the file 'mu'." + eolchar, 'wb') 517 svntest.main.run_svn(None, 'propset', 'svn:eol-style', eol, mu_path) 518 519 # Created expected output tree for 'svn ci' 520 expected_output = svntest.wc.State(wc_dir, { 521 'A/mu' : Item(verb='Sending'), 522 }) 523 524 # Create expected status tree; all local revisions should be at 525 # revision 1, but mu should be at revision rev + 1. 526 expected_status = svntest.actions.get_virginal_state(wc_dir, 1) 527 expected_status.tweak('A/mu', wc_rev=rev + 1) 528 529 svntest.actions.run_and_verify_commit(wc_dir, 530 expected_output, 531 expected_status) 532 533 # Grab the diff 534 exit_code, expected_output, err = svntest.actions.run_and_verify_svn( 535 None, [], 536 'diff', '-r', 'PREV', '-x', '--ignore-eol-style', mu_path) 537 538 539 output = run_svnlook('diff', '-r', str(rev + 1), '-x', 540 '--ignore-eol-style', repo_dir) 541 rev += 1 542 543 canonical_mu_path = mu_path.replace(os.path.sep, '/') 544 545 # replace wcdir/A/mu with A/mu in expected_output 546 for i in range(len(expected_output)): 547 expected_output[i] = expected_output[i].replace(canonical_mu_path, 548 'A/mu') 549 550 # Check that the header filenames match. 551 if expected_output[2].split()[1] != output[2].split()[1]: 552 raise svntest.Failure 553 if expected_output[3].split()[1] != output[3].split()[1]: 554 raise svntest.Failure 555 556 svntest.verify.compare_and_display_lines('', '', 557 expected_output[4:], 558 output[4:]) 559 560 561#---------------------------------------------------------------------- 562def diff_binary(sbox): 563 "test 'svnlook diff' on binary files" 564 565 sbox.build() 566 repo_dir = sbox.repo_dir 567 wc_dir = sbox.wc_dir 568 569 # Set A/mu to a binary mime-type, tweak its text, and commit. 570 mu_path = os.path.join(wc_dir, 'A', 'mu') 571 svntest.main.file_append(mu_path, 'new appended text for mu') 572 svntest.main.run_svn(binary_mime_type_on_text_file_warning, 573 'propset', 'svn:mime-type', 574 'application/octet-stream', mu_path) 575 svntest.main.run_svn(None, 'ci', '-m', 'log msg', mu_path) 576 577 # Now run 'svnlook diff' and look for the "Binary files differ" message. 578 output = run_svnlook('diff', repo_dir) 579 if not "(Binary files differ)\n" in output: 580 raise svntest.Failure("No 'Binary files differ' indication in " 581 "'svnlook diff' output.") 582 583#---------------------------------------------------------------------- 584def test_filesize(sbox): 585 "test 'svnlook filesize'" 586 587 sbox.build() 588 repo_dir = sbox.repo_dir 589 wc_dir = sbox.wc_dir 590 591 tree_output = run_svnlook('tree', '--full-paths', repo_dir) 592 for line in tree_output: 593 # Drop line endings 594 line = line.rstrip() 595 # Skip directories 596 if line[-1] == '/': 597 continue 598 # Run 'svnlook cat' and measure the size of the output. 599 cat_output = run_svnlook('cat', repo_dir, line) 600 cat_size = len("".join(cat_output)) 601 # Run 'svnlook filesize' and compare the results with the CAT_SIZE. 602 filesize_output = run_svnlook('filesize', repo_dir, line) 603 if len(filesize_output) != 1: 604 raise svntest.Failure("'svnlook filesize' printed something other than " 605 "a single line of output.") 606 filesize = int(filesize_output[0].strip()) 607 if filesize != cat_size: 608 raise svntest.Failure("'svnlook filesize' and the counted length of " 609 "'svnlook cat's output differ for the path " 610 "'%s'." % (line)) 611 612#---------------------------------------------------------------------- 613def verify_logfile(logfilename, expected_data): 614 if os.path.exists(logfilename): 615 fp = open(logfilename) 616 else: 617 raise svntest.verify.SVNUnexpectedOutput("hook logfile %s not found"\ 618 % logfilename) 619 620 actual_data = fp.readlines() 621 fp.close() 622 os.unlink(logfilename) 623 svntest.verify.compare_and_display_lines('wrong hook logfile content', 624 'STDOUT', 625 expected_data, actual_data) 626 627def test_txn_flag(sbox): 628 "test 'svnlook * -t'" 629 630 sbox.build() 631 repo_dir = sbox.repo_dir 632 wc_dir = sbox.wc_dir 633 logfilepath = os.path.join(repo_dir, 'hooks.log') 634 635 # List changed dirs and files in this transaction 636 hook_template = """import sys,os,subprocess 637svnlook_bin=%s 638 639fp = open(os.path.join(sys.argv[1], 'hooks.log'), 'wb') 640def output_command(fp, cmd, opt): 641 command = [svnlook_bin, cmd, '-t', sys.argv[2], sys.argv[1]] + opt 642 process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, bufsize=-1) 643 (output, errors) = process.communicate() 644 status = process.returncode 645 fp.write(output) 646 fp.write(errors) 647 return status 648 649for (svnlook_cmd, svnlook_opt) in %s: 650 output_command(fp, svnlook_cmd, svnlook_opt.split()) 651fp.close()""" 652 pre_commit_hook = svntest.main.get_pre_commit_hook_path(repo_dir) 653 654 # 1. svnlook 'changed' -t and 'dirs-changed' -t 655 hook_instance = hook_template % (repr(svntest.main.svnlook_binary), 656 repr([('changed', ''), 657 ('dirs-changed', '')])) 658 svntest.main.create_python_hook_script(pre_commit_hook, 659 hook_instance) 660 661 # Change files mu and rho 662 A_path = os.path.join(wc_dir, 'A') 663 mu_path = os.path.join(wc_dir, 'A', 'mu') 664 rho_path = os.path.join(wc_dir, 'A', 'D', 'G', 'rho') 665 svntest.main.file_append(mu_path, 'appended mu text') 666 svntest.main.file_append(rho_path, 'new appended text for rho') 667 668 # commit, and check the hook's logfile 669 svntest.actions.run_and_verify_svn(None, [], 670 'ci', '-m', 'log msg', wc_dir) 671 svntest.actions.run_and_verify_svn(None, [], 672 'up', wc_dir) 673 674 expected_data = [ 'U A/D/G/rho\n', 'U A/mu\n', 'A/\n', 'A/D/G/\n' ] 675 verify_logfile(logfilepath, expected_data) 676 677 # 2. svnlook 'propget' -t, 'proplist' -t 678 # 2. Change a dir and revision property 679 hook_instance = hook_template % (repr(svntest.main.svnlook_binary), 680 repr([('propget', 'bogus_prop /A'), 681 ('propget', '--revprop bogus_rev_prop'), 682 ('proplist', '/A'), 683 ('proplist', '--revprop')])) 684 svntest.main.create_python_hook_script(pre_commit_hook, 685 hook_instance) 686 687 svntest.actions.run_and_verify_svn(None, [], 'propset', 688 'bogus_prop', 'bogus_val\n', A_path) 689 svntest.actions.run_and_verify_svn(None, [], 690 'ci', '-m', 'log msg', wc_dir, 691 '--with-revprop', 'bogus_rev_prop=bogus_rev_val\n') 692 # Now check the logfile 693 expected_data = [ 'bogus_val\n', 694 'bogus_rev_val\n', 695 "Properties on '/A':\n", 696 ' bogus_prop\n', 697 ' svn:log\n', ' svn:author\n', 698 ' bogus_rev_prop\n', 699 ' svn:date\n', 700 ' svn:txn-client-compat-version\n', 701 ' svn:txn-user-agent\n', 702 ] 703 verify_logfile(logfilepath, svntest.verify.UnorderedOutput(expected_data)) 704 705# From r1293375 until fixed in r1303856, 'svnlook changed' and 'svnlook diff' 706# produced no output on a property delete. 707def property_delete(sbox): 708 "property delete" 709 710 sbox.build() 711 repo_dir = sbox.repo_dir 712 713 sbox.simple_propset('foo', 'bar', 'A/mu') 714 sbox.simple_commit() 715 sbox.simple_propdel('foo', 'A/mu') 716 sbox.simple_commit() 717 718 svntest.actions.run_and_verify_svnlook(["_U A/mu\n"], [], 719 'changed', repo_dir) 720 721 722######################################################################## 723# Run the tests 724 725 726# list all tests here, starting with None: 727test_list = [ None, 728 test_misc, 729 delete_file_in_moved_dir, 730 test_print_property_diffs, 731 info_bad_newlines, 732 changed_copy_info, 733 tree_non_recursive, 734 limit_history, 735 diff_ignore_whitespace, 736 diff_ignore_eolstyle, 737 diff_binary, 738 test_filesize, 739 test_txn_flag, 740 property_delete, 741 ] 742 743if __name__ == '__main__': 744 svntest.main.run_tests(test_list) 745 # NOTREACHED 746 747 748### End of file. 749