azure-fix 0.7.0.pre3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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