~svn/ubuntu/raring/subversion/ppa

« back to all changes in this revision

Viewing changes to subversion/tests/clients/cmdline/log_tests.py

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-12-05 01:26:14 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051205012614-qom4xfypgtsqc2xq
Tags: 1.2.3dfsg1-3ubuntu1
Merge with the final Debian release of 1.2.3dfsg1-3, bringing in
fixes to the clean target, better documentation of the libdb4.3
upgrade and build fixes to work with swig1.3_1.3.27.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
#
 
3
#  log_tests.py:  testing "svn log"
 
4
#
 
5
#  Subversion is a tool for revision control. 
 
6
#  See http://subversion.tigris.org for more information.
 
7
#    
 
8
# ====================================================================
 
9
# Copyright (c) 2000-2004 CollabNet.  All rights reserved.
 
10
#
 
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.
 
16
#
 
17
######################################################################
 
18
 
 
19
# General modules
 
20
import string, sys, re, os, shutil
 
21
 
 
22
# Our testing module
 
23
import svntest
 
24
from svntest import SVNAnyOutput
 
25
 
 
26
 
 
27
######################################################################
 
28
#
 
29
# The Plan:
 
30
#
 
31
# Get a repository, commit about 6 or 7 revisions to it, each
 
32
# involving different kinds of operations.  Make sure to have some
 
33
# add, del, mv, cp, as well as file modifications, and make sure that
 
34
# some files are modified more than once.
 
35
#
 
36
# Give each commit a recognizable log message.  Test all combinations
 
37
# of -r options, including none.  Then test with -v, which will
 
38
# (presumably) show changed paths as well.
 
39
#
 
40
######################################################################
 
41
 
 
42
 
 
43
 
 
44
######################################################################
 
45
# Globals
 
46
#
 
47
 
 
48
# These variables are set by guarantee_repos_and_wc().
 
49
max_revision = 0    # Highest revision in the repos
 
50
 
 
51
# What separates log msgs from one another in raw log output.
 
52
msg_separator = '------------------------------------' \
 
53
                + '------------------------------------\n'
 
54
 
 
55
 
 
56
# (abbreviation)
 
57
Skip = svntest.testcase.Skip
 
58
XFail = svntest.testcase.XFail
 
59
Item = svntest.wc.StateItem
 
60
 
 
61
 
 
62
######################################################################
 
63
# Utilities
 
64
#
 
65
 
 
66
def guarantee_repos_and_wc(sbox):
 
67
  "Make a repos and wc, commit max_revision revs."
 
68
  global max_revision
 
69
 
 
70
  sbox.build()
 
71
  wc_path = sbox.wc_dir
 
72
 
 
73
  # Now we have a repos and wc at revision 1.
 
74
 
 
75
  was_cwd = os.getcwd ()
 
76
  os.chdir (wc_path)
 
77
 
 
78
  # Set up the paths we'll be using most often.
 
79
  iota_path = os.path.join ('iota')
 
80
  mu_path = os.path.join ('A', 'mu')
 
81
  B_path = os.path.join ('A', 'B')
 
82
  omega_path = os.path.join ('A', 'D', 'H', 'omega')
 
83
  pi_path = os.path.join ('A', 'D', 'G', 'pi')
 
84
  rho_path = os.path.join ('A', 'D', 'G', 'rho')
 
85
  alpha_path = os.path.join ('A', 'B', 'E', 'alpha')
 
86
  beta_path = os.path.join ('A', 'B', 'E', 'beta')
 
87
  psi_path = os.path.join ('A', 'D', 'H', 'psi')
 
88
  epsilon_path = os.path.join ('A', 'C', 'epsilon')
 
89
 
 
90
  # Do a varied bunch of commits.  No copies yet, we'll wait till Ben
 
91
  # is done for that.
 
92
 
 
93
  # Revision 2: edit iota
 
94
  svntest.main.file_append (iota_path, "2")
 
95
  svntest.main.run_svn (None, 'ci', '-m', "Log message for revision 2")
 
