PageRenderTime 38ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/boto-2.5.2/tests/integration/s3/test_key.py

#
Python | 352 lines | 313 code | 8 blank | 31 comment | 5 complexity | 70e78a13dfd7079e7362286fc6969017 MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. # Copyright (c) 2012 Mitch Garnaat http://garnaat.org/
  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. Some unit tests for S3 Key
  25. """
  26. import unittest
  27. import time
  28. import StringIO
  29. from boto.s3.connection import S3Connection
  30. from boto.s3.key import Key
  31. from boto.exception import S3ResponseError
  32. class S3KeyTest (unittest.TestCase):
  33. s3 = True
  34. def setUp(self):
  35. self.conn = S3Connection()
  36. self.bucket_name = 'keytest-%d' % int(time.time())
  37. self.bucket = self.conn.create_bucket(self.bucket_name)
  38. def tearDown(self):
  39. for key in self.bucket:
  40. key.delete()
  41. self.bucket.delete()
  42. def test_set_contents_from_file_dataloss(self):
  43. # Create an empty stringio and write to it.
  44. content = "abcde"
  45. sfp = StringIO.StringIO()
  46. sfp.write(content)
  47. # Try set_contents_from_file() without rewinding sfp
  48. k = self.bucket.new_key("k")
  49. try:
  50. k.set_contents_from_file(sfp)
  51. self.fail("forgot to rewind so should fail.")
  52. except AttributeError:
  53. pass
  54. # call with rewind and check if we wrote 5 bytes
  55. k.set_contents_from_file(sfp, rewind=True)
  56. self.assertEqual(k.size, 5)
  57. # check actual contents by getting it.
  58. kn = self.bucket.new_key("k")
  59. ks = kn.get_contents_as_string()
  60. self.assertEqual(ks, content)
  61. # finally, try with a 0 length string
  62. sfp = StringIO.StringIO()
  63. k = self.bucket.new_key("k")
  64. k.set_contents_from_file(sfp)
  65. self.assertEqual(k.size, 0)
  66. # check actual contents by getting it.
  67. kn = self.bucket.new_key("k")
  68. ks = kn.get_contents_as_string()
  69. self.assertEqual(ks, "")
  70. def test_set_contents_as_file(self):
  71. content="01234567890123456789"
  72. sfp = StringIO.StringIO(content)
  73. # fp is set at 0 for just opened (for read) files.
  74. # set_contents should write full content to key.
  75. k = self.bucket.new_key("k")
  76. k.set_contents_from_file(sfp)
  77. self.assertEqual(k.size, 20)
  78. kn = self.bucket.new_key("k")
  79. ks = kn.get_contents_as_string()
  80. self.assertEqual(ks, content)
  81. # set fp to 5 and set contents. this should
  82. # set "567890123456789" to the key
  83. sfp.seek(5)
  84. k = self.bucket.new_key("k")
  85. k.set_contents_from_file(sfp)
  86. self.assertEqual(k.size, 15)
  87. kn = self.bucket.new_key("k")
  88. ks = kn.get_contents_as_string()
  89. self.assertEqual(ks, content[5:])
  90. # set fp to 5 and only set 5 bytes. this should
  91. # write the value "56789" to the key.
  92. sfp.seek(5)
  93. k = self.bucket.new_key("k")
  94. k.set_contents_from_file(sfp, size=5)
  95. self.assertEqual(k.size, 5)
  96. self.assertEqual(sfp.tell(), 10)
  97. kn = self.bucket.new_key("k")
  98. ks = kn.get_contents_as_string()
  99. self.assertEqual(ks, content[5:10])
  100. def test_set_contents_with_md5(self):
  101. content="01234567890123456789"
  102. sfp = StringIO.StringIO(content)
  103. # fp is set at 0 for just opened (for read) files.
  104. # set_contents should write full content to key.
  105. k = self.bucket.new_key("k")
  106. good_md5 = k.compute_md5(sfp)
  107. k.set_contents_from_file(sfp, md5=good_md5)
  108. kn = self.bucket.new_key("k")
  109. ks = kn.get_contents_as_string()
  110. self.assertEqual(ks, content)
  111. # set fp to 5 and only set 5 bytes. this should
  112. # write the value "56789" to the key.
  113. sfp.seek(5)
  114. k = self.bucket.new_key("k")
  115. good_md5 = k.compute_md5(sfp, size=5)
  116. k.set_contents_from_file(sfp, size=5, md5=good_md5)
  117. self.assertEqual(sfp.tell(), 10)
  118. kn = self.bucket.new_key("k")
  119. ks = kn.get_contents_as_string()
  120. self.assertEqual(ks, content[5:10])
  121. # let's try a wrong md5 by just altering it.
  122. k = self.bucket.new_key("k")
  123. sfp.seek(0)
  124. hexdig, base64 = k.compute_md5(sfp)
  125. bad_md5 = (hexdig, base64[3:])
  126. try:
  127. k.set_contents_from_file(sfp, md5=bad_md5)
  128. self.fail("should fail with bad md5")
  129. except S3ResponseError:
  130. pass
  131. def test_get_contents_with_md5(self):
  132. content="01234567890123456789"
  133. sfp = StringIO.StringIO(content)
  134. k = self.bucket.new_key("k")
  135. k.set_contents_from_file(sfp)
  136. kn = self.bucket.new_key("k")
  137. s = kn.get_contents_as_string()
  138. self.assertEqual(kn.md5, k.md5)
  139. self.assertEqual(s, content)
  140. def test_file_callback(self):
  141. def callback(wrote, total):
  142. self.my_cb_cnt += 1
  143. self.assertNotEqual(wrote, self.my_cb_last, "called twice with same value")
  144. self.my_cb_last = wrote
  145. # Zero bytes written => 1 call
  146. self.my_cb_cnt = 0
  147. self.my_cb_last = None
  148. k = self.bucket.new_key("k")
  149. k.BufferSize = 2
  150. sfp = StringIO.StringIO("")
  151. k.set_contents_from_file(sfp, cb=callback, num_cb=10)
  152. self.assertEqual(self.my_cb_cnt, 1)
  153. self.assertEqual(self.my_cb_last, 0)
  154. sfp.close()
  155. # Read back zero bytes => 1 call
  156. self.my_cb_cnt = 0
  157. self.my_cb_last = None
  158. s = k.get_contents_as_string(cb=callback)
  159. self.assertEqual(self.my_cb_cnt, 1)
  160. self.assertEqual(self.my_cb_last, 0)
  161. content="01234567890123456789"
  162. sfp = StringIO.StringIO(content)
  163. # expect 2 calls due start/finish
  164. self.my_cb_cnt = 0
  165. self.my_cb_last = None
  166. k = self.bucket.new_key("k")
  167. k.set_contents_from_file(sfp, cb=callback, num_cb=10)
  168. self.assertEqual(self.my_cb_cnt, 2)
  169. self.assertEqual(self.my_cb_last, 20)
  170. # Read back all bytes => 2 calls
  171. self.my_cb_cnt = 0
  172. self.my_cb_last = None
  173. s = k.get_contents_as_string(cb=callback)
  174. self.assertEqual(self.my_cb_cnt, 2)
  175. self.assertEqual(self.my_cb_last, 20)
  176. self.assertEqual(s, content)
  177. # rewind sfp and try upload again. -1 should call
  178. # for every read/write so that should make 11 when bs=2
  179. sfp.seek(0)
  180. self.my_cb_cnt = 0
  181. self.my_cb_last = None
  182. k = self.bucket.new_key("k")
  183. k.BufferSize = 2
  184. k.set_contents_from_file(sfp, cb=callback, num_cb=-1)
  185. self.assertEqual(self.my_cb_cnt, 11)
  186. self.assertEqual(self.my_cb_last, 20)
  187. # Read back all bytes => 11 calls
  188. self.my_cb_cnt = 0
  189. self.my_cb_last = None
  190. s = k.get_contents_as_string(cb=callback, num_cb=-1)
  191. self.assertEqual(self.my_cb_cnt, 11)
  192. self.assertEqual(self.my_cb_last, 20)
  193. self.assertEqual(s, content)
  194. # no more than 1 times => 2 times
  195. # last time always 20 bytes
  196. sfp.seek(0)
  197. self.my_cb_cnt = 0
  198. self.my_cb_last = None
  199. k = self.bucket.new_key("k")
  200. k.BufferSize = 2
  201. k.set_contents_from_file(sfp, cb=callback, num_cb=1)
  202. self.assertTrue(self.my_cb_cnt <= 2)
  203. self.assertEqual(self.my_cb_last, 20)
  204. # no more than 1 times => 2 times
  205. self.my_cb_cnt = 0
  206. self.my_cb_last = None
  207. s = k.get_contents_as_string(cb=callback, num_cb=1)
  208. self.assertTrue(self.my_cb_cnt <= 2)
  209. self.assertEqual(self.my_cb_last, 20)
  210. self.assertEqual(s, content)
  211. # no more than 2 times
  212. # last time always 20 bytes
  213. sfp.seek(0)
  214. self.my_cb_cnt = 0
  215. self.my_cb_last = None
  216. k = self.bucket.new_key("k")
  217. k.BufferSize = 2
  218. k.set_contents_from_file(sfp, cb=callback, num_cb=2)
  219. self.assertTrue(self.my_cb_cnt <= 2)
  220. self.assertEqual(self.my_cb_last, 20)
  221. # no more than 2 times
  222. self.my_cb_cnt = 0
  223. self.my_cb_last = None
  224. s = k.get_contents_as_string(cb=callback, num_cb=2)
  225. self.assertTrue(self.my_cb_cnt <= 2)
  226. self.assertEqual(self.my_cb_last, 20)
  227. self.assertEqual(s, content)
  228. # no more than 3 times
  229. # last time always 20 bytes
  230. sfp.seek(0)
  231. self.my_cb_cnt = 0
  232. self.my_cb_last = None
  233. k = self.bucket.new_key("k")
  234. k.BufferSize = 2
  235. k.set_contents_from_file(sfp, cb=callback, num_cb=3)
  236. self.assertTrue(self.my_cb_cnt <= 3)
  237. self.assertEqual(self.my_cb_last, 20)
  238. # no more than 3 times
  239. self.my_cb_cnt = 0
  240. self.my_cb_last = None
  241. s = k.get_contents_as_string(cb=callback, num_cb=3)
  242. self.assertTrue(self.my_cb_cnt <= 3)
  243. self.assertEqual(self.my_cb_last, 20)
  244. self.assertEqual(s, content)
  245. # no more than 4 times
  246. # last time always 20 bytes
  247. sfp.seek(0)
  248. self.my_cb_cnt = 0
  249. self.my_cb_last = None
  250. k = self.bucket.new_key("k")
  251. k.BufferSize = 2
  252. k.set_contents_from_file(sfp, cb=callback, num_cb=4)
  253. self.assertTrue(self.my_cb_cnt <= 4)
  254. self.assertEqual(self.my_cb_last, 20)
  255. # no more than 4 times
  256. self.my_cb_cnt = 0
  257. self.my_cb_last = None
  258. s = k.get_contents_as_string(cb=callback, num_cb=4)
  259. self.assertTrue(self.my_cb_cnt <= 4)
  260. self.assertEqual(self.my_cb_last, 20)
  261. self.assertEqual(s, content)
  262. # no more than 6 times
  263. # last time always 20 bytes
  264. sfp.seek(0)
  265. self.my_cb_cnt = 0
  266. self.my_cb_last = None
  267. k = self.bucket.new_key("k")
  268. k.BufferSize = 2
  269. k.set_contents_from_file(sfp, cb=callback, num_cb=6)
  270. self.assertTrue(self.my_cb_cnt <= 6)
  271. self.assertEqual(self.my_cb_last, 20)
  272. # no more than 6 times
  273. self.my_cb_cnt = 0
  274. self.my_cb_last = None
  275. s = k.get_contents_as_string(cb=callback, num_cb=6)
  276. self.assertTrue(self.my_cb_cnt <= 6)
  277. self.assertEqual(self.my_cb_last, 20)
  278. self.assertEqual(s, content)
  279. # no more than 10 times
  280. # last time always 20 bytes
  281. sfp.seek(0)
  282. self.my_cb_cnt = 0
  283. self.my_cb_last = None
  284. k = self.bucket.new_key("k")
  285. k.BufferSize = 2
  286. k.set_contents_from_file(sfp, cb=callback, num_cb=10)
  287. self.assertTrue(self.my_cb_cnt <= 10)
  288. self.assertEqual(self.my_cb_last, 20)
  289. # no more than 10 times
  290. self.my_cb_cnt = 0
  291. self.my_cb_last = None
  292. s = k.get_contents_as_string(cb=callback, num_cb=10)
  293. self.assertTrue(self.my_cb_cnt <= 10)
  294. self.assertEqual(self.my_cb_last, 20)
  295. self.assertEqual(s, content)
  296. # no more than 1000 times
  297. # last time always 20 bytes
  298. sfp.seek(0)
  299. self.my_cb_cnt = 0
  300. self.my_cb_last = None
  301. k = self.bucket.new_key("k")
  302. k.BufferSize = 2
  303. k.set_contents_from_file(sfp, cb=callback, num_cb=1000)
  304. self.assertTrue(self.my_cb_cnt <= 1000)
  305. self.assertEqual(self.my_cb_last, 20)
  306. # no more than 1000 times
  307. self.my_cb_cnt = 0
  308. self.my_cb_last = None
  309. s = k.get_contents_as_string(cb=callback, num_cb=1000)
  310. self.assertTrue(self.my_cb_cnt <= 1000)
  311. self.assertEqual(self.my_cb_last, 20)
  312. self.assertEqual(s, content)