s3-restful 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,531 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ class ItemTest < Test::Unit::TestCase
4
+ context "An S3Restful::S3::Item instance" do
5
+
6
+ setup do
7
+ S3Restful::Log.level = Logger::ERROR
8
+ @item = S3Restful::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :server => '127.0.0.1')
9
+
10
+ @time = "Thu, 25 Feb 2010 10:00:00 GMT"
11
+ Time.stubs(:now).returns(Time.parse(@time))
12
+ #stub(:utc_httpdate => @time, :to_i => 99, :usec => 88))
13
+ end
14
+
15
+ context "validation" do
16
+ should "require a bucket and a key" do
17
+ assert_raise(ArgumentError) do
18
+ item = S3Restful::S3::Item.new()
19
+ end
20
+
21
+ assert_raise(ArgumentError) do
22
+ item = S3Restful::S3::Item.new('the-key')
23
+ end
24
+
25
+ assert_nothing_raised(ArgumentError) do
26
+ item = S3Restful::S3::Item.new('the-bucket', 'the-key')
27
+ end
28
+
29
+ end
30
+
31
+ should "not allow unknown options" do
32
+ assert_raise(ArgumentError) do
33
+ item = S3Restful::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :lala => 'lulul')
34
+ end
35
+ end
36
+
37
+ should "check valid protocol" do
38
+ assert_raise(ArgumentError) do
39
+ item = S3Restful::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :protocol => 'lulul')
40
+ end
41
+
42
+ assert_nothing_raised do
43
+ item = S3Restful::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :protocol => 'http')
44
+ end
45
+
46
+ assert_nothing_raised do
47
+ item = S3Restful::S3::Item.new('the-bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :protocol => 'https')
48
+ end
49
+ end
50
+ end
51
+
52
+ context "when building the item url" do
53
+ should "build the full path out of the server, bucket, and key" do
54
+ @item = S3Restful::S3::Item.new('the-bucketissoooooooooooooooooooooooooooooooooooooolonggggggggggggggggggggggggggggggggggg', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret', :server => '127.0.0.1')
55
+ assert_equal "https://127.0.0.1:443/the-bucketissoooooooooooooooooooooooooooooooooooooolonggggggggggggggggggggggggggggggggggg/the-key", @item.url
56
+ end
57
+
58
+ should "use the DNS bucket name where possible" do
59
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => '123', :aws_secret_access_key => 'secret')
60
+ assert_equal "https://bucket.s3.amazonaws.com:443/the-key", @item.url
61
+ end
62
+ end
63
+
64
+ context "when getting an item" do
65
+
66
+ should "call the on success callback" do
67
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, fake_response("data-here"))
68
+
69
+ called = false
70
+ data = nil
71
+ on_success = Proc.new {|http| called = true, data = http.response}
72
+ @item = S3Restful::S3::Item.new('bucket', 'the-key')
73
+ run_in_em_loop do
74
+ @item.get(:on_success => on_success)
75
+
76
+ EM.add_timer(1) {
77
+ assert called
78
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
79
+ assert_equal "data-here\n", data
80
+ EM.stop_event_loop
81
+ }
82
+
83
+ end
84
+ end
85
+
86
+ should "support direct blocks" do
87
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, fake_response("data-here"))
88
+
89
+ called = false
90
+ data = nil
91
+ @item = S3Restful::S3::Item.new('bucket', 'the-key')
92
+ run_in_em_loop do
93
+ @item.get do |http|
94
+ called = true
95
+ data = http.response
96
+ end
97
+
98
+ EM.add_timer(1) {
99
+ assert called
100
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
101
+ assert_equal "data-here\n", data
102
+ EM.stop_event_loop
103
+ }
104
+
105
+ end
106
+ end
107
+
108
+ should "support stream blocks" do
109
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, fake_response(""))
110
+
111
+ called = false
112
+ data = ""
113
+ @item = S3Restful::S3::Item.new('bucket', 'the-key')
114
+ run_in_em_loop do
115
+ response = @item.get
116
+ response.stream do |chunk|
117
+ called = true
118
+ data << chunk
119
+ end
120
+ response.on_body_data "data-here"
121
+
122
+ EM.add_timer(1) {
123
+ assert called
124
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
125
+ assert_equal "data-here", data
126
+ EM.stop_event_loop
127
+ }
128
+
129
+ end
130
+ end
131
+
132
+ should "sign requests if AWS credentials are passend" do
133
+ time = "Thu, 25 Feb 2010 12:06:33 GMT"
134
+ Time.stubs(:now).returns(Time.parse(time))
135
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {"Authorization"=>"AWS abc:3OEcVbE//maUUmqh3A5ETEcr9TE=", 'date' => time}, fake_response("data-here"))
136
+
137
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
138
+ run_in_em_loop do
139
+ @item.get
140
+
141
+ EM.add_timer(1) {
142
+ EM.stop_event_loop
143
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {"Authorization"=>"AWS abc:3OEcVbE//maUUmqh3A5ETEcr9TE=", 'date' => time})
144
+ }
145
+
146
+ end
147
+ end
148
+
149
+ should "retry on error" do
150
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, error_response(400))
151
+
152
+ @item = S3Restful::S3::Item.new('bucket', 'the-key')
153
+ run_in_em_loop do
154
+ @item.get(:on_error => Proc.new{} ) #ignore error
155
+
156
+ EM.add_timer(1) {
157
+ EM.stop_event_loop
158
+ assert_equal 5, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
159
+ }
160
+
161
+ end
162
+ end
163
+
164
+ should "handle re-direct" do
165
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :get, {}, redirect_response('https://bucket.s3-external-3.amazonaws.com/the-key'))
166
+ EventMachine::MockHttpRequest.register('https://bucket.s3-external-3.amazonaws.com:443/the-key', :get, {}, fake_response('hy there'))
167
+
168
+ @item = S3Restful::S3::Item.new('bucket', 'the-key')
169
+ run_in_em_loop do
170
+ @item.get
171
+
172
+ EM.add_timer(1) {
173
+ EM.stop_event_loop
174
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :get, {})
175
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3-external-3.amazonaws.com:443/the-key', :get, {})
176
+ }
177
+
178
+ end
179
+ end
180
+ end
181
+
182
+ context "when deleting an item" do
183
+ should "send a DELETE to the items location" do
184
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
185
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
186
+ 'date' => @time,
187
+ 'url' => "/bucket/the-key"}, fake_response("data-here"))
188
+
189
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
190
+ run_in_em_loop do
191
+ @item.delete
192
+
193
+ EM.add_timer(1) {
194
+ EM.stop_event_loop
195
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
196
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
197
+ 'date' => @time,
198
+ 'url' => "/bucket/the-key"})
199
+ }
200
+
201
+ end
202
+ end
203
+
204
+ should "support direct blocks" do
205
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
206
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
207
+ 'date' => @time,
208
+ 'url' => "/bucket/the-key"}, fake_response("data-here"))
209
+
210
+ called = false
211
+ data = nil
212
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
213
+ run_in_em_loop do
214
+ @item.delete do |http|
215
+ called = true
216
+ data = http.response
217
+ end
218
+
219
+ EM.add_timer(1) {
220
+ assert called
221
+ assert_equal "data-here\n", data
222
+ EM.stop_event_loop
223
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
224
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
225
+ 'date' => @time,
226
+ 'url' => "/bucket/the-key"})
227
+ }
228
+
229
+ end
230
+ end
231
+
232
+ should "handle re-direct" do
233
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
234
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
235
+ 'date' => @time,
236
+ 'url' => "/bucket/the-key"}, redirect_response('https://bucket.s3-external-3.amazonaws.com/the-key'))
237
+ EventMachine::MockHttpRequest.register('https://bucket.s3-external-3.amazonaws.com:443/the-key', :delete, {
238
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
239
+ 'date' => @time,
240
+ 'url' => "/bucket/the-key"}, fake_response("success!"))
241
+
242
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
243
+ run_in_em_loop do
244
+ @item.delete
245
+
246
+ EM.add_timer(1) {
247
+ EM.stop_event_loop
248
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
249
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
250
+ 'date' => @time,
251
+ 'url' => "/bucket/the-key"})
252
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3-external-3.amazonaws.com:443/the-key', :delete, {
253
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
254
+ 'date' => @time,
255
+ 'url' => "/bucket/the-key"})
256
+ }
257
+
258
+ end
259
+ end
260
+
261
+ should "handle retry" do
262
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
263
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
264
+ 'date' => @time,
265
+ 'url' => "/bucket/the-key"}, error_response(400))
266
+
267
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
268
+ run_in_em_loop do
269
+ @item.delete(:on_error => Proc.new{} ) #ignore error
270
+
271
+ EM.add_timer(1) {
272
+ EM.stop_event_loop
273
+ assert_equal 5, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :delete, {
274
+ "Authorization"=>"AWS abc:nvkrlq4wor1qbFXZh6rHnAbiRjk=",
275
+ 'date' => @time,
276
+ 'url' => "/bucket/the-key"})
277
+ }
278
+
279
+ end
280
+ end
281
+ end
282
+
283
+ context "when loading the headers" do
284
+ should "request via HEAD" do
285
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :head, {}, fake_response('hy there'))
286
+
287
+ @item = S3Restful::S3::Item.new('bucket', 'the-key')
288
+ run_in_em_loop do
289
+ @item.head
290
+
291
+ EM.add_timer(1) {
292
+ EM.stop_event_loop
293
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :head, {})
294
+ }
295
+
296
+ end
297
+ end
298
+ end
299
+
300
+ context "when saving an item" do
301
+
302
+ should "post to the desired location" do
303
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
304
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
305
+ 'date' => @time,
306
+ 'url' => "/bucket/the-key"}, fake_response("data-here"))
307
+
308
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
309
+ run_in_em_loop do
310
+ @item.put('content')
311
+
312
+ EM.add_timer(1) {
313
+ EM.stop_event_loop
314
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
315
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
316
+ 'date' => @time,
317
+ 'url' => "/bucket/the-key"})
318
+ }
319
+
320
+ end
321
+ end
322
+
323
+ should "support direct blocks" do
324
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
325
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
326
+ 'date' => @time,
327
+ 'url' => "/bucket/the-key"}, fake_response("data-here"))
328
+
329
+ called = false
330
+ data = nil
331
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
332
+ run_in_em_loop do
333
+ @item.put('upload me') do |http|
334
+ called = true
335
+ data = http.response
336
+ end
337
+
338
+ EM.add_timer(1) {
339
+ assert called
340
+ assert_equal "data-here\n", data
341
+ EM.stop_event_loop
342
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
343
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
344
+ 'date' => @time,
345
+ 'url' => "/bucket/the-key"})
346
+ }
347
+
348
+ end
349
+ end
350
+
351
+ should "set the desired permissions" do
352
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
353
+ "Authorization"=>"AWS abc:cqkfX+nC7WIkYD+yWaUFuoRuePA=",
354
+ 'date' => @time,
355
+ 'url' => "/bucket/the-key",
356
+ "x-amz-acl" => 'public-read'}, fake_response("data-here"))
357
+
358
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123' , :permissions => 'public-read')
359
+ run_in_em_loop do
360
+ @item.put('content')
361
+
362
+ EM.add_timer(1) {
363
+ EM.stop_event_loop
364
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
365
+ "Authorization"=>"AWS abc:cqkfX+nC7WIkYD+yWaUFuoRuePA=",
366
+ 'date' => @time,
367
+ 'url' => "/bucket/the-key",
368
+ 'x-amz-acl' => 'public-read'})
369
+ }
370
+
371
+ end
372
+ end
373
+
374
+ should "allow to set custom headers" do
375
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
376
+ "Authorization"=>"AWS abc:wrPkGKrlwH2AtNzBVS80vU73TDc=",
377
+ 'date' => @time,
378
+ 'url' => "/bucket/the-key",
379
+ "x-amz-acl" => 'public-read',
380
+ 'Cache-Control' => "max-age=252460800",
381
+ 'Expires' => 'Fri, 16 Nov 2018 22:09:29 GMT',
382
+ 'x-amz-meta-abc' => 'ABC'}, fake_response("data-here"))
383
+
384
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc',
385
+ :aws_secret_access_key => '123' ,
386
+ :permissions => 'public-read')
387
+ run_in_em_loop do
388
+ @item.put('content', :headers => {
389
+ 'Expires' => 'Fri, 16 Nov 2018 22:09:29 GMT',
390
+ 'Cache-Control' => "max-age=252460800",
391
+ 'x-amz-meta-abc' => 'ABC'})
392
+
393
+ EM.add_timer(1) {
394
+ EM.stop_event_loop
395
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
396
+ "Authorization"=>"AWS abc:wrPkGKrlwH2AtNzBVS80vU73TDc=",
397
+ 'date' => @time,
398
+ 'url' => "/bucket/the-key",
399
+ 'x-amz-acl' => 'public-read',
400
+ 'Cache-Control' => "max-age=252460800",
401
+ 'Expires' => 'Fri, 16 Nov 2018 22:09:29 GMT',
402
+ 'x-amz-meta-abc' => 'ABC'})
403
+ }
404
+
405
+ end
406
+ end
407
+
408
+ should "validate the headers" do
409
+
410
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc',
411
+ :aws_secret_access_key => '123' ,
412
+ :permissions => 'public-read')
413
+
414
+ assert_raise(ArgumentError) do
415
+ @item.put('content', :headers => {
416
+ 'expires' => 'Fri, 16 Nov 2018 22:09:29 GMT',
417
+ 'cache_control' => "max-age=252460800"})
418
+ end
419
+ end
420
+
421
+ should "re-post to a new location" do
422
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
423
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
424
+ 'date' => @time,
425
+ 'url' => "/bucket/the-key"}, redirect_response('https://bucket.s3-external-3.amazonaws.com/the-key'))
426
+ EventMachine::MockHttpRequest.register('https://bucket.s3-external-3.amazonaws.com:443/the-key', :put, {
427
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
428
+ 'date' => @time,
429
+ 'url' => "/bucket/the-key"}, fake_response('Thanks!'))
430
+
431
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
432
+ run_in_em_loop do
433
+ @item.put('content')
434
+
435
+ EM.add_timer(1) {
436
+ EM.stop_event_loop
437
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
438
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
439
+ 'date' => @time,
440
+ 'url' => "/bucket/the-key"})
441
+
442
+ assert_equal 1, EventMachine::MockHttpRequest.count('https://bucket.s3-external-3.amazonaws.com:443/the-key', :put, {
443
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
444
+ 'date' => @time,
445
+ 'url' => "/bucket/the-key"})
446
+ }
447
+
448
+ end
449
+ end
450
+
451
+ should "retry on error" do
452
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
453
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
454
+ 'date' => @time,
455
+ 'url' => "/bucket/the-key"}, error_response(400))
456
+
457
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
458
+ run_in_em_loop do
459
+ @item.put('content', :on_error => Proc.new{} )
460
+
461
+ EM.add_timer(1) {
462
+ EM.stop_event_loop
463
+ assert_equal 5, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
464
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
465
+ 'date' => @time,
466
+ 'url' => "/bucket/the-key"})
467
+ }
468
+
469
+ end
470
+ end
471
+
472
+ should "call error handler after retry reached" do
473
+ EventMachine::MockHttpRequest.register('https://bucket.s3.amazonaws.com:443/the-key', :put, {
474
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
475
+ 'date' => @time,
476
+ 'url' => "/bucket/the-key"}, error_response(400))
477
+
478
+ called = false
479
+ on_error = Proc.new {|http| called = true}
480
+
481
+ @item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
482
+ run_in_em_loop do
483
+ @item.put('content', :on_error => on_error, :retry_count => 1)
484
+
485
+ EM.add_timer(1) {
486
+ EM.stop_event_loop
487
+ assert called
488
+ assert_equal 2, EventMachine::MockHttpRequest.count('https://bucket.s3.amazonaws.com:443/the-key', :put, {
489
+ "Authorization"=>"AWS abc:lZMKxGDKcQ1PH8yjbpyN7o2sPWg=",
490
+ 'date' => @time,
491
+ 'url' => "/bucket/the-key"})
492
+ }
493
+
494
+ end
495
+ end
496
+
497
+ end
498
+
499
+ context "SSL options" do
500
+ setup do
501
+ S3Restful::S3.ssl_options[:verify_peer] = true
502
+ S3Restful::S3.ssl_options[:cert_chain_file] = '/etc/foo.ca'
503
+ end
504
+
505
+ should "re-use the global options" do
506
+ item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
507
+ assert item.options[:ssl][:verify_peer]
508
+ assert_equal '/etc/foo.ca', item.options[:ssl][:cert_chain_file]
509
+ end
510
+
511
+ should "allow to override global options" do
512
+ item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123', :ssl => {:cert_chain_file => nil, :verify_peer => false})
513
+ assert !item.options[:ssl][:verify_peer]
514
+ assert_nil item.options[:ssl][:cert_chain_file]
515
+ end
516
+
517
+ should "pass the options to the Request" do
518
+ item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
519
+ S3Restful::S3::Request.expects(:new).with(:get, anything, {:ssl => {:cert_chain_file => '/etc/foo.ca', :verify_peer => true}, :headers => {'Authorization' => 'AWS abc:LGLdCdGTuLAHs+InbMWEnQR6djc=', 'date' => 'Thu, 25 Feb 2010 10:00:00 GMT'}}).returns(stub(:execute => nil))
520
+ item.get
521
+ end
522
+
523
+ should "allow to override the options per request" do
524
+ item = S3Restful::S3::Item.new('bucket', 'the-key', :aws_access_key_id => 'abc', :aws_secret_access_key => '123')
525
+ S3Restful::S3::Request.expects(:new).with(:get, anything, {:ssl => {:foo => :bar}, :headers => {'Authorization' => 'AWS abc:LGLdCdGTuLAHs+InbMWEnQR6djc=', 'date' => 'Thu, 25 Feb 2010 10:00:00 GMT'}}).returns(stub(:execute => nil))
526
+ item.get(:ssl => {:foo => :bar})
527
+ end
528
+ end
529
+
530
+ end
531
+ end
@@ -0,0 +1,109 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ class ItemTest < Test::Unit::TestCase
4
+ context "An S3Restful::S3::Request instance" do
5
+
6
+ setup do
7
+ S3Restful::Log.level = Logger::ERROR
8
+ @response_stub = stub()
9
+ @response_stub.stubs(:errback)
10
+ @response_stub.stubs(:callback)
11
+ end
12
+
13
+ context "validation" do
14
+ should "check HTTP method" do
15
+ assert_raise(ArgumentError) do
16
+ S3Restful::S3::Request.new(:foo, 'https://www.example.com')
17
+ end
18
+
19
+ assert_nothing_raised do
20
+ S3Restful::S3::Request.new(:get, 'https://www.example.com')
21
+ end
22
+ end
23
+
24
+ should "check the options" do
25
+ assert_raise(ArgumentError) do
26
+ S3Restful::S3::Request.new(:get, 'https://www.example.com', {:foo => :bar})
27
+ end
28
+
29
+ assert_nothing_raised do
30
+ S3Restful::S3::Request.new(:get, 'https://www.example.com', {:timeout => 4})
31
+ end
32
+ end
33
+ end
34
+
35
+ context "when executing" do
36
+ should "have no response before executing" do
37
+ assert_nil S3Restful::S3::Request.new(:get, 'https://www.example.com').response
38
+ end
39
+
40
+ should "call em-http-request" do
41
+ request = mock(:get => @response_stub)
42
+ EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
43
+ S3Restful::S3::Request.new(:get, 'https://www.example.com').execute
44
+ end
45
+
46
+ should "return the response" do
47
+ request = mock(:get => @response_stub)
48
+ EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
49
+ resp = S3Restful::S3::Request.new(:get, 'https://www.example.com').execute
50
+ assert_equal resp, @response_stub
51
+ end
52
+
53
+ should "pass the given headers and options" do
54
+ request = mock('em-http-request')
55
+ request.expects(:get).with(:timeout => 10, :head => {'a' => 'b'}, :body => nil, :ssl => {:verify_peer => false, :cert_chain_file => nil}).returns(@response_stub)
56
+ EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
57
+ S3Restful::S3::Request.new(:get, 'https://www.example.com', :headers => {'a' => 'b'}).execute
58
+ end
59
+
60
+ should "post any given data" do
61
+ request = mock('em-http-request')
62
+ request.expects(:put).with(:timeout => 10, :body => 'the-data', :head => {}, :ssl => {:verify_peer => false, :cert_chain_file => nil}).returns(@response_stub)
63
+ EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
64
+ S3Restful::S3::Request.new(:put, 'https://www.example.com', :data => 'the-data').execute
65
+ end
66
+
67
+ should "pass SSL options to em-http-request" do
68
+ request = mock('em-http-request')
69
+ request.expects(:put).with(:timeout => 10, :body => 'the-data', :head => {}, :ssl => {:verfiy_peer => true, :cert_chain_file => '/tmp/server.crt'}).returns(@response_stub)
70
+ EventMachine::MockHttpRequest.expects(:new).with('https://www.example.com').returns(request)
71
+ S3Restful::S3::Request.new(:put, 'https://www.example.com', :data => 'the-data', :ssl => {:verfiy_peer => true, :cert_chain_file => '/tmp/server.crt'}).execute
72
+ end
73
+
74
+ context "when handling errors" do
75
+ should "call the user error handler" do
76
+ EventMachine::MockHttpRequest.register('http://www.example.com:80/', :get, {}, error_response(400))
77
+
78
+ called = false
79
+ on_error = Proc.new {|http| called = true}
80
+
81
+ run_in_em_loop do
82
+ S3Restful::S3::Request.new(:get, 'http://www.example.com/', :on_error => on_error).execute
83
+
84
+ EM.add_timer(1) {
85
+ EM.stop_event_loop
86
+ assert called
87
+ assert_equal 5, EventMachine::MockHttpRequest.count('http://www.example.com:80/', :get, {})
88
+ }
89
+
90
+ end
91
+ end
92
+
93
+ should "use a default error handler if there is no user handler" do
94
+ EventMachine::MockHttpRequest.register('http://www.example.com:80/', :get, {}, error_response(400))
95
+
96
+ assert_raise(S3Restful::Error) do
97
+ run_in_em_loop do
98
+ S3Restful::S3::Request.new(:get, 'http://www.example.com/').execute
99
+ end
100
+ end
101
+ EM.stop_event_loop if EM.reactor_running?
102
+ end
103
+
104
+ end
105
+
106
+ end
107
+
108
+ end
109
+ end
data/test/s3_test.rb ADDED
@@ -0,0 +1,32 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class S3Test < Test::Unit::TestCase
4
+ context "The S3Restful::S3 module" do
5
+
6
+ should "allow to set global SSL options" do
7
+ assert S3Restful::S3.respond_to?(:ssl_options)
8
+ assert S3Restful::S3.respond_to?(:ssl_options=)
9
+ end
10
+
11
+ should "set and get verify_peer" do
12
+ S3Restful::S3.ssl_options[:verify_peer] = true
13
+ assert S3Restful::S3.ssl_options[:verify_peer]
14
+ S3Restful::S3.ssl_options[:verify_peer] = false
15
+ assert !S3Restful::S3.ssl_options[:verify_peer]
16
+ end
17
+
18
+ should "set and get cert_chain_file" do
19
+ S3Restful::S3.ssl_options[:cert_chain_file] = '/etc/cacert'
20
+ assert_equal '/etc/cacert', S3Restful::S3.ssl_options[:cert_chain_file]
21
+ S3Restful::S3.ssl_options[:cert_chain_file] = nil
22
+ assert_nil S3Restful::S3.ssl_options[:cert_chain_file]
23
+ end
24
+
25
+ should "default to no certificate file and no verification" do
26
+ S3Restful::S3.instance_variable_set("@_ssl_options", nil)
27
+ assert !S3Restful::S3.ssl_options[:verify_peer]
28
+ assert_nil S3Restful::S3.ssl_options[:cert_chain_file]
29
+ end
30
+
31
+ end
32
+ end