96
  svntest.main.run_svn (None, 'up')
 
97
 
 
98
  # Revision 3: edit A/D/H/omega, A/D/G/pi, A/D/G/rho, and A/B/E/alpha
 
99
  svntest.main.file_append (omega_path, "3")
 
100
  svntest.main.file_append (pi_path, "3")
 
101
  svntest.main.file_append (rho_path, "3")
 
102
  svntest.main.file_append (alpha_path, "3")
 
103
  svntest.main.run_svn (None, 'ci', '-m', "Log message for revision 3")
 
104
  svntest.main.run_svn (None, 'up')
 
105
 
 
106
  # Revision 4: edit iota again, add A/C/epsilon
 
107
  svntest.main.file_append (iota_path, "4")
 
108
  svntest.main.file_append (epsilon_path, "4")
 
109
  svntest.main.run_svn (None, 'add', epsilon_path)
 
110
  svntest.main.run_svn (None, 'ci', '-m', "Log message for revision 4")
 
111
  svntest.main.run_svn (None, 'up')
 
112
 
 
113
  # Revision 5: edit A/C/epsilon, delete A/D/G/rho
 
114
  svntest.main.file_append (epsilon_path, "5")
 
115
  svntest.main.run_svn (None, 'rm', rho_path)
 
116
  svntest.main.run_svn (None, 'ci', '-m', "Log message for revision 5")
 
117
  svntest.main.run_svn (None, 'up')
 
118
 
 
119
  # Revision 6: prop change on A/B, edit A/D/H/psi
 
120
  svntest.main.run_svn (None, 'ps', 'blue', 'azul', B_path)  
 
121
  svntest.main.file_append (psi_path, "6")
 
122
  svntest.main.run_svn (None, 'ci', '-m', "Log message for revision 6")
 
123
  svntest.main.run_svn (None, 'up')
 
124
 
 
125
  # Revision 7: edit A/mu, prop change on A/mu
 
126
  svntest.main.file_append (mu_path, "7")
 
127
  svntest.main.run_svn (None, 'ps', 'red', 'burgundy', mu_path)
 
128
  svntest.main.run_svn (None, 'ci', '-m', "Log message for revision 7")
 
129
  svntest.main.run_svn (None, 'up')
 
130
 
 
131
  # Revision 8: edit iota yet again, re-add A/D/G/rho
 
132
  svntest.main.file_append (iota_path, "8")
 
133
  svntest.main.file_append (rho_path, "8")
 
134
  svntest.main.run_svn (None, 'add', rho_path)
 
135
  svntest.main.run_svn (None, 'ci', '-m', "Log message for revision 8")
 
136
  svntest.main.run_svn (None, 'up')
 
137
 
 
138
  # Revision 9: edit A/B/E/beta, delete A/B/E/alpha
 
139
  svntest.main.file_append (beta_path, "9")
 
140
  svntest.main.run_svn (None, 'rm', alpha_path)
 
141
  svntest.main.run_svn (None, 'ci', '-m', "Log message for revision 9")
 
142
  svntest.main.run_svn (None, 'up')
 
143
 
 
144
  max_revision = 9
 
145
 
 
146
  # Restore.
 
147
  os.chdir (was_cwd)
 
148
 
 
149
  # Let's run 'svn status' and make sure the working copy looks
 
150
  # exactly the way we think it should.  Start with a generic
 
151
  # greek-tree-list, where every local and repos revision is at 9.
 
152
  expected_status = svntest.actions.get_virginal_state(wc_path, 9)
 
153
  expected_status.remove('A/B/E/alpha')
 
154
  expected_status.add({
 
155
    'A/C/epsilon' : Item(status='  ', wc_rev=9),
 
156
    })
 
157
 
 
158
  # props exist on A/B and A/mu
 
159
  expected_status.tweak('A/B', 'A/mu', status='  ')
 
160
 
 
161
  # Run 'svn st -uv' and compare the actual results with our tree.
 
162
  svntest.actions.run_and_verify_status(wc_path, expected_status)
 
