azurex 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (299) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.travis.yml +11 -0
  4. data/ChangeLog.txt +40 -0
  5. data/Gemfile +16 -0
  6. data/README.md +606 -0
  7. data/Rakefile +125 -0
  8. data/azurex.gemspec +47 -0
  9. data/lib/azure.rb +52 -0
  10. data/lib/azure/base_management/affinity_group.rb +32 -0
  11. data/lib/azure/base_management/base_management_service.rb +238 -0
  12. data/lib/azure/base_management/location.rb +27 -0
  13. data/lib/azure/base_management/management_http_request.rb +244 -0
  14. data/lib/azure/base_management/serialization.rb +129 -0
  15. data/lib/azure/base_management/sql_management_http_request.rb +45 -0
  16. data/lib/azure/blob/blob.rb +32 -0
  17. data/lib/azure/blob/blob_service.rb +1424 -0
  18. data/lib/azure/blob/block.rb +31 -0
  19. data/lib/azure/blob/container.rb +32 -0
  20. data/lib/azure/blob/serialization.rb +285 -0
  21. data/lib/azure/cloud_service_management/cloud_service.rb +38 -0
  22. data/lib/azure/cloud_service_management/cloud_service_management_service.rb +361 -0
  23. data/lib/azure/cloud_service_management/configuration_set.rb +28 -0
  24. data/lib/azure/cloud_service_management/deployment.rb +64 -0
  25. data/lib/azure/cloud_service_management/input_endpoint.rb +29 -0
  26. data/lib/azure/cloud_service_management/instance_endpoint.rb +31 -0
  27. data/lib/azure/cloud_service_management/persistent_vm_downtime.rb +29 -0
  28. data/lib/azure/cloud_service_management/role.rb +30 -0
  29. data/lib/azure/cloud_service_management/role_instance.rb +40 -0
  30. data/lib/azure/cloud_service_management/serialization.rb +329 -0
  31. data/lib/azure/cloud_service_management/virtual_ip.rb +29 -0
  32. data/lib/azure/core.rb +39 -0
  33. data/lib/azure/core/auth/authorizer.rb +36 -0
  34. data/lib/azure/core/auth/shared_key.rb +110 -0
  35. data/lib/azure/core/auth/shared_key_lite.rb +48 -0
  36. data/lib/azure/core/auth/signer.rb +48 -0
  37. data/lib/azure/core/configuration.rb +211 -0
  38. data/lib/azure/core/error.rb +22 -0
  39. data/lib/azure/core/filtered_service.rb +44 -0
  40. data/lib/azure/core/http/debug_filter.rb +36 -0
  41. data/lib/azure/core/http/http_error.rb +88 -0
  42. data/lib/azure/core/http/http_filter.rb +53 -0
  43. data/lib/azure/core/http/http_request.rb +159 -0
  44. data/lib/azure/core/http/http_response.rb +140 -0
  45. data/lib/azure/core/http/retry_policy.rb +74 -0
  46. data/lib/azure/core/http/signer_filter.rb +34 -0
  47. data/lib/azure/core/service.rb +63 -0
  48. data/lib/azure/core/signed_service.rb +43 -0
  49. data/lib/azure/core/utility.rb +190 -0
  50. data/lib/azure/queue/message.rb +30 -0
  51. data/lib/azure/queue/queue.rb +29 -0
  52. data/lib/azure/queue/queue_service.rb +568 -0
  53. data/lib/azure/queue/serialization.rb +106 -0
  54. data/lib/azure/service/access_policy.rb +26 -0
  55. data/lib/azure/service/enumeration_results.rb +21 -0
  56. data/lib/azure/service/logging.rb +32 -0
  57. data/lib/azure/service/metrics.rb +31 -0
  58. data/lib/azure/service/retention_policy.rb +25 -0
  59. data/lib/azure/service/serialization.rb +240 -0
  60. data/lib/azure/service/signed_identifier.rb +30 -0
  61. data/lib/azure/service/storage_service.rb +79 -0
  62. data/lib/azure/service/storage_service_properties.rb +32 -0
  63. data/lib/azure/service_bus/action.rb +21 -0
  64. data/lib/azure/service_bus/auth/wrap_service.rb +89 -0
  65. data/lib/azure/service_bus/auth/wrap_signer.rb +69 -0
  66. data/lib/azure/service_bus/brokered_message.rb +124 -0
  67. data/lib/azure/service_bus/brokered_message_serializer.rb +159 -0
  68. data/lib/azure/service_bus/correlation_filter.rb +45 -0
  69. data/lib/azure/service_bus/empty_rule_action.rb +30 -0
  70. data/lib/azure/service_bus/false_filter.rb +38 -0
  71. data/lib/azure/service_bus/filter.rb +21 -0
  72. data/lib/azure/service_bus/interval.rb +104 -0
  73. data/lib/azure/service_bus/queue.rb +230 -0
  74. data/lib/azure/service_bus/resource.rb +109 -0
  75. data/lib/azure/service_bus/rule.rb +98 -0
  76. data/lib/azure/service_bus/rule_aspect.rb +34 -0
  77. data/lib/azure/service_bus/serialization.rb +160 -0
  78. data/lib/azure/service_bus/service_bus_service.rb +829 -0
  79. data/lib/azure/service_bus/sql_filter.rb +50 -0
  80. data/lib/azure/service_bus/sql_rule_action.rb +50 -0
  81. data/lib/azure/service_bus/subscription.rb +184 -0
  82. data/lib/azure/service_bus/topic.rb +187 -0
  83. data/lib/azure/service_bus/true_filter.rb +38 -0
  84. data/lib/azure/sql_database_management/serialization.rb +111 -0
  85. data/lib/azure/sql_database_management/sql_database.rb +31 -0
  86. data/lib/azure/sql_database_management/sql_database_management_service.rb +200 -0
  87. data/lib/azure/storage_management/serialization.rb +206 -0
  88. data/lib/azure/storage_management/storage_account.rb +47 -0
  89. data/lib/azure/storage_management/storage_management_service.rb +211 -0
  90. data/lib/azure/table/auth/shared_key.rb +92 -0
  91. data/lib/azure/table/auth/shared_key_lite.rb +44 -0
  92. data/lib/azure/table/batch.rb +330 -0
  93. data/lib/azure/table/batch_response.rb +118 -0
  94. data/lib/azure/table/edmtype.rb +127 -0
  95. data/lib/azure/table/entity.rb +31 -0
  96. data/lib/azure/table/guid.rb +24 -0
  97. data/lib/azure/table/query.rb +112 -0
  98. data/lib/azure/table/serialization.rb +108 -0
  99. data/lib/azure/table/table_service.rb +560 -0
  100. data/lib/azure/version.rb +31 -0
  101. data/lib/azure/virtual_machine_image_management/serialization.rb +52 -0
  102. data/lib/azure/virtual_machine_image_management/virtual_machine_disk.rb +25 -0
  103. data/lib/azure/virtual_machine_image_management/virtual_machine_image.rb +25 -0
  104. data/lib/azure/virtual_machine_image_management/virtual_machine_image_management_service.rb +66 -0
  105. data/lib/azure/virtual_machine_management/serialization.rb +450 -0
  106. data/lib/azure/virtual_machine_management/virtual_machine.rb +45 -0
  107. data/lib/azure/virtual_machine_management/virtual_machine_management_service.rb +562 -0
  108. data/lib/azure/virtual_network_management/serialization.rb +192 -0
  109. data/lib/azure/virtual_network_management/virtual_network.rb +37 -0
  110. data/lib/azure/virtual_network_management/virtual_network_management_service.rb +109 -0
  111. data/test/fixtures/32px-fulls-black.jpg +0 -0
  112. data/test/fixtures/affinity_group.xml +33 -0
  113. data/test/fixtures/all_containers.xml +20 -0
  114. data/test/fixtures/all_tables.xml +22 -0
  115. data/test/fixtures/certificate.pem +21 -0
  116. data/test/fixtures/container_acl.xml +11 -0
  117. data/test/fixtures/create_sql_database_server.xml +2 -0
  118. data/test/fixtures/create_storage_desc_error.xml +5 -0
  119. data/test/fixtures/create_storage_extendedprop_error.xml +8 -0
  120. data/test/fixtures/create_storage_extendedpropname_error.xml +6 -0
  121. data/test/fixtures/create_storage_full_error.xml +6 -0
  122. data/test/fixtures/create_storage_label_error.xml +5 -0
  123. data/test/fixtures/create_storage_location_error.xml +5 -0
  124. data/test/fixtures/create_storage_name_error.xml +6 -0
  125. data/test/fixtures/create_table_response_entry.xml +15 -0
  126. data/test/fixtures/delete_storage_container_error.xml +5 -0
  127. data/test/fixtures/delete_storage_error.xml +5 -0
  128. data/test/fixtures/deployment_error.xml +5 -0
  129. data/test/fixtures/empty_xml_file +0 -0
  130. data/test/fixtures/get_deployment.xml +94 -0
  131. data/test/fixtures/get_deployment_existing.xml +94 -0
  132. data/test/fixtures/get_deployment_missing.xml +5 -0
  133. data/test/fixtures/get_storage_account_error.xml +5 -0
  134. data/test/fixtures/get_storage_account_properties.xml +32 -0
  135. data/test/fixtures/get_storage_account_properties_new.xml +32 -0
  136. data/test/fixtures/http_error.xml +5 -0
  137. data/test/fixtures/insert_entity_response_entry.xml +25 -0
  138. data/test/fixtures/list_affinity_groups.xml +22 -0
  139. data/test/fixtures/list_blobs.xml +121 -0
  140. data/test/fixtures/list_block_all_with_none_committed.xml +22 -0
  141. data/test/fixtures/list_blocks_all.xml +23 -0
  142. data/test/fixtures/list_blocks_committed.xml +13 -0
  143. data/test/fixtures/list_cloud_services.xml +39 -0
  144. data/test/fixtures/list_containers.xml +38 -0
  145. data/test/fixtures/list_firewall_management_endpoint.xml +27 -0
  146. data/test/fixtures/list_images.xml +110 -0
  147. data/test/fixtures/list_locations.xml +62 -0
  148. data/test/fixtures/list_page_ranges.xml +11 -0
  149. data/test/fixtures/list_sql_database.xml +36 -0
  150. data/test/fixtures/list_sql_server_firewall.xml +23 -0
  151. data/test/fixtures/list_storage_account_single.xml +25 -0
  152. data/test/fixtures/list_storage_accounts.xml +46 -0
  153. data/test/fixtures/list_virtual_networks.xml +92 -0
  154. data/test/fixtures/logging.xml +11 -0
  155. data/test/fixtures/management_certificate.pem +55 -0
  156. data/test/fixtures/messages.xml +12 -0
  157. data/test/fixtures/metrics.xml +10 -0
  158. data/test/fixtures/privatekey.key +28 -0
  159. data/test/fixtures/query_entities_empty_response.xml +7 -0
  160. data/test/fixtures/query_entities_response.xml +45 -0
  161. data/test/fixtures/queue_service_properties.xml +22 -0
  162. data/test/fixtures/queue_service_properties_original.xml +19 -0
  163. data/test/fixtures/queues.xml +16 -0
  164. data/test/fixtures/retention_policy.xml +5 -0
  165. data/test/fixtures/sb_default_create_queue_response.xml +23 -0
  166. data/test/fixtures/sb_default_create_topic_response.xml +18 -0
  167. data/test/fixtures/sb_get_access_token_response.txt +1 -0
  168. data/test/fixtures/sb_queues_runtime_peek_message_response_headers.txt +9 -0
  169. data/test/fixtures/storage_service_keys.xml +8 -0
  170. data/test/fixtures/storage_service_properties.xml +23 -0
  171. data/test/fixtures/update_storage_account.xml +16 -0
  172. data/test/fixtures/update_storage_error.xml +5 -0
  173. data/test/fixtures/updated_storage_accounts.xml +53 -0
  174. data/test/fixtures/virtual_machine.xml +115 -0
  175. data/test/fixtures/windows_virtual_machine.xml +106 -0
  176. data/test/integration/affinity_group/Affinity_test.rb +55 -0
  177. data/test/integration/affinity_group/Create_Affinity_test.rb +63 -0
  178. data/test/integration/affinity_group/Delete_Affinity_test.rb +56 -0
  179. data/test/integration/affinity_group/List_Affinity_test.rb +41 -0
  180. data/test/integration/affinity_group/Update_Affinity_test.rb +82 -0
  181. data/test/integration/blob/blob_gb18030_test.rb +199 -0
  182. data/test/integration/blob/blob_metadata_test.rb +75 -0
  183. data/test/integration/blob/blob_pages_test.rb +119 -0
  184. data/test/integration/blob/blob_properties_test.rb +77 -0
  185. data/test/integration/blob/block_blob_test.rb +254 -0
  186. data/test/integration/blob/container/container_acl_test.rb +69 -0
  187. data/test/integration/blob/container/container_metadata_test.rb +50 -0
  188. data/test/integration/blob/container/create_container_test.rb +60 -0
  189. data/test/integration/blob/container/delete_container_test.rb +39 -0
  190. data/test/integration/blob/container/get_container_properties_test.rb +48 -0
  191. data/test/integration/blob/container/list_containers_test.rb +79 -0
  192. data/test/integration/blob/container/root_container_test.rb +54 -0
  193. data/test/integration/blob/copy_blob_test.rb +113 -0
  194. data/test/integration/blob/create_blob_snapshot_test.rb +80 -0
  195. data/test/integration/blob/create_page_blob_test.rb +83 -0
  196. data/test/integration/blob/delete_blob_test.rb +159 -0
  197. data/test/integration/blob/get_blob_test.rb +65 -0
  198. data/test/integration/blob/informative_errors_test.rb +39 -0
  199. data/test/integration/blob/lease/acquire_lease_test.rb +36 -0
  200. data/test/integration/blob/lease/break_lease_test.rb +40 -0
  201. data/test/integration/blob/lease/release_lease_test.rb +40 -0
  202. data/test/integration/blob/lease/renew_lease_test.rb +42 -0
  203. data/test/integration/blob/list_blobs_test.rb +113 -0
  204. data/test/integration/cloud_service/Cloud_Create_test.rb +44 -0
  205. data/test/integration/cloud_service/Cloud_Delete_test.rb +44 -0
  206. data/test/integration/database/create_sql_server_firewall_test.rb +86 -0
  207. data/test/integration/database/create_sql_server_test.rb +53 -0
  208. data/test/integration/database/delete_sql_server_firewall_test.rb +70 -0
  209. data/test/integration/database/delete_sql_server_test.rb +58 -0
  210. data/test/integration/database/list_sql_server_firewall_test.rb +45 -0
  211. data/test/integration/database/list_sql_servers_test.rb +44 -0
  212. data/test/integration/database/reset_password_sql_server_test.rb +55 -0
  213. data/test/integration/location/Location_List_test.rb +39 -0
  214. data/test/integration/queue/clear_messages_test.rb +42 -0
  215. data/test/integration/queue/create_message_test.rb +75 -0
  216. data/test/integration/queue/create_queue_test.rb +50 -0
  217. data/test/integration/queue/delete_message_test.rb +67 -0
  218. data/test/integration/queue/delete_queue_test.rb +45 -0
  219. data/test/integration/queue/informative_errors_test.rb +42 -0
  220. data/test/integration/queue/list_messages_encoded_test.rb +79 -0
  221. data/test/integration/queue/list_messages_test.rb +79 -0
  222. data/test/integration/queue/list_queues_test.rb +44 -0
  223. data/test/integration/queue/peek_messages_test.rb +59 -0
  224. data/test/integration/queue/queue_gb18030_test.rb +131 -0
  225. data/test/integration/queue/queue_metadata_test.rb +40 -0
  226. data/test/integration/queue/update_message_test.rb +74 -0
  227. data/test/integration/service_bus/informative_errors_test.rb +37 -0
  228. data/test/integration/service_bus/queues_scenario_test.rb +200 -0
  229. data/test/integration/service_bus/queues_test.rb +266 -0
  230. data/test/integration/service_bus/rules_test.rb +145 -0
  231. data/test/integration/service_bus/sb_queue_gb18030_test.rb +182 -0
  232. data/test/integration/service_bus/scenario_test.rb +101 -0
  233. data/test/integration/service_bus/subscriptions_test.rb +211 -0
  234. data/test/integration/service_bus/topics_scenario_test.rb +406 -0
  235. data/test/integration/service_bus/topics_test.rb +129 -0
  236. data/test/integration/storage_management/storage_management_test.rb +177 -0
  237. data/test/integration/table/create_table_test.rb +36 -0
  238. data/test/integration/table/delete_entity_batch_test.rb +107 -0
  239. data/test/integration/table/delete_entity_test.rb +94 -0
  240. data/test/integration/table/delete_table_test.rb +40 -0
  241. data/test/integration/table/get_table_test.rb +37 -0
  242. data/test/integration/table/informative_errors_test.rb +39 -0
  243. data/test/integration/table/insert_entity_batch_test.rb +100 -0
  244. data/test/integration/table/insert_entity_test.rb +88 -0
  245. data/test/integration/table/insert_or_merge_entity_batch_test.rb +159 -0
  246. data/test/integration/table/insert_or_merge_entity_test.rb +143 -0
  247. data/test/integration/table/insert_or_replace_entity_batch_test.rb +152 -0
  248. data/test/integration/table/insert_or_replace_entity_test.rb +137 -0
  249. data/test/integration/table/merge_entity_batch_test.rb +128 -0
  250. data/test/integration/table/merge_entity_test.rb +113 -0
  251. data/test/integration/table/query_entities_test.rb +195 -0
  252. data/test/integration/table/query_tables_test.rb +43 -0
  253. data/test/integration/table/query_test.rb +251 -0
  254. data/test/integration/table/table_acl_test.rb +52 -0
  255. data/test/integration/table/table_gb18030_test.rb +355 -0
  256. data/test/integration/table/update_entity_batch_test.rb +149 -0
  257. data/test/integration/table/update_entity_test.rb +131 -0
  258. data/test/integration/test_helper.rb +42 -0
  259. data/test/integration/vm/VM_Create_test.rb +260 -0
  260. data/test/integration/vm/VM_Delete_test.rb +53 -0
  261. data/test/integration/vm/VM_Operations_test.rb +172 -0
  262. data/test/integration/vm_image/virtual_machine_disk_test.rb +37 -0
  263. data/test/integration/vm_image/virtual_machine_image_test.rb +37 -0
  264. data/test/integration/vnet/Virtual_Network_Create_test.rb +116 -0
  265. data/test/integration/vnet/Virtual_Network_list_test.rb +48 -0
  266. data/test/support/env.rb +19 -0
  267. data/test/support/fixtures.rb +36 -0
  268. data/test/support/name_generator.rb +160 -0
  269. data/test/support/stubs.rb +42 -0
  270. data/test/support/virtual_machine_name_generator.rb +102 -0
  271. data/test/support/virtual_network_helper.rb +73 -0
  272. data/test/test_helper.rb +53 -0
  273. data/test/unit/affinity_group/affinity_group_test.rb +192 -0
  274. data/test/unit/affinity_group/serialization_test.rb +88 -0
  275. data/test/unit/base_management/location_test.rb +57 -0
  276. data/test/unit/blob/blob_service_test.rb +1947 -0
  277. data/test/unit/cloud_service_management/cloud_service_management_service_test.rb +248 -0
  278. data/test/unit/cloud_service_management/serialization_test.rb +169 -0
  279. data/test/unit/core/auth/shared_key_lite_test.rb +51 -0
  280. data/test/unit/core/auth/shared_key_test.rb +58 -0
  281. data/test/unit/core/auth/signer_test.rb +30 -0
  282. data/test/unit/core/http/http_error_test.rb +57 -0
  283. data/test/unit/core/http/http_request_test.rb +66 -0
  284. data/test/unit/core/http/http_response_test.rb +45 -0
  285. data/test/unit/core/http/retry_policy_test.rb +23 -0
  286. data/test/unit/database/serialization_test.rb +97 -0
  287. data/test/unit/database/sql_database_server_service_test.rb +288 -0
  288. data/test/unit/service/serialization_test.rb +502 -0
  289. data/test/unit/service/storage_service_test.rb +291 -0
  290. data/test/unit/storage_management/serialization_test.rb +245 -0
  291. data/test/unit/storage_management/storage_management_service_test.rb +261 -0
  292. data/test/unit/table/edmtype_test.rb +108 -0
  293. data/test/unit/virtual_machine_image_management/serialization_test.rb +35 -0
  294. data/test/unit/virtual_machine_image_management/virtual_machine_image_management_service_test.rb +65 -0
  295. data/test/unit/virtual_machine_management/serialization_test.rb +256 -0
  296. data/test/unit/virtual_machine_management/virtual_machine_management_service_test.rb +442 -0
  297. data/test/unit/vnet/serialization_test.rb +187 -0
  298. data/test/unit/vnet/virtual_network_management_service_test.rb +131 -0
  299. metadata +471 -0
