Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(925)

Side by Side Diff: gslib/tests/test_naming.py

Issue 698893003: Update checked in version of gsutil to version 4.6 (Closed) Base URL: http://dart.googlecode.com/svn/third_party/gsutil/
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gslib/tests/test_mv.py ('k') | gslib/tests/test_notification.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # -*- coding: utf-8 -*-
1 # Copyright 2010 Google Inc. All Rights Reserved. 2 # Copyright 2010 Google Inc. All Rights Reserved.
2 # -*- coding: utf-8 -*-
3 # 3 #
4 # Permission is hereby granted, free of charge, to any person obtaining a 4 # Permission is hereby granted, free of charge, to any person obtaining a
5 # copy of this software and associated documentation files (the 5 # copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including 6 # "Software"), to deal in the Software without restriction, including
7 # without limitation the rights to use, copy, modify, merge, publish, dis- 7 # without limitation the rights to use, copy, modify, merge, publish, dis-
8 # tribute, sublicense, and/or sell copies of the Software, and to permit 8 # tribute, sublicense, and/or sell copies of the Software, and to permit
9 # persons to whom the Software is furnished to do so, subject to the fol- 9 # persons to whom the Software is furnished to do so, subject to the fol-
10 # lowing conditions: 10 # lowing conditions:
11 # 11 #
12 # The above copyright notice and this permission notice shall be included 12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software. 13 # in all copies or substantial portions of the Software.
14 # 14 #
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- 16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
17 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 17 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
18 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 # IN THE SOFTWARE. 21 # IN THE SOFTWARE.
22 """Tests for gsutil naming logic.
22 23
23 """Tests for gsutil naming logic.
24 The test code in this file runs against an in-memory storage service mock, 24 The test code in this file runs against an in-memory storage service mock,
25 so runs very quickly. This is valuable for testing changes that impact the 25 so runs very quickly. This is valuable for testing changes that impact the
26 naming rules, since those rules are complex and it's useful to be able to 26 naming rules, since those rules are complex and it's useful to be able to
27 make small incremental changes and rerun the tests frequently. Additional 27 make small incremental changes and rerun the tests frequently. Additional
28 end-to-end tests (which send traffic to the production Google Cloud Storage 28 end-to-end tests (which send traffic to the production Google Cloud Storage
29 service) are available via the gsutil test command. 29 service) are available via the gsutil test command.
30 """ 30 """
31 31
32 from __future__ import absolute_import
33
32 import gzip 34 import gzip
33 import os 35 import os
34 import StringIO 36 import StringIO
35 37
36 import boto 38 from gslib import copy_helper
37 from boto.exception import StorageResponseError 39 from gslib.cloud_api import NotFoundException
38 from boto import storage_uri 40 from gslib.cloud_api import ServiceException
39
40 from gslib.commands import cp
41 from gslib.exception import CommandException 41 from gslib.exception import CommandException
42 from gslib.storage_url import StorageUrlFromString
42 import gslib.tests.testcase as testcase 43 import gslib.tests.testcase as testcase
43 from gslib.tests.util import ObjectToURI as suri 44 from gslib.tests.util import ObjectToURI as suri
44 from gslib.tests.util import PerformsFileToObjectUpload 45 from gslib.tests.util import SetBotoConfigForTest
46 from gslib.util import UTF8
47
45 48
46 def _Overwrite(fp): 49 def _Overwrite(fp):
47 """Overwrite first byte in an open file and flush contents.""" 50 """Overwrite first byte in an open file and flush contents."""
48 fp.seek(0) 51 fp.seek(0)
49 fp.write('x') 52 fp.write('x')
50 fp.flush() 53 fp.flush()
51 54
55
52 def _Append(fp): 56 def _Append(fp):
53 """Append a byte at end of an open file and flush contents.""" 57 """Append a byte at end of an open file and flush contents."""
54 fp.seek(0,2) 58 fp.seek(0, 2)
55 fp.write('x') 59 fp.write('x')
56 fp.flush() 60 fp.flush()
57 61
62
63 # TODO: Re-enable PerformsFileToObjectUpload decorator on tests in this file
64 # once we refactor to a thread-safe mock storage service implementation.
58 class GsutilNamingTests(testcase.GsUtilUnitTestCase): 65 class GsutilNamingTests(testcase.GsUtilUnitTestCase):
59 """gsutil command method test suite""" 66 """Unit tests for gsutil naming logic."""
60 67
61 def testGetPathBeforeFinalDir(self): 68 def testGetPathBeforeFinalDir(self):
62 """Tests _GetPathBeforeFinalDir() (unit test)""" 69 """Tests GetPathBeforeFinalDir() (unit test)."""
63 self.assertEqual('gs://', 70 self.assertEqual(
64 cp._GetPathBeforeFinalDir(storage_uri('gs://bucket/'))) 71 'gs://', copy_helper.GetPathBeforeFinalDir(StorageUrlFromString(
65 self.assertEqual('gs://bucket', 72 'gs://bucket/')))
66 cp._GetPathBeforeFinalDir(storage_uri('gs://bucket/dir/'))) 73 self.assertEqual(
67 self.assertEqual('gs://bucket', 74 'gs://bucket', copy_helper.GetPathBeforeFinalDir(StorageUrlFromString(
68 cp._GetPathBeforeFinalDir(storage_uri('gs://bucket/dir'))) 75 'gs://bucket/dir/')))
69 self.assertEqual('gs://bucket/dir', 76 self.assertEqual(
70 cp._GetPathBeforeFinalDir( 77 'gs://bucket', copy_helper.GetPathBeforeFinalDir(StorageUrlFromString(
71 storage_uri('gs://bucket/dir/obj'))) 78 'gs://bucket/dir')))
79 self.assertEqual(
80 'gs://bucket/dir', copy_helper.GetPathBeforeFinalDir(
81 StorageUrlFromString('gs://bucket/dir/obj')))
72 src_dir = self.CreateTempDir() 82 src_dir = self.CreateTempDir()
73 subdir = os.path.join(src_dir, 'subdir') 83 subdir = os.path.join(src_dir, 'subdir')
74 os.mkdir(subdir) 84 os.mkdir(subdir)
75 self.assertEqual(suri(src_dir), 85 self.assertEqual(suri(src_dir),
76 cp._GetPathBeforeFinalDir(storage_uri(suri(subdir)))) 86 copy_helper.GetPathBeforeFinalDir(
87 StorageUrlFromString(suri(subdir))))
77 88
78 @PerformsFileToObjectUpload 89 # @PerformsFileToObjectUpload
79 def testCopyingTopLevelFileToBucket(self): 90 def testCopyingTopLevelFileToBucket(self):
80 """Tests copying one top-level file to a bucket""" 91 """Tests copying one top-level file to a bucket."""
81 src_file = self.CreateTempFile(file_name='f0') 92 src_file = self.CreateTempFile(file_name='f0')
82 dst_bucket_uri = self.CreateBucket() 93 dst_bucket_uri = self.CreateBucket()
83 self.RunCommand('cp', [src_file, suri(dst_bucket_uri)]) 94 self.RunCommand('cp', [src_file, suri(dst_bucket_uri)])
84 actual = list(self._test_wildcard_iterator( 95 actual = list(self._test_wildcard_iterator(
85 suri(dst_bucket_uri, '**')).IterUris()) 96 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
86 self.assertEqual(1, len(actual)) 97 self.assertEqual(1, len(actual))
87 self.assertEqual('f0', actual[0].object_name) 98 self.assertEqual('f0', actual[0].root_object.name)
88 99
89 @PerformsFileToObjectUpload 100 # @PerformsFileToObjectUpload
90 def testCopyingMultipleFilesToBucket(self): 101 def testCopyingMultipleFilesToBucket(self):
91 """Tests copying multiple files to a bucket""" 102 """Tests copying multiple files to a bucket."""
92 src_file0 = self.CreateTempFile(file_name='f0') 103 src_file0 = self.CreateTempFile(file_name='f0')
93 src_file1 = self.CreateTempFile(file_name='f1') 104 src_file1 = self.CreateTempFile(file_name='f1')
94 dst_bucket_uri = self.CreateBucket() 105 dst_bucket_uri = self.CreateBucket()
95 self.RunCommand('cp', [src_file0, src_file1, suri(dst_bucket_uri)]) 106 self.RunCommand('cp', [src_file0, src_file1, suri(dst_bucket_uri)])
96 actual = list(self._test_wildcard_iterator( 107 actual = set(str(u) for u in self._test_wildcard_iterator(
97 suri(dst_bucket_uri, '**')).IterUris()) 108 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
98 self.assertEqual(2, len(actual)) 109 expected = set([
99 self.assertEqual('f0', actual[0].object_name) 110 suri(dst_bucket_uri, 'f0'),
100 self.assertEqual('f1', actual[1].object_name) 111 suri(dst_bucket_uri, 'f1'),
112 ])
113 self.assertEqual(expected, actual)
101 114
102 @PerformsFileToObjectUpload 115 # @PerformsFileToObjectUpload
116 def testCopyingNestedFileToBucketSubdir(self):
117 """Tests copying a nested file to a bucket subdir.
118
119 Tests that we correctly translate local FS-specific delimiters ('\' on
120 Windows) to bucket delimiter (/).
121 """
122 tmpdir = self.CreateTempDir()
123 subdir = os.path.join(tmpdir, 'subdir')
124 os.mkdir(subdir)
125 src_file = self.CreateTempFile(tmpdir=tmpdir, file_name='obj', contents='')
126 dst_bucket_uri = self.CreateBucket()
127 # Make an object under subdir so next copy will treat subdir as a subdir.
128 self.RunCommand('cp', [src_file, suri(dst_bucket_uri, 'subdir/a')])
129 self.RunCommand('cp', [src_file, suri(dst_bucket_uri, 'subdir')])
130 actual = set(str(u) for u in self._test_wildcard_iterator(
131 suri(dst_bucket_uri, '**')).IterObjects())
132 expected = set([
133 suri(dst_bucket_uri, 'subdir', 'a'),
134 suri(dst_bucket_uri, 'subdir', 'obj'),
135 ])
136 self.assertEqual(expected, actual)
137
138 # @PerformsFileToObjectUpload
103 def testCopyingAbsolutePathDirToBucket(self): 139 def testCopyingAbsolutePathDirToBucket(self):
104 """Tests recursively copying absolute path directory to a bucket""" 140 """Tests recursively copying absolute path directory to a bucket."""
105 dst_bucket_uri = self.CreateBucket() 141 dst_bucket_uri = self.CreateBucket()
106 src_dir_root = self.CreateTempDir(test_files=[ 142 src_dir_root = self.CreateTempDir(test_files=[
107 'f0', 'f1', 'f2.txt', ('dir0', 'dir1', 'nested')]) 143 'f0', 'f1', 'f2.txt', ('dir0', 'dir1', 'nested')])
108 self.RunCommand('cp', ['-R', src_dir_root, suri(dst_bucket_uri)]) 144 self.RunCommand('cp', ['-R', src_dir_root, suri(dst_bucket_uri)])
109 actual = set(str(u) for u in self._test_wildcard_iterator( 145 actual = set(str(u) for u in self._test_wildcard_iterator(
110 suri(dst_bucket_uri, '**')).IterUris()) 146 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
111 src_tmpdir = os.path.split(src_dir_root)[1] 147 src_tmpdir = os.path.split(src_dir_root)[1]
112 expected = set([ 148 expected = set([
113 suri(dst_bucket_uri, src_tmpdir, 'f0'), 149 suri(dst_bucket_uri, src_tmpdir, 'f0'),
114 suri(dst_bucket_uri, src_tmpdir, 'f1'), 150 suri(dst_bucket_uri, src_tmpdir, 'f1'),
115 suri(dst_bucket_uri, src_tmpdir, 'f2.txt'), 151 suri(dst_bucket_uri, src_tmpdir, 'f2.txt'),
116 suri(dst_bucket_uri, src_tmpdir, 'dir0', 'dir1', 'nested')]) 152 suri(dst_bucket_uri, src_tmpdir, 'dir0', 'dir1', 'nested')])
117 self.assertEqual(expected, actual) 153 self.assertEqual(expected, actual)
118 154
119 @PerformsFileToObjectUpload 155 # @PerformsFileToObjectUpload
120 def testCopyingRelativePathDirToBucket(self): 156 def testCopyingRelativePathDirToBucket(self):
121 """Tests recursively copying relative directory to a bucket""" 157 """Tests recursively copying relative directory to a bucket."""
122 dst_bucket_uri = self.CreateBucket() 158 dst_bucket_uri = self.CreateBucket()
123 src_dir = self.CreateTempDir(test_files=[('dir0', 'f1')]) 159 src_dir = self.CreateTempDir(test_files=[('dir0', 'f1')])
124 self.RunCommand('cp', ['-R', 'dir0', suri(dst_bucket_uri)], cwd=src_dir) 160 self.RunCommand('cp', ['-R', 'dir0', suri(dst_bucket_uri)], cwd=src_dir)
125 actual = set(str(u) for u in self._test_wildcard_iterator( 161 actual = set(str(u) for u in self._test_wildcard_iterator(
126 suri(dst_bucket_uri, '**')).IterUris()) 162 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
127 expected = set([suri(dst_bucket_uri, 'dir0', 'f1')]) 163 expected = set([suri(dst_bucket_uri, 'dir0', 'f1')])
128 self.assertEqual(expected, actual) 164 self.assertEqual(expected, actual)
129 165
130 @PerformsFileToObjectUpload 166 # @PerformsFileToObjectUpload
131 def testCopyingRelPathSubDirToBucketSubdirWithDollarFolderObj(self): 167 def testCopyingRelPathSubDirToBucketSubdirWithDollarFolderObj(self):
132 """Tests recursively copying relative sub-directory to bucket subdir 168 """Tests recursively copying relative sub-directory to bucket subdir.
133 signified by a $folder$ object""" 169
170 Subdir is signified by a $folder$ object.
171 """
134 # Create a $folder$ object to simulate a folder created by GCS manager (or 172 # Create a $folder$ object to simulate a folder created by GCS manager (or
135 # various other tools), which gsutil understands to mean there is a folder 173 # various other tools), which gsutil understands to mean there is a folder
136 # into which the object is being copied. 174 # into which the object is being copied.
137 dst_bucket_uri = self.CreateBucket() 175 dst_bucket_uri = self.CreateBucket()
138 self.CreateObject(bucket_uri=dst_bucket_uri, object_name='abc_$folder$', 176 self.CreateObject(bucket_uri=dst_bucket_uri, object_name='abc_$folder$',
139 contents='') 177 contents='')
140 src_dir = self.CreateTempDir(test_files=[('dir0', 'dir1', 'f1')]) 178 src_dir = self.CreateTempDir(test_files=[('dir0', 'dir1', 'f1')])
141 self.RunCommand('cp', ['-R', os.path.join('dir0', 'dir1'), 179 self.RunCommand('cp', ['-R', os.path.join('dir0', 'dir1'),
142 suri(dst_bucket_uri, 'abc')], cwd=src_dir) 180 suri(dst_bucket_uri, 'abc')], cwd=src_dir)
143 actual = set(str(u) for u in self._test_wildcard_iterator( 181 actual = set(str(u) for u in self._test_wildcard_iterator(
144 suri(dst_bucket_uri, '**')).IterUris()) 182 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
145 expected = set([suri(dst_bucket_uri, 'abc_$folder$'), 183 expected = set([suri(dst_bucket_uri, 'abc_$folder$'),
146 suri(dst_bucket_uri, 'abc', 'dir1', 'f1')]) 184 suri(dst_bucket_uri, 'abc', 'dir1', 'f1')])
147 self.assertEqual(expected, actual) 185 self.assertEqual(expected, actual)
148 186
149 @PerformsFileToObjectUpload 187 # @PerformsFileToObjectUpload
150 def testCopyingRelativePathSubDirToBucketSubdirSignifiedBySlash(self): 188 def testCopyingRelativePathSubDirToBucketSubdirSignifiedBySlash(self):
151 """Tests recursively copying relative sub-directory to bucket subdir 189 """Tests recursively copying relative sub-directory to bucket subdir.
152 signified by a / object""" 190
191 Subdir is signified by a / object.
192 """
153 dst_bucket_uri = self.CreateBucket() 193 dst_bucket_uri = self.CreateBucket()
154 src_dir = self.CreateTempDir(test_files=[('dir0', 'dir1', 'f1')]) 194 src_dir = self.CreateTempDir(test_files=[('dir0', 'dir1', 'f1')])
155 self.RunCommand('cp', ['-R', os.path.join('dir0', 'dir1'), 195 self.RunCommand('cp', ['-R', os.path.join('dir0', 'dir1'),
156 suri(dst_bucket_uri, 'abc') + '/'], cwd=src_dir) 196 suri(dst_bucket_uri, 'abc') + '/'], cwd=src_dir)
157 actual = set(str(u) for u in self._test_wildcard_iterator( 197 actual = set(str(u) for u in self._test_wildcard_iterator(
158 suri(dst_bucket_uri, '**')).IterUris()) 198 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
159 expected = set([suri(dst_bucket_uri, 'abc', 'dir1', 'f1')]) 199 expected = set([suri(dst_bucket_uri, 'abc', 'dir1', 'f1')])
160 self.assertEqual(expected, actual) 200 self.assertEqual(expected, actual)
161 201
162 @PerformsFileToObjectUpload 202 # @PerformsFileToObjectUpload
163 def testCopyingRelativePathSubDirToBucket(self): 203 def testCopyingRelativePathSubDirToBucket(self):
164 """Tests recursively copying relative sub-directory to a bucket""" 204 """Tests recursively copying relative sub-directory to a bucket."""
165 dst_bucket_uri = self.CreateBucket() 205 dst_bucket_uri = self.CreateBucket()
166 src_dir = self.CreateTempDir(test_files=[('dir0', 'dir1', 'f1')]) 206 src_dir = self.CreateTempDir(test_files=[('dir0', 'dir1', 'f1')])
167 self.RunCommand('cp', ['-R', os.path.join('dir0', 'dir1'), 207 self.RunCommand('cp', ['-R', os.path.join('dir0', 'dir1'),
168 suri(dst_bucket_uri)], cwd=src_dir) 208 suri(dst_bucket_uri)], cwd=src_dir)
169 actual = set(str(u) for u in self._test_wildcard_iterator( 209 actual = set(str(u) for u in self._test_wildcard_iterator(
170 suri(dst_bucket_uri, '**')).IterUris()) 210 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
171 expected = set([suri(dst_bucket_uri, 'dir1', 'f1')]) 211 expected = set([suri(dst_bucket_uri, 'dir1', 'f1')])
172 self.assertEqual(expected, actual) 212 self.assertEqual(expected, actual)
173 213
174 @PerformsFileToObjectUpload 214 # @PerformsFileToObjectUpload
175 def testCopyingDotSlashToBucket(self): 215 def testCopyingDotSlashToBucket(self):
176 """Tests copying ./ to a bucket produces expected naming""" 216 """Tests copying ./ to a bucket produces expected naming."""
177 # When running a command like gsutil cp -r . gs://dest we expect the dest 217 # When running a command like gsutil cp -r . gs://dest we expect the dest
178 # obj names to be of the form gs://dest/abc, not gs://dest/./abc. 218 # obj names to be of the form gs://dest/abc, not gs://dest/./abc.
179 dst_bucket_uri = self.CreateBucket() 219 dst_bucket_uri = self.CreateBucket()
180 src_dir = self.CreateTempDir(test_files=['foo']) 220 src_dir = self.CreateTempDir(test_files=['foo'])
181 for rel_src_dir in ['.', '.%s' % os.sep]: 221 for rel_src_dir in ['.', '.%s' % os.sep]:
182 self.RunCommand('cp', ['-R', rel_src_dir, suri(dst_bucket_uri)], 222 self.RunCommand('cp', ['-R', rel_src_dir, suri(dst_bucket_uri)],
183 cwd=src_dir) 223 cwd=src_dir)
184 actual = set(str(u) for u in self._test_wildcard_iterator( 224 actual = set(str(u) for u in self._test_wildcard_iterator(
185 suri(dst_bucket_uri, '**')).IterUris()) 225 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
186 expected = set([suri(dst_bucket_uri, 'foo')]) 226 expected = set([suri(dst_bucket_uri, 'foo')])
187 self.assertEqual(expected, actual) 227 self.assertEqual(expected, actual)
188 228
189 @PerformsFileToObjectUpload 229 # @PerformsFileToObjectUpload
190 def testCopyingDirContainingOneFileToBucket(self): 230 def testCopyingDirContainingOneFileToBucket(self):
191 """Tests copying a directory containing 1 file to a bucket. 231 """Tests copying a directory containing 1 file to a bucket.
232
192 We test this case to ensure that correct bucket handling isn't dependent 233 We test this case to ensure that correct bucket handling isn't dependent
193 on the copy being treated as a multi-source copy. 234 on the copy being treated as a multi-source copy.
194 """ 235 """
195 dst_bucket_uri = self.CreateBucket() 236 dst_bucket_uri = self.CreateBucket()
196 src_dir = self.CreateTempDir(test_files=[('dir0', 'dir1', 'foo')]) 237 src_dir = self.CreateTempDir(test_files=[('dir0', 'dir1', 'foo')])
197 self.RunCommand('cp', ['-R', os.path.join(src_dir, 'dir0', 'dir1'), 238 self.RunCommand('cp', ['-R', os.path.join(src_dir, 'dir0', 'dir1'),
198 suri(dst_bucket_uri)]) 239 suri(dst_bucket_uri)])
199 actual = list((str(u) for u in self._test_wildcard_iterator( 240 actual = list((str(u) for u in self._test_wildcard_iterator(
200 suri(dst_bucket_uri, '**')).IterUris())) 241 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True)))
201 self.assertEqual(1, len(actual)) 242 self.assertEqual(1, len(actual))
202 self.assertEqual(suri(dst_bucket_uri, 'dir1', 'foo'), actual[0]) 243 self.assertEqual(suri(dst_bucket_uri, 'dir1', 'foo'), actual[0])
203 244
204 def testCopyingBucketToDir(self): 245 def testCopyingBucketToDir(self):
205 """Tests copying from a bucket to a directory""" 246 """Tests copying from a bucket to a directory."""
206 src_bucket_uri = self.CreateBucket(test_objects=['foo', 'dir/foo2']) 247 src_bucket_uri = self.CreateBucket(test_objects=['foo', 'dir/foo2'])
207 dst_dir = self.CreateTempDir() 248 dst_dir = self.CreateTempDir()
208 self.RunCommand('cp', ['-R', suri(src_bucket_uri), dst_dir]) 249 # Mock objects don't support hash digestion.
250 with SetBotoConfigForTest([('GSUtil', 'check_hashes', 'never')]):
251 self.RunCommand('cp', ['-R', suri(src_bucket_uri), dst_dir])
209 actual = set(str(u) for u in self._test_wildcard_iterator( 252 actual = set(str(u) for u in self._test_wildcard_iterator(
210 '%s%s**' % (dst_dir, os.sep)).IterUris()) 253 '%s%s**' % (dst_dir, os.sep)).IterAll(expand_top_level_buckets=True))
211 expected = set([suri(dst_dir, src_bucket_uri.bucket_name, 'foo'), 254 expected = set([suri(dst_dir, src_bucket_uri.bucket_name, 'foo'),
212 suri(dst_dir, src_bucket_uri.bucket_name, 'dir', 'foo2')]) 255 suri(dst_dir, src_bucket_uri.bucket_name, 'dir', 'foo2')])
213 self.assertEqual(expected, actual) 256 self.assertEqual(expected, actual)
214 257
215 def testCopyingBucketToBucket(self): 258 def testCopyingBucketToBucket(self):
216 """Tests copying from a bucket-only URI to a bucket""" 259 """Tests copying from a bucket-only URI to a bucket."""
217 src_bucket_uri = self.CreateBucket(test_objects=['foo', 'dir/foo2']) 260 src_bucket_uri = self.CreateBucket(test_objects=['foo', 'dir/foo2'])
218 dst_bucket_uri = self.CreateBucket() 261 dst_bucket_uri = self.CreateBucket()
219 self.RunCommand('cp', ['-R', suri(src_bucket_uri), suri(dst_bucket_uri)]) 262 self.RunCommand('cp', ['-R', suri(src_bucket_uri), suri(dst_bucket_uri)])
220 actual = set(str(u) for u in self._test_wildcard_iterator( 263 actual = set(str(u) for u in self._test_wildcard_iterator(
221 suri(dst_bucket_uri, '**')).IterUris()) 264 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
222 expected = set([ 265 expected = set([
223 suri(dst_bucket_uri, src_bucket_uri.bucket_name, 'foo'), 266 suri(dst_bucket_uri, src_bucket_uri.bucket_name, 'foo'),
224 suri(dst_bucket_uri, src_bucket_uri.bucket_name, 'dir', 'foo2')]) 267 suri(dst_bucket_uri, src_bucket_uri.bucket_name, 'dir', 'foo2')])
225 self.assertEqual(expected, actual) 268 self.assertEqual(expected, actual)
226 269
227 def testCopyingDirectoryToDirectory(self): 270 def testCopyingDirectoryToDirectory(self):
228 """Tests copying from a directory to a directory""" 271 """Tests copying from a directory to a directory."""
229 src_dir = self.CreateTempDir(test_files=['foo', ('dir', 'foo2')]) 272 src_dir = self.CreateTempDir(test_files=['foo', ('dir', 'foo2')])
230 dst_dir = self.CreateTempDir() 273 dst_dir = self.CreateTempDir()
231 self.RunCommand('cp', ['-R', src_dir, dst_dir]) 274 self.RunCommand('cp', ['-R', src_dir, dst_dir])
232 actual = set(str(u) for u in self._test_wildcard_iterator( 275 actual = set(str(u) for u in self._test_wildcard_iterator(
233 '%s%s**' % (dst_dir, os.sep)).IterUris()) 276 '%s%s**' % (dst_dir, os.sep)).IterAll(expand_top_level_buckets=True))
234 src_dir_base = os.path.split(src_dir)[1] 277 src_dir_base = os.path.split(src_dir)[1]
235 expected = set([suri(dst_dir, src_dir_base, 'foo'), 278 expected = set([suri(dst_dir, src_dir_base, 'foo'),
236 suri(dst_dir, src_dir_base, 'dir', 'foo2')]) 279 suri(dst_dir, src_dir_base, 'dir', 'foo2')])
237 self.assertEqual(expected, actual) 280 self.assertEqual(expected, actual)
238 281
239 def testCopyingFilesAndDirNonRecursive(self): 282 def testCopyingFilesAndDirNonRecursive(self):
240 """Tests copying containing files and a directory without -R""" 283 """Tests copying containing files and a directory without -R."""
241 src_dir = self.CreateTempDir(test_files=['foo', 'bar', ('d1', 'f2'), 284 src_dir = self.CreateTempDir(test_files=['foo', 'bar', ('d1', 'f2'),
242 ('d2', 'f3'), ('d3', 'd4', 'f4')]) 285 ('d2', 'f3'), ('d3', 'd4', 'f4')])
243 dst_dir = self.CreateTempDir() 286 dst_dir = self.CreateTempDir()
244 self.RunCommand('cp', ['%s%s*' % (src_dir, os.sep), dst_dir]) 287 self.RunCommand('cp', ['%s%s*' % (src_dir, os.sep), dst_dir])
245 actual = set(str(u) for u in self._test_wildcard_iterator( 288 actual = set(str(u) for u in self._test_wildcard_iterator(
246 '%s%s**' % (dst_dir, os.sep)).IterUris()) 289 '%s%s**' % (dst_dir, os.sep)).IterAll(expand_top_level_buckets=True))
247 expected = set([suri(dst_dir, 'foo'), suri(dst_dir, 'bar')]) 290 expected = set([suri(dst_dir, 'foo'), suri(dst_dir, 'bar')])
248 self.assertEqual(expected, actual) 291 self.assertEqual(expected, actual)
249 292
250 def testCopyingFileToDir(self): 293 def testCopyingFileToDir(self):
251 """Tests copying one file to a directory""" 294 """Tests copying one file to a directory."""
252 src_file = self.CreateTempFile(file_name='foo') 295 src_file = self.CreateTempFile(file_name='foo')
253 dst_dir = self.CreateTempDir() 296 dst_dir = self.CreateTempDir()
254 self.RunCommand('cp', [src_file, dst_dir]) 297 self.RunCommand('cp', [src_file, dst_dir])
255 actual = list(self._test_wildcard_iterator( 298 actual = list(self._test_wildcard_iterator(
256 '%s%s*' % (dst_dir, os.sep)).IterUris()) 299 '%s%s*' % (dst_dir, os.sep)).IterAll(expand_top_level_buckets=True))
257 self.assertEqual(1, len(actual)) 300 self.assertEqual(1, len(actual))
258 self.assertEqual(suri(dst_dir, 'foo'), actual[0].uri) 301 self.assertEqual(suri(dst_dir, 'foo'), str(actual[0]))
259 302
260 @PerformsFileToObjectUpload 303 # @PerformsFileToObjectUpload
261 def testCopyingFileToObjectWithConsecutiveSlashes(self): 304 def testCopyingFileToObjectWithConsecutiveSlashes(self):
262 """Tests copying a file to an object containing consecutive slashes""" 305 """Tests copying a file to an object containing consecutive slashes."""
263 src_file = self.CreateTempFile(file_name='f0') 306 src_file = self.CreateTempFile(file_name='f0')
264 dst_bucket_uri = self.CreateBucket() 307 dst_bucket_uri = self.CreateBucket()
265 self.RunCommand('cp', [src_file, suri(dst_bucket_uri) + '//obj']) 308 self.RunCommand('cp', [src_file, suri(dst_bucket_uri) + '//obj'])
266 actual = list(self._test_wildcard_iterator( 309 actual = list(self._test_wildcard_iterator(
267 suri(dst_bucket_uri, '**')).IterUris()) 310 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
268 self.assertEqual(1, len(actual)) 311 self.assertEqual(1, len(actual))
269 self.assertEqual('/obj', actual[0].object_name) 312 self.assertEqual('/obj', actual[0].root_object.name)
270 313
271 def testCopyingCompressedFileToBucket(self): 314 def testCopyingCompressedFileToBucket(self):
272 """Tests copying one file with compression to a bucket""" 315 """Tests copying one file with compression to a bucket."""
273 src_file = self.CreateTempFile(contents='plaintext', file_name='f2.txt') 316 src_file = self.CreateTempFile(contents='plaintext', file_name='f2.txt')
274 dst_bucket_uri = self.CreateBucket() 317 dst_bucket_uri = self.CreateBucket()
275 self.RunCommand('cp', ['-z', 'txt', src_file, suri(dst_bucket_uri)],) 318 self.RunCommand('cp', ['-z', 'txt', src_file, suri(dst_bucket_uri)],)
276 actual = list(str(u) for u in self._test_wildcard_iterator( 319 actual = list(self._test_wildcard_iterator(
277 suri(dst_bucket_uri, '*')).IterUris()) 320 suri(dst_bucket_uri, '*')).IterAll(expand_top_level_buckets=True))
278 self.assertEqual(1, len(actual)) 321 self.assertEqual(1, len(actual))
279 expected_dst_uri = dst_bucket_uri.clone_replace_name('f2.txt') 322 actual_obj = actual[0].root_object
280 self.assertEqual(expected_dst_uri.uri, actual[0]) 323 self.assertEqual('f2.txt', actual_obj.name)
281 dst_key = expected_dst_uri.get_key() 324 self.assertEqual('gzip', actual_obj.contentEncoding)
282 dst_key.open_read() 325
283 self.assertEqual('gzip', dst_key.content_encoding) 326 stdout = self.RunCommand('cat', [suri(dst_bucket_uri, 'f2.txt')],
284 contents = dst_key.read() 327 return_stdout=True)
285 f = gzip.GzipFile(fileobj=StringIO.StringIO(contents), mode='rb') 328
329 f = gzip.GzipFile(fileobj=StringIO.StringIO(stdout), mode='rb')
286 try: 330 try:
287 self.assertEqual(f.read(), 'plaintext') 331 self.assertEqual(f.read(), 'plaintext')
288 finally: 332 finally:
289 f.close() 333 f.close()
290 334
291 def testCopyingObjectToObject(self): 335 def testCopyingObjectToObject(self):
292 """Tests copying an object to an object""" 336 """Tests copying an object to an object."""
293 src_bucket_uri = self.CreateBucket(test_objects=['obj']) 337 src_bucket_uri = self.CreateBucket(test_objects=['obj'])
294 dst_bucket_uri = self.CreateBucket() 338 dst_bucket_uri = self.CreateBucket()
295 self.RunCommand('cp', [suri(src_bucket_uri, 'obj'), suri(dst_bucket_uri)]) 339 self.RunCommand('cp', [suri(src_bucket_uri, 'obj'), suri(dst_bucket_uri)])
296 actual = list(self._test_wildcard_iterator( 340 actual = list(self._test_wildcard_iterator(
297 suri(dst_bucket_uri, '*')).IterUris()) 341 suri(dst_bucket_uri, '*')).IterAll(expand_top_level_buckets=True))
298 self.assertEqual(1, len(actual)) 342 self.assertEqual(1, len(actual))
299 self.assertEqual('obj', actual[0].object_name) 343 self.assertEqual('obj', actual[0].root_object.name)
300 344
301 def testCopyingObjectToObjectUsingDestWildcard(self): 345 def testCopyingObjectToObjectUsingDestWildcard(self):
302 """Tests copying an object to an object using a dest wildcard""" 346 """Tests copying an object to an object using a dest wildcard."""
303 src_bucket_uri = self.CreateBucket(test_objects=['obj']) 347 src_bucket_uri = self.CreateBucket(test_objects=['obj'])
304 dst_bucket_uri = self.CreateBucket(test_objects=['dstobj']) 348 dst_bucket_uri = self.CreateBucket(test_objects=['dstobj'])
305 self.RunCommand('cp', [suri(src_bucket_uri, 'obj'), 349 self.RunCommand('cp', [suri(src_bucket_uri, 'obj'),
306 '%s*' % dst_bucket_uri.uri]) 350 '%s*' % dst_bucket_uri.uri])
307 actual = list(self._test_wildcard_iterator( 351 actual = set(str(u) for u in self._test_wildcard_iterator(
308 suri(dst_bucket_uri, '*')).IterUris()) 352 suri(dst_bucket_uri, '*')).IterAll(expand_top_level_buckets=True))
309 self.assertEqual(1, len(actual)) 353 expected = set([suri(dst_bucket_uri, 'dstobj')])
310 self.assertEqual('dstobj', actual[0].object_name) 354 self.assertEqual(expected, actual)
311 355
312 def testCopyingObjsAndFilesToDir(self): 356 def testCopyingObjsAndFilesToDir(self):
313 """Tests copying objects and files to a directory""" 357 """Tests copying objects and files to a directory."""
314 src_bucket_uri = self.CreateBucket(test_objects=['f1']) 358 src_bucket_uri = self.CreateBucket(test_objects=['f1'])
315 src_dir = self.CreateTempDir(test_files=['f2']) 359 src_dir = self.CreateTempDir(test_files=['f2'])
316 dst_dir = self.CreateTempDir() 360 dst_dir = self.CreateTempDir()
317 self.RunCommand('cp', ['-R', suri(src_bucket_uri, '**'), 361 # Mock objects don't support hash digestion.
318 os.path.join(src_dir, '**'), dst_dir]) 362 with SetBotoConfigForTest([('GSUtil', 'check_hashes', 'never')]):
363 self.RunCommand('cp', ['-R', suri(src_bucket_uri, '**'),
364 os.path.join(src_dir, '**'), dst_dir])
319 actual = set(str(u) for u in self._test_wildcard_iterator( 365 actual = set(str(u) for u in self._test_wildcard_iterator(
320 os.path.join(dst_dir, '**')).IterUris()) 366 os.path.join(dst_dir, '**')).IterAll(expand_top_level_buckets=True))
321 expected = set([suri(dst_dir, 'f1'), suri(dst_dir, 'f2')]) 367 expected = set([suri(dst_dir, 'f1'), suri(dst_dir, 'f2')])
322 self.assertEqual(expected, actual) 368 self.assertEqual(expected, actual)
323 369
324 def testCopyingObjToDot(self): 370 def testCopyingObjToDot(self):
325 """Tests that copying an object to . or ./ downloads to correct name""" 371 """Tests that copying an object to . or ./ downloads to correct name."""
326 src_bucket_uri = self.CreateBucket(test_objects=['f1']) 372 src_bucket_uri = self.CreateBucket(test_objects=['f1'])
327 dst_dir = self.CreateTempDir() 373 dst_dir = self.CreateTempDir()
328 for final_char in ('/', ''): 374 for final_char in ('/', ''):
329 self.RunCommand('cp', [suri(src_bucket_uri, 'f1'), '.%s' % final_char], 375 # Mock objects don't support hash digestion.
330 cwd=dst_dir) 376 with SetBotoConfigForTest([('GSUtil', 'check_hashes', 'never')]):
377 self.RunCommand('cp', [suri(src_bucket_uri, 'f1'), '.%s' % final_char],
378 cwd=dst_dir)
331 actual = set() 379 actual = set()
332 for dirname, dirnames, filenames in os.walk(dst_dir): 380 for dirname, dirnames, filenames in os.walk(dst_dir):
333 for subdirname in dirnames: 381 for subdirname in dirnames:
334 actual.add(os.path.join(dirname, subdirname)) 382 actual.add(os.path.join(dirname, subdirname))
335 for filename in filenames: 383 for filename in filenames:
336 actual.add(os.path.join(dirname, filename)) 384 actual.add(os.path.join(dirname, filename))
337 expected = set([os.path.join(dst_dir, 'f1')]) 385 expected = set([os.path.join(dst_dir, 'f1')])
338 self.assertEqual(expected, actual) 386 self.assertEqual(expected, actual)
339 387
340 @PerformsFileToObjectUpload 388 # @PerformsFileToObjectUpload
341 def testCopyingObjsAndFilesToBucket(self): 389 def testCopyingObjsAndFilesToBucket(self):
342 """Tests copying objects and files to a bucket""" 390 """Tests copying objects and files to a bucket."""
343 src_bucket_uri = self.CreateBucket(test_objects=['f1']) 391 src_bucket_uri = self.CreateBucket(test_objects=['f1'])
344 src_dir = self.CreateTempDir(test_files=['f2']) 392 src_dir = self.CreateTempDir(test_files=['f2'])
345 dst_bucket_uri = self.CreateBucket() 393 dst_bucket_uri = self.CreateBucket()
346 self.RunCommand('cp', ['-R', suri(src_bucket_uri, '**'), 394 self.RunCommand('cp', ['-R', suri(src_bucket_uri, '**'),
347 '%s%s**' % (src_dir, os.sep), suri(dst_bucket_uri)]) 395 '%s%s**' % (src_dir, os.sep), suri(dst_bucket_uri)])
348 actual = set(str(u) for u in self._test_wildcard_iterator( 396 actual = set(str(u) for u in self._test_wildcard_iterator(
349 suri(dst_bucket_uri, '**')).IterUris()) 397 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
350 expected = set([suri(dst_bucket_uri, 'f1'), suri(dst_bucket_uri, 'f2')]) 398 expected = set([suri(dst_bucket_uri, 'f1'), suri(dst_bucket_uri, 'f2')])
351 self.assertEqual(expected, actual) 399 self.assertEqual(expected, actual)
352 400
401 # @PerformsFileToObjectUpload
402 def testCopyingSubdirRecursiveToNonexistentSubdir(self):
403 """Tests copying a directory with a single file recursively to a bucket.
404
405 The file should end up in a new bucket subdirectory with the file's
406 directory structure starting below the recursive copy point, as in Unix cp.
407
408 Example:
409 filepath: dir1/dir2/foo
410 cp -r dir1 dir3
411 Results in dir3/dir2/foo being created.
412 """
413 src_dir = self.CreateTempDir()
414 self.CreateTempFile(tmpdir=src_dir + '/dir1/dir2', file_name='foo')
415 dst_bucket_uri = self.CreateBucket()
416 self.RunCommand('cp', ['-R', src_dir + '/dir1',
417 suri(dst_bucket_uri, 'dir3')])
418 actual = set(str(u) for u in self._test_wildcard_iterator(
419 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
420 expected = set([suri(dst_bucket_uri, 'dir3/dir2/foo')])
421 self.assertEqual(expected, actual)
422
353 def testAttemptDirCopyWithoutRecursion(self): 423 def testAttemptDirCopyWithoutRecursion(self):
354 """Tests copying a directory without -R""" 424 """Tests copying a directory without -R."""
355 src_dir = self.CreateTempDir(test_files=1) 425 src_dir = self.CreateTempDir(test_files=1)
356 dst_dir = self.CreateTempDir() 426 dst_dir = self.CreateTempDir()
357 try: 427 try:
358 self.RunCommand('cp', [src_dir, dst_dir]) 428 self.RunCommand('cp', [src_dir, dst_dir])
359 self.fail('Did not get expected CommandException') 429 self.fail('Did not get expected CommandException')
360 except CommandException, e: 430 except CommandException, e:
361 self.assertIn('No URIs matched', e.reason) 431 self.assertIn('No URLs matched', e.reason)
432
433 def testNonRecursiveFileAndSameNameSubdir(self):
434 """Tests copying a file and subdirectory of the same name without -R."""
435 src_bucket_uri = self.CreateBucket(test_objects=['f1', 'f1/f2'])
436 dst_dir = self.CreateTempDir()
437 # Mock objects don't support hash digestion.
438 with SetBotoConfigForTest([('GSUtil', 'check_hashes', 'never')]):
439 self.RunCommand('cp', [suri(src_bucket_uri, 'f1'), dst_dir])
440 actual = list(self._test_wildcard_iterator(
441 '%s%s*' % (dst_dir, os.sep)).IterAll(expand_top_level_buckets=True))
442 self.assertEqual(1, len(actual))
443 self.assertEqual(suri(dst_dir, 'f1'), str(actual[0]))
444 # TODO: Assert that we omit the prefix here when unit_testcase supports
445 # returning stderr.
362 446
363 def testAttemptCopyingProviderOnlySrc(self): 447 def testAttemptCopyingProviderOnlySrc(self):
364 """Attempts to copy a src specified as a provider-only URI""" 448 """Attempts to copy a src specified as a provider-only URI."""
365 src_bucket_uri = self.CreateBucket() 449 src_bucket_uri = self.CreateBucket()
366 try: 450 try:
367 self.RunCommand('cp', ['gs://', suri(src_bucket_uri)]) 451 self.RunCommand('cp', ['gs://', suri(src_bucket_uri)])
368 self.fail('Did not get expected CommandException') 452 self.fail('Did not get expected CommandException')
369 except CommandException, e: 453 except CommandException, e:
370 self.assertIn('provider-only', e.reason) 454 self.assertIn('provider-only', e.reason)
371 455
372 def testAttemptCopyingOverlappingSrcDstFile(self): 456 def testAttemptCopyingOverlappingSrcDstFile(self):
373 """Attempts to an object atop itself""" 457 """Attempts to an object atop itself."""
374 src_file = self.CreateTempFile() 458 src_file = self.CreateTempFile()
375 try: 459 try:
376 self.RunCommand('cp', [src_file, src_file]) 460 self.RunCommand('cp', [src_file, src_file])
377 self.fail('Did not get expected CommandException') 461 self.fail('Did not get expected CommandException')
378 except CommandException, e: 462 except CommandException, e:
379 self.assertIn('are the same file - abort', e.reason) 463 self.assertIn('are the same file - abort', e.reason)
380 464
381 def testAttemptCopyingToMultiMatchWildcard(self): 465 def testAttemptCopyingToMultiMatchWildcard(self):
382 """Attempts to copy where dst wildcard matches >1 obj""" 466 """Attempts to copy where dst wildcard matches >1 obj."""
383 src_bucket_uri = self.CreateBucket() 467 src_bucket_uri = self.CreateBucket(test_objects=2)
384 try: 468 try:
385 self.RunCommand('cp', [suri(src_bucket_uri, 'obj0'), 469 self.RunCommand('cp', [suri(src_bucket_uri, 'obj0'),
386 suri(src_bucket_uri, '*')]) 470 suri(src_bucket_uri, '*')])
387 self.fail('Did not get expected CommandException') 471 self.fail('Did not get expected CommandException')
388 except CommandException, e: 472 except CommandException, e:
389 self.assertNotEqual(e.reason.find('must match exactly 1 URI'), -1) 473 self.assertNotEqual(e.reason.find('must match exactly 1 URL'), -1)
390 474
391 def testAttemptCopyingMultiObjsToFile(self): 475 def testAttemptCopyingMultiObjsToFile(self):
392 """Attempts to copy multiple objects to a file""" 476 """Attempts to copy multiple objects to a file."""
393 src_bucket_uri = self.CreateBucket(test_objects=2) 477 src_bucket_uri = self.CreateBucket(test_objects=2)
394 dst_file = self.CreateTempFile() 478 dst_file = self.CreateTempFile()
395 try: 479 try:
396 self.RunCommand('cp', ['-R', suri(src_bucket_uri, '*'), dst_file]) 480 self.RunCommand('cp', ['-R', suri(src_bucket_uri, '*'), dst_file])
397 self.fail('Did not get expected CommandException') 481 self.fail('Did not get expected CommandException')
398 except CommandException, e: 482 except CommandException, e:
399 self.assertIn('must name a directory, bucket, or', e.reason) 483 self.assertIn('must name a directory, bucket, or', e.reason)
400 484
401 def testAttemptCopyingWithFileDirConflict(self): 485 def testAttemptCopyingWithFileDirConflict(self):
402 """Attempts to copy objects that cause a file/directory conflict""" 486 """Attempts to copy objects that cause a file/directory conflict."""
403 # Create objects with name conflicts (a/b and a). Use 'dst' bucket because 487 # Create objects with name conflicts (a/b and a). Use 'dst' bucket because
404 # it gets cleared after each test. 488 # it gets cleared after each test.
405 bucket_uri = self.CreateBucket() 489 bucket_uri = self.CreateBucket()
406 self.CreateObject(bucket_uri=bucket_uri, object_name='a') 490 self.CreateObject(bucket_uri=bucket_uri, object_name='a')
407 self.CreateObject(bucket_uri=bucket_uri, object_name='b/a') 491 self.CreateObject(bucket_uri=bucket_uri, object_name='b/a')
408 dst_dir = self.CreateTempDir() 492 dst_dir = self.CreateTempDir()
409 try: 493 try:
410 self.RunCommand('cp', ['-R', suri(bucket_uri), dst_dir]) 494 self.RunCommand('cp', ['-R', suri(bucket_uri), dst_dir])
411 self.fail('Did not get expected CommandException') 495 self.fail('Did not get expected CommandException')
412 except CommandException, e: 496 except CommandException, e:
413 self.assertNotEqual('exists where a directory needs to be created', 497 self.assertNotEqual('exists where a directory needs to be created',
414 e.reason) 498 e.reason)
415 499
416 def testAttemptCopyingWithDirFileConflict(self): 500 def testAttemptCopyingWithDirFileConflict(self):
417 """Attempts to copy an object that causes a directory/file conflict""" 501 """Attempts to copy an object that causes a directory/file conflict."""
418 # Create an object that conflicts with dest subdir. 502 # Create an object that conflicts with dest subdir.
419 tmpdir = self.CreateTempDir() 503 tmpdir = self.CreateTempDir()
420 os.mkdir(os.path.join(tmpdir, 'abc')) 504 os.mkdir(os.path.join(tmpdir, 'abc'))
421 src_uri = self.CreateObject(object_name='abc', contents='bar') 505 src_uri = self.CreateObject(object_name='abc', contents='bar')
422 try: 506 try:
423 self.RunCommand('cp', [suri(src_uri), tmpdir + '/']) 507 self.RunCommand('cp', [suri(src_uri), tmpdir + '/'])
424 self.fail('Did not get expected CommandException') 508 self.fail('Did not get expected CommandException')
425 except CommandException, e: 509 except CommandException, e:
426 self.assertNotEqual('where the file needs to be created', e.reason) 510 self.assertNotEqual('where the file needs to be created', e.reason)
427 511
428 def testWildcardMoveWithinBucket(self): 512 def testWildcardMoveWithinBucket(self):
429 """Attempts to move using src wildcard that overlaps dest object. 513 """Attempts to move using src wildcard that overlaps dest object.
430 We want to ensure that this doesn't stomp the result data. See the 514
431 comment starting with 'Expand wildcards before' in commands/mv.py 515 We want to ensure that this doesn't stomp the result data.
432 for details.
433 """ 516 """
434 dst_bucket_uri = self.CreateBucket(test_objects=['old']) 517 dst_bucket_uri = self.CreateBucket(test_objects=['old'])
435 self.RunCommand('mv', [suri(dst_bucket_uri, 'old*'), 518 self.RunCommand('mv', [suri(dst_bucket_uri, 'old*'),
436 suri(dst_bucket_uri, 'new')]) 519 suri(dst_bucket_uri, 'new')])
437 actual = set(str(u) for u in self._test_wildcard_iterator( 520 actual = set(str(u) for u in self._test_wildcard_iterator(
438 suri(dst_bucket_uri, '**')).IterUris()) 521 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
439 expected = set([suri(dst_bucket_uri, 'new')]) 522 expected = set([suri(dst_bucket_uri, 'new')])
440 self.assertEqual(expected, actual) 523 self.assertEqual(expected, actual)
441 524
442 def testLsNonExistentObjectWithPrefixName(self): 525 def testLsNonExistentObjectWithPrefixName(self):
443 """Test ls of non-existent obj that matches prefix of existing objs""" 526 """Test ls of non-existent obj that matches prefix of existing objs."""
444 # Use an object name that matches a prefix of other names at that level, to 527 # Use an object name that matches a prefix of other names at that level, to
445 # ensure the ls subdir handling logic doesn't pick up anything extra. 528 # ensure the ls subdir handling logic doesn't pick up anything extra.
446 src_bucket_uri = self.CreateBucket() 529 src_bucket_uri = self.CreateBucket(test_objects=['obj_with_suffix'])
447 try: 530 try:
448 output = self.RunCommand('ls', [suri(src_bucket_uri, 'obj')], 531 self.RunCommand('ls', [suri(src_bucket_uri, 'obj')])
449 return_stdout=True)
450 except CommandException, e: 532 except CommandException, e:
451 self.assertIn('No such object', e.reason) 533 self.assertIn('matched no objects', e.reason)
452 534
453 def testLsBucketNonRecursive(self): 535 def testLsBucketNonRecursive(self):
454 """Test that ls of a bucket returns expected results""" 536 """Test that ls of a bucket returns expected results."""
455 src_bucket_uri = self.CreateBucket(test_objects=['foo1', 'd0/foo2', 537 src_bucket_uri = self.CreateBucket(test_objects=['foo1', 'd0/foo2',
456 'd1/d2/foo3']) 538 'd1/d2/foo3'])
457 output = self.RunCommand('ls', [suri(src_bucket_uri, '*')], 539 output = self.RunCommand('ls', [suri(src_bucket_uri, '*')],
458 return_stdout=True) 540 return_stdout=True)
459 expected = set([suri(src_bucket_uri, 'foo1'), 541 expected = set([suri(src_bucket_uri, 'foo1'),
460 suri(src_bucket_uri, 'd1', ':'), 542 suri(src_bucket_uri, 'd1', ':'),
461 suri(src_bucket_uri, 'd1', 'd2') + src_bucket_uri.delim, 543 suri(src_bucket_uri, 'd1', 'd2') + src_bucket_uri.delim,
462 suri(src_bucket_uri, 'd0', ':'), 544 suri(src_bucket_uri, 'd0', ':'),
463 suri(src_bucket_uri, 'd0', 'foo2')]) 545 suri(src_bucket_uri, 'd0', 'foo2')])
464 expected.add('') # Blank line between subdir listings. 546 expected.add('') # Blank line between subdir listings.
465 actual = set(output.split('\n')) 547 actual = set(output.split('\n'))
466 self.assertEqual(expected, actual) 548 self.assertEqual(expected, actual)
467 549
468 def testLsBucketRecursive(self): 550 def testLsBucketRecursive(self):
469 """Test that ls -R of a bucket returns expected results""" 551 """Test that ls -R of a bucket returns expected results."""
470 src_bucket_uri = self.CreateBucket(test_objects=['foo1', 'd0/foo2', 552 src_bucket_uri = self.CreateBucket(test_objects=['foo1', 'd0/foo2',
471 'd1/d2/foo3']) 553 'd1/d2/foo3'])
472 output = self.RunCommand('ls', ['-R', suri(src_bucket_uri, '*')], 554 output = self.RunCommand('ls', ['-R', suri(src_bucket_uri, '*')],
473 return_stdout=True) 555 return_stdout=True)
474 expected = set([suri(src_bucket_uri, 'foo1'), 556 expected = set([suri(src_bucket_uri, 'foo1'),
475 suri(src_bucket_uri, 'd1', ':'), 557 suri(src_bucket_uri, 'd1', ':'),
476 suri(src_bucket_uri, 'd1', 'd2', ':'), 558 suri(src_bucket_uri, 'd1', 'd2', ':'),
477 suri(src_bucket_uri, 'd1', 'd2', 'foo3'), 559 suri(src_bucket_uri, 'd1', 'd2', 'foo3'),
478 suri(src_bucket_uri, 'd0', ':'), 560 suri(src_bucket_uri, 'd0', ':'),
479 suri(src_bucket_uri, 'd0', 'foo2')]) 561 suri(src_bucket_uri, 'd0', 'foo2')])
480 expected.add('') # Blank line between subdir listings. 562 expected.add('') # Blank line between subdir listings.
481 actual = set(output.split('\n')) 563 actual = set(output.split('\n'))
482 self.assertEqual(expected, actual) 564 self.assertEqual(expected, actual)
483 565
484 def testLsBucketRecursiveWithLeadingSlashObjectName(self): 566 def testLsBucketRecursiveWithLeadingSlashObjectName(self):
485 """Test that ls -R of a bucket with an object that has leading slash""" 567 """Test that ls -R of a bucket with an object that has leading slash."""
486 dst_bucket_uri = self.CreateBucket(test_objects=['f0']) 568 dst_bucket_uri = self.CreateBucket(test_objects=['f0'])
487 output = self.RunCommand('ls', ['-R', suri(dst_bucket_uri) + '*'], 569 output = self.RunCommand('ls', ['-R', suri(dst_bucket_uri) + '*'],
488 return_stdout=True) 570 return_stdout=True)
489 expected = set([suri(dst_bucket_uri, 'f0')]) 571 expected = set([suri(dst_bucket_uri, 'f0')])
490 expected.add('') # Blank line between subdir listings. 572 expected.add('') # Blank line between subdir listings.
491 actual = set(output.split('\n')) 573 actual = set(output.split('\n'))
492 self.assertEqual(expected, actual) 574 self.assertEqual(expected, actual)
493 575
494 def testLsBucketSubdirNonRecursive(self): 576 def testLsBucketSubdirNonRecursive(self):
495 """Test that ls of a bucket subdir returns expected results""" 577 """Test that ls of a bucket subdir returns expected results."""
496 src_bucket_uri = self.CreateBucket(test_objects=['src_subdir/foo', 578 src_bucket_uri = self.CreateBucket(test_objects=['src_subdir/foo',
497 'src_subdir/nested/foo2']) 579 'src_subdir/nested/foo2'])
498 output = self.RunCommand('ls', [suri(src_bucket_uri, 'src_subdir')], 580 output = self.RunCommand('ls', [suri(src_bucket_uri, 'src_subdir')],
499 return_stdout=True) 581 return_stdout=True)
500 expected = set([ 582 expected = set([
501 suri(src_bucket_uri, 'src_subdir', 'foo'), 583 suri(src_bucket_uri, 'src_subdir', 'foo'),
502 suri(src_bucket_uri, 'src_subdir', 'nested') + src_bucket_uri.delim]) 584 suri(src_bucket_uri, 'src_subdir', 'nested') + src_bucket_uri.delim])
503 expected.add('') # Blank line between subdir listings. 585 expected.add('') # Blank line between subdir listings.
504 actual = set(output.split('\n')) 586 actual = set(output.split('\n'))
505 self.assertEqual(expected, actual) 587 self.assertEqual(expected, actual)
506 588
507 def testLsBucketSubdirRecursive(self): 589 def testLsBucketSubdirRecursive(self):
508 """Test that ls -R of a bucket subdir returns expected results""" 590 """Test that ls -R of a bucket subdir returns expected results."""
509 src_bucket_uri = self.CreateBucket(test_objects=['src_subdir/foo', 591 src_bucket_uri = self.CreateBucket(test_objects=['src_subdir/foo',
510 'src_subdir/nested/foo2']) 592 'src_subdir/nested/foo2'])
511 for final_char in ('/', ''): 593 for final_char in ('/', ''):
512 output = self.RunCommand( 594 output = self.RunCommand(
513 'ls', ['-R', suri(src_bucket_uri, 'src_subdir') + final_char], 595 'ls', ['-R', suri(src_bucket_uri, 'src_subdir') + final_char],
514 return_stdout=True) 596 return_stdout=True)
515 expected = set([ 597 expected = set([
516 suri(src_bucket_uri, 'src_subdir', ':'), 598 suri(src_bucket_uri, 'src_subdir', ':'),
517 suri(src_bucket_uri, 'src_subdir', 'foo'), 599 suri(src_bucket_uri, 'src_subdir', 'foo'),
518 suri(src_bucket_uri, 'src_subdir', 'nested', ':'), 600 suri(src_bucket_uri, 'src_subdir', 'nested', ':'),
519 suri(src_bucket_uri, 'src_subdir', 'nested', 'foo2')]) 601 suri(src_bucket_uri, 'src_subdir', 'nested', 'foo2')])
520 expected.add('') # Blank line between subdir listings. 602 expected.add('') # Blank line between subdir listings.
521 actual = set(output.split('\n')) 603 actual = set(output.split('\n'))
522 self.assertEqual(expected, actual) 604 self.assertEqual(expected, actual)
523 605
524 def testSetAclOnBucketRuns(self): 606 def testSetAclOnBucketRuns(self):
525 """Test that the 'acl set' command basically runs""" 607 """Test that the 'acl set' command basically runs."""
526 # We don't test reading back the acl (via 'acl get' command) because at 608 # We don't test reading back the acl (via 'acl get' command) because at
527 # present MockStorageService doesn't translate canned ACLs into actual ACL 609 # present MockStorageService doesn't translate canned ACLs into actual ACL
528 # XML. 610 # XML.
529 src_bucket_uri = self.CreateBucket() 611 src_bucket_uri = self.CreateBucket()
530 self.RunCommand('acl', ['set', 'private', suri(src_bucket_uri)]) 612 self.RunCommand('acl', ['set', 'private', suri(src_bucket_uri)])
531 613
532 def testSetAclOnWildcardNamedBucketRuns(self): 614 def testSetAclOnWildcardNamedBucketRuns(self):
533 """Test that 'acl set' basically runs against wildcard-named bucket""" 615 """Test that 'acl set' basically runs against wildcard-named bucket."""
534 # We don't test reading back the acl (via 'acl get' command) because at 616 # We don't test reading back the acl (via 'acl get' command) because at
535 # present MockStorageService doesn't translate canned ACLs into actual ACL 617 # present MockStorageService doesn't translate canned ACLs into actual ACL
536 # XML. 618 # XML.
537 src_bucket_uri = self.CreateBucket(test_objects=['f0']) 619 src_bucket_uri = self.CreateBucket(test_objects=['f0'])
538 self.RunCommand('acl', ['set', 'private', suri(src_bucket_uri)[:-2] + '*']) 620 self.RunCommand('acl', ['set', 'private', suri(src_bucket_uri)[:-2] + '*'])
539 621
540 def testSetAclOnObjectRuns(self): 622 def testSetAclOnObjectRuns(self):
541 """Test that the 'acl set' command basically runs""" 623 """Test that the 'acl set' command basically runs."""
542 src_bucket_uri = self.CreateBucket(test_objects=['f0']) 624 src_bucket_uri = self.CreateBucket(test_objects=['f0'])
543 self.RunCommand('acl', ['set', 'private', suri(src_bucket_uri, '*')]) 625 self.RunCommand('acl', ['set', 'private', suri(src_bucket_uri, '*')])
544 626
545 def testSetDefAclOnBucketRuns(self): 627 def testSetDefAclOnBucketRuns(self):
546 """Test that the 'defacl set' command basically runs""" 628 """Test that the 'defacl set' command basically runs."""
547 src_bucket_uri = self.CreateBucket() 629 src_bucket_uri = self.CreateBucket()
548 self.RunCommand('defacl', ['set', 'private', suri(src_bucket_uri)]) 630 self.RunCommand('defacl', ['set', 'private', suri(src_bucket_uri)])
549 631
550 def testSetDefAclOnObjectFails(self): 632 def testSetDefAclOnObjectFails(self):
551 """Test that the 'defacl set' command fails when run against an object""" 633 """Test that the 'defacl set' command fails when run against an object."""
552 src_bucket_uri = self.CreateBucket() 634 src_bucket_uri = self.CreateBucket()
553 try: 635 try:
554 self.RunCommand('defacl', ['set', 'private', suri(src_bucket_uri, '*')]) 636 self.RunCommand('defacl', ['set', 'private', suri(src_bucket_uri, '*')])
555 self.fail('Did not get expected CommandException') 637 self.fail('Did not get expected CommandException')
556 except CommandException, e: 638 except CommandException, e:
557 self.assertIn('URI must name a bucket', e.reason) 639 self.assertIn('URL must name a bucket', e.reason)
558 640
559 @PerformsFileToObjectUpload 641 # @PerformsFileToObjectUpload
560 def testMinusDOptionWorks(self): 642 def testMinusDOptionWorks(self):
561 """Tests using gsutil -D option""" 643 """Tests using gsutil -D option."""
562 src_file = self.CreateTempFile(file_name='f0') 644 src_file = self.CreateTempFile(file_name='f0')
563 dst_bucket_uri = self.CreateBucket() 645 dst_bucket_uri = self.CreateBucket()
564 self.RunCommand('cp', [src_file, suri(dst_bucket_uri)], debug=3) 646 self.RunCommand('cp', [src_file, suri(dst_bucket_uri)], debug=3)
565 actual = list(self._test_wildcard_iterator( 647 actual = list(self._test_wildcard_iterator(
566 suri(dst_bucket_uri, '*')).IterUris()) 648 suri(dst_bucket_uri, '*')).IterAll(expand_top_level_buckets=True))
567 self.assertEqual(1, len(actual)) 649 self.assertEqual(1, len(actual))
568 self.assertEqual('f0', actual[0].object_name) 650 self.assertEqual('f0', actual[0].root_object.name)
569 651
570 def DownloadTestHelper(self, func): 652 def DownloadTestHelper(self, func):
653 """Test resumable download with custom test function.
654
655 The custom function distorts downloaded data. We expect an exception to be
656 raised and the dest file to be removed.
657
658 Args:
659 func: Custom test function used to distort the downloaded data.
571 """ 660 """
572 Test resumable download with custom test function to distort downloaded 661 object_uri = self.CreateObject(contents='foo')
573 data. We expect an exception to be raised and the dest file to be removed. 662 # Need to explicitly tell the key to populate its etag so that hash
574 """ 663 # validation will be performed.
575 object_uri = self.CreateObject() 664 object_uri.get_key().set_etag()
576 dst_dir = self.CreateTempDir() 665 dst_dir = self.CreateTempDir()
666 got_expected_exception = False
577 try: 667 try:
578 self.RunCommand('cp', [suri(object_uri), dst_dir], test_method=func) 668 self.RunCommand('cp', [suri(object_uri), dst_dir], test_method=func)
579 self.fail('Did not get expected CommandException') 669 self.fail('Did not get expected CommandException')
580 except CommandException: 670 except CommandException:
581 self.assertFalse(os.listdir(dst_dir)) 671 self.assertFalse(os.listdir(dst_dir))
672 got_expected_exception = True
582 except Exception, e: 673 except Exception, e:
583 self.fail('Unexpected exception raised') 674 self.fail('Unexpected exception raised: %s' % e)
675 if not got_expected_exception:
676 self.fail('Did not get expected CommandException')
584 677
585 def testDownloadWithObjectSizeChange(self): 678 def testDownloadWithObjectSizeChange(self):
586 """ 679 """Test resumable download on an object that changes size.
587 Test resumable download on an object that changes size before the 680
588 downloaded file's checksum is validated. 681 Size change occurs before the downloaded file's checksum is validated.
589 """ 682 """
590 self.DownloadTestHelper(_Append) 683 self.DownloadTestHelper(_Append)
591 684
592 def testDownloadWithFileContentChange(self): 685 def testDownloadWithFileContentChange(self):
593 """ 686 """Tests resumable download on an object that changes content.
594 Tests resumable download on an object where the file content changes 687
595 before the downloaded file's checksum is validated. 688 Content change occurs before the downloaded file's checksum is validated.
596 """ 689 """
597 self.DownloadTestHelper(_Overwrite) 690 self.DownloadTestHelper(_Overwrite)
598 691
599 @PerformsFileToObjectUpload 692 # @PerformsFileToObjectUpload
600 def testFlatCopyingObjsAndFilesToBucketSubDir(self): 693 def testFlatCopyingObjsAndFilesToBucketSubDir(self):
601 """Tests copying flatly listed objects and files to bucket subdir""" 694 """Tests copying flatly listed objects and files to bucket subdir."""
602 src_bucket_uri = self.CreateBucket(test_objects=['f0', 'd0/f1', 'd1/d2/f2']) 695 src_bucket_uri = self.CreateBucket(test_objects=['f0', 'd0/f1', 'd1/d2/f2'])
603 src_dir = self.CreateTempDir(test_files=['f3', ('d3', 'f4'), 696 src_dir = self.CreateTempDir(test_files=['f3', ('d3', 'f4'),
604 ('d4', 'd5', 'f5')]) 697 ('d4', 'd5', 'f5')])
605 dst_bucket_uri = self.CreateBucket(test_objects=['dst_subdir0/existing', 698 dst_bucket_uri = self.CreateBucket(test_objects=['dst_subdir0/existing',
606 'dst_subdir1/existing']) 699 'dst_subdir1/existing'])
607 # Test with and without final slash on dest subdir. 700 # Test with and without final slash on dest subdir.
608 for i, final_char in enumerate(('/', '')): 701 for i, final_char in enumerate(('/', '')):
609 self.RunCommand( 702 self.RunCommand(
610 'cp', ['-R', suri(src_bucket_uri, '**'), os.path.join(src_dir, '**'), 703 'cp', ['-R', suri(src_bucket_uri, '**'), os.path.join(src_dir, '**'),
611 suri(dst_bucket_uri, 'dst_subdir%d' % i) + final_char]) 704 suri(dst_bucket_uri, 'dst_subdir%d' % i) + final_char])
612 705
613 actual = set(str(u) for u in self._test_wildcard_iterator( 706 actual = set(str(u) for u in self._test_wildcard_iterator(
614 suri(dst_bucket_uri, '**')).IterUris()) 707 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
615 expected = set() 708 expected = set()
616 for i in range(2): 709 for i in range(2):
617 expected.add(suri(dst_bucket_uri, 'dst_subdir%d' % i, 'existing')) 710 expected.add(suri(dst_bucket_uri, 'dst_subdir%d' % i, 'existing'))
618 for j in range(6): 711 for j in range(6):
619 expected.add(suri(dst_bucket_uri, 'dst_subdir%d' % i, 'f%d' % j)) 712 expected.add(suri(dst_bucket_uri, 'dst_subdir%d' % i, 'f%d' % j))
620 self.assertEqual(expected, actual) 713 self.assertEqual(expected, actual)
621 714
622 @PerformsFileToObjectUpload 715 # @PerformsFileToObjectUpload
623 def testRecursiveCopyObjsAndFilesToExistingBucketSubDir(self): 716 def testRecursiveCopyObjsAndFilesToExistingBucketSubDir(self):
624 """Tests recursive copy of objects and files to existing bucket subdir""" 717 """Tests recursive copy of objects and files to existing bucket subdir."""
625 src_bucket_uri = self.CreateBucket(test_objects=['f0', 'nested/f1']) 718 src_bucket_uri = self.CreateBucket(test_objects=['f0', 'nested/f1'])
626 dst_bucket_uri = self.CreateBucket(test_objects=[ 719 dst_bucket_uri = self.CreateBucket(test_objects=[
627 'dst_subdir0/existing_obj', 'dst_subdir1/existing_obj']) 720 'dst_subdir0/existing_obj', 'dst_subdir1/existing_obj'])
628 src_dir = self.CreateTempDir(test_files=['f2', ('nested', 'f3')]) 721 src_dir = self.CreateTempDir(test_files=['f2', ('nested', 'f3')])
629 # Test with and without final slash on dest subdir. 722 # Test with and without final slash on dest subdir.
630 for i, final_char in enumerate(('/', '')): 723 for i, final_char in enumerate(('/', '')):
631 self.RunCommand( 724 self.RunCommand(
632 'cp', ['-R', suri(src_bucket_uri), src_dir, 725 'cp', ['-R', suri(src_bucket_uri), src_dir,
633 suri(dst_bucket_uri, 'dst_subdir%d' % i) + final_char]) 726 suri(dst_bucket_uri, 'dst_subdir%d' % i) + final_char])
634 actual = set(str(u) for u in self._test_wildcard_iterator( 727 actual = set(str(u) for u in self._test_wildcard_iterator(
635 suri(dst_bucket_uri, 'dst_subdir%d' % i, '**')).IterUris()) 728 suri(dst_bucket_uri, 'dst_subdir%d' % i, '**')).IterAll(
729 expand_top_level_buckets=True))
636 tmp_dirname = os.path.split(src_dir)[1] 730 tmp_dirname = os.path.split(src_dir)[1]
637 bucketname = src_bucket_uri.bucket_name 731 bucketname = src_bucket_uri.bucket_name
638 expected = set([ 732 expected = set([
639 suri(dst_bucket_uri, 'dst_subdir%d' % i, 'existing_obj'), 733 suri(dst_bucket_uri, 'dst_subdir%d' % i, 'existing_obj'),
640 suri(dst_bucket_uri, 'dst_subdir%d' % i, bucketname, 'f0'), 734 suri(dst_bucket_uri, 'dst_subdir%d' % i, bucketname, 'f0'),
641 suri(dst_bucket_uri, 'dst_subdir%d' % i, bucketname, 'nested', 'f1'), 735 suri(dst_bucket_uri, 'dst_subdir%d' % i, bucketname, 'nested', 'f1'),
642 suri(dst_bucket_uri, 'dst_subdir%d' % i, tmp_dirname, 'f2'), 736 suri(dst_bucket_uri, 'dst_subdir%d' % i, tmp_dirname, 'f2'),
643 suri(dst_bucket_uri, 'dst_subdir%d' % i, tmp_dirname, 'nested', 'f3') 737 suri(dst_bucket_uri, 'dst_subdir%d' % i, tmp_dirname, 'nested', 'f3')
644 ]) 738 ])
645 self.assertEqual(expected, actual) 739 self.assertEqual(expected, actual)
646 740
647 @PerformsFileToObjectUpload 741 # @PerformsFileToObjectUpload
648 def testRecursiveCopyObjsAndFilesToNonExistentBucketSubDir(self): 742 def testRecursiveCopyObjsAndFilesToNonExistentBucketSubDir(self):
649 """Tests recursive copy of objs + files to non-existent bucket subdir""" 743 """Tests recursive copy of objs + files to non-existent bucket subdir."""
650 src_bucket_uri = self.CreateBucket(test_objects=['f0', 'nested/f1']) 744 src_bucket_uri = self.CreateBucket(test_objects=['f0', 'nested/f1'])
651 src_dir = self.CreateTempDir(test_files=['f2', ('nested', 'f3')]) 745 src_dir = self.CreateTempDir(test_files=['f2', ('nested', 'f3')])
652 dst_bucket_uri = self.CreateBucket() 746 dst_bucket_uri = self.CreateBucket()
653 x = ['-R', src_dir, suri(src_bucket_uri), 747 self.RunCommand('cp', ['-R', src_dir, suri(src_bucket_uri),
654 suri(dst_bucket_uri, 'dst_subdir')] 748 suri(dst_bucket_uri, 'dst_subdir')])
655 stdout = self.RunCommand(
656 'cp', x, return_stdout=True)
657 actual = set(str(u) for u in self._test_wildcard_iterator( 749 actual = set(str(u) for u in self._test_wildcard_iterator(
658 suri(dst_bucket_uri, '**')).IterUris()) 750 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
659 expected = set([suri(dst_bucket_uri, 'dst_subdir', 'f0'), 751 expected = set([suri(dst_bucket_uri, 'dst_subdir', 'f0'),
660 suri(dst_bucket_uri, 'dst_subdir', 'nested', 'f1'), 752 suri(dst_bucket_uri, 'dst_subdir', 'nested', 'f1'),
661 suri(dst_bucket_uri, 'dst_subdir', 'f2'), 753 suri(dst_bucket_uri, 'dst_subdir', 'f2'),
662 suri(dst_bucket_uri, 'dst_subdir', 'nested', 'f3')]) 754 suri(dst_bucket_uri, 'dst_subdir', 'nested', 'f3')])
663 self.assertEqual(expected, actual) 755 self.assertEqual(expected, actual)
664 756
665 def testCopyingBucketSubDirToDir(self): 757 def testCopyingBucketSubDirToDir(self):
666 """Tests copying a bucket subdir to a directory""" 758 """Tests copying a bucket subdir to a directory."""
667 src_bucket_uri = self.CreateBucket(test_objects=['src_subdir/obj']) 759 src_bucket_uri = self.CreateBucket(test_objects=['src_subdir/obj'])
668 dst_dir = self.CreateTempDir() 760 dst_dir = self.CreateTempDir()
669 # Test with and without final slash on dest subdir. 761 # Test with and without final slash on dest subdir.
670 for (final_src_char, final_dst_char) in ( 762 for (final_src_char, final_dst_char) in (
671 ('', ''), ('', '/'), ('/', ''), ('/', '/') ): 763 ('', ''), ('', '/'), ('/', ''), ('/', '/')):
672 self.RunCommand( 764 # Mock objects don't support hash digestion.
673 'cp', ['-R', suri(src_bucket_uri, 'src_subdir') + final_src_char, 765 with SetBotoConfigForTest([('GSUtil', 'check_hashes', 'never')]):
674 dst_dir + final_dst_char]) 766 self.RunCommand(
767 'cp', ['-R', suri(src_bucket_uri, 'src_subdir') + final_src_char,
768 dst_dir + final_dst_char])
675 actual = set(str(u) for u in self._test_wildcard_iterator( 769 actual = set(str(u) for u in self._test_wildcard_iterator(
676 '%s%s**' % (dst_dir, os.sep)).IterUris()) 770 '%s%s**' % (dst_dir, os.sep)).IterAll(expand_top_level_buckets=True))
677 expected = set([suri(dst_dir, 'src_subdir', 'obj')]) 771 expected = set([suri(dst_dir, 'src_subdir', 'obj')])
678 self.assertEqual(expected, actual) 772 self.assertEqual(expected, actual)
679 773
680 def testCopyingWildcardSpecifiedBucketSubDirToExistingDir(self): 774 def testCopyingWildcardSpecifiedBucketSubDirToExistingDir(self):
681 """Tests copying a wildcard-specified bucket subdir to a directory""" 775 """Tests copying a wildcard-specified bucket subdir to a directory."""
682 src_bucket_uri = self.CreateBucket( 776 src_bucket_uri = self.CreateBucket(
683 test_objects=['src_sub0dir/foo', 'src_sub1dir/foo', 'src_sub2dir/foo', 777 test_objects=['src_sub0dir/foo', 'src_sub1dir/foo', 'src_sub2dir/foo',
684 'src_sub3dir/foo']) 778 'src_sub3dir/foo'])
685 dst_dir = self.CreateTempDir() 779 dst_dir = self.CreateTempDir()
686 # Test with and without final slash on dest subdir. 780 # Test with and without final slash on dest subdir.
687 for i, (final_src_char, final_dst_char) in enumerate(( 781 for i, (final_src_char, final_dst_char) in enumerate((
688 ('', ''), ('', '/'), ('/', ''), ('/', '/') )): 782 ('', ''), ('', '/'), ('/', ''), ('/', '/'))):
689 self.RunCommand( 783 # Mock objects don't support hash digestion.
690 'cp', ['-R', suri(src_bucket_uri, 'src_sub%d*' % i) + final_src_char, 784 with SetBotoConfigForTest([('GSUtil', 'check_hashes', 'never')]):
691 dst_dir + final_dst_char]) 785 self.RunCommand(
786 'cp', ['-R', suri(src_bucket_uri, 'src_sub%d*' % i) +
787 final_src_char, dst_dir + final_dst_char])
692 actual = set(str(u) for u in self._test_wildcard_iterator( 788 actual = set(str(u) for u in self._test_wildcard_iterator(
693 os.path.join(dst_dir, 'src_sub%ddir' % i, '**')).IterUris()) 789 os.path.join(dst_dir, 'src_sub%ddir' % i, '**')).IterAll(
790 expand_top_level_buckets=True))
694 expected = set([suri(dst_dir, 'src_sub%ddir' % i, 'foo')]) 791 expected = set([suri(dst_dir, 'src_sub%ddir' % i, 'foo')])
695 self.assertEqual(expected, actual) 792 self.assertEqual(expected, actual)
696 793
697 def testCopyingBucketSubDirToDirFailsWithoutMinusR(self): 794 def testCopyingBucketSubDirToDirFailsWithoutMinusR(self):
698 """Tests for failure when attempting bucket subdir copy without -R""" 795 """Tests for failure when attempting bucket subdir copy without -R."""
699 src_bucket_uri = self.CreateBucket(test_objects=['src_subdir/obj']) 796 src_bucket_uri = self.CreateBucket(test_objects=['src_subdir/obj'])
700 dst_dir = self.CreateTempDir() 797 dst_dir = self.CreateTempDir()
701 try: 798 try:
702 self.RunCommand( 799 self.RunCommand(
703 'cp', [suri(src_bucket_uri, 'src_subdir'), dst_dir]) 800 'cp', [suri(src_bucket_uri, 'src_subdir'), dst_dir])
704 self.fail('Did not get expected CommandException') 801 self.fail('Did not get expected CommandException')
705 except CommandException, e: 802 except CommandException, e:
706 self.assertIn('does not exist', e.reason) 803 self.assertIn('No URLs matched', e.reason)
707 804
708 def testCopyingBucketSubDirToBucketSubDir(self): 805 def testCopyingBucketSubDirToBucketSubDir(self):
709 """Tests copying a bucket subdir to another bucket subdir""" 806 """Tests copying a bucket subdir to another bucket subdir."""
710 src_bucket_uri = self.CreateBucket( 807 src_bucket_uri = self.CreateBucket(
711 test_objects=['src_subdir_%d/obj' % i for i in range(4)]) 808 test_objects=['src_subdir_%d/obj' % i for i in range(4)])
712 dst_bucket_uri = self.CreateBucket( 809 dst_bucket_uri = self.CreateBucket(
713 test_objects=['dst_subdir_%d/obj2' % i for i in range(4)]) 810 test_objects=['dst_subdir_%d/obj2' % i for i in range(4)])
714 # Test with and without final slash on dest subdir. 811 # Test with and without final slash on dest subdir.
715 for i, (final_src_char, final_dst_char) in enumerate(( 812 for i, (final_src_char, final_dst_char) in enumerate((
716 ('', ''), ('', '/'), ('/', ''), ('/', '/') )): 813 ('', ''), ('', '/'), ('/', ''), ('/', '/'))):
717 self.RunCommand( 814 self.RunCommand(
718 'cp', ['-R', suri(src_bucket_uri, 'src_subdir_%d' % i) + final_src_cha r, 815 'cp', ['-R',
816 suri(src_bucket_uri, 'src_subdir_%d' % i) + final_src_char,
719 suri(dst_bucket_uri, 'dst_subdir_%d' % i) + final_dst_char]) 817 suri(dst_bucket_uri, 'dst_subdir_%d' % i) + final_dst_char])
720 actual = set(str(u) for u in self._test_wildcard_iterator( 818 actual = set(str(u) for u in self._test_wildcard_iterator(
721 suri(dst_bucket_uri, 'dst_subdir_%d' % i, '**')).IterUris()) 819 suri(dst_bucket_uri, 'dst_subdir_%d' % i, '**')).IterAll(
820 expand_top_level_buckets=True))
722 expected = set([suri(dst_bucket_uri, 'dst_subdir_%d' % i, 821 expected = set([suri(dst_bucket_uri, 'dst_subdir_%d' % i,
723 'src_subdir_%d' % i, 'obj'), 822 'src_subdir_%d' % i, 'obj'),
724 suri(dst_bucket_uri, 'dst_subdir_%d' % i, 'obj2')]) 823 suri(dst_bucket_uri, 'dst_subdir_%d' % i, 'obj2')])
725 self.assertEqual(expected, actual) 824 self.assertEqual(expected, actual)
726 825
727 def testCopyingBucketSubDirToBucketSubDirWithNested(self): 826 def testCopyingBucketSubDirToBucketSubDirWithNested(self):
728 """Tests copying a bucket subdir to another bucket subdir with nesting.""" 827 """Tests copying a bucket subdir to another bucket subdir with nesting."""
729 src_bucket_uri = self.CreateBucket( 828 src_bucket_uri = self.CreateBucket(
730 test_objects=['src_subdir_%d/obj' % i for i in range(4)] + 829 test_objects=['src_subdir_%d/obj' % i for i in range(4)] +
731 ['src_subdir_%d/nested/obj' % i for i in range(4)]) 830 ['src_subdir_%d/nested/obj' % i for i in range(4)])
732 dst_bucket_uri = self.CreateBucket( 831 dst_bucket_uri = self.CreateBucket(
733 test_objects=['dst_subdir_%d/obj2' % i for i in range(4)]) 832 test_objects=['dst_subdir_%d/obj2' % i for i in range(4)])
734 # Test with and without final slash on dest subdir. 833 # Test with and without final slash on dest subdir.
735 for i, (final_src_char, final_dst_char) in enumerate(( 834 for i, (final_src_char, final_dst_char) in enumerate((
736 ('', ''), ('', '/'), ('/', ''), ('/', '/') )): 835 ('', ''), ('', '/'), ('/', ''), ('/', '/'))):
737 self.RunCommand( 836 self.RunCommand(
738 'cp', ['-R', suri(src_bucket_uri, 'src_subdir_%d' % i) + final_src_cha r, 837 'cp', ['-R',
838 suri(src_bucket_uri, 'src_subdir_%d' % i) + final_src_char,
739 suri(dst_bucket_uri, 'dst_subdir_%d' % i) + final_dst_char]) 839 suri(dst_bucket_uri, 'dst_subdir_%d' % i) + final_dst_char])
740 actual = set(str(u) for u in self._test_wildcard_iterator( 840 actual = set(str(u) for u in self._test_wildcard_iterator(
741 suri(dst_bucket_uri, 'dst_subdir_%d' % i, '**')).IterUris()) 841 suri(dst_bucket_uri, 'dst_subdir_%d' % i, '**')).IterAll(
842 expand_top_level_buckets=True))
742 expected = set([suri(dst_bucket_uri, 'dst_subdir_%d' % i, 843 expected = set([suri(dst_bucket_uri, 'dst_subdir_%d' % i,
743 'src_subdir_%d' % i, 'obj'), 844 'src_subdir_%d' % i, 'obj'),
744 suri(dst_bucket_uri, 'dst_subdir_%d' % i, 845 suri(dst_bucket_uri, 'dst_subdir_%d' % i,
745 'src_subdir_%d' % i, 'nested', 'obj'), 846 'src_subdir_%d' % i, 'nested', 'obj'),
746 suri(dst_bucket_uri, 'dst_subdir_%d' % i, 'obj2')]) 847 suri(dst_bucket_uri, 'dst_subdir_%d' % i, 'obj2')])
747 self.assertEqual(expected, actual) 848 self.assertEqual(expected, actual)
748 849
749 def testMovingBucketSubDirToExistingBucketSubDir(self): 850 def testMovingBucketSubDirToExistingBucketSubDir(self):
750 """Tests moving a bucket subdir to a existing bucket subdir""" 851 """Tests moving a bucket subdir to a existing bucket subdir."""
751 src_objs = ['foo'] 852 src_objs = ['foo']
752 for i in range(4): 853 for i in range(4):
753 src_objs.extend(['src_subdir%d/foo2' % i, 'src_subdir%d/nested/foo3' % i]) 854 src_objs.extend(['src_subdir%d/foo2' % i, 'src_subdir%d/nested/foo3' % i])
754 src_bucket_uri = self.CreateBucket(test_objects=src_objs) 855 src_bucket_uri = self.CreateBucket(test_objects=src_objs)
755 dst_bucket_uri = self.CreateBucket( 856 dst_bucket_uri = self.CreateBucket(
756 test_objects=['dst_subdir%d/existing' % i for i in range(4)]) 857 test_objects=['dst_subdir%d/existing' % i for i in range(4)])
757 # Test with and without final slash on dest subdir. 858 # Test with and without final slash on dest subdir.
758 for i, (final_src_char, final_dst_char) in enumerate(( 859 for i, (final_src_char, final_dst_char) in enumerate((
759 ('', ''), ('', '/'), ('/', ''), ('/', '/') )): 860 ('', ''), ('', '/'), ('/', ''), ('/', '/'))):
760 self.RunCommand( 861 self.RunCommand(
761 'mv', [suri(src_bucket_uri, 'src_subdir%d' % i) + final_src_char, 862 'mv', [suri(src_bucket_uri, 'src_subdir%d' % i) + final_src_char,
762 suri(dst_bucket_uri, 'dst_subdir%d' % i) + final_dst_char]) 863 suri(dst_bucket_uri, 'dst_subdir%d' % i) + final_dst_char])
763 864
764 actual = set(str(u) for u in self._test_wildcard_iterator( 865 actual = set(str(u) for u in self._test_wildcard_iterator(
765 suri(dst_bucket_uri, '**')).IterUris()) 866 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
766 expected = set() 867 expected = set()
767 for i in range(4): 868 for i in range(4):
768 expected.add(suri(dst_bucket_uri, 'dst_subdir%d' % i, 'existing')) 869 expected.add(suri(dst_bucket_uri, 'dst_subdir%d' % i, 'existing'))
769 expected.add(suri(dst_bucket_uri, 'dst_subdir%d' % i, 'src_subdir%d' %i, 870 expected.add(suri(dst_bucket_uri, 'dst_subdir%d' % i, 'src_subdir%d' %i,
770 'foo2')) 871 'foo2'))
771 expected.add(suri(dst_bucket_uri, 'dst_subdir%d' % i, 'src_subdir%d' %i, 872 expected.add(suri(dst_bucket_uri, 'dst_subdir%d' % i, 'src_subdir%d' %i,
772 'nested', 'foo3')) 873 'nested', 'foo3'))
773 self.assertEqual(expected, actual) 874 self.assertEqual(expected, actual)
774 875
775 def testCopyingObjectToBucketSubDir(self): 876 def testCopyingObjectToBucketSubDir(self):
776 """Tests copying an object to a bucket subdir""" 877 """Tests copying an object to a bucket subdir."""
777 src_bucket_uri = self.CreateBucket(test_objects=['obj0']) 878 src_bucket_uri = self.CreateBucket(test_objects=['obj0'])
778 dst_bucket_uri = self.CreateBucket(test_objects=['dir0/existing', 879 dst_bucket_uri = self.CreateBucket(test_objects=['dir0/existing',
779 'dir1/existing']) 880 'dir1/existing'])
780 # Test with and without final slash on dest subdir. 881 # Test with and without final slash on dest subdir.
781 for i, final_dst_char in enumerate(('', '/')): 882 for i, final_dst_char in enumerate(('', '/')):
782 self.RunCommand('cp', [ 883 self.RunCommand('cp', [
783 suri(src_bucket_uri, 'obj0'), 884 suri(src_bucket_uri, 'obj0'),
784 suri(dst_bucket_uri, 'dir%d' % i) + final_dst_char]) 885 suri(dst_bucket_uri, 'dir%d' % i) + final_dst_char])
785 actual = set(str(u) for u in self._test_wildcard_iterator( 886 actual = set(str(u) for u in self._test_wildcard_iterator(
786 suri(dst_bucket_uri, 'dir%d' % i, '**')).IterUris()) 887 suri(dst_bucket_uri, 'dir%d' % i, '**')).IterAll(
888 expand_top_level_buckets=True))
787 expected = set([suri(dst_bucket_uri, 'dir%d' % i, 'obj0'), 889 expected = set([suri(dst_bucket_uri, 'dir%d' % i, 'obj0'),
788 suri(dst_bucket_uri, 'dir%d' % i, 'existing')]) 890 suri(dst_bucket_uri, 'dir%d' % i, 'existing')])
789 self.assertEqual(expected, actual) 891 self.assertEqual(expected, actual)
790 892
791 @PerformsFileToObjectUpload 893 # @PerformsFileToObjectUpload
792 def testCopyingWildcardedFilesToBucketSubDir(self): 894 def testCopyingWildcardedFilesToBucketSubDir(self):
793 """Tests copying wildcarded files to a bucket subdir""" 895 """Tests copying wildcarded files to a bucket subdir."""
794 dst_bucket_uri = self.CreateBucket(test_objects=['subdir0/existing', 896 dst_bucket_uri = self.CreateBucket(test_objects=['subdir0/existing',
795 'subdir1/existing']) 897 'subdir1/existing'])
796 src_dir = self.CreateTempDir(test_files=['f0', 'f1', 'f2']) 898 src_dir = self.CreateTempDir(test_files=['f0', 'f1', 'f2'])
797 # Test with and without final slash on dest subdir. 899 # Test with and without final slash on dest subdir.
798 for i, final_dst_char in enumerate(('', '/')): 900 for i, final_dst_char in enumerate(('', '/')):
799 self.RunCommand( 901 self.RunCommand(
800 'cp', [os.path.join(src_dir, 'f?'), 902 'cp', [os.path.join(src_dir, 'f?'),
801 suri(dst_bucket_uri, 'subdir%d' % i) + final_dst_char]) 903 suri(dst_bucket_uri, 'subdir%d' % i) + final_dst_char])
802 actual = set(str(u) for u in self._test_wildcard_iterator( 904 actual = set(str(u) for u in self._test_wildcard_iterator(
803 suri(dst_bucket_uri, 'subdir%d' % i, '**')).IterUris()) 905 suri(dst_bucket_uri, 'subdir%d' % i, '**')).IterAll(
906 expand_top_level_buckets=True))
804 expected = set([suri(dst_bucket_uri, 'subdir%d' % i, 'existing'), 907 expected = set([suri(dst_bucket_uri, 'subdir%d' % i, 'existing'),
805 suri(dst_bucket_uri, 'subdir%d' % i, 'f0'), 908 suri(dst_bucket_uri, 'subdir%d' % i, 'f0'),
806 suri(dst_bucket_uri, 'subdir%d' % i, 'f1'), 909 suri(dst_bucket_uri, 'subdir%d' % i, 'f1'),
807 suri(dst_bucket_uri, 'subdir%d' % i, 'f2')]) 910 suri(dst_bucket_uri, 'subdir%d' % i, 'f2')])
808 self.assertEqual(expected, actual) 911 self.assertEqual(expected, actual)
809 912
810 @PerformsFileToObjectUpload 913 # @PerformsFileToObjectUpload
811 def testCopyingOneNestedFileToBucketSubDir(self): 914 def testCopyingOneNestedFileToBucketSubDir(self):
812 """Tests copying one nested file to a bucket subdir""" 915 """Tests copying one nested file to a bucket subdir."""
813 dst_bucket_uri = self.CreateBucket(test_objects=['d0/placeholder', 916 dst_bucket_uri = self.CreateBucket(test_objects=['d0/placeholder',
814 'd1/placeholder']) 917 'd1/placeholder'])
815 src_dir = self.CreateTempDir(test_files=[('d3', 'd4', 'nested', 'f1')]) 918 src_dir = self.CreateTempDir(test_files=[('d3', 'd4', 'nested', 'f1')])
816 # Test with and without final slash on dest subdir. 919 # Test with and without final slash on dest subdir.
817 for i, final_dst_char in enumerate(('', '/')): 920 for i, final_dst_char in enumerate(('', '/')):
818 self.RunCommand('cp', ['-r', suri(src_dir, 'd3'), 921 self.RunCommand('cp', ['-r', suri(src_dir, 'd3'),
819 suri(dst_bucket_uri, 'd%d' % i) + final_dst_char]) 922 suri(dst_bucket_uri, 'd%d' % i) + final_dst_char])
820 actual = set(str(u) for u in self._test_wildcard_iterator( 923 actual = set(str(u) for u in self._test_wildcard_iterator(
821 suri(dst_bucket_uri, '**')).IterUris()) 924 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
822 expected = set([ 925 expected = set([
823 suri(dst_bucket_uri, 'd0', 'placeholder'), 926 suri(dst_bucket_uri, 'd0', 'placeholder'),
824 suri(dst_bucket_uri, 'd1', 'placeholder'), 927 suri(dst_bucket_uri, 'd1', 'placeholder'),
825 suri(dst_bucket_uri, 'd0', 'd3', 'd4', 'nested', 'f1'), 928 suri(dst_bucket_uri, 'd0', 'd3', 'd4', 'nested', 'f1'),
826 suri(dst_bucket_uri, 'd1', 'd3', 'd4', 'nested', 'f1')]) 929 suri(dst_bucket_uri, 'd1', 'd3', 'd4', 'nested', 'f1')])
827 self.assertEqual(expected, actual) 930 self.assertEqual(expected, actual)
828 931
829 def testMovingWildcardedFilesToNonExistentBucketSubDir(self): 932 def testMovingWildcardedFilesToNonExistentBucketSubDir(self):
830 """Tests moving files to a non-existent bucket subdir""" 933 """Tests moving files to a non-existent bucket subdir."""
831 # This tests for how we allow users to do something like: 934 # This tests for how we allow users to do something like:
832 # gsutil cp *.txt gs://bucket/dir 935 # gsutil cp *.txt gs://bucket/dir
833 # where *.txt matches more than 1 file and gs://bucket/dir 936 # where *.txt matches more than 1 file and gs://bucket/dir
834 # doesn't exist as a subdir. 937 # doesn't exist as a subdir.
835 # 938 #
836 src_bucket_uri = self.CreateBucket(test_objects=[ 939 src_bucket_uri = self.CreateBucket(test_objects=[
837 'f0f0', 'f0f1', 'f1f0', 'f1f1']) 940 'f0f0', 'f0f1', 'f1f0', 'f1f1'])
838 dst_bucket_uri = self.CreateBucket(test_objects=[ 941 dst_bucket_uri = self.CreateBucket(test_objects=[
839 'dst_subdir0/existing_obj', 'dst_subdir1/existing_obj']) 942 'dst_subdir0/existing_obj', 'dst_subdir1/existing_obj'])
840 # Test with and without final slash on dest subdir. 943 # Test with and without final slash on dest subdir.
841 for i, final_dst_char in enumerate(('', '/')): 944 for i, final_dst_char in enumerate(('', '/')):
842 # Copy some files into place in dst bucket. 945 # Copy some files into place in dst bucket.
843 self.RunCommand( 946 self.RunCommand(
844 'cp', [suri(src_bucket_uri, 'f%df*' % i), 947 'cp', [suri(src_bucket_uri, 'f%df*' % i),
845 suri(dst_bucket_uri, 'dst_subdir%d' % i) + final_dst_char]) 948 suri(dst_bucket_uri, 'dst_subdir%d' % i) + final_dst_char])
846 # Now do the move test. 949 # Now do the move test.
847 self.RunCommand( 950 self.RunCommand(
848 'mv', [suri(src_bucket_uri, 'f%d*' % i), 951 'mv', [suri(src_bucket_uri, 'f%d*' % i),
849 suri(dst_bucket_uri, 'nonexisting%d' % i) + final_dst_char]) 952 suri(dst_bucket_uri, 'nonexisting%d' % i) + final_dst_char])
850 953
851 actual = set(str(u) for u in self._test_wildcard_iterator( 954 actual = set(str(u) for u in self._test_wildcard_iterator(
852 suri(dst_bucket_uri, '**')).IterUris()) 955 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
853 expected = set([ 956 expected = set([
854 suri(dst_bucket_uri, 'dst_subdir0', 'existing_obj'), 957 suri(dst_bucket_uri, 'dst_subdir0', 'existing_obj'),
855 suri(dst_bucket_uri, 'dst_subdir0', 'f0f0'), 958 suri(dst_bucket_uri, 'dst_subdir0', 'f0f0'),
856 suri(dst_bucket_uri, 'dst_subdir0', 'f0f1'), 959 suri(dst_bucket_uri, 'dst_subdir0', 'f0f1'),
857 suri(dst_bucket_uri, 'nonexisting0', 'f0f0'), 960 suri(dst_bucket_uri, 'nonexisting0', 'f0f0'),
858 suri(dst_bucket_uri, 'nonexisting0', 'f0f1'), 961 suri(dst_bucket_uri, 'nonexisting0', 'f0f1'),
859 suri(dst_bucket_uri, 'dst_subdir1', 'existing_obj'), 962 suri(dst_bucket_uri, 'dst_subdir1', 'existing_obj'),
860 suri(dst_bucket_uri, 'dst_subdir1', 'f1f0'), 963 suri(dst_bucket_uri, 'dst_subdir1', 'f1f0'),
861 suri(dst_bucket_uri, 'dst_subdir1', 'f1f1'), 964 suri(dst_bucket_uri, 'dst_subdir1', 'f1f1'),
862 suri(dst_bucket_uri, 'nonexisting1', 'f1f0'), 965 suri(dst_bucket_uri, 'nonexisting1', 'f1f0'),
863 suri(dst_bucket_uri, 'nonexisting1', 'f1f1')]) 966 suri(dst_bucket_uri, 'nonexisting1', 'f1f1')])
864 self.assertEqual(expected, actual) 967 self.assertEqual(expected, actual)
865 968
866 def testMovingObjectToBucketSubDir(self): 969 def testMovingObjectToBucketSubDir(self):
867 """Tests moving an object to a bucket subdir""" 970 """Tests moving an object to a bucket subdir."""
868 src_bucket_uri = self.CreateBucket(test_objects=['obj0', 'obj1']) 971 src_bucket_uri = self.CreateBucket(test_objects=['obj0', 'obj1'])
869 dst_bucket_uri = self.CreateBucket(test_objects=[ 972 dst_bucket_uri = self.CreateBucket(test_objects=[
870 'dst_subdir0/existing_obj', 'dst_subdir1/existing_obj']) 973 'dst_subdir0/existing_obj', 'dst_subdir1/existing_obj'])
871 # Test with and without final slash on dest subdir. 974 # Test with and without final slash on dest subdir.
872 for i, final_dst_char in enumerate(('', '/')): 975 for i, final_dst_char in enumerate(('', '/')):
873 self.RunCommand( 976 self.RunCommand(
874 'mv', [suri(src_bucket_uri, 'obj%d' % i), 977 'mv', [suri(src_bucket_uri, 'obj%d' % i),
875 suri(dst_bucket_uri, 'dst_subdir%d' % i) + final_dst_char]) 978 suri(dst_bucket_uri, 'dst_subdir%d' % i) + final_dst_char])
876 979
877 actual = set(str(u) for u in self._test_wildcard_iterator( 980 actual = set(str(u) for u in self._test_wildcard_iterator(
878 suri(dst_bucket_uri, '**')).IterUris()) 981 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
879 expected = set([ 982 expected = set([
880 suri(dst_bucket_uri, 'dst_subdir0', 'existing_obj'), 983 suri(dst_bucket_uri, 'dst_subdir0', 'existing_obj'),
881 suri(dst_bucket_uri, 'dst_subdir0', 'obj0'), 984 suri(dst_bucket_uri, 'dst_subdir0', 'obj0'),
882 suri(dst_bucket_uri, 'dst_subdir1', 'existing_obj'), 985 suri(dst_bucket_uri, 'dst_subdir1', 'existing_obj'),
883 suri(dst_bucket_uri, 'dst_subdir1', 'obj1')]) 986 suri(dst_bucket_uri, 'dst_subdir1', 'obj1')])
884 self.assertEqual(expected, actual) 987 self.assertEqual(expected, actual)
885 988
886 actual = set(str(u) for u in self._test_wildcard_iterator( 989 actual = set(str(u) for u in self._test_wildcard_iterator(
887 suri(src_bucket_uri, '**')).IterUris()) 990 suri(src_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
888 self.assertEqual(actual, set()) 991 self.assertEqual(actual, set())
889 992
890 def testWildcardSrcSubDirMoveDisallowed(self): 993 def testWildcardSrcSubDirMoveDisallowed(self):
891 """Tests moving a bucket subdir specified by wildcard is disallowed""" 994 """Tests moving a bucket subdir specified by wildcard is disallowed."""
892 src_bucket_uri = self.CreateBucket(test_objects=['dir/foo1']) 995 src_bucket_uri = self.CreateBucket(test_objects=['dir/foo1'])
893 dst_bucket_uri = self.CreateBucket(test_objects=['dir/foo2']) 996 dst_bucket_uri = self.CreateBucket(test_objects=['dir/foo2'])
894 try: 997 try:
895 self.RunCommand( 998 self.RunCommand(
896 'mv', [suri(src_bucket_uri, 'dir*'), suri(dst_bucket_uri, 'dir')]) 999 'mv', [suri(src_bucket_uri, 'dir*'), suri(dst_bucket_uri, 'dir')])
897 self.fail('Did not get expected CommandException') 1000 self.fail('Did not get expected CommandException')
898 except CommandException, e: 1001 except CommandException, e:
899 self.assertIn('mv command disallows naming', e.reason) 1002 self.assertIn('mv command disallows naming', e.reason)
900 1003
901 def testMovingBucketSubDirToNonExistentBucketSubDir(self): 1004 def testMovingBucketSubDirToNonExistentBucketSubDir(self):
902 """Tests moving a bucket subdir to a non-existent bucket subdir""" 1005 """Tests moving a bucket subdir to a non-existent bucket subdir."""
903 src_bucket = self.CreateBucket(test_objects=[ 1006 src_bucket = self.CreateBucket(test_objects=[
904 'foo', 'src_subdir0/foo2', 'src_subdir0/nested/foo3', 1007 'foo', 'src_subdir0/foo2', 'src_subdir0/nested/foo3',
905 'src_subdir1/foo2', 'src_subdir1/nested/foo3']) 1008 'src_subdir1/foo2', 'src_subdir1/nested/foo3'])
906 dst_bucket = self.CreateBucket() 1009 dst_bucket = self.CreateBucket()
907 # Test with and without final slash on dest subdir. 1010 # Test with and without final slash on dest subdir.
908 for i, final_src_char in enumerate(('', '/')): 1011 for i, final_src_char in enumerate(('', '/')):
909 self.RunCommand( 1012 self.RunCommand(
910 'mv', [suri(src_bucket, 'src_subdir%d' % i) + final_src_char, 1013 'mv', [suri(src_bucket, 'src_subdir%d' % i) + final_src_char,
911 suri(dst_bucket, 'dst_subdir%d' % i)]) 1014 suri(dst_bucket, 'dst_subdir%d' % i)])
912 1015
913 actual = set(str(u) for u in self._test_wildcard_iterator( 1016 actual = set(str(u) for u in self._test_wildcard_iterator(
914 suri(dst_bucket, '**')).IterUris()) 1017 suri(dst_bucket, '**')).IterAll(expand_top_level_buckets=True))
915 # Unlike the case with copying, with mv we expect renaming to occur 1018 # Unlike the case with copying, with mv we expect renaming to occur
916 # at the level of the src subdir, vs appending that subdir beneath the 1019 # at the level of the src subdir, vs appending that subdir beneath the
917 # dst subdir like is done for copying. 1020 # dst subdir like is done for copying.
918 expected = set([suri(dst_bucket, 'dst_subdir0', 'foo2'), 1021 expected = set([suri(dst_bucket, 'dst_subdir0', 'foo2'),
919 suri(dst_bucket, 'dst_subdir1', 'foo2'), 1022 suri(dst_bucket, 'dst_subdir1', 'foo2'),
920 suri(dst_bucket, 'dst_subdir0', 'nested', 'foo3'), 1023 suri(dst_bucket, 'dst_subdir0', 'nested', 'foo3'),
921 suri(dst_bucket, 'dst_subdir1', 'nested', 'foo3')]) 1024 suri(dst_bucket, 'dst_subdir1', 'nested', 'foo3')])
922 self.assertEqual(expected, actual) 1025 self.assertEqual(expected, actual)
923 1026
924 def testRemovingBucketSubDir(self): 1027 def testRemovingBucketSubDir(self):
925 """Tests removing a bucket subdir""" 1028 """Tests removing a bucket subdir."""
926 dst_bucket_uri = self.CreateBucket(test_objects=[ 1029 dst_bucket_uri = self.CreateBucket(test_objects=[
927 'f0', 'dir0/f1', 'dir0/nested/f2', 'dir1/f1', 'dir1/nested/f2']) 1030 'f0', 'dir0/f1', 'dir0/nested/f2', 'dir1/f1', 'dir1/nested/f2'])
928 # Test with and without final slash on dest subdir. 1031 # Test with and without final slash on dest subdir.
929 for i, final_src_char in enumerate(('', '/')): 1032 for i, final_src_char in enumerate(('', '/')):
930 # Test removing bucket subdir. 1033 # Test removing bucket subdir.
931 self.RunCommand( 1034 self.RunCommand(
932 'rm', ['-R', suri(dst_bucket_uri, 'dir%d' % i) + final_src_char]) 1035 'rm', ['-R', suri(dst_bucket_uri, 'dir%d' % i) + final_src_char])
933 actual = set(str(u) for u in self._test_wildcard_iterator( 1036 actual = set(str(u) for u in self._test_wildcard_iterator(
934 suri(dst_bucket_uri, '**')).IterUris()) 1037 suri(dst_bucket_uri, '**')).IterAll(expand_top_level_buckets=True))
935 expected = set([suri(dst_bucket_uri, 'f0')]) 1038 expected = set([suri(dst_bucket_uri, 'f0')])
936 self.assertEqual(expected, actual) 1039 self.assertEqual(expected, actual)
937 1040
938 def testRecursiveRemoveObjsInBucket(self): 1041 def testRecursiveRemoveObjsInBucket(self):
939 """Tests removing all objects in bucket via rm -R gs://bucket""" 1042 """Tests removing all objects in bucket via rm -R gs://bucket."""
940 bucket_uris = [ 1043 bucket_uris = [
941 self.CreateBucket(test_objects=['f0', 'dir/f1', 'dir/nested/f2']), 1044 self.CreateBucket(test_objects=['f0', 'dir/f1', 'dir/nested/f2']),
942 self.CreateBucket(test_objects=['f0', 'dir/f1', 'dir/nested/f2'])] 1045 self.CreateBucket(test_objects=['f0', 'dir/f1', 'dir/nested/f2'])]
943 # Test with and without final slash on dest subdir. 1046 # Test with and without final slash on dest subdir.
944 for i, final_src_char in enumerate(('', '/')): 1047 for i, final_src_char in enumerate(('', '/')):
945 # Test removing all objects via rm -R. 1048 # Test removing all objects via rm -R.
946 self.RunCommand('rm', ['-R', suri(bucket_uris[i]) + final_src_char]) 1049 self.RunCommand('rm', ['-R', suri(bucket_uris[i]) + final_src_char])
947 try: 1050 try:
948 self.RunCommand('ls', [suri(bucket_uris[i])]) 1051 self.RunCommand('ls', [suri(bucket_uris[i])])
949 # Ensure exception is raised. 1052 # Ensure exception is raised.
950 self.assertTrue(False) 1053 self.assertTrue(False)
951 except boto.exception.StorageResponseError, e: 1054 except NotFoundException, e:
952 self.assertEqual(e.status, 404) 1055 self.assertEqual(e.status, 404)
953 1056
954 def testUnicodeArgs(self): 1057 def testUnicodeArgs(self):
955 """Tests that you can list an object with unicode characters.""" 1058 """Tests that you can list an object with unicode characters."""
956 object_name = u'フォ' 1059 object_name = u'フォ'
957 bucket_uri = self.CreateBucket() 1060 bucket_uri = self.CreateBucket()
958 self.CreateObject(bucket_uri=bucket_uri, object_name=object_name, 1061 self.CreateObject(bucket_uri=bucket_uri, object_name=object_name,
959 contents='foo') 1062 contents='foo')
960 object_name_bytes = object_name.encode('utf-8') 1063 object_name_bytes = object_name.encode(UTF8)
961 stdout = self.RunCommand('ls', [suri(bucket_uri, object_name_bytes)], 1064 stdout = self.RunCommand('ls', [suri(bucket_uri, object_name_bytes)],
962 return_stdout=True) 1065 return_stdout=True)
963 self.assertIn(object_name_bytes, stdout) 1066 self.assertIn(object_name_bytes, stdout)
964 1067
965 def testRecursiveListTrailingSlash(self): 1068 def testRecursiveListTrailingSlash(self):
966 bucket_uri = self.CreateBucket() 1069 bucket_uri = self.CreateBucket()
967 obj_uri = self.CreateObject( 1070 obj_uri = self.CreateObject(
968 bucket_uri=bucket_uri, object_name='/', contents='foo') 1071 bucket_uri=bucket_uri, object_name='/', contents='foo')
969 stdout = self.RunCommand('ls', ['-R', suri(bucket_uri)], return_stdout=True) 1072 stdout = self.RunCommand('ls', ['-R', suri(bucket_uri)], return_stdout=True)
970 # Note: The suri function normalizes the URI, so the double slash gets 1073 # Note: The suri function normalizes the URI, so the double slash gets
971 # removed. 1074 # removed.
972 self.assertEqual(stdout.splitlines(), [suri(obj_uri) + '/']) 1075 self.assertEqual(stdout.splitlines(), [suri(obj_uri) + '/:',
1076 suri(obj_uri) + '/'])
973 1077
974 def FinalObjNameComponent(self, uri): 1078 def FinalObjNameComponent(self, uri):
975 """For gs://bucket/abc/def/ghi returns ghi.""" 1079 """For gs://bucket/abc/def/ghi returns ghi."""
976 return uri.uri.rpartition('/')[-1] 1080 return uri.uri.rpartition('/')[-1]
977 1081
1082 def testFileContainingColon(self):
1083 url_str = 'abc:def'
1084 url = StorageUrlFromString(url_str)
1085 self.assertEqual('file', url.scheme)
1086 self.assertEqual('file://%s' % url_str, url.url_string)
1087
978 1088
979 # TODO: These should all be moved to their own test_*.py testing files. 1089 # TODO: These should all be moved to their own test_*.py testing files.
980 class GsUtilCommandTests(testcase.GsUtilUnitTestCase): 1090 class GsUtilCommandTests(testcase.GsUtilUnitTestCase):
981 """Basic sanity check tests to make sure commands run.""" 1091 """Basic sanity check tests to make sure commands run."""
982 1092
983 def testDisableLoggingCommandRuns(self): 1093 def testDisableLoggingCommandRuns(self):
984 """Test that the 'logging set off' command basically runs""" 1094 """Test that the 'logging set off' command basically runs."""
985 src_bucket_uri = self.CreateBucket() 1095 src_bucket_uri = self.CreateBucket()
986 self.RunCommand('logging', ['set', 'off', suri(src_bucket_uri)]) 1096 self.RunCommand('logging', ['set', 'off', suri(src_bucket_uri)])
987 1097
988 def testEnableLoggingCommandRuns(self): 1098 def testEnableLoggingCommandRuns(self):
989 """Test that the 'logging set on' command basically runs""" 1099 """Test that the 'logging set on' command basically runs."""
990 src_bucket_uri = self.CreateBucket() 1100 src_bucket_uri = self.CreateBucket()
991 self.RunCommand('logging', ['set', 'on', '-b', 'gs://log_bucket', 1101 self.RunCommand('logging', ['set', 'on', '-b', 'gs://log_bucket',
992 suri(src_bucket_uri)]) 1102 suri(src_bucket_uri)])
993 1103
994 def testHelpCommandDoesntRaise(self): 1104 def testHelpCommandDoesntRaise(self):
995 """Test that the help command doesn't raise (sanity checks all help)""" 1105 """Test that the help command doesn't raise (sanity checks all help)."""
996 # Unset PAGER if defined, so help output paginating into $PAGER doesn't 1106 # Unset PAGER if defined, so help output paginating into $PAGER doesn't
997 # cause test to pause. 1107 # cause test to pause.
998 if 'PAGER' in os.environ: 1108 if 'PAGER' in os.environ:
999 del os.environ['PAGER'] 1109 del os.environ['PAGER']
1000 self.RunCommand('help', []) 1110 self.RunCommand('help', [])
1001 1111
1002 def testCatCommandRuns(self): 1112 def testCatCommandRuns(self):
1003 """Test that the cat command basically runs""" 1113 """Test that the cat command basically runs."""
1004 src_uri = self.CreateObject(contents='foo') 1114 src_uri = self.CreateObject(contents='foo')
1005 stdout = self.RunCommand('cat', [suri(src_uri)], return_stdout=True) 1115 stdout = self.RunCommand('cat', [suri(src_uri)], return_stdout=True)
1006 self.assertEqual(stdout, 'foo') 1116 self.assertEqual(stdout, 'foo')
1007 1117
1008 def testGetAclCommandRuns(self):
1009 """Test that the 'acl get' command basically runs"""
1010 src_bucket_uri = self.CreateBucket()
1011 self.RunCommand('acl', ['get', suri(src_bucket_uri)])
1012
1013 def testGetDefAclCommandRuns(self):
1014 """Test that the 'defacl get' command basically runs"""
1015 src_bucket_uri = self.CreateBucket()
1016 self.RunCommand('defacl', ['get', suri(src_bucket_uri)])
1017
1018 def testGetLoggingCommandRuns(self): 1118 def testGetLoggingCommandRuns(self):
1019 """Test that the 'logging get' command basically runs""" 1119 """Test that the 'logging get' command basically runs."""
1020 src_bucket_uri = self.CreateBucket() 1120 src_bucket_uri = self.CreateBucket()
1021 self.RunCommand('logging', ['get', suri(src_bucket_uri)]) 1121 self.RunCommand('logging', ['get', suri(src_bucket_uri)])
1022 1122
1023 def testMakeBucketsCommand(self): 1123 def testMakeBucketsCommand(self):
1024 """Test mb on existing bucket""" 1124 """Test mb on existing bucket."""
1025 dst_bucket_uri = self.CreateBucket() 1125 dst_bucket_uri = self.CreateBucket()
1026 try: 1126 try:
1027 self.RunCommand('mb', [suri(dst_bucket_uri)]) 1127 self.RunCommand('mb', [suri(dst_bucket_uri)])
1028 self.fail('Did not get expected StorageCreateError') 1128 self.fail('Did not get expected StorageCreateError')
1029 except boto.exception.StorageCreateError, e: 1129 except ServiceException, e:
1030 self.assertEqual(e.status, 409) 1130 self.assertEqual(e.status, 409)
1031 1131
1032 def testRemoveBucketsCommand(self): 1132 def testRemoveBucketsCommand(self):
1033 """Test rb on non-existent bucket""" 1133 """Test rb on non-existent bucket."""
1034 dst_bucket_uri = self.CreateBucket() 1134 dst_bucket_uri = self.CreateBucket()
1035 try: 1135 try:
1036 self.RunCommand( 1136 self.RunCommand(
1037 'rb', ['gs://non_existent_%s' % dst_bucket_uri.bucket_name]) 1137 'rb', ['gs://no_exist_%s' % dst_bucket_uri.bucket_name])
1038 self.fail('Did not get expected StorageResponseError') 1138 self.fail('Did not get expected NotFoundException')
1039 except boto.exception.StorageResponseError, e: 1139 except NotFoundException, e:
1040 self.assertEqual(e.status, 404) 1140 self.assertEqual(e.status, 404)
1041 1141
1042 def testRemoveObjsCommand(self): 1142 def testRemoveObjsCommand(self):
1043 """Test rm command on non-existent object""" 1143 """Test rm command on non-existent object."""
1044 dst_bucket_uri = self.CreateBucket() 1144 dst_bucket_uri = self.CreateBucket()
1045 try: 1145 try:
1046 self.RunCommand('rm', [suri(dst_bucket_uri, 'non_existent')]) 1146 self.RunCommand('rm', [suri(dst_bucket_uri, 'non_existent')])
1047 self.fail('Did not get expected WildcardException') 1147 self.fail('Did not get expected CommandException')
1048 except StorageResponseError, e: 1148 except CommandException, e:
1049 self.assertIn('Not Found', e.reason) 1149 self.assertIn('No URLs matched', e.reason)
1050 1150
1051 # Now that gsutil ver computes a checksum it adds 1-3 seconds to test run 1151 # Now that gsutil ver computes a checksum it adds 1-3 seconds to test run
1052 # time (for in memory mocked tests that otherwise take ~ 0.1 seconds). Since 1152 # time (for in memory mocked tests that otherwise take ~ 0.1 seconds). Since
1053 # it provides very little test value, we're leaving this test commented out. 1153 # it provides very little test value, we're leaving this test commented out.
1054 #def testVerCommmandRuns(self): 1154 # def testVerCommmandRuns(self):
1055 # """Test that the Ver command basically runs""" 1155 # """Test that the Ver command basically runs"""
1056 # self.RunCommand('ver', []) 1156 # self.RunCommand('ver', [])
OLDNEW
« no previous file with comments | « gslib/tests/test_mv.py ('k') | gslib/tests/test_notification.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698