| OLD | NEW |
| 1 # -*- coding: utf-8 -*- |
| 1 # Copyright 2013 Google Inc. All Rights Reserved. | 2 # Copyright 2013 Google Inc. All Rights Reserved. |
| 2 # | 3 # |
| 3 # Licensed under the Apache License, Version 2.0 (the "License"); | 4 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 # you may not use this file except in compliance with the License. | 5 # you may not use this file except in compliance with the License. |
| 5 # You may obtain a copy of the License at | 6 # You may obtain a copy of the License at |
| 6 # | 7 # |
| 7 # http://www.apache.org/licenses/LICENSE-2.0 | 8 # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 # | 9 # |
| 9 # Unless required by applicable law or agreed to in writing, software | 10 # Unless required by applicable law or agreed to in writing, software |
| 10 # distributed under the License is distributed on an "AS IS" BASIS, | 11 # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 # See the License for the specific language governing permissions and | 13 # See the License for the specific language governing permissions and |
| 13 # limitations under the License. | 14 # limitations under the License. |
| 15 """Integration tests for rm command.""" |
| 16 |
| 17 from __future__ import absolute_import |
| 14 | 18 |
| 15 import gslib.tests.testcase as testcase | 19 import gslib.tests.testcase as testcase |
| 16 from boto.exception import GSResponseError | |
| 17 from gslib.exception import CommandException | |
| 18 from gslib.tests.testcase.base import MAX_BUCKET_LENGTH | 20 from gslib.tests.testcase.base import MAX_BUCKET_LENGTH |
| 19 from gslib.tests.util import ObjectToURI as suri | 21 from gslib.tests.util import ObjectToURI as suri |
| 20 from gslib.util import Retry | 22 from gslib.util import Retry |
| 21 | 23 |
| 22 | 24 |
| 23 class TestRm(testcase.GsUtilIntegrationTestCase): | 25 class TestRm(testcase.GsUtilIntegrationTestCase): |
| 24 """Integration tests for rm command.""" | 26 """Integration tests for rm command.""" |
| 25 | 27 |
| 26 def test_all_versions_current(self): | 28 def test_all_versions_current(self): |
| 27 """Test that 'rm -a' for an object with a current version works.""" | 29 """Test that 'rm -a' for an object with a current version works.""" |
| 28 bucket_uri = self.CreateVersionedBucket() | 30 bucket_uri = self.CreateVersionedBucket() |
| 29 key_uri = bucket_uri.clone_replace_name('foo') | 31 key_uri = bucket_uri.clone_replace_name('foo') |
| 30 key_uri.set_contents_from_string('bar') | 32 key_uri.set_contents_from_string('bar') |
| 31 g1 = key_uri.generation | 33 g1 = key_uri.generation or key_uri.version_id |
| 32 key_uri.set_contents_from_string('baz') | 34 key_uri.set_contents_from_string('baz') |
| 33 g2 = key_uri.generation | 35 g2 = key_uri.generation or key_uri.version_id |
| 34 # Use @Retry as hedge against bucket listing eventual consistency. | 36 # Use @Retry as hedge against bucket listing eventual consistency. |
| 35 @Retry(AssertionError, tries=3, timeout_secs=1) | 37 @Retry(AssertionError, tries=3, timeout_secs=1) |
| 36 def _Check1(stderr_lines): | 38 def _Check1(stderr_lines): |
| 37 stderr = self.RunGsUtil(['-m', 'rm', '-a', suri(key_uri)], | 39 stderr = self.RunGsUtil(['-m', 'rm', '-a', suri(key_uri)], |
| 38 return_stderr=True) | 40 return_stderr=True) |
| 39 stderr_lines.update(set(stderr.splitlines())) | 41 stderr_lines.update(set(stderr.splitlines())) |
| 40 stderr = '\n'.join(stderr_lines) | 42 stderr = '\n'.join(stderr_lines) |
| 41 self.assertEqual(stderr.count('Removing gs://'), 2) | 43 self.assertEqual(stderr.count('Removing %s://' % self.default_provider), |
| 44 2) |
| 42 self.assertIn('Removing %s#%s...' % (suri(key_uri), g1), stderr) | 45 self.assertIn('Removing %s#%s...' % (suri(key_uri), g1), stderr) |
| 43 self.assertIn('Removing %s#%s...' % (suri(key_uri), g2), stderr) | 46 self.assertIn('Removing %s#%s...' % (suri(key_uri), g2), stderr) |
| 44 all_stderr_lines = set() | 47 all_stderr_lines = set() |
| 45 _Check1(all_stderr_lines) | 48 _Check1(all_stderr_lines) |
| 46 # Use @Retry as hedge against bucket listing eventual consistency. | 49 self.AssertNObjectsInBucket(bucket_uri, 0, versioned=True) |
| 47 @Retry(AssertionError, tries=3, timeout_secs=1) | |
| 48 def _Check2(): | |
| 49 stdout = self.RunGsUtil(['ls', '-a', suri(bucket_uri)], | |
| 50 return_stdout=True) | |
| 51 self.assertEqual(stdout, '') | |
| 52 _Check2() | |
| 53 | 50 |
| 54 def test_all_versions_no_current(self): | 51 def test_all_versions_no_current(self): |
| 55 """Test that 'rm -a' for an object without a current version works.""" | 52 """Test that 'rm -a' for an object without a current version works.""" |
| 56 bucket_uri = self.CreateVersionedBucket() | 53 bucket_uri = self.CreateVersionedBucket() |
| 57 key_uri = bucket_uri.clone_replace_name('foo') | 54 key_uri = bucket_uri.clone_replace_name('foo') |
| 58 key_uri.set_contents_from_string('bar') | 55 key_uri.set_contents_from_string('bar') |
| 59 g1 = key_uri.generation | 56 g1 = key_uri.generation or key_uri.version_id |
| 60 key_uri.set_contents_from_string('baz') | 57 key_uri.set_contents_from_string('baz') |
| 61 g2 = key_uri.generation | 58 g2 = key_uri.generation or key_uri.version_id |
| 62 stderr = self.RunGsUtil(['rm', suri(key_uri)], return_stderr=True) | 59 stderr = self.RunGsUtil(['rm', suri(key_uri)], return_stderr=True) |
| 63 self.assertEqual(stderr.count('Removing gs://'), 1) | 60 self.assertEqual(stderr.count('Removing %s://' % self.default_provider), 1) |
| 64 self.assertIn('Removing %s...' % suri(key_uri), stderr) | 61 self.assertIn('Removing %s...' % suri(key_uri), stderr) |
| 65 stderr = self.RunGsUtil(['-m', 'rm', '-a', suri(key_uri)], | 62 stderr = self.RunGsUtil(['-m', 'rm', '-a', suri(key_uri)], |
| 66 return_stderr=True) | 63 return_stderr=True) |
| 67 self.assertEqual(stderr.count('Removing gs://'), 2) | 64 self.assertEqual(stderr.count('Removing %s://' % self.default_provider), 2) |
| 68 self.assertIn('Removing %s#%s...' % (suri(key_uri), g1), stderr) | 65 self.assertIn('Removing %s#%s...' % (suri(key_uri), g1), stderr) |
| 69 self.assertIn('Removing %s#%s...' % (suri(key_uri), g2), stderr) | 66 self.assertIn('Removing %s#%s...' % (suri(key_uri), g2), stderr) |
| 70 # Use @Retry as hedge against bucket listing eventual consistency. | 67 # Use @Retry as hedge against bucket listing eventual consistency. |
| 71 @Retry(AssertionError, tries=3, timeout_secs=1) | 68 self.AssertNObjectsInBucket(bucket_uri, 0, versioned=True) |
| 72 def _Check1(): | |
| 73 stdout = self.RunGsUtil(['ls', '-a', suri(bucket_uri)], | |
| 74 return_stdout=True) | |
| 75 self.assertEqual(stdout, '') | |
| 76 _Check1() | |
| 77 | 69 |
| 78 def test_fails_for_missing_obj(self): | 70 def test_fails_for_missing_obj(self): |
| 79 bucket_uri = self.CreateVersionedBucket() | 71 bucket_uri = self.CreateVersionedBucket() |
| 80 stderr = self.RunGsUtil(['rm', '-a', '%s/foo' % suri(bucket_uri)], | 72 stderr = self.RunGsUtil(['rm', '-a', '%s/foo' % suri(bucket_uri)], |
| 81 return_stderr=True, expected_status=1) | 73 return_stderr=True, expected_status=1) |
| 82 self.assertIn('Not Found', stderr) | 74 self.assertIn('No URLs matched', stderr) |
| 83 | 75 |
| 84 def test_remove_all_versions_recursive_on_bucket(self): | 76 def test_remove_all_versions_recursive_on_bucket(self): |
| 85 """Test that 'rm -ar' works on bucket.""" | 77 """Test that 'rm -r' works on bucket.""" |
| 86 bucket_uri = self.CreateVersionedBucket() | 78 bucket_uri = self.CreateVersionedBucket() |
| 87 k1_uri = bucket_uri.clone_replace_name('foo') | 79 k1_uri = bucket_uri.clone_replace_name('foo') |
| 88 k2_uri = bucket_uri.clone_replace_name('foo2') | 80 k2_uri = bucket_uri.clone_replace_name('foo2') |
| 89 k1_uri.set_contents_from_string('bar') | 81 k1_uri.set_contents_from_string('bar') |
| 90 k2_uri.set_contents_from_string('bar2') | 82 k2_uri.set_contents_from_string('bar2') |
| 91 k1g1 = k1_uri.generation | 83 k1g1 = k1_uri.generation or k1_uri.version_id |
| 92 k2g1 = k2_uri.generation | 84 k2g1 = k2_uri.generation or k2_uri.version_id |
| 93 k1_uri.set_contents_from_string('baz') | 85 k1_uri.set_contents_from_string('baz') |
| 94 k2_uri.set_contents_from_string('baz2') | 86 k2_uri.set_contents_from_string('baz2') |
| 95 k1g2 = k1_uri.generation | 87 k1g2 = k1_uri.generation or k1_uri.version_id |
| 96 k2g2 = k2_uri.generation | 88 k2g2 = k2_uri.generation or k2_uri.version_id |
| 89 |
| 90 self.AssertNObjectsInBucket(bucket_uri, 4, versioned=True) |
| 91 |
| 92 all_stderr_lines = set() |
| 93 stderr = self.RunGsUtil(['rm', '-r', suri(bucket_uri)], |
| 94 return_stderr=True) |
| 95 all_stderr_lines.update(set(stderr.splitlines())) |
| 96 stderr = '\n'.join(all_stderr_lines) |
| 97 self.assertEqual(stderr.count('Removing %s://' % self.default_provider), 5) |
| 98 self.assertIn('Removing %s#%s...' % (suri(k1_uri), k1g1), stderr) |
| 99 self.assertIn('Removing %s#%s...' % (suri(k1_uri), k1g2), stderr) |
| 100 self.assertIn('Removing %s#%s...' % (suri(k2_uri), k2g1), stderr) |
| 101 self.assertIn('Removing %s#%s...' % (suri(k2_uri), k2g2), stderr) |
| 102 self.assertIn('Removing %s/...' % suri(bucket_uri), stderr) |
| 97 | 103 |
| 98 # Use @Retry as hedge against bucket listing eventual consistency. | 104 # Use @Retry as hedge against bucket listing eventual consistency. |
| 99 @Retry(AssertionError, tries=3, timeout_secs=1) | 105 @Retry(AssertionError, tries=3, timeout_secs=1) |
| 100 def _Check(stderr_lines): | 106 def _Check(): |
| 101 status = self.RunGsUtil(['ls', '-b', suri(bucket_uri)], | |
| 102 return_status=True, expected_status=None) | |
| 103 if status == 0: | |
| 104 # If ls succeeded, the bucket exists, so try and delete. | |
| 105 stderr = self.RunGsUtil(['rm', '-ar', suri(bucket_uri)], | |
| 106 return_stderr=True) | |
| 107 stderr_lines.update(set(stderr.splitlines())) | |
| 108 stderr = '\n'.join(stderr_lines) | |
| 109 self.assertEqual(stderr.count('Removing gs://'), 5) | |
| 110 self.assertIn('Removing %s#%s...' % (suri(k1_uri), k1g1), stderr) | |
| 111 self.assertIn('Removing %s#%s...' % (suri(k1_uri), k1g2), stderr) | |
| 112 self.assertIn('Removing %s#%s...' % (suri(k2_uri), k2g1), stderr) | |
| 113 self.assertIn('Removing %s#%s...' % (suri(k2_uri), k2g2), stderr) | |
| 114 # Bucket should no longer exist. | 107 # Bucket should no longer exist. |
| 115 stderr = self.RunGsUtil(['ls', '-a', suri(bucket_uri)], | 108 stderr = self.RunGsUtil(['ls', '-a', suri(bucket_uri)], |
| 116 return_stderr=True, expected_status=1) | 109 return_stderr=True, expected_status=1) |
| 117 self.assertIn('bucket does not exist', stderr) | 110 self.assertIn('bucket does not exist', stderr) |
| 118 all_stderr_lines = set() | 111 _Check() |
| 119 _Check(all_stderr_lines) | |
| 120 | 112 |
| 121 def test_remove_all_versions_recursive_on_subdir(self): | 113 def test_remove_all_versions_recursive_on_subdir(self): |
| 122 """Test that 'rm -ar' works on subdir.""" | 114 """Test that 'rm -r' works on subdir.""" |
| 123 bucket_uri = self.CreateVersionedBucket() | 115 bucket_uri = self.CreateVersionedBucket() |
| 124 k1_uri = bucket_uri.clone_replace_name('dir/foo') | 116 k1_uri = bucket_uri.clone_replace_name('dir/foo') |
| 125 k2_uri = bucket_uri.clone_replace_name('dir/foo2') | 117 k2_uri = bucket_uri.clone_replace_name('dir/foo2') |
| 126 k1_uri.set_contents_from_string('bar') | 118 k1_uri.set_contents_from_string('bar') |
| 127 k2_uri.set_contents_from_string('bar2') | 119 k2_uri.set_contents_from_string('bar2') |
| 128 k1g1 = k1_uri.generation | 120 k1g1 = k1_uri.generation or k1_uri.version_id |
| 129 k2g1 = k2_uri.generation | 121 k2g1 = k2_uri.generation or k2_uri.version_id |
| 130 k1_uri.set_contents_from_string('baz') | 122 k1_uri.set_contents_from_string('baz') |
| 131 k2_uri.set_contents_from_string('baz2') | 123 k2_uri.set_contents_from_string('baz2') |
| 132 k1g2 = k1_uri.generation | 124 k1g2 = k1_uri.generation or k1_uri.version_id |
| 133 k2g2 = k2_uri.generation | 125 k2g2 = k2_uri.generation or k2_uri.version_id |
| 126 self.AssertNObjectsInBucket(bucket_uri, 4, versioned=True) |
| 134 | 127 |
| 135 stderr = self.RunGsUtil(['rm', '-ar', '%s/dir' % suri(bucket_uri)], | 128 stderr = self.RunGsUtil(['rm', '-r', '%s/dir' % suri(bucket_uri)], |
| 136 return_stderr=True) | 129 return_stderr=True) |
| 137 self.assertEqual(stderr.count('Removing gs://'), 4) | 130 self.assertEqual(stderr.count('Removing %s://' % self.default_provider), 4) |
| 138 self.assertIn('Removing %s#%s...' % (suri(k1_uri), k1g1), stderr) | 131 self.assertIn('Removing %s#%s...' % (suri(k1_uri), k1g1), stderr) |
| 139 self.assertIn('Removing %s#%s...' % (suri(k1_uri), k1g2), stderr) | 132 self.assertIn('Removing %s#%s...' % (suri(k1_uri), k1g2), stderr) |
| 140 self.assertIn('Removing %s#%s...' % (suri(k2_uri), k2g1), stderr) | 133 self.assertIn('Removing %s#%s...' % (suri(k2_uri), k2g1), stderr) |
| 141 self.assertIn('Removing %s#%s...' % (suri(k2_uri), k2g2), stderr) | 134 self.assertIn('Removing %s#%s...' % (suri(k2_uri), k2g2), stderr) |
| 142 # Use @Retry as hedge against bucket listing eventual consistency. | 135 self.AssertNObjectsInBucket(bucket_uri, 0, versioned=True) |
| 143 @Retry(AssertionError, tries=3, timeout_secs=1) | 136 |
| 144 def _Check1(): | 137 def test_missing_first_force(self): |
| 145 stdout = self.RunGsUtil(['ls', '-a', suri(bucket_uri)], | 138 bucket_uri = self.CreateBucket() |
| 146 return_stdout=True) | 139 object_uri = self.CreateObject(bucket_uri=bucket_uri, object_name='present', |
| 147 self.assertEqual(stdout, '') | 140 contents='foo') |
| 148 _Check1() | 141 self.AssertNObjectsInBucket(bucket_uri, 1) |
| 142 self.RunGsUtil(['rm', '%s/missing' % suri(bucket_uri), |
| 143 suri(object_uri)], expected_status=1) |
| 144 stderr = self.RunGsUtil( |
| 145 ['rm', '-f', '%s/missing' % suri(bucket_uri), suri(object_uri)], |
| 146 return_stderr=True, expected_status=1) |
| 147 self.assertEqual(stderr.count('Removing %s://' % self.default_provider), 1) |
| 148 self.RunGsUtil(['stat', suri(object_uri)], expected_status=1) |
| 149 | 149 |
| 150 def test_some_missing(self): | 150 def test_some_missing(self): |
| 151 """Test that 'rm -a' fails when some but not all uris don't exist.""" | 151 """Test that 'rm -a' fails when some but not all uris don't exist.""" |
| 152 bucket_uri = self.CreateVersionedBucket() | 152 bucket_uri = self.CreateVersionedBucket() |
| 153 key_uri = bucket_uri.clone_replace_name('foo') | 153 key_uri = bucket_uri.clone_replace_name('foo') |
| 154 key_uri.set_contents_from_string('bar') | 154 key_uri.set_contents_from_string('bar') |
| 155 self.AssertNObjectsInBucket(bucket_uri, 1, versioned=True) |
| 155 stderr = self.RunGsUtil(['rm', '-a', suri(key_uri), '%s/missing' | 156 stderr = self.RunGsUtil(['rm', '-a', suri(key_uri), '%s/missing' |
| 156 % suri(bucket_uri)], | 157 % suri(bucket_uri)], |
| 157 return_stderr=True, expected_status=1) | 158 return_stderr=True, expected_status=1) |
| 158 self.assertEqual(stderr.count('Removing gs://'), 2) | 159 self.assertEqual(stderr.count('Removing %s://' % self.default_provider), 1) |
| 159 self.assertIn('Not Found', stderr) | 160 self.assertIn('No URLs matched', stderr) |
| 160 | 161 |
| 161 def test_some_missing_force(self): | 162 def test_some_missing_force(self): |
| 162 """Test that 'rm -af' succeeds despite hidden first uri.""" | 163 """Test that 'rm -af' succeeds despite hidden first uri.""" |
| 163 bucket_uri = self.CreateVersionedBucket() | 164 bucket_uri = self.CreateVersionedBucket() |
| 164 key_uri = bucket_uri.clone_replace_name('foo') | 165 key_uri = bucket_uri.clone_replace_name('foo') |
| 165 key_uri.set_contents_from_string('bar') | 166 key_uri.set_contents_from_string('bar') |
| 166 stderr = self.RunGsUtil(['rm', '-af', suri(key_uri), '%s/missing' | 167 self.AssertNObjectsInBucket(bucket_uri, 1, versioned=True) |
| 167 % suri(bucket_uri)], return_stderr=True) | 168 stderr = self.RunGsUtil( |
| 168 self.assertEqual(stderr.count('Removing gs://'), 2) | 169 ['rm', '-af', suri(key_uri), '%s/missing' % suri(bucket_uri)], |
| 169 # Use @Retry as hedge against bucket listing eventual consistency. | 170 return_stderr=True, expected_status=1) |
| 170 @Retry(AssertionError, tries=3, timeout_secs=1) | 171 self.assertEqual(stderr.count('Removing %s://' % self.default_provider), 1) |
| 171 def _Check1(): | 172 self.AssertNObjectsInBucket(bucket_uri, 0) |
| 172 stdout = self.RunGsUtil(['ls', '-a', suri(bucket_uri)], | |
| 173 return_stdout=True) | |
| 174 self.assertEqual(stdout, '') | |
| 175 _Check1() | |
| 176 | 173 |
| 177 def test_folder_objects_deleted(self): | 174 def test_folder_objects_deleted(self): |
| 178 """Test for 'rm -r' of a folder with a dir_$folder$ marker.""" | 175 """Test for 'rm -r' of a folder with a dir_$folder$ marker.""" |
| 179 bucket_uri = self.CreateVersionedBucket() | 176 bucket_uri = self.CreateVersionedBucket() |
| 180 key_uri = bucket_uri.clone_replace_name('abc/o1') | 177 key_uri = bucket_uri.clone_replace_name('abc/o1') |
| 181 key_uri.set_contents_from_string('foobar') | 178 key_uri.set_contents_from_string('foobar') |
| 182 folderkey = bucket_uri.clone_replace_name('abc_$folder$') | 179 folderkey = bucket_uri.clone_replace_name('abc_$folder$') |
| 183 folderkey.set_contents_from_string('') | 180 folderkey.set_contents_from_string('') |
| 184 # Use @Retry as hedge against bucket listing eventual consistency. | 181 self.AssertNObjectsInBucket(bucket_uri, 2, versioned=True) |
| 185 @Retry(AssertionError, tries=3, timeout_secs=1) | 182 self.RunGsUtil(['rm', '-r', '%s/abc' % suri(bucket_uri)]) |
| 186 def _Check1(): | 183 self.AssertNObjectsInBucket(bucket_uri, 0, versioned=True) |
| 187 self.RunGsUtil(['rm', '-r', '%s/abc' % suri(bucket_uri)]) | 184 # Bucket should not be deleted (Should not get ServiceException). |
| 188 stdout = self.RunGsUtil(['ls', suri(bucket_uri)], return_stdout=True) | 185 bucket_uri.get_location(validate=False) |
| 189 self.assertEqual(stdout, '') | 186 |
| 190 _Check1() | 187 def test_folder_objects_deleted_with_wildcard(self): |
| 191 # Bucket should not be deleted (Should not get GSResponseError). | 188 """Test for 'rm -r' of a folder with a dir_$folder$ marker.""" |
| 189 bucket_uri = self.CreateVersionedBucket() |
| 190 key_uri = bucket_uri.clone_replace_name('abc/o1') |
| 191 key_uri.set_contents_from_string('foobar') |
| 192 folderkey = bucket_uri.clone_replace_name('abc_$folder$') |
| 193 folderkey.set_contents_from_string('') |
| 194 |
| 195 self.AssertNObjectsInBucket(bucket_uri, 2, versioned=True) |
| 196 stderr = self.RunGsUtil(['rm', '-r', '%s/**' % suri(bucket_uri)], |
| 197 return_stderr=True) |
| 198 # Folder wildcard should not generate an error if it's not matched. |
| 199 self.assertNotIn('No URLs matched', stderr) |
| 200 |
| 201 self.AssertNObjectsInBucket(bucket_uri, 0, versioned=True) |
| 202 # Bucket should not be deleted (Should not get ServiceException). |
| 192 bucket_uri.get_location(validate=False) | 203 bucket_uri.get_location(validate=False) |
| 193 | 204 |
| 194 def test_recursive_bucket_rm(self): | 205 def test_recursive_bucket_rm(self): |
| 195 """Test for 'rm -r' of a bucket.""" | 206 """Test for 'rm -r' of a bucket.""" |
| 196 bucket_uri = self.CreateBucket() | 207 bucket_uri = self.CreateBucket() |
| 197 self.CreateObject(bucket_uri) | 208 self.CreateObject(bucket_uri) |
| 209 self.RunGsUtil(['rm', '-r', suri(bucket_uri)]) |
| 198 # Use @Retry as hedge against bucket listing eventual consistency. | 210 # Use @Retry as hedge against bucket listing eventual consistency. |
| 199 @Retry(AssertionError, tries=3, timeout_secs=1) | 211 @Retry(AssertionError, tries=3, timeout_secs=1) |
| 200 def _Check1(): | 212 def _Check1(): |
| 201 self.RunGsUtil(['rm', '-r', suri(bucket_uri)]) | |
| 202 # Bucket should be deleted. | 213 # Bucket should be deleted. |
| 203 stderr = self.RunGsUtil(['ls', '-Lb', suri(bucket_uri)], | 214 stderr = self.RunGsUtil(['ls', '-Lb', suri(bucket_uri)], |
| 204 return_stderr=True, expected_status=1) | 215 return_stderr=True, expected_status=1) |
| 205 self.assertIn('bucket does not exist', stderr) | 216 self.assertIn('bucket does not exist', stderr) |
| 206 _Check1() | 217 _Check1() |
| 207 | 218 |
| 208 # Now try same thing, but for a versioned bucket with multiple versions of | 219 # Now try same thing, but for a versioned bucket with multiple versions of |
| 209 # an object present. | 220 # an object present. |
| 210 bucket_uri = self.CreateVersionedBucket() | 221 bucket_uri = self.CreateVersionedBucket() |
| 211 self.CreateObject(bucket_uri, 'obj', 'z') | 222 self.CreateObject(bucket_uri, 'obj', 'z') |
| 212 self.CreateObject(bucket_uri, 'obj', 'z') | 223 self.CreateObject(bucket_uri, 'obj', 'z') |
| 213 self.CreateObject(bucket_uri, 'obj', 'z') | 224 self.CreateObject(bucket_uri, 'obj', 'z') |
| 214 stderr = self.RunGsUtil(['rm', '-r', suri(bucket_uri)], | 225 self.AssertNObjectsInBucket(bucket_uri, 3, versioned=True) |
| 226 self.RunGsUtil(['rm', suri(bucket_uri, '**')]) |
| 227 stderr = self.RunGsUtil(['rb', suri(bucket_uri)], |
| 215 return_stderr=True, expected_status=1) | 228 return_stderr=True, expected_status=1) |
| 216 self.assertIn('versioning enabled', stderr) | 229 self.assertIn('Bucket is not empty', stderr) |
| 217 | 230 |
| 218 # Now try with rm -ra. | 231 # Now try with rm -r. |
| 219 @Retry(AssertionError, tries=3, timeout_secs=1) | 232 @Retry(AssertionError, tries=3, timeout_secs=1) |
| 220 def _Check2(): | 233 def _Check2(): |
| 221 self.RunGsUtil(['rm', '-ra', suri(bucket_uri)]) | 234 self.RunGsUtil(['rm', '-r', suri(bucket_uri)]) |
| 222 # Bucket should be deleted. | 235 # Bucket should be deleted. |
| 223 stderr = self.RunGsUtil(['ls', '-Lb', suri(bucket_uri)], | 236 stderr = self.RunGsUtil(['ls', '-Lb', suri(bucket_uri)], |
| 224 return_stderr=True, expected_status=1) | 237 return_stderr=True, expected_status=1) |
| 225 self.assertIn('bucket does not exist', stderr) | 238 self.assertIn('bucket does not exist', stderr) |
| 226 _Check2() | 239 _Check2() |
| 227 | 240 |
| 228 def test_recursive_bucket_rm_with_wildcarding(self): | 241 def test_recursive_bucket_rm_with_wildcarding(self): |
| 229 """Tests removing all objects and buckets matching a bucket wildcard""" | 242 """Tests removing all objects and buckets matching a bucket wildcard.""" |
| 230 buri_base = 'gsutil-test-%s' % self._testMethodName | 243 buri_base = 'gsutil-test-%s' % self._testMethodName |
| 231 buri_base = buri_base[:MAX_BUCKET_LENGTH-20] | 244 buri_base = buri_base[:MAX_BUCKET_LENGTH-20] |
| 232 buri_base = '%s-%s' % (buri_base, self.MakeRandomTestString()) | 245 buri_base = '%s-%s' % (buri_base, self.MakeRandomTestString()) |
| 233 buri1 = self.CreateBucket(bucket_name='%s-tbuck1' % buri_base) | 246 buri1 = self.CreateBucket(bucket_name='%s-tbuck1' % buri_base) |
| 234 buri2 = self.CreateBucket(bucket_name='%s-tbuck2' % buri_base) | 247 buri2 = self.CreateBucket(bucket_name='%s-tbuck2' % buri_base) |
| 235 buri3 = self.CreateBucket(bucket_name='%s-tb3' % buri_base) | 248 buri3 = self.CreateBucket(bucket_name='%s-tb3' % buri_base) |
| 236 ouri1 = self.CreateObject(bucket_uri=buri1, object_name='o1', contents='z') | 249 self.CreateObject(bucket_uri=buri1, object_name='o1', contents='z') |
| 237 ouri2 = self.CreateObject(bucket_uri=buri2, object_name='o2', contents='z') | 250 self.CreateObject(bucket_uri=buri2, object_name='o2', contents='z') |
| 238 ouri3 = self.CreateObject(bucket_uri=buri3, object_name='o3', contents='z') | 251 self.CreateObject(bucket_uri=buri3, object_name='o3', contents='z') |
| 239 @Retry(AssertionError, tries=3, timeout_secs=1) | 252 @Retry(AssertionError, tries=3, timeout_secs=1) |
| 240 def _Check(): | 253 def _Check(): |
| 241 self.RunGsUtil(['rm', '-r', 'gs://%s-tbu*' % buri_base]) | 254 self.RunGsUtil(['rm', '-r', '%s://%s-tbu*' % (self.default_provider, |
| 242 stdout = self.RunGsUtil(['ls', 'gs://%s-tb*' % buri_base], | 255 buri_base)]) |
| 256 stdout = self.RunGsUtil(['ls', '%s://%s-tb*' % (self.default_provider, |
| 257 buri_base)], |
| 243 return_stdout=True) | 258 return_stdout=True) |
| 244 # 2 = one for single expected line plus one for final \n. | 259 # 2 = one for single expected line plus one for final \n. |
| 245 self.assertEqual(2, len(stdout.split('\n'))) | 260 self.assertEqual(2, len(stdout.split('\n'))) |
| 246 self.assertEqual('gs://%s-tb3/o3' % buri_base, stdout.strip()) | 261 self.assertEqual('%s://%s-tb3/o3' % (self.default_provider, buri_base), |
| 262 stdout.strip()) |
| 247 _Check() | 263 _Check() |
| 248 | 264 |
| 249 def test_rm_quiet(self): | 265 def test_rm_quiet(self): |
| 250 """Test that 'rm -q' outputs no progress indications.""" | 266 """Test that 'rm -q' outputs no progress indications.""" |
| 251 bucket_uri = self.CreateBucket() | 267 bucket_uri = self.CreateBucket() |
| 252 key_uri = self.CreateObject(bucket_uri=bucket_uri, contents='foo') | 268 key_uri = self.CreateObject(bucket_uri=bucket_uri, contents='foo') |
| 269 self.AssertNObjectsInBucket(bucket_uri, 1) |
| 253 stderr = self.RunGsUtil(['-q', 'rm', suri(key_uri)], return_stderr=True) | 270 stderr = self.RunGsUtil(['-q', 'rm', suri(key_uri)], return_stderr=True) |
| 254 self.assertEqual(stderr.count('Removing '), 0) | 271 self.assertEqual(stderr.count('Removing '), 0) |
| 272 |
| 273 def test_rm_object_with_slash(self): |
| 274 """Tests removing a bucket that has an object with a slash in it.""" |
| 275 bucket_uri = self.CreateVersionedBucket() |
| 276 ouri1 = self.CreateObject(bucket_uri=bucket_uri, |
| 277 object_name='/dirwithslash/foo', contents='z') |
| 278 ouri2 = self.CreateObject(bucket_uri=bucket_uri, |
| 279 object_name='dirnoslash/foo', contents='z') |
| 280 ouri3 = self.CreateObject(bucket_uri=bucket_uri, |
| 281 object_name='dirnoslash/foo2', contents='z') |
| 282 |
| 283 self.AssertNObjectsInBucket(bucket_uri, 3, versioned=True) |
| 284 |
| 285 # Test with and without final slash on dest subdir. |
| 286 all_stderr_lines = set() |
| 287 stderr = self.RunGsUtil(['rm', '-r', suri(bucket_uri)], |
| 288 return_stderr=True) |
| 289 all_stderr_lines.update(set(stderr.splitlines())) |
| 290 stderr = '\n'.join(all_stderr_lines) |
| 291 self.assertEqual(stderr.count('Removing %s://' % self.default_provider), 4) |
| 292 self.assertIn('Removing %s' % suri(ouri1), stderr) |
| 293 self.assertIn('Removing %s' % suri(ouri2), stderr) |
| 294 self.assertIn('Removing %s' % suri(ouri3), stderr) |
| 295 |
| 296 def test_slasher_horror_film(self): |
| 297 """Tests removing a bucket with objects that are filled with slashes.""" |
| 298 bucket_uri = self.CreateVersionedBucket() |
| 299 ouri1 = self.CreateObject(bucket_uri=bucket_uri, |
| 300 object_name='h/e/l//lo', |
| 301 contents='Halloween') |
| 302 ouri2 = self.CreateObject(bucket_uri=bucket_uri, |
| 303 object_name='/h/e/l/l/o', |
| 304 contents='A Nightmare on Elm Street') |
| 305 ouri3 = self.CreateObject(bucket_uri=bucket_uri, |
| 306 object_name='//h//e/l//l/o', |
| 307 contents='Friday the 13th') |
| 308 ouri4 = self.CreateObject(bucket_uri=bucket_uri, |
| 309 object_name='//h//e//l//l//o', |
| 310 contents='I Know What You Did Last Summer') |
| 311 ouri5 = self.CreateObject(bucket_uri=bucket_uri, |
| 312 object_name='/', |
| 313 contents='Scream') |
| 314 ouri6 = self.CreateObject(bucket_uri=bucket_uri, |
| 315 object_name='//', |
| 316 contents='Child\'s Play') |
| 317 ouri7 = self.CreateObject(bucket_uri=bucket_uri, |
| 318 object_name='///', |
| 319 contents='The Prowler') |
| 320 ouri8 = self.CreateObject(bucket_uri=bucket_uri, |
| 321 object_name='////', |
| 322 contents='Black Christmas') |
| 323 ouri9 = self.CreateObject( |
| 324 bucket_uri=bucket_uri, |
| 325 object_name='everything/is/better/with/slashes///////', |
| 326 contents='Maniac') |
| 327 |
| 328 self.AssertNObjectsInBucket(bucket_uri, 9, versioned=True) |
| 329 |
| 330 all_stderr_lines = set() |
| 331 stderr = self.RunGsUtil(['rm', '-r', suri(bucket_uri)], |
| 332 return_stderr=True) |
| 333 all_stderr_lines.update(set(stderr.splitlines())) |
| 334 stderr = '\n'.join(all_stderr_lines) |
| 335 self.assertEqual(stderr.count('Removing %s://' % self.default_provider), 10) |
| 336 self.assertIn('Removing %s' % suri(ouri1), stderr) |
| 337 self.assertIn('Removing %s' % suri(ouri2), stderr) |
| 338 self.assertIn('Removing %s' % suri(ouri3), stderr) |
| 339 self.assertIn('Removing %s' % suri(ouri4), stderr) |
| 340 self.assertIn('Removing %s' % suri(ouri5), stderr) |
| 341 self.assertIn('Removing %s' % suri(ouri6), stderr) |
| 342 self.assertIn('Removing %s' % suri(ouri7), stderr) |
| 343 self.assertIn('Removing %s' % suri(ouri8), stderr) |
| 344 self.assertIn('Removing %s' % suri(ouri9), stderr) |
| 345 self.assertIn('Removing %s' % suri(bucket_uri), stderr) |
| 346 |
| OLD | NEW |