1#!/usr/bin/env python
2#
3#  cat_tests.py:  testing cat cases.
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
34# (abbreviation)
35Skip = svntest.testcase.Skip_deco
36SkipUnless = svntest.testcase.SkipUnless_deco
37XFail = svntest.testcase.XFail_deco
38Issues = svntest.testcase.Issues_deco
39Issue = svntest.testcase.Issue_deco
40Wimp = svntest.testcase.Wimp_deco
41Item = svntest.wc.StateItem
42
43
44######################################################################
45# Tests
46#
47#   Each test must return on success or raise on failure.
48
49
50#----------------------------------------------------------------------
51
52def cat_local_directory(sbox):
53  "cat a local directory"
54  sbox.build(read_only = True)
55
56  A_path = os.path.join(sbox.wc_dir, 'A')
57
58  expected_err = "svn: warning: W195007: '" + \
59                 re.escape(os.path.abspath(A_path)) + \
60                 "' refers to a directory"
61
62  svntest.actions.run_and_verify_svn2(None, expected_err,
63                                      1, 'cat', A_path)
64
65def cat_remote_directory(sbox):
66  "cat a remote directory"
67  sbox.build(create_wc = False, read_only = True)
68
69  A_url = sbox.repo_url + '/A'
70  expected_err = "svn: warning: W195007: URL '" + A_url + \
71      "' refers to a directory\n.*"
72
73  svntest.actions.run_and_verify_svn2(None, expected_err,
74                                      1, 'cat', A_url)
75
76def cat_base(sbox):
77  "cat a file at revision BASE"
78  sbox.build(read_only = True)
79
80  wc_dir = sbox.wc_dir
81
82  mu_path = os.path.join(wc_dir, 'A', 'mu')
83  svntest.main.file_append(mu_path, 'Appended text')
84
85  exit_code, outlines, errlines = svntest.main.run_svn(0, 'cat', mu_path)
86
87  # Verify the expected output
88  expected_output = svntest.main.greek_state.desc['A/mu'].contents
89  if len(outlines) != 1 or outlines[0] != expected_output:
90    raise svntest.Failure('Cat failed: expected "%s", but received "%s"' % \
91      (expected_output, outlines))
92
93def cat_nonexistent_file(sbox):
94  "cat a nonexistent file"
95  sbox.build(read_only = True)
96
97  wc_dir = sbox.wc_dir
98
99  bogus_path = os.path.join(wc_dir, 'A', 'bogus')
100  expected_err = "svn: warning: W200005: '" + \
101                 re.escape(os.path.abspath(bogus_path)) + \
102                 "' is not under version control"
103
104  svntest.actions.run_and_verify_svn2(None, expected_err, 1,
105                                      'cat', bogus_path)
106
107def cat_skip_uncattable(sbox):
108  "cat should skip uncattable resources"
109  sbox.build(read_only = True)
110
111  wc_dir = sbox.wc_dir
112  dir_path = os.path.join(wc_dir, 'A', 'D')
113  new_file_path = os.path.join(dir_path, 'new')
114  open(new_file_path, 'w')
115  item_list = os.listdir(dir_path)
116
117  # First we test running 'svn cat' on individual objects, expecting
118  # warnings for unversioned files and for directories.  Then we try
119  # running 'svn cat' on multiple targets at once, and make sure we
120  # get the warnings we expect.
121
122  # item_list has all the files and directories under 'dir_path'
123  for file in item_list:
124    if file == svntest.main.get_admin_name():
125      continue
126    item_to_cat = os.path.join(dir_path, file)
127    if item_to_cat == new_file_path:
128      expected_err = "svn: warning: W200005: '" + \
129                     re.escape(os.path.abspath(item_to_cat)) + \
130                     "' is not under version control"
131      svntest.actions.run_and_verify_svn2(None, expected_err, 1,
132                                           'cat', item_to_cat)
133
134    elif os.path.isdir(item_to_cat):
135      expected_err = "svn: warning: W195007: '" + \
136                     re.escape(os.path.abspath(item_to_cat)) + \
137                     "' refers to a directory"
138      svntest.actions.run_and_verify_svn2(None, expected_err, 1,
139                                           'cat', item_to_cat)
140    else:
141      svntest.actions.run_and_verify_svn(["This is the file '"+file+"'.\n"],
142                                         [], 'cat', item_to_cat)
143
144  G_path = os.path.join(dir_path, 'G')
145  rho_path = os.path.join(G_path, 'rho')
146
147  expected_out = "This is the file 'rho'.\n"
148  expected_err1 = "svn: warning: W195007: '" + \
149                  re.escape(os.path.abspath(G_path)) + \
150                  "' refers to a directory\n"
151  svntest.actions.run_and_verify_svn2(expected_out, expected_err1, 1,
152                                       'cat', rho_path, G_path)
153
154  expected_err2 = "svn: warning: W200005: '" + \
155                  re.escape(os.path.abspath(new_file_path)) + \
156                  "' is not under version control\n"
157  svntest.actions.run_and_verify_svn2(expected_out, expected_err2, 1,
158                                       'cat', rho_path, new_file_path)
159
160  expected_err3 = expected_err1 + expected_err2 + \
161      ".*svn: E200009: Could not cat all targets because some targets"
162  expected_err_re = re.compile(expected_err3, re.DOTALL)
163
164  exit_code, output, error = svntest.main.run_svn(1, 'cat', rho_path, G_path, new_file_path)
165  error = [line for line in error
166           if not re.compile(svntest.main.stack_trace_regexp).match(line)]
167
168  # Verify output
169  if output[0] != expected_out:
170    raise svntest.Failure('Cat failed: expected "%s", but received "%s"' % \
171                          (expected_out, "".join(output)))
172
173  # Verify error
174  if not expected_err_re.match("".join(error)):
175    raise svntest.Failure('Cat failed: expected error "%s", but received "%s"' % \
176                          (expected_err3, "".join(error)))
177
178# Test for issue #3560 'svn_wc_status3() returns incorrect status for
179# unversioned files'.
180@Issue(3560)
181def cat_unversioned_file(sbox):
182  "cat an unversioned file parent dir thinks exists"
183  sbox.build()
184  wc_dir = sbox.wc_dir
185  iota_path = os.path.join(wc_dir, 'iota')
186
187  # Delete a file an commit the deletion.
188  svntest.actions.run_and_verify_svn2(None, [], 0,
189                                      'delete', iota_path)
190  svntest.actions.run_and_verify_svn2(None, [], 0,
191                                      'commit', '-m', 'delete a file',
192                                      iota_path)
193
194  # Now try to cat the deleted file, it should be reported as unversioned.
195  expected_error = "svn: warning: W200005: '" + \
196                   re.escape(os.path.abspath(iota_path)) + \
197                   "' is not under version control"
198  svntest.actions.run_and_verify_svn2([], expected_error, 1,
199                                       'cat', iota_path)
200
201  # Put an unversioned file at 'iota' and try to cat it again, the result
202  # should still be the same.
203  svntest.main.file_write(iota_path, "This the unversioned file 'iota'.\n")
204  svntest.actions.run_and_verify_svn2([], expected_error, 1,
205                                      'cat', iota_path)
206
207def cat_keywords(sbox):
208  "cat a file with the svn:keywords property"
209  sbox.build()
210  wc_dir = sbox.wc_dir
211  iota_path = os.path.join(wc_dir, 'iota')
212
213  svntest.actions.run_and_verify_svn(["This is the file 'iota'.\n"],
214                                     [], 'cat', iota_path)
215
216  svntest.main.file_append(iota_path, "$Revision$\n")
217  svntest.actions.run_and_verify_svn(None, [],
218                                     'propset', 'svn:keywords', 'Revision',
219                                     iota_path)
220
221  svntest.actions.run_and_verify_svn(None, [],
222                                     'ci', '-m', 'r2', wc_dir)
223
224  svntest.actions.run_and_verify_svn(["This is the file 'iota'.\n", "$Revision: 2 $\n"],
225                                     [], 'cat', iota_path)
226
227def cat_url_special_characters(sbox):
228  """special characters in svn cat URL"""
229  sbox.build(create_wc = False)
230  wc_dir = sbox.wc_dir
231
232  special_urls = [sbox.repo_url + '/A' + '/%2E',
233                  sbox.repo_url + '%2F' + 'A']
234
235  expected_err = "svn: warning: W195007: URL '" + sbox.repo_url + '/A' + \
236      "' refers to a directory\n.*"
237
238  for url in special_urls:
239    svntest.actions.run_and_verify_svn2(None, expected_err, 1,
240                                         'cat', url)
241
242def cat_non_existing_remote_file(sbox):
243  """cat non-existing remote file"""
244  sbox.build(create_wc = False)
245  non_existing_path = sbox.repo_url + '/non-existing'
246
247  expected_err = "svn: warning: W160013: .*not found.*" + \
248      non_existing_path.split('/')[1]
249
250  # cat operation on non-existing remote path should return 1
251  svntest.actions.run_and_verify_svn2(None, expected_err, 1,
252                                      'cat', non_existing_path)
253
254########################################################################
255# Run the tests
256
257
258# list all tests here, starting with None:
259test_list = [ None,
260              cat_local_directory,
261              cat_remote_directory,
262              cat_base,
263              cat_nonexistent_file,
264              cat_skip_uncattable,
265              cat_unversioned_file,
266              cat_keywords,
267              cat_url_special_characters,
268              cat_non_existing_remote_file,
269             ]
270
271if __name__ == '__main__':
272  svntest.main.run_tests(test_list)
273  # NOTREACHED
274
275
276### End of file.
277