163
 
 
164
 
 
165
 
 
166
 
 
167
# For errors seen while parsing log data.
 
168
class SVNLogParseError(Exception):
 
169
  def __init__ (self, args=None):
 
170
    self.args = args
 
171
 
 
172
 
 
173
def parse_log_output(log_lines):
 
174
  """Return a log chain derived from LOG_LINES.
 
175
  A log chain is a list of hashes; each hash represents one log
 
176
  message, in the order it appears in LOG_LINES (the first log
 
177
  message in the data is also the first element of the list, and so
 
178
  on).
 
179
 
 
180
  Each hash contains the following keys/values:
 
181
 
 
182
     'revision' ===>  number
 
183
     'author'   ===>  string
 
184
     'date'     ===>  string
 
185
     'msg'      ===>  string  (the log message itself)
 
186
 
 
187
  If LOG_LINES contains changed-path information, then the hash
 
188
  also contains
 
189
 
 
190
     'paths'    ===>  list of strings
 
191
 
 
192
     """
 
193
 
 
194
  # Here's some log output to look at while writing this function:
 
195
  
 
196
  # ------------------------------------------------------------------------
 
197
  # r5 | kfogel | Tue 6 Nov 2001 17:18:19 | 1 line
 
198
  # 
 
199
  # Log message for revision 5.
 
200
  # ------------------------------------------------------------------------
 
201
  # r4 | kfogel | Tue 6 Nov 2001 17:18:18 | 1 line
 
202
  # 
 
203
  # Log message for revision 4.
 
204
  # ------------------------------------------------------------------------
 
205
  # r3 | kfogel | Tue 6 Nov 2001 17:18:17 | 1 line
 
206
  # 
 
207
  # Log message for revision 3.
 
208
  # ------------------------------------------------------------------------
 
209
  # r2 | kfogel | Tue 6 Nov 2001 17:18:16 | 1 line
 
210
  # 
 
211
  # Log message for revision 2.
 
212
  # ------------------------------------------------------------------------
 
213
  # r1 | foo | Tue 6 Nov 2001 15:27:57 | 1 line
 
214
  # 
 
215
  # Log message for revision 1.
 
216
  # ------------------------------------------------------------------------
 
217
 
 
218
  # Regular expression to match the header line of a log message, with
 
219
  # these groups: (revision number), (author), (date), (num lines).
 
220
  header_re = re.compile ('^r([0-9]+) \| ' \
 
221
                          + '([^|]*) \| ([^|]*) \| ([0-9]+) lines?')
 
222
 
 
223
  # The log chain to return.
 
224
  chain = []
 
225
 
 
226
  this_item = None
 
227
  while 1:
 
228
    try:
 
229
      this_line = log_lines.pop (0)
 
230
    except IndexError:
 
231
      return chain
 
232
 
 
233
    match = header_re.search (this_line)
 
234
    if match and match.groups ():
 
235
      this_item = {}
 
236
      this_item['revision'] = match.group(1)
 
237
      this_item['author']   = match.group(2)
 
238
      this_item['date']     = match.group(3)
 
239
      lines = string.atoi ((match.group (4)))
 
240
 
 
241
      # Eat the expected blank line.
 
242
      log_lines.pop (0)
 
243
 
 
244
      ### todo: we don't parse changed-paths yet, since Subversion
 
245
      ### doesn't output them.  When it does, they'll appear here,
 
246
      ### right after the header line, and then there'll be a blank
 
247
      ### line between them and the msg.
 
248
 
 
249
      # Accumulate the log message
 
250
      msg = ''
 
251
      for line in log_lines[0:lines]:
 
252
        msg += line
 
253
      del log_lines[0:lines]
 
254
    elif this_line == msg_separator:
 
255
      if this_item:
 
256
        this_item['msg'] = msg
 
257
        chain.append (this_item)
 
258
    else:  # if didn't see separator now, then something's wrong
 
259
      raise SVNLogParseError, "trailing garbage after log message"
 
260
 
 
261
  return chain
 
262
 
 
263
 
 
264
def check_log_chain (chain, revlist):
 
