1#!/usr/bin/env python
2#
3#  redirect_tests.py:  Test ra_dav handling of server-side redirects
4#
5#  Subversion is a tool for revision control.
6#  See http://subversion.apache.org for more information.
7#
8# ====================================================================
9#    Licensed to the Apache Software Foundation (ASF) under one
10#    or more contributor license agreements.  See the NOTICE file
11#    distributed with this work for additional information
12#    regarding copyright ownership.  The ASF licenses this file
13#    to you under the Apache License, Version 2.0 (the
14#    "License"); you may not use this file except in compliance
15#    with the License.  You may obtain a copy of the License at
16#
17#      http://www.apache.org/licenses/LICENSE-2.0
18#
19#    Unless required by applicable law or agreed to in writing,
20#    software distributed under the License is distributed on an
21#    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
22#    KIND, either express or implied.  See the License for the
23#    specific language governing permissions and limitations
24#    under the License.
25######################################################################
26
27# General modules
28import os, re
29
30# Our testing module
31import svntest
32
33# (abbreviations)
34Skip = svntest.testcase.Skip_deco
35SkipUnless = svntest.testcase.SkipUnless_deco
36XFail = svntest.testcase.XFail_deco
37Issues = svntest.testcase.Issues_deco
38Issue = svntest.testcase.Issue_deco
39Wimp = svntest.testcase.Wimp_deco
40
41# Regular expression which matches the redirection notification
42redirect_regex = re.compile(r"^Redirecting to URL '.*'")
43
44# Generic UUID-matching regular expression
45uuid_regex = re.compile(r"[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}")
46
47
48def verify_url(wc_path, url, wc_path_is_file=False):
49  # check that we have a Repository Root and Repository UUID
50  name = os.path.basename(wc_path)
51  expected = {'Path' : re.escape(wc_path),
52              'URL' : url,
53              'Repository Root' : '.*',
54              'Revision' : '.*',
55              'Node Kind' : 'directory',
56              'Repository UUID' : uuid_regex,
57             }
58  if wc_path_is_file:
59    expected.update({'Name' : name,
60                     'Node Kind' : 'file',
61                     })
62  svntest.actions.run_and_verify_info([expected], wc_path)
63
64
65######################################################################
66# Tests
67#
68#   Each test must return on success or raise on failure.
69
70#----------------------------------------------------------------------
71@SkipUnless(svntest.main.is_ra_type_dav)
72def temporary_redirect(sbox):
73  "temporary redirect should error out"
74
75  sbox.build(create_wc=False)
76  wc_dir = sbox.add_wc_path("my")
77  co_url = sbox.redirected_root_url(temporary=True)
78
79  # Try various actions against the repository, expecting an error
80  # that indicates that some relocation has occurred.
81  exit_code, out, err = svntest.main.run_svn('.*moved temporarily.*',
82                                             'info', co_url)
83  exit_code, out, err = svntest.main.run_svn('.*moved temporarily.*',
84                                             'co', co_url, wc_dir)
85  exit_code, out, err = svntest.main.run_svn('.*moved temporarily.*',
86                                             'mkdir', '-m', 'MKDIR',
87                                             co_url + '/newdir')
88  exit_code, out, err = svntest.main.run_svn('.*moved temporarily.*',
89                                             'delete', '-m', 'DELETE',
90                                             co_url + '/iota')
91
92#----------------------------------------------------------------------
93@SkipUnless(svntest.main.is_ra_type_dav)
94def redirected_checkout(sbox):
95  "redirected checkout"
96
97  sbox.build(create_wc=False)
98  wc_dir = sbox.add_wc_path("my")
99  co_url = sbox.redirected_root_url()
100
101  # Checkout the working copy via its redirect URL
102  exit_code, out, err = svntest.main.run_svn(None, 'co', co_url, wc_dir)
103  if err:
104    raise svntest.Failure
105  if not redirect_regex.match(out[0]):
106    raise svntest.Failure
107
108  # Verify that we have the expected URL.
109  verify_url(wc_dir, sbox.repo_url)
110
111#----------------------------------------------------------------------
112@SkipUnless(svntest.main.is_ra_type_dav)
113def redirected_update(sbox):
114  "redirected update"
115
116  sbox.build()
117  wc_dir = sbox.wc_dir
118  relocate_url = sbox.redirected_root_url()
119
120  # Relocate (by cheating) the working copy to the redirect URL.  When
121  # we then update, we'll expect to find ourselves automagically back
122  # to the original URL.  (This is because we can't easily introduce a
123  # redirect to the Apache configuration from the test suite here.)
124  svntest.actions.no_relocate_validation()
125  exit_code, out, err = svntest.main.run_svn(None, 'sw', '--relocate',
126                                             sbox.repo_url, relocate_url,
127                                             wc_dir)
128  svntest.actions.do_relocate_validation()
129
130  # Now update the working copy.
131  exit_code, out, err = svntest.main.run_svn(None, 'up', wc_dir)
132  if err:
133    raise svntest.Failure
134  if not re.match("^Updating '.*':", out[0]):
135    raise svntest.Failure
136  if not redirect_regex.match(out[1]):
137    raise svntest.Failure
138
139  # Verify that we have the expected URL.
140  verify_url(wc_dir, sbox.repo_url)
141
142#----------------------------------------------------------------------
143@SkipUnless(svntest.main.is_ra_type_dav)
144def redirected_nonroot_update(sbox):
145  "redirected update of non-repos-root wc"
146
147  sbox.build(create_wc=False)
148  wc_dir = sbox.wc_dir
149  checkout_url = sbox.repo_url + '/A'
150  relocate_url = sbox.redirected_root_url() + '/A'
151
152  # Checkout a subdir of the repository root.
153  exit_code, out, err = svntest.main.run_svn(None, 'co',
154                                             checkout_url, wc_dir)
155  if err:
156    raise svntest.Failure
157
158  # Relocate (by cheating) the working copy to the redirect URL.  When
159  # we then update, we'll expect to find ourselves automagically back
160  # to the original URL.  (This is because we can't easily introduce a
161  # redirect to the Apache configuration from the test suite here.)
162  svntest.actions.no_relocate_validation()
163  exit_code, out, err = svntest.main.run_svn(None, 'sw', '--relocate',
164                                             checkout_url, relocate_url,
165                                             wc_dir)
166  svntest.actions.do_relocate_validation()
167
168  # Now update the working copy.
169  exit_code, out, err = svntest.main.run_svn(None, 'up', wc_dir)
170  if err:
171    raise svntest.Failure
172  if not re.match("^Updating '.*':", out[0]):
173    raise svntest.Failure
174  if not redirect_regex.match(out[1]):
175    raise svntest.Failure
176
177  # Verify that we have the expected URL.
178  verify_url(wc_dir, checkout_url)
179
180#----------------------------------------------------------------------
181@SkipUnless(svntest.main.is_ra_type_dav)
182def redirected_externals(sbox):
183  "redirected externals"
184
185  sbox.build()
186
187  sbox.simple_propset('svn:externals',
188                      '^/A/B/E/alpha fileX\n'
189                      '^/A/B/F dirX',
190                      'A/C')
191  sbox.simple_commit()
192  sbox.simple_update()
193
194  wc_dir = sbox.add_wc_path("my")
195  co_url = sbox.redirected_root_url()
196  exit_code, out, err = svntest.main.run_svn(None, 'co', co_url, wc_dir)
197  if err:
198    raise svntest.Failure
199  if not redirect_regex.match(out[0]):
200    raise svntest.Failure
201
202  verify_url(wc_dir, sbox.repo_url)
203  verify_url(sbox.ospath('A/C/fileX'), sbox.repo_url + '/A/B/E/alpha',
204             wc_path_is_file=True)
205  verify_url(sbox.ospath('A/C/dirX'), sbox.repo_url + '/A/B/F')
206
207#----------------------------------------------------------------------
208@SkipUnless(svntest.main.is_ra_type_dav)
209def redirected_copy(sbox):
210  "redirected copy"
211
212  sbox.build(create_wc=False)
213
214  # E170011 = SVN_ERR_RA_SESSION_URL_MISMATCH
215  expected_error = "svn: E170011: Repository moved permanently"
216
217  # This tests the actual copy handling
218  svntest.actions.run_and_verify_svn(None, expected_error,
219                                     'cp', '-m', 'failed copy',
220                                     sbox.redirected_root_url() + '/A',
221                                     sbox.redirected_root_url() + '/A_copied')
222
223  # This tests the cmdline handling of '^/copy-of-A'
224  svntest.actions.run_and_verify_svn(None, expected_error,
225                                     'cp', '-m', 'failed copy',
226                                     sbox.redirected_root_url() + '/A',
227                                     '^/copy-of-A')
228
229  # E170011 = SVN_ERR_RA_SESSION_URL_MISMATCH
230  expected_error = "svn: E170011: Repository moved temporarily"
231
232  # This tests the actual copy handling
233  svntest.actions.run_and_verify_svn(None, expected_error,
234                                     'cp', '-m', 'failed copy',
235                                     sbox.redirected_root_url(temporary=True) + '/A',
236                                     sbox.redirected_root_url(temporary=True) + '/A_copied')
237
238  # This tests the cmdline handling of '^/copy-of-A'
239  svntest.actions.run_and_verify_svn(None, expected_error,
240                                     'cp', '-m', 'failed copy',
241                                     sbox.redirected_root_url(temporary=True) + '/A',
242                                     '^/copy-of-A')
243#----------------------------------------------------------------------
244@SkipUnless(svntest.main.is_ra_type_dav)
245def redirected_commands(sbox):
246  "redirected commands"
247
248  sbox.build(create_wc=False)
249
250  svntest.actions.run_and_verify_svn(None, [],
251                                     'log',
252                                     sbox.redirected_root_url() + '/A')
253
254  svntest.actions.run_and_verify_svn(None, [],
255                                     'ls',
256                                     sbox.redirected_root_url() + '/A')
257
258  svntest.actions.run_and_verify_svn(None, [],
259                                     'info',
260                                     sbox.redirected_root_url() + '/A')
261
262#----------------------------------------------------------------------
263
264########################################################################
265# Run the tests
266
267# list all tests here, starting with None:
268test_list = [ None,
269              temporary_redirect,
270              redirected_checkout,
271              redirected_update,
272              redirected_nonroot_update,
273              redirected_externals,
274              redirected_copy,
275              redirected_commands,
276             ]
277
278if __name__ == '__main__':
279  svntest.main.run_tests(test_list)
280  # NOTREACHED
281
282
283### End of file.
284