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

Side by Side Diff: third_party/gsutil/gslib/tests/test_rsync.py

Issue 1380943003: Roll version of gsutil to 4.15. (Closed) Base URL: https://github.com/catapult-project/catapult.git@master
Patch Set: rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/gsutil/gslib/tests/test_rm.py ('k') | third_party/gsutil/gslib/tests/test_trace.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 # Copyright 2014 Google Inc. All Rights Reserved. 2 # Copyright 2014 Google Inc. All Rights Reserved.
3 # 3 #
4 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # 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.
6 # You may obtain a copy of the License at 6 # You may obtain a copy of the License at
7 # 7 #
8 # http://www.apache.org/licenses/LICENSE-2.0 8 # http://www.apache.org/licenses/LICENSE-2.0
9 # 9 #
10 # Unless required by applicable law or agreed to in writing, software 10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS, 11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and 13 # See the License for the specific language governing permissions and
14 # limitations under the License. 14 # limitations under the License.
15 """Integration tests for rsync command.""" 15 """Integration tests for rsync command."""
16 16
17 import os 17 import os
18 18
19 import crcmod 19 import crcmod
20 20
21 import gslib.tests.testcase as testcase 21 import gslib.tests.testcase as testcase
22 from gslib.tests.testcase.integration_testcase import SkipForS3 22 from gslib.tests.testcase.integration_testcase import SkipForS3
23 from gslib.tests.util import ObjectToURI as suri 23 from gslib.tests.util import ObjectToURI as suri
24 from gslib.tests.util import PerformsFileToObjectUpload 24 from gslib.tests.util import SequentialAndParallelTransfer
25 from gslib.tests.util import SetBotoConfigForTest 25 from gslib.tests.util import SetBotoConfigForTest
26 from gslib.tests.util import unittest 26 from gslib.tests.util import unittest
27 from gslib.util import IS_WINDOWS 27 from gslib.util import IS_WINDOWS
28 from gslib.util import Retry 28 from gslib.util import Retry
29 from gslib.util import UsingCrcmodExtension 29 from gslib.util import UsingCrcmodExtension
30 30
31 NO_CHANGES = 'Building synchronization state...\nStarting synchronization\n' 31 NO_CHANGES = 'Building synchronization state...\nStarting synchronization\n'
32 32
33 33
34 def _TailSet(start_point, listing): 34 def _TailSet(start_point, listing):
35 """Returns set of object name tails. 35 """Returns set of object name tails.
36 36
37 Tails can be compared between source and dest, past the point at which rsync 37 Tails can be compared between source and dest, past the point at which rsync
38 was done. For example if test ran rsync gs://bucket1/dir gs://bucket2/dir2, 38 was done. For example if test ran rsync gs://bucket1/dir gs://bucket2/dir2,
39 the tails for listings from bucket1 would start after "dir", while the tails 39 the tails for listings from bucket1 would start after "dir", while the tails
40 for listings from bucket2 would start after "dir2". 40 for listings from bucket2 would start after "dir2".
41 41
42 Args: 42 Args:
43 start_point: The target of the rsync command, e.g., for the above command it 43 start_point: The target of the rsync command, e.g., for the above command it
44 would be gs://bucket1/dir for the bucket1 listing results and 44 would be gs://bucket1/dir for the bucket1 listing results and
45 gs://bucket2/dir2 for the bucket2 listing results. 45 gs://bucket2/dir2 for the bucket2 listing results.
46 listing: The listing over which to compute tail. 46 listing: The listing over which to compute tail.
47 47
48 Returns: 48 Returns:
49 Object name tails. 49 Object name tails.
50 """ 50 """
51 return set(l[len(start_point):] for l in listing.strip().split('\n')) 51 return set(l[len(start_point):] for l in listing.strip().split('\n'))
52 52
53
53 # TODO: Add inspection to the retry wrappers in this test suite where the state 54 # TODO: Add inspection to the retry wrappers in this test suite where the state
54 # at the end of a retry block is depended upon by subsequent tests (since 55 # at the end of a retry block is depended upon by subsequent tests (since
55 # listing content can vary depending on which backend server is reached until 56 # listing content can vary depending on which backend server is reached until
56 # eventual consistency is reached). 57 # eventual consistency is reached).
57 # TODO: Remove retry wrappers and AssertNObjectsInBucket calls if GCS ever 58 # TODO: Remove retry wrappers and AssertNObjectsInBucket calls if GCS ever
58 # supports strong listing consistency. 59 # supports strong listing consistency.
59 class TestRsync(testcase.GsUtilIntegrationTestCase): 60 class TestRsync(testcase.GsUtilIntegrationTestCase):
60 """Integration tests for rsync command.""" 61 """Integration tests for rsync command."""
61 62
62 @staticmethod 63 @staticmethod
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 # Note: The tests below exercise the cases 106 # Note: The tests below exercise the cases
106 # {src_dir, src_bucket} X {dst_dir, dst_bucket}. We use gsutil rsync -d for 107 # {src_dir, src_bucket} X {dst_dir, dst_bucket}. We use gsutil rsync -d for
107 # all the cases but then have just one test without -d (test_bucket_to_bucket) 108 # all the cases but then have just one test without -d (test_bucket_to_bucket)
108 # as representative of handling without the -d option. This provides 109 # as representative of handling without the -d option. This provides
109 # reasonable test coverage because the -d handling it src/dest URI-type 110 # reasonable test coverage because the -d handling it src/dest URI-type
110 # independent, and keeps the test case combinations more manageable. 111 # independent, and keeps the test case combinations more manageable.
111 112
112 def test_bucket_to_bucket(self): 113 def test_bucket_to_bucket(self):
113 """Tests that flat and recursive rsync between 2 buckets works correctly.""" 114 """Tests that flat and recursive rsync between 2 buckets works correctly."""
114 # Create 2 buckets with 1 overlapping object, 1 extra object at root level 115 # Create 2 buckets with 1 overlapping object, 1 extra object at root level
115 # in each, and 1 extra object 1 level down in each. Make the overlapping 116 # in each, and 1 extra object 1 level down in each, where one of the objects
116 # objects named the same but with different content, to test that we detect 117 # starts with "." to test that we don't skip those objects. Make the
117 # and properly copy in that case. 118 # overlapping objects named the same but with different content, to test
119 # that we detect and properly copy in that case.
118 bucket1_uri = self.CreateBucket() 120 bucket1_uri = self.CreateBucket()
119 bucket2_uri = self.CreateBucket() 121 bucket2_uri = self.CreateBucket()
120 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj1', 122 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj1',
121 contents='obj1') 123 contents='obj1')
122 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj2', 124 self.CreateObject(bucket_uri=bucket1_uri, object_name='.obj2',
123 contents='obj2') 125 contents='.obj2')
124 self.CreateObject(bucket_uri=bucket1_uri, object_name='subdir/obj3', 126 self.CreateObject(bucket_uri=bucket1_uri, object_name='subdir/obj3',
125 contents='subdir/obj3') 127 contents='subdir/obj3')
126 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj2', 128 self.CreateObject(bucket_uri=bucket2_uri, object_name='.obj2',
127 contents='OBJ2') 129 contents='.OBJ2')
128 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj4', 130 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj4',
129 contents='obj4') 131 contents='obj4')
130 self.CreateObject(bucket_uri=bucket2_uri, object_name='subdir/obj5', 132 self.CreateObject(bucket_uri=bucket2_uri, object_name='subdir/obj5',
131 contents='subdir/obj5') 133 contents='subdir/obj5')
132 134
133 # Use @Retry as hedge against bucket listing eventual consistency. 135 # Use @Retry as hedge against bucket listing eventual consistency.
134 @Retry(AssertionError, tries=3, timeout_secs=1) 136 @Retry(AssertionError, tries=3, timeout_secs=1)
135 def _Check1(): 137 def _Check1():
136 """Tests rsync works as expected.""" 138 """Tests rsync works as expected."""
137 self.RunGsUtil(['rsync', suri(bucket1_uri), suri(bucket2_uri)]) 139 self.RunGsUtil(['rsync', suri(bucket1_uri), suri(bucket2_uri)])
138 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri)) 140 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri))
139 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri)) 141 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri))
140 # First bucket should have un-altered content. 142 # First bucket should have un-altered content.
141 self.assertEquals(listing1, set(['/obj1', '/obj2', '/subdir/obj3'])) 143 self.assertEquals(listing1, set(['/obj1', '/.obj2', '/subdir/obj3']))
142 # Second bucket should have new objects added from source bucket (without 144 # Second bucket should have new objects added from source bucket (without
143 # removing extraneeous object found in dest bucket), and without the 145 # removing extraneeous object found in dest bucket), and without the
144 # subdir objects synchronized. 146 # subdir objects synchronized.
145 self.assertEquals(listing2, 147 self.assertEquals(listing2,
146 set(['/obj1', '/obj2', '/obj4', '/subdir/obj5'])) 148 set(['/obj1', '/.obj2', '/obj4', '/subdir/obj5']))
147 # Assert that the src/dest objects that had same length but different 149 # Assert that the src/dest objects that had same length but different
148 # content were correctly synchronized (bucket to bucket sync uses 150 # content were correctly synchronized (bucket to bucket sync uses
149 # checksums). 151 # checksums).
150 self.assertEquals('obj2', self.RunGsUtil( 152 self.assertEquals('.obj2', self.RunGsUtil(
151 ['cat', suri(bucket1_uri, 'obj2')], return_stdout=True)) 153 ['cat', suri(bucket1_uri, '.obj2')], return_stdout=True))
152 self.assertEquals('obj2', self.RunGsUtil( 154 self.assertEquals('.obj2', self.RunGsUtil(
153 ['cat', suri(bucket2_uri, 'obj2')], return_stdout=True)) 155 ['cat', suri(bucket2_uri, '.obj2')], return_stdout=True))
154 _Check1() 156 _Check1()
155 157
156 # Use @Retry as hedge against bucket listing eventual consistency. 158 # Use @Retry as hedge against bucket listing eventual consistency.
157 @Retry(AssertionError, tries=3, timeout_secs=1) 159 @Retry(AssertionError, tries=3, timeout_secs=1)
158 def _Check2(): 160 def _Check2():
159 # Check that re-running the same rsync command causes no more changes. 161 # Check that re-running the same rsync command causes no more changes.
160 self.assertEquals(NO_CHANGES, self.RunGsUtil( 162 self.assertEquals(NO_CHANGES, self.RunGsUtil(
161 ['rsync', suri(bucket1_uri), suri(bucket2_uri)], return_stderr=True)) 163 ['rsync', suri(bucket1_uri), suri(bucket2_uri)], return_stderr=True))
162 _Check2() 164 _Check2()
163 165
164 # Now add and remove some objects in each bucket and test rsync -r. 166 # Now add and remove some objects in each bucket and test rsync -r.
165 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj6', 167 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj6',
166 contents='obj6') 168 contents='obj6')
167 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj7', 169 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj7',
168 contents='obj7') 170 contents='obj7')
169 self.RunGsUtil(['rm', suri(bucket1_uri, 'obj1')]) 171 self.RunGsUtil(['rm', suri(bucket1_uri, 'obj1')])
170 self.RunGsUtil(['rm', suri(bucket2_uri, 'obj2')]) 172 self.RunGsUtil(['rm', suri(bucket2_uri, '.obj2')])
171 173
172 # Use @Retry as hedge against bucket listing eventual consistency. 174 # Use @Retry as hedge against bucket listing eventual consistency.
173 @Retry(AssertionError, tries=3, timeout_secs=1) 175 @Retry(AssertionError, tries=3, timeout_secs=1)
174 def _Check3(): 176 def _Check3():
175 self.RunGsUtil(['rsync', '-r', suri(bucket1_uri), suri(bucket2_uri)]) 177 self.RunGsUtil(['rsync', '-r', suri(bucket1_uri), suri(bucket2_uri)])
176 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri)) 178 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri))
177 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri)) 179 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri))
178 # First bucket should have un-altered content. 180 # First bucket should have un-altered content.
179 self.assertEquals(listing1, set(['/obj2', '/obj6', '/subdir/obj3'])) 181 self.assertEquals(listing1, set(['/.obj2', '/obj6', '/subdir/obj3']))
180 # Second bucket should have objects tha were newly added to first bucket 182 # Second bucket should have objects tha were newly added to first bucket
181 # (wihout removing extraneous dest bucket objects), and without the 183 # (wihout removing extraneous dest bucket objects), and without the
182 # subdir objects synchronized. 184 # subdir objects synchronized.
183 self.assertEquals(listing2, set(['/obj1', '/obj2', '/obj4', '/obj6', 185 self.assertEquals(listing2, set(['/obj1', '/.obj2', '/obj4', '/obj6',
184 '/obj7', '/subdir/obj3', 186 '/obj7', '/subdir/obj3',
185 '/subdir/obj5'])) 187 '/subdir/obj5']))
186 _Check3() 188 _Check3()
187 189
188 # Use @Retry as hedge against bucket listing eventual consistency. 190 # Use @Retry as hedge against bucket listing eventual consistency.
189 @Retry(AssertionError, tries=3, timeout_secs=1) 191 @Retry(AssertionError, tries=3, timeout_secs=1)
190 def _Check4(): 192 def _Check4():
191 # Check that re-running the same rsync command causes no more changes. 193 # Check that re-running the same rsync command causes no more changes.
192 self.assertEquals(NO_CHANGES, self.RunGsUtil( 194 self.assertEquals(NO_CHANGES, self.RunGsUtil(
193 ['rsync', '-r', suri(bucket1_uri), suri(bucket2_uri)], 195 ['rsync', '-r', suri(bucket1_uri), suri(bucket2_uri)],
194 return_stderr=True)) 196 return_stderr=True))
195 _Check4() 197 _Check4()
196 198
197 def test_bucket_to_bucket_minus_d(self): 199 def test_bucket_to_bucket_minus_d(self):
198 """Tests that flat and recursive rsync between 2 buckets works correctly.""" 200 """Tests that flat and recursive rsync between 2 buckets works correctly."""
199 # Create 2 buckets with 1 overlapping object, 1 extra object at root level 201 # Create 2 buckets with 1 overlapping object, 1 extra object at root level
200 # in each, and 1 extra object 1 level down in each. Make the overlapping 202 # in each, and 1 extra object 1 level down in each, where one of the objects
201 # objects named the same but with different content, to test that we detect 203 # starts with "." to test that we don't skip those objects. Make the
202 # and properly copy in that case. 204 # overlapping objects named the same but with different content, to test
205 # that we detect and properly copy in that case.
203 bucket1_uri = self.CreateBucket() 206 bucket1_uri = self.CreateBucket()
204 bucket2_uri = self.CreateBucket() 207 bucket2_uri = self.CreateBucket()
205 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj1', 208 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj1',
206 contents='obj1') 209 contents='obj1')
207 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj2', 210 self.CreateObject(bucket_uri=bucket1_uri, object_name='.obj2',
208 contents='obj2') 211 contents='.obj2')
209 self.CreateObject(bucket_uri=bucket1_uri, object_name='subdir/obj3', 212 self.CreateObject(bucket_uri=bucket1_uri, object_name='subdir/obj3',
210 contents='subdir/obj3') 213 contents='subdir/obj3')
211 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj2', 214 self.CreateObject(bucket_uri=bucket2_uri, object_name='.obj2',
212 contents='OBJ2') 215 contents='.OBJ2')
213 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj4', 216 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj4',
214 contents='obj4') 217 contents='obj4')
215 self.CreateObject(bucket_uri=bucket2_uri, object_name='subdir/obj5', 218 self.CreateObject(bucket_uri=bucket2_uri, object_name='subdir/obj5',
216 contents='subdir/obj5') 219 contents='subdir/obj5')
217 220
218 # Use @Retry as hedge against bucket listing eventual consistency. 221 # Use @Retry as hedge against bucket listing eventual consistency.
219 @Retry(AssertionError, tries=3, timeout_secs=1) 222 @Retry(AssertionError, tries=3, timeout_secs=1)
220 def _Check1(): 223 def _Check1():
221 """Tests rsync works as expected.""" 224 """Tests rsync works as expected."""
222 self.RunGsUtil(['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)]) 225 self.RunGsUtil(['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)])
223 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri)) 226 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri))
224 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri)) 227 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri))
225 # First bucket should have un-altered content. 228 # First bucket should have un-altered content.
226 self.assertEquals(listing1, set(['/obj1', '/obj2', '/subdir/obj3'])) 229 self.assertEquals(listing1, set(['/obj1', '/.obj2', '/subdir/obj3']))
227 # Second bucket should have content like first bucket but without the 230 # Second bucket should have content like first bucket but without the
228 # subdir objects synchronized. 231 # subdir objects synchronized.
229 self.assertEquals(listing2, set(['/obj1', '/obj2', '/subdir/obj5'])) 232 self.assertEquals(listing2, set(['/obj1', '/.obj2', '/subdir/obj5']))
230 # Assert that the src/dest objects that had same length but different 233 # Assert that the src/dest objects that had same length but different
231 # content were correctly synchronized (bucket to bucket sync uses 234 # content were correctly synchronized (bucket to bucket sync uses
232 # checksums). 235 # checksums).
233 self.assertEquals('obj2', self.RunGsUtil( 236 self.assertEquals('.obj2', self.RunGsUtil(
234 ['cat', suri(bucket1_uri, 'obj2')], return_stdout=True)) 237 ['cat', suri(bucket1_uri, '.obj2')], return_stdout=True))
235 self.assertEquals('obj2', self.RunGsUtil( 238 self.assertEquals('.obj2', self.RunGsUtil(
236 ['cat', suri(bucket2_uri, 'obj2')], return_stdout=True)) 239 ['cat', suri(bucket2_uri, '.obj2')], return_stdout=True))
237 _Check1() 240 _Check1()
238 241
239 # Use @Retry as hedge against bucket listing eventual consistency. 242 # Use @Retry as hedge against bucket listing eventual consistency.
240 @Retry(AssertionError, tries=3, timeout_secs=1) 243 @Retry(AssertionError, tries=3, timeout_secs=1)
241 def _Check2(): 244 def _Check2():
242 # Check that re-running the same rsync command causes no more changes. 245 # Check that re-running the same rsync command causes no more changes.
243 self.assertEquals(NO_CHANGES, self.RunGsUtil( 246 self.assertEquals(NO_CHANGES, self.RunGsUtil(
244 ['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)], 247 ['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)],
245 return_stderr=True)) 248 return_stderr=True))
246 _Check2() 249 _Check2()
247 250
248 # Now add and remove some objects in each bucket and test rsync -r. 251 # Now add and remove some objects in each bucket and test rsync -r.
249 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj6', 252 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj6',
250 contents='obj6') 253 contents='obj6')
251 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj7', 254 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj7',
252 contents='obj7') 255 contents='obj7')
253 self.RunGsUtil(['rm', suri(bucket1_uri, 'obj1')]) 256 self.RunGsUtil(['rm', suri(bucket1_uri, 'obj1')])
254 self.RunGsUtil(['rm', suri(bucket2_uri, 'obj2')]) 257 self.RunGsUtil(['rm', suri(bucket2_uri, '.obj2')])
255 258
256 # Use @Retry as hedge against bucket listing eventual consistency. 259 # Use @Retry as hedge against bucket listing eventual consistency.
257 @Retry(AssertionError, tries=3, timeout_secs=1) 260 @Retry(AssertionError, tries=3, timeout_secs=1)
258 def _Check3(): 261 def _Check3():
259 self.RunGsUtil(['rsync', '-d', '-r', 262 self.RunGsUtil(['rsync', '-d', '-r',
260 suri(bucket1_uri), suri(bucket2_uri)]) 263 suri(bucket1_uri), suri(bucket2_uri)])
261 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri)) 264 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri))
262 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri)) 265 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri))
263 # First bucket should have un-altered content. 266 # First bucket should have un-altered content.
264 self.assertEquals(listing1, set(['/obj2', '/obj6', '/subdir/obj3'])) 267 self.assertEquals(listing1, set(['/.obj2', '/obj6', '/subdir/obj3']))
265 # Second bucket should have content like first bucket but without the 268 # Second bucket should have content like first bucket but without the
266 # subdir objects synchronized. 269 # subdir objects synchronized.
267 self.assertEquals(listing2, set(['/obj2', '/obj6', '/subdir/obj3'])) 270 self.assertEquals(listing2, set(['/.obj2', '/obj6', '/subdir/obj3']))
268 _Check3() 271 _Check3()
269 272
270 # Use @Retry as hedge against bucket listing eventual consistency. 273 # Use @Retry as hedge against bucket listing eventual consistency.
271 @Retry(AssertionError, tries=3, timeout_secs=1) 274 @Retry(AssertionError, tries=3, timeout_secs=1)
272 def _Check4(): 275 def _Check4():
273 # Check that re-running the same rsync command causes no more changes. 276 # Check that re-running the same rsync command causes no more changes.
274 self.assertEquals(NO_CHANGES, self.RunGsUtil( 277 self.assertEquals(NO_CHANGES, self.RunGsUtil(
275 ['rsync', '-d', '-r', suri(bucket1_uri), suri(bucket2_uri)], 278 ['rsync', '-d', '-r', suri(bucket1_uri), suri(bucket2_uri)],
276 return_stderr=True)) 279 return_stderr=True))
277 _Check4() 280 _Check4()
278 281
279 # Test sequential upload as well as parallel composite upload case. 282 # Test sequential upload as well as parallel composite upload case.
280 @PerformsFileToObjectUpload 283 @SequentialAndParallelTransfer
281 @unittest.skipUnless(UsingCrcmodExtension(crcmod), 284 @unittest.skipUnless(UsingCrcmodExtension(crcmod),
282 'Test requires fast crcmod.') 285 'Test requires fast crcmod.')
283 def test_dir_to_bucket_minus_d(self): 286 def test_dir_to_bucket_minus_d(self):
284 """Tests that flat and recursive rsync dir to bucket works correctly.""" 287 """Tests that flat and recursive rsync dir to bucket works correctly."""
285 # Create dir and bucket with 1 overlapping object, 1 extra object at root 288 # Create dir and bucket with 1 overlapping object, 1 extra object at root
286 # level in each, and 1 extra object 1 level down in each. Make the 289 # level in each, and 1 extra object 1 level down in each, where one of the
290 # objects starts with "." to test that we don't skip those objects. Make the
287 # overlapping objects named the same but with different content, to test 291 # overlapping objects named the same but with different content, to test
288 # that we detect and properly copy in that case. 292 # that we detect and properly copy in that case.
289 tmpdir = self.CreateTempDir() 293 tmpdir = self.CreateTempDir()
290 subdir = os.path.join(tmpdir, 'subdir') 294 subdir = os.path.join(tmpdir, 'subdir')
291 os.mkdir(subdir) 295 os.mkdir(subdir)
292 bucket_uri = self.CreateBucket() 296 bucket_uri = self.CreateBucket()
293 self.CreateTempFile(tmpdir=tmpdir, file_name='obj1', contents='obj1') 297 self.CreateTempFile(tmpdir=tmpdir, file_name='obj1', contents='obj1')
294 self.CreateTempFile(tmpdir=tmpdir, file_name='obj2', contents='obj2') 298 self.CreateTempFile(tmpdir=tmpdir, file_name='.obj2', contents='.obj2')
295 self.CreateTempFile(tmpdir=subdir, file_name='obj3', contents='subdir/obj3') 299 self.CreateTempFile(tmpdir=subdir, file_name='obj3', contents='subdir/obj3')
296 self.CreateObject(bucket_uri=bucket_uri, object_name='obj2', 300 self.CreateObject(bucket_uri=bucket_uri, object_name='.obj2',
297 contents='OBJ2') 301 contents='.OBJ2')
298 self.CreateObject(bucket_uri=bucket_uri, object_name='obj4', 302 self.CreateObject(bucket_uri=bucket_uri, object_name='obj4',
299 contents='obj4') 303 contents='obj4')
300 self.CreateObject(bucket_uri=bucket_uri, object_name='subdir/obj5', 304 self.CreateObject(bucket_uri=bucket_uri, object_name='subdir/obj5',
301 contents='subdir/obj5') 305 contents='subdir/obj5')
302 306
303 # Need to make sure the bucket listing is caught-up, otherwise the 307 # Need to make sure the bucket listing is caught-up, otherwise the
304 # first rsync may not see obj2 and overwrite it. 308 # first rsync may not see .obj2 and overwrite it.
305 self.AssertNObjectsInBucket(bucket_uri, 3) 309 self.AssertNObjectsInBucket(bucket_uri, 3)
306 310
307 # Use @Retry as hedge against bucket listing eventual consistency. 311 # Use @Retry as hedge against bucket listing eventual consistency.
308 @Retry(AssertionError, tries=3, timeout_secs=1) 312 @Retry(AssertionError, tries=3, timeout_secs=1)
309 def _Check1(): 313 def _Check1():
310 """Tests rsync works as expected.""" 314 """Tests rsync works as expected."""
311 self.RunGsUtil(['rsync', '-d', tmpdir, suri(bucket_uri)]) 315 self.RunGsUtil(['rsync', '-d', tmpdir, suri(bucket_uri)])
312 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir)) 316 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir))
313 listing2 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri)) 317 listing2 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri))
314 # Dir should have un-altered content. 318 # Dir should have un-altered content.
315 self.assertEquals(listing1, set(['/obj1', '/obj2', '/subdir/obj3'])) 319 self.assertEquals(listing1, set(['/obj1', '/.obj2', '/subdir/obj3']))
316 # Bucket should have content like dir but without the subdir objects 320 # Bucket should have content like dir but without the subdir objects
317 # synchronized. 321 # synchronized.
318 self.assertEquals(listing2, set(['/obj1', '/obj2', '/subdir/obj5'])) 322 self.assertEquals(listing2, set(['/obj1', '/.obj2', '/subdir/obj5']))
319 # Assert that the src/dest objects that had same length but different 323 # Assert that the src/dest objects that had same length but different
320 # content were not synchronized (dir to bucket sync doesn't use checksums 324 # content were not synchronized (dir to bucket sync doesn't use checksums
321 # unless you specify -c). 325 # unless you specify -c).
322 with open(os.path.join(tmpdir, 'obj2')) as f: 326 with open(os.path.join(tmpdir, '.obj2')) as f:
323 self.assertEquals('obj2', '\n'.join(f.readlines())) 327 self.assertEquals('.obj2', '\n'.join(f.readlines()))
324 self.assertEquals('OBJ2', self.RunGsUtil( 328 self.assertEquals('.OBJ2', self.RunGsUtil(
325 ['cat', suri(bucket_uri, 'obj2')], return_stdout=True)) 329 ['cat', suri(bucket_uri, '.obj2')], return_stdout=True))
326 _Check1() 330 _Check1()
327 331
328 # Use @Retry as hedge against bucket listing eventual consistency. 332 # Use @Retry as hedge against bucket listing eventual consistency.
329 @Retry(AssertionError, tries=3, timeout_secs=1) 333 @Retry(AssertionError, tries=3, timeout_secs=1)
330 def _Check2(): 334 def _Check2():
331 # Check that re-running the same rsync command causes no more changes. 335 # Check that re-running the same rsync command causes no more changes.
332 self.assertEquals(NO_CHANGES, self.RunGsUtil( 336 self.assertEquals(NO_CHANGES, self.RunGsUtil(
333 ['rsync', '-d', tmpdir, suri(bucket_uri)], return_stderr=True)) 337 ['rsync', '-d', tmpdir, suri(bucket_uri)], return_stderr=True))
334 _Check2() 338 _Check2()
335 339
336 # Now rerun the sync with the -c option. 340 # Now rerun the sync with the -c option.
337 # Use @Retry as hedge against bucket listing eventual consistency. 341 # Use @Retry as hedge against bucket listing eventual consistency.
338 @Retry(AssertionError, tries=3, timeout_secs=1) 342 @Retry(AssertionError, tries=3, timeout_secs=1)
339 def _Check3(): 343 def _Check3():
340 """Tests rsync -c works as expected.""" 344 """Tests rsync -c works as expected."""
341 self.RunGsUtil(['rsync', '-d', '-c', tmpdir, suri(bucket_uri)]) 345 self.RunGsUtil(['rsync', '-d', '-c', tmpdir, suri(bucket_uri)])
342 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir)) 346 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir))
343 listing2 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri)) 347 listing2 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri))
344 # Dir should have un-altered content. 348 # Dir should have un-altered content.
345 self.assertEquals(listing1, set(['/obj1', '/obj2', '/subdir/obj3'])) 349 self.assertEquals(listing1, set(['/obj1', '/.obj2', '/subdir/obj3']))
346 # Bucket should have content like dir but without the subdir objects 350 # Bucket should have content like dir but without the subdir objects
347 # synchronized. 351 # synchronized.
348 self.assertEquals(listing2, set(['/obj1', '/obj2', '/subdir/obj5'])) 352 self.assertEquals(listing2, set(['/obj1', '/.obj2', '/subdir/obj5']))
349 # Assert that the src/dest objects that had same length but different 353 # Assert that the src/dest objects that had same length but different
350 # content were synchronized (dir to bucket sync with -c uses checksums). 354 # content were synchronized (dir to bucket sync with -c uses checksums).
351 with open(os.path.join(tmpdir, 'obj2')) as f: 355 with open(os.path.join(tmpdir, '.obj2')) as f:
352 self.assertEquals('obj2', '\n'.join(f.readlines())) 356 self.assertEquals('.obj2', '\n'.join(f.readlines()))
353 self.assertEquals('obj2', self.RunGsUtil( 357 self.assertEquals('.obj2', self.RunGsUtil(
354 ['cat', suri(bucket_uri, 'obj2')], return_stdout=True)) 358 ['cat', suri(bucket_uri, '.obj2')], return_stdout=True))
355 _Check3() 359 _Check3()
356 360
357 # Use @Retry as hedge against bucket listing eventual consistency. 361 # Use @Retry as hedge against bucket listing eventual consistency.
358 @Retry(AssertionError, tries=3, timeout_secs=1) 362 @Retry(AssertionError, tries=3, timeout_secs=1)
359 def _Check4(): 363 def _Check4():
360 # Check that re-running the same rsync command causes no more changes. 364 # Check that re-running the same rsync command causes no more changes.
361 self.assertEquals(NO_CHANGES, self.RunGsUtil( 365 self.assertEquals(NO_CHANGES, self.RunGsUtil(
362 ['rsync', '-d', '-c', tmpdir, suri(bucket_uri)], return_stderr=True)) 366 ['rsync', '-d', '-c', tmpdir, suri(bucket_uri)], return_stderr=True))
363 _Check4() 367 _Check4()
364 368
365 # Now add and remove some objects in dir and bucket and test rsync -r. 369 # Now add and remove some objects in dir and bucket and test rsync -r.
366 self.CreateTempFile(tmpdir=tmpdir, file_name='obj6', contents='obj6') 370 self.CreateTempFile(tmpdir=tmpdir, file_name='obj6', contents='obj6')
367 self.CreateObject(bucket_uri=bucket_uri, object_name='obj7', 371 self.CreateObject(bucket_uri=bucket_uri, object_name='obj7',
368 contents='obj7') 372 contents='obj7')
369 os.unlink(os.path.join(tmpdir, 'obj1')) 373 os.unlink(os.path.join(tmpdir, 'obj1'))
370 self.RunGsUtil(['rm', suri(bucket_uri, 'obj2')]) 374 self.RunGsUtil(['rm', suri(bucket_uri, '.obj2')])
371 375
372 # Use @Retry as hedge against bucket listing eventual consistency. 376 # Use @Retry as hedge against bucket listing eventual consistency.
373 @Retry(AssertionError, tries=3, timeout_secs=1) 377 @Retry(AssertionError, tries=3, timeout_secs=1)
374 def _Check5(): 378 def _Check5():
375 self.RunGsUtil(['rsync', '-d', '-r', tmpdir, suri(bucket_uri)]) 379 self.RunGsUtil(['rsync', '-d', '-r', tmpdir, suri(bucket_uri)])
376 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir)) 380 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir))
377 listing2 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri)) 381 listing2 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri))
378 # Dir should have un-altered content. 382 # Dir should have un-altered content.
379 self.assertEquals(listing1, set(['/obj2', '/obj6', '/subdir/obj3'])) 383 self.assertEquals(listing1, set(['/.obj2', '/obj6', '/subdir/obj3']))
380 # Bucket should have content like dir but without the subdir objects 384 # Bucket should have content like dir but without the subdir objects
381 # synchronized. 385 # synchronized.
382 self.assertEquals(listing2, set(['/obj2', '/obj6', '/subdir/obj3'])) 386 self.assertEquals(listing2, set(['/.obj2', '/obj6', '/subdir/obj3']))
383 _Check5() 387 _Check5()
384 388
385 # Use @Retry as hedge against bucket listing eventual consistency. 389 # Use @Retry as hedge against bucket listing eventual consistency.
386 @Retry(AssertionError, tries=3, timeout_secs=1) 390 @Retry(AssertionError, tries=3, timeout_secs=1)
387 def _Check6(): 391 def _Check6():
388 # Check that re-running the same rsync command causes no more changes. 392 # Check that re-running the same rsync command causes no more changes.
389 self.assertEquals(NO_CHANGES, self.RunGsUtil( 393 self.assertEquals(NO_CHANGES, self.RunGsUtil(
390 ['rsync', '-d', '-r', tmpdir, suri(bucket_uri)], return_stderr=True)) 394 ['rsync', '-d', '-r', tmpdir, suri(bucket_uri)], return_stderr=True))
391 _Check6() 395 _Check6()
392 396
393 @unittest.skipUnless(UsingCrcmodExtension(crcmod), 397 @unittest.skipUnless(UsingCrcmodExtension(crcmod),
394 'Test requires fast crcmod.') 398 'Test requires fast crcmod.')
395 def test_dir_to_dir_minus_d(self): 399 def test_dir_to_dir_minus_d(self):
396 """Tests that flat and recursive rsync dir to dir works correctly.""" 400 """Tests that flat and recursive rsync dir to dir works correctly."""
397 # Create 2 dirs with 1 overlapping file, 1 extra file at root 401 # Create 2 dirs with 1 overlapping file, 1 extra file at root
398 # level in each, and 1 extra file 1 level down in each. Make the 402 # level in each, and 1 extra file 1 level down in each, where one of the
403 # objects starts with "." to test that we don't skip those objects. Make the
399 # overlapping files named the same but with different content, to test 404 # overlapping files named the same but with different content, to test
400 # that we detect and properly copy in that case. 405 # that we detect and properly copy in that case.
401 tmpdir1 = self.CreateTempDir() 406 tmpdir1 = self.CreateTempDir()
402 tmpdir2 = self.CreateTempDir() 407 tmpdir2 = self.CreateTempDir()
403 subdir1 = os.path.join(tmpdir1, 'subdir1') 408 subdir1 = os.path.join(tmpdir1, 'subdir1')
404 subdir2 = os.path.join(tmpdir2, 'subdir2') 409 subdir2 = os.path.join(tmpdir2, 'subdir2')
405 os.mkdir(subdir1) 410 os.mkdir(subdir1)
406 os.mkdir(subdir2) 411 os.mkdir(subdir2)
407 self.CreateTempFile(tmpdir=tmpdir1, file_name='obj1', contents='obj1') 412 self.CreateTempFile(tmpdir=tmpdir1, file_name='obj1', contents='obj1')
408 self.CreateTempFile(tmpdir=tmpdir1, file_name='obj2', contents='obj2') 413 self.CreateTempFile(tmpdir=tmpdir1, file_name='.obj2', contents='.obj2')
409 self.CreateTempFile( 414 self.CreateTempFile(
410 tmpdir=subdir1, file_name='obj3', contents='subdir1/obj3') 415 tmpdir=subdir1, file_name='obj3', contents='subdir1/obj3')
411 self.CreateTempFile(tmpdir=tmpdir2, file_name='obj2', contents='OBJ2') 416 self.CreateTempFile(tmpdir=tmpdir2, file_name='.obj2', contents='.OBJ2')
412 self.CreateTempFile(tmpdir=tmpdir2, file_name='obj4', contents='obj4') 417 self.CreateTempFile(tmpdir=tmpdir2, file_name='obj4', contents='obj4')
413 self.CreateTempFile( 418 self.CreateTempFile(
414 tmpdir=subdir2, file_name='obj5', contents='subdir2/obj5') 419 tmpdir=subdir2, file_name='obj5', contents='subdir2/obj5')
415 420
416 self.RunGsUtil(['rsync', '-d', tmpdir1, tmpdir2]) 421 self.RunGsUtil(['rsync', '-d', tmpdir1, tmpdir2])
417 listing1 = _TailSet(tmpdir1, self._FlatListDir(tmpdir1)) 422 listing1 = _TailSet(tmpdir1, self._FlatListDir(tmpdir1))
418 listing2 = _TailSet(tmpdir2, self._FlatListDir(tmpdir2)) 423 listing2 = _TailSet(tmpdir2, self._FlatListDir(tmpdir2))
419 # dir1 should have un-altered content. 424 # dir1 should have un-altered content.
420 self.assertEquals(listing1, set(['/obj1', '/obj2', '/subdir1/obj3'])) 425 self.assertEquals(listing1, set(['/obj1', '/.obj2', '/subdir1/obj3']))
421 # dir2 should have content like dir1 but without the subdir1 objects 426 # dir2 should have content like dir1 but without the subdir1 objects
422 # synchronized. 427 # synchronized.
423 self.assertEquals(listing2, set(['/obj1', '/obj2', '/subdir2/obj5'])) 428 self.assertEquals(listing2, set(['/obj1', '/.obj2', '/subdir2/obj5']))
424 # Assert that the src/dest objects that had same length but different 429 # Assert that the src/dest objects that had same length but different
425 # checksums were not synchronized (dir to dir sync doesn't use checksums 430 # checksums were not synchronized (dir to dir sync doesn't use checksums
426 # unless you specify -c). 431 # unless you specify -c).
427 with open(os.path.join(tmpdir1, 'obj2')) as f: 432 with open(os.path.join(tmpdir1, '.obj2')) as f:
428 self.assertEquals('obj2', '\n'.join(f.readlines())) 433 self.assertEquals('.obj2', '\n'.join(f.readlines()))
429 with open(os.path.join(tmpdir2, 'obj2')) as f: 434 with open(os.path.join(tmpdir2, '.obj2')) as f:
430 self.assertEquals('OBJ2', '\n'.join(f.readlines())) 435 self.assertEquals('.OBJ2', '\n'.join(f.readlines()))
431 436
432 # Use @Retry as hedge against bucket listing eventual consistency. 437 # Use @Retry as hedge against bucket listing eventual consistency.
433 @Retry(AssertionError, tries=3, timeout_secs=1) 438 @Retry(AssertionError, tries=3, timeout_secs=1)
434 def _Check1(): 439 def _Check1():
435 # Check that re-running the same rsync command causes no more changes. 440 # Check that re-running the same rsync command causes no more changes.
436 self.assertEquals(NO_CHANGES, self.RunGsUtil( 441 self.assertEquals(NO_CHANGES, self.RunGsUtil(
437 ['rsync', '-d', tmpdir1, tmpdir2], return_stderr=True)) 442 ['rsync', '-d', tmpdir1, tmpdir2], return_stderr=True))
438 _Check1() 443 _Check1()
439 444
440 # Now rerun the sync with the -c option. 445 # Now rerun the sync with the -c option.
441 self.RunGsUtil(['rsync', '-d', '-c', tmpdir1, tmpdir2]) 446 self.RunGsUtil(['rsync', '-d', '-c', tmpdir1, tmpdir2])
442 listing1 = _TailSet(tmpdir1, self._FlatListDir(tmpdir1)) 447 listing1 = _TailSet(tmpdir1, self._FlatListDir(tmpdir1))
443 listing2 = _TailSet(tmpdir2, self._FlatListDir(tmpdir2)) 448 listing2 = _TailSet(tmpdir2, self._FlatListDir(tmpdir2))
444 # dir1 should have un-altered content. 449 # dir1 should have un-altered content.
445 self.assertEquals(listing1, set(['/obj1', '/obj2', '/subdir1/obj3'])) 450 self.assertEquals(listing1, set(['/obj1', '/.obj2', '/subdir1/obj3']))
446 # dir2 should have content like dir but without the subdir objects 451 # dir2 should have content like dir but without the subdir objects
447 # synchronized. 452 # synchronized.
448 self.assertEquals(listing2, set(['/obj1', '/obj2', '/subdir2/obj5'])) 453 self.assertEquals(listing2, set(['/obj1', '/.obj2', '/subdir2/obj5']))
449 # Assert that the src/dest objects that had same length but different 454 # Assert that the src/dest objects that had same length but different
450 # content were synchronized (dir to dir sync with -c uses checksums). 455 # content were synchronized (dir to dir sync with -c uses checksums).
451 with open(os.path.join(tmpdir1, 'obj2')) as f: 456 with open(os.path.join(tmpdir1, '.obj2')) as f:
452 self.assertEquals('obj2', '\n'.join(f.readlines())) 457 self.assertEquals('.obj2', '\n'.join(f.readlines()))
453 with open(os.path.join(tmpdir1, 'obj2')) as f: 458 with open(os.path.join(tmpdir1, '.obj2')) as f:
454 self.assertEquals('obj2', '\n'.join(f.readlines())) 459 self.assertEquals('.obj2', '\n'.join(f.readlines()))
455 460
456 # Use @Retry as hedge against bucket listing eventual consistency. 461 # Use @Retry as hedge against bucket listing eventual consistency.
457 @Retry(AssertionError, tries=3, timeout_secs=1) 462 @Retry(AssertionError, tries=3, timeout_secs=1)
458 def _Check2(): 463 def _Check2():
459 # Check that re-running the same rsync command causes no more changes. 464 # Check that re-running the same rsync command causes no more changes.
460 self.assertEquals(NO_CHANGES, self.RunGsUtil( 465 self.assertEquals(NO_CHANGES, self.RunGsUtil(
461 ['rsync', '-d', '-c', tmpdir1, tmpdir2], return_stderr=True)) 466 ['rsync', '-d', '-c', tmpdir1, tmpdir2], return_stderr=True))
462 _Check2() 467 _Check2()
463 468
464 # Now add and remove some objects in both dirs and test rsync -r. 469 # Now add and remove some objects in both dirs and test rsync -r.
465 self.CreateTempFile(tmpdir=tmpdir1, file_name='obj6', contents='obj6') 470 self.CreateTempFile(tmpdir=tmpdir1, file_name='obj6', contents='obj6')
466 self.CreateTempFile(tmpdir=tmpdir2, file_name='obj7', contents='obj7') 471 self.CreateTempFile(tmpdir=tmpdir2, file_name='obj7', contents='obj7')
467 os.unlink(os.path.join(tmpdir1, 'obj1')) 472 os.unlink(os.path.join(tmpdir1, 'obj1'))
468 os.unlink(os.path.join(tmpdir2, 'obj2')) 473 os.unlink(os.path.join(tmpdir2, '.obj2'))
469 474
470 self.RunGsUtil(['rsync', '-d', '-r', tmpdir1, tmpdir2]) 475 self.RunGsUtil(['rsync', '-d', '-r', tmpdir1, tmpdir2])
471 listing1 = _TailSet(tmpdir1, self._FlatListDir(tmpdir1)) 476 listing1 = _TailSet(tmpdir1, self._FlatListDir(tmpdir1))
472 listing2 = _TailSet(tmpdir2, self._FlatListDir(tmpdir2)) 477 listing2 = _TailSet(tmpdir2, self._FlatListDir(tmpdir2))
473 # dir1 should have un-altered content. 478 # dir1 should have un-altered content.
474 self.assertEquals(listing1, set(['/obj2', '/obj6', '/subdir1/obj3'])) 479 self.assertEquals(listing1, set(['/.obj2', '/obj6', '/subdir1/obj3']))
475 # dir2 should have content like dir but without the subdir objects 480 # dir2 should have content like dir but without the subdir objects
476 # synchronized. 481 # synchronized.
477 self.assertEquals(listing2, set(['/obj2', '/obj6', '/subdir1/obj3'])) 482 self.assertEquals(listing2, set(['/.obj2', '/obj6', '/subdir1/obj3']))
478 483
479 # Use @Retry as hedge against bucket listing eventual consistency. 484 # Use @Retry as hedge against bucket listing eventual consistency.
480 @Retry(AssertionError, tries=3, timeout_secs=1) 485 @Retry(AssertionError, tries=3, timeout_secs=1)
481 def _Check3(): 486 def _Check3():
482 # Check that re-running the same rsync command causes no more changes. 487 # Check that re-running the same rsync command causes no more changes.
483 self.assertEquals(NO_CHANGES, self.RunGsUtil( 488 self.assertEquals(NO_CHANGES, self.RunGsUtil(
484 ['rsync', '-d', '-r', tmpdir1, tmpdir2], return_stderr=True)) 489 ['rsync', '-d', '-r', tmpdir1, tmpdir2], return_stderr=True))
485 _Check3() 490 _Check3()
486 491
487 def test_dir_to_dir_minus_d_more_files_than_bufsize(self): 492 def test_dir_to_dir_minus_d_more_files_than_bufsize(self):
(...skipping 23 matching lines...) Expand all
511 # Check that re-running the same rsync command causes no more changes. 516 # Check that re-running the same rsync command causes no more changes.
512 self.assertEquals(NO_CHANGES, self.RunGsUtil( 517 self.assertEquals(NO_CHANGES, self.RunGsUtil(
513 ['rsync', '-d', tmpdir1, tmpdir2], return_stderr=True)) 518 ['rsync', '-d', tmpdir1, tmpdir2], return_stderr=True))
514 _Check() 519 _Check()
515 520
516 @unittest.skipUnless(UsingCrcmodExtension(crcmod), 521 @unittest.skipUnless(UsingCrcmodExtension(crcmod),
517 'Test requires fast crcmod.') 522 'Test requires fast crcmod.')
518 def test_bucket_to_dir_minus_d(self): 523 def test_bucket_to_dir_minus_d(self):
519 """Tests that flat and recursive rsync bucket to dir works correctly.""" 524 """Tests that flat and recursive rsync bucket to dir works correctly."""
520 # Create bucket and dir with 1 overlapping object, 1 extra object at root 525 # Create bucket and dir with 1 overlapping object, 1 extra object at root
521 # level in each, and 1 extra object 1 level down in each. Make the 526 # level in each, and 1 extra object 1 level down in each, where one of the
527 # objects starts with "." to test that we don't skip those objects. Make the
522 # overlapping objects named the same but with different content, to test 528 # overlapping objects named the same but with different content, to test
523 # that we detect and properly copy in that case. 529 # that we detect and properly copy in that case.
524 bucket_uri = self.CreateBucket() 530 bucket_uri = self.CreateBucket()
525 tmpdir = self.CreateTempDir() 531 tmpdir = self.CreateTempDir()
526 subdir = os.path.join(tmpdir, 'subdir') 532 subdir = os.path.join(tmpdir, 'subdir')
527 os.mkdir(subdir) 533 os.mkdir(subdir)
528 self.CreateObject(bucket_uri=bucket_uri, object_name='obj1', 534 self.CreateObject(bucket_uri=bucket_uri, object_name='obj1',
529 contents='obj1') 535 contents='obj1')
530 self.CreateObject(bucket_uri=bucket_uri, object_name='obj2', 536 self.CreateObject(bucket_uri=bucket_uri, object_name='.obj2',
531 contents='obj2') 537 contents='.obj2')
532 self.CreateObject(bucket_uri=bucket_uri, object_name='subdir/obj3', 538 self.CreateObject(bucket_uri=bucket_uri, object_name='subdir/obj3',
533 contents='subdir/obj3') 539 contents='subdir/obj3')
534 self.CreateTempFile(tmpdir=tmpdir, file_name='obj2', contents='OBJ2') 540 self.CreateTempFile(tmpdir=tmpdir, file_name='.obj2', contents='.OBJ2')
535 self.CreateTempFile(tmpdir=tmpdir, file_name='obj4', contents='obj4') 541 self.CreateTempFile(tmpdir=tmpdir, file_name='obj4', contents='obj4')
536 self.CreateTempFile(tmpdir=subdir, file_name='obj5', contents='subdir/obj5') 542 self.CreateTempFile(tmpdir=subdir, file_name='obj5', contents='subdir/obj5')
537 543
538 # Use @Retry as hedge against bucket listing eventual consistency. 544 # Use @Retry as hedge against bucket listing eventual consistency.
539 @Retry(AssertionError, tries=3, timeout_secs=1) 545 @Retry(AssertionError, tries=3, timeout_secs=1)
540 def _Check1(): 546 def _Check1():
541 """Tests rsync works as expected.""" 547 """Tests rsync works as expected."""
542 self.RunGsUtil(['rsync', '-d', suri(bucket_uri), tmpdir]) 548 self.RunGsUtil(['rsync', '-d', suri(bucket_uri), tmpdir])
543 listing1 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri)) 549 listing1 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri))
544 listing2 = _TailSet(tmpdir, self._FlatListDir(tmpdir)) 550 listing2 = _TailSet(tmpdir, self._FlatListDir(tmpdir))
545 # Bucket should have un-altered content. 551 # Bucket should have un-altered content.
546 self.assertEquals(listing1, set(['/obj1', '/obj2', '/subdir/obj3'])) 552 self.assertEquals(listing1, set(['/obj1', '/.obj2', '/subdir/obj3']))
547 # Dir should have content like bucket but without the subdir objects 553 # Dir should have content like bucket but without the subdir objects
548 # synchronized. 554 # synchronized.
549 self.assertEquals(listing2, set(['/obj1', '/obj2', '/subdir/obj5'])) 555 self.assertEquals(listing2, set(['/obj1', '/.obj2', '/subdir/obj5']))
550 # Assert that the src/dest objects that had same length but different 556 # Assert that the src/dest objects that had same length but different
551 # content were not synchronized (bucket to dir sync doesn't use checksums 557 # content were not synchronized (bucket to dir sync doesn't use checksums
552 # unless you specify -c). 558 # unless you specify -c).
553 self.assertEquals('obj2', self.RunGsUtil( 559 self.assertEquals('.obj2', self.RunGsUtil(
554 ['cat', suri(bucket_uri, 'obj2')], return_stdout=True)) 560 ['cat', suri(bucket_uri, '.obj2')], return_stdout=True))
555 with open(os.path.join(tmpdir, 'obj2')) as f: 561 with open(os.path.join(tmpdir, '.obj2')) as f:
556 self.assertEquals('OBJ2', '\n'.join(f.readlines())) 562 self.assertEquals('.OBJ2', '\n'.join(f.readlines()))
557 _Check1() 563 _Check1()
558 564
559 # Use @Retry as hedge against bucket listing eventual consistency. 565 # Use @Retry as hedge against bucket listing eventual consistency.
560 @Retry(AssertionError, tries=3, timeout_secs=1) 566 @Retry(AssertionError, tries=3, timeout_secs=1)
561 def _Check2(): 567 def _Check2():
562 # Check that re-running the same rsync command causes no more changes. 568 # Check that re-running the same rsync command causes no more changes.
563 self.assertEquals(NO_CHANGES, self.RunGsUtil( 569 self.assertEquals(NO_CHANGES, self.RunGsUtil(
564 ['rsync', '-d', suri(bucket_uri), tmpdir], return_stderr=True)) 570 ['rsync', '-d', suri(bucket_uri), tmpdir], return_stderr=True))
565 _Check2() 571 _Check2()
566 572
567 # Now rerun the sync with the -c option. 573 # Now rerun the sync with the -c option.
568 # Use @Retry as hedge against bucket listing eventual consistency. 574 # Use @Retry as hedge against bucket listing eventual consistency.
569 @Retry(AssertionError, tries=3, timeout_secs=1) 575 @Retry(AssertionError, tries=3, timeout_secs=1)
570 def _Check3(): 576 def _Check3():
571 """Tests rsync -c works as expected.""" 577 """Tests rsync -c works as expected."""
572 self.RunGsUtil(['rsync', '-d', '-c', suri(bucket_uri), tmpdir]) 578 self.RunGsUtil(['rsync', '-d', '-c', suri(bucket_uri), tmpdir])
573 listing1 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri)) 579 listing1 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri))
574 listing2 = _TailSet(tmpdir, self._FlatListDir(tmpdir)) 580 listing2 = _TailSet(tmpdir, self._FlatListDir(tmpdir))
575 # Bucket should have un-altered content. 581 # Bucket should have un-altered content.
576 self.assertEquals(listing1, set(['/obj1', '/obj2', '/subdir/obj3'])) 582 self.assertEquals(listing1, set(['/obj1', '/.obj2', '/subdir/obj3']))
577 # Dir should have content like bucket but without the subdir objects 583 # Dir should have content like bucket but without the subdir objects
578 # synchronized. 584 # synchronized.
579 self.assertEquals(listing2, set(['/obj1', '/obj2', '/subdir/obj5'])) 585 self.assertEquals(listing2, set(['/obj1', '/.obj2', '/subdir/obj5']))
580 # Assert that the src/dest objects that had same length but different 586 # Assert that the src/dest objects that had same length but different
581 # content were synchronized (bucket to dir sync with -c uses checksums). 587 # content were synchronized (bucket to dir sync with -c uses checksums).
582 self.assertEquals('obj2', self.RunGsUtil( 588 self.assertEquals('.obj2', self.RunGsUtil(
583 ['cat', suri(bucket_uri, 'obj2')], return_stdout=True)) 589 ['cat', suri(bucket_uri, '.obj2')], return_stdout=True))
584 with open(os.path.join(tmpdir, 'obj2')) as f: 590 with open(os.path.join(tmpdir, '.obj2')) as f:
585 self.assertEquals('obj2', '\n'.join(f.readlines())) 591 self.assertEquals('.obj2', '\n'.join(f.readlines()))
586 _Check3() 592 _Check3()
587 593
588 # Use @Retry as hedge against bucket listing eventual consistency. 594 # Use @Retry as hedge against bucket listing eventual consistency.
589 @Retry(AssertionError, tries=3, timeout_secs=1) 595 @Retry(AssertionError, tries=3, timeout_secs=1)
590 def _Check4(): 596 def _Check4():
591 # Check that re-running the same rsync command causes no more changes. 597 # Check that re-running the same rsync command causes no more changes.
592 self.assertEquals(NO_CHANGES, self.RunGsUtil( 598 self.assertEquals(NO_CHANGES, self.RunGsUtil(
593 ['rsync', '-d', '-c', suri(bucket_uri), tmpdir], return_stderr=True)) 599 ['rsync', '-d', '-c', suri(bucket_uri), tmpdir], return_stderr=True))
594 _Check4() 600 _Check4()
595 601
596 # Now add and remove some objects in dir and bucket and test rsync -r. 602 # Now add and remove some objects in dir and bucket and test rsync -r.
597 self.CreateObject(bucket_uri=bucket_uri, object_name='obj6', 603 self.CreateObject(bucket_uri=bucket_uri, object_name='obj6',
598 contents='obj6') 604 contents='obj6')
599 self.CreateTempFile(tmpdir=tmpdir, file_name='obj7', contents='obj7') 605 self.CreateTempFile(tmpdir=tmpdir, file_name='obj7', contents='obj7')
600 self.RunGsUtil(['rm', suri(bucket_uri, 'obj1')]) 606 self.RunGsUtil(['rm', suri(bucket_uri, 'obj1')])
601 os.unlink(os.path.join(tmpdir, 'obj2')) 607 os.unlink(os.path.join(tmpdir, '.obj2'))
602 608
603 # Use @Retry as hedge against bucket listing eventual consistency. 609 # Use @Retry as hedge against bucket listing eventual consistency.
604 @Retry(AssertionError, tries=3, timeout_secs=1) 610 @Retry(AssertionError, tries=3, timeout_secs=1)
605 def _Check5(): 611 def _Check5():
606 self.RunGsUtil(['rsync', '-d', '-r', suri(bucket_uri), tmpdir]) 612 self.RunGsUtil(['rsync', '-d', '-r', suri(bucket_uri), tmpdir])
607 listing1 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri)) 613 listing1 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri))
608 listing2 = _TailSet(tmpdir, self._FlatListDir(tmpdir)) 614 listing2 = _TailSet(tmpdir, self._FlatListDir(tmpdir))
609 # Bucket should have un-altered content. 615 # Bucket should have un-altered content.
610 self.assertEquals(listing1, set(['/obj2', '/obj6', '/subdir/obj3'])) 616 self.assertEquals(listing1, set(['/.obj2', '/obj6', '/subdir/obj3']))
611 # Dir should have content like bucket but without the subdir objects 617 # Dir should have content like bucket but without the subdir objects
612 # synchronized. 618 # synchronized.
613 self.assertEquals(listing2, set(['/obj2', '/obj6', '/subdir/obj3'])) 619 self.assertEquals(listing2, set(['/.obj2', '/obj6', '/subdir/obj3']))
614 _Check5() 620 _Check5()
615 621
616 # Use @Retry as hedge against bucket listing eventual consistency. 622 # Use @Retry as hedge against bucket listing eventual consistency.
617 @Retry(AssertionError, tries=3, timeout_secs=1) 623 @Retry(AssertionError, tries=3, timeout_secs=1)
618 def _Check6(): 624 def _Check6():
619 # Check that re-running the same rsync command causes no more changes. 625 # Check that re-running the same rsync command causes no more changes.
620 self.assertEquals(NO_CHANGES, self.RunGsUtil( 626 self.assertEquals(NO_CHANGES, self.RunGsUtil(
621 ['rsync', '-d', '-r', suri(bucket_uri), tmpdir], return_stderr=True)) 627 ['rsync', '-d', '-r', suri(bucket_uri), tmpdir], return_stderr=True))
622 _Check6() 628 _Check6()
623 629
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 def _Check1(): 682 def _Check1():
677 """Tests rsync works as expected.""" 683 """Tests rsync works as expected."""
678 output = self.RunGsUtil( 684 output = self.RunGsUtil(
679 ['rsync', '-d', '-r', suri(bucket_uri), tmpdir], return_stderr=True) 685 ['rsync', '-d', '-r', suri(bucket_uri), tmpdir], return_stderr=True)
680 listing1 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri)) 686 listing1 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri))
681 listing2 = _TailSet(tmpdir, self._FlatListDir(tmpdir)) 687 listing2 = _TailSet(tmpdir, self._FlatListDir(tmpdir))
682 # Bucket should have un-altered content. 688 # Bucket should have un-altered content.
683 self.assertEquals(listing1, set(['/obj1', '//'])) 689 self.assertEquals(listing1, set(['/obj1', '//']))
684 # Bucket should not have the placeholder object. 690 # Bucket should not have the placeholder object.
685 self.assertEquals(listing2, set(['/obj1'])) 691 self.assertEquals(listing2, set(['/obj1']))
686 # Stdout should report what happened.
687 self.assertRegexpMatches(output, r'.*Skipping cloud sub-directory.*')
688 _Check1() 692 _Check1()
689 693
690 @unittest.skipIf(IS_WINDOWS, 'os.symlink() is not available on Windows.') 694 @unittest.skipIf(IS_WINDOWS, 'os.symlink() is not available on Windows.')
691 def test_rsync_minus_d_minus_e(self): 695 def test_rsync_minus_d_minus_e(self):
692 """Tests that rsync -e ignores symlinks.""" 696 """Tests that rsync -e ignores symlinks."""
693 tmpdir = self.CreateTempDir() 697 tmpdir = self.CreateTempDir()
694 subdir = os.path.join(tmpdir, 'subdir') 698 subdir = os.path.join(tmpdir, 'subdir')
695 os.mkdir(subdir) 699 os.mkdir(subdir)
696 bucket_uri = self.CreateBucket() 700 bucket_uri = self.CreateBucket()
697 fpath1 = self.CreateTempFile( 701 fpath1 = self.CreateTempFile(
698 tmpdir=tmpdir, file_name='obj1', contents='obj1') 702 tmpdir=tmpdir, file_name='obj1', contents='obj1')
699 self.CreateTempFile(tmpdir=tmpdir, file_name='obj2', contents='obj2') 703 self.CreateTempFile(tmpdir=tmpdir, file_name='.obj2', contents='.obj2')
700 self.CreateTempFile(tmpdir=subdir, file_name='obj3', contents='subdir/obj3') 704 self.CreateTempFile(tmpdir=subdir, file_name='obj3', contents='subdir/obj3')
701 good_symlink_path = os.path.join(tmpdir, 'symlink1') 705 good_symlink_path = os.path.join(tmpdir, 'symlink1')
702 os.symlink(fpath1, good_symlink_path) 706 os.symlink(fpath1, good_symlink_path)
703 # Make a symlink that points to a non-existent path to test that -e also 707 # Make a symlink that points to a non-existent path to test that -e also
704 # handles that case. 708 # handles that case.
705 bad_symlink_path = os.path.join(tmpdir, 'symlink2') 709 bad_symlink_path = os.path.join(tmpdir, 'symlink2')
706 os.symlink(os.path.join('/', 'non-existent'), bad_symlink_path) 710 os.symlink(os.path.join('/', 'non-existent'), bad_symlink_path)
707 self.CreateObject(bucket_uri=bucket_uri, object_name='obj2', 711 self.CreateObject(bucket_uri=bucket_uri, object_name='.obj2',
708 contents='OBJ2') 712 contents='.OBJ2')
709 self.CreateObject(bucket_uri=bucket_uri, object_name='obj4', 713 self.CreateObject(bucket_uri=bucket_uri, object_name='obj4',
710 contents='obj4') 714 contents='obj4')
711 self.CreateObject(bucket_uri=bucket_uri, object_name='subdir/obj5', 715 self.CreateObject(bucket_uri=bucket_uri, object_name='subdir/obj5',
712 contents='subdir/obj5') 716 contents='subdir/obj5')
713 717
714 # Use @Retry as hedge against bucket listing eventual consistency. 718 # Use @Retry as hedge against bucket listing eventual consistency.
715 @Retry(AssertionError, tries=3, timeout_secs=1) 719 @Retry(AssertionError, tries=3, timeout_secs=1)
716 def _Check1(): 720 def _Check1():
717 """Ensure listings match the commented expectations.""" 721 """Ensure listings match the commented expectations."""
718 self.RunGsUtil(['rsync', '-d', '-e', tmpdir, suri(bucket_uri)]) 722 self.RunGsUtil(['rsync', '-d', '-e', tmpdir, suri(bucket_uri)])
719 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir)) 723 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir))
720 listing2 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri)) 724 listing2 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri))
721 # Dir should have un-altered content. 725 # Dir should have un-altered content.
722 self.assertEquals( 726 self.assertEquals(
723 listing1, 727 listing1,
724 set(['/obj1', '/obj2', '/subdir/obj3', '/symlink1', '/symlink2'])) 728 set(['/obj1', '/.obj2', '/subdir/obj3', '/symlink1', '/symlink2']))
725 # Bucket should have content like dir but without the symlink, and 729 # Bucket should have content like dir but without the symlink, and
726 # without subdir objects synchronized. 730 # without subdir objects synchronized.
727 self.assertEquals(listing2, set(['/obj1', '/obj2', '/subdir/obj5'])) 731 self.assertEquals(listing2, set(['/obj1', '/.obj2', '/subdir/obj5']))
728 _Check1() 732 _Check1()
729 733
730 # Now remove invalid symlink and run without -e, and see that symlink gets 734 # Now remove invalid symlink and run without -e, and see that symlink gets
731 # copied (as file to which it points). Use @Retry as hedge against bucket 735 # copied (as file to which it points). Use @Retry as hedge against bucket
732 # listing eventual consistency. 736 # listing eventual consistency.
733 os.unlink(bad_symlink_path) 737 os.unlink(bad_symlink_path)
734 @Retry(AssertionError, tries=3, timeout_secs=1) 738 @Retry(AssertionError, tries=3, timeout_secs=1)
735 def _Check2(): 739 def _Check2():
736 """Tests rsync works as expected.""" 740 """Tests rsync works as expected."""
737 self.RunGsUtil(['rsync', '-d', tmpdir, suri(bucket_uri)]) 741 self.RunGsUtil(['rsync', '-d', tmpdir, suri(bucket_uri)])
738 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir)) 742 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir))
739 listing2 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri)) 743 listing2 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri))
740 # Dir should have un-altered content. 744 # Dir should have un-altered content.
741 self.assertEquals( 745 self.assertEquals(
742 listing1, set(['/obj1', '/obj2', '/subdir/obj3', '/symlink1'])) 746 listing1, set(['/obj1', '/.obj2', '/subdir/obj3', '/symlink1']))
743 # Bucket should have content like dir but without the symlink, and 747 # Bucket should have content like dir but without the symlink, and
744 # without subdir objects synchronized. 748 # without subdir objects synchronized.
745 self.assertEquals( 749 self.assertEquals(
746 listing2, set(['/obj1', '/obj2', '/subdir/obj5', '/symlink1'])) 750 listing2, set(['/obj1', '/.obj2', '/subdir/obj5', '/symlink1']))
747 self.assertEquals('obj1', self.RunGsUtil( 751 self.assertEquals('obj1', self.RunGsUtil(
748 ['cat', suri(bucket_uri, 'symlink1')], return_stdout=True)) 752 ['cat', suri(bucket_uri, 'symlink1')], return_stdout=True))
749 _Check2() 753 _Check2()
750 754
751 # Use @Retry as hedge against bucket listing eventual consistency. 755 # Use @Retry as hedge against bucket listing eventual consistency.
752 @Retry(AssertionError, tries=3, timeout_secs=1) 756 @Retry(AssertionError, tries=3, timeout_secs=1)
753 def _Check3(): 757 def _Check3():
754 # Check that re-running the same rsync command causes no more changes. 758 # Check that re-running the same rsync command causes no more changes.
755 self.assertEquals(NO_CHANGES, self.RunGsUtil( 759 self.assertEquals(NO_CHANGES, self.RunGsUtil(
756 ['rsync', '-d', tmpdir, suri(bucket_uri)], return_stderr=True)) 760 ['rsync', '-d', tmpdir, suri(bucket_uri)], return_stderr=True))
757 _Check3() 761 _Check3()
758 762
759 @SkipForS3('S3 does not support composite objects') 763 @SkipForS3('S3 does not support composite objects')
760 def test_bucket_to_bucket_minus_d_with_composites(self): 764 def test_bucket_to_bucket_minus_d_with_composites(self):
761 """Tests that rsync works with composite objects (which don't have MD5s).""" 765 """Tests that rsync works with composite objects (which don't have MD5s)."""
762 bucket1_uri = self.CreateBucket() 766 bucket1_uri = self.CreateBucket()
763 bucket2_uri = self.CreateBucket() 767 bucket2_uri = self.CreateBucket()
764 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj1', 768 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj1',
765 contents='obj1') 769 contents='obj1')
766 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj2', 770 self.CreateObject(bucket_uri=bucket1_uri, object_name='.obj2',
767 contents='obj2') 771 contents='.obj2')
768 self.RunGsUtil( 772 self.RunGsUtil(
769 ['compose', suri(bucket1_uri, 'obj1'), suri(bucket1_uri, 'obj2'), 773 ['compose', suri(bucket1_uri, 'obj1'), suri(bucket1_uri, '.obj2'),
770 suri(bucket1_uri, 'obj3')]) 774 suri(bucket1_uri, 'obj3')])
771 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj2', 775 self.CreateObject(bucket_uri=bucket2_uri, object_name='.obj2',
772 contents='OBJ2') 776 contents='.OBJ2')
773 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj4', 777 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj4',
774 contents='obj4') 778 contents='obj4')
775 779
776 # Use @Retry as hedge against bucket listing eventual consistency. 780 # Use @Retry as hedge against bucket listing eventual consistency.
777 @Retry(AssertionError, tries=3, timeout_secs=1) 781 @Retry(AssertionError, tries=3, timeout_secs=1)
778 def _Check1(): 782 def _Check1():
779 self.RunGsUtil(['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)]) 783 self.RunGsUtil(['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)])
780 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri)) 784 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri))
781 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri)) 785 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri))
782 # First bucket should have un-altered content. 786 # First bucket should have un-altered content.
783 self.assertEquals(listing1, set(['/obj1', '/obj2', '/obj3'])) 787 self.assertEquals(listing1, set(['/obj1', '/.obj2', '/obj3']))
784 # Second bucket should have content like first bucket but without the 788 # Second bucket should have content like first bucket but without the
785 # subdir objects synchronized. 789 # subdir objects synchronized.
786 self.assertEquals(listing2, set(['/obj1', '/obj2', '/obj3'])) 790 self.assertEquals(listing2, set(['/obj1', '/.obj2', '/obj3']))
787 _Check1() 791 _Check1()
788 792
789 # Use @Retry as hedge against bucket listing eventual consistency. 793 # Use @Retry as hedge against bucket listing eventual consistency.
790 @Retry(AssertionError, tries=3, timeout_secs=1) 794 @Retry(AssertionError, tries=3, timeout_secs=1)
791 def _Check2(): 795 def _Check2():
792 # Check that re-running the same rsync command causes no more changes. 796 # Check that re-running the same rsync command causes no more changes.
793 self.assertEquals(NO_CHANGES, self.RunGsUtil( 797 self.assertEquals(NO_CHANGES, self.RunGsUtil(
794 ['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)], 798 ['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)],
795 return_stderr=True)) 799 return_stderr=True))
796 _Check2() 800 _Check2()
797 801
798 def test_bucket_to_bucket_minus_d_empty_dest(self): 802 def test_bucket_to_bucket_minus_d_empty_dest(self):
799 """Tests working with empty dest bucket (iter runs out before src iter).""" 803 """Tests working with empty dest bucket (iter runs out before src iter)."""
800 bucket1_uri = self.CreateBucket() 804 bucket1_uri = self.CreateBucket()
801 bucket2_uri = self.CreateBucket() 805 bucket2_uri = self.CreateBucket()
802 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj1', 806 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj1',
803 contents='obj1') 807 contents='obj1')
804 self.CreateObject(bucket_uri=bucket1_uri, object_name='obj2', 808 self.CreateObject(bucket_uri=bucket1_uri, object_name='.obj2',
805 contents='obj2') 809 contents='.obj2')
806 810
807 # Use @Retry as hedge against bucket listing eventual consistency. 811 # Use @Retry as hedge against bucket listing eventual consistency.
808 @Retry(AssertionError, tries=3, timeout_secs=1) 812 @Retry(AssertionError, tries=3, timeout_secs=1)
809 def _Check1(): 813 def _Check1():
810 self.RunGsUtil(['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)]) 814 self.RunGsUtil(['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)])
811 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri)) 815 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri))
812 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri)) 816 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri))
813 self.assertEquals(listing1, set(['/obj1', '/obj2'])) 817 self.assertEquals(listing1, set(['/obj1', '/.obj2']))
814 self.assertEquals(listing2, set(['/obj1', '/obj2'])) 818 self.assertEquals(listing2, set(['/obj1', '/.obj2']))
815 _Check1() 819 _Check1()
816 820
817 # Use @Retry as hedge against bucket listing eventual consistency. 821 # Use @Retry as hedge against bucket listing eventual consistency.
818 @Retry(AssertionError, tries=3, timeout_secs=1) 822 @Retry(AssertionError, tries=3, timeout_secs=1)
819 def _Check2(): 823 def _Check2():
820 # Check that re-running the same rsync command causes no more changes. 824 # Check that re-running the same rsync command causes no more changes.
821 self.assertEquals(NO_CHANGES, self.RunGsUtil( 825 self.assertEquals(NO_CHANGES, self.RunGsUtil(
822 ['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)], 826 ['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)],
823 return_stderr=True)) 827 return_stderr=True))
824 _Check2() 828 _Check2()
825 829
826 def test_bucket_to_bucket_minus_d_empty_src(self): 830 def test_bucket_to_bucket_minus_d_empty_src(self):
827 """Tests working with empty src bucket (iter runs out before dst iter).""" 831 """Tests working with empty src bucket (iter runs out before dst iter)."""
828 bucket1_uri = self.CreateBucket() 832 bucket1_uri = self.CreateBucket()
829 bucket2_uri = self.CreateBucket() 833 bucket2_uri = self.CreateBucket()
830 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj1', 834 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj1',
831 contents='obj1') 835 contents='obj1')
832 self.CreateObject(bucket_uri=bucket2_uri, object_name='obj2', 836 self.CreateObject(bucket_uri=bucket2_uri, object_name='.obj2',
833 contents='obj2') 837 contents='.obj2')
834 838
835 # Use @Retry as hedge against bucket listing eventual consistency. 839 # Use @Retry as hedge against bucket listing eventual consistency.
836 @Retry(AssertionError, tries=3, timeout_secs=1) 840 @Retry(AssertionError, tries=3, timeout_secs=1)
837 def _Check1(): 841 def _Check1():
838 self.RunGsUtil(['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)]) 842 self.RunGsUtil(['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)])
839 stderr = self.RunGsUtil(['ls', suri(bucket1_uri, '**')], 843 stderr = self.RunGsUtil(['ls', suri(bucket1_uri, '**')],
840 expected_status=1, return_stderr=True) 844 expected_status=1, return_stderr=True)
841 self.assertIn('One or more URLs matched no objects', stderr) 845 self.assertIn('One or more URLs matched no objects', stderr)
842 stderr = self.RunGsUtil(['ls', suri(bucket2_uri, '**')], 846 stderr = self.RunGsUtil(['ls', suri(bucket2_uri, '**')],
843 expected_status=1, return_stderr=True) 847 expected_status=1, return_stderr=True)
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 _Check2() 893 _Check2()
890 894
891 def test_rsync_to_nonexistent_bucket_subdir(self): 895 def test_rsync_to_nonexistent_bucket_subdir(self):
892 """Tests that rsync to non-existent bucket subdir works.""" 896 """Tests that rsync to non-existent bucket subdir works."""
893 # Create dir with some objects and empty bucket. 897 # Create dir with some objects and empty bucket.
894 tmpdir = self.CreateTempDir() 898 tmpdir = self.CreateTempDir()
895 subdir = os.path.join(tmpdir, 'subdir') 899 subdir = os.path.join(tmpdir, 'subdir')
896 os.mkdir(subdir) 900 os.mkdir(subdir)
897 bucket_url = self.CreateBucket() 901 bucket_url = self.CreateBucket()
898 self.CreateTempFile(tmpdir=tmpdir, file_name='obj1', contents='obj1') 902 self.CreateTempFile(tmpdir=tmpdir, file_name='obj1', contents='obj1')
899 self.CreateTempFile(tmpdir=tmpdir, file_name='obj2', contents='obj2') 903 self.CreateTempFile(tmpdir=tmpdir, file_name='.obj2', contents='.obj2')
900 self.CreateTempFile(tmpdir=subdir, file_name='obj3', contents='subdir/obj3') 904 self.CreateTempFile(tmpdir=subdir, file_name='obj3', contents='subdir/obj3')
901 905
902 # Use @Retry as hedge against bucket listing eventual consistency. 906 # Use @Retry as hedge against bucket listing eventual consistency.
903 @Retry(AssertionError, tries=3, timeout_secs=1) 907 @Retry(AssertionError, tries=3, timeout_secs=1)
904 def _Check1(): 908 def _Check1():
905 """Tests rsync works as expected.""" 909 """Tests rsync works as expected."""
906 self.RunGsUtil(['rsync', '-r', tmpdir, suri(bucket_url, 'subdir')]) 910 self.RunGsUtil(['rsync', '-r', tmpdir, suri(bucket_url, 'subdir')])
907 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir)) 911 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir))
908 listing2 = _TailSet( 912 listing2 = _TailSet(
909 suri(bucket_url, 'subdir'), 913 suri(bucket_url, 'subdir'),
910 self._FlatListBucket(bucket_url.clone_replace_name('subdir'))) 914 self._FlatListBucket(bucket_url.clone_replace_name('subdir')))
911 # Dir should have un-altered content. 915 # Dir should have un-altered content.
912 self.assertEquals(listing1, set(['/obj1', '/obj2', '/subdir/obj3'])) 916 self.assertEquals(listing1, set(['/obj1', '/.obj2', '/subdir/obj3']))
913 # Bucket subdir should have content like dir. 917 # Bucket subdir should have content like dir.
914 self.assertEquals(listing2, set(['/obj1', '/obj2', '/subdir/obj3'])) 918 self.assertEquals(listing2, set(['/obj1', '/.obj2', '/subdir/obj3']))
915 _Check1() 919 _Check1()
916 920
917 # Use @Retry as hedge against bucket listing eventual consistency. 921 # Use @Retry as hedge against bucket listing eventual consistency.
918 @Retry(AssertionError, tries=3, timeout_secs=1) 922 @Retry(AssertionError, tries=3, timeout_secs=1)
919 def _Check2(): 923 def _Check2():
920 # Check that re-running the same rsync command causes no more changes. 924 # Check that re-running the same rsync command causes no more changes.
921 self.assertEquals(NO_CHANGES, self.RunGsUtil( 925 self.assertEquals(NO_CHANGES, self.RunGsUtil(
922 ['rsync', '-r', tmpdir, suri(bucket_url, 'subdir')], 926 ['rsync', '-r', tmpdir, suri(bucket_url, 'subdir')],
923 return_stderr=True)) 927 return_stderr=True))
924 _Check2() 928 _Check2()
925 929
926 def test_rsync_from_nonexistent_bucket(self): 930 def test_rsync_from_nonexistent_bucket(self):
927 """Tests that rsync from a non-existent bucket subdir fails gracefully.""" 931 """Tests that rsync from a non-existent bucket subdir fails gracefully."""
928 tmpdir = self.CreateTempDir() 932 tmpdir = self.CreateTempDir()
929 self.CreateTempFile(tmpdir=tmpdir, file_name='obj1', contents='obj1') 933 self.CreateTempFile(tmpdir=tmpdir, file_name='obj1', contents='obj1')
930 self.CreateTempFile(tmpdir=tmpdir, file_name='obj2', contents='obj2') 934 self.CreateTempFile(tmpdir=tmpdir, file_name='.obj2', contents='.obj2')
931 bucket_url_str = '%s://%s' % ( 935 bucket_url_str = '%s://%s' % (
932 self.default_provider, self.nonexistent_bucket_name) 936 self.default_provider, self.nonexistent_bucket_name)
933 stderr = self.RunGsUtil(['rsync', '-d', bucket_url_str, tmpdir], 937 stderr = self.RunGsUtil(['rsync', '-d', bucket_url_str, tmpdir],
934 expected_status=1, return_stderr=True) 938 expected_status=1, return_stderr=True)
935 self.assertIn('Caught non-retryable exception', stderr) 939 self.assertIn('Caught non-retryable exception', stderr)
936 listing = _TailSet(tmpdir, self._FlatListDir(tmpdir)) 940 listing = _TailSet(tmpdir, self._FlatListDir(tmpdir))
937 # Dir should have un-altered content. 941 # Dir should have un-altered content.
938 self.assertEquals(listing, set(['/obj1', '/obj2'])) 942 self.assertEquals(listing, set(['/obj1', '/.obj2']))
939 943
940 def test_rsync_to_nonexistent_bucket(self): 944 def test_rsync_to_nonexistent_bucket(self):
941 """Tests that rsync from a non-existent bucket subdir fails gracefully.""" 945 """Tests that rsync from a non-existent bucket subdir fails gracefully."""
942 tmpdir = self.CreateTempDir() 946 tmpdir = self.CreateTempDir()
943 self.CreateTempFile(tmpdir=tmpdir, file_name='obj1', contents='obj1') 947 self.CreateTempFile(tmpdir=tmpdir, file_name='obj1', contents='obj1')
944 self.CreateTempFile(tmpdir=tmpdir, file_name='obj2', contents='obj2') 948 self.CreateTempFile(tmpdir=tmpdir, file_name='.obj2', contents='.obj2')
945 bucket_url_str = '%s://%s' % ( 949 bucket_url_str = '%s://%s' % (
946 self.default_provider, self.nonexistent_bucket_name) 950 self.default_provider, self.nonexistent_bucket_name)
947 stderr = self.RunGsUtil(['rsync', '-d', bucket_url_str, tmpdir], 951 stderr = self.RunGsUtil(['rsync', '-d', bucket_url_str, tmpdir],
948 expected_status=1, return_stderr=True) 952 expected_status=1, return_stderr=True)
949 self.assertIn('Caught non-retryable exception', stderr) 953 self.assertIn('Caught non-retryable exception', stderr)
950 listing = _TailSet(tmpdir, self._FlatListDir(tmpdir)) 954 listing = _TailSet(tmpdir, self._FlatListDir(tmpdir))
951 # Dir should have un-altered content. 955 # Dir should have un-altered content.
952 self.assertEquals(listing, set(['/obj1', '/obj2'])) 956 self.assertEquals(listing, set(['/obj1', '/.obj2']))
953 957
954 def test_bucket_to_bucket_minus_d_with_overwrite_and_punc_chars(self): 958 def test_bucket_to_bucket_minus_d_with_overwrite_and_punc_chars(self):
955 """Tests that punc chars in filenames don't confuse sort order.""" 959 """Tests that punc chars in filenames don't confuse sort order."""
956 bucket1_uri = self.CreateBucket() 960 bucket1_uri = self.CreateBucket()
957 bucket2_uri = self.CreateBucket() 961 bucket2_uri = self.CreateBucket()
958 # Create 2 objects in each bucket, with one overwritten with a name that's 962 # Create 2 objects in each bucket, with one overwritten with a name that's
959 # less than the next name in destination bucket when encoded, but not when 963 # less than the next name in destination bucket when encoded, but not when
960 # compared without encoding. 964 # compared without encoding.
961 self.CreateObject(bucket_uri=bucket1_uri, object_name='e/obj1', 965 self.CreateObject(bucket_uri=bucket1_uri, object_name='e/obj1',
962 contents='obj1') 966 contents='obj1')
963 self.CreateObject(bucket_uri=bucket1_uri, object_name='e-1/obj2', 967 self.CreateObject(bucket_uri=bucket1_uri, object_name='e-1/.obj2',
964 contents='obj2') 968 contents='.obj2')
965 self.CreateObject(bucket_uri=bucket2_uri, object_name='e/obj1', 969 self.CreateObject(bucket_uri=bucket2_uri, object_name='e/obj1',
966 contents='OBJ1') 970 contents='OBJ1')
967 self.CreateObject(bucket_uri=bucket2_uri, object_name='e-1/obj2', 971 self.CreateObject(bucket_uri=bucket2_uri, object_name='e-1/.obj2',
968 contents='obj2') 972 contents='.obj2')
969 # Need to make sure the bucket listings are caught-up, otherwise the 973 # Need to make sure the bucket listings are caught-up, otherwise the
970 # rsync may not see all objects and fail to synchronize correctly. 974 # rsync may not see all objects and fail to synchronize correctly.
971 self.AssertNObjectsInBucket(bucket1_uri, 2) 975 self.AssertNObjectsInBucket(bucket1_uri, 2)
972 self.AssertNObjectsInBucket(bucket2_uri, 2) 976 self.AssertNObjectsInBucket(bucket2_uri, 2)
973 977
974 # Use @Retry as hedge against bucket listing eventual consistency. 978 # Use @Retry as hedge against bucket listing eventual consistency.
975 @Retry(AssertionError, tries=3, timeout_secs=1) 979 @Retry(AssertionError, tries=3, timeout_secs=1)
976 def _Check1(): 980 def _Check1():
977 """Tests rsync works as expected.""" 981 """Tests rsync works as expected."""
978 self.RunGsUtil(['rsync', '-rd', suri(bucket1_uri), suri(bucket2_uri)]) 982 self.RunGsUtil(['rsync', '-rd', suri(bucket1_uri), suri(bucket2_uri)])
979 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri)) 983 listing1 = _TailSet(suri(bucket1_uri), self._FlatListBucket(bucket1_uri))
980 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri)) 984 listing2 = _TailSet(suri(bucket2_uri), self._FlatListBucket(bucket2_uri))
981 # First bucket should have un-altered content. 985 # First bucket should have un-altered content.
982 self.assertEquals(listing1, set(['/e/obj1', '/e-1/obj2'])) 986 self.assertEquals(listing1, set(['/e/obj1', '/e-1/.obj2']))
983 self.assertEquals(listing2, set(['/e/obj1', '/e-1/obj2'])) 987 self.assertEquals(listing2, set(['/e/obj1', '/e-1/.obj2']))
984 # Assert correct contents. 988 # Assert correct contents.
985 self.assertEquals('obj1', self.RunGsUtil( 989 self.assertEquals('obj1', self.RunGsUtil(
986 ['cat', suri(bucket2_uri, 'e/obj1')], return_stdout=True)) 990 ['cat', suri(bucket2_uri, 'e/obj1')], return_stdout=True))
987 self.assertEquals('obj2', self.RunGsUtil( 991 self.assertEquals('.obj2', self.RunGsUtil(
988 ['cat', suri(bucket2_uri, 'e-1/obj2')], return_stdout=True)) 992 ['cat', suri(bucket2_uri, 'e-1/.obj2')], return_stdout=True))
989 _Check1() 993 _Check1()
990 994
991 # Use @Retry as hedge against bucket listing eventual consistency. 995 # Use @Retry as hedge against bucket listing eventual consistency.
992 @Retry(AssertionError, tries=3, timeout_secs=1) 996 @Retry(AssertionError, tries=3, timeout_secs=1)
993 def _Check2(): 997 def _Check2():
994 # Check that re-running the same rsync command causes no more changes. 998 # Check that re-running the same rsync command causes no more changes.
995 self.assertEquals(NO_CHANGES, self.RunGsUtil( 999 self.assertEquals(NO_CHANGES, self.RunGsUtil(
996 ['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)], 1000 ['rsync', '-d', suri(bucket1_uri), suri(bucket2_uri)],
997 return_stderr=True)) 1001 return_stderr=True))
998 _Check2() 1002 _Check2()
999 1003
1000 def test_dir_to_bucket_minus_x(self): 1004 def test_dir_to_bucket_minus_x(self):
1001 """Tests that rsync -x option works correctly.""" 1005 """Tests that rsync -x option works correctly."""
1002 # Create dir and bucket with 1 overlapping and 2 extra objects in each. 1006 # Create dir and bucket with 1 overlapping and 2 extra objects in each.
1003 tmpdir = self.CreateTempDir() 1007 tmpdir = self.CreateTempDir()
1004 bucket_uri = self.CreateBucket() 1008 bucket_uri = self.CreateBucket()
1005 self.CreateTempFile(tmpdir=tmpdir, file_name='obj1', contents='obj1') 1009 self.CreateTempFile(tmpdir=tmpdir, file_name='obj1', contents='obj1')
1006 self.CreateTempFile(tmpdir=tmpdir, file_name='obj2', contents='obj2') 1010 self.CreateTempFile(tmpdir=tmpdir, file_name='.obj2', contents='.obj2')
1007 self.CreateTempFile(tmpdir=tmpdir, file_name='obj3', contents='obj3') 1011 self.CreateTempFile(tmpdir=tmpdir, file_name='obj3', contents='obj3')
1008 self.CreateObject(bucket_uri=bucket_uri, object_name='obj2', 1012 self.CreateObject(bucket_uri=bucket_uri, object_name='.obj2',
1009 contents='obj2') 1013 contents='.obj2')
1010 self.CreateObject(bucket_uri=bucket_uri, object_name='obj4', 1014 self.CreateObject(bucket_uri=bucket_uri, object_name='obj4',
1011 contents='obj4') 1015 contents='obj4')
1012 self.CreateObject(bucket_uri=bucket_uri, object_name='obj5', 1016 self.CreateObject(bucket_uri=bucket_uri, object_name='obj5',
1013 contents='obj5') 1017 contents='obj5')
1014 1018
1015 # Need to make sure the bucket listing is caught-up, otherwise the 1019 # Need to make sure the bucket listing is caught-up, otherwise the
1016 # first rsync may not see obj2 and overwrite it. 1020 # first rsync may not see .obj2 and overwrite it.
1017 self.AssertNObjectsInBucket(bucket_uri, 3) 1021 self.AssertNObjectsInBucket(bucket_uri, 3)
1018 1022
1019 # Use @Retry as hedge against bucket listing eventual consistency. 1023 # Use @Retry as hedge against bucket listing eventual consistency.
1020 @Retry(AssertionError, tries=3, timeout_secs=1) 1024 @Retry(AssertionError, tries=3, timeout_secs=1)
1021 def _Check1(): 1025 def _Check1():
1022 """Tests rsync works as expected.""" 1026 """Tests rsync works as expected."""
1023 self.RunGsUtil(['rsync', '-d', '-x', 'obj[34]', tmpdir, suri(bucket_uri)]) 1027 self.RunGsUtil(['rsync', '-d', '-x', 'obj[34]', tmpdir, suri(bucket_uri)])
1024 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir)) 1028 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir))
1025 listing2 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri)) 1029 listing2 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri))
1026 # Dir should have un-altered content. 1030 # Dir should have un-altered content.
1027 self.assertEquals(listing1, set(['/obj1', '/obj2', '/obj3'])) 1031 self.assertEquals(listing1, set(['/obj1', '/.obj2', '/obj3']))
1028 # Bucket should have content like dir but ignoring obj3 from dir and not 1032 # Bucket should have content like dir but ignoring obj3 from dir and not
1029 # deleting obj4 from bucket (per exclude regex). 1033 # deleting obj4 from bucket (per exclude regex).
1030 self.assertEquals(listing2, set(['/obj1', '/obj2', '/obj4'])) 1034 self.assertEquals(listing2, set(['/obj1', '/.obj2', '/obj4']))
1031 _Check1() 1035 _Check1()
1032 1036
1033 # Use @Retry as hedge against bucket listing eventual consistency. 1037 # Use @Retry as hedge against bucket listing eventual consistency.
1034 @Retry(AssertionError, tries=3, timeout_secs=1) 1038 @Retry(AssertionError, tries=3, timeout_secs=1)
1035 def _Check2(): 1039 def _Check2():
1036 # Check that re-running the same rsync command causes no more changes. 1040 # Check that re-running the same rsync command causes no more changes.
1037 self.assertEquals(NO_CHANGES, self.RunGsUtil( 1041 self.assertEquals(NO_CHANGES, self.RunGsUtil(
1038 ['rsync', '-d', '-x', 'obj[34]', tmpdir, suri(bucket_uri)], 1042 ['rsync', '-d', '-x', 'obj[34]', tmpdir, suri(bucket_uri)],
1039 return_stderr=True)) 1043 return_stderr=True))
1040 _Check2() 1044 _Check2()
1045
1046 @unittest.skipIf(IS_WINDOWS,
1047 "os.chmod() won't make file unreadable on Windows.")
1048 def test_dir_to_bucket_minus_C(self):
1049 """Tests that rsync -C option works correctly."""
1050 # Create dir with 3 objects, the middle of which is unreadable.
1051 tmpdir = self.CreateTempDir()
1052 bucket_uri = self.CreateBucket()
1053 self.CreateTempFile(tmpdir=tmpdir, file_name='obj1', contents='obj1')
1054 path = self.CreateTempFile(tmpdir=tmpdir, file_name='obj2', contents='obj2')
1055 os.chmod(path, 0)
1056 self.CreateTempFile(tmpdir=tmpdir, file_name='obj3', contents='obj3')
1057
1058 # Use @Retry as hedge against bucket listing eventual consistency.
1059 @Retry(AssertionError, tries=3, timeout_secs=1)
1060 def _Check():
1061 """Tests rsync works as expected."""
1062 stderr = self.RunGsUtil(['rsync', '-C', tmpdir, suri(bucket_uri)],
1063 expected_status=1, return_stderr=True)
1064 self.assertIn('1 files/objects could not be copied/removed.', stderr)
1065 listing1 = _TailSet(tmpdir, self._FlatListDir(tmpdir))
1066 listing2 = _TailSet(suri(bucket_uri), self._FlatListBucket(bucket_uri))
1067 # Dir should have un-altered content.
1068 self.assertEquals(listing1, set(['/obj1', '/obj2', '/obj3']))
1069 # Bucket should have obj1 and obj3 even though obj2 was unreadable.
1070 self.assertEquals(listing2, set(['/obj1', '/obj3']))
1071 _Check()
OLDNEW
« no previous file with comments | « third_party/gsutil/gslib/tests/test_rm.py ('k') | third_party/gsutil/gslib/tests/test_trace.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698