Add a little more to the svn_rangelist_intersect test to test the
[svn.git] / subversion / tests / cmdline / changelist_tests.py
blob56fd60392b7cf3d4f6a092c34b87ffc58e1e79eb
1 #!/usr/bin/env python
3 # changelist_tests.py: testing changelist uses.
5 # Subversion is a tool for revision control.
6 # See http://subversion.tigris.org for more information.
8 # ====================================================================
9 # Copyright (c) 2008 CollabNet. All rights reserved.
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.
17 ######################################################################
19 # General modules
20 import string, sys, os, re
22 # Our testing module
23 import svntest
25 # (abbreviation)
26 Skip = svntest.testcase.Skip
27 SkipUnless = svntest.testcase.SkipUnless
28 XFail = svntest.testcase.XFail
29 Item = svntest.wc.StateItem
32 ######################################################################
33 # Utilities
36 def mod_all_files(wc_dir, new_text):
37 """Walk over working copy WC_DIR, appending NEW_TEXT to all the
38 files in that tree (but not inside the .svn areas of that tree)."""
40 def tweak_files(new_text, dirname, names):
41 if os.path.basename(dirname) == ".svn":
42 del names[:]
43 else:
44 for name in names:
45 full_path = os.path.join(dirname, name)
46 if os.path.isfile(full_path):
47 svntest.main.file_append(full_path, new_text)
49 os.path.walk(wc_dir, tweak_files, new_text)
51 def changelist_all_files(wc_dir, name_func):
52 """Walk over working copy WC_DIR, adding versioned files to
53 changelists named by invoking NAME_FUNC(full-path-of-file) and
54 noting its string return value (or None, if we wish to remove the
55 file from a changelist)."""
57 def do_changelist(name_func, dirname, names):
58 if os.path.basename(dirname) == ".svn":
59 del names[:]
60 else:
61 for name in names:
62 full_path = os.path.join(dirname, name)
63 if os.path.isfile(full_path):
64 clname = name_func(full_path)
65 if not clname:
66 svntest.main.run_svn(None, "changelist", "--remove", full_path)
67 else:
68 svntest.main.run_svn(None, "changelist", clname, full_path)
70 os.path.walk(wc_dir, do_changelist, name_func)
72 def clname_from_lastchar_cb(full_path):
73 """Callback for changelist_all_files() that returns a changelist
74 name matching the last character in the file's name. For example,
75 after running this on a greek tree where every file has some text
76 modification, 'svn status' shows:
78 --- Changelist 'a':
79 M A/B/lambda
80 M A/B/E/alpha
81 M A/B/E/beta
82 M A/D/gamma
83 M A/D/H/omega
84 M iota
86 --- Changelist 'u':
87 M A/mu
88 M A/D/G/tau
90 --- Changelist 'i':
91 M A/D/G/pi
92 M A/D/H/chi
93 M A/D/H/psi
95 --- Changelist 'o':
96 M A/D/G/rho
97 """
98 return full_path[-1]
101 # Regular expressions for 'svn changelist' output.
102 _re_cl_add = re.compile("Path '(.*)' is now a member of changelist '(.*)'.")
103 _re_cl_rem = re.compile("Path '(.*)' is no longer a member of a changelist.")
105 def verify_changelist_output(output, expected_adds=None,
106 expected_removals=None):
107 """Compare lines of OUTPUT from 'svn changelist' against
108 EXPECTED_ADDS (a dictionary mapping paths to changelist names) and
109 EXPECTED_REMOVALS (a dictionary mapping paths to ... whatever)."""
111 num_expected = 0
112 if expected_adds:
113 num_expected += len(expected_adds)
114 if expected_removals:
115 num_expected += len(expected_removals)
117 if len(output) != num_expected:
118 raise svntest.Failure("Unexpected number of 'svn changelist' output lines")
120 for line in output:
121 line = line.rstrip()
122 match = _re_cl_rem.match(line)
123 if match \
124 and expected_removals \
125 and expected_removals.has_key(match.group(1)):
126 continue
127 elif match:
128 raise svntest.Failure("Unexpected changelist removal line: " + line)
129 match = _re_cl_add.match(line)
130 if match \
131 and expected_adds \
132 and expected_adds.get(match.group(1)) == match.group(2):
133 continue
134 elif match:
135 raise svntest.Failure("Unexpected changelist add line: " + line)
136 raise svntest.Failure("Unexpected line: " + line)
138 def verify_pget_output(output, expected_props):
139 """Compare lines of OUTPUT from 'svn propget' against EXPECTED_PROPS
140 (a dictionary mapping paths to property values)."""
142 _re_pget = re.compile('^(.*) - (.*)$')
143 actual_props = {}
144 for line in output:
145 try:
146 path, prop = line.rstrip().split(' - ')
147 except:
148 raise svntest.Failure("Unexpected output line: " + line)
149 actual_props[path] = prop
150 if expected_props != actual_props:
151 raise svntest.Failure("Got unexpected property results")
154 ######################################################################
155 # Tests
157 # Each test must return on success or raise on failure.
160 #----------------------------------------------------------------------
162 def add_remove_changelists(sbox):
163 "add and remove files from changelists"
165 sbox.build()
166 wc_dir = sbox.wc_dir
168 ### First, we play with just adding to changelists ###
170 # svn changelist foo WC_DIR
171 output, errput = svntest.main.run_svn(None, "changelist", "foo",
172 wc_dir)
173 verify_changelist_output(output) # nothing expected
175 # svn changelist foo WC_DIR --depth files
176 output, errput = svntest.main.run_svn(None, "changelist", "foo",
177 "--depth", "files",
178 wc_dir)
179 expected_adds = {
180 os.path.join(wc_dir, 'iota') : 'foo',
182 verify_changelist_output(output, expected_adds)
184 # svn changelist foo WC_DIR --depth infinity
185 output, errput = svntest.main.run_svn(None, "changelist", "foo",
186 "--depth", "infinity",
187 wc_dir)
188 expected_adds = {
189 os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') : 'foo',
190 os.path.join(wc_dir, 'A', 'B', 'E', 'beta') : 'foo',
191 os.path.join(wc_dir, 'A', 'B', 'lambda') : 'foo',
192 os.path.join(wc_dir, 'A', 'D', 'G', 'pi') : 'foo',
193 os.path.join(wc_dir, 'A', 'D', 'G', 'rho') : 'foo',
194 os.path.join(wc_dir, 'A', 'D', 'G', 'tau') : 'foo',
195 os.path.join(wc_dir, 'A', 'D', 'H', 'chi') : 'foo',
196 os.path.join(wc_dir, 'A', 'D', 'H', 'omega') : 'foo',
197 os.path.join(wc_dir, 'A', 'D', 'H', 'psi') : 'foo',
198 os.path.join(wc_dir, 'A', 'D', 'gamma') : 'foo',
199 os.path.join(wc_dir, 'A', 'mu') : 'foo',
201 verify_changelist_output(output, expected_adds)
203 ### Now, change some changelists ###
205 # svn changelist bar WC_DIR/A/D --depth infinity
206 output, errput = svntest.main.run_svn(".*", "changelist", "bar",
207 "--depth", "infinity",
208 os.path.join(wc_dir, 'A', 'D'))
209 expected_adds = {
210 os.path.join(wc_dir, 'A', 'D', 'G', 'pi') : 'bar',
211 os.path.join(wc_dir, 'A', 'D', 'G', 'rho') : 'bar',
212 os.path.join(wc_dir, 'A', 'D', 'G', 'tau') : 'bar',
213 os.path.join(wc_dir, 'A', 'D', 'H', 'chi') : 'bar',
214 os.path.join(wc_dir, 'A', 'D', 'H', 'omega') : 'bar',
215 os.path.join(wc_dir, 'A', 'D', 'H', 'psi') : 'bar',
216 os.path.join(wc_dir, 'A', 'D', 'gamma') : 'bar',
218 verify_changelist_output(output, expected_adds)
220 # svn changelist baz WC_DIR/A/D/H --depth infinity
221 output, errput = svntest.main.run_svn(".*", "changelist", "baz",
222 "--depth", "infinity",
223 os.path.join(wc_dir, 'A', 'D', 'H'))
224 expected_adds = {
225 os.path.join(wc_dir, 'A', 'D', 'H', 'chi') : 'baz',
226 os.path.join(wc_dir, 'A', 'D', 'H', 'omega') : 'baz',
227 os.path.join(wc_dir, 'A', 'D', 'H', 'psi') : 'baz',
229 verify_changelist_output(output, expected_adds)
231 ### Now, let's selectively rename some changelists ###
233 # svn changelist foo-rename WC_DIR --depth infinity --changelist foo
234 output, errput = svntest.main.run_svn(".*", "changelist", "foo-rename",
235 "--depth", "infinity",
236 "--changelist", "foo",
237 wc_dir)
238 expected_adds = {
239 os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') : 'foo-rename',
240 os.path.join(wc_dir, 'A', 'B', 'E', 'beta') : 'foo-rename',
241 os.path.join(wc_dir, 'A', 'B', 'lambda') : 'foo-rename',
242 os.path.join(wc_dir, 'A', 'mu') : 'foo-rename',
243 os.path.join(wc_dir, 'iota') : 'foo-rename',
245 verify_changelist_output(output, expected_adds)
247 # svn changelist bar WC_DIR --depth infinity
248 # --changelist foo-rename --changelist baz
249 output, errput = svntest.main.run_svn(".*", "changelist", "bar",
250 "--depth", "infinity",
251 "--changelist", "foo-rename",
252 "--changelist", "baz",
253 wc_dir)
254 expected_adds = {
255 os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') : 'bar',
256 os.path.join(wc_dir, 'A', 'B', 'E', 'beta') : 'bar',
257 os.path.join(wc_dir, 'A', 'B', 'lambda') : 'bar',
258 os.path.join(wc_dir, 'A', 'D', 'H', 'chi') : 'bar',
259 os.path.join(wc_dir, 'A', 'D', 'H', 'omega') : 'bar',
260 os.path.join(wc_dir, 'A', 'D', 'H', 'psi') : 'bar',
261 os.path.join(wc_dir, 'A', 'mu') : 'bar',
262 os.path.join(wc_dir, 'iota') : 'bar',
264 verify_changelist_output(output, expected_adds)
266 ### Okay. Time to remove some stuff from changelists now. ###
268 # svn changelist --remove WC_DIR
269 output, errput = svntest.main.run_svn(None, "changelist", "--remove",
270 wc_dir)
271 verify_changelist_output(output) # nothing expected
273 # svn changelist --remove WC_DIR --depth files
274 output, errput = svntest.main.run_svn(None, "changelist", "--remove",
275 "--depth", "files",
276 wc_dir)
277 expected_removals = {
278 os.path.join(wc_dir, 'iota') : None,
280 verify_changelist_output(output, None, expected_removals)
282 # svn changelist --remove WC_DIR --depth infinity
283 output, errput = svntest.main.run_svn(None, "changelist", "--remove",
284 "--depth", "infinity",
285 wc_dir)
286 expected_removals = {
287 os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') : None,
288 os.path.join(wc_dir, 'A', 'B', 'E', 'beta') : None,
289 os.path.join(wc_dir, 'A', 'B', 'lambda') : None,
290 os.path.join(wc_dir, 'A', 'D', 'G', 'pi') : None,
291 os.path.join(wc_dir, 'A', 'D', 'G', 'rho') : None,
292 os.path.join(wc_dir, 'A', 'D', 'G', 'tau') : None,
293 os.path.join(wc_dir, 'A', 'D', 'H', 'chi') : None,
294 os.path.join(wc_dir, 'A', 'D', 'H', 'omega') : None,
295 os.path.join(wc_dir, 'A', 'D', 'H', 'psi') : None,
296 os.path.join(wc_dir, 'A', 'D', 'gamma') : None,
297 os.path.join(wc_dir, 'A', 'mu') : None,
299 verify_changelist_output(output, None, expected_removals)
301 ### Add files to changelists based on the last character in their names ###
303 changelist_all_files(wc_dir, clname_from_lastchar_cb)
305 ### Now, do selective changelist removal ###
307 # svn changelist --remove WC_DIR --depth infinity --changelist a
308 output, errput = svntest.main.run_svn(None, "changelist", "--remove",
309 "--depth", "infinity",
310 "--changelist", "a",
311 wc_dir)
312 expected_removals = {
313 os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') : None,
314 os.path.join(wc_dir, 'A', 'B', 'E', 'beta') : None,
315 os.path.join(wc_dir, 'A', 'B', 'lambda') : None,
316 os.path.join(wc_dir, 'A', 'D', 'H', 'omega') : None,
317 os.path.join(wc_dir, 'A', 'D', 'gamma') : None,
318 os.path.join(wc_dir, 'iota') : None,
320 verify_changelist_output(output, None, expected_removals)
322 # svn changelist --remove WC_DIR --depth infinity
323 # --changelist i --changelist o
324 output, errput = svntest.main.run_svn(None, "changelist", "--remove",
325 "--depth", "infinity",
326 "--changelist", "i",
327 "--changelist", "o",
328 wc_dir)
329 expected_removals = {
330 os.path.join(wc_dir, 'A', 'D', 'G', 'pi') : None,
331 os.path.join(wc_dir, 'A', 'D', 'G', 'rho') : None,
332 os.path.join(wc_dir, 'A', 'D', 'H', 'chi') : None,
333 os.path.join(wc_dir, 'A', 'D', 'H', 'psi') : None,
335 verify_changelist_output(output, None, expected_removals)
337 #----------------------------------------------------------------------
339 def commit_one_changelist(sbox):
340 "commit with single --changelist"
342 sbox.build()
343 wc_dir = sbox.wc_dir
345 # Add a line of text to all the versioned files in the tree.
346 mod_all_files(wc_dir, "New text.\n")
348 # Add files to changelists based on the last character in their names.
349 changelist_all_files(wc_dir, clname_from_lastchar_cb)
351 # Now, test a commit that uses a single changelist filter (--changelist a).
352 expected_output = svntest.wc.State(wc_dir, {
353 'A/B/lambda' : Item(verb='Sending'),
354 'A/B/E/alpha' : Item(verb='Sending'),
355 'A/B/E/beta' : Item(verb='Sending'),
356 'A/D/gamma' : Item(verb='Sending'),
357 'A/D/H/omega' : Item(verb='Sending'),
358 'iota' : Item(verb='Sending'),
360 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
361 expected_status.tweak('A/mu', 'A/D/G/tau', 'A/D/G/pi', 'A/D/H/chi',
362 'A/D/H/psi', 'A/D/G/rho', wc_rev=1, status='M ')
363 expected_status.tweak('iota', 'A/B/lambda', 'A/B/E/alpha', 'A/B/E/beta',
364 'A/D/gamma', 'A/D/H/omega', wc_rev=2, status=' ')
365 svntest.actions.run_and_verify_commit(wc_dir,
366 expected_output,
367 expected_status,
368 None,
369 wc_dir,
370 "--changelist",
371 "a")
373 #----------------------------------------------------------------------
375 def commit_multiple_changelists(sbox):
376 "commit with multiple --changelist's"
378 sbox.build()
379 wc_dir = sbox.wc_dir
381 # Add a line of text to all the versioned files in the tree.
382 mod_all_files(wc_dir, "New text.\n")
384 # Add files to changelists based on the last character in their names.
385 changelist_all_files(wc_dir, clname_from_lastchar_cb)
387 # Now, test a commit that uses multiple changelist filters
388 # (--changelist=a --changelist=i).
389 expected_output = svntest.wc.State(wc_dir, {
390 'A/B/lambda' : Item(verb='Sending'),
391 'A/B/E/alpha' : Item(verb='Sending'),
392 'A/B/E/beta' : Item(verb='Sending'),
393 'A/D/gamma' : Item(verb='Sending'),
394 'A/D/H/omega' : Item(verb='Sending'),
395 'iota' : Item(verb='Sending'),
396 'A/D/G/pi' : Item(verb='Sending'),
397 'A/D/H/chi' : Item(verb='Sending'),
398 'A/D/H/psi' : Item(verb='Sending'),
400 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
401 expected_status.tweak('A/mu', 'A/D/G/tau', 'A/D/G/rho',
402 wc_rev=1, status='M ')
403 expected_status.tweak('iota', 'A/B/lambda', 'A/B/E/alpha', 'A/B/E/beta',
404 'A/D/gamma', 'A/D/H/omega', 'A/D/G/pi', 'A/D/H/chi',
405 'A/D/H/psi', wc_rev=2, status=' ')
406 svntest.actions.run_and_verify_commit(wc_dir,
407 expected_output,
408 expected_status,
409 None,
410 wc_dir,
411 "--changelist", "a",
412 "--changelist", "i")
414 #----------------------------------------------------------------------
416 def info_with_changelists(sbox):
417 "info --changelist"
419 sbox.build()
420 wc_dir = sbox.wc_dir
422 # Add files to changelists based on the last character in their names.
423 changelist_all_files(wc_dir, clname_from_lastchar_cb)
425 # Now, test various combinations of changelist specification and depths.
426 for clname in [['a'], ['i'], ['a', 'i']]:
427 for depth in [None, 'files', 'infinity']:
429 # Figure out what we expect to see in our info output.
430 expected_paths = []
431 if 'a' in clname:
432 if depth == 'infinity':
433 expected_paths.append('A/B/lambda')
434 expected_paths.append('A/B/E/alpha')
435 expected_paths.append('A/B/E/beta')
436 expected_paths.append('A/D/gamma')
437 expected_paths.append('A/D/H/omega')
438 if depth == 'files' or depth == 'infinity':
439 expected_paths.append('iota')
440 if 'i' in clname:
441 if depth == 'infinity':
442 expected_paths.append('A/D/G/pi')
443 expected_paths.append('A/D/H/chi')
444 expected_paths.append('A/D/H/psi')
445 expected_paths = map(lambda x:
446 os.path.join(wc_dir, x.replace('/', os.sep)),
447 expected_paths)
448 expected_paths.sort()
450 # Build the command line.
451 args = ['info', wc_dir]
452 for cl in clname:
453 args.append('--changelist')
454 args.append(cl)
455 if depth:
456 args.append('--depth')
457 args.append(depth)
459 # Run 'svn info ...'
460 output, errput = svntest.main.run_svn(None, *args)
462 # Filter the output for lines that begin with 'Path:', and
463 # reduce even those lines to just the actual path.
464 def startswith_path(line):
465 return line[:6] == 'Path: ' and 1 or 0
466 paths = map(lambda x: x[6:].rstrip(), filter(startswith_path, output))
467 paths.sort()
469 # And, compare!
470 if (paths != expected_paths):
471 raise svntest.Failure("Expected paths (%s) and actual paths (%s) "
472 "don't gel" % (str(expected_paths), str(paths)))
474 #----------------------------------------------------------------------
476 def diff_with_changelists(sbox):
477 "diff --changelist (wc-wc and repos-wc)"
479 sbox.build()
480 wc_dir = sbox.wc_dir
482 # Add a line of text to all the versioned files in the tree.
483 mod_all_files(wc_dir, "New text.\n")
485 # Add files to changelists based on the last character in their names.
486 changelist_all_files(wc_dir, clname_from_lastchar_cb)
488 # Now, test various combinations of changelist specification and depths.
489 for is_repos_wc in [0, 1]:
490 for clname in [['a'], ['i'], ['a', 'i']]:
491 for depth in ['files', 'infinity']:
493 # Figure out what we expect to see in our diff output.
494 expected_paths = []
495 if 'a' in clname:
496 if depth == 'infinity':
497 expected_paths.append('A/B/lambda')
498 expected_paths.append('A/B/E/alpha')
499 expected_paths.append('A/B/E/beta')
500 expected_paths.append('A/D/gamma')
501 expected_paths.append('A/D/H/omega')
502 if depth == 'files' or depth == 'infinity':
503 expected_paths.append('iota')
504 if 'i' in clname:
505 if depth == 'infinity':
506 expected_paths.append('A/D/G/pi')
507 expected_paths.append('A/D/H/chi')
508 expected_paths.append('A/D/H/psi')
509 expected_paths = map(lambda x:
510 os.path.join(wc_dir, x.replace('/', os.sep)),
511 expected_paths)
512 expected_paths.sort()
514 # Build the command line.
515 args = ['diff']
516 for cl in clname:
517 args.append('--changelist')
518 args.append(cl)
519 if depth:
520 args.append('--depth')
521 args.append(depth)
522 if is_repos_wc:
523 args.append('--old')
524 args.append(sbox.repo_url)
525 args.append('--new')
526 args.append(sbox.wc_dir)
527 else:
528 args.append(wc_dir)
530 # Run 'svn diff ...'
531 output, errput = svntest.main.run_svn(None, *args)
533 # Filter the output for lines that begin with 'Index:', and
534 # reduce even those lines to just the actual path.
535 def startswith_path(line):
536 return line[:7] == 'Index: ' and 1 or 0
537 paths = map(lambda x: x[7:].rstrip(), filter(startswith_path, output))
538 paths.sort()
540 # Diff output on Win32 uses '/' path separators.
541 if sys.platform == 'win32':
542 paths = map(lambda x:
543 x.replace('/', os.sep),
544 paths)
546 # And, compare!
547 if (paths != expected_paths):
548 raise svntest.Failure("Expected paths (%s) and actual paths (%s) "
549 "don't gel"
550 % (str(expected_paths), str(paths)))
552 #----------------------------------------------------------------------
554 def propmods_with_changelists(sbox):
555 "propset/del/get --changelist"
557 sbox.build()
558 wc_dir = sbox.wc_dir
560 # Add files to changelists based on the last character in their names.
561 changelist_all_files(wc_dir, clname_from_lastchar_cb)
563 # Set property 'name'='value' on all working copy items.
564 svntest.main.run_svn(None, "pset", "--depth", "infinity",
565 "name", "value", wc_dir)
566 expected_disk = svntest.main.greek_state.copy()
567 expected_disk.add({'' : Item(props={ 'name' : 'value' })})
568 expected_disk.tweak('A', 'A/B', 'A/B/E', 'A/B/E/alpha', 'A/B/E/beta',
569 'A/B/F', 'A/B/lambda', 'A/C', 'A/D', 'A/D/G',
570 'A/D/G/pi', 'A/D/G/rho', 'A/D/G/tau', 'A/D/H',
571 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi', 'A/D/gamma',
572 'A/mu', 'iota', props={ 'name' : 'value' })
573 actual_disk_tree = svntest.tree.build_tree_from_wc(wc_dir, 1)
574 svntest.tree.compare_trees("disk", actual_disk_tree,
575 expected_disk.old_tree())
577 # Remove the 'name' property from files in the 'o' and 'i' changelists.
578 svntest.main.run_svn(None, "pdel", "--depth", "infinity",
579 "name", "--changelist", "o", "--changelist", "i",
580 wc_dir)
581 expected_disk.tweak('A/D/G/pi', 'A/D/G/rho', 'A/D/H/chi', 'A/D/H/psi',
582 props={})
583 actual_disk_tree = svntest.tree.build_tree_from_wc(wc_dir, 1)
584 svntest.tree.compare_trees("disk", actual_disk_tree,
585 expected_disk.old_tree())
587 # Add 'foo'='bar' property on all files under A/B to depth files and
588 # in changelist 'a'.
589 svntest.main.run_svn(None, "pset", "--depth", "files",
590 "foo", "bar", "--changelist", "a",
591 os.path.join(wc_dir, 'A', 'B'))
592 expected_disk.tweak('A/B/lambda', props={ 'name' : 'value',
593 'foo' : 'bar' })
594 actual_disk_tree = svntest.tree.build_tree_from_wc(wc_dir, 1)
595 svntest.tree.compare_trees("disk", actual_disk_tree,
596 expected_disk.old_tree())
598 # Add 'bloo'='blarg' property to all files in changelist 'a'.
599 svntest.main.run_svn(None, "pset", "--depth", "infinity",
600 "bloo", "blarg", "--changelist", "a",
601 wc_dir)
602 expected_disk.tweak('A/B/lambda', props={ 'name' : 'value',
603 'foo' : 'bar',
604 'bloo' : 'blarg' })
605 expected_disk.tweak('A/B/E/alpha', 'A/B/E/beta', 'A/D/H/omega', 'A/D/gamma',
606 'iota', props={ 'name' : 'value',
607 'bloo' : 'blarg' })
608 actual_disk_tree = svntest.tree.build_tree_from_wc(wc_dir, 1)
609 svntest.tree.compare_trees("disk", actual_disk_tree,
610 expected_disk.old_tree())
612 # Propget 'name' in files in changelists 'a' and 'i' to depth files.
613 output, errput = svntest.main.run_svn(None, "pget",
614 "--depth", "files", "name",
615 "--changelist", "a",
616 "--changelist", "i",
617 wc_dir)
618 verify_pget_output(output, {
619 os.path.join(wc_dir, 'iota') : 'value',
622 # Propget 'name' in files in changelists 'a' and 'i' to depth infinity.
623 output, errput = svntest.main.run_svn(None, "pget",
624 "--depth", "infinity", "name",
625 "--changelist", "a",
626 "--changelist", "i",
627 wc_dir)
628 verify_pget_output(output, {
629 os.path.join(wc_dir, 'A', 'D', 'gamma') : 'value',
630 os.path.join(wc_dir, 'A', 'B', 'E', 'alpha') : 'value',
631 os.path.join(wc_dir, 'iota') : 'value',
632 os.path.join(wc_dir, 'A', 'B', 'E', 'beta') : 'value',
633 os.path.join(wc_dir, 'A', 'B', 'lambda') : 'value',
634 os.path.join(wc_dir, 'A', 'D', 'H', 'omega') : 'value',
638 #----------------------------------------------------------------------
640 def revert_with_changelists(sbox):
641 "revert --changelist"
643 sbox.build()
644 wc_dir = sbox.wc_dir
646 # Add files to changelists based on the last character in their names.
647 changelist_all_files(wc_dir, clname_from_lastchar_cb)
649 # Add a line of text to all the versioned files in the tree.
650 mod_all_files(wc_dir, "Please, oh please, revert me!\n")
651 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
652 expected_status.tweak('A/B/lambda', 'A/B/E/alpha', 'A/B/E/beta',
653 'A/D/gamma', 'A/D/H/omega', 'iota', 'A/mu',
654 'A/D/G/tau', 'A/D/G/pi', 'A/D/H/chi',
655 'A/D/H/psi', 'A/D/G/rho', status='M ')
656 svntest.actions.run_and_verify_status(wc_dir, expected_status)
658 # 'svn revert --changelist a WC_DIR' (without depth, no change expected)
659 svntest.main.run_svn(None, "revert", "--changelist", "a", wc_dir)
660 svntest.actions.run_and_verify_status(wc_dir, expected_status)
662 # 'svn revert --changelist o --depth files WC_DIR WC_DIR/A/B' (no change)
663 svntest.main.run_svn(None, "revert", "--depth", "files",
664 "--changelist", "o",
665 wc_dir, os.path.join(wc_dir, 'A', 'B'))
666 svntest.actions.run_and_verify_status(wc_dir, expected_status)
668 # 'svn revert --changelist a --depth files WC_DIR WC_DIR/A/B'
669 # (iota, lambda reverted)
670 svntest.main.run_svn(None, "revert", "--depth", "files",
671 "--changelist", "a",
672 wc_dir, os.path.join(wc_dir, 'A', 'B'))
673 expected_status.tweak('iota', 'A/B/lambda', status=' ')
674 svntest.actions.run_and_verify_status(wc_dir, expected_status)
676 # 'svn revert --changelist a --changelist i --depth infinity WC_DIR'
677 # (alpha, beta, gamma, omega, pi, chi, psi reverted)
678 svntest.main.run_svn(None, "revert", "--depth", "infinity",
679 "--changelist", "a", "--changelist", "i",
680 wc_dir)
681 expected_status.tweak('A/B/E/alpha', 'A/B/E/beta', 'A/D/gamma',
682 'A/D/H/omega', 'A/D/G/pi', 'A/D/H/chi',
683 'A/D/H/psi', status=' ')
684 svntest.actions.run_and_verify_status(wc_dir, expected_status)
686 # 'svn revert --depth infinity WC_DIR' (back to pristine-ness)
687 svntest.main.run_svn(None, "revert", "--depth", "infinity",
688 wc_dir)
689 expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
690 svntest.actions.run_and_verify_status(wc_dir, expected_status)
692 #----------------------------------------------------------------------
694 def update_with_changelists(sbox):
695 "update --changelist"
697 sbox.build()
698 wc_dir = sbox.wc_dir
700 # Add a line of text to all the versioned files in the tree, commit, update.
701 mod_all_files(wc_dir, "Added line.\n")
702 svntest.main.run_svn(None, "commit", "-m", "logmsg", wc_dir)
703 svntest.main.run_svn(None, "update", wc_dir)
705 # Add files to changelists based on the last character in their names.
706 changelist_all_files(wc_dir, clname_from_lastchar_cb)
708 ### Backdate only the files in the 'a' and 'i' changelists at depth
709 ### files under WC_DIR and WC_DIR/A/B.
711 # We expect update to only touch lambda and iota.
712 expected_output = svntest.wc.State(wc_dir, {
713 'A/B/lambda' : Item(status='U '),
714 'iota' : Item(status='U '),
717 # Disk state should have all the files except iota and lambda
718 # carrying new text.
719 expected_disk = svntest.main.greek_state.copy()
720 expected_disk.tweak('A/B/E/alpha',
721 contents="This is the file 'alpha'.\nAdded line.\n")
722 expected_disk.tweak('A/B/E/beta',
723 contents="This is the file 'beta'.\nAdded line.\n")
724 expected_disk.tweak('A/D/gamma',
725 contents="This is the file 'gamma'.\nAdded line.\n")
726 expected_disk.tweak('A/D/H/omega',
727 contents="This is the file 'omega'.\nAdded line.\n")
728 expected_disk.tweak('A/mu',
729 contents="This is the file 'mu'.\nAdded line.\n")
730 expected_disk.tweak('A/D/G/tau',
731 contents="This is the file 'tau'.\nAdded line.\n")
732 expected_disk.tweak('A/D/G/pi',
733 contents="This is the file 'pi'.\nAdded line.\n")
734 expected_disk.tweak('A/D/H/chi',
735 contents="This is the file 'chi'.\nAdded line.\n")
736 expected_disk.tweak('A/D/H/psi',
737 contents="This is the file 'psi'.\nAdded line.\n")
738 expected_disk.tweak('A/D/G/rho',
739 contents="This is the file 'rho'.\nAdded line.\n")
741 # Status is clean, but with iota and lambda at r1 and all else at r2.
742 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
743 expected_status.tweak('iota', 'A/B/lambda', wc_rev=1)
745 # Update.
746 svntest.actions.run_and_verify_update(wc_dir,
747 expected_output,
748 expected_disk,
749 expected_status,
750 None, None, None,
751 None, None, 1,
752 "-r", "1",
753 "--changelist", "a",
754 "--changelist", "i",
755 "--depth", "files",
756 wc_dir,
757 os.path.join(wc_dir, 'A', 'B'))
759 ### Backdate to depth infinity all changelists "a", "i", and "o" now.
761 # We expect update to only touch all the files ending in 'a', 'i',
762 # and 'o' (except lambda and iota which were previously updated).
763 expected_output = svntest.wc.State(wc_dir, {
764 'A/D/G/pi' : Item(status='U '),
765 'A/D/H/chi' : Item(status='U '),
766 'A/D/H/psi' : Item(status='U '),
767 'A/D/G/rho' : Item(status='U '),
768 'A/B/E/alpha' : Item(status='U '),
769 'A/B/E/beta' : Item(status='U '),
770 'A/D/gamma' : Item(status='U '),
771 'A/D/H/omega' : Item(status='U '),
774 # Disk state should have only tau and mu carrying new text.
775 expected_disk = svntest.main.greek_state.copy()
776 expected_disk.tweak('A/mu',
777 contents="This is the file 'mu'.\nAdded line.\n")
778 expected_disk.tweak('A/D/G/tau',
779 contents="This is the file 'tau'.\nAdded line.\n")
781 # Status is clean, but with iota and lambda at r1 and all else at r2.
782 expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
783 expected_status.tweak('iota', 'A/B/lambda', 'A/D/G/pi', 'A/D/H/chi',
784 'A/D/H/psi', 'A/D/G/rho', 'A/B/E/alpha',
785 'A/B/E/beta', 'A/D/gamma', 'A/D/H/omega', wc_rev=1)
787 # Update.
788 svntest.actions.run_and_verify_update(wc_dir,
789 expected_output,
790 expected_disk,
791 expected_status,
792 None, None, None,
793 None, None, 1,
794 "-r", "1",
795 "--changelist", "a",
796 "--changelist", "i",
797 "--changelist", "o",
798 "--depth", "infinity",
799 wc_dir)
802 ########################################################################
803 # Run the tests
805 # list all tests here, starting with None:
806 test_list = [ None,
807 add_remove_changelists,
808 commit_one_changelist,
809 commit_multiple_changelists,
810 info_with_changelists,
811 diff_with_changelists,
812 propmods_with_changelists,
813 revert_with_changelists,
814 update_with_changelists,
817 if __name__ == '__main__':
818 svntest.main.run_tests(test_list)
819 # NOTREACHED
822 ### End of file.