| OLD | NEW |
| 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', []) |
| OLD | NEW |