AzureBlobStorage.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. <?php
  2. namespace spec\Gaufrette\Adapter;
  3. use PHPSpec2\ObjectBehavior;
  4. use WindowsAzure\Blob\Models\Blob;
  5. use WindowsAzure\Common\ServiceException;
  6. class AzureBlobStorage extends ObjectBehavior
  7. {
  8. /**
  9. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  10. */
  11. public function let($blobProxyFactory)
  12. {
  13. $this->beConstructedWith($blobProxyFactory, 'containerName');
  14. }
  15. public function it_should_be_initializable()
  16. {
  17. $this->shouldHaveType('Gaufrette\Adapter\AzureBlobStorage');
  18. $this->shouldHaveType('Gaufrette\Adapter');
  19. $this->shouldHaveType('Gaufrette\Adapter\MetadataSupporter');
  20. }
  21. /**
  22. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  23. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  24. * @param \WindowsAzure\Blob\Models\GetBlobResult $getBlobResult
  25. */
  26. public function it_should_read_file($blobProxyFactory, $blobProxy, $getBlobResult)
  27. {
  28. $getBlobResult
  29. ->getContentStream()
  30. ->shouldBeCalled()
  31. //azure blob content is handled as stream so we need to fake it
  32. ->willReturn(fopen('data://text/plain,some content','r'));
  33. $blobProxy
  34. ->getBlob('containerName', 'filename')
  35. ->shouldBeCalled()
  36. ->willReturn($getBlobResult);
  37. $blobProxyFactory
  38. ->create()
  39. ->shouldBeCalled()
  40. ->willReturn($blobProxy);
  41. $this->read('filename')->shouldReturn('some content');
  42. }
  43. /**
  44. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  45. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  46. */
  47. public function it_should_return_false_when_cannot_read($blobProxyFactory, $blobProxy)
  48. {
  49. $blobProxy
  50. ->getBlob('containerName', 'filename')
  51. ->shouldBeCalled()
  52. ->willThrow(new ServiceException(500));
  53. $blobProxyFactory
  54. ->create()
  55. ->shouldBeCalled()
  56. ->willReturn($blobProxy);
  57. $this->read('filename')->shouldReturn(false);
  58. }
  59. /**
  60. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  61. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  62. */
  63. public function it_should_not_mask_exception_when_read($blobProxyFactory, $blobProxy)
  64. {
  65. $blobProxy
  66. ->getBlob('containerName', 'filename')
  67. ->shouldBeCalled()
  68. ->willThrow(new \RuntimeException('read'));
  69. $blobProxyFactory
  70. ->create()
  71. ->shouldBeCalled()
  72. ->willReturn($blobProxy);
  73. $this->shouldThrow(new \RuntimeException('read'))->duringRead('filename');
  74. }
  75. /**
  76. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  77. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  78. */
  79. public function it_should_rename_file($blobProxyFactory, $blobProxy)
  80. {
  81. $blobProxy
  82. ->copyBlob('containerName', 'filename2', 'containerName', 'filename1')
  83. ->shouldBeCalled();
  84. $blobProxy
  85. ->deleteBlob('containerName', 'filename1')
  86. ->shouldBeCalled();
  87. $blobProxyFactory
  88. ->create()
  89. ->shouldBeCalled()
  90. ->willReturn($blobProxy);
  91. $this->rename('filename1', 'filename2')->shouldReturn(true);
  92. }
  93. /**
  94. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  95. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  96. */
  97. public function it_should_return_false_when_cannot_rename($blobProxyFactory, $blobProxy)
  98. {
  99. $blobProxy
  100. ->copyBlob('containerName', 'filename2', 'containerName', 'filename1')
  101. ->shouldBeCalled()
  102. ->willThrow(new ServiceException(500));
  103. $blobProxyFactory
  104. ->create()
  105. ->shouldBeCalled()
  106. ->willReturn($blobProxy);
  107. $this->rename('filename1', 'filename2')->shouldReturn(false);
  108. }
  109. /**
  110. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  111. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  112. */
  113. public function it_should_not_mask_exception_when_rename($blobProxyFactory, $blobProxy)
  114. {
  115. $blobProxy
  116. ->copyBlob('containerName', 'filename2', 'containerName', 'filename1')
  117. ->shouldBeCalled()
  118. ->willThrow(new \RuntimeException('rename'));
  119. $blobProxyFactory
  120. ->create()
  121. ->shouldBeCalled()
  122. ->willReturn($blobProxy);
  123. $this->shouldThrow(new \RuntimeException('rename'))->duringRename('filename1', 'filename2');
  124. }
  125. /**
  126. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  127. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  128. */
  129. public function it_should_write_file($blobProxyFactory, $blobProxy)
  130. {
  131. $blobProxy
  132. ->createBlockBlob('containerName', 'filename', 'some content',
  133. \Mockery::type('\WindowsAzure\Blob\Models\CreateBlobOptions'))
  134. ->shouldBeCalled();
  135. $blobProxyFactory
  136. ->create()
  137. ->shouldBeCalled()
  138. ->willReturn($blobProxy);
  139. $this->write('filename', 'some content')->shouldReturn(12);
  140. }
  141. /**
  142. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  143. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  144. */
  145. public function it_should_return_false_when_cannot_write($blobProxyFactory, $blobProxy)
  146. {
  147. $blobProxy
  148. ->createBlockBlob('containerName', 'filename', 'some content',
  149. \Mockery::type('\WindowsAzure\Blob\Models\CreateBlobOptions'))
  150. ->willThrow(new ServiceException(500));
  151. $blobProxyFactory
  152. ->create()
  153. ->shouldBeCalled()
  154. ->willReturn($blobProxy);
  155. $this->write('filename', 'some content')->shouldReturn(false);
  156. }
  157. /**
  158. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  159. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  160. */
  161. public function it_should_not_mask_exception_when_write($blobProxyFactory, $blobProxy)
  162. {
  163. $blobProxy
  164. ->createBlockBlob('containerName', 'filename', 'some content',
  165. \Mockery::type('\WindowsAzure\Blob\Models\CreateBlobOptions'))
  166. ->willThrow(new \RuntimeException('write'));
  167. $blobProxyFactory
  168. ->create()
  169. ->shouldBeCalled()
  170. ->willReturn($blobProxy);
  171. $this->shouldThrow(new \RuntimeException('write'))->duringWrite('filename', 'some content');
  172. }
  173. /**
  174. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  175. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  176. * @param \WindowsAzure\Blob\Models\GetBlobResult $getBlobResult
  177. */
  178. public function it_should_check_if_file_exists($blobProxyFactory, $blobProxy, $getBlobResult)
  179. {
  180. $blobProxyFactory
  181. ->create()
  182. ->shouldBeCalled()
  183. ->willReturn($blobProxy);
  184. $blobProxy
  185. ->getBlob('containerName', 'filename')
  186. ->shouldBeCalled()
  187. ->willThrow(new ServiceException(404));
  188. $this->exists('filename')->shouldReturn(false);
  189. $blobProxy
  190. ->getBlob('containerName', 'filename2')
  191. ->shouldBeCalled()
  192. ->willReturn($getBlobResult);
  193. $this->exists('filename2')->shouldReturn(true);
  194. }
  195. /**
  196. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  197. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  198. */
  199. public function it_should_not_mask_exception_when_check_if_file_exists($blobProxyFactory, $blobProxy)
  200. {
  201. $blobProxyFactory
  202. ->create()
  203. ->shouldBeCalled()
  204. ->willReturn($blobProxy);
  205. $blobProxy
  206. ->getBlob('containerName', 'filename')
  207. ->shouldBeCalled()
  208. ->willThrow(new \RuntimeException('exists'));
  209. $this->shouldThrow(new \RuntimeException('exists'))->duringExists('filename');
  210. }
  211. /**
  212. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  213. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  214. * @param \WindowsAzure\Blob\Models\GetBlobPropertiesResult $getBlobPropertiesResult
  215. * @param \WindowsAzure\Blob\Models\BlobProperties $blobProperties
  216. */
  217. public function it_should_get_file_mtime($blobProxyFactory, $blobProxy, $getBlobPropertiesResult, $blobProperties)
  218. {
  219. $blobProxyFactory
  220. ->create()
  221. ->shouldBeCalled()
  222. ->willReturn($blobProxy);
  223. $blobProxy
  224. ->getBlobProperties('containerName', 'filename')
  225. ->shouldBeCalled()
  226. ->willReturn($getBlobPropertiesResult);
  227. $getBlobPropertiesResult
  228. ->getProperties()
  229. ->shouldBeCalled()
  230. ->willReturn($blobProperties);
  231. $blobProperties
  232. ->getLastModified()
  233. ->shouldBeCalled()
  234. ->willReturn(new \DateTime('1987-12-28 20:00:00'));
  235. $this->mtime('filename')->shouldReturn(strtotime('1987-12-28 20:00:00'));
  236. }
  237. /**
  238. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  239. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  240. */
  241. public function it_should_return_false_when_cannot_mtime($blobProxyFactory, $blobProxy)
  242. {
  243. $blobProxyFactory
  244. ->create()
  245. ->shouldBeCalled()
  246. ->willReturn($blobProxy);
  247. $blobProxy
  248. ->getBlobProperties('containerName', 'filename')
  249. ->shouldBeCalled()
  250. ->willThrow(new ServiceException(500));
  251. $this->mtime('filename')->shouldReturn(false);
  252. }
  253. /**
  254. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  255. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  256. */
  257. public function it_should_not_mask_exception_when_get_mtime($blobProxyFactory, $blobProxy)
  258. {
  259. $blobProxyFactory
  260. ->create()
  261. ->shouldBeCalled()
  262. ->willReturn($blobProxy);
  263. $blobProxy
  264. ->getBlobProperties('containerName', 'filename')
  265. ->shouldBeCalled()
  266. ->willThrow(new \RuntimeException('mtime'));
  267. $this->shouldThrow(new \RuntimeException('mtime'))->duringMtime('filename');
  268. }
  269. /**
  270. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  271. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  272. */
  273. public function it_should_delete_file($blobProxyFactory, $blobProxy)
  274. {
  275. $blobProxyFactory
  276. ->create()
  277. ->shouldBeCalled()
  278. ->willReturn($blobProxy);
  279. $blobProxy
  280. ->deleteBlob('containerName', 'filename')
  281. ->shouldBeCalled();
  282. $this->delete('filename')->shouldReturn(true);
  283. }
  284. /**
  285. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  286. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  287. */
  288. public function it_should_return_false_when_cannot_delete_file($blobProxyFactory, $blobProxy)
  289. {
  290. $blobProxyFactory
  291. ->create()
  292. ->shouldBeCalled()
  293. ->willReturn($blobProxy);
  294. $blobProxy
  295. ->deleteBlob('containerName', 'filename')
  296. ->shouldBeCalled()
  297. ->willThrow(new ServiceException(500));
  298. $this->delete('filename')->shouldReturn(false);
  299. }
  300. /**
  301. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  302. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  303. */
  304. public function it_should_not_mask_exception_when_delete($blobProxyFactory, $blobProxy)
  305. {
  306. $blobProxyFactory
  307. ->create()
  308. ->shouldBeCalled()
  309. ->willReturn($blobProxy);
  310. $blobProxy
  311. ->deleteBlob('containerName', 'filename')
  312. ->shouldBeCalled()
  313. ->willThrow(new \RuntimeException('delete'));
  314. $this->shouldThrow(new \RuntimeException('delete'))->duringDelete('filename');
  315. }
  316. /**
  317. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  318. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  319. * @param \WindowsAzure\Blob\Models\ListBlobsResult $listBlobResult
  320. */
  321. public function it_should_get_keys($blobProxyFactory, $blobProxy, $listBlobResult)
  322. {
  323. $fileNames = array('aaa', 'aaa/filename', 'filename1', 'filename2');
  324. $blobs = array();
  325. foreach ($fileNames as $fileName) {
  326. $blob = new Blob();
  327. $blob->setName($fileName);
  328. $blobs[] = $blob;
  329. }
  330. $blobProxyFactory
  331. ->create()
  332. ->shouldBeCalled()
  333. ->willReturn($blobProxy);
  334. $blobProxy
  335. ->listBlobs('containerName')
  336. ->shouldBeCalled()
  337. ->willReturn($listBlobResult);
  338. $listBlobResult
  339. ->getBlobs()
  340. ->shouldBeCalled()
  341. ->willReturn($blobs);
  342. $this->keys()->shouldReturn(array('aaa', 'aaa/filename', 'filename1', 'filename2'));
  343. }
  344. /**
  345. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  346. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  347. */
  348. public function it_should_not_mask_exception_when_get_keys($blobProxyFactory, $blobProxy)
  349. {
  350. $blobProxyFactory
  351. ->create()
  352. ->shouldBeCalled()
  353. ->willReturn($blobProxy);
  354. $blobProxy
  355. ->listBlobs('containerName')
  356. ->shouldBeCalled()
  357. ->willThrow(new \RuntimeException('keys'));
  358. $this->shouldThrow(new \RuntimeException('keys'))->duringKeys();
  359. }
  360. /**
  361. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  362. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  363. */
  364. public function it_should_handle_dirs($blobProxyFactory, $blobProxy)
  365. {
  366. $blobProxyFactory
  367. ->create()
  368. ->shouldBeCalled()
  369. ->willReturn($blobProxy);
  370. $blobProxy
  371. ->getBlob('containerName', 'filename')
  372. ->shouldNotBeCalled();
  373. $blobProxy
  374. ->getBlob('containerName', 'filename/')
  375. ->shouldBeCalled()
  376. ->willThrow(new ServiceException(404));
  377. $blobProxy
  378. ->getBlob('containerName', 'dirname/')
  379. ->shouldBeCalled();
  380. $this->isDirectory('filename')->shouldReturn(false);
  381. $this->isDirectory('dirname')->shouldReturn(true);
  382. }
  383. /**
  384. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  385. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  386. */
  387. public function it_should_create_container($blobProxyFactory, $blobProxy)
  388. {
  389. $blobProxyFactory
  390. ->create()
  391. ->shouldBeCalled()
  392. ->willReturn($blobProxy);
  393. $blobProxy
  394. ->createContainer('containerName', null)
  395. ->shouldBeCalled();
  396. $this->createContainer('containerName');
  397. }
  398. /**
  399. * @param \Gaufrette\Adapter\AzureBlobStorage\BlobProxyFactoryInterface $blobProxyFactory
  400. * @param \WindowsAzure\Blob\Internal\IBlob $blobProxy
  401. */
  402. public function it_should_fail_when_cannot_create_container($blobProxyFactory, $blobProxy)
  403. {
  404. $blobProxyFactory
  405. ->create()
  406. ->shouldBeCalled()
  407. ->willReturn($blobProxy);
  408. $blobProxy
  409. ->createContainer('containerName', null)
  410. ->shouldBeCalled()
  411. ->willThrow(new ServiceException(500));
  412. $this->shouldThrow(new \RuntimeException('Failed to create the configured container "containerName": 0 ().', null))->duringCreateContainer('containerName');
  413. }
  414. }