aws-s3 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/INSTALL +4 -0
- data/README +28 -27
- data/Rakefile +33 -4
- data/lib/aws/s3.rb +1 -0
- data/lib/aws/s3/acl.rb +8 -3
- data/lib/aws/s3/base.rb +10 -8
- data/lib/aws/s3/bucket.rb +1 -5
- data/lib/aws/s3/connection.rb +48 -9
- data/lib/aws/s3/exceptions.rb +3 -0
- data/lib/aws/s3/extensions.rb +99 -9
- data/lib/aws/s3/logging.rb +152 -9
- data/lib/aws/s3/object.rb +30 -22
- data/lib/aws/s3/parsing.rb +0 -29
- data/lib/aws/s3/response.rb +2 -2
- data/lib/aws/s3/version.rb +2 -2
- data/support/faster-xml-simple/lib/faster_xml_simple.rb +30 -11
- data/support/faster-xml-simple/test/regression_test.rb +11 -5
- data/support/faster-xml-simple/test/test_helper.rb +17 -0
- data/support/faster-xml-simple/test/xml_simple_comparison_test.rb +2 -3
- data/test/acl_test.rb +13 -2
- data/test/connection_test.rb +8 -0
- data/test/extensions_test.rb +57 -4
- data/test/fixtures/loglines.yml +5 -0
- data/test/fixtures/logs.yml +7 -0
- data/test/logging_test.rb +54 -1
- data/test/object_test.rb +15 -0
- data/test/parsing_test.rb +0 -20
- data/test/remote/object_test.rb +49 -1
- metadata +5 -2
data/lib/aws/s3/parsing.rb
CHANGED
@@ -39,35 +39,6 @@ module AWS
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
42
|
-
|
43
|
-
class CoercibleString < String
|
44
|
-
attr_accessor :generator
|
45
|
-
class << self
|
46
|
-
def coerce(string)
|
47
|
-
new(string).coerce
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def coerce
|
52
|
-
case self
|
53
|
-
when 'true': true
|
54
|
-
when 'false': false
|
55
|
-
when /^\d+$/: Integer(self)
|
56
|
-
when datetime_format: Time.parse(self)
|
57
|
-
else
|
58
|
-
self
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
# Lame hack since Date._parse is so accepting. S3 dates are of the form: '2006-10-29T23:14:47.000Z'
|
65
|
-
# so unless the string looks like that, don't even try, otherwise it might convert an object's
|
66
|
-
# key from something like '03 1-2-3-Apple-Tree.mp3' to Sat Feb 03 00:00:00 CST 2001.
|
67
|
-
def datetime_format
|
68
|
-
/^\d{4}-\d{2}-\d{2}\w\d{2}:\d{2}:\d{2}/
|
69
|
-
end
|
70
|
-
end
|
71
42
|
|
72
43
|
class XmlParser < Hash
|
73
44
|
include Typecasting
|
data/lib/aws/s3/response.rb
CHANGED
@@ -57,7 +57,7 @@ module AWS
|
|
57
57
|
memoized :parsed
|
58
58
|
|
59
59
|
def inspect
|
60
|
-
"
|
60
|
+
"#<%s:0x%s %s %s>" % [self.class, object_id, response.code, response.message]
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
@@ -119,7 +119,7 @@ module AWS
|
|
119
119
|
end
|
120
120
|
|
121
121
|
def inspect
|
122
|
-
"
|
122
|
+
"#<%s:0x%s %s %s: '%s'>" % [self.class.name, object_id, response.code, error.code, error.message]
|
123
123
|
end
|
124
124
|
end
|
125
125
|
end
|
data/lib/aws/s3/version.rb
CHANGED
@@ -37,7 +37,7 @@ class FasterXmlSimple
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def out
|
40
|
-
{doc.root.name => collapse(doc.root
|
40
|
+
{doc.root.name => collapse(doc.root)}
|
41
41
|
end
|
42
42
|
|
43
43
|
private
|
@@ -45,14 +45,17 @@ class FasterXmlSimple
|
|
45
45
|
{'contentkey' => '__content__', 'forcearray' => []}
|
46
46
|
end
|
47
47
|
|
48
|
-
def collapse(element
|
48
|
+
def collapse(element)
|
49
49
|
result = hash_of_attributes(element)
|
50
50
|
if text_node? element
|
51
51
|
text = collapse_text(element)
|
52
52
|
result.merge!(content_key => text) if text =~ /\S/
|
53
53
|
elsif element.children?
|
54
54
|
element.inject(result) do |hash, child|
|
55
|
-
|
55
|
+
unless child.text?
|
56
|
+
child_result = collapse(child)
|
57
|
+
(hash[child.name] ||= []) << child_result
|
58
|
+
end
|
56
59
|
hash
|
57
60
|
end
|
58
61
|
end
|
@@ -61,15 +64,14 @@ class FasterXmlSimple
|
|
61
64
|
end
|
62
65
|
# Compact them to ensure it complies with the user's requests
|
63
66
|
inline_single_element_arrays(result)
|
64
|
-
|
65
|
-
|
67
|
+
suppress_empty_content(result) unless force_content?
|
68
|
+
remove_empty_elements(result) if suppress_empty?
|
69
|
+
|
66
70
|
result
|
67
71
|
end
|
68
72
|
|
69
73
|
def empty_element
|
70
|
-
if options
|
71
|
-
raise 'unimplemented'
|
72
|
-
elsif !options.has_key? 'suppressempty'
|
74
|
+
if !options.has_key? 'suppressempty'
|
73
75
|
{}
|
74
76
|
else
|
75
77
|
options['suppressempty']
|
@@ -92,12 +94,26 @@ class FasterXmlSimple
|
|
92
94
|
end
|
93
95
|
end
|
94
96
|
|
95
|
-
def
|
97
|
+
def remove_empty_elements(result)
|
98
|
+
result.each do |key, value|
|
99
|
+
if value == empty_element
|
100
|
+
result.delete key
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def suppress_empty?
|
106
|
+
options['suppressempty'] == true
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
def suppress_empty_content(result)
|
96
112
|
result.delete content_key if result[content_key] !~ /\S/
|
97
113
|
end
|
98
114
|
|
99
|
-
def
|
100
|
-
options
|
115
|
+
def force_content?
|
116
|
+
options['forcecontent']
|
101
117
|
end
|
102
118
|
|
103
119
|
# a text node is one with 1 or more child nodes which are
|
@@ -122,6 +138,9 @@ class FasterXmlSimple
|
|
122
138
|
end
|
123
139
|
|
124
140
|
def parse(string)
|
141
|
+
if string == ''
|
142
|
+
string = ' '
|
143
|
+
end
|
125
144
|
XML::Parser.string(string).parse
|
126
145
|
end
|
127
146
|
end
|
@@ -1,7 +1,6 @@
|
|
1
|
-
require '
|
2
|
-
require 'test/unit'
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
3
2
|
|
4
|
-
class RegressionTest <
|
3
|
+
class RegressionTest < FasterXSTest
|
5
4
|
def test_content_nil_regressions
|
6
5
|
expected = {"asdf"=>{"jklsemicolon"=>{}}}
|
7
6
|
assert_equal expected, FasterXmlSimple.xml_in("<asdf><jklsemicolon /></asdf>")
|
@@ -23,8 +22,15 @@ class RegressionTest < Test::Unit::TestCase
|
|
23
22
|
assert_equal Hash.new, FasterXmlSimple.xml_in(str)["asdf"]["fdsa"]
|
24
23
|
assert_nil FasterXmlSimple.xml_in(str, 'suppressempty'=>nil)["asdf"]["fdsa"]
|
25
24
|
assert_equal '', FasterXmlSimple.xml_in(str, 'suppressempty'=>'')["asdf"]["fdsa"]
|
26
|
-
|
25
|
+
assert !FasterXmlSimple.xml_in(str, 'suppressempty'=>true)["asdf"].has_key?("fdsa")
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_empty_string_doesnt_crash
|
29
|
+
assert_raise(XML::Parser::ParseError) do
|
30
|
+
silence_stderr do
|
31
|
+
FasterXmlSimple.xml_in('')
|
32
|
+
end
|
33
|
+
end
|
27
34
|
end
|
28
|
-
|
29
35
|
|
30
36
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
require 'test/unit'
|
3
|
+
require 'faster_xml_simple'
|
4
|
+
|
5
|
+
class FasterXSTest < Test::Unit::TestCase
|
6
|
+
def default_test
|
7
|
+
end
|
8
|
+
|
9
|
+
def silence_stderr
|
10
|
+
str = STDERR.dup
|
11
|
+
STDERR.reopen("/dev/null")
|
12
|
+
STDERR.sync=true
|
13
|
+
yield
|
14
|
+
ensure
|
15
|
+
STDERR.reopen(str)
|
16
|
+
end
|
17
|
+
end
|
data/test/acl_test.rb
CHANGED
@@ -102,6 +102,17 @@ class PolicyTest < Test::Unit::TestCase
|
|
102
102
|
assert_nil policy.grants.delete(non_grant)
|
103
103
|
end
|
104
104
|
end
|
105
|
+
|
106
|
+
def test_grant_list_comparison
|
107
|
+
policy = ACL::Policy.new
|
108
|
+
policy2 = ACL::Policy.new
|
109
|
+
|
110
|
+
grant_names = [:public_read, :public_read_acp, :authenticated_write]
|
111
|
+
grant_names.each {|grant_name| policy.grants << ACL::Grant.grant(grant_name)}
|
112
|
+
grant_names.reverse_each {|grant_name| policy2.grants << ACL::Grant.grant(grant_name)}
|
113
|
+
|
114
|
+
assert_equal policy.grants, policy2.grants
|
115
|
+
end
|
105
116
|
end
|
106
117
|
|
107
118
|
class GrantTest < Test::Unit::TestCase
|
@@ -123,7 +134,7 @@ class GrantTest < Test::Unit::TestCase
|
|
123
134
|
|
124
135
|
grant = nil
|
125
136
|
assert_nothing_raised do
|
126
|
-
grant = ACL::Grant.grant
|
137
|
+
grant = ACL::Grant.grant(:public_read)
|
127
138
|
end
|
128
139
|
|
129
140
|
assert grant
|
@@ -240,4 +251,4 @@ class ACLOptionProcessorTest < Test::Unit::TestCase
|
|
240
251
|
def acl(options)
|
241
252
|
options['x-amz-acl']
|
242
253
|
end
|
243
|
-
end
|
254
|
+
end
|
data/test/connection_test.rb
CHANGED
@@ -27,6 +27,14 @@ class ConnectionTest < Test::Unit::TestCase
|
|
27
27
|
assert_equal 'https://', connection.protocol
|
28
28
|
end
|
29
29
|
|
30
|
+
def test_connection_is_persistent_by_default
|
31
|
+
connection = Connection.new(@keys)
|
32
|
+
assert connection.persistent?
|
33
|
+
|
34
|
+
connection = Connection.new(@keys.merge(:persistent => false))
|
35
|
+
assert !connection.persistent?
|
36
|
+
end
|
37
|
+
|
30
38
|
def test_server_and_port_are_passed_onto_connection
|
31
39
|
connection = Connection.new(@keys)
|
32
40
|
options = connection.instance_variable_get('@options')
|
data/test/extensions_test.rb
CHANGED
@@ -64,6 +64,37 @@ class StringExtensionsTest < Test::Unit::TestCase
|
|
64
64
|
assert_equal after, before.to_header
|
65
65
|
end
|
66
66
|
end
|
67
|
+
|
68
|
+
def test_utf8?
|
69
|
+
assert !"318597/620065/GTL_75\24300_A600_A610.zip".utf8?
|
70
|
+
assert "318597/620065/GTL_75£00_A600_A610.zip".utf8?
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_remove_extended
|
74
|
+
assert "318597/620065/GTL_75\24300_A600_A610.zip".remove_extended.utf8?
|
75
|
+
assert "318597/620065/GTL_75£00_A600_A610.zip".remove_extended.utf8?
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class CoercibleStringTest < Test::Unit::TestCase
|
80
|
+
|
81
|
+
def test_coerce
|
82
|
+
coercions = [
|
83
|
+
['1', 1],
|
84
|
+
['false', false],
|
85
|
+
['true', true],
|
86
|
+
['2006-10-29T23:14:47.000Z', Time.parse('2006-10-29T23:14:47.000Z')],
|
87
|
+
['Hello!', 'Hello!'],
|
88
|
+
['false23', 'false23'],
|
89
|
+
['03 1-2-3-Apple-Tree.mp3', '03 1-2-3-Apple-Tree.mp3']
|
90
|
+
]
|
91
|
+
|
92
|
+
coercions.each do |before, after|
|
93
|
+
assert_nothing_raised do
|
94
|
+
assert_equal after, CoercibleString.coerce(before)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
67
98
|
end
|
68
99
|
|
69
100
|
class KerneltExtensionsTest < Test::Unit::TestCase
|
@@ -122,6 +153,11 @@ class ModuleExtensionsTest < Test::Unit::TestCase
|
|
122
153
|
Time.now
|
123
154
|
end
|
124
155
|
end
|
156
|
+
|
157
|
+
def quux
|
158
|
+
Time.now
|
159
|
+
end
|
160
|
+
memoized :quux
|
125
161
|
end
|
126
162
|
|
127
163
|
def setup
|
@@ -129,19 +165,38 @@ class ModuleExtensionsTest < Test::Unit::TestCase
|
|
129
165
|
end
|
130
166
|
|
131
167
|
def test_memoize
|
168
|
+
assert !@instance.instance_variables.include?('@foo')
|
132
169
|
cached_result = @instance.foo
|
133
170
|
assert_equal cached_result, @instance.foo
|
171
|
+
assert @instance.instance_variables.include?('@foo')
|
134
172
|
assert_equal cached_result, @instance.send(:instance_variable_get, :@foo)
|
135
|
-
assert_not_equal cached_result, @instance.foo(:reload)
|
173
|
+
assert_not_equal cached_result, new_cache = @instance.foo(:reload)
|
174
|
+
assert_equal new_cache, @instance.foo
|
175
|
+
assert_equal new_cache, @instance.send(:instance_variable_get, :@foo)
|
136
176
|
end
|
137
177
|
|
138
|
-
def
|
178
|
+
def test_customizing_memoize_storage
|
179
|
+
assert !@instance.instance_variables.include?('@bar')
|
180
|
+
assert !@instance.instance_variables.include?('@baz')
|
139
181
|
cached_result = @instance.bar
|
182
|
+
assert !@instance.instance_variables.include?('@bar')
|
183
|
+
assert @instance.instance_variables.include?('@baz')
|
140
184
|
assert_equal cached_result, @instance.bar
|
141
185
|
assert_equal cached_result, @instance.send(:instance_variable_get, :@baz)
|
142
186
|
assert_nil @instance.send(:instance_variable_get, :@bar)
|
143
187
|
end
|
144
188
|
|
189
|
+
def test_memoized
|
190
|
+
assert !@instance.instance_variables.include?('@quux')
|
191
|
+
cached_result = @instance.quux
|
192
|
+
assert_equal cached_result, @instance.quux
|
193
|
+
assert @instance.instance_variables.include?('@quux')
|
194
|
+
assert_equal cached_result, @instance.send(:instance_variable_get, :@quux)
|
195
|
+
assert_not_equal cached_result, new_cache = @instance.quux(:reload)
|
196
|
+
assert_equal new_cache, @instance.quux
|
197
|
+
assert_equal new_cache, @instance.send(:instance_variable_get, :@quux)
|
198
|
+
end
|
199
|
+
|
145
200
|
def test_constant_setting
|
146
201
|
some_module = Module.new
|
147
202
|
assert !some_module.const_defined?(:FOO)
|
@@ -164,8 +219,6 @@ class ModuleExtensionsTest < Test::Unit::TestCase
|
|
164
219
|
assert_equal 'bar', some_module::FOO
|
165
220
|
assert_equal 'bar', some_module.foo
|
166
221
|
end
|
167
|
-
|
168
|
-
|
169
222
|
end
|
170
223
|
|
171
224
|
class AttributeProxyTest < Test::Unit::TestCase
|
@@ -0,0 +1,5 @@
|
|
1
|
+
bucket_get:
|
2
|
+
"bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [14/Nov/2006:06:36:48 +0000] 67.165.183.125 bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 8B5297D428A05432 REST.GET.BUCKET - \"GET /marcel HTTP/1.1\" 200 - 4534 - 398 395 \"-\" \"-\"\n"
|
3
|
+
|
4
|
+
browser_get:
|
5
|
+
"bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [25/Nov/2006:06:26:23 +0000] 67.165.183.125 65a011a29cdf8ec533ec3d1ccaae921c 41521D07CA012312 REST.GET.OBJECT kiss.jpg \"GET /marcel/kiss.jpg HTTP/1.1\" 200 - 67748 67748 259 104 \"-\" \"Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0\"\n"
|
@@ -0,0 +1,7 @@
|
|
1
|
+
simple_log:
|
2
|
+
- "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [14/Nov/2006:06:36:48 +0000] 67.165.183.125 bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 8B5297D428A05432 REST.GET.BUCKET - \"GET /marcel HTTP/1.1\" 200 - 4534 - 398 395 \"-\" \"-\"\n"
|
3
|
+
- "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [14/Nov/2006:06:38:58 +0000] 67.165.183.125 bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 8F6F3C4027849420 REST.GET.BUCKET - \"GET /marcel HTTP/1.1\" 200 - 4534 - 458 456 \"-\" \"-\"\n"
|
4
|
+
|
5
|
+
requests_from_a_browser:
|
6
|
+
- "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [25/Nov/2006:06:26:23 +0000] 67.165.183.125 65a011a29cdf8ec533ec3d1ccaae921c 41521D07CA012312 REST.GET.OBJECT kiss.jpg \"GET /marcel/kiss.jpg HTTP/1.1\" 200 - 67748 67748 259 104 \"-\" \"Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0\"\n"
|
7
|
+
- "bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1 marcel [25/Nov/2006:06:26:27 +0000] 67.165.183.125 65a011a29cdf8ec533ec3d1ccaae921c 88629578AFDDD9B5 REST.GET.TORRENT kiss.jpg \"GET /marcel/kiss.jpg?torrent HTTP/1.1\" 200 - 215 - 379 - \"-\" \"Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0\"\n"
|
data/test/logging_test.rb
CHANGED
@@ -27,10 +27,63 @@ class LoggingStatusReadingTest < Test::Unit::TestCase
|
|
27
27
|
end
|
28
28
|
|
29
29
|
class LoggingStatusWritingTest < LoggingStatusReadingTest
|
30
|
-
|
31
30
|
def setup
|
32
31
|
super
|
33
32
|
@disabled = Logging::Status.new(Parsing::XmlParser.new(@disabled.to_xml))
|
34
33
|
@enabled = Logging::Status.new(Parsing::XmlParser.new(@enabled.to_xml))
|
35
34
|
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class LogTest < Test::Unit::TestCase
|
38
|
+
def test_value_converted_to_log_lines
|
39
|
+
log_object = S3Object.new
|
40
|
+
log_object.value = Fixtures::Logs.simple_log.join
|
41
|
+
log = Logging::Log.new(log_object)
|
42
|
+
assert_nothing_raised do
|
43
|
+
log.lines
|
44
|
+
end
|
45
|
+
|
46
|
+
assert_equal 2, log.lines.size
|
47
|
+
assert_kind_of Logging::Log::Line, log.lines.first
|
48
|
+
assert_equal 'marcel', log.lines.first.bucket
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class LogLineTest < Test::Unit::TestCase
|
53
|
+
def setup
|
54
|
+
@line = Logging::Log::Line.new(Fixtures::Loglines.bucket_get)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_field_accessors
|
58
|
+
expected_results = {
|
59
|
+
:owner => Owner.new('id' => 'bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1'),
|
60
|
+
:bucket => 'marcel',
|
61
|
+
:time => Time.parse('11/14/2006 06:36:48 +0000'),
|
62
|
+
:remote_ip => '67.165.183.125',
|
63
|
+
:request_id => '8B5297D428A05432',
|
64
|
+
:requestor => Owner.new('id' => 'bb2041a25975c3d4ce9775fe9e93e5b77a6a9fad97dc7e00686191f3790b13f1'),
|
65
|
+
:operation => 'REST.GET.BUCKET',
|
66
|
+
:key => nil,
|
67
|
+
:request_uri => 'GET /marcel HTTP/1.1',
|
68
|
+
:http_status => 200,
|
69
|
+
:error_code => nil,
|
70
|
+
:bytes_sent => 4534,
|
71
|
+
:object_size => nil,
|
72
|
+
:total_time => 398,
|
73
|
+
:turn_around_time => 395,
|
74
|
+
:referrer => nil,
|
75
|
+
:user_agent => nil
|
76
|
+
}
|
77
|
+
|
78
|
+
expected_results.each do |field, expected|
|
79
|
+
assert_equal expected, @line.send(field)
|
80
|
+
end
|
81
|
+
|
82
|
+
assert_equal expected_results, @line.attributes
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_user_agent
|
86
|
+
line = Logging::Log::Line.new(Fixtures::Loglines.browser_get)
|
87
|
+
assert_equal 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0', line.user_agent
|
88
|
+
end
|
36
89
|
end
|
data/test/object_test.rb
CHANGED
@@ -105,6 +105,21 @@ class ObjectTest < Test::Unit::TestCase
|
|
105
105
|
about = S3Object.about('foo', 'bar')
|
106
106
|
assert_kind_of S3Object::About, about
|
107
107
|
assert_equal headers, about
|
108
|
+
|
109
|
+
S3Object.request_returns :code => 404
|
110
|
+
assert_raises(NoSuchKey) do
|
111
|
+
S3Object.about('foo', 'bar')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_exists?
|
117
|
+
S3Object.in_test_mode do
|
118
|
+
S3Object.request_returns :code => 404
|
119
|
+
assert_equal false, S3Object.exists?('foo', 'bar')
|
120
|
+
|
121
|
+
S3Object.request_returns :code => 200
|
122
|
+
assert_equal true, S3Object.exists?('foo', 'bar')
|
108
123
|
end
|
109
124
|
end
|
110
125
|
|