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,316 @@
1
+ helpers = require('./helpers')
2
+ EventEmitter = require('events').EventEmitter
3
+ AWS = helpers.AWS
4
+ MockService = helpers.MockService
5
+ Buffer = AWS.util.Buffer
6
+
7
+ describe 'AWS.Request', ->
8
+ service = null
9
+ beforeEach ->
10
+ service = new MockService
11
+
12
+ describe 'error handling', ->
13
+ it 'throws errors out of callback', ->
14
+ helpers.mockHttpResponse 200, {}, ''
15
+ expect(->
16
+ service.makeRequest 'mockMethod', ->
17
+ throw new Error('error')
18
+ ).toThrow('error')
19
+
20
+ for evt in ['error', 'success', 'complete']
21
+ it 'throws errors out of terminal ' + evt + ' event', ->
22
+ helpers.mockHttpResponse 200, {}, ''
23
+ expect(->
24
+ req = service.makeRequest('mockMethod')
25
+ req.on evt, -> throw new Error('error')
26
+ req.send()
27
+ ).toThrow('error')
28
+
29
+ it 'propagates errors to error event', ->
30
+ helpers.mockHttpResponse 200, {}, ''
31
+ err = null
32
+ expect(->
33
+ req = service.makeRequest('mockMethod')
34
+ req.on 'extractData', -> throw new Error('error')
35
+ req.send((e) -> err = e)
36
+ ).not.toThrow('error')
37
+ expect(err.message).toEqual('error')
38
+
39
+ describe 'isPageable', ->
40
+ beforeEach ->
41
+ service = new AWS.Service apiConfig: new AWS.Model.Api
42
+ operations: mockMethod: {}
43
+
44
+ it 'is pageable if it has a pagination config for the operation', ->
45
+ service.api.paginators['mockMethod'] = new AWS.Model.Paginator('mockMethod', limit_key: 'Marker')
46
+
47
+ request = service.makeRequest('mockMethod')
48
+ expect(request.isPageable()).toEqual(true)
49
+
50
+ it 'is not pageable if the pagination config does not exist for the operation', ->
51
+ expect(service.makeRequest('mockMethod').isPageable()).toEqual(false)
52
+
53
+ describe 'eachPage', ->
54
+ beforeEach ->
55
+ service = new AWS.Service apiConfig: new AWS.Model.Api
56
+ operations:
57
+ mockMethod:
58
+ input:
59
+ type: 'structure'
60
+ members:
61
+ NextToken: type: 'string'
62
+ output:
63
+ type: 'structure'
64
+ members:
65
+ NextToken: type: 'string'
66
+ Value: type: 'integer'
67
+ paginators:
68
+ mockMethod:
69
+ input_token: 'NextToken'
70
+ output_token: 'NextToken'
71
+
72
+ helpers.mockResponses service, [
73
+ {data: {Value: 1, NextToken: 'a'}},
74
+ {data: {Value: 2, NextToken: 'b'}},
75
+ {data: {Value: 3, NextToken: 'c'}},
76
+ {data: {Value: 4}}
77
+ ]
78
+
79
+ it 'can page multiple responses', ->
80
+ resps = []
81
+ runs ->
82
+ service.mockMethod().eachPage (err, data) ->
83
+ resps.push([err, data])
84
+ waitsFor -> resps.length > 3
85
+ runs ->
86
+ expect(resps).toEqual [
87
+ [null, {Value: 1, NextToken: 'a'}],
88
+ [null, {Value: 2, NextToken: 'b'}],
89
+ [null, {Value: 3, NextToken: 'c'}],
90
+ [null, {Value: 4}],
91
+ [null, null]
92
+ ]
93
+
94
+ it 'supports stopping responses if false is returned', ->
95
+ resps = []
96
+ runs ->
97
+ service.mockMethod().eachPage (err, data) ->
98
+ if resps.length == 2
99
+ return false
100
+ resps.push([err, data])
101
+ true
102
+ waitsFor -> resps.length == 2
103
+ runs ->
104
+ expect(resps).toEqual [
105
+ [null, {Value: 1, NextToken: 'a'}],
106
+ [null, {Value: 2, NextToken: 'b'}]
107
+ ]
108
+
109
+ it 'supports asynchronous eachPage calls', ->
110
+ resps = []
111
+ runs ->
112
+ service.mockMethod().eachPage (err, data, done) ->
113
+ process.nextTick ->
114
+ resps.push([err, data])
115
+ done()
116
+ waitsFor -> resps.length > 3
117
+ runs ->
118
+ expect(resps).toEqual [
119
+ [null, {Value: 1, NextToken: 'a'}],
120
+ [null, {Value: 2, NextToken: 'b'}],
121
+ [null, {Value: 3, NextToken: 'c'}],
122
+ [null, {Value: 4}],
123
+ [null, null]
124
+ ]
125
+
126
+ it 'throws error from eachPage callback', ->
127
+ try
128
+ service.mockMethod().eachPage -> invalidCode
129
+ catch e
130
+ expect(e.name).toEqual('ReferenceError')
131
+
132
+ describe 'waitFor', ->
133
+ it 'creates a ResourceWaiter object', ->
134
+ service.api.waiters = state: operation: 'mockMethod'
135
+ service.waitFor('state')
136
+
137
+ describe 'send', ->
138
+ it 'accepts an optional callback', ->
139
+ error = null; data = null
140
+ helpers.mockHttpResponse 200, {}, ['FOO', 'BAR', 'BAZ', 'QUX']
141
+ runs ->
142
+ service.makeRequest('mockMethod').send (e, d) -> data = d
143
+ waitsFor -> data
144
+ runs ->
145
+ expect(data).toEqual('FOOBARBAZQUX')
146
+
147
+ describe 'abort', ->
148
+ it 'allows aborting requests', ->
149
+ error = null; data = null; done = null
150
+ helpers.mockHttpResponse 200, {}, ['FOO', 'BAR', 'BAZ', 'QUX']
151
+ runs ->
152
+ req = service.makeRequest('mockMethod')
153
+ req.on 'send', (resp) -> req.abort()
154
+ req.send (e, d) -> done = true; error = e; data = d
155
+ waitsFor -> done
156
+ runs ->
157
+ expect(data).toEqual(null)
158
+ expect(error.code).toEqual('RequestAbortedError')
159
+ expect(error.message).toMatch(/aborted by user/)
160
+
161
+ if AWS.util.isNode()
162
+ describe 'createReadStream', ->
163
+ it 'streams data', ->
164
+ data = ''; done = false
165
+ helpers.mockHttpResponse 200, {}, ['FOO', 'BAR', 'BAZ', 'QUX']
166
+
167
+ runs ->
168
+ request = service.makeRequest('mockMethod')
169
+ s = request.createReadStream()
170
+ s.on 'end', -> done = true
171
+ s.on 'data', (c) -> data += c.toString()
172
+ waitsFor -> done == true
173
+ runs ->
174
+ expect(data).toEqual('FOOBARBAZQUX')
175
+
176
+ it 'streams2 data (readable event)', ->
177
+ if AWS.HttpClient.streamsApiVersion < 2
178
+ return
179
+
180
+ data = ''; done = false
181
+ helpers.mockHttpResponse 200, {}, ['FOO', 'BAR', 'BAZ', 'QUX']
182
+
183
+ runs ->
184
+ request = service.makeRequest('mockMethod')
185
+ s = request.createReadStream()
186
+ s.on 'end', -> done = true
187
+ s.on 'readable', ->
188
+ try
189
+ chunk = s.read()
190
+ if chunk
191
+ data += chunk
192
+ catch e
193
+ console.log(e.stack)
194
+
195
+ waitsFor -> done == true
196
+ runs ->
197
+ expect(data).toEqual('FOOBARBAZQUX')
198
+
199
+ it 'streams2 data does not hang out while waiting response', ->
200
+ if AWS.HttpClient.streamsApiVersion < 2
201
+ return
202
+
203
+ data = ''; done = false
204
+ helpers.mockHttpResponse 200, {}, ['FOO', 'BAR', null, null, 'BAZ', 'QUX']
205
+
206
+ runs ->
207
+ request = service.makeRequest('mockMethod')
208
+ s = request.createReadStream()
209
+ s.on 'end', -> done = true
210
+ s.on 'readable', ->
211
+ try
212
+ chunk = s.read()
213
+ if chunk
214
+ data += chunk
215
+ catch e
216
+ console.log(e.stack)
217
+
218
+ waitsFor -> done == true
219
+ runs ->
220
+ expect(data).toEqual('FOOBARBAZQUX')
221
+
222
+ it 'does not stream data on failures', ->
223
+ data = ''; error = null; done = false
224
+ helpers.mockHttpResponse 404, {}, ['No such file']
225
+
226
+ runs ->
227
+ request = service.makeRequest('mockMethod')
228
+ s = request.createReadStream()
229
+ s.on 'end', -> done = true
230
+ s.on 'error', (e) -> error = e; done = true
231
+ s.on 'data', (c) -> data += c.toString()
232
+ waitsFor -> done == true
233
+ runs ->
234
+ expect(data).toEqual('')
235
+ expect(error.statusCode).toEqual(404)
236
+
237
+ it 'retries temporal errors and streams resulting successful response', ->
238
+ data = ''; error = null; done = false
239
+ helpers.mockIntermittentFailureResponse 2, 200, {}, ['FOO', 'BAR', 'BAZ', 'QUX']
240
+
241
+ runs ->
242
+ request = service.makeRequest('mockMethod')
243
+ s = request.createReadStream()
244
+ s.on 'end', -> done = true
245
+ s.on 'error', (e) -> error = e; done = true
246
+ s.on 'data', (c) -> data += c.toString()
247
+ waitsFor -> done == true
248
+ runs ->
249
+ expect(data).toEqual('FOOBARBAZQUX')
250
+ expect(error).toEqual(null)
251
+
252
+ it 'streams partial data and raises an error', ->
253
+ data = ''; error = null; reqError = null; done = false
254
+ spyOn(AWS.HttpClient, 'getInstance')
255
+ AWS.HttpClient.getInstance.andReturn handleRequest: (req, opts, cb, errCb) ->
256
+ req = new EventEmitter()
257
+ req.statusCode = 200
258
+ req.headers = {}
259
+ cb(req)
260
+ req.emit('headers', 200, {})
261
+ AWS.util.arrayEach ['FOO', 'BAR', 'BAZ'], (str) ->
262
+ req.emit 'data', new Buffer(str)
263
+ errCb new Error('fail')
264
+ req
265
+
266
+ runs ->
267
+ request = service.makeRequest('mockMethod')
268
+ request.on 'error', (e) -> reqError = e
269
+ request.on 'complete', -> done = true
270
+ s = request.createReadStream()
271
+ s.on 'error', (e) -> error = e
272
+ s.on 'data', (c) -> data += c.toString()
273
+ waitsFor -> done == true
274
+ runs ->
275
+ expect(data).toEqual('FOOBARBAZ')
276
+ expect(error.message).toEqual('fail')
277
+ expect(reqError.message).toEqual('fail')
278
+
279
+ it 'fails if retry occurs in the middle of a failing stream', ->
280
+ data = ''; error = null; reqError = null; resp = null
281
+ retryCount = 0
282
+ spyOn(AWS.HttpClient, 'getInstance')
283
+ AWS.HttpClient.getInstance.andReturn handleRequest: (req, opts, cb, errCb) ->
284
+ req = new EventEmitter()
285
+ req.statusCode = 200
286
+ req.headers = {}
287
+ process.nextTick ->
288
+ cb(req)
289
+ req.emit('headers', 200, {})
290
+ AWS.util.arrayEach ['FOO', 'BAR', 'BAZ', 'QUX'], (str) ->
291
+ if str == 'BAZ' and retryCount < 1
292
+ process.nextTick ->
293
+ retryCount += 1
294
+ errCb code: 'NetworkingError', message: 'FAIL!', retryable: true
295
+ return AWS.util.abort
296
+ else
297
+ process.nextTick -> req.emit 'data', new Buffer(str)
298
+ if retryCount >= 1
299
+ process.nextTick -> req.emit('end')
300
+ req
301
+
302
+ runs ->
303
+ request = service.makeRequest('mockMethod')
304
+ request.on 'error', (e) -> reqError = e
305
+ request.on 'complete', (r) -> resp = r
306
+ s = request.createReadStream()
307
+ s.on 'error', (e) -> error = e
308
+ s.on 'data', (c) -> data += c.toString()
309
+ waitsFor -> resp != null
310
+ runs ->
311
+ expect(data).toEqual('FOOBAR')
312
+ expect(error.code).toEqual('NetworkingError')
313
+ expect(reqError.code).toEqual('NetworkingError')
314
+ expect(reqError.hostname).toEqual('mockservice.mock-region.amazonaws.com')
315
+ expect(reqError.region).toEqual('mock-region')
316
+ expect(resp.retryCount).toEqual(0)
@@ -0,0 +1,89 @@
1
+ helpers = require('./helpers')
2
+ AWS = helpers.AWS
3
+
4
+ describe 'AWS.ResourceWaiter', ->
5
+ describe 'wait', ->
6
+ it 'waits until a given state is met', ->
7
+ err = null; data = null; resp = null
8
+ db = new AWS.DynamoDB
9
+ helpers.mockResponses db, [
10
+ {data: {Table: TableStatus: 'LOADING'}},
11
+ {data: {Table: TableStatus: 'LOADING'}},
12
+ {data: {Table: TableStatus: 'ACTIVE'}}
13
+ ]
14
+
15
+ waiter = new AWS.ResourceWaiter(db, 'tableExists')
16
+ waiter.wait (e, d) -> resp = this; err = e; data = d
17
+ expect(err).toEqual(null)
18
+ expect(data.Table.TableStatus).toEqual('ACTIVE')
19
+ expect(resp.retryCount).toEqual(2)
20
+
21
+ it 'can override the final state', ->
22
+ err = null; data = null; resp = null
23
+ db = new AWS.DynamoDB
24
+ helpers.mockResponses db, [
25
+ {data: {Table: TableStatus: 'LOADING'}},
26
+ {data: {Table: TableStatus: 'LOADING'}},
27
+ {data: {Table: TableStatus: 'ACTIVE'}},
28
+ {data: {Table: TableStatus: 'FOO'}}
29
+ ]
30
+
31
+ waiter = new AWS.ResourceWaiter(db, {tableExists: 'FOO'})
32
+ waiter.wait (e, d) -> resp = this; err = e; data = d
33
+ expect(err).toEqual(null)
34
+ expect(data.Table.TableStatus).toEqual('FOO')
35
+ expect(resp.retryCount).toEqual(3)
36
+
37
+ it 'throws an error if terminal state is not configured', ->
38
+ try
39
+ new AWS.ResourceWaiter(new AWS.DynamoDB, 'invalidState')
40
+ catch e
41
+ err = e
42
+ expect(err.message).toEqual('State invalidState not found.')
43
+
44
+ it 'gives up after a maximum number of retries', ->
45
+ err = null; data = null; resp = null
46
+ db = new AWS.DynamoDB
47
+ resps = ({data: {Table: {TableStatus: 'LOADING'}}} for _ in [1..26])
48
+ resps.push({data: {Table: {TableStatus: 'ACTIVE'}}})
49
+ helpers.mockResponses db, resps
50
+
51
+ waiter = new AWS.ResourceWaiter(db, 'tableExists')
52
+ waiter.wait (e, d) -> resp = this; err = e; data = d
53
+ expect(data).toEqual(null)
54
+ expect(err.code).toEqual('ResourceNotReady')
55
+ expect(resp.retryCount).toEqual(25) # 25 max retries
56
+ expect(resp.error.retryDelay).toEqual(20000) # 20s delay
57
+
58
+ it 'accepts error state as a terminal state', ->
59
+ err = null; data = null; resp = null
60
+ s3 = new AWS.S3
61
+ helpers.mockResponses s3, [
62
+ {httpResponse: {statusCode: 200}},
63
+ {httpResponse: {statusCode: 200}},
64
+ {httpResponse: {statusCode: 404}}
65
+ ]
66
+
67
+ waiter = new AWS.ResourceWaiter(s3, 'bucketNotExists')
68
+ waiter.wait Bucket: 'bucket', (e, d) -> resp = this; err = e; data = d
69
+ expect(err).toEqual(null)
70
+ expect(resp.httpResponse.statusCode).toEqual(404)
71
+ expect(resp.retryCount).toEqual(3)
72
+
73
+ it 'fails fast if failure value is found', ->
74
+ err = null; data = null; resp = null
75
+ ec2 = new AWS.EC2
76
+ helpers.mockResponses ec2, [
77
+ {data: {Reservations: [{Instances: [{State: {Name: 'pending'}}]}]}},
78
+ {data: {Reservations: [{Instances: [{State: {Name: 'pending'}}]}]}},
79
+ {data: {Reservations: [{Instances: [{State: {Name: 'pending'}}]}]}},
80
+ {data: {Reservations: [{Instances: [{State: {Name: 'terminated'}}]}]}},
81
+ {data: {Reservations: [{Instances: [{State: {Name: 'pending'}}]}]}},
82
+ {data: {Reservations: [{Instances: [{State: {Name: 'running'}}]}]}}
83
+ ]
84
+
85
+ waiter = new AWS.ResourceWaiter(ec2, 'instanceRunning')
86
+ waiter.wait InstanceIds: ['id-123456'], (e, d) -> resp = this; err = e; data = d
87
+ expect(data).toEqual(null)
88
+ expect(err.code).toEqual('ResourceNotReady')
89
+ expect(resp.retryCount).toEqual(3)
@@ -0,0 +1,81 @@
1
+ helpers = require('./helpers')
2
+ EventEmitter = require('events').EventEmitter
3
+ AWS = helpers.AWS
4
+
5
+ describe 'AWS.Response', ->
6
+ service = null; response = null
7
+
8
+ beforeEach ->
9
+ service = new AWS.Service apiConfig: new AWS.Model.Api operations: op: {}
10
+ response = new AWS.Response(service.makeRequest('op'))
11
+
12
+ makePageable = ->
13
+ service.api.paginators.op = new AWS.Model.Paginator 'op',
14
+ limit_key: 'Limit'
15
+ input_token: 'Marker'
16
+ output_token: 'Marker'
17
+ result_key: 'Result'
18
+
19
+ fill = (err, data, pageable) ->
20
+ makePageable() if pageable
21
+ response.error = err
22
+ response.data = data
23
+
24
+ describe 'hasNextPage', ->
25
+ it 'returns undefined if the request is not pageable', ->
26
+ fill(null, Marker: 'next_page')
27
+ expect(response.hasNextPage()).toEqual(undefined)
28
+
29
+ it 'returns false if there is no marker in the response', ->
30
+ fill(null, {}, true)
31
+ expect(response.hasNextPage()).toEqual(false)
32
+
33
+ it 'returns false if the response returned an error', ->
34
+ fill(new Error, null, true)
35
+ expect(response.hasNextPage()).toEqual(false)
36
+
37
+ it 'returns true if there is a marker in the response', ->
38
+ fill(null, Marker: 'next_page', true)
39
+ expect(response.hasNextPage()).toEqual(true)
40
+
41
+ describe 'nextPage', ->
42
+ it 'throws an exception if the operation has no pagination information', ->
43
+ service.api.pagination = {}
44
+ expect(-> response.nextPage()).toThrow('No pagination configuration for op')
45
+
46
+ it 'returns null if there are no more pages', ->
47
+ fill(null, {}, true)
48
+ expect(response.nextPage()).toEqual(null)
49
+
50
+ it 'returns a request object with the next page marker filled in params', ->
51
+ fill(null, Marker: 'next_page', true)
52
+ req = response.nextPage()
53
+ expect(req.params.Marker).toEqual('next_page')
54
+ expect(req.operation).toEqual(response.request.operation)
55
+
56
+ it 'throws error if response returned an error and there is no callback', ->
57
+ fill(new Error('error!'), null, true)
58
+ expect(-> response.nextPage()).toThrow('error!')
59
+
60
+ it 'sends the request if passed with a callback', ->
61
+ err = null; data = null
62
+ helpers.mockHttpResponse 200, {}, ['']
63
+ fill(null, Marker: 'next_page', true)
64
+ runs ->
65
+ response.nextPage (e, d) -> err = e; data = d
66
+ waitsFor -> err || data
67
+ runs ->
68
+ expect(err).toEqual(null)
69
+ expect(data).toEqual({})
70
+
71
+ it 'passes null to callback if there are no more pages', ->
72
+ fill(null, {}, true)
73
+ response.nextPage (err, data) ->
74
+ expect(err).toEqual(null)
75
+ expect(data).toEqual(null)
76
+
77
+ it 'passes error through if original response returned an error', ->
78
+ fill('error!', null, true)
79
+ response.nextPage (err, data) ->
80
+ expect(err).toEqual('error!')
81
+ expect(data).toEqual(null)
@@ -0,0 +1,118 @@
1
+ helpers = require('./helpers')
2
+ AWS = helpers.AWS
3
+
4
+ describe 'AWS.SequentialExecutor', ->
5
+ beforeEach -> @emitter = new AWS.SequentialExecutor()
6
+
7
+ describe 'addListeners', ->
8
+ it 'accepts a hash of events and functions', ->
9
+ triggers = [0, 0, 0]
10
+ listeners =
11
+ eventName:
12
+ ConstantName1: -> triggers[0] = 1
13
+ ConstantName2: -> triggers[1] = 1
14
+ otherEventName:
15
+ ConstantName3: -> triggers[2] = 1
16
+
17
+ @emitter.addListeners(listeners)
18
+ expect(triggers).toEqual([0, 0, 0])
19
+
20
+ @emitter.emit('eventName')
21
+ expect(triggers).toEqual([1, 1, 0])
22
+
23
+ @emitter.emit('otherEventName')
24
+ expect(triggers).toEqual([1, 1, 1])
25
+
26
+ it 'accepts a SequentialExecutor object', ->
27
+ triggers = [0, 0, 0]
28
+ listeners = new AWS.SequentialExecutor()
29
+ listeners.on 'eventName', -> triggers[0] = 1
30
+ listeners.on 'eventName', -> triggers[1] = 1
31
+ listeners.on 'otherEventName', -> triggers[2] = 1
32
+
33
+ @emitter.addListeners(listeners)
34
+ expect(triggers).toEqual([0, 0, 0])
35
+
36
+ @emitter.emit('eventName')
37
+ expect(triggers).toEqual([1, 1, 0])
38
+
39
+ @emitter.emit('otherEventName')
40
+ expect(triggers).toEqual([1, 1, 1])
41
+
42
+ describe 'addNamedListener', ->
43
+ it 'defines a constant with the callback', ->
44
+ spy = jasmine.createSpy()
45
+ @emitter.addNamedListener('CONSTNAME', 'eventName', spy)
46
+ expect(@emitter.CONSTNAME).toBe(spy)
47
+
48
+ # also verify that event is hooked up like normal
49
+ @emitter.emit('eventName', ['argument'])
50
+ expect(spy).toHaveBeenCalledWith('argument')
51
+
52
+ it 'is chainable', ->
53
+ r = @emitter.addNamedListener('CONSTNAME', 'eventName', ->)
54
+ expect(r).toBe(@emitter)
55
+
56
+ describe 'addNamedListeners', ->
57
+ it 'is chainable', ->
58
+ r = @emitter.addNamedListeners(->)
59
+ expect(r).toBe(@emitter)
60
+
61
+ it 'provides an add function in callback to call addNamedListener', ->
62
+ spy1 = jasmine.createSpy(); spy2 = jasmine.createSpy()
63
+ @emitter.addNamedListeners (add) ->
64
+ add('CONST1', 'event1', spy1)
65
+ add('CONST2', 'event2', spy2)
66
+
67
+ expect(@emitter.CONST1).toBe(spy1)
68
+ expect(@emitter.CONST2).toBe(spy2)
69
+
70
+ @emitter.emit('event1', ['arg1'])
71
+ @emitter.emit('event2', ['arg2'])
72
+
73
+ expect(spy1).toHaveBeenCalledWith('arg1')
74
+ expect(spy2).toHaveBeenCalledWith('arg2')
75
+
76
+ describe 'emit', ->
77
+ it 'emits to all listeners', ->
78
+ list = []
79
+ @emitter.on 'event1', -> list.push(1)
80
+ @emitter.on 'event1', -> list.push(2)
81
+ @emitter.on 'event1', -> list.push(3)
82
+ @emitter.emit('event1')
83
+ expect(list).toEqual([1,2,3])
84
+
85
+ it 'stops emitting if error is returned', ->
86
+ list = []
87
+ @emitter.on 'event1', -> list.push(1)
88
+ @emitter.on 'event1', -> list.push(2); throw new Error('error')
89
+ @emitter.on 'event1', -> list.push(3)
90
+ expect(=> @emitter.emit 'event1').toThrow('error')
91
+ expect(list).toEqual([1,2])
92
+
93
+ it 'stops emitting if error is returned (async)', ->
94
+ list = []
95
+ @emitter.on 'event1', -> list.push(1)
96
+ @emitter.onAsync 'event1', (err, done) -> list.push(2); done('ERROR')
97
+ @emitter.on 'event1', -> list.push(3)
98
+ @emitter.emit 'event1', [null], (err) ->
99
+ expect(err).toEqual('ERROR')
100
+ expect(list).toEqual([1,2])
101
+
102
+ if AWS.util.isNode()
103
+ describe 'domain support', ->
104
+ domain = null
105
+ beforeEach -> domain = require('domain').create()
106
+ afterEach -> domain.dispose()
107
+
108
+ it 'supports domains', ->
109
+ helpers.mockHttpResponse 200, {}, 'Success!'
110
+
111
+ thrown = null
112
+ domain.on 'error', (err) -> thrown = err
113
+ domain.run ->
114
+ service = new MockService()
115
+ service.makeRequest 'operationName', ->
116
+ invalidCode
117
+
118
+ expect(thrown.name).toEqual('ReferenceError')