juliusl-azure-sdk-for-ruby 0.7.0

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