@@ -0,0 +1,88 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright 2013 Microsoft Open Technologies, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (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
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #--------------------------------------------------------------------------
15
+ require 'test_helper'
16
+
17
+ describe Azure::BaseManagement::Serialization do
18
+
19
+ subject { Azure::BaseManagement::Serialization }
20
+ let(:location) { 'West Us' }
21
+
22
+ describe '#affinity_group_to_xml' do
23
+ let(:affinity_group_name) { 'AG1' }
24
+ let(:label) { 'Label Name' }
25
+
26
+ it 'serializes the argument to xml' do
27
+ result = subject.affinity_group_to_xml(affinity_group_name,
28
+ location,
29
+ label)
30
+ doc = Nokogiri::XML result
31
+ doc.css('Name').text.must_equal affinity_group_name
32
+ doc.css('Label').text.must_equal Base64.encode64(label).strip
33
+ doc.css('Location').text.must_equal location
34
+ result.must_be_kind_of String
35
+ end
36
+
37
+ it 'serializes the argument to xml when optional description is given' do
38
+ options = { description: 'Affinity Group Description' }
39
+ result = subject.affinity_group_to_xml(affinity_group_name,
40
+ location,
41
+ label,
42
+ options)
43
+ doc = Nokogiri::XML result
44
+ doc.css('Name').text.must_equal affinity_group_name
45
+ doc.css('Label').text.must_equal Base64.encode64(label).strip
46
+ doc.css('Description').text.must_equal options[:description]
47
+ doc.css('Location').text.must_equal location
48
+ result.must_be_kind_of String
49
+ end
50
+ end
51
+
52
+ describe '#affinity_groups_from_xml' do
53
+ let(:affinity_groups_xml) do
54
+ Nokogiri::XML(Fixtures['list_affinity_groups'])
55
+ end
56
+
57
+ it 'accepts an XML string' do
58
+ subject.affinity_groups_from_xml affinity_groups_xml
59
+ end
60
+
61
+ it 'returns an Array of Azure::BaseManagementt::AffinityGroup instances' do
62
+ results = subject.affinity_groups_from_xml affinity_groups_xml
63
+ results.must_be_kind_of Array
64
+ results[0].must_be_kind_of Azure::BaseManagement::AffinityGroup
65
+ results.count.must_equal 2
66
+ end
67
+ end
68
+
69
+ describe '#affinity_group_from_xml' do
70
+
71
+ let(:affinity_group_xml) { Nokogiri::XML(Fixtures['affinity_group']) }
72
+
73
+ it 'accepts an XML string' do
74
+ subject.affinity_group_from_xml affinity_group_xml
75
+ end
76
+
77
+ it 'returns an Azure::BaseManagement::AffinityGroup instances' do
78
+ affinity_group = subject.affinity_group_from_xml affinity_group_xml
79
+ affinity_group.must_be_kind_of Azure::BaseManagement::AffinityGroup
80
+ affinity_group.hosted_services.size.must_equal 1
81
+ affinity_group.storage_services.size.must_equal 1
82
+ affinity_group.capability.must_equal %w[PersistentVMRole HighMemory]
83
+ affinity_group.name.must_equal affinity_group_xml.css('Name').text
84
+ affinity_group.description.must_equal affinity_group_xml.css(
85
+ 'Description').text
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,57 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright 2013 Microsoft Open Technologies, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (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
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #--------------------------------------------------------------------------
15
+ require "test_helper"
16
+
17
+ describe Azure::BaseManagement::Location do
18
+
19
+ subject do
20
+ Azure::BaseManagementService.new
21
+ end
22
+
23
+ describe "#list_locations" do
24
+ let(:request_path) { '/locations' }
25
+ let(:locations_xml) { Fixtures['list_locations'] }
26
+ let(:method) { :get }
27
+ let(:mock_request){ mock() }
28
+ let(:response) {
29
+ response = mock()
30
+ response.stubs(:body).returns(locations_xml)
31
+ response
32
+ }
33
+ let(:response_body) { Nokogiri::XML response.body }
34
+
35
+ before {
36
+ ManagementHttpRequest.stubs(:new).with(method, request_path, nil).returns(mock_request)
37
+ mock_request.expects(:call).returns(response_body)
38
+ }
39
+
40
+ it "assembles a URI for the request" do
41
+ subject.list_locations
42
+ end
43
+
44
+ it "sets the properties of the location" do
45
+ location = subject.list_locations.first
46
+ location.name.must_equal 'West US'
47
+ end
48
+
49
+ it "returns a list of locations data center locations that are valid for given subscription" do
50
+ results = subject.list_locations
51
+ results.must_be_kind_of Array
52
+ results.length.must_equal 6
53
+ results.first.must_be_kind_of Azure::BaseManagement::Location
54
+ end
55
+ end
56
+
57
+ end
@@ -0,0 +1,1947 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (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
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #--------------------------------------------------------------------------
15
+ require 'test_helper'
16
+ require 'azure/blob/blob_service'
17
+ require 'azure/blob/serialization'
18
+ require 'azure/blob/container'
19
+ require 'azure/blob/blob'
20
+ require 'azure/service/signed_identifier'
21
+
22
+ describe Azure::Blob::BlobService do
23
+
24
+ subject { Azure::Blob::BlobService.new }
25
+ let(:serialization) { Azure::Blob::Serialization }
26
+ let(:uri) { URI.parse "http://foo.com" }
27
+ let(:query) { {} }
28
+ let(:request_headers) { {} }
29
+ let(:request_body) { "request-body" }
30
+
31
+ let(:response_headers) { {} }
32
+ let(:response_body) { mock() }
33
+ let(:response) { mock() }
34
+
35
+ before {
36
+ response.stubs(:body).returns(response_body)
37
+ response.stubs(:headers).returns(response_headers)
38
+ }
39
+
40
+ describe "#list_containers" do
41
+ let(:method) { :get }
42
+ let(:container_enumeration_result) { Azure::Service::EnumerationResults.new }
43
+
44
+ before {
45
+ subject.stubs(:containers_uri).with({}).returns(uri)
46
+ subject.stubs(:call).with(method, uri).returns(response)
47
+ serialization.stubs(:container_enumeration_results_from_xml).with(response_body).returns(container_enumeration_result)
48
+ }
49
+
50
+ it "assembles a URI for the request" do
51
+ subject.expects(:containers_uri).with({}).returns(uri)
52
+ subject.list_containers
53
+ end
54
+
55
+ it "calls StorageService#call with the prepared request" do
56
+ subject.expects(:call).with(method, uri).returns(response)
57
+ subject.list_containers
58
+ end
59
+
60
+ it "deserializes the response" do
61
+ serialization.expects(:container_enumeration_results_from_xml).with(response_body).returns(container_enumeration_result)
62
+ subject.list_containers
63
+ end
64
+
65
+ it "returns a list of containers for the account" do
66
+ result = subject.list_containers
67
+ result.must_be_kind_of Azure::Service::EnumerationResults
68
+ end
69
+
70
+ describe "when the options Hash is used" do
71
+ before {
72
+ subject.expects(:call).with(:get, uri).returns(response)
73
+ serialization.expects(:container_enumeration_results_from_xml).with(response_body).returns(container_enumeration_result)
74
+ }
75
+
76
+ it "modifies the URI query parameters when provided a :prefix value" do
77
+ query = { "prefix" => "pre" }
78
+ subject.expects(:containers_uri).with(query).returns(uri)
79
+
80
+ options = { :prefix => "pre" }
81
+ subject.list_containers options
82
+ end
83
+
84
+ it "modifies the URI query parameters when provided a :marker value" do
85
+ query = { "marker" => "mark" }
86
+ subject.expects(:containers_uri).with(query).returns(uri)
87
+
88
+ options = { :marker => "mark" }
89
+ subject.list_containers options
90
+ end
91
+
92
+ it "modifies the URI query parameters when provided a :max_results value" do
93
+ query = { "maxresults" => "5" }
94
+ subject.expects(:containers_uri).with(query).returns(uri)
95
+
96
+ options = { :max_results => 5 }
97
+ subject.list_containers options
98
+ end
99
+
100
+ it "modifies the URI query parameters when provided a :metadata value" do
101
+ query = { "include" => "metadata" }
102
+ subject.expects(:containers_uri).with(query).returns(uri)
103
+
104
+ options = { :metadata => true }
105
+ subject.list_containers options
106
+ end
107
+
108
+ it "modifies the URI query parameters when provided a :timeout value" do
109
+ query = { "timeout" => "37" }
110
+ subject.expects(:containers_uri).with(query).returns(uri)
111
+
112
+ options = { :timeout => 37 }
113
+ subject.list_containers options
114
+ end
115
+ it "does not modify the URI query parameters when provided an unknown value" do
116
+ subject.expects(:containers_uri).with({}).returns(uri)
117
+
118
+ options = { :unknown_key => "some_value" }
119
+ subject.list_containers options
120
+ end
121
+ end
122
+ end
123
+
124
+ describe "container functions" do
125
+ let(:container_name) { "container-name" }
126
+ let(:container) { Azure::Blob::Container.new }
127
+
128
+ describe "#create_container" do
129
+
130
+ let(:method) { :put }
131
+ before {
132
+ subject.stubs(:container_uri).with(container_name, {}).returns(uri)
133
+ subject.stubs(:call).with(method, uri, nil, {}).returns(response)
134
+ serialization.stubs(:container_from_headers).with(response_headers).returns(container)
135
+ }
136
+
137
+ it "assembles a URI for the request" do
138
+ subject.expects(:container_uri).with(container_name, {}).returns(uri)
139
+ subject.create_container container_name
140
+ end
141
+
142
+ it "calls StorageService#call with the prepared request" do
143
+ subject.expects(:call).with(method, uri, nil, {}).returns(response)
144
+ subject.create_container container_name
145
+ end
146
+
147
+ it "deserializes the response" do
148
+ serialization.expects(:container_from_headers).with(response_headers).returns(container)
149
+ subject.create_container container_name
150
+ end
151
+
152
+ it "returns a new container" do
153
+ result = subject.create_container container_name
154
+
155
+ result.must_be_kind_of Azure::Blob::Container
156
+ result.name.must_equal container_name
157
+ end
158
+
159
+ describe "when optional metadata parameter is used" do
160
+ let(:container_metadata) {
161
+ {
162
+ "MetadataKey" => "MetaDataValue",
163
+ "MetadataKey1" => "MetaDataValue1" }
164
+ }
165
+
166
+ before {
167
+ request_headers = {
168
+ "x-ms-meta-MetadataKey" => "MetaDataValue",
169
+ "x-ms-meta-MetadataKey1" => "MetaDataValue1"
170
+ }
171
+
172
+ subject.stubs(:container_uri).with(container_name, {}).returns(uri)
173
+ serialization.stubs(:container_from_headers).with(response_headers).returns(container)
174
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
175
+ }
176
+
177
+ it "adds metadata to the request headers" do
178
+ subject.create_container container_name, container_metadata
179
+ end
180
+ end
181
+
182
+ describe "when optional public_access_level parameter is used" do
183
+ let(:public_access_level) { "public-access-level-value" }
184
+
185
+ before {
186
+ request_headers = { "x-ms-blob-public-access" => public_access_level }
187
+
188
+ subject.stubs(:container_uri).with(container_name, {}).returns(uri)
189
+ serialization.stubs(:container_from_headers).with(response_headers).returns(container)
190
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
191
+ }
192
+
193
+ it "adds public_access_level to the request headers" do
194
+ subject.create_container container_name, { :public_access_level => public_access_level }
195
+ end
196
+ end
197
+ end
198
+
199
+ describe "#delete_container" do
200
+ let(:method) { :delete }
201
+ before {
202
+ response.stubs(:success?).returns(true)
203
+ subject.stubs(:container_uri).with(container_name, {}).returns(uri)
204
+ subject.stubs(:call).with(method, uri).returns(response)
205
+ }
206
+
207
+ it "assembles a URI for the request" do
208
+ subject.expects(:container_uri).with(container_name, {}).returns(uri)
209
+ subject.delete_container container_name
210
+ end
211
+
212
+ it "calls StorageService#call with the prepared request" do
213
+ subject.expects(:call).with(method, uri).returns(response)
214
+ subject.delete_container container_name
215
+ end
216
+
217
+ it "returns nil on success" do
218
+ result = subject.delete_container container_name
219
+ result.must_equal nil
220
+ end
221
+ end
222
+
223
+ describe "#get_container_properties" do
224
+ let(:method) { :get }
225
+ let(:container_properties) { {} }
226
+
227
+ before {
228
+ container.properties = container_properties
229
+ response_headers = {}
230
+ subject.stubs(:container_uri).with(container_name, {}).returns(uri)
231
+ subject.stubs(:call).with(method, uri).returns(response)
232
+ serialization.stubs(:container_from_headers).with(response_headers).returns(container)
233
+ }
234
+
235
+ it "assembles a URI for the request" do
236
+ subject.expects(:container_uri).with(container_name, {}).returns(uri)
237
+ subject.get_container_properties container_name
238
+ end
239
+
240
+ it "calls StorageService#call with the prepared request" do
241
+ subject.expects(:call).with(method, uri).returns(response)
242
+ subject.get_container_properties container_name
243
+ end
244
+
245
+ it "deserializes the response" do
246
+ serialization.expects(:container_from_headers).with(response_headers).returns(container)
247
+ subject.get_container_properties container_name
248
+ end
249
+
250
+ it "returns a container, with it's properties attribute populated" do
251
+ result = subject.get_container_properties container_name
252
+ result.must_be_kind_of Azure::Blob::Container
253
+ result.name.must_equal container_name
254
+ result.properties.must_equal container_properties
255
+ end
256
+ end
257
+
258
+ describe "#get_container_metadata" do
259
+ let(:method) { :get }
260
+ let(:container_metadata) { { "MetadataKey" => "MetaDataValue", "MetadataKey1" => "MetaDataValue1" } }
261
+ let(:response_headers) { { "x-ms-meta-MetadataKey" => "MetaDataValue", "x-ms-meta-MetadataKey1" => "MetaDataValue1" } }
262
+
263
+ before {
264
+ query.update({ "comp" => "metadata" })
265
+ response.stubs(:headers).returns(response_headers)
266
+ subject.stubs(:container_uri).with(container_name, query).returns(uri)
267
+ subject.stubs(:call).with(method, uri).returns(response)
268
+
269
+ container.metadata = container_metadata
270
+ serialization.stubs(:container_from_headers).with(response_headers).returns(container)
271
+ }
272
+
273
+ it "assembles a URI for the request" do
274
+ subject.expects(:container_uri).with(container_name, query).returns(uri)
275
+ subject.get_container_metadata container_name
276
+ end
277
+
278
+ it "calls StorageService#call with the prepared request" do
279
+ subject.expects(:call).with(method, uri).returns(response)
280
+ subject.get_container_metadata container_name
281
+ end
282
+
283
+ it "deserializes the response" do
284
+ serialization.expects(:container_from_headers).with(response_headers).returns(container)
285
+ subject.get_container_metadata container_name
286
+ end
287
+
288
+ it "returns a container, with it's metadata attribute populated" do
289
+ result = subject.get_container_metadata container_name
290
+ result.must_be_kind_of Azure::Blob::Container
291
+ result.name.must_equal container_name
292
+ result.metadata.must_equal container_metadata
293
+ end
294
+ end
295
+
296
+ describe "#get_container_acl" do
297
+ let(:method) { :get }
298
+ let(:signed_identifier){ Azure::Service::SignedIdentifier.new }
299
+ let(:signed_identifiers){ [signed_identifier] }
300
+
301
+ before {
302
+ query.update({"comp"=>"acl"})
303
+ response.stubs(:headers).returns({})
304
+ response_body.stubs(:length).returns(37)
305
+ subject.stubs(:container_uri).with(container_name, query).returns(uri)
306
+ subject.stubs(:call).with(method, uri).returns(response)
307
+
308
+ serialization.stubs(:container_from_headers).with(response_headers).returns(container)
309
+ serialization.stubs(:signed_identifiers_from_xml).with(response_body).returns(signed_identifiers)
310
+ }
311
+
312
+ it "assembles a URI for the request" do
313
+ subject.expects(:container_uri).with(container_name, query).returns(uri)
314
+ subject.get_container_acl container_name
315
+ end
316
+
317
+ it "calls StorageService#call with the prepared request" do
318
+ subject.expects(:call).with(method, uri).returns(response)
319
+ subject.get_container_acl container_name
320
+ end
321
+
322
+ it "deserializes the response" do
323
+ serialization.expects(:container_from_headers).with(response_headers).returns(container)
324
+ serialization.expects(:signed_identifiers_from_xml).with(response_body).returns(signed_identifiers)
325
+ subject.get_container_acl container_name
326
+ end
327
+
328
+ it "returns a container and an ACL" do
329
+ returned_container, returned_acl = subject.get_container_acl container_name
330
+
331
+ returned_container.must_be_kind_of Azure::Blob::Container
332
+ returned_container.name.must_equal container_name
333
+
334
+ returned_acl.must_be_kind_of Array
335
+ returned_acl[0].must_be_kind_of Azure::Service::SignedIdentifier
336
+ end
337
+ end
338
+
339
+ describe "#set_container_acl" do
340
+ let(:method) { :put }
341
+ let(:public_access_level) { "any-public-access-level" }
342
+
343
+ before {
344
+ query.update({"comp"=>"acl"})
345
+ request_headers["x-ms-blob-public-access"] = public_access_level
346
+
347
+ response.stubs(:headers).returns({})
348
+ subject.stubs(:container_uri).with(container_name, query).returns(uri)
349
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
350
+ serialization.stubs(:container_from_headers).with(response_headers).returns(container)
351
+ }
352
+
353
+ it "assembles a URI for the request" do
354
+ subject.expects(:container_uri).with(container_name, query).returns(uri)
355
+ subject.set_container_acl container_name, public_access_level
356
+ end
357
+
358
+ it "calls StorageService#call with the prepared request" do
359
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
360
+ subject.set_container_acl container_name, public_access_level
361
+ end
362
+
363
+
364
+ it "deserializes the response" do
365
+ serialization.expects(:container_from_headers).with(response_headers).returns(container)
366
+ subject.set_container_acl container_name, public_access_level
367
+ end
368
+
369
+ it "returns a container and an ACL" do
370
+ returned_container, returned_acl = subject.set_container_acl container_name, public_access_level
371
+
372
+ returned_container.must_be_kind_of Azure::Blob::Container
373
+ returned_container.name.must_equal container_name
374
+ returned_container.public_access_level.must_equal public_access_level
375
+
376
+ returned_acl.must_be_kind_of Array
377
+ end
378
+
379
+ describe "when the public_access_level parameter is set to 'container'" do
380
+ let(:public_access_level) { "container"}
381
+ before {
382
+ request_headers["x-ms-blob-public-access"] = public_access_level
383
+ }
384
+
385
+ it "sets the x-ms-blob-public-access header" do
386
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
387
+ subject.set_container_acl container_name, public_access_level
388
+ end
389
+
390
+ describe "when a signed_identifiers value is provided" do
391
+ let(:signed_identifier){ Azure::Service::SignedIdentifier.new }
392
+ let(:signed_identifiers){ [signed_identifier] }
393
+ before {
394
+ subject.stubs(:call).with(method, uri, request_body, request_headers).returns(response)
395
+ serialization.stubs(:signed_identifiers_to_xml).with(signed_identifiers).returns(request_body)
396
+ }
397
+
398
+ it "serializes the request contents" do
399
+ serialization.expects(:signed_identifiers_to_xml).with(signed_identifiers).returns(request_body)
400
+ subject.set_container_acl container_name, public_access_level, { :signed_identifiers => signed_identifiers }
401
+ end
402
+
403
+ it "returns a container and an ACL" do
404
+ returned_container, returned_acl = subject.set_container_acl container_name, public_access_level, { :signed_identifiers => signed_identifiers }
405
+
406
+ returned_container.must_be_kind_of Azure::Blob::Container
407
+ returned_container.name.must_equal container_name
408
+ returned_container.public_access_level.must_equal public_access_level
409
+
410
+ returned_acl.must_be_kind_of Array
411
+ returned_acl[0].must_be_kind_of Azure::Service::SignedIdentifier
412
+ end
413
+ end
414
+ end
415
+
416
+ describe "when the public_access_level parameter is set to nil" do
417
+ let(:public_access_level) { nil }
418
+ before {
419
+ request_headers.delete "x-ms-blob-public-access"
420
+ }
421
+
422
+ it "sets the x-ms-blob-public-access header" do
423
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
424
+ subject.set_container_acl container_name, public_access_level
425
+ end
426
+ end
427
+
428
+ describe "when the public_access_level parameter is set to empty string" do
429
+ let(:public_access_level) { "" }
430
+ before {
431
+ request_headers.delete "x-ms-blob-public-access"
432
+ }
433
+
434
+ it "sets the x-ms-blob-public-access header" do
435
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
436
+ subject.set_container_acl container_name, public_access_level
437
+ end
438
+ end
439
+ end
440
+
441
+ describe "#set_container_metadata" do
442
+ let(:method) { :put }
443
+ let(:container_metadata) { { "MetadataKey" => "MetaDataValue", "MetadataKey1" => "MetaDataValue1" } }
444
+ let(:request_headers) { { "x-ms-meta-MetadataKey" => "MetaDataValue", "x-ms-meta-MetadataKey1" => "MetaDataValue1" } }
445
+
446
+ before {
447
+ query.update({ "comp" => "metadata" })
448
+ response.stubs(:success?).returns(true)
449
+ subject.stubs(:container_uri).with(container_name, query).returns(uri)
450
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
451
+ }
452
+
453
+ it "assembles a URI for the request" do
454
+ subject.expects(:container_uri).with(container_name, query).returns(uri)
455
+ subject.set_container_metadata container_name, container_metadata
456
+ end
457
+
458
+ it "calls StorageService#call with the prepared request" do
459
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
460
+ subject.set_container_metadata container_name, container_metadata
461
+ end
462
+
463
+ it "returns nil on success" do
464
+ result = subject.set_container_metadata container_name, container_metadata
465
+ result.must_equal nil
466
+ end
467
+ end
468
+
469
+ describe "#list_blobs" do
470
+ let(:method) { :get }
471
+ let(:query) {{"comp"=>"list"}}
472
+ let(:blob_enumeration_results) { Azure::Service::EnumerationResults.new}
473
+
474
+ before {
475
+ subject.stubs(:container_uri).with(container_name, query).returns(uri)
476
+ subject.stubs(:call).with(method, uri).returns(response)
477
+ serialization.stubs(:blob_enumeration_results_from_xml).with(response_body).returns(blob_enumeration_results)
478
+ }
479
+
480
+ it "assembles a URI for the request" do
481
+ subject.expects(:container_uri).with(container_name, query).returns(uri)
482
+ subject.list_blobs container_name
483
+ end
484
+
485
+ it "calls StorageService#call with the prepared request" do
486
+ subject.expects(:call).with(method, uri).returns(response)
487
+ subject.list_blobs container_name
488
+ end
489
+
490
+ it "deserializes the response" do
491
+ serialization.expects(:blob_enumeration_results_from_xml).with(response_body).returns(blob_enumeration_results)
492
+ subject.list_blobs container_name
493
+ end
494
+
495
+ it "returns a list of containers for the account" do
496
+ result = subject.list_blobs container_name
497
+ result.must_be_kind_of Azure::Service::EnumerationResults
498
+ end
499
+
500
+ describe "when the options Hash is used" do
501
+ before {
502
+ subject.expects(:call).with(:get, uri).returns(response)
503
+ serialization.expects(:blob_enumeration_results_from_xml).with(response_body).returns(blob_enumeration_results)
504
+ subject.expects(:container_uri).with(container_name, query).returns(uri)
505
+ }
506
+
507
+ it "modifies the URI query parameters when provided a :prefix value" do
508
+ query["prefix"]= "pre"
509
+ options = { :prefix => "pre" }
510
+ subject.list_blobs container_name, options
511
+ end
512
+
513
+ it "modifies the URI query parameters when provided a :prefix value" do
514
+ query["delimiter"] = "delim"
515
+ options = { :delimiter => "delim" }
516
+ subject.list_blobs container_name, options
517
+ end
518
+
519
+ it "modifies the URI query parameters when provided a :marker value" do
520
+ query["marker"] = "mark"
521
+ options = { :marker => "mark" }
522
+ subject.list_blobs container_name, options
523
+ end
524
+
525
+ it "modifies the URI query parameters when provided a :max_results value" do
526
+ query["maxresults"] = "5"
527
+ options = { :max_results => 5 }
528
+ subject.list_blobs container_name, options
529
+ end
530
+
531
+ it "modifies the URI query parameters when provided a :metadata value" do
532
+ query["include"] = "metadata"
533
+ options = { :metadata => true }
534
+ subject.list_blobs container_name, options
535
+ end
536
+
537
+ it "modifies the URI query parameters when provided a :snapshots value" do
538
+ query["include"] = "snapshots"
539
+ options = { :snapshots => true }
540
+ subject.list_blobs container_name, options
541
+ end
542
+
543
+ it "modifies the URI query parameters when provided a :uncommittedblobs value" do
544
+ query["include"] = "uncommittedblobs"
545
+ options = { :uncommittedblobs => true }
546
+ subject.list_blobs container_name, options
547
+ end
548
+
549
+ it "modifies the URI query parameters when provided a :copy value" do
550
+ query["include"] = "copy"
551
+ options = { :copy => true }
552
+ subject.list_blobs container_name, options
553
+ end
554
+
555
+ it "modifies the URI query parameters when provided more than one of :metadata, :snapshots, :uncommittedblobs or :copy values" do
556
+ query["include"] = "metadata,snapshots,uncommittedblobs,copy"
557
+
558
+ options = {
559
+ :copy => true,
560
+ :metadata => true,
561
+ :snapshots => true,
562
+ :uncommittedblobs => true
563
+ }
564
+
565
+ subject.list_blobs container_name, options
566
+ end
567
+
568
+ it "modifies the URI query parameters when provided a :timeout value" do
569
+ query["timeout"] = "37"
570
+ options = { :timeout => 37 }
571
+ subject.list_blobs container_name, options
572
+ end
573
+
574
+ it "does not modify the URI query parameters when provided an unknown value" do
575
+ options = { :unknown_key => "some_value" }
576
+ subject.list_blobs container_name, options
577
+ end
578
+ end
579
+ end
580
+
581
+ describe "blob functions" do
582
+ let(:blob_name){ "blob-name" }
583
+ let(:blob) { Azure::Blob::Blob.new }
584
+
585
+ describe "#create_page_blob" do
586
+ let(:method) { :put }
587
+ let(:blob_length) { 37 }
588
+ let(:request_headers) {
589
+ {
590
+ "x-ms-blob-type" => "PageBlob",
591
+ "Content-Length" => 0.to_s,
592
+ "x-ms-blob-content-length" => blob_length.to_s,
593
+ "x-ms-sequence-number" => 0.to_s
594
+ }
595
+ }
596
+
597
+ before {
598
+ subject.stubs(:blob_uri).with(container_name, blob_name, {}).returns(uri)
599
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
600
+ serialization.stubs(:blob_from_headers).with(response_headers).returns(blob)
601
+ }
602
+
603
+ it "assembles a URI for the request" do
604
+ subject.expects(:blob_uri).with(container_name, blob_name, {}).returns(uri)
605
+ subject.create_page_blob container_name, blob_name, blob_length
606
+ end
607
+
608
+ it "calls StorageService#call with the prepared request" do
609
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
610
+ subject.create_page_blob container_name, blob_name, blob_length
611
+ end
612
+
613
+ it "returns a Blob on success" do
614
+ result = subject.create_page_blob container_name, blob_name, blob_length
615
+ result.must_be_kind_of Azure::Blob::Blob
616
+ result.must_equal blob
617
+ result.name.must_equal blob_name
618
+ end
619
+
620
+ describe "when the options Hash is used" do
621
+ it "modifies the request headers when provided a :sequence_number value" do
622
+ request_headers["x-ms-sequence-number"] = 37.to_s
623
+ subject.create_page_blob container_name, blob_name, blob_length, { :sequence_number => 37.to_s }
624
+ end
625
+
626
+ it "modifies the request headers when provided a :blob_content_type value" do
627
+ request_headers["x-ms-blob-content-type"] = "bct-value"
628
+ subject.create_page_blob container_name, blob_name, blob_length, { :blob_content_type => "bct-value" }
629
+ end
630
+
631
+ it "modifies the request headers when provided a :blob_content_encoding value" do
632
+ request_headers["x-ms-blob-content-encoding"] = "bce-value"
633
+ subject.create_page_blob container_name, blob_name, blob_length, { :blob_content_encoding => "bce-value" }
634
+ end
635
+
636
+ it "modifies the request headers when provided a :blob_content_language value" do
637
+ request_headers["x-ms-blob-content-language"] = "bcl-value"
638
+ subject.create_page_blob container_name, blob_name, blob_length, { :blob_content_language => "bcl-value" }
639
+ end
640
+
641
+ it "modifies the request headers when provided a :blob_content_md5 value" do
642
+ request_headers["x-ms-blob-content-md5"] = "bcm-value"
643
+ subject.create_page_blob container_name, blob_name, blob_length, { :blob_content_md5 => "bcm-value" }
644
+ end
645
+
646
+ it "modifies the request headers when provided a :blob_cache_control value" do
647
+ request_headers["x-ms-blob-cache-control"] = "bcc-value"
648
+ subject.create_page_blob container_name, blob_name, blob_length, { :blob_cache_control => "bcc-value" }
649
+ end
650
+
651
+ it "modifies the request headers when provided a :content_type value" do
652
+ request_headers["Content-Type"] = "ct-value"
653
+ subject.create_page_blob container_name, blob_name, blob_length, { :content_type => "ct-value" }
654
+ end
655
+
656
+ it "modifies the request headers when provided a :content_encoding value" do
657
+ request_headers["Content-Encoding"] = "ce-value"
658
+ subject.create_page_blob container_name, blob_name, blob_length, { :content_encoding => "ce-value" }
659
+ end
660
+
661
+ it "modifies the request headers when provided a :content_language value" do
662
+ request_headers["Content-Language"] = "cl-value"
663
+ subject.create_page_blob container_name, blob_name, blob_length, { :content_language => "cl-value" }
664
+ end
665
+
666
+ it "modifies the request headers when provided a :content_md5 value" do
667
+ request_headers["Content-MD5"] = "cm-value"
668
+ subject.create_page_blob container_name, blob_name, blob_length, { :content_md5 => "cm-value" }
669
+ end
670
+
671
+ it "modifies the request headers when provided a :cache_control value" do
672
+ request_headers["Cache-Control"] = "cc-value"
673
+ subject.create_page_blob container_name, blob_name, blob_length, { :cache_control => "cc-value" }
674
+ end
675
+
676
+ it "modifies the request headers when provided a :metadata value" do
677
+ request_headers["x-ms-meta-MetadataKey"] = "MetaDataValue"
678
+ request_headers["x-ms-meta-MetadataKey1"] = "MetaDataValue1"
679
+ options = { :metadata => { "MetadataKey" => "MetaDataValue", "MetadataKey1" => "MetaDataValue1"} }
680
+ subject.create_page_blob container_name, blob_name, blob_length, options
681
+ end
682
+
683
+ it "does not modify the request headers when provided an unknown value" do
684
+ subject.create_page_blob container_name, blob_name, blob_length, { :unknown_key => "some_value" }
685
+ end
686
+ end
687
+ end
688
+
689
+ describe "#create_blob_pages" do
690
+ let(:method) { :put }
691
+ let(:start_range) { 255 }
692
+ let(:end_range) { 512 }
693
+ let(:content) { "some content" }
694
+ let(:query) { {"comp" => "page"} }
695
+ let(:request_headers) {
696
+ {
697
+ "x-ms-page-write" => "update",
698
+ "x-ms-range" => "bytes=#{start_range}-#{end_range}",
699
+ "Content-Type" => ""
700
+ }
701
+ }
702
+
703
+ before {
704
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
705
+ subject.stubs(:call).with(method, uri, content, request_headers).returns(response)
706
+ serialization.stubs(:blob_from_headers).with(response_headers).returns(blob)
707
+ }
708
+
709
+ it "assembles a URI for the request" do
710
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
711
+ subject.create_blob_pages container_name, blob_name, start_range, end_range, content
712
+ end
713
+
714
+ it "calls StorageService#call with the prepared request" do
715
+ subject.expects(:call).with(method, uri, content, request_headers).returns(response)
716
+ subject.create_blob_pages container_name, blob_name, start_range, end_range, content
717
+ end
718
+
719
+ it "returns a Blob on success" do
720
+ result = subject.create_blob_pages container_name, blob_name, start_range, end_range, content
721
+ result.must_be_kind_of Azure::Blob::Blob
722
+ result.must_equal blob
723
+ result.name.must_equal blob_name
724
+ end
725
+
726
+ describe "when the options Hash is used" do
727
+ it "modifies the request headers when provided a :if_sequence_number_eq value" do
728
+ request_headers["x-ms-if-sequence-number-eq"] = "isne-value"
729
+ subject.create_blob_pages container_name, blob_name, start_range, end_range, content, { :if_sequence_number_eq => "isne-value" }
730
+ end
731
+
732
+ it "modifies the request headers when provided a :if_sequence_number_lt value" do
733
+ request_headers["x-ms-if-sequence-number-lt"] = "isnlt-value"
734
+ subject.create_blob_pages container_name, blob_name, start_range, end_range, content, { :if_sequence_number_lt => "isnlt-value" }
735
+ end
736
+
737
+ it "modifies the request headers when provided a :if_sequence_number_le value" do
738
+ request_headers["x-ms-if-sequence-number-le"] = "isnle-value"
739
+ subject.create_blob_pages container_name, blob_name, start_range, end_range, content, { :if_sequence_number_le => "isnle-value" }
740
+ end
741
+
742
+ it "modifies the request headers when provided a :if_modified_since value" do
743
+ request_headers["If-Modified-Since"] = "ims-value"
744
+ subject.create_blob_pages container_name, blob_name, start_range, end_range, content, { :if_modified_since => "ims-value" }
745
+ end
746
+
747
+ it "modifies the request headers when provided a :if_unmodified_since value" do
748
+ request_headers["If-Unmodified-Since"] = "iums-value"
749
+ subject.create_blob_pages container_name, blob_name, start_range, end_range, content, { :if_unmodified_since => "iums-value" }
750
+ end
751
+
752
+ it "modifies the request headers when provided a :if_match value" do
753
+ request_headers["If-Match"] = "im-value"
754
+ subject.create_blob_pages container_name, blob_name, start_range, end_range, content, { :if_match => "im-value" }
755
+ end
756
+
757
+ it "modifies the request headers when provided a :if_none_match value" do
758
+ request_headers["If-None-Match"] = "inm-value"
759
+ subject.create_blob_pages container_name, blob_name, start_range, end_range, content, { :if_none_match => "inm-value" }
760
+ end
761
+
762
+
763
+ it "does not modify the request headers when provided an unknown value" do
764
+ subject.create_blob_pages container_name, blob_name, start_range, end_range, content, { :unknown_key => "some_value" }
765
+ end
766
+ end
767
+ end
768
+
769
+ describe "#clear_blob_pages" do
770
+ let(:method) { :put }
771
+ let(:query) { {"comp" => "page"} }
772
+ let(:start_range){ 255 }
773
+ let(:end_range){ 512 }
774
+ let(:request_headers) {
775
+ {
776
+ "x-ms-range" => "bytes=#{start_range}-#{end_range}",
777
+ "x-ms-page-write" => "clear",
778
+ "Content-Type" => ""
779
+ }
780
+ }
781
+
782
+ before {
783
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
784
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
785
+ serialization.stubs(:blob_from_headers).with(response_headers).returns(blob)
786
+ }
787
+
788
+ it "assembles a URI for the request" do
789
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
790
+ subject.clear_blob_pages container_name, blob_name, start_range, end_range
791
+ end
792
+
793
+ it "calls StorageService#call with the prepared request" do
794
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
795
+ subject.clear_blob_pages container_name, blob_name, start_range, end_range
796
+ end
797
+
798
+ it "returns a Blob on success" do
799
+ result = subject.clear_blob_pages container_name, blob_name, start_range, end_range
800
+ result.must_be_kind_of Azure::Blob::Blob
801
+ result.must_equal blob
802
+ result.name.must_equal blob_name
803
+ end
804
+
805
+ # describe "when start_range is provided" do
806
+ # let(:start_range){ 255 }
807
+ # before { request_headers["x-ms-range"]="#{start_range}-" }
808
+
809
+ # it "modifies the request headers with the desired range" do
810
+ # subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
811
+ # subject.clear_blob_pages container_name, blob_name, start_range
812
+ # end
813
+ # end
814
+
815
+ # describe "when end_range is provided" do
816
+ # let(:end_range){ 512 }
817
+ # before { request_headers["x-ms-range"]="0-#{end_range}" }
818
+
819
+ # it "modifies the request headers with the desired range" do
820
+ # subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
821
+ # subject.clear_blob_pages container_name, blob_name, nil, end_range
822
+ # end
823
+ # end
824
+
825
+ # describe "when both start_range and end_range are provided" do
826
+ # before { request_headers["x-ms-range"]="bytes=#{start_range}-#{end_range}" }
827
+
828
+ # it "modifies the request headers with the desired range" do
829
+ # subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
830
+ # subject.clear_blob_pages container_name, blob_name, start_range, end_range
831
+ # end
832
+ # end
833
+ end
834
+
835
+ describe "#create_blob_block" do
836
+ require 'base64'
837
+
838
+ let(:method) { :put }
839
+ let(:content) { "some content"}
840
+ let(:block_id) { "block-id"}
841
+ let(:server_generated_content_md5) { "server-content-md5" }
842
+ let(:request_headers) { {} }
843
+
844
+ before {
845
+ query.update({ "comp" => "block", "blockid" => Base64.strict_encode64(block_id) })
846
+ response_headers["Content-MD5"] = server_generated_content_md5
847
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
848
+ subject.stubs(:call).with(method, uri, content, request_headers).returns(response)
849
+ }
850
+
851
+ it "assembles a URI for the request" do
852
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
853
+ subject.create_blob_block container_name, blob_name, block_id, content
854
+ end
855
+
856
+ it "calls StorageService#call with the prepared request" do
857
+ subject.expects(:call).with(method, uri, content, request_headers).returns(response)
858
+ subject.create_blob_block container_name, blob_name, block_id, content
859
+ end
860
+
861
+ it "returns content MD5 on success" do
862
+ result = subject.create_blob_block container_name, blob_name, block_id, content
863
+ result.must_equal server_generated_content_md5
864
+ end
865
+
866
+ describe "when the options Hash is used" do
867
+ it "modifies the request headers when provided a :content_md5 value" do
868
+ request_headers["Content-MD5"] = "content-md5"
869
+ subject.create_blob_block container_name, blob_name, block_id, content, { :content_md5 => "content-md5" }
870
+ end
871
+
872
+ it "does not modify the request headers when provided an unknown value" do
873
+ subject.create_blob_block container_name, blob_name, block_id, content, { :unknown_key => "some_value" }
874
+ end
875
+ end
876
+ end
877
+
878
+ describe "#create_block_blob" do
879
+ let(:method) { :put }
880
+ let(:content) { "some content" }
881
+ let(:request_headers) {
882
+ {
883
+ "x-ms-blob-type" => "BlockBlob",
884
+ "Content-Type" => "application/octet-stream"
885
+ }
886
+ }
887
+
888
+ before {
889
+ subject.stubs(:blob_uri).with(container_name, blob_name, {}).returns(uri)
890
+ subject.stubs(:call).with(method, uri, content, request_headers).returns(response)
891
+ serialization.stubs(:blob_from_headers).with(response_headers).returns(blob)
892
+ }
893
+
894
+ it "assembles a URI for the request" do
895
+ subject.expects(:blob_uri).with(container_name, blob_name, {}).returns(uri)
896
+ subject.create_block_blob container_name, blob_name, content
897
+ end
898
+
899
+ it "calls StorageService#call with the prepared request" do
900
+ subject.expects(:call).with(method, uri, content, request_headers).returns(response)
901
+ subject.create_block_blob container_name, blob_name, content
902
+ end
903
+
904
+ it "returns a Blob on success" do
905
+ result = subject.create_block_blob container_name, blob_name, content
906
+ result.must_be_kind_of Azure::Blob::Blob
907
+ result.must_equal blob
908
+ result.name.must_equal blob_name
909
+ end
910
+
911
+ describe "when the options Hash is used" do
912
+ it "modifies the request headers when provided a :blob_content_type value" do
913
+ request_headers["x-ms-blob-content-type"] = "bct-value"
914
+ subject.create_block_blob container_name, blob_name, content, { :blob_content_type => "bct-value" }
915
+ end
916
+
917
+ it "modifies the request headers when provided a :blob_content_encoding value" do
918
+ request_headers["x-ms-blob-content-encoding"] = "bce-value"
919
+ subject.create_block_blob container_name, blob_name, content, { :blob_content_encoding => "bce-value" }
920
+ end
921
+
922
+ it "modifies the request headers when provided a :blob_content_language value" do
923
+ request_headers["x-ms-blob-content-language"] = "bcl-value"
924
+ subject.create_block_blob container_name, blob_name, content, { :blob_content_language => "bcl-value" }
925
+ end
926
+
927
+ it "modifies the request headers when provided a :blob_content_md5 value" do
928
+ request_headers["x-ms-blob-content-md5"] = "bcm-value"
929
+ subject.create_block_blob container_name, blob_name, content, { :blob_content_md5 => "bcm-value" }
930
+ end
931
+
932
+ it "modifies the request headers when provided a :blob_cache_control value" do
933
+ request_headers["x-ms-blob-cache-control"] = "bcc-value"
934
+ subject.create_block_blob container_name, blob_name, content, { :blob_cache_control => "bcc-value" }
935
+ end
936
+
937
+ it "modifies the request headers when provided a :content_type value" do
938
+ request_headers["Content-Type"] = "ct-value"
939
+ subject.create_block_blob container_name, blob_name, content, { :content_type => "ct-value" }
940
+ end
941
+
942
+ it "modifies the request headers when provided a :content_encoding value" do
943
+ request_headers["Content-Encoding"] = "ce-value"
944
+ subject.create_block_blob container_name, blob_name, content, { :content_encoding => "ce-value" }
945
+ end
946
+
947
+ it "modifies the request headers when provided a :content_language value" do
948
+ request_headers["Content-Language"] = "cl-value"
949
+ subject.create_block_blob container_name, blob_name, content, { :content_language => "cl-value" }
950
+ end
951
+
952
+ it "modifies the request headers when provided a :content_md5 value" do
953
+ request_headers["Content-MD5"] = "cm-value"
954
+ subject.create_block_blob container_name, blob_name, content, { :content_md5 => "cm-value" }
955
+ end
956
+
957
+ it "modifies the request headers when provided a :cache_control value" do
958
+ request_headers["Cache-Control"] = "cc-value"
959
+ subject.create_block_blob container_name, blob_name, content, { :cache_control => "cc-value" }
960
+ end
961
+
962
+ it "modifies the request headers when provided a :metadata value" do
963
+ request_headers["x-ms-meta-MetadataKey"] = "MetaDataValue"
964
+ request_headers["x-ms-meta-MetadataKey1"] = "MetaDataValue1"
965
+ options = { :metadata => { "MetadataKey" => "MetaDataValue", "MetadataKey1" => "MetaDataValue1"} }
966
+ subject.create_block_blob container_name, blob_name, content, options
967
+ end
968
+
969
+ it "does not modify the request headers when provided an unknown value" do
970
+ subject.create_block_blob container_name, blob_name, content, { :unknown_key => "some_value" }
971
+ end
972
+ end
973
+ end
974
+
975
+ describe "#commit_blob_blocks" do
976
+ let(:method) { :put }
977
+ let(:request_body) { "body" }
978
+ let(:block_list) { mock() }
979
+ let(:request_headers) { {} }
980
+
981
+ before {
982
+ query.update({ "comp" => "blocklist" })
983
+ response.stubs(:success?).returns(true)
984
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
985
+ serialization.stubs(:block_list_to_xml).with(block_list).returns(request_body)
986
+ subject.stubs(:call).with(method, uri, request_body, request_headers).returns(response)
987
+ }
988
+
989
+ it "assembles a URI for the request" do
990
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
991
+ subject.commit_blob_blocks container_name, blob_name, block_list
992
+ end
993
+
994
+ it "calls StorageService#call with the prepared request" do
995
+ subject.expects(:call).with(method, uri, request_body, request_headers).returns(response)
996
+ subject.commit_blob_blocks container_name, blob_name, block_list
997
+ end
998
+
999
+ it "serializes the block list" do
1000
+ serialization.expects(:block_list_to_xml).with(block_list).returns(request_body)
1001
+ subject.commit_blob_blocks container_name, blob_name, block_list
1002
+ end
1003
+
1004
+ it "returns nil on success" do
1005
+ result = subject.commit_blob_blocks container_name, blob_name, block_list
1006
+ result.must_equal nil
1007
+ end
1008
+
1009
+ describe "when the options Hash is used" do
1010
+ it "modifies the request headers when provided a :content_md5 value" do
1011
+ request_headers["Content-MD5"] = "cm-value"
1012
+ subject.commit_blob_blocks container_name, blob_name, block_list, { :content_md5 => "cm-value" }
1013
+ end
1014
+
1015
+ it "modifies the request headers when provided a :blob_content_type value" do
1016
+ request_headers["x-ms-blob-content-type"] = "bct-value"
1017
+ subject.commit_blob_blocks container_name, blob_name, block_list, { :blob_content_type => "bct-value" }
1018
+ end
1019
+
1020
+ it "modifies the request headers when provided a :blob_content_encoding value" do
1021
+ request_headers["x-ms-blob-content-encoding"] = "bce-value"
1022
+ subject.commit_blob_blocks container_name, blob_name, block_list, { :blob_content_encoding => "bce-value" }
1023
+ end
1024
+
1025
+ it "modifies the request headers when provided a :blob_content_language value" do
1026
+ request_headers["x-ms-blob-content-language"] = "bcl-value"
1027
+ subject.commit_blob_blocks container_name, blob_name, block_list, { :blob_content_language => "bcl-value" }
1028
+ end
1029
+
1030
+ it "modifies the request headers when provided a :blob_content_md5 value" do
1031
+ request_headers["x-ms-blob-content-md5"] = "bcm-value"
1032
+ subject.commit_blob_blocks container_name, blob_name, block_list, { :blob_content_md5 => "bcm-value" }
1033
+ end
1034
+
1035
+ it "modifies the request headers when provided a :blob_cache_control value" do
1036
+ request_headers["x-ms-blob-cache-control"] = "bcc-value"
1037
+ subject.commit_blob_blocks container_name, blob_name, block_list, { :blob_cache_control => "bcc-value" }
1038
+ end
1039
+
1040
+ it "modifies the request headers when provided a :metadata value" do
1041
+ request_headers["x-ms-meta-MetadataKey"] = "MetaDataValue"
1042
+ request_headers["x-ms-meta-MetadataKey1"] = "MetaDataValue1"
1043
+ options = { :metadata => { "MetadataKey" => "MetaDataValue", "MetadataKey1" => "MetaDataValue1"} }
1044
+ subject.commit_blob_blocks container_name, blob_name, block_list, options
1045
+ end
1046
+
1047
+ it "does not modify the request headers when provided an unknown value" do
1048
+ subject.commit_blob_blocks container_name, blob_name, block_list, { :unknown_key => "some_value" }
1049
+ end
1050
+ end
1051
+ end
1052
+
1053
+ describe "#list_blob_blocks" do
1054
+ let(:method) { :get }
1055
+ let(:query) {{"comp"=>"blocklist", "blocklisttype"=>"all"}}
1056
+ let(:blob_block_list) { [Azure::Blob::Block.new] }
1057
+
1058
+ before {
1059
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
1060
+ subject.stubs(:call).with(method, uri).returns(response)
1061
+ serialization.stubs(:block_list_from_xml).with(response_body).returns(blob_block_list)
1062
+ }
1063
+
1064
+ it "assembles a URI for the request" do
1065
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1066
+ subject.list_blob_blocks container_name, blob_name
1067
+ end
1068
+
1069
+ it "calls StorageService#call with the prepared request" do
1070
+ subject.expects(:call).with(method, uri).returns(response)
1071
+ subject.list_blob_blocks container_name, blob_name
1072
+ end
1073
+
1074
+ it "deserializes the response" do
1075
+ serialization.expects(:block_list_from_xml).with(response_body).returns(blob_block_list)
1076
+ subject.list_blob_blocks container_name, blob_name
1077
+ end
1078
+
1079
+ it "returns a list of containers for the account" do
1080
+ result = subject.list_blob_blocks container_name, blob_name
1081
+ result.must_be_kind_of Array
1082
+ result.first.must_be_kind_of Azure::Blob::Block
1083
+ end
1084
+
1085
+ describe "when blocklist_type is provided" do
1086
+ it "modifies the request query when the value is :all" do
1087
+ query["blocklisttype"] = "all"
1088
+ subject.list_blob_blocks container_name, blob_name, { :blocklist_type => :all }
1089
+ end
1090
+
1091
+ it "modifies the request query when the value is :uncommitted" do
1092
+ query["blocklisttype"] = "uncommitted"
1093
+ subject.list_blob_blocks container_name, blob_name, { :blocklist_type => :uncommitted }
1094
+ end
1095
+
1096
+ it "modifies the request query when the value is :committed" do
1097
+ query["blocklisttype"] = "committed"
1098
+ subject.list_blob_blocks container_name, blob_name, { :blocklist_type => :committed }
1099
+ end
1100
+ end
1101
+
1102
+ describe "when snapshot is provided" do
1103
+ it "modifies the request query with the provided value" do
1104
+ query["snapshot"] = "snapshot-id"
1105
+ subject.list_blob_blocks container_name, blob_name, { :snapshot => "snapshot-id" }
1106
+ end
1107
+ end
1108
+ end
1109
+
1110
+ describe "#list_page_blob_ranges" do
1111
+ let(:method) { :get }
1112
+ let(:query) { {"comp"=>"pagelist"} }
1113
+ let(:page_list) { [[0, 511], [512, 1023]] }
1114
+
1115
+ before {
1116
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
1117
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
1118
+ serialization.stubs(:page_list_from_xml).with(response_body).returns(page_list)
1119
+ }
1120
+
1121
+ it "assembles a URI for the request" do
1122
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1123
+ subject.list_page_blob_ranges container_name, blob_name
1124
+ end
1125
+
1126
+ it "calls StorageService#call with the prepared request" do
1127
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1128
+ subject.list_page_blob_ranges container_name, blob_name
1129
+ end
1130
+
1131
+ it "deserializes the response" do
1132
+ serialization.expects(:page_list_from_xml).with(response_body).returns(page_list)
1133
+ subject.list_page_blob_ranges container_name, blob_name
1134
+ end
1135
+
1136
+ it "returns a list of containers for the account" do
1137
+ result = subject.list_page_blob_ranges container_name, blob_name
1138
+ result.must_be_kind_of Array
1139
+ result.first.must_be_kind_of Array
1140
+ result.first.first.must_be_kind_of Integer
1141
+ result.first.first.next.must_be_kind_of Integer
1142
+ end
1143
+
1144
+ # describe "when start_range is provided" do
1145
+ # let(:start_range){ 255 }
1146
+ # before { request_headers["x-ms-range"]="#{start_range}-" }
1147
+
1148
+ # it "modifies the request headers with the desired range" do
1149
+ # subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1150
+ # subject.list_page_blob_ranges container_name, blob_name, start_range
1151
+ # end
1152
+ # end
1153
+
1154
+ # describe "when end_range is provided" do
1155
+ # let(:end_range){ 512 }
1156
+ # before { request_headers["x-ms-range"]="0-#{end_range}" }
1157
+
1158
+ # it "modifies the request headers with the desired range" do
1159
+ # subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1160
+ # subject.list_page_blob_ranges container_name, blob_name, nil, end_range
1161
+ # end
1162
+ # end
1163
+
1164
+ describe "when both start_range and end_range are provided" do
1165
+ let(:start_range){ 255 }
1166
+ let(:end_range){ 512 }
1167
+ before { request_headers["x-ms-range"]="bytes=#{start_range}-#{end_range}" }
1168
+
1169
+ it "modifies the request headers with the desired range" do
1170
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1171
+ subject.list_page_blob_ranges container_name, blob_name, { :start_range => start_range, :end_range => end_range }
1172
+ end
1173
+ end
1174
+
1175
+ describe "when snapshot is provided" do
1176
+ it "modifies the request query with the provided value" do
1177
+ query["snapshot"] = "snapshot-id"
1178
+ subject.list_page_blob_ranges container_name, blob_name, { :snapshot => "snapshot-id" }
1179
+ end
1180
+ end
1181
+ end
1182
+
1183
+ describe "#set_blob_properties" do
1184
+ let(:method) { :put }
1185
+ let(:request_headers) { {} }
1186
+
1187
+ before {
1188
+ query.update({ "comp" => "properties" })
1189
+ response.stubs(:success?).returns(true)
1190
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
1191
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
1192
+ }
1193
+
1194
+ it "assembles a URI for the request" do
1195
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1196
+ subject.set_blob_properties container_name, blob_name
1197
+ end
1198
+
1199
+ it "calls StorageService#call with the prepared request" do
1200
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1201
+ subject.set_blob_properties container_name, blob_name
1202
+ end
1203
+
1204
+ it "returns nil on success" do
1205
+ result = subject.set_blob_properties container_name, blob_name
1206
+ result.must_equal nil
1207
+ end
1208
+
1209
+ describe "when the options Hash is used" do
1210
+ it "modifies the request headers when provided a :blob_content_type value" do
1211
+ request_headers["x-ms-blob-content-type"] = "bct-value"
1212
+ subject.set_blob_properties container_name, blob_name, { :blob_content_type => "bct-value" }
1213
+ end
1214
+
1215
+ it "modifies the request headers when provided a :blob_content_encoding value" do
1216
+ request_headers["x-ms-blob-content-encoding"] = "bce-value"
1217
+ subject.set_blob_properties container_name, blob_name, { :blob_content_encoding => "bce-value" }
1218
+ end
1219
+
1220
+ it "modifies the request headers when provided a :blob_content_language value" do
1221
+ request_headers["x-ms-blob-content-language"] = "bcl-value"
1222
+ subject.set_blob_properties container_name, blob_name, { :blob_content_language => "bcl-value" }
1223
+ end
1224
+
1225
+ it "modifies the request headers when provided a :blob_content_md5 value" do
1226
+ request_headers["x-ms-blob-content-md5"] = "bcm-value"
1227
+ subject.set_blob_properties container_name, blob_name, { :blob_content_md5 => "bcm-value" }
1228
+ end
1229
+
1230
+ it "modifies the request headers when provided a :blob_cache_control value" do
1231
+ request_headers["x-ms-blob-cache-control"] = "bcc-value"
1232
+ subject.set_blob_properties container_name, blob_name, { :blob_cache_control => "bcc-value" }
1233
+ end
1234
+
1235
+ it "modifies the request headers when provided a :blob_content_length value" do
1236
+ request_headers["x-ms-blob-content-length"] = "37"
1237
+ subject.set_blob_properties container_name, blob_name, { :blob_content_length => 37.to_s }
1238
+ end
1239
+
1240
+ it "modifies the request headers when provided a :sequence_number_action value" do
1241
+ request_headers["x-ms-blob-sequence-number-action"] = "anyvalue"
1242
+ subject.set_blob_properties container_name, blob_name, { :sequence_number_action => :anyvalue }
1243
+ end
1244
+
1245
+ it "modifies the request headers when provided a :sequence_number value" do
1246
+ request_headers["x-ms-blob-sequence-number"] = "37"
1247
+ subject.set_blob_properties container_name, blob_name, { :sequence_number => 37.to_s }
1248
+ end
1249
+
1250
+ it "does not modify the request headers when provided an unknown value" do
1251
+ subject.set_blob_properties container_name, blob_name, { :unknown_key => "some_value" }
1252
+ end
1253
+ end
1254
+ end
1255
+
1256
+ describe "#set_blob_metadata" do
1257
+ let(:method) { :put }
1258
+ let(:blob_metadata) { { "MetadataKey" => "MetaDataValue", "MetadataKey1" => "MetaDataValue1" } }
1259
+ let(:request_headers) { { "x-ms-meta-MetadataKey" => "MetaDataValue", "x-ms-meta-MetadataKey1" => "MetaDataValue1" } }
1260
+
1261
+ before {
1262
+ query.update({ "comp" => "metadata" })
1263
+ response.stubs(:success?).returns(true)
1264
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
1265
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
1266
+ }
1267
+
1268
+ it "assembles a URI for the request" do
1269
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1270
+ subject.set_blob_metadata container_name, blob_name, blob_metadata
1271
+ end
1272
+
1273
+ it "calls StorageService#call with the prepared request" do
1274
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1275
+ subject.set_blob_metadata container_name, blob_name, blob_metadata
1276
+ end
1277
+
1278
+ it "returns nil on success" do
1279
+ result = subject.set_blob_metadata container_name, blob_name, blob_metadata
1280
+ result.must_equal nil
1281
+ end
1282
+ end
1283
+
1284
+ describe "#get_blob_properties" do
1285
+ let(:method) { :head }
1286
+
1287
+ before {
1288
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
1289
+ subject.stubs(:call).with(method, uri).returns(response)
1290
+ serialization.stubs(:blob_from_headers).with(response_headers).returns(blob)
1291
+ }
1292
+
1293
+ it "assembles a URI for the request" do
1294
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1295
+ subject.get_blob_properties container_name, blob_name
1296
+ end
1297
+
1298
+ it "calls StorageService#call with the prepared request" do
1299
+ subject.expects(:call).with(method, uri).returns(response)
1300
+ subject.get_blob_properties container_name, blob_name
1301
+ end
1302
+
1303
+ it "returns the blob on success" do
1304
+ result = subject.get_blob_properties container_name, blob_name
1305
+
1306
+ result.must_be_kind_of Azure::Blob::Blob
1307
+ result.must_equal blob
1308
+ result.name.must_equal blob_name
1309
+ end
1310
+
1311
+ describe "when snapshot is provided" do
1312
+ let(:snapshot){ "snapshot" }
1313
+ before { query["snapshot"]=snapshot }
1314
+
1315
+ it "modifies the blob uri query string with the snapshot" do
1316
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1317
+ subject.get_blob_properties container_name, blob_name, { :snapshot => snapshot }
1318
+ end
1319
+
1320
+ it "sets the snapshot value on the returned blob" do
1321
+ result = subject.get_blob_properties container_name, blob_name, { :snapshot => snapshot }
1322
+ result.snapshot.must_equal snapshot
1323
+ end
1324
+ end
1325
+ end
1326
+
1327
+ describe "#get_blob_metadata" do
1328
+ let(:method) { :get }
1329
+
1330
+ before {
1331
+ query["comp"]="metadata"
1332
+
1333
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
1334
+ subject.stubs(:call).with(method, uri).returns(response)
1335
+ serialization.stubs(:blob_from_headers).with(response_headers).returns(blob)
1336
+ }
1337
+
1338
+ it "assembles a URI for the request" do
1339
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1340
+ subject.get_blob_metadata container_name, blob_name
1341
+ end
1342
+
1343
+ it "calls StorageService#call with the prepared request" do
1344
+ subject.expects(:call).with(method, uri).returns(response)
1345
+ subject.get_blob_metadata container_name, blob_name
1346
+ end
1347
+
1348
+ it "returns the blob on success" do
1349
+ result = subject.get_blob_metadata container_name, blob_name
1350
+
1351
+ result.must_be_kind_of Azure::Blob::Blob
1352
+ result.must_equal blob
1353
+ result.name.must_equal blob_name
1354
+ end
1355
+
1356
+ describe "when snapshot is provided" do
1357
+ let(:snapshot){ "snapshot" }
1358
+ before {
1359
+ query["snapshot"]=snapshot
1360
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
1361
+ }
1362
+
1363
+ it "modifies the blob uri query string with the snapshot" do
1364
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1365
+ subject.get_blob_metadata container_name, blob_name, { :snapshot => snapshot }
1366
+ end
1367
+
1368
+ it "sets the snapshot value on the returned blob" do
1369
+ result = subject.get_blob_metadata container_name, blob_name, { :snapshot => snapshot }
1370
+ result.snapshot.must_equal snapshot
1371
+ end
1372
+ end
1373
+ end
1374
+
1375
+ describe "#get_blob" do
1376
+ let(:method) { :get }
1377
+
1378
+ before {
1379
+ response.stubs(:success?).returns(true)
1380
+ response_body = "body-contents"
1381
+
1382
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
1383
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
1384
+ serialization.stubs(:blob_from_headers).with(response_headers).returns(blob)
1385
+ }
1386
+
1387
+ it "assembles a URI for the request" do
1388
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1389
+ subject.get_blob container_name, blob_name
1390
+ end
1391
+
1392
+ it "calls StorageService#call with the prepared request" do
1393
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1394
+ subject.get_blob container_name, blob_name
1395
+ end
1396
+
1397
+ it "returns the blob and blob contents on success" do
1398
+ returned_blob, returned_blob_contents = subject.get_blob container_name, blob_name
1399
+
1400
+ returned_blob.must_be_kind_of Azure::Blob::Blob
1401
+ returned_blob.must_equal blob
1402
+
1403
+ returned_blob_contents.must_equal response_body
1404
+ end
1405
+
1406
+ describe "when snapshot is provided" do
1407
+ let(:source_snapshot){ "source-snapshot" }
1408
+ before { query["snapshot"]=source_snapshot }
1409
+
1410
+ it "modifies the blob uri query string with the snapshot" do
1411
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1412
+ subject.get_blob container_name, blob_name, { :snapshot => source_snapshot }
1413
+ end
1414
+ end
1415
+
1416
+ # describe "when start_range is provided" do
1417
+ # let(:start_range){ 255 }
1418
+ # before { request_headers["x-ms-range"]="#{start_range}-" }
1419
+
1420
+ # it "modifies the request headers with the desired range" do
1421
+ # subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1422
+ # subject.get_blob container_name, blob_name, start_range
1423
+ # end
1424
+ # end
1425
+
1426
+ # describe "when end_range is provided" do
1427
+ # let(:end_range){ 512 }
1428
+ # before { request_headers["x-ms-range"]="0-#{end_range}" }
1429
+
1430
+ # it "modifies the request headers with the desired range" do
1431
+ # subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1432
+ # subject.get_blob container_name, blob_name, nil, end_range
1433
+ # end
1434
+ # end
1435
+
1436
+ describe "when both start_range and end_range are provided" do
1437
+ let(:start_range){ 255 }
1438
+ let(:end_range){ 512 }
1439
+ before { request_headers["x-ms-range"]="bytes=#{start_range}-#{end_range}" }
1440
+
1441
+ it "modifies the request headers with the desired range" do
1442
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1443
+ subject.get_blob container_name, blob_name, { :start_range => start_range, :end_range => end_range }
1444
+ end
1445
+ end
1446
+
1447
+ describe "when get_content_md5 is true" do
1448
+ let(:get_content_md5) { true }
1449
+
1450
+ describe "and a range is specified" do
1451
+ let(:start_range){ 255 }
1452
+ let(:end_range){ 512 }
1453
+ before {
1454
+ request_headers["x-ms-range"]="bytes=#{start_range}-#{end_range}"
1455
+ request_headers["x-ms-range-get-content-md5"]= true
1456
+ }
1457
+
1458
+ it "modifies the request headers to include the x-ms-range-get-content-md5 header" do
1459
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1460
+ subject.get_blob container_name, blob_name, { :start_range => start_range, :end_range => end_range, :get_content_md5 => true }
1461
+ end
1462
+ end
1463
+
1464
+ describe "and a range is NOT specified" do
1465
+ it "does not modify the request headers" do
1466
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1467
+ subject.get_blob container_name, blob_name, { :get_content_md5 => true }
1468
+ end
1469
+ end
1470
+ end
1471
+ end
1472
+
1473
+ describe "#delete_blob" do
1474
+ let(:method) { :delete }
1475
+
1476
+ before {
1477
+ response.stubs(:success?).returns(true)
1478
+ request_headers["x-ms-delete-snapshots"] = "include"
1479
+
1480
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
1481
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
1482
+ }
1483
+
1484
+ it "assembles a URI for the request" do
1485
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1486
+ subject.delete_blob container_name, blob_name
1487
+ end
1488
+
1489
+ it "calls StorageService#call with the prepared request" do
1490
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1491
+ subject.delete_blob container_name, blob_name
1492
+ end
1493
+
1494
+ it "returns nil on success" do
1495
+ result = subject.delete_blob container_name, blob_name
1496
+ result.must_equal nil
1497
+ end
1498
+
1499
+ describe "when snapshot is provided" do
1500
+ let(:source_snapshot){ "source-snapshot" }
1501
+ before {
1502
+ request_headers.delete "x-ms-delete-snapshots"
1503
+ query["snapshot"] = source_snapshot
1504
+ }
1505
+
1506
+ it "modifies the blob uri query string with the snapshot" do
1507
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1508
+ subject.delete_blob container_name, blob_name, { :snapshot => source_snapshot }
1509
+ end
1510
+
1511
+ it "does not include a x-ms-delete-snapshots header" do
1512
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1513
+ subject.delete_blob container_name, blob_name, { :snapshot => source_snapshot }
1514
+ end
1515
+ end
1516
+
1517
+ describe "when delete_snapshots is provided" do
1518
+ let(:delete_snapshots){ :anyvalue }
1519
+ before { request_headers["x-ms-delete-snapshots"]=delete_snapshots.to_s }
1520
+
1521
+ it "modifies the request headers with the provided value" do
1522
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1523
+ subject.delete_blob container_name, blob_name, { :delete_snapshots => delete_snapshots }
1524
+ end
1525
+ end
1526
+
1527
+ describe "when snapshot is provided and delete_snapshots is provided" do
1528
+ let(:source_snapshot){ "source-snapshot" }
1529
+ let(:delete_snapshots){ :anyvalue }
1530
+ before {
1531
+ request_headers.delete "x-ms-delete-snapshots"
1532
+ query["snapshot"]=source_snapshot
1533
+ }
1534
+
1535
+ it "modifies the blob uri query string with the snapshot" do
1536
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1537
+ subject.delete_blob container_name, blob_name, { :snapshot => source_snapshot, :delete_snapshots => delete_snapshots }
1538
+ end
1539
+
1540
+ it "does not include a x-ms-delete-snapshots header" do
1541
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1542
+ subject.delete_blob container_name, blob_name, { :snapshot => source_snapshot, :delete_snapshots => delete_snapshots }
1543
+ end
1544
+ end
1545
+ end
1546
+
1547
+ describe "#create_blob_snapshot" do
1548
+ let(:method) { :put }
1549
+ let(:snapshot_id) { "snapshot-id" }
1550
+
1551
+ before {
1552
+ query["comp"] = "snapshot"
1553
+
1554
+ response_headers["x-ms-snapshot"] = snapshot_id
1555
+
1556
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
1557
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
1558
+ }
1559
+
1560
+ it "assembles a URI for the request" do
1561
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1562
+ subject.create_blob_snapshot container_name, blob_name
1563
+ end
1564
+
1565
+ it "calls StorageService#call with the prepared request" do
1566
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1567
+ subject.create_blob_snapshot container_name, blob_name
1568
+ end
1569
+
1570
+ it "returns the snapshot id on success" do
1571
+ result = subject.create_blob_snapshot container_name, blob_name
1572
+ result.must_be_kind_of String
1573
+ result.must_equal snapshot_id
1574
+ end
1575
+
1576
+ describe "when the options Hash is used" do
1577
+ before {
1578
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1579
+ }
1580
+
1581
+ it "modifies the request headers when provided a :if_modified_since value" do
1582
+ request_headers["If-Modified-Since"] = "ims-value"
1583
+ subject.create_blob_snapshot container_name, blob_name, { :if_modified_since => "ims-value" }
1584
+ end
1585
+
1586
+ it "modifies the request headers when provided a :if_unmodified_since value" do
1587
+ request_headers["If-Unmodified-Since"] = "iums-value"
1588
+ subject.create_blob_snapshot container_name, blob_name, { :if_unmodified_since => "iums-value" }
1589
+ end
1590
+
1591
+ it "modifies the request headers when provided a :if_match value" do
1592
+ request_headers["If-Match"] = "im-value"
1593
+ subject.create_blob_snapshot container_name, blob_name, { :if_match => "im-value" }
1594
+ end
1595
+
1596
+ it "modifies the request headers when provided a :if_none_match value" do
1597
+ request_headers["If-None-Match"] = "inm-value"
1598
+ subject.create_blob_snapshot container_name, blob_name, { :if_none_match => "inm-value" }
1599
+ end
1600
+
1601
+ it "modifies the request headers when provided a :metadata value" do
1602
+ request_headers["x-ms-meta-MetadataKey"] = "MetaDataValue"
1603
+ request_headers["x-ms-meta-MetadataKey1"] = "MetaDataValue1"
1604
+ options = { :metadata => { "MetadataKey" => "MetaDataValue", "MetadataKey1" => "MetaDataValue1"} }
1605
+ subject.create_blob_snapshot container_name, blob_name, options
1606
+ end
1607
+
1608
+ it "does not modify the request headers when provided an unknown value" do
1609
+ subject.create_blob_snapshot container_name, blob_name, { :unknown_key => "some_value" }
1610
+ end
1611
+ end
1612
+ end
1613
+
1614
+ describe "#copy_blob" do
1615
+ let(:method) { :put }
1616
+ let(:source_container_name) { "source-container-name" }
1617
+ let(:source_blob_name) { "source-blob-name" }
1618
+ let(:source_uri) { URI.parse("http://dummy.uri/source") }
1619
+
1620
+ let(:copy_id) { "copy-id" }
1621
+ let(:copy_status) { "copy-status" }
1622
+
1623
+ before {
1624
+ request_headers["x-ms-copy-source"] = source_uri.to_s
1625
+
1626
+ response_headers["x-ms-copy-id"] = copy_id
1627
+ response_headers["x-ms-copy-status"] = copy_status
1628
+
1629
+ subject.stubs(:blob_uri).with(container_name, blob_name, {}).returns(uri)
1630
+ subject.stubs(:blob_uri).with(source_container_name, source_blob_name, query).returns(source_uri)
1631
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
1632
+ }
1633
+
1634
+ it "assembles a URI for the request" do
1635
+ subject.expects(:blob_uri).with(container_name, blob_name, {}).returns(uri)
1636
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name
1637
+ end
1638
+
1639
+ it "assembles the source URI and places it in the header" do
1640
+ subject.expects(:blob_uri).with(source_container_name, source_blob_name, query).returns(source_uri)
1641
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name
1642
+ end
1643
+
1644
+ it "calls StorageService#call with the prepared request" do
1645
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1646
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name
1647
+ end
1648
+
1649
+ it "returns the copy id and copy status on success" do
1650
+ returned_copy_id, returned_copy_status = subject.copy_blob container_name, blob_name, source_container_name, source_blob_name
1651
+ returned_copy_id.must_equal copy_id
1652
+ returned_copy_status.must_equal copy_status
1653
+ end
1654
+
1655
+ describe "when snapshot is provided" do
1656
+ let(:source_snapshot){"source-snapshot"}
1657
+ before {
1658
+ query["snapshot"]=source_snapshot
1659
+ }
1660
+
1661
+ it "modifies the source blob uri query string with the snapshot" do
1662
+ subject.expects(:blob_uri).with(source_container_name, source_blob_name, query).returns(source_uri)
1663
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, { :source_snapshot => source_snapshot }
1664
+ end
1665
+ end
1666
+
1667
+ describe "when the options Hash is used" do
1668
+ before {
1669
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1670
+ }
1671
+
1672
+ it "modifies the request headers when provided a :dest_if_modified_since value" do
1673
+ request_headers["If-Modified-Since"] = "ims-value"
1674
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, { :dest_if_modified_since => "ims-value" }
1675
+ end
1676
+
1677
+ it "modifies the request headers when provided a :dest_if_unmodified_since value" do
1678
+ request_headers["If-Unmodified-Since"] = "iums-value"
1679
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, { :dest_if_unmodified_since => "iums-value" }
1680
+ end
1681
+
1682
+ it "modifies the request headers when provided a :dest_if_match value" do
1683
+ request_headers["If-Match"] = "im-value"
1684
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, { :dest_if_match => "im-value" }
1685
+ end
1686
+
1687
+ it "modifies the request headers when provided a :dest_if_none_match value" do
1688
+ request_headers["If-None-Match"] = "inm-value"
1689
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, { :dest_if_none_match => "inm-value" }
1690
+ end
1691
+
1692
+ it "modifies the request headers when provided a :source_if_modified_since value" do
1693
+ request_headers["x-ms-source-if-modified-since"] = "ims-value"
1694
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, { :source_if_modified_since => "ims-value" }
1695
+ end
1696
+
1697
+ it "modifies the request headers when provided a :source_if_unmodified_since value" do
1698
+ request_headers["x-ms-source-if-unmodified-since"] = "iums-value"
1699
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, { :source_if_unmodified_since => "iums-value" }
1700
+ end
1701
+
1702
+ it "modifies the request headers when provided a :source_if_match value" do
1703
+ request_headers["x-ms-source-if-match"] = "im-value"
1704
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, { :source_if_match => "im-value" }
1705
+ end
1706
+
1707
+ it "modifies the request headers when provided a :source_if_none_match value" do
1708
+ request_headers["x-ms-source-if-none-match"] = "inm-value"
1709
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, { :source_if_none_match => "inm-value" }
1710
+ end
1711
+
1712
+ it "modifies the request headers when provided a :metadata value" do
1713
+ request_headers["x-ms-meta-MetadataKey"] = "MetaDataValue"
1714
+ request_headers["x-ms-meta-MetadataKey1"] = "MetaDataValue1"
1715
+ options = { :metadata => { "MetadataKey" => "MetaDataValue", "MetadataKey1" => "MetaDataValue1"} }
1716
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, options
1717
+ end
1718
+
1719
+ it "does not modify the request headers when provided an unknown value" do
1720
+ subject.copy_blob container_name, blob_name, source_container_name, source_blob_name, { :unknown_key => "some_value" }
1721
+ end
1722
+ end
1723
+ end
1724
+
1725
+ describe "lease functions" do
1726
+ let(:method) { :put }
1727
+ let(:lease_id) { "lease-id" }
1728
+
1729
+ before {
1730
+ query.update({"comp"=>"lease"})
1731
+ subject.stubs(:blob_uri).with(container_name, blob_name, query).returns(uri)
1732
+ subject.stubs(:call).with(method, uri, nil, request_headers).returns(response)
1733
+ }
1734
+
1735
+ describe "#acquire_lease" do
1736
+ before {
1737
+ request_headers["x-ms-lease-action"] = "acquire"
1738
+ request_headers["x-ms-lease-duration"] = "-1"
1739
+
1740
+ response.stubs(:success?).returns(true)
1741
+ response_headers["x-ms-lease-id"] = lease_id
1742
+ }
1743
+
1744
+ it "assembles a URI for the request" do
1745
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1746
+ subject.acquire_lease container_name, blob_name
1747
+ end
1748
+
1749
+ it "calls StorageService#call with the prepared request" do
1750
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1751
+ subject.acquire_lease container_name, blob_name
1752
+ end
1753
+
1754
+ it "returns lease id on success" do
1755
+ result = subject.acquire_lease container_name, blob_name
1756
+ result.must_equal lease_id
1757
+ end
1758
+
1759
+ describe "when passed a duration" do
1760
+ let(:duration) { 37 }
1761
+ before { request_headers["x-ms-lease-duration"] = "37" }
1762
+
1763
+ it "modifies the headers to include the provided duration value" do
1764
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1765
+ subject.acquire_lease container_name, blob_name, { :duration => duration }
1766
+ end
1767
+ end
1768
+
1769
+ describe "when passed a proposed_lease_id" do
1770
+ let(:default_duration) { -1 }
1771
+ let(:proposed_lease_id) { "proposed-lease-id" }
1772
+ before { request_headers["x-ms-proposed-lease-id"] = proposed_lease_id }
1773
+
1774
+ it "modifies the headers to include the proposed lease id" do
1775
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1776
+ subject.acquire_lease container_name, blob_name, { :duration => default_duration, :proposed_lease_id => proposed_lease_id }
1777
+ end
1778
+ end
1779
+ end
1780
+
1781
+ describe "#renew_lease" do
1782
+ before {
1783
+ request_headers["x-ms-lease-action"] = "renew"
1784
+ request_headers["x-ms-lease-id"] = lease_id
1785
+
1786
+ response.stubs(:success?).returns(true)
1787
+ response_headers["x-ms-lease-id"] = lease_id
1788
+ }
1789
+
1790
+ it "assembles a URI for the request" do
1791
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1792
+ subject.renew_lease container_name, blob_name, lease_id
1793
+ end
1794
+
1795
+ it "calls StorageService#call with the prepared request" do
1796
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1797
+ subject.renew_lease container_name, blob_name, lease_id
1798
+ end
1799
+
1800
+ it "returns lease id on success" do
1801
+ result = subject.renew_lease container_name, blob_name, lease_id
1802
+ result.must_equal lease_id
1803
+ end
1804
+ end
1805
+
1806
+ describe "#release_lease" do
1807
+ before {
1808
+ request_headers["x-ms-lease-action"] = "release"
1809
+ request_headers["x-ms-lease-id"] = lease_id
1810
+
1811
+ response.stubs(:success?).returns(true)
1812
+ }
1813
+
1814
+ it "assembles a URI for the request" do
1815
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1816
+ subject.release_lease container_name, blob_name, lease_id
1817
+ end
1818
+
1819
+ it "calls StorageService#call with the prepared request" do
1820
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1821
+ subject.release_lease container_name, blob_name, lease_id
1822
+ end
1823
+
1824
+ it "returns nil on success" do
1825
+ result = subject.release_lease container_name, blob_name, lease_id
1826
+ result.must_equal nil
1827
+ end
1828
+ end
1829
+
1830
+ describe "#break_lease" do
1831
+ let(:lease_time) { 38 }
1832
+ before {
1833
+ request_headers["x-ms-lease-action"] = "break"
1834
+
1835
+ response.stubs(:success?).returns(true)
1836
+ response_headers["x-ms-lease-time"] = lease_time.to_s
1837
+ }
1838
+
1839
+ it "assembles a URI for the request" do
1840
+ subject.expects(:blob_uri).with(container_name, blob_name, query).returns(uri)
1841
+ subject.break_lease container_name, blob_name
1842
+ end
1843
+
1844
+ it "calls StorageService#call with the prepared request" do
1845
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1846
+ subject.break_lease container_name, blob_name
1847
+ end
1848
+
1849
+ it "returns lease time on success" do
1850
+ result = subject.break_lease container_name, blob_name
1851
+ result.must_equal lease_time
1852
+ end
1853
+
1854
+ describe "when passed an optional break period" do
1855
+ let(:break_period) { 37 }
1856
+ before { request_headers["x-ms-lease-break-period"] = break_period.to_s }
1857
+
1858
+ it "modifies the request headers to include a break period" do
1859
+ subject.expects(:call).with(method, uri, nil, request_headers).returns(response)
1860
+ subject.break_lease container_name, blob_name, { :break_period => break_period }
1861
+ end
1862
+ end
1863
+ end
1864
+ end
1865
+ end
1866
+ end
1867
+
1868
+ class MockBlobService < Azure::Blob::BlobService
1869
+ def containers_uri(query={})
1870
+ super
1871
+ end
1872
+
1873
+ def container_uri(name, query={})
1874
+ super
1875
+ end
1876
+
1877
+ def blob_uri(container_name, blob_name, query={})
1878
+ super
1879
+ end
1880
+ end
1881
+
1882
+ describe "uri functions" do
1883
+ subject { MockBlobService.new }
1884
+
1885
+ let(:container_name) { "container" }
1886
+ let(:blob_name) { "blob" }
1887
+ let(:query) { { "param" => "value", "param 1" => "value 1" } }
1888
+ let(:host_uri) { "http://dummy.uri" }
1889
+
1890
+ before {
1891
+ subject.host = host_uri
1892
+ }
1893
+
1894
+ describe "#containers_uri" do
1895
+ it "returns a containers URI" do
1896
+ result = subject.containers_uri
1897
+ result.must_be_kind_of URI
1898
+ result.scheme.must_equal "http"
1899
+ result.host.must_equal "dummy.uri"
1900
+ result.path.must_equal "/"
1901
+ result.query.must_equal "comp=list"
1902
+ end
1903
+
1904
+ it "encodes optional query has as uri parameters" do
1905
+ result = subject.containers_uri query
1906
+ result.query.must_equal "comp=list&param=value&param+1=value+1"
1907
+ end
1908
+ end
1909
+
1910
+ describe "#container_uri" do
1911
+ it "returns a container URI" do
1912
+ result = subject.container_uri container_name
1913
+ result.must_be_kind_of URI
1914
+ result.scheme.must_equal "http"
1915
+ result.host.must_equal "dummy.uri"
1916
+ result.path.must_equal "/container"
1917
+ result.query.must_equal "restype=container"
1918
+ end
1919
+
1920
+ it "encodes optional query has as uri parameters" do
1921
+ result = subject.container_uri container_name, query
1922
+ result.query.must_equal "restype=container&param=value&param+1=value+1"
1923
+ end
1924
+
1925
+ it "returns the same URI instance when the first parameter is a URI" do
1926
+ random_uri = URI.parse("http://random.uri")
1927
+ result = subject.container_uri random_uri
1928
+ result.must_equal random_uri
1929
+ end
1930
+ end
1931
+
1932
+ describe "#blob_uri" do
1933
+ it "returns a blob URI" do
1934
+ result = subject.blob_uri container_name, blob_name
1935
+ result.must_be_kind_of URI
1936
+ result.scheme.must_equal "http"
1937
+ result.host.must_equal "dummy.uri"
1938
+ result.path.must_equal "/container/blob"
1939
+ end
1940
+
1941
+ it "encodes optional query has as uri parameters" do
1942
+ result = subject.blob_uri container_name, blob_name, query
1943
+ result.query.must_equal "param=value&param+1=value+1"
1944
+ end
1945
+ end
1946
+ end
1947
+ end