265
  """Verify that log chain CHAIN contains the right log messages for
 
266
  revisions START to END (see documentation for parse_log_output() for
 
267
  more about log chains.)
 
268
 
 
269
  Do nothing if the log chain's messages run from revision START to END
 
270
  with no gaps, and that each log message is one line of the form
 
271
 
 
272
     'Log message for revision N'
 
273
 
 
274
  where N is the revision number of that commit.  Also verify that
 
275
  author and date are present and look sane, but don't check them too
 
276
  carefully.
 
277
 
 
278
  Raise if anything looks wrong.
 
279
  """
 
280
 
 
281
  for expect_rev in revlist:
 
282
    log_item = chain.pop (0)
 
283
    saw_rev = string.atoi (log_item['revision'])
 
284
    date = log_item['date']
 
285
    author = log_item['author']
 
286
    msg = log_item['msg']
 
287
    # The most important check is that the revision is right:
 
288
    if expect_rev != saw_rev: raise svntest.Failure
 
289
    # Check that date looks at least vaguely right:
 
290
    date_re = re.compile ('[0-9]+')
 
291
    if (not date_re.search (date)): raise svntest.Failure
 
292
    # Authors are a little harder, since they might not exist over ra-dav.
 
293
    # Well, it's not much of a check, but we'll do what we can.
 
294
    author_re = re.compile ('[a-zA-Z]+')
 
295
    if (not (author_re.search (author)
 
296
             or author == ''
 
297
             or author == '(no author)')): raise svntest.Failure
 
298
    # Check that the log message looks right:
 
299
    msg_re = re.compile ('Log message for revision ' + `saw_rev`)
 
300
    if (not msg_re.search (msg)): raise svntest.Failure
 
301
 
 
302
  ### todo: need some multi-line log messages mixed in with the
 
303
  ### one-liners.  Easy enough, just make the prime revisions use REV
 
304
  ### lines, and the rest use 1 line, or something, so it's
 
305
  ### predictable based on REV.
 
306
 
 
307
 
 
308
######################################################################
 
309
# Tests
 
310
#
 
311
 
 
312
#----------------------------------------------------------------------
 
313
def plain_log(sbox):
 
314
  "'svn log', no args, top of wc"
 
315
 
 
316
  guarantee_repos_and_wc(sbox)
 
317
 
 
318
  was_cwd = os.getcwd()
 
319
  os.chdir(sbox.wc_dir)
 
320
 
 
321
  try:
 
322
    output, err = svntest.actions.run_and_verify_svn ("", None, [], 'log')
 
323
 
 
324
    log_chain = parse_log_output (output)
 
325
    if check_log_chain (log_chain, range(max_revision, 1 - 1, -1)):
 
326
      raise svntest.Failure
 
327
    
 
328
  finally:
 
329
    os.chdir (was_cwd)
 
330
 
 
331
 
 
332
#----------------------------------------------------------------------
 
333
def versioned_log_message(sbox):
 
334
  "'svn commit -F foo' when foo is a versioned file"
 
335
 
 
336
  sbox.build()
 
337
 
 
338
  was_cwd = os.getcwd ()
 
339
  os.chdir (sbox.wc_dir)
 
340
 
 
341
  try:
 
342
    iota_path = os.path.join ('iota')
 
343
    mu_path = os.path.join ('A', 'mu')
 
344
    log_path = os.path.join ('A', 'D', 'H', 'omega')
 
345
    
 
346
    svntest.main.file_append (iota_path, "2")
 
347
    
 
348
    # try to check in a change using a versioned file as your log entry.
 
349
    svntest.actions.run_and_verify_svn("", None, SVNAnyOutput,
 
350
                                       'ci', '-F', log_path)
 
351
 
 
352
    # force it.  should not produce any errors.
 
353
    svntest.actions.run_and_verify_svn ("", None, [],
 
354
                                        'ci', '-F', log_path, '--force-log')
 
355
 
 
356
    svntest.main.file_append (mu_path, "2")
 
