juliusl-azure-sdk-for-ruby 0.7.0

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