aws-sdk 2.0.1 → 2.0.5

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 (251) hide show
  1. package/.eslintrc +20 -0
  2. package/.gitignore +10 -0
  3. package/.travis.yml +20 -0
  4. package/.yardopts +20 -0
  5. package/.yardopts_guide +21 -0
  6. package/Gemfile +16 -0
  7. package/Gemfile.lock +34 -0
  8. package/README.md +5 -6
  9. package/Rakefile +14 -0
  10. package/UPGRADING.md +9 -4
  11. package/configuration.sample +5 -0
  12. package/dist/BUNDLE_LICENSE.txt +96 -0
  13. package/dist/aws-sdk.js +9594 -0
  14. package/dist/aws-sdk.min.js +21 -0
  15. package/dist-tools/.eslintrc +10 -0
  16. package/dist-tools/browser-builder.js +142 -0
  17. package/dist-tools/strategies/cache.js +68 -0
  18. package/dist-tools/strategies/default.js +165 -0
  19. package/dist-tools/test/browser-builder.mocha.spec.coffee +182 -0
  20. package/dist-tools/test/helpers.coffee +16 -0
  21. package/doc-src/guide/browser-building.md +93 -0
  22. package/doc-src/guide/browser-configuring-wif.md +287 -0
  23. package/doc-src/guide/browser-configuring.md +218 -0
  24. package/doc-src/guide/browser-examples.md +220 -0
  25. package/doc-src/guide/browser-intro.md +46 -0
  26. package/doc-src/guide/browser-making-requests.md +279 -0
  27. package/doc-src/guide/browser-services.md +75 -0
  28. package/doc-src/guide/index.md +41 -0
  29. package/doc-src/guide/node-configuring.md +272 -0
  30. package/doc-src/guide/node-examples.md +341 -0
  31. package/doc-src/guide/node-intro.md +32 -0
  32. package/doc-src/guide/node-making-requests.md +309 -0
  33. package/doc-src/guide/node-services.md +159 -0
  34. package/doc-src/templates/api-versions/model_documentor.rb +366 -0
  35. package/doc-src/templates/api-versions/plugin.rb +230 -0
  36. package/doc-src/templates/api-versions/templates/default/class/html/setup.rb +9 -0
  37. package/doc-src/templates/api-versions/templates/default/class/html/waiter_details_list.erb +7 -0
  38. package/doc-src/templates/api-versions/templates/default/class/html/waiter_summary.erb +7 -0
  39. package/doc-src/templates/api-versions/templates/default/docstring/html/experimental.erb +4 -0
  40. package/doc-src/templates/api-versions/templates/default/docstring/setup.rb +9 -0
  41. package/doc-src/templates/api-versions/templates/default/fulldoc/html/css/common.css +6 -0
  42. package/doc-src/templates/api-versions/templates/default/fulldoc/html/setup.rb +62 -0
  43. package/doc-src/templates/api-versions/templates/default/layout/html/services.erb +10 -0
  44. package/doc-src/templates/api-versions/templates/default/layout/html/setup.rb +28 -0
  45. package/doc-src/templates/api-versions/templates/default/module/html/box_info.erb +45 -0
  46. package/doc-src/templates/api-versions/templates/default/module/html/children.erb +8 -0
  47. package/doc-src/templates/api-versions/templates/default/tags/setup.rb +3 -0
  48. package/doc-src/templates/api-versions/templates/default/waiter_details/html/method_signature.erb +3 -0
  49. package/doc-src/templates/api-versions/templates/default/waiter_details/html/setup.rb +5 -0
  50. package/doc-src/templates/default/layout/html/footer.erb +31 -0
  51. package/doc-src/templates/default/layout/html/layout.erb +23 -0
  52. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/css/highlight.github.css +127 -0
  53. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/css/style.css +1192 -0
  54. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/img/logo.png +0 -0
  55. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/app.js +33 -0
  56. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/highlight.pack.js +27 -0
  57. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/AUTHORS +55 -0
  58. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/LICENSE +25 -0
  59. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/doctools.js +247 -0
  60. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/file.png +0 -0
  61. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/searchtools.js +568 -0
  62. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/underscore.js +23 -0
  63. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/search.erb +29 -0
  64. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/search_index.erb +1 -0
  65. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/setup.rb +75 -0
  66. package/doc-src/templates/flasky_sphinx_guide/layout/html/layout.erb +93 -0
  67. package/doc-src/templates/flasky_sphinx_guide/layout/html/setup.rb +9 -0
  68. package/doc-src/templates/flasky_sphinx_guide/layout/html/sidebar.erb +45 -0
  69. package/doc-src/templates/flasky_sphinx_guide/onefile/html/layout.erb +51 -0
  70. package/doc-src/templates/flasky_sphinx_guide/onefile/html/setup.rb +1 -0
  71. package/eslint-rules/no-require-in-service.js +10 -0
  72. package/features/autoscaling/autoscaling.feature +21 -0
  73. package/features/autoscaling/step_definitions/autoscaling.js +49 -0
  74. package/features/cloudformation/cloudformation.feature +22 -0
  75. package/features/cloudformation/step_definitions/cloudformation.js +26 -0
  76. package/features/cloudfront/cloudfront.feature +28 -0
  77. package/features/cloudfront/step_definitions/cloudfront-latest.js +54 -0
  78. package/features/cloudfront/step_definitions/cloudfront.js +21 -0
  79. package/features/cloudsearch/cloudsearch.feature +34 -0
  80. package/features/cloudsearch/step_definitions/cloudsearch.js +42 -0
  81. package/features/cloudtrail/cloudtrail.feature +17 -0
  82. package/features/cloudtrail/step_definitions/cloudtrail.js +14 -0
  83. package/features/cloudwatch/cloudwatch.feature +15 -0
  84. package/features/cloudwatch/step_definitions/cloudwatch.js +48 -0
  85. package/features/datapipeline/datapipeline.feature +23 -0
  86. package/features/datapipeline/step_definitions/datapipeline.js +79 -0
  87. package/features/directconnect/directconnect.feature +20 -0
  88. package/features/directconnect/step_definitions/directconnect.js +44 -0
  89. package/features/dynamodb/crc32.feature +18 -0
  90. package/features/dynamodb/step_definitions/dynamodb.js +154 -0
  91. package/features/dynamodb/tables.feature +50 -0
  92. package/features/ec2/ec2.feature +28 -0
  93. package/features/ec2/step_definitions/ec2.js +65 -0
  94. package/features/elasticache/elasticache.feature +20 -0
  95. package/features/elasticache/step_definitions/elasticache.js +34 -0
  96. package/features/elasticbeanstalk/elasticbeanstalk.feature +22 -0
  97. package/features/elasticbeanstalk/step_definitions/elasticbeanstalk.js +38 -0
  98. package/features/elastictranscoder/elastictranscoder.feature +24 -0
  99. package/features/elastictranscoder/step_definitions/elastictranscoder.js +56 -0
  100. package/features/elb/elb.feature +19 -0
  101. package/features/elb/step_definitions/elb.js +37 -0
  102. package/features/emr/emr.feature +16 -0
  103. package/features/emr/step_definitions/emr.js +45 -0
  104. package/features/extra/assertions.js +29 -0
  105. package/features/extra/dummy.feature +0 -0
  106. package/features/extra/fixtures/testfile.txt +1 -0
  107. package/features/extra/helpers.js +113 -0
  108. package/features/extra/hooks.js +107 -0
  109. package/features/extra/world.js +12 -0
  110. package/features/glacier/glacier.feature +47 -0
  111. package/features/glacier/step_definitions/glacier.js +112 -0
  112. package/features/iam/iam.feature +24 -0
  113. package/features/iam/step_definitions/iam.js +66 -0
  114. package/features/importexport/importexport.feature +53 -0
  115. package/features/importexport/step_definitions/importexport.js +42 -0
  116. package/features/kinesis/kinesis.feature +9 -0
  117. package/features/kinesis/step_definitions/kinesis.js +10 -0
  118. package/features/opsworks/opsworks.feature +26 -0
  119. package/features/opsworks/step_definitions/opsworks.js +42 -0
  120. package/features/rds/rds.feature +32 -0
  121. package/features/rds/step_definitions/rds.js +72 -0
  122. package/features/redshift/redshift.feature +20 -0
  123. package/features/redshift/step_definitions/redshift.js +33 -0
  124. package/features/route53/route53.feature +41 -0
  125. package/features/route53/step_definitions/route53.js +97 -0
  126. package/features/s3/buckets.feature +40 -0
  127. package/features/s3/objects.feature +122 -0
  128. package/features/s3/step_definitions/buckets.js +136 -0
  129. package/features/s3/step_definitions/hooks.js +39 -0
  130. package/features/s3/step_definitions/objects.js +204 -0
  131. package/features/s3/step_definitions/proxy.js +44 -0
  132. package/features/ses/ses.feature +20 -0
  133. package/features/ses/step_definitions/ses.js +22 -0
  134. package/features/simpledb/simpledb.feature +29 -0
  135. package/features/simpledb/step_definitions/simpledb.js +46 -0
  136. package/features/sns/sns.feature +15 -0
  137. package/features/sns/step_definitions/sns.js +33 -0
  138. package/features/sqs/messages.feature +21 -0
  139. package/features/sqs/queues.feature +18 -0
  140. package/features/sqs/step_definitions/messages.js +46 -0
  141. package/features/sqs/step_definitions/queues.js +33 -0
  142. package/features/sqs/step_definitions/sqs.js +7 -0
  143. package/features/storagegateway/step_definitions/storagegateway.js +16 -0
  144. package/features/storagegateway/storagegateway.feature +13 -0
  145. package/features/sts/step_definitions/sts.js +35 -0
  146. package/features/sts/sts.feature +29 -0
  147. package/features/support/step_definitions/support.js +35 -0
  148. package/features/support/support.feature +18 -0
  149. package/features/swf/step_definitions/swf.js +38 -0
  150. package/features/swf/swf.feature +15 -0
  151. package/index.js +2 -0
  152. package/lib/core.js +2 -2
  153. package/lib/credentials/shared_ini_file_credentials.js +0 -1
  154. package/lib/event_listeners.js +13 -1
  155. package/lib/http/node.js +19 -30
  156. package/lib/model/resource_waiter.js +0 -4
  157. package/lib/model/shape.js +2 -1
  158. package/lib/protocol/rest_xml.js +1 -1
  159. package/lib/region_config.js +31 -0
  160. package/lib/region_config.json +56 -0
  161. package/lib/request.js +37 -45
  162. package/lib/sequential_executor.js +17 -34
  163. package/lib/service.js +17 -44
  164. package/lib/services/cloudsearchdomain.js +69 -0
  165. package/lib/services/route53.js +0 -12
  166. package/lib/services/s3.js +3 -19
  167. package/lib/signers/v4.js +2 -1
  168. package/lib/util.js +28 -3
  169. package/package.json +3 -3
  170. package/scripts/console +11 -3
  171. package/scripts/coverage +126 -0
  172. package/tasks/apis.rake +122 -0
  173. package/tasks/browser.rake +89 -0
  174. package/tasks/docs.rake +36 -0
  175. package/tasks/lib/cucumber_generator.rb +40 -0
  176. package/tasks/util.rake +33 -0
  177. package/test/browser/js/jasmine-1.3.1.js +2600 -0
  178. package/test/browser/js/jasmine-html.js +681 -0
  179. package/test/browser/runner.html +109 -0
  180. package/test/browser/runner.js +92 -0
  181. package/test/browser/sample/appinfo.sample.js +15 -0
  182. package/test/browser/sample/console.html +429 -0
  183. package/test/browser/sample/css/smoothness/images/animated-overlay.gif +0 -0
  184. package/test/browser/sample/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  185. package/test/browser/sample/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  186. package/test/browser/sample/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  187. package/test/browser/sample/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  188. package/test/browser/sample/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  189. package/test/browser/sample/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  190. package/test/browser/sample/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  191. package/test/browser/sample/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  192. package/test/browser/sample/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  193. package/test/browser/sample/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  194. package/test/browser/sample/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  195. package/test/browser/sample/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  196. package/test/browser/sample/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  197. package/test/browser/sample/css/smoothness/jquery-ui-1.10.1.custom.css +1175 -0
  198. package/test/browser/sample/css/smoothness/jquery-ui-1.10.1.custom.min.css +5 -0
  199. package/test/browser/sample/img/loading.gif +0 -0
  200. package/test/browser/sample/js/jquery-1.9.1.js +9597 -0
  201. package/test/browser/sample/js/jquery-ui-1.10.1.custom.js +14903 -0
  202. package/test/browser/sample/js/jquery-ui-1.10.1.custom.min.js +6 -0
  203. package/test/browser/sample/s3upload.html +111 -0
  204. package/test/browser.spec.coffee +207 -0
  205. package/test/config.spec.coffee +202 -0
  206. package/test/credential_provider_chain.spec.coffee +90 -0
  207. package/test/credentials.spec.coffee +452 -0
  208. package/test/endpoint.spec.coffee +80 -0
  209. package/test/event_listeners.spec.coffee +493 -0
  210. package/test/helpers.coffee +150 -0
  211. package/test/http_request.spec.coffee +55 -0
  212. package/test/json/builder.spec.coffee +129 -0
  213. package/test/json/parser.spec.coffee +108 -0
  214. package/test/metadata_service.spec.coffee +54 -0
  215. package/test/model/api.spec.coffee +67 -0
  216. package/test/model/shape.spec.coffee +23 -0
  217. package/test/node_http_client.spec.coffee +40 -0
  218. package/test/param_validator.spec.coffee +456 -0
  219. package/test/protocol/json.spec.coffee +167 -0
  220. package/test/protocol/query.spec.coffee +191 -0
  221. package/test/protocol/rest.spec.coffee +237 -0
  222. package/test/protocol/rest_json.spec.coffee +255 -0
  223. package/test/protocol/rest_xml.spec.coffee +329 -0
  224. package/test/query/query_param_serializer.spec.coffee +327 -0
  225. package/test/region_config.spec.coffee +50 -0
  226. package/test/request.spec.coffee +316 -0
  227. package/test/resource_waiter.spec.coffee +89 -0
  228. package/test/response.spec.coffee +81 -0
  229. package/test/sequential_executor.spec.coffee +118 -0
  230. package/test/service.spec.coffee +230 -0
  231. package/test/services/cloudfront.spec.coffee +44 -0
  232. package/test/services/cloudsearchdomain.spec.coffee +23 -0
  233. package/test/services/dynamodb.spec.coffee +32 -0
  234. package/test/services/ec2.spec.coffee +78 -0
  235. package/test/services/elastictranscoder.spec.coffee +43 -0
  236. package/test/services/glacier.spec.coffee +61 -0
  237. package/test/services/rds.spec.coffee +38 -0
  238. package/test/services/route53.spec.coffee +77 -0
  239. package/test/services/s3.spec.coffee +538 -0
  240. package/test/services/simpledb.spec.coffee +12 -0
  241. package/test/services/sqs.spec.coffee +130 -0
  242. package/test/services/sts.spec.coffee +72 -0
  243. package/test/services/swf.spec.coffee +6 -0
  244. package/test/signers/presign.spec.coffee +36 -0
  245. package/test/signers/s3.spec.coffee +297 -0
  246. package/test/signers/v2.spec.coffee +68 -0
  247. package/test/signers/v4.spec.coffee +135 -0
  248. package/test/util.spec.coffee +510 -0
  249. package/test/xml/builder.spec.coffee +529 -0
  250. package/test/xml/parser.spec.coffee +587 -0
  251. package/lib/services/simpledb.js +0 -15
