1# -*- coding: utf-8 -*- 2# Copyright (c) 2013, Google, Inc. 3# All rights reserved. 4# 5# Permission is hereby granted, free of charge, to any person obtaining a 6# copy of this software and associated documentation files (the 7# "Software"), to deal in the Software without restriction, including 8# without limitation the rights to use, copy, modify, merge, publish, dis- 9# tribute, sublicense, and/or sell copies of the Software, and to permit 10# persons to whom the Software is furnished to do so, subject to the fol- 11# lowing conditions: 12# 13# The above copyright notice and this permission notice shall be included 14# in all copies or substantial portions of the Software. 15# 16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- 18# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22# IN THE SOFTWARE. 23 24"""Integration tests for GS versioning support.""" 25 26import StringIO 27import os 28import tempfile 29from xml import sax 30 31from boto import handler 32from boto.exception import GSResponseError 33from boto.gs.acl import ACL 34from tests.integration.gs.testcase import GSTestCase 35 36 37# HTTP Error returned when a generation precondition fails. 38VERSION_MISMATCH = "412" 39 40 41class GSGenerationConditionalsTest(GSTestCase): 42 43 def testConditionalSetContentsFromFile(self): 44 b = self._MakeBucket() 45 k = b.new_key("foo") 46 s1 = "test1" 47 fp = StringIO.StringIO(s1) 48 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 49 k.set_contents_from_file(fp, if_generation=999) 50 51 fp = StringIO.StringIO(s1) 52 k.set_contents_from_file(fp, if_generation=0) 53 g1 = k.generation 54 55 s2 = "test2" 56 fp = StringIO.StringIO(s2) 57 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 58 k.set_contents_from_file(fp, if_generation=int(g1)+1) 59 60 fp = StringIO.StringIO(s2) 61 k.set_contents_from_file(fp, if_generation=g1) 62 self.assertEqual(k.get_contents_as_string(), s2) 63 64 def testConditionalSetContentsFromString(self): 65 b = self._MakeBucket() 66 k = b.new_key("foo") 67 s1 = "test1" 68 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 69 k.set_contents_from_string(s1, if_generation=999) 70 71 k.set_contents_from_string(s1, if_generation=0) 72 g1 = k.generation 73 74 s2 = "test2" 75 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 76 k.set_contents_from_string(s2, if_generation=int(g1)+1) 77 78 k.set_contents_from_string(s2, if_generation=g1) 79 self.assertEqual(k.get_contents_as_string(), s2) 80 81 def testConditionalSetContentsFromFilename(self): 82 s1 = "test1" 83 s2 = "test2" 84 f1 = tempfile.NamedTemporaryFile(prefix="boto-gs-test", delete=False) 85 f2 = tempfile.NamedTemporaryFile(prefix="boto-gs-test", delete=False) 86 fname1 = f1.name 87 fname2 = f2.name 88 f1.write(s1) 89 f1.close() 90 f2.write(s2) 91 f2.close() 92 93 try: 94 b = self._MakeBucket() 95 k = b.new_key("foo") 96 97 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 98 k.set_contents_from_filename(fname1, if_generation=999) 99 100 k.set_contents_from_filename(fname1, if_generation=0) 101 g1 = k.generation 102 103 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 104 k.set_contents_from_filename(fname2, if_generation=int(g1)+1) 105 106 k.set_contents_from_filename(fname2, if_generation=g1) 107 self.assertEqual(k.get_contents_as_string(), s2) 108 finally: 109 os.remove(fname1) 110 os.remove(fname2) 111 112 def testBucketConditionalSetAcl(self): 113 b = self._MakeVersionedBucket() 114 k = b.new_key("foo") 115 s1 = "test1" 116 k.set_contents_from_string(s1) 117 118 g1 = k.generation 119 mg1 = k.metageneration 120 self.assertEqual(str(mg1), "1") 121 b.set_acl("public-read", key_name="foo") 122 123 k = b.get_key("foo") 124 g2 = k.generation 125 mg2 = k.metageneration 126 127 self.assertEqual(g2, g1) 128 self.assertGreater(mg2, mg1) 129 130 with self.assertRaisesRegexp(ValueError, ("Received if_metageneration " 131 "argument with no " 132 "if_generation argument")): 133 b.set_acl("bucket-owner-full-control", key_name="foo", 134 if_metageneration=123) 135 136 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 137 b.set_acl("bucket-owner-full-control", key_name="foo", 138 if_generation=int(g2) + 1) 139 140 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 141 b.set_acl("bucket-owner-full-control", key_name="foo", 142 if_generation=g2, if_metageneration=int(mg2) + 1) 143 144 b.set_acl("bucket-owner-full-control", key_name="foo", if_generation=g2) 145 146 k = b.get_key("foo") 147 g3 = k.generation 148 mg3 = k.metageneration 149 self.assertEqual(g3, g2) 150 self.assertGreater(mg3, mg2) 151 152 b.set_acl("public-read", key_name="foo", if_generation=g3, 153 if_metageneration=mg3) 154 155 def testConditionalSetContentsFromStream(self): 156 b = self._MakeBucket() 157 k = b.new_key("foo") 158 s1 = "test1" 159 fp = StringIO.StringIO(s1) 160 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 161 k.set_contents_from_stream(fp, if_generation=999) 162 163 fp = StringIO.StringIO(s1) 164 k.set_contents_from_stream(fp, if_generation=0) 165 g1 = k.generation 166 167 k = b.get_key("foo") 168 s2 = "test2" 169 fp = StringIO.StringIO(s2) 170 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 171 k.set_contents_from_stream(fp, if_generation=int(g1)+1) 172 173 fp = StringIO.StringIO(s2) 174 k.set_contents_from_stream(fp, if_generation=g1) 175 self.assertEqual(k.get_contents_as_string(), s2) 176 177 def testBucketConditionalSetCannedAcl(self): 178 b = self._MakeVersionedBucket() 179 k = b.new_key("foo") 180 s1 = "test1" 181 k.set_contents_from_string(s1) 182 183 g1 = k.generation 184 mg1 = k.metageneration 185 self.assertEqual(str(mg1), "1") 186 b.set_canned_acl("public-read", key_name="foo") 187 188 k = b.get_key("foo") 189 g2 = k.generation 190 mg2 = k.metageneration 191 192 self.assertEqual(g2, g1) 193 self.assertGreater(mg2, mg1) 194 195 with self.assertRaisesRegexp(ValueError, ("Received if_metageneration " 196 "argument with no " 197 "if_generation argument")): 198 b.set_canned_acl("bucket-owner-full-control", key_name="foo", 199 if_metageneration=123) 200 201 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 202 b.set_canned_acl("bucket-owner-full-control", key_name="foo", 203 if_generation=int(g2) + 1) 204 205 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 206 b.set_canned_acl("bucket-owner-full-control", key_name="foo", 207 if_generation=g2, if_metageneration=int(mg2) + 1) 208 209 b.set_canned_acl("bucket-owner-full-control", key_name="foo", 210 if_generation=g2) 211 212 k = b.get_key("foo") 213 g3 = k.generation 214 mg3 = k.metageneration 215 self.assertEqual(g3, g2) 216 self.assertGreater(mg3, mg2) 217 218 b.set_canned_acl("public-read", key_name="foo", if_generation=g3, 219 if_metageneration=mg3) 220 221 def testBucketConditionalSetXmlAcl(self): 222 b = self._MakeVersionedBucket() 223 k = b.new_key("foo") 224 s1 = "test1" 225 k.set_contents_from_string(s1) 226 227 g1 = k.generation 228 mg1 = k.metageneration 229 self.assertEqual(str(mg1), "1") 230 231 acl_xml = ( 232 '<ACCESSControlList><EntrIes><Entry>' + 233 '<Scope type="AllUsers"></Scope><Permission>READ</Permission>' + 234 '</Entry></EntrIes></ACCESSControlList>') 235 acl = ACL() 236 h = handler.XmlHandler(acl, b) 237 sax.parseString(acl_xml, h) 238 acl = acl.to_xml() 239 240 b.set_xml_acl(acl, key_name="foo") 241 242 k = b.get_key("foo") 243 g2 = k.generation 244 mg2 = k.metageneration 245 246 self.assertEqual(g2, g1) 247 self.assertGreater(mg2, mg1) 248 249 with self.assertRaisesRegexp(ValueError, ("Received if_metageneration " 250 "argument with no " 251 "if_generation argument")): 252 b.set_xml_acl(acl, key_name="foo", if_metageneration=123) 253 254 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 255 b.set_xml_acl(acl, key_name="foo", if_generation=int(g2) + 1) 256 257 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 258 b.set_xml_acl(acl, key_name="foo", if_generation=g2, 259 if_metageneration=int(mg2) + 1) 260 261 b.set_xml_acl(acl, key_name="foo", if_generation=g2) 262 263 k = b.get_key("foo") 264 g3 = k.generation 265 mg3 = k.metageneration 266 self.assertEqual(g3, g2) 267 self.assertGreater(mg3, mg2) 268 269 b.set_xml_acl(acl, key_name="foo", if_generation=g3, 270 if_metageneration=mg3) 271 272 def testObjectConditionalSetAcl(self): 273 b = self._MakeVersionedBucket() 274 k = b.new_key("foo") 275 k.set_contents_from_string("test1") 276 277 g1 = k.generation 278 mg1 = k.metageneration 279 self.assertEqual(str(mg1), "1") 280 k.set_acl("public-read") 281 282 k = b.get_key("foo") 283 g2 = k.generation 284 mg2 = k.metageneration 285 286 self.assertEqual(g2, g1) 287 self.assertGreater(mg2, mg1) 288 289 with self.assertRaisesRegexp(ValueError, ("Received if_metageneration " 290 "argument with no " 291 "if_generation argument")): 292 k.set_acl("bucket-owner-full-control", if_metageneration=123) 293 294 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 295 k.set_acl("bucket-owner-full-control", if_generation=int(g2) + 1) 296 297 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 298 k.set_acl("bucket-owner-full-control", if_generation=g2, 299 if_metageneration=int(mg2) + 1) 300 301 k.set_acl("bucket-owner-full-control", if_generation=g2) 302 303 k = b.get_key("foo") 304 g3 = k.generation 305 mg3 = k.metageneration 306 self.assertEqual(g3, g2) 307 self.assertGreater(mg3, mg2) 308 309 k.set_acl("public-read", if_generation=g3, if_metageneration=mg3) 310 311 def testObjectConditionalSetCannedAcl(self): 312 b = self._MakeVersionedBucket() 313 k = b.new_key("foo") 314 k.set_contents_from_string("test1") 315 316 g1 = k.generation 317 mg1 = k.metageneration 318 self.assertEqual(str(mg1), "1") 319 k.set_canned_acl("public-read") 320 321 k = b.get_key("foo") 322 g2 = k.generation 323 mg2 = k.metageneration 324 325 self.assertEqual(g2, g1) 326 self.assertGreater(mg2, mg1) 327 328 with self.assertRaisesRegexp(ValueError, ("Received if_metageneration " 329 "argument with no " 330 "if_generation argument")): 331 k.set_canned_acl("bucket-owner-full-control", 332 if_metageneration=123) 333 334 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 335 k.set_canned_acl("bucket-owner-full-control", 336 if_generation=int(g2) + 1) 337 338 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 339 k.set_canned_acl("bucket-owner-full-control", if_generation=g2, 340 if_metageneration=int(mg2) + 1) 341 342 k.set_canned_acl("bucket-owner-full-control", if_generation=g2) 343 344 k = b.get_key("foo") 345 g3 = k.generation 346 mg3 = k.metageneration 347 self.assertEqual(g3, g2) 348 self.assertGreater(mg3, mg2) 349 350 k.set_canned_acl("public-read", if_generation=g3, if_metageneration=mg3) 351 352 def testObjectConditionalSetXmlAcl(self): 353 b = self._MakeVersionedBucket() 354 k = b.new_key("foo") 355 s1 = "test1" 356 k.set_contents_from_string(s1) 357 358 g1 = k.generation 359 mg1 = k.metageneration 360 self.assertEqual(str(mg1), "1") 361 362 acl_xml = ( 363 '<ACCESSControlList><EntrIes><Entry>' + 364 '<Scope type="AllUsers"></Scope><Permission>READ</Permission>' + 365 '</Entry></EntrIes></ACCESSControlList>') 366 acl = ACL() 367 h = handler.XmlHandler(acl, b) 368 sax.parseString(acl_xml, h) 369 acl = acl.to_xml() 370 371 k.set_xml_acl(acl) 372 373 k = b.get_key("foo") 374 g2 = k.generation 375 mg2 = k.metageneration 376 377 self.assertEqual(g2, g1) 378 self.assertGreater(mg2, mg1) 379 380 with self.assertRaisesRegexp(ValueError, ("Received if_metageneration " 381 "argument with no " 382 "if_generation argument")): 383 k.set_xml_acl(acl, if_metageneration=123) 384 385 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 386 k.set_xml_acl(acl, if_generation=int(g2) + 1) 387 388 with self.assertRaisesRegexp(GSResponseError, VERSION_MISMATCH): 389 k.set_xml_acl(acl, if_generation=g2, if_metageneration=int(mg2) + 1) 390 391 k.set_xml_acl(acl, if_generation=g2) 392 393 k = b.get_key("foo") 394 g3 = k.generation 395 mg3 = k.metageneration 396 self.assertEqual(g3, g2) 397 self.assertGreater(mg3, mg2) 398 399 k.set_xml_acl(acl, if_generation=g3, if_metageneration=mg3) 400