azure-fix 0.7.0.pre3

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