~svn/ubuntu/oneiric/subversion/ppa

« back to all changes in this revision

Viewing changes to subversion/tests/cmdline/svnsync_tests.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2006-12-13 17:57:16 UTC
  • mfrom: (1.1.6 upstream) (0.1.3 etch)
  • Revision ID: james.westby@ubuntu.com-20061213175716-2ysv6z4w5dpa2r2f
Tags: 1.4.2dfsg1-2ubuntu1
* Merge with Debian unstable; remaining changes:
  - Create pot file on build.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
#
 
3
#  svnsync_tests.py:  Tests SVNSync's repository mirroring capabilities.
 
4
#
 
5
#  Subversion is a tool for revision control. 
 
6
#  See http://subversion.tigris.org for more information.
 
7
#    
 
8
# ====================================================================
 
9
# Copyright (c) 2005, 2006 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.path
 
21
 
 
22
# Our testing module
 
23
import svntest
 
24
 
 
25
from authz_tests import write_restrictive_svnserve_conf, \
 
26
                        skip_test_when_no_authz_available
 
27
 
 
28
# (abbreviation)
 
29
Skip = svntest.testcase.Skip
 
30
XFail = svntest.testcase.XFail
 
31
Item = svntest.wc.StateItem
 
32
 
 
33
 
 
34
######################################################################
 
35
# Helper routines
 
36
 
 
37
 
 
38
def build_repos(sbox):
 
39
  """Avoid the use sbox.build() because we're working with a repos
 
40
  other than the Greek tree."""
 
41
  # Cleanup after the last run by removing any left-over repository.
 
42
  svntest.main.safe_rmtree(sbox.repo_dir)
 
43
 
 
44
  # Create an empty repository.
 
45
  svntest.main.create_repos(sbox.repo_dir)
 
46
  svntest.main.set_repos_paths(sbox.repo_dir)
 
47
 
 
48
 
 
49
def run_sync(url, expected_error=None):
 
50
  "Synchronize the mirror repository with the master"
 
51
  output, errput = svntest.main.run_svnsync(
 
52
    "synchronize", url,
 
53
    "--username", svntest.main.wc_author,
 
54
    "--password", svntest.main.wc_passwd)
 
55
  if errput:
 
56
    if expected_error is None:
 
57
      raise svntest.actions.SVNUnexpectedStderr(errput)
 
58
    else:
 
59
      svntest.actions.match_or_fail(None, "STDERR", expected_error, errput)
 
60
  elif expected_error is not None:
 
61
    raise svntest.actions.SVNExpectedStderr()
 
62
  if not output and not expected_error:
 
63
    # should be: ['Committed revision 1.\n', 'Committed revision 2.\n']
 
64
    raise svntest.actions.SVNUnexpectedStdout("Missing stdout")
 
65
 
 
66
def run_init(dst_url, src_url):
 
67
  "Initialize the mirror repository from the master"
 
68
  output, errput = svntest.main.run_svnsync(
 
69
    "initialize", dst_url, src_url,
 
70
    "--username", svntest.main.wc_author,
 
71
    "--password", svntest.main.wc_passwd)
 
72
  if output != ['Copied properties for revision 0.\n']:
 
73
    raise svntest.actions.SVNUnexpectedStdout(output)
 
74
  if errput:
 
75
    raise svntest.actions.SVNUnexpectedStderr(errput)
 
76
 
 
77
 
 
78
def run_test(sbox, dump_file_name):
 
79
  "Load a dump file, sync repositories, and compare contents."
 
80
 
 
81
  # Create the empty master repository.
 
82
  build_repos(sbox)
 
83
 
 
84
  # This directory contains all the dump files
 
85
  svnsync_tests_dir = os.path.join(os.path.dirname(sys.argv[0]),
 
86
                                   'svnsync_tests_data')
 
87
  # Load the specified dump file into the master repository.
 
88
  master_dumpfile_contents = file(os.path.join(svnsync_tests_dir,
 
89
                                               dump_file_name)).readlines()
 