@@ -0,0 +1,122 @@
1
+ # language: en
2
+ @s3 @objects
3
+ Feature: Working with Objects in S3
4
+
5
+ As a user of S3
6
+ I need to be able to work with objects in a bucket.
7
+
8
+ Scenario: CRUD objects
9
+ When I write "world" to the key "hello"
10
+ Then the object with the key "hello" should exist
11
+ And the object with the key "hello" should contain "world"
12
+ When I write "new world" to the key "hello"
13
+ Then the object with the key "hello" should exist
14
+ Then the object with the key "hello" should contain "new world"
15
+
16
+ # Empty files
17
+ When I write "" to the key "hello"
18
+ Then the object with the key "hello" should exist
19
+ And the object with the key "hello" should contain ""
20
+
21
+ # ContentLength
22
+ When I write "foobar" to the key "hello" with ContentLength 3
23
+ Then the object with the key "hello" should exist
24
+ And the object with the key "hello" should contain "foo"
25
+
26
+ # ContentLength
27
+ When I write empty buffer to the key "hello"
28
+ Then the object with the key "hello" should exist
29
+ And the object with the key "hello" should contain ""
30
+
31
+ # UTF-8
32
+ When I write "åß∂ƒ©" to the key "hello"
33
+ Then the object with the key "hello" should exist
34
+ And the object with the key "hello" should contain "åß∂ƒ©"
35
+
36
+ When I copy an object with the key "hello" to "byebye"
37
+ Then the object with the key "byebye" should exist
38
+ And the object with the key "byebye" should contain "åß∂ƒ©"
39
+ And I delete the object with the key "byebye"
40
+
41
+ # Unauthenticated request
42
+ When I write "world" to the public key "hello"
43
+ Then the unauthenticated request to read key "hello" should equal "world"
44
+
45
+ When I delete the object with the key "hello"
46
+ Then the object with the key "hello" should not exist
47
+
48
+ @presigned
49
+ Scenario: Pre-signed URLs
50
+ Given I get a pre-signed URL to PUT the key "hello"
51
+ And I access the URL via HTTP PUT with data "PRESIGNED BODY CONTENTS"
52
+ When I get a pre-signed URL to GET the key "hello"
53
+ And I access the URL via HTTP GET
54
+ Then the HTTP response should equal "PRESIGNED BODY CONTENTS"
55
+
56
+ @presigned @checksum
57
+ Scenario: Pre-signed URLs with checksum
58
+ Given I get a pre-signed URL to PUT the key "hello" with data "CHECKSUMMED"
59
+ And I access the URL via HTTP PUT with data "NOT CHECKSUMMED"
60
+ Then the HTTP response should contain "SignatureDoesNotMatch"
61
+
62
+ @buffer
63
+ Scenario: Buffers and streams
64
+ When I write buffer "world" to the key "hello"
65
+ Then the object with the key "hello" should exist
66
+ And the object with the key "hello" should contain "world"
67
+
68
+ When I write file "testfile.txt" to the key "hello"
69
+ Then the object with the key "hello" should exist
70
+ And the object with the key "hello" should contain "CONTENTS OF FILE"
71
+
72
+ When I stream key "hello"
73
+ Then the streamed data should contain "CONTENTS OF FILE"
74
+
75
+ When I stream2 key "hello"
76
+ Then the streamed data should contain "CONTENTS OF FILE"
77
+
78
+ @progress
79
+ Scenario: Progress events
80
+ When I write a 512KB buffer to the key "hello" with progress events
81
+ Then more than 1 "httpUploadProgress" event should fire
82
+ And the "total" value of the progress event should equal 512KB
83
+ And the "loaded" value of the first progress event should be greater than 10 bytes
84
+
85
+ When I read the key "hello" with progress events
86
+ Then more than 1 "httpDownloadProgress" event should fire
87
+ And the "total" value of the progress event should equal 512KB
88
+ And the "loaded" value of the first progress event should be greater than 10 bytes
89
+
90
+ @proxy
91
+ Scenario: Proxy support
92
+ When I write "world" to the key "hello"
93
+ Then the object with the key "hello" should exist
94
+ And the object with the key "hello" should contain "world"
95
+
96
+ When I delete the object with the key "hello"
97
+ Then the object with the key "hello" should not exist
98
+
99
+ And I teardown the local proxy server
100
+
101
+ @pagination
102
+ Scenario: Paginating responses
103
+ Given I delete the object with the key "hello"
104
+ And I write "data" to the key "obj0"
105
+ And I write "data" to the key "obj1"
106
+ And I write "data" to the key "obj2"
107
+ And I write "data" to the key "obj3"
108
+ And I write "data" to the key "obj4"
109
+ And I write "data" to the key "obj5"
110
+ And I write "data" to the key "obj6"
111
+ And I write "data" to the key "obj7"
112
+ And I write "data" to the key "obj8"
113
+ And I write "data" to the key "obj9"
114
+ And the object with the key "obj9" should exist
115
+ And I setup the listObjects request for the bucket
116
+ When I paginate the "listObjects" operation with limit 3
117
+ Then I should get 4 pages
118
+
119
+ @error
120
+ Scenario: Error handling
121
+ Given I write "data" to the invalid key ""
122
+ Then the status code should be 400
@@ -0,0 +1,136 @@
1
+ module.exports = function() {
2
+
3
+ this.When(/^I create a bucket$/, function(next) {
4
+ this.bucket = this.uniqueName('aws-sdk-js-integration');
5
+ this.request('s3', 'createBucket', {Bucket:this.bucket}, next);
6
+ });
7
+
8
+ this.When(/^I create a bucket with the location constraint "([^"]*)"$/, function(loc, next) {
9
+ this.bucket = this.uniqueName('aws-sdk-js-integration');
10
+ var params = { Bucket: this.bucket, CreateBucketConfiguration: { LocationConstraint: loc }};
11
+ this.request('s3', 'createBucket', params, next);
12
+ });
13
+
14
+ this.Then(/^the bucket should exist$/, function(next) {
15
+ this.s3.waitFor('bucketExists', {Bucket:this.bucket}, next);
16
+ });
17
+
18
+ this.When(/^I delete the bucket$/, function(next) {
19
+ this.request('s3', 'deleteBucket', {Bucket:this.bucket}, next);
20
+ });
21
+
22
+ this.Then(/^the bucket should not exist$/, function(next) {
23
+ this.s3.waitFor('bucketNotExists', {Bucket:this.bucket}, next);
24
+ });
25
+
26
+ this.Then(/^the bucket should have a location constraint of "([^"]*)"$/, function(loc, next) {
27
+ var self = this;
28
+ self.s3.getBucketLocation({Bucket:self.bucket}, function(err, data) {
29
+ self.assert.equal(data.LocationConstraint, loc);
30
+ next();
31
+ });
32
+ });
33
+
34
+ this.Then(/^I delete the bucket$/, function(next) {
35
+ this.request('s3', 'deleteBucket', {Bucket:this.bucket}, next);
36
+ });
37
+
38
+ this.When(/^I put a transition lifecycle configuration on the bucket with prefix "([^"]*)"$/, function(prefix, callback) {
39
+ var params = {
40
+ Bucket: this.bucket,
41
+ LifecycleConfiguration: {
42
+ Rules: [{
43
+ Prefix: prefix,
44
+ Status: 'Enabled',
45
+ Transition: {Days: 0, StorageClass: 'GLACIER'}
46
+ }]
47
+ }
48
+ };
49
+
50
+ this.request('s3', 'putBucketLifecycle', params, callback);
51
+ });
52
+
53
+ this.When(/^I get the transition lifecycle configuration on the bucket$/, function(callback) {
54
+ this.eventually(callback, function(next) {
55
+ this.request('s3', 'getBucketLifecycle', {Bucket: this.bucket}, next);
56
+ });
57
+ });
58
+
59
+ this.Then(/^the lifecycle configuration should have transition days of (\d+)$/, function(days, callback) {
60
+ this.assert.equal(this.data.Rules[0].Transition.Days, 0);
61
+ callback();
62
+ });
63
+
64
+ this.Then(/^the lifecycle configuration should have transition storage class of "([^"]*)"$/, function(value, callback) {
65
+ this.assert.equal(this.data.Rules[0].Transition.StorageClass, value);
66
+ callback();
67
+ });
68
+
69
+ this.When(/^I put a bucket CORS configuration$/, function(callback) {
70
+ var params = {
71
+ Bucket: this.bucket,
72
+ CORSConfiguration: {
73
+ CORSRules: [{
74
+ AllowedMethods: ['DELETE', 'POST', 'PUT'],
75
+ AllowedOrigins: ['http://example.com'],
76
+ AllowedHeaders: ['*'],
77
+ ExposeHeaders: ['x-amz-server-side-encryption'],
78
+ MaxAgeSeconds: 5000
79
+ }]
80
+ }
81
+ }
82
+ this.request('s3', 'putBucketCors', params, callback);
83
+ });
84
+
85
+ this.When(/^I get the bucket CORS configuration$/, function(callback) {
86
+ this.request('s3', 'getBucketCors', {Bucket: this.bucket}, callback);
87
+ });
88
+
89
+ this.Then(/^the AllowedMethods list should inclue "([^"]*)"$/, function(value, callback) {
90
+ this.assert.equal(this.data.CORSRules[0].AllowedMethods.sort().join(" "), "DELETE POST PUT");
91
+ callback();
92
+ });
93
+
94
+ this.Then(/^the AllowedOrigin value should equal "([^"]*)"$/, function(value, callback) {
95
+ this.assert.equal(this.data.CORSRules[0].AllowedOrigins[0], value);
96
+ callback();
97
+ });
98
+
99
+ this.Then(/^the AllowedHeader value should equal "([^"]*)"$/, function(value, callback) {
100
+ this.assert.equal(this.data.CORSRules[0].AllowedHeaders[0], value);
101
+ callback();
102
+ });
103
+
104
+ this.Then(/^the ExposeHeader value should equal "([^"]*)"$/, function(value, callback) {
105
+ this.assert.equal(this.data.CORSRules[0].ExposeHeaders[0], value);
106
+ callback();
107
+ });
108
+
109
+ this.Then(/^the MaxAgeSeconds value should equal (\d+)$/, function(value, callback) {
110
+ this.assert.equal(this.data.CORSRules[0].MaxAgeSeconds, parseInt(value));
111
+ callback();
112
+ });
113
+
114
+ this.When(/^I put a bucket tag with key "([^"]*)" and value "([^"]*)"$/, function(key, value, callback) {
115
+ var params = {
116
+ Bucket: this.bucket,
117
+ Tagging: {
118
+ TagSet: [
119
+ {Key: key, Value: value}
120
+ ]
121
+ }
122
+ };
123
+
124
+ this.request('s3', 'putBucketTagging', params, callback);
125
+ });
126
+
127
+ this.When(/^I get the bucket tagging$/, function(callback) {
128
+ this.request('s3', 'getBucketTagging', {Bucket: this.bucket}, callback);
129
+ });
130
+
131
+ this.Then(/^the first tag in the tag set should have key and value "([^"]*)", "([^"]*)"$/, function(key, value, callback) {
132
+ this.assert.equal(this.data.TagSet[0].Key, key);
133
+ this.assert.equal(this.data.TagSet[0].Value, value);
134
+ callback();
135
+ });
136
+ };
@@ -0,0 +1,39 @@
1
+ module.exports = function () {
2
+
3
+ function cleanBucket(world, bucket, callback) {
4
+ if (!bucket) { callback(); return; }
5
+
6
+ var params = {Bucket: bucket};
7
+ var deleteBucket = function() {
8
+ delete params.Delete;
9
+ world.request('s3', 'deleteBucket', params, callback, false);
10
+ }
11
+
12
+ world.s3.listObjects(params, function (err, data) {
13
+ if (err) { deleteBucket(); return; }
14
+ if (data.Contents.length > 0) {
15
+ params.Delete = { Objects: [] };
16
+ world.AWS.util.arrayEach(data.Contents, function (item) {
17
+ params.Delete.Objects.push({Key: item.Key});
18
+ });
19
+ world.request('s3', 'deleteObjects', params, deleteBucket);
20
+ } else {
21
+ deleteBucket();
22
+ }
23
+ });
24
+ }
25
+
26
+ this.Before("@s3", function (callback) {
27
+ this.service = this.s3 = new this.AWS.S3({maxRetries: 100});
28
+ callback();
29
+ });
30
+
31
+ this.After("@s3", function (callback) {
32
+ cleanBucket(this, this.bucket, callback);
33
+ });
34
+
35
+ this.AfterAll(function(callback) {
36
+ cleanBucket(this, this.sharedBucket, callback);
37
+ });
38
+
39
+ };
@@ -0,0 +1,204 @@
1
+ module.exports = function () {
2
+ /**
3
+ * Create a single bucket that will be shared by all s3 object scenarios.
4
+ */
5
+ this.Before("@s3", "@objects", function (callback) {
6
+
7
+ // execute only once
8
+ if (this.sharedBucket) {
9
+ callback();
10
+ return;
11
+ }
12
+
13
+ this.sharedBucket = this.uniqueName('aws-sdk-js-integration');
14
+ this.s3.createBucket({Bucket:this.sharedBucket}, function(err, data) {
15
+ callback();
16
+ });
17
+ });
18
+
19
+ this.When(/^I write (buffer )?"([^"]*)" to the key "([^"]*)"$/, function(buffer, contents, key, next) {
20
+ var params = {Bucket: this.sharedBucket, Key: key, Body: buffer ? new Buffer(contents) : contents};
21
+ this.request('s3', 'putObject', params, next);
22
+ });
23
+
24
+ this.When(/^I write (buffer )?"([^"]*)" to the invalid key "([^"]*)"$/, function(buffer, contents, key, next) {
25
+ var params = {Bucket: this.sharedBucket, Key: key, Body: buffer ? new Buffer(contents) : contents};
26
+ this.request('s3', 'putObject', params, next, false);
27
+ });
28
+
29
+ this.When(/^I write "([^"]*)" to the key "([^"]*)" with ContentLength (\d+)$/, function(contents, key, contentLength, next) {
30
+ var params = {Bucket: this.sharedBucket, Key: key, Body: contents, ContentLength: parseInt(contentLength)};
31
+ this.s3nochecksums = new this.AWS.S3({computeChecksums: false});
32
+ this.request('s3nochecksums', 'putObject', params, next);
33
+ });
34
+
35
+ this.When(/^I write empty buffer to the key "([^"]*)"$/, function (key, next) {
36
+ var params = {Bucket: this.sharedBucket, Key: key, Body: new Buffer(0)};
37
+ this.request('s3', 'putObject', params, next);
38
+ });
39
+
40
+ this.Then(/^the object with the key "([^"]*)" should contain "([^"]*)"$/, function(key, contents, next) {
41
+ this.assert.equal(this.data.Body.toString().replace("\n", ""), contents);
42
+ next();
43
+ });
44
+
45
+ this.When(/^I copy an object with the key "([^"]*)" to "([^"]*)"$/, function(key1, key2, next) {
46
+ var params = {
47
+ Bucket: this.sharedBucket, Key: key2, CopySource: '/' + this.sharedBucket + '/' + key1
48
+ }
49
+ this.request('s3', 'copyObject', params, next);
50
+ });
51
+
52
+ this.When(/^I delete the object with the key "([^"]*)"$/, function(key, next) {
53
+ var params = {Bucket:this.sharedBucket,Key:key};
54
+ this.request('s3', 'deleteObject', params, next);
55
+ });
56
+
57
+ this.Then(/^the object with the key "([^"]*)" should (not )?exist$/, function(key, shouldNotExist, next) {
58
+ var params = { Bucket:this.sharedBucket, Key:key };
59
+ this.eventually(next, function (retry) {
60
+ retry.condition = function() {
61
+ if (shouldNotExist) {
62
+ return this.error && this.error.code == 'NoSuchKey';
63
+ } else {
64
+ return !this.error;
65
+ }
66
+ };
67
+ this.request('s3', 'getObject', params, retry, false);
68
+ });
69
+ });
70
+
71
+ this.When(/^I write file "([^"]*)" to the key "([^"]*)"$/, function(filename, key, next) {
72
+ var fs = require('fs');
73
+ var params = {Bucket: this.sharedBucket, Key: key, Body:
74
+ fs.createReadStream(__dirname + '/../../extra/fixtures/' + filename)};
75
+ this.request('s3', 'putObject', params, next);
76
+ });
77
+
78
+ this.When(/^I stream key "([^"]*)"$/, function(key, callback) {
79
+ var params = {Bucket: this.sharedBucket, Key: key};
80
+ var world = this;
81
+ this.result = '';
82
+ this.service.getObject(params).createReadStream().
83
+ on('end', function() { callback(); }).
84
+ on('data', function(d) { world.result += d.toString(); });
85
+ });
86
+
87
+ this.When(/^I stream2 key "([^"]*)"$/, function(key, callback) {
88
+ if (!require('stream').Readable) return callback();
89
+ var params = {Bucket: this.sharedBucket, Key: key};
90
+ var world = this;
91
+ this.result = '';
92
+ var stream = this.service.getObject(params).createReadStream();
93
+ stream.on('end', function() { callback(); });
94
+ stream.on('readable', function() {
95
+ var v = stream.read(); if (v) world.result += v;
96
+ });
97
+ });
98
+
99
+ this.Then(/^the streamed data should contain "([^"]*)"$/, function(data, callback) {
100
+ this.assert.equal(this.result.replace('\n', ''), data);
101
+ callback();
102
+ });
103
+
104
+ this.When(/^I get a pre\-signed URL to GET the key "([^"]*)"$/, function(key, callback) {
105
+ this.signedUrl = this.s3.getSignedUrl('getObject', {Bucket: this.sharedBucket, Key: key});
106
+ callback();
107
+ });
108
+
109
+ this.When(/^I access the URL via HTTP GET$/, function(callback, verb) {
110
+ var world = this;
111
+ this.data = '';
112
+ require('https').get(this.signedUrl, function (res) {
113
+ res.on('data', function (chunk) {
114
+ world.data += chunk.toString();
115
+ }).on('end', callback);
116
+ }).on('error', callback.fail);
117
+ });
118
+
119
+ this.Given(/^I get a pre\-signed URL to PUT the key "([^"]*)"(?: with data "([^"]*)")?$/, function(key, body, callback) {
120
+ var params = {Bucket: this.sharedBucket, Key: key};
121
+ if (body) params.Body = body;
122
+ this.signedUrl = this.s3.getSignedUrl('putObject', params);
123
+ callback();
124
+ });
125
+
126
+ this.Given(/^I access the URL via HTTP PUT with data "([^"]*)"$/, function(body, callback) {
127
+ var world = this;
128
+ this.data = '';
129
+
130
+ var data = body;
131
+ var options = require('url').parse(this.signedUrl);
132
+ options.method = 'PUT';
133
+ options.headers = {'Content-Length': data.length};
134
+
135
+ var req = require('https').request(options, function (res) {
136
+ res.on('data', function (chunk) {
137
+ world.data += chunk.toString();
138
+ }).on('end', callback);
139
+ }).on('error', callback.fail).end(data);
140
+ });
141
+
142
+ this.Then(/^the HTTP response should equal "([^"]*)"$/, function(data, callback) {
143
+ this.assert.equal(this.data, data);
144
+ callback();
145
+ });
146
+
147
+ this.Then(/^the HTTP response should contain "([^"]*)"$/, function(data, callback) {
148
+ this.assert.match(this.data, data);
149
+ callback();
150
+ });
151
+
152
+ this.Given(/^I setup the listObjects request for the bucket$/, function(callback) {
153
+ this.params = { Bucket: this.sharedBucket };
154
+ callback();
155
+ });
156
+
157
+ // progress events
158
+
159
+ this.When(/^I write a (\d+)KB buffer to the key "([^"]*)" with progress events$/, function(kb, key, callback) {
160
+ var self = this;
161
+ var body = new Buffer(new Array(kb * 1024 + 1).join('x'));
162
+ this.progress = [];
163
+ var req = this.s3.putObject({Bucket: this.sharedBucket, Key: key, Body: body});
164
+ req.on('httpUploadProgress', function (p) { self.progress.push(p) });
165
+ req.send(callback);
166
+ });
167
+
168
+ this.Then(/^more than (\d+) "([^"]*)" event should fire$/, function(numEvents, eventName, callback) {
169
+ this.assert.compare(this.progress.length, '>', numEvents);
170
+ callback();
171
+ });
172
+
173
+ this.Then(/^the "([^"]*)" value of the progress event should equal (\d+)KB$/, function(prop, kb, callback) {
174
+ this.assert.equal(this.progress[0][prop], kb * 1024);
175
+ callback();
176
+ });
177
+
178
+ this.Then(/^the "([^"]*)" value of the first progress event should be greater than (\d+) bytes$/, function(prop, bytes, callback) {
179
+ this.assert.compare(this.progress[0][prop], '>', bytes);
180
+ callback();
181
+ });
182
+
183
+ this.When(/^I read the key "([^"]*)" with progress events$/, function(key, callback) {
184
+ var self = this;
185
+ this.progress = [];
186
+ var req = this.s3.getObject({Bucket: this.sharedBucket, Key: key});
187
+ req.on('httpDownloadProgress', function (p) { self.progress.push(p) });
188
+ req.send(callback);
189
+ });
190
+
191
+ this.When(/^I write "([^"]*)" to the public key "([^"]*)"$/, function(data, key, next) {
192
+ var params = {Bucket: this.sharedBucket, Key: key, Body: data, ACL: 'public-read'};
193
+ this.request('s3', 'putObject', params, next);
194
+ });
195
+
196
+ this.Then(/^the unauthenticated request to read key "([^"]*)" should equal "([^"]*)"$/, function(key, body, next) {
197
+ var params = {Bucket: this.sharedBucket, Key: key};
198
+ this.s3.makeUnauthenticatedRequest('getObject', params, function (err, data) {
199
+ if (err) return next(err);
200
+ this.assert.equal(data.Body.toString(), body);
201
+ next();
202
+ }.bind(this));
203
+ });
204
+ };
@@ -0,0 +1,44 @@
1
+ var url = require('url');
2
+ var http = require('http');
3
+
4
+ module.exports = function() {
5
+ this.Before("@s3", "@proxy", function(callback) {
6
+ setupProxyServer.call(this);
7
+
8
+ this.service = this.s3 = new this.AWS.S3({
9
+ httpOptions: { proxy: 'http://localhost:' + this.proxyPort }
10
+ });
11
+
12
+ callback();
13
+ });
14
+
15
+ this.Then(/^I teardown the local proxy server$/, function(callback) {
16
+ this.service = this.s3 = new this.AWS.S3();
17
+ this.proxyServer.close(callback);
18
+ });
19
+
20
+ function setupProxyServer() {
21
+ if (this.proxyServer) return;
22
+ this.proxyPort = 8000 + parseInt(Math.random() * 100);
23
+ this.proxyServer = http.createServer(function (req, res) {
24
+ var uri = url.parse(req.url);
25
+ var options = {
26
+ host: uri.hostname,
27
+ port: uri.port || 80,
28
+ method: req.method,
29
+ path: uri.path,
30
+ headers: req.headers
31
+ };
32
+ options.headers.host = uri.hostname;
33
+
34
+ var s = http.request(options, function (res2) {
35
+ res.writeHead(res2.statusCode, res2.headers);
36
+ res2.on('data', function(ch) {
37
+ res.write(ch);
38
+ }).on('end', function() { res.end(); });
39
+ });
40
+ req.pipe(s);
41
+ });
42
+ this.proxyServer.listen(this.proxyPort);
43
+ }
44
+ };
@@ -0,0 +1,20 @@
1
+ # language: en
2
+ @ses
3
+ Feature: SES
4
+
5
+ I want to use Simple Email Service.
6
+
7
+ Scenario: Check quota
8
+ When I check quota
9
+ Then the result should include number "SentLast24Hours"
10
+ And the result should include number "MaxSendRate"
11
+
12
+ Scenario: Verify email
13
+ When I ask to verify the email address "foo@example.com"
14
+ Then the status code should be 200
15
+
16
+ Scenario: Rescue SES InvalidParameterValue
17
+ When I ask to verify the email address "abc123"
18
+ Then I should get the error:
19
+ | code | message |
20
+ | InvalidParameterValue | Invalid email address<abc123>. |
@@ -0,0 +1,22 @@
1
+ module.exports = function() {
2
+ this.Before("@ses", function (callback) {
3
+ this.service = new this.AWS.SES();
4
+ callback();
5
+ });
6
+
7
+ this.When(/^I check quota$/, function(next) {
8
+ this.request(null, 'getSendQuota', {}, next);
9
+ });
10
+
11
+ this.Then(/^the result should include (\S+) "([^"]*)"$/, function(type, attr, next) {
12
+ if (this.data[attr] === undefined) next.fail("Missing " + attr);
13
+ if (typeof this.data[attr] !== type) next.fail("Incorrect type " + attr);
14
+ next();
15
+ });
16
+
17
+ this.When(/^I ask to verify the email address "([^"]*)"$/, function(email, next) {
18
+ this.request(null, 'verifyEmailAddress', {EmailAddress: email}, next, function() {
19
+ // do nothing
20
+ });
21
+ });
22
+ };
@@ -0,0 +1,29 @@
1
+ # language: en
2
+ @simpledb
3
+ Feature: Amazon SimpleDB
4
+
5
+ I want to use Amazon SimpleDB
6
+
7
+ Scenario: CRUD
8
+ Given I create a SimpleDB domain
9
+ And I put an item "key" with attributes:
10
+ """
11
+ [{"Name": "attr1", "Value": "value1"}]
12
+ """
13
+ And I get the item "key"
14
+ Then the result should have attribute "attr1" with "value1"
15
+ And I delete the domain
16
+
17
+ Scenario: SELECT * statements
18
+ Given I create a SimpleDB domain
19
+ And I put an item "key" with attributes:
20
+ """
21
+ [{"Name": "attr1", "Value": "value1"}]
22
+ """
23
+ And I select "*" from the domain
24
+ Then the select result should contain the item
25
+ And I delete the domain
26
+
27
+ Scenario: Error handling
28
+ Given I create a domain with no name
29
+ Then the error code should be "InvalidParameterValue"
@@ -0,0 +1,46 @@
1
+ module.exports = function() {
2
+ this.Before("@simpledb", function (callback) {
3
+ this.service = new this.AWS.SimpleDB();
4
+ this.domainName = 'aws-sdk-js-integration-' + new Date().getTime();
5
+ callback();
6
+ });
7
+
8
+ this.Given(/^I create a SimpleDB domain$/, function(callback) {
9
+ this.request(null, 'createDomain', {DomainName: this.domainName}, callback);
10
+ });
11
+
12
+ this.Given(/^I put an item "([^"]*)" with attributes:$/, function(item, string, callback) {
13
+ this.item = {Name: item, Attributes: JSON.parse(string)};
14
+ var params = {DomainName: this.domainName, ItemName: item, Attributes: this.item.Attributes};
15
+ this.request(null, 'putAttributes', params, callback);
16
+ });
17
+
18
+ this.Given(/^I get the item "([^"]*)"$/, function(item, callback) {
19
+ var params = {DomainName: this.domainName, ItemName: item, ConsistentRead: true};
20
+ this.request(null, 'getAttributes', params, callback);
21
+ });
22
+
23
+ this.Given(/^I select "([^"]*)" from the domain$/, function(expr, callback) {
24
+ var params = {SelectExpression: 'SELECT ' + expr + ' FROM `' + this.domainName + '`', ConsistentRead: true};
25
+ this.request(null, 'select', params, callback);
26
+ });
27
+
28
+ this.Then(/^the select result should contain the item$/, function(callback) {
29
+ this.assert.deepEqual(this.data.Items, [this.item]);
30
+ callback();
31
+ });
32
+
33
+ this.Then(/^the result should have attribute "([^"]*)" with "([^"]*)"$/, function(name, value, callback) {
34
+ this.assert.equal(this.data.Attributes[0].Name, name);
35
+ this.assert.equal(this.data.Attributes[0].Value, value);
36
+ callback();
37
+ });
38
+
39
+ this.Then(/^I delete the domain$/, function(callback) {
40
+ this.request(null, 'deleteDomain', {DomainName: this.domainName}, callback);
41
+ });
42
+
43
+ this.Given(/^I create a domain with no name$/, function(callback) {
44
+ this.request(null, 'createDomain', {DomainName: ''}, callback, false);
45
+ });
46
+ };
@@ -0,0 +1,15 @@
1
+ # language: en
2
+ @sns
3
+ Feature: Simple Notification Service
4
+
5
+ I want to use Amazon Simple Notification Service
6
+
7
+ Scenario: Topics
8
+ Given I create an SNS topic with name "aws-js-sdk-integration-topic"
9
+ And I list the SNS topics
10
+ Then the list should contain the topic ARN
11
+ And I delete the SNS topic
12
+
13
+ Scenario: Error handling
14
+ Given I get SNS topic attributes with an invalid ARN
15
+ Then the error code should be "InvalidParameter"