357
 
 
358
    # try the same thing, but specifying the file to commit explicitly.
 
359
    svntest.actions.run_and_verify_svn("", None, SVNAnyOutput,
 
360
                                       'ci', '-F', log_path, mu_path)
 
361
 
 
362
    # force it...  should succeed.
 
363
    svntest.actions.run_and_verify_svn ("", None, [],
 
364
                                        'ci',
 
365
                                        '-F', log_path,
 
366
                                        '--force-log', mu_path)
 
367
 
 
368
  finally:
 
369
    os.chdir (was_cwd)
 
370
 
 
371
 
 
372
#----------------------------------------------------------------------
 
373
def log_with_empty_repos(sbox):
 
374
  "'svn log' on an empty repository"
 
375
 
 
376
  # Create virgin repos
 
377
  svntest.main.safe_rmtree(sbox.repo_dir, 1)
 
378
  svntest.main.create_repos(sbox.repo_dir)
 
379
  svntest.main.set_repos_paths(sbox.repo_dir)
 
380
 
 
381
  svntest.actions.run_and_verify_svn ("", None, [],
 
382
                                      'log',
 
383
                                      '--username', svntest.main.wc_author,
 
384
                                      '--password', svntest.main.wc_passwd,
 
385
                                      svntest.main.current_repo_url)
 
386
 
 
387
#----------------------------------------------------------------------
 
388
def log_where_nothing_changed(sbox):
 
389
  "'svn log -rN some_dir_unchanged_in_N'"
 
390
  sbox.build()
 
391
 
 
392
  # Fix bug whereby running 'svn log -rN SOMEPATH' would result in an
 
393
  # xml protocol error if there were no changes in revision N
 
394
  # underneath SOMEPATH.  This problem was introduced in revision
 
395
  # 3811, which didn't cover the case where svn_repos_get_logs might
 
396
  # invoke log_receiver zero times.  Since the receiver never ran, the
 
397
  # lrb->needs_header flag never got cleared.  Control would proceed
 
398
  # without error to the end of dav_svn__log_report(), which would
 
399
  # send a closing tag even though no opening tag had ever been sent.
 
400
 
 
401
  rho_path = os.path.join (sbox.wc_dir, 'A', 'D', 'G', 'rho')
 
402
  svntest.main.file_append (rho_path, "some new material in rho")
 
403
  svntest.actions.run_and_verify_svn(None, None, [], 'ci', '-m',
 
404
                                     'log msg', rho_path)
 
405
 
 
406
  # Now run 'svn log -r2' on a directory unaffected by revision 2.
 
407
  H_path = os.path.join (sbox.wc_dir, 'A', 'D', 'H')
 
408
  svntest.actions.run_and_verify_svn(None, None, [],
 
409
                                     'log', '-r', '2', H_path)
 
410
 
 
411
 
 
412
#----------------------------------------------------------------------
 
413
def log_to_revision_zero(sbox):
 
414
  "'svn log -v -r 1:0 wc_root'"
 
415
  sbox.build()
 
416
 
 
417
  # This used to segfault the server.
 
418
  
 
419
  svntest.actions.run_and_verify_svn(None, None, [],
 
420
                                     'log', '-v',
 
421
                                     '-r', '1:0', sbox.wc_dir)
 
422
 
 
423
#----------------------------------------------------------------------
 
424
def log_with_path_args(sbox):
 
425
  "'svn log', with args, top of wc"
 
426
 
 
427
  guarantee_repos_and_wc(sbox)
 
428
 
 
429
  was_cwd = os.getcwd()
 
430
  os.chdir(sbox.wc_dir)
 
431
 
 
432
  try:
 
433
    output, err = svntest.actions.run_and_verify_svn(
 
434
      None, None, [],
 
435
      'log', svntest.main.current_repo_url, 'A/D/G', 'A/D/H')
 
436
 
 
437
    log_chain = parse_log_output (output)
 
438
    if check_log_chain (log_chain, [8, 6, 5, 3, 1]):
 
439
      raise svntest.Failure
 
440
 
 
441
  finally:
 
442
    os.chdir (was_cwd)
 
443
 
 
444
#----------------------------------------------------------------------
 
445
def url_missing_in_head(sbox):
 
446
  "'svn log -r N URL' when URL is not in HEAD "
 
447
 
 
448
  guarantee_repos_and_wc(sbox)
 
449
 
 
450
  my_url = svntest.main.current_repo_url + "/A/B/E/alpha"
 
451
  
 
452
  svntest.actions.run_and_verify_svn(None, None, [],
 
453
                                     'log', '-r', '8', my_url)
 
454
 
 
455
#----------------------------------------------------------------------
 
456
def log_through_copyfrom_history(sbox):
 
457
  "'svn log TGT' with copyfrom history"
 
458
  sbox.build()
 
459
  wc_dir = sbox.wc_dir
 
460
 
 
461
  mu_path = os.path.join (wc_dir, 'A', 'mu')
 
462
  mu2_path = os.path.join (wc_dir, 'A', 'mu2')
 
463
  mu_URL = svntest.main.current_repo_url + '/A/mu'
 
464
  mu2_URL = svntest.main.current_repo_url + '/A/mu2'
 
465
 
 
466
  svntest.main.file_append (mu_path, "2")
 
467
  svntest.actions.run_and_verify_svn (None, None, [], 'ci', wc_dir,
 
468
                                      '-m', "Log message for revision 2")
 
469
  svntest.main.file_append (mu2_path, "this is mu2")
 
470
  svntest.actions.run_and_verify_svn (None, None, [], 'add', mu2_path)
 
471
  svntest.actions.run_and_verify_svn (None, None, [], 'ci', wc_dir,
 
472
                                      '-m', "Log message for revision 3")
 
473
  svntest.actions.run_and_verify_svn (None, None, [], 'rm', mu2_path)
 
474
  svntest.actions.run_and_verify_svn (None, None, [], 'ci', wc_dir,
 
475
                                      '-m', "Log message for revision 4")
 
476
  svntest.main.file_append (mu_path, "5")
 
477
  svntest.actions.run_and_verify_svn (None, None, [], 'ci', wc_dir,
 
478
                                      '-m', "Log message for revision 5")
 
479
 
 
480
  svntest.actions.run_and_verify_svn (None, None, [],
 
481
                                      'cp', '-r', '5', mu_URL, mu2_URL,
 
482
                                      '-m', "Log message for revision 6")
 
483
  svntest.actions.run_and_verify_svn (None, None, [], 'up', wc_dir)
 
484
 
 
485
  # The full log for mu2 is relatively unsurprising
 
486
  output, err = svntest.actions.run_and_verify_svn (None, None, [],
 
487
                                                    'log', mu2_path)
 
488
  log_chain = parse_log_output (output)
 
489
  if check_log_chain (log_chain, [6, 5, 2, 1]):
 
490
    raise svntest.Failure
 
491
 
 
492
  output, err = svntest.actions.run_and_verify_svn (None, None, [],
 
493
                                                    'log', mu2_URL)
 
494
  log_chain = parse_log_output (output)
 
495
  if check_log_chain (log_chain, [6, 5, 2, 1]):
 
496
    raise svntest.Failure
 
497
 
 
498
  # First "oddity", the full log for mu2 doesn't include r3, but the -r3
 
499
  # log works!
 
500
  output, err = svntest.actions.run_and_verify_svn (None, None, [],
 
501
                                                    'log', '-r', '3', mu2_path)
 
502
  log_chain = parse_log_output (output)
 
503
  if check_log_chain (log_chain, [3]):
 
504
    raise svntest.Failure
 
505
 
 
506
  output, err = svntest.actions.run_and_verify_svn (None, None, [],
 
507
                                                    'log', '-r', '3', mu2_URL)
 
508
  log_chain = parse_log_output (output)
 
509
  if check_log_chain (log_chain, [3]):
 
510
    raise svntest.Failure
 
511
 
 
512
  # Second "oddity", the full log for mu2 includes r2, but the -r2 log
 
513
  # fails!
 
514
  svntest.actions.run_and_verify_svn (None, [], SVNAnyOutput,
 
515
                                      'log', '-r', '2', mu2_path)
 
516
  svntest.actions.run_and_verify_svn (None, [], SVNAnyOutput,
 
517
                                      'log', '-r', '2', mu2_URL)
 
518
  
 
519
#----------------------------------------------------------------------
 
520
def escape_control_chars(sbox):
 
521
  "mod_dav_svn must escape invalid XML control chars"
 
522
 
 
523
  dump_str = """SVN-fs-dump-format-version: 2
 
524
 
 
525
UUID: ffcae364-69ee-0310-a980-ca5f10462af2
 
526
 
 
527
Revision-number: 0
 
528
Prop-content-length: 56
 
529
Content-length: 56
 
530
 
 
531
K 8
 
532
svn:date
 
533
V 27
 
534
2005-01-24T10:09:21.759592Z
 
535
PROPS-END
 
536
 
 
537
Revision-number: 1
 
538
Prop-content-length: 128
 
539
Content-length: 128
 
540
 
 
541
K 7
 
542
svn:log
 
543
V 100
 
544
This msg contains a Ctrl-T (\x14) and a Ctrl-I (\t).
 
545
The former might be escaped, but the latter never.
 
546
 
 
547
K 10
 
548
svn:author
 
549
V 7
 
550
jrandom
 
551
K 8
 
552
svn:date
 
553
V 27
 
554
2005-01-24T10:09:22.012524Z
 
555
PROPS-END
 
556
"""
 
557
 
 
558
  # Create virgin repos and working copy
 
559
  svntest.main.safe_rmtree(sbox.repo_dir, 1)
 
560
  svntest.main.create_repos(sbox.repo_dir)
 
561
  svntest.main.set_repos_paths(sbox.repo_dir)
 
562
 
 
563
  URL = svntest.main.current_repo_url
 
564
 
 
565
  # load dumpfile with control character into repos to get
 
566
  # a log with control char content
 
567
  output, errput = \
 
568
    svntest.main.run_command_stdin(
 
569
    "%s load --quiet %s" % (svntest.main.svnadmin_binary, sbox.repo_dir),
 
570
    None, 1, dump_str)
 
571
 
 
572
  # run log
 
573
  output, errput = svntest.actions.run_and_verify_svn ("", None, [], 'log', URL)
 
574
 
 
575
  # Verify the output contains either the expected fuzzy escape
 
576
  # sequence, or the literal control char.
 
577
  match_unescaped_ctrl_re = "This msg contains a Ctrl-T \(.\) " \
 
578
                            "and a Ctrl-I \(\t\)\."
 
579
  match_escaped_ctrl_re = "^This msg contains a Ctrl-T \(\?\\\\020\) " \
 
580
                          "and a Ctrl-I \(\t\)\."
 
581
  matched = None
 
582
  for line in output:
 
583
    if re.match (match_unescaped_ctrl_re, line) \
 
584
       or re.match (match_escaped_ctrl_re, line):
 
585
      matched = 1
 
586
 
 
587
  if not matched:
 
588
    raise svntest.Failure ("log message not transmitted properly:" +
 
589
                           str(output) + "\n" + "error: " + str(errput))
 
590
 
 
591
 
 
592
########################################################################
 
593
# Run the tests
 
594
 
 
595
 
 
596
# list all tests here, starting with None:
 
597
test_list = [ None,
 
598
              plain_log,
 
599
              versioned_log_message,
 
600
              log_with_empty_repos,
 
601
              log_where_nothing_changed,
 
602
              log_to_revision_zero,
 
603
              log_with_path_args,
 
604
              url_missing_in_head,
 
605
              log_through_copyfrom_history,
 
606
              escape_control_chars,
 
607
             ]
 
608
 
 
609
if __name__ == '__main__':
 
610
  svntest.main.run_tests(test_list)
 
611
  # NOTREACHED
 
612
 
 
613
 
 
614
### End of file.