90
  svntest.actions.run_and_verify_load(sbox.repo_dir, master_dumpfile_contents)
 
91
 
 
92
  # Create the empty destination repository.
 
93
  dest_sbox = sbox.clone_dependent()
 
94
  build_repos(dest_sbox)
 
95
 
 
96
  # Setup the mirror repository.  Feed it the UUID of the source repository.
 
97
  output, errput = svntest.main.run_svnlook("uuid", sbox.repo_dir)
 
98
  mirror_cfg = ["SVN-fs-dump-format-version: 2\n",
 
99
                "UUID: " + output[0],
 
100
                ]
 
101
  svntest.actions.run_and_verify_load(dest_sbox.repo_dir, mirror_cfg)
 
102
 
 
103
  # Create the revprop-change hook for this test
 
104
  svntest.actions.enable_revprop_changes(svntest.main.current_repo_dir)
 
105
 
 
106
  run_init(dest_sbox.repo_url, sbox.repo_url)
 
107
 
 
108
  run_sync(dest_sbox.repo_url)
 
109
 
 
110
  # Remove some SVNSync-specific housekeeping properties from the
 
111
  # mirror repository in preparation for the comparison dump.
 
112
  for prop_name in ("svn:sync-from-url", "svn:sync-from-uuid",
 
113
                    "svn:sync-last-merged-rev"):
 
114
    svntest.actions.run_and_verify_svn(
 
115
      None, None, [], "propdel", "--username", svntest.main.wc_author,
 
116
      "--password", svntest.main.wc_passwd, "--revprop", "-r", "0",
 
117
      prop_name, dest_sbox.repo_url)
 
118
 
 
119
  # Create a dump file from the mirror repository.
 
120
  dest_dump = svntest.actions.run_and_verify_dump(dest_sbox.repo_dir)
 
121
 
 
122
  # Compare the original dump file (used to create the master
 
123
  # repository) with the dump produced by the mirror repository.
 
124
  svntest.actions.compare_and_display_lines(
 
125
    "Dump files", "DUMP", master_dumpfile_contents, dest_dump)
 
126
 
 
127
 
 
128
######################################################################
 
129
# Tests
 
130
 
 
131
#----------------------------------------------------------------------
 
132
 
 
133
def copy_and_modify(sbox):
 
134
  "copy and modify"
 
135
  run_test(sbox, "copy-and-modify.dump")
 
136
 
 
137
#----------------------------------------------------------------------
 
138
 
 
139
def copy_from_previous_version_and_modify(sbox):
 
140
  "copy from previous version and modify"
 
141
  run_test(sbox, "copy-from-previous-version-and-modify.dump")
 
142
 
 
143
#----------------------------------------------------------------------
 
144
 
 
145
def copy_from_previous_version(sbox):
 
146
  "copy from previous version"
 
147
  run_test(sbox, "copy-from-previous-version.dump")
 
148
 
 
149
#----------------------------------------------------------------------
 
150
 
 
151
def modified_in_place(sbox):
 
152
  "modified in place"
 
153
  run_test(sbox, "modified-in-place.dump")
 
154
 
 
155
#----------------------------------------------------------------------
 
156
 
 
157
def tag_empty_trunk(sbox):
 
158
  "tag empty trunk"
 
159
  run_test(sbox, "tag-empty-trunk.dump")
 
160
 
 
161
#----------------------------------------------------------------------
 
162
 
 
163
def tag_trunk_with_dir(sbox):
 
164
  "tag trunk containing a sub-directory"
 
165
  run_test(sbox, "tag-trunk-with-dir.dump")
 
166
 
 
167
#----------------------------------------------------------------------
 
168
 
 
169
def tag_trunk_with_file(sbox):
 
170
  "tag trunk containing a file"
 
171
  run_test(sbox, "tag-trunk-with-file.dump")
 
172
 
 
173
#----------------------------------------------------------------------
 
174
 
 
175
def tag_trunk_with_file2(sbox):
 
176
  "tag trunk containing a file (#2)"
 
177
  run_test(sbox, "tag-trunk-with-file2.dump")
 
178
 
 
179
#----------------------------------------------------------------------
 
180
 
 
181
def tag_with_modified_file(sbox):
 
182
  "tag with a modified file"
 
183
  run_test(sbox, "tag-with-modified-file.dump")
 
184
 
 
185
#----------------------------------------------------------------------
 
186
 
 
187
def dir_prop_change(sbox):
 
188
  "directory property changes"
 
189
  run_test(sbox, "dir_prop_change.dump")
 
190
 
 
191
#----------------------------------------------------------------------
 
192
 
 
193
def file_dir_file(sbox):
 
194
  "files and dirs mixed together"
 
195
  run_test(sbox, "file-dir-file.dump")
 
196
 
 
197
#----------------------------------------------------------------------
 
198
 
 
199
def copy_parent_modify_prop(sbox):
 
200
  "copy parent and modify prop"
 
201
  run_test(sbox, "copy-parent-modify-prop.dump")
 
202
 
 
203
#----------------------------------------------------------------------
 
204
 
 
205
def detect_meddling(sbox):
 
206
  "detect non-svnsync commits in destination"
 
207
 
 
208
  sbox.build("svnsync-meddling")
 
209
 
 
210
  dest_sbox = sbox.clone_dependent()
 
211
  build_repos(dest_sbox)
 
212
 
 
213
  # Make our own destination checkout (have to do it ourself because
 
214
  # it is not greek).
 
215
  
 
216
  svntest.main.safe_rmtree(dest_sbox.wc_dir)
 
217
  svntest.actions.run_and_verify_svn(None,
 
218
                                     None,
 
219
                                     [],
 
220
                                     'co',
 
221
                                     dest_sbox.repo_url,
 
222
                                     dest_sbox.wc_dir)
 
223
 
 
224
  svntest.actions.enable_revprop_changes(svntest.main.current_repo_dir)
 
225
 
 
226
  run_init(dest_sbox.repo_url, sbox.repo_url)
 
227
  run_sync(dest_sbox.repo_url)
 
228
 
 
229
  svntest.actions.run_and_verify_svn(None,
 
230
                                     None,
 
231
                                     [],
 
232
                                     'up',
 
233
                                     '--username',
 
234
                                     svntest.main.wc_author,
 
235
                                     '--password',
 
236
                                     svntest.main.wc_passwd,
 
237
                                     dest_sbox.wc_dir)
 
238
 
 
239
  # Commit some change to the destination, which should be detected by svnsync
 
240
  svntest.main.file_append(os.path.join(dest_sbox.wc_dir, 'A', 'B', 'lambda'),
 
241
                           'new lambda text')
 
242
  svntest.actions.run_and_verify_svn(None,
 
243
                                     None,
 
244
                                     [],
 
245
                                     'ci',
 
246
                                     '-m', 'msg',
 
247
                                     '--username',
 
248
                                     svntest.main.wc_author,
 
249
                                     '--password',
 
250
                                     svntest.main.wc_passwd,
 
251
                                     dest_sbox.wc_dir)
 
252
 
 
253
  run_sync(dest_sbox.repo_url,
 
254
           ".*Destination HEAD \\(2\\) is not the last merged revision \\(1\\).*")
 
255
 
 
256
#----------------------------------------------------------------------
 
257
 
 
258
def basic_authz(sbox):
 
259
  "verify that unreadable content is not synced"
 
260
 
 
261
  skip_test_when_no_authz_available()
 
262
 
 
263
  sbox.build("svnsync-basic-authz")
 
264
 
 
265
  write_restrictive_svnserve_conf(svntest.main.current_repo_dir)
 
266
 
 
267
  dest_sbox = sbox.clone_dependent()
 
268
  build_repos(dest_sbox)
 
269
 
 
270
  svntest.actions.enable_revprop_changes(svntest.main.current_repo_dir)
 
271
 
 
272
  run_init(dest_sbox.repo_url, sbox.repo_url)
 
273
 
 
274
  fp = open(sbox.authz_file, 'w')
 
275
  fp.write("[svnsync-basic-authz:/]\n" +
 
276
           "* = r\n" +
 
277
           "\n" +
 
278
           "[svnsync-basic-authz:/A/B]\n" +
 
279
           "* = \n" +
 
280
           "\n" +
 
281
           "[svnsync-basic-authz-1:/]\n" +
 
282
           "* = rw\n")
 
283
  fp.close()
 
284
 
 
285
  run_sync(dest_sbox.repo_url)
 
286
 
 
287
  lambda_url = dest_sbox.repo_url + '/A/B/lambda'
 
288
 
 
289
  # this file should have been blocked by authz
 
290
  svntest.actions.run_and_verify_svn(None,
 
291
                                     [],
 
292
                                     svntest.SVNAnyOutput,
 
293
                                     'cat',
 
294
                                     '--username', svntest.main.wc_author,
 
295
                                     '--password', svntest.main.wc_passwd,
 
296
                                     lambda_url)
 
297
 
 
298
#----------------------------------------------------------------------
 
299
 
 
300
def copy_from_unreadable_dir(sbox):
 
301
  "verify that copies from unreadable dirs work"
 
302
 
 
303
  skip_test_when_no_authz_available()
 
304
 
 
305
  sbox.build("svnsync-copy-from-unreadable-dir")
 
306
 
 
307
  B_url = sbox.repo_url + '/A/B'
 
308
  P_url = sbox.repo_url + '/A/P'
 
309
 
 
310
  # Set a property on the directory we're going to copy, and a file in it, to
 
311
  # confirm that they're transmitted when we later sync the copied directory
 
312
  svntest.actions.run_and_verify_svn(None,
 
313
                                     None,
 
314
                                     [],
 
315
                                     'pset',
 
316
                                     'foo',
 
317
                                     'bar',
 
318
                                     sbox.wc_dir + '/A/B/lambda')
 
319
 
 
320
  svntest.actions.run_and_verify_svn(None,
 
321
                                     None,
 
322
                                     [],
 
323
                                     'pset',
 
324
                                     'baz',
 
325
                                     'zot',
 
326
                                     sbox.wc_dir + '/A/B')
 
327
 
 
328
  svntest.actions.run_and_verify_svn(None,
 
329
                                     None,
 
330
                                     [],
 
331
                                     'ci',
 
332
                                     sbox.wc_dir + '/A/B',
 
333
                                     '-m', 'log_msg')
 
334
 
 
335
  # Now copy that directory so we'll see it in our synced copy
 
336
  svntest.actions.run_and_verify_svn(None,
 
337
                                     None,
 
338
                                     [],
 
339
                                     'cp',
 
340
                                     B_url,
 
341
                                     P_url,
 
342
                                     '--username', svntest.main.wc_author,
 
343
                                     '--password', svntest.main.wc_passwd,
 
344
                                     '-m', 'Copy B to P')
 
345
 
 
346
  write_restrictive_svnserve_conf(svntest.main.current_repo_dir)
 
347
 
 
348
  dest_sbox = sbox.clone_dependent()
 
349
  build_repos(dest_sbox)
 
350
 
 
351
  svntest.actions.enable_revprop_changes(svntest.main.current_repo_dir)
 
352
 
 
353
  fp = open(sbox.authz_file, 'w')
 
354
 
 
355
  # For mod_dav_svn's parent path setup we need per-repos permissions in
 
356
  # the authz file...
 
357
  if sbox.repo_url.startswith('http'):
 
358
    fp.write("[svnsync-copy-from-unreadable-dir:/]\n" +
 
359
             "* = r\n" +
 
360
             "\n" +
 
361
             "[svnsync-copy-from-unreadable-dir:/A/B]\n" +
 
362
             "* = \n" +
 
363
             "\n" +
 
364
             "[svnsync-copy-from-unreadable-dir-1:/]\n" +
 
365
             "* = rw")
 
366
 
 
367
  # Otherwise we can just go with the permissions needed for the source
 
368
  # repository.
 
369
  else:
 
370
    fp.write("[/]\n" +
 
371
             "* = r\n" +
 
372
             "\n" +
 
373
             "[/A/B]\n" +
 
374
             "* =\n")
 
375
  fp.close()
 
376
 
 
377
  run_init(dest_sbox.repo_url, sbox.repo_url)
 
378
 
 
379
  run_sync(dest_sbox.repo_url)
 
380
 
 
381
  lambda_url = dest_sbox.repo_url + '/A/B/lambda'
 
382
 
 
383
  expected_out = [
 
384
    'Changed paths:\n',
 
385
    '   A /A/P\n',
 
386
    '   A /A/P/E\n',
 
387
    '   A /A/P/E/alpha\n',
 
388
    '   A /A/P/E/beta\n',
 
389
    '   A /A/P/F\n',
 
390
    '   A /A/P/lambda\n',
 
391
    '\n',
 
392
    'Copy B to P\n',
 
393
  ]
 
394
 
 
395
  out, err = svntest.main.run_svn(None,
 
396
                                  'log',
 
397
                                  '--username', svntest.main.wc_author,
 
398
                                  '--password', svntest.main.wc_passwd,
 
399
                                  '-r', '3',
 
400
                                  '-v',
 
401
                                  dest_sbox.repo_url)
 
402
 
 
403
  if err:
 
404
    raise svntest.actions.SVNUnexpectedStderr(err)
 
405
 
 
406
  svntest.actions.compare_and_display_lines(None,
 
407
                                            'LOG',
 
408
                                            expected_out,
 
409
                                            out[2:11])
 
410
 
 
411
  svntest.actions.run_and_verify_svn(None,
 
412
                                     ['bar\n'],
 
413
                                     [],
 
414
                                     'pget',
 
415
                                     'foo',
 
416
                                     dest_sbox.repo_url + '/A/P/lambda')
 
417
 
 
418
  svntest.actions.run_and_verify_svn(None,
 
419
                                     ['zot\n'],
 
420
                                     [],
 
421
                                     'pget',
 
422
                                     'baz',
 
423
                                     dest_sbox.repo_url + '/A/P')
 
424
 
 
425
def url_encoding(sbox):
 
426
  "test url encoding issues"
 
427
  run_test(sbox, "url-encoding-bug.dump")
 
428
 
 
429
 
 
430
# A test for copying revisions that lack a property that already exists
 
431
# on the destination rev as part of the commit (i.e. svn:author in this
 
432
# case, but svn:date would also work).
 
433
def no_author(sbox):
 
434
  "test copying revs with no svn:author revprops"
 
435
  run_test(sbox, "no-author.dump")
 
436
 
 
437
 
 
438
########################################################################
 
439
# Run the tests
 
440
 
 
441
 
 
442
# list all tests here, starting with None:
 
443
test_list = [ None,
 
444
              copy_and_modify,
 
445
              copy_from_previous_version_and_modify,
 
446
              copy_from_previous_version,
 
447
              modified_in_place,
 
448
              tag_empty_trunk,
 
449
              tag_trunk_with_dir,
 
450
              tag_trunk_with_file2,
 
451
              tag_trunk_with_file,
 
452
              tag_with_modified_file,
 
453
              dir_prop_change,
 
454
              file_dir_file,
 
455
              copy_parent_modify_prop,
 
456
              detect_meddling,
 
457
              basic_authz,
 
458
              copy_from_unreadable_dir,
 
459
              url_encoding,
 
460
              no_author,
 
461
             ]
 
462
 
 
463
if __name__ == '__main__':
 
464
  svntest.main.run_tests(test_list)
 
465
  # NOTREACHED
 
466
 
 
467
 
 
468
### End of file.