cloudfiles 1.4.18 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -0
- data/CONTRIBUTORS +1 -0
- data/cloudfiles.gemspec +5 -3
- data/lib/client.rb +620 -0
- data/lib/cloudfiles.rb +1 -1
- data/lib/cloudfiles/authentication.rb +10 -25
- data/lib/cloudfiles/connection.rb +55 -123
- data/lib/cloudfiles/container.rb +89 -73
- data/lib/cloudfiles/storage_object.rb +52 -36
- data/lib/cloudfiles/version.rb +1 -1
- data/test/cloudfiles_authentication_test.rb +17 -22
- data/test/cloudfiles_client_test.rb +797 -0
- data/test/cloudfiles_connection_test.rb +53 -194
- data/test/cloudfiles_container_test.rb +253 -121
- data/test/cloudfiles_storage_object_test.rb +51 -65
- data/test/test_helper.rb +1 -0
- metadata +12 -10
@@ -34,8 +34,11 @@ module CloudFiles
|
|
34
34
|
# Retrieves Metadata for the object
|
35
35
|
def object_metadata
|
36
36
|
@object_metadata ||= (
|
37
|
-
|
38
|
-
|
37
|
+
begin
|
38
|
+
response = SwiftClient.head_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name, (CloudFiles.escape self.name))
|
39
|
+
rescue ClientException => e
|
40
|
+
raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist" unless (e.status.to_s =~ /^20/)
|
41
|
+
end
|
39
42
|
resphash = {}
|
40
43
|
metas = response.to_hash.select { |k,v| k.match(/^x-object-meta/) }
|
41
44
|
|
@@ -91,9 +94,12 @@ module CloudFiles
|
|
91
94
|
range = sprintf("bytes=%d-%d", offset.to_i, (offset.to_i + size.to_i) - 1)
|
92
95
|
headers['Range'] = range
|
93
96
|
end
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
+
begin
|
98
|
+
response = SwiftClient.get_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name, (CloudFiles.escape self.name))
|
99
|
+
response[1]
|
100
|
+
rescue ClientException => e
|
101
|
+
raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist" unless (e.status.to_s =~ /^20/)
|
102
|
+
end
|
97
103
|
end
|
98
104
|
alias :read :data
|
99
105
|
|
@@ -115,9 +121,8 @@ module CloudFiles
|
|
115
121
|
range = sprintf("bytes=%d-%d", offset.to_i, (offset.to_i + size.to_i) - 1)
|
116
122
|
headers['Range'] = range
|
117
123
|
end
|
118
|
-
|
119
|
-
|
120
|
-
response.read_body(&block)
|
124
|
+
begin
|
125
|
+
SwiftClient.get_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name, (CloudFiles.escape self.name), nil, nil, &block)
|
121
126
|
end
|
122
127
|
end
|
123
128
|
|
@@ -140,10 +145,14 @@ module CloudFiles
|
|
140
145
|
def set_metadata(metadatahash)
|
141
146
|
headers = {}
|
142
147
|
metadatahash.each{ |key, value| headers['X-Object-Meta-' + key.to_s.capitalize] = value.to_s }
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
148
|
+
begin
|
149
|
+
SwiftClient.post_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name, (CloudFiles.escape self.name), headers)
|
150
|
+
true
|
151
|
+
rescue ClientException => e
|
152
|
+
raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist" if (e.status.to_s == "404")
|
153
|
+
raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{e.status.to_s}" unless (e.status.to_s =~ /^20/)
|
154
|
+
false
|
155
|
+
end
|
147
156
|
end
|
148
157
|
alias :metadata= :set_metadata
|
149
158
|
|
@@ -164,10 +173,14 @@ module CloudFiles
|
|
164
173
|
# fails.
|
165
174
|
def set_manifest(manifest)
|
166
175
|
headers = {'X-Object-Manifest' => manifest}
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
176
|
+
begin
|
177
|
+
SwiftClient.post_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name, (CloudFiles.escape self.name), headers)
|
178
|
+
true
|
179
|
+
rescue ClientException => e
|
180
|
+
raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist" if (response.code == "404")
|
181
|
+
raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code =~ /^20/)
|
182
|
+
false
|
183
|
+
end
|
171
184
|
end
|
172
185
|
|
173
186
|
|
@@ -201,21 +214,16 @@ module CloudFiles
|
|
201
214
|
|
202
215
|
def write(data = nil, headers = {})
|
203
216
|
raise CloudFiles::Exception::Syntax, "No data or header updates supplied" if ((data.nil? && $stdin.tty?) and headers.empty?)
|
204
|
-
if headers['Content-Type'].nil?
|
205
|
-
type = MIME::Types.type_for(self.name).first.to_s
|
206
|
-
if type.empty?
|
207
|
-
headers['Content-Type'] = "application/octet-stream"
|
208
|
-
else
|
209
|
-
headers['Content-Type'] = type
|
210
|
-
end
|
211
|
-
end
|
212
217
|
# If we're taking data from standard input, send that IO object to cfreq
|
213
218
|
data = $stdin if (data.nil? && $stdin.tty? == false)
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
+
begin
|
220
|
+
response = SwiftClient.put_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name, (CloudFiles.escape self.name), data, nil, nil, nil, nil, headers)
|
221
|
+
rescue ClientException => e
|
222
|
+
code = e.status.to_s
|
223
|
+
raise CloudFiles::Exception::InvalidResponse, "Invalid content-length header sent" if (code == "412")
|
224
|
+
raise CloudFiles::Exception::MisMatchedChecksum, "Mismatched etag" if (code == "422")
|
225
|
+
raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{code}" unless (code =~ /^20./)
|
226
|
+
end
|
219
227
|
make_path(File.dirname(self.name)) if @make_path == true
|
220
228
|
self.refresh
|
221
229
|
true
|
@@ -241,9 +249,13 @@ module CloudFiles
|
|
241
249
|
raise Exception::CDNNotAvailable unless cdn_available?
|
242
250
|
headers = {}
|
243
251
|
headers = {"X-Purge-Email" => email} if email
|
244
|
-
|
245
|
-
|
246
|
-
|
252
|
+
begin
|
253
|
+
SwiftClient.delete_object(self.container.connection.cdnurl, self.container.connection.authtoken, self.container.escaped_name, (CloudFiles.escape self.name), nil, headers)
|
254
|
+
true
|
255
|
+
rescue ClientException => e
|
256
|
+
raise CloudFiles::Exception::Connection, "Error Unable to Purge Object: #{@name}" unless (e.status.to_s =~ /^20.$/)
|
257
|
+
false
|
258
|
+
end
|
247
259
|
end
|
248
260
|
|
249
261
|
# A convenience method to stream data into an object from a local file (or anything that can be loaded by Ruby's open method)
|
@@ -296,6 +308,7 @@ module CloudFiles
|
|
296
308
|
def save_to_filename(filename)
|
297
309
|
File.open(filename, 'wb+') do |f|
|
298
310
|
self.data_stream do |chunk|
|
311
|
+
puts chunk.length
|
299
312
|
f.write chunk
|
300
313
|
end
|
301
314
|
end
|
@@ -359,10 +372,13 @@ module CloudFiles
|
|
359
372
|
headers = {'X-Copy-From' => "#{self.container.name}/#{self.name}", 'Content-Type' => self.content_type.sub(/;.+/, '')}.merge(new_headers)
|
360
373
|
# , 'Content-Type' => self.content_type
|
361
374
|
new_path = "#{CloudFiles.escape new_container}/#{CloudFiles.escape new_name, '/'}"
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
375
|
+
begin
|
376
|
+
response = SwiftClient.put_object(self.container.connection.storageurl, self.container.connection.authtoken, (CloudFiles.escape new_container), (CloudFiles.escape new_name), nil, nil, nil, nil, nil, headers)
|
377
|
+
return CloudFiles::Container.new(self.container.connection, new_container).object(new_name)
|
378
|
+
rescue ClientException => e
|
379
|
+
code = e.status.to_s
|
380
|
+
raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code =~ /^20/)
|
381
|
+
end
|
366
382
|
end
|
367
383
|
|
368
384
|
# Takes the same options as the copy method, only it does a copy followed by a delete on the original object.
|
data/lib/cloudfiles/version.rb
CHANGED
@@ -2,37 +2,25 @@ $:.unshift File.dirname(__FILE__)
|
|
2
2
|
require 'test_helper'
|
3
3
|
|
4
4
|
class CloudfilesAuthenticationTest < Test::Unit::TestCase
|
5
|
-
|
6
|
-
|
7
5
|
def test_good_authentication
|
8
|
-
response = {'x-cdn-management-url' => 'http://cdn.example.com/path', 'x-storage-url' => 'http://cdn.example.com/storage', 'authtoken' => 'dummy_token'}
|
9
|
-
|
10
|
-
|
11
|
-
server.stubs(:get).returns(response)
|
12
|
-
CloudFiles::Authentication.any_instance.stubs(:get_server).returns(server)
|
13
|
-
@connection = stub(:authuser => 'dummy_user', :authkey => 'dummy_key', :cdnmgmthost= => true, :cdnmgmtpath= => true, :cdnmgmtport= => true, :cdnmgmtscheme= => true, :storagehost= => true, :storagepath= => true, :storageport= => true, :storagescheme= => true, :authtoken= => true, :authok= => true, :snet? => false, :auth_url => 'https://auth.api.rackspacecloud.com/v1.0', :cdn_available? => true, :cdn_available= => true)
|
6
|
+
response = ['http://cdn.example.com/storage', 'dummy_token', {'x-cdn-management-url' => 'http://cdn.example.com/path', 'x-storage-url' => 'http://cdn.example.com/storage', 'authtoken' => 'dummy_token'}]
|
7
|
+
SwiftClient.stubs(:get_auth).returns(response)
|
8
|
+
@connection = stub(:authuser => 'dummy_user', :authkey => 'dummy_key', :cdnmgmthost= => true, :cdnmgmtpath= => true, :cdnmgmtport= => true, :cdnmgmtscheme= => true, :storagehost= => true, :storagepath= => true, :storageport= => true, :storagescheme= => true, :authtoken= => true, :authok= => true, :snet? => false, :auth_url => 'https://auth.api.rackspacecloud.com/v1.0', :cdn_available? => true, :cdn_available= => true, :snet => false)
|
14
9
|
result = CloudFiles::Authentication.new(@connection)
|
15
10
|
assert_equal result.class, CloudFiles::Authentication
|
16
11
|
end
|
17
12
|
|
18
13
|
def test_snet_authentication
|
19
|
-
response = {'x-cdn-management-url' => 'http://cdn.example.com/path', 'x-storage-url' => 'http://cdn.example.com/storage', 'authtoken' => 'dummy_token'}
|
20
|
-
|
21
|
-
|
22
|
-
server.stubs(:get).returns(response)
|
23
|
-
CloudFiles::Authentication.any_instance.stubs(:get_server).returns(server)
|
24
|
-
@connection = stub(:authuser => 'dummy_user', :authkey => 'dummy_key', :cdnmgmthost= => true, :cdnmgmtpath= => true, :cdnmgmtport= => true, :cdnmgmtscheme= => true, :storagehost= => true, :storagepath= => true, :storageport= => true, :storagescheme= => true, :authtoken= => true, :authok= => true, :snet? => true, :auth_url => 'https://auth.api.rackspacecloud.com/v1.0', :cdn_available? => true, :cdn_available= => true)
|
14
|
+
response = ['http://cdn.example.com/storage', 'dummy_token', {'x-cdn-management-url' => 'http://cdn.example.com/path', 'x-storage-url' => 'http://cdn.example.com/storage', 'authtoken' => 'dummy_token'}]
|
15
|
+
SwiftClient.stubs(:get_auth).returns(response)
|
16
|
+
@connection = stub(:authuser => 'dummy_user', :authkey => 'dummy_key', :cdnmgmthost= => true, :cdnmgmtpath= => true, :cdnmgmtport= => true, :cdnmgmtscheme= => true, :storagehost= => true, :storagepath= => true, :storageport= => true, :storagescheme= => true, :authtoken= => true, :authok= => true, :snet? => true, :auth_url => 'https://auth.api.rackspacecloud.com/v1.0', :cdn_available? => true, :cdn_available= => true, :snet => true)
|
25
17
|
result = CloudFiles::Authentication.new(@connection)
|
26
18
|
assert_equal result.class, CloudFiles::Authentication
|
27
19
|
end
|
28
20
|
|
29
21
|
def test_bad_authentication
|
30
|
-
|
31
|
-
|
32
|
-
server = mock(:use_ssl= => true, :verify_mode= => true, :start => true)
|
33
|
-
server.stubs(:get).returns(response)
|
34
|
-
CloudFiles::Authentication.any_instance.stubs(:get_server).returns(server)
|
35
|
-
@connection = stub(:authuser => 'bad_user', :authkey => 'bad_key', :authok= => true, :authtoken= => true, :auth_url => 'https://auth.api.rackspacecloud.com/v1.0', :cdn_available? => true)
|
22
|
+
SwiftClient.stubs(:get_auth).returns(nil)
|
23
|
+
@connection = stub(:authuser => 'bad_user', :authkey => 'bad_key', :authok= => true, :authtoken= => true, :auth_url => 'https://auth.api.rackspacecloud.com/v1.0', :cdn_available? => true, :snet? => false)
|
36
24
|
assert_raises(CloudFiles::Exception::Authentication) do
|
37
25
|
result = CloudFiles::Authentication.new(@connection)
|
38
26
|
end
|
@@ -40,10 +28,17 @@ class CloudfilesAuthenticationTest < Test::Unit::TestCase
|
|
40
28
|
|
41
29
|
def test_bad_hostname
|
42
30
|
Net::HTTP.stubs(:new).raises(CloudFiles::Exception::Connection)
|
43
|
-
@connection = stub(:proxy_host => nil, :proxy_port => nil, :authuser => 'bad_user', :authkey => 'bad_key', :authok= => true, :authtoken= => true, :auth_url => 'https://auth.api.rackspacecloud.com/v1.0', :cdn_available? => true)
|
31
|
+
@connection = stub(:proxy_host => nil, :proxy_port => nil, :authuser => 'bad_user', :authkey => 'bad_key', :authok= => true, :authtoken= => true, :auth_url => 'https://auth.api.rackspacecloud.com/v1.0', :cdn_available? => true, :snet? => false)
|
44
32
|
assert_raises(CloudFiles::Exception::Connection) do
|
45
33
|
result = CloudFiles::Authentication.new(@connection)
|
46
34
|
end
|
47
35
|
end
|
48
|
-
|
36
|
+
|
37
|
+
def test_authentication_general_exception
|
38
|
+
SwiftClient.stubs(:get_auth).raises(ClientException.new('foobar'))
|
39
|
+
@connection = stub(:proxy_host => nil, :proxy_port => nil, :authuser => 'bad_user', :authkey => 'bad_key', :authok= => true, :authtoken= => true, :auth_url => 'https://auth.api.rackspacecloud.com/v1.0', :cdn_available? => true, :snet? => false)
|
40
|
+
assert_raises(CloudFiles::Exception::Connection) do
|
41
|
+
result = CloudFiles::Authentication.new(@connection)
|
42
|
+
end
|
43
|
+
end
|
49
44
|
end
|
@@ -0,0 +1,797 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class SwiftClientTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@url = "http://foo.bar:1234/auth/v1.0"
|
8
|
+
@user = "foo_user"
|
9
|
+
@key = "foo_key"
|
10
|
+
@token = 'foo_token'
|
11
|
+
Net::HTTP.any_instance.stubs(:new).stubs({:port => 1234, :address => 'foo.bar', :class => Net::HTTP})
|
12
|
+
@parsed, @conn = SwiftClient.http_connection(@url)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_client_exception
|
16
|
+
foo = ClientException.new("foobar", :http_status => "404")
|
17
|
+
assert_equal "foobar 404", foo.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_chunked_connection_wrapper
|
21
|
+
file = mock("File")
|
22
|
+
file.stubs(:read).returns("this ", "is so", "me da", "ta!", "")
|
23
|
+
file.stubs(:eof?).returns(true)
|
24
|
+
file.stubs(:eof!).returns(true)
|
25
|
+
chunk = ChunkedConnectionWrapper.new(file, 5)
|
26
|
+
assert_equal "this ", chunk.read(123)
|
27
|
+
assert_equal "is so", chunk.read(123)
|
28
|
+
assert_equal "me da", chunk.read(123)
|
29
|
+
assert_equal "ta!", chunk.read(123)
|
30
|
+
assert_equal true, chunk.eof?
|
31
|
+
assert_equal true, chunk.eof!
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_query
|
35
|
+
query = Query.new("foo=bar&baz=quu")
|
36
|
+
query.add("chunky", "bacon")
|
37
|
+
assert_equal "chunky=bacon&baz=quu&foo=bar", query.to_s
|
38
|
+
assert query.has_key? "chunky"
|
39
|
+
query.delete("chunky")
|
40
|
+
assert_equal false, query.has_key?("chunky")
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_http_connection
|
44
|
+
parsed, conn = SwiftClient.http_connection("http://foo.bar:1234/auth/v1.0")
|
45
|
+
assert_equal 'http', parsed.scheme
|
46
|
+
assert_equal 1234, parsed.port
|
47
|
+
assert_equal 'foo.bar', parsed.host
|
48
|
+
assert_equal '/auth/v1.0', parsed.path
|
49
|
+
assert_equal 'foo.bar', conn.address
|
50
|
+
assert_equal 1234, conn.port
|
51
|
+
assert_equal Net::HTTP, conn.class
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_http_connection_with_ssl
|
55
|
+
parsed, conn = SwiftClient.http_connection("https://foo.bar:443/auth/v1.0")
|
56
|
+
assert_equal 'https', parsed.scheme
|
57
|
+
assert_equal 443, parsed.port
|
58
|
+
assert_equal 'foo.bar', parsed.host
|
59
|
+
assert_equal '/auth/v1.0', parsed.path
|
60
|
+
assert_equal 'foo.bar', conn.address
|
61
|
+
assert_equal 443, conn.port
|
62
|
+
assert_equal Net::HTTP, conn.class
|
63
|
+
assert_equal true, conn.use_ssl?
|
64
|
+
assert_equal OpenSSL::SSL::VERIFY_NONE, conn.verify_mode
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_http_connection_with_bad_scheme
|
68
|
+
assert_raises(ClientException) do
|
69
|
+
parsed, conn = SwiftClient.http_connection("ftp://foo.bar:443/auth/v1.0")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_auth
|
74
|
+
response = stub(
|
75
|
+
:code => "200",
|
76
|
+
:header => {'x-storage-url' => 'http://foo.bar:1234/v1/AUTH_test', 'x-storage-token' => 'AUTH_test', 'x-auth-token' => 'AUTH_test', 'content-length' => 0, 'date' => 'Tue, 11 Oct 2011 20:54:06 GMT'}
|
77
|
+
)
|
78
|
+
conn = mock("Net::HTTP")
|
79
|
+
conn.stubs(:started?).returns(true)
|
80
|
+
conn.stubs(:get).returns(response)
|
81
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
82
|
+
assert_nothing_raised do
|
83
|
+
storage_url, token, headers = SwiftClient.get_auth(@url, @user, @key)
|
84
|
+
assert_equal "http://foo.bar:1234/v1/AUTH_test", storage_url
|
85
|
+
assert_equal 'AUTH_test', token
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_auth_with_snet
|
90
|
+
response = stub(
|
91
|
+
:code => "200",
|
92
|
+
:header => {'x-storage-url' => 'http://foo.bar:1234/v1/AUTH_test', 'x-storage-token' => 'AUTH_test', 'x-auth-token' => 'AUTH_test', 'content-length' => 0, 'date' => 'Tue, 11 Oct 2011 20:54:06 GMT'}
|
93
|
+
)
|
94
|
+
conn = mock("Net::HTTP")
|
95
|
+
conn.stubs(:started?).returns(true)
|
96
|
+
conn.stubs(:get).returns(response)
|
97
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
98
|
+
assert_nothing_raised do
|
99
|
+
storage_url, token, headers = SwiftClient.get_auth(@url, @user, @key, true)
|
100
|
+
assert_equal "http://snet-foo.bar:1234/v1/AUTH_test", storage_url
|
101
|
+
assert_equal 'AUTH_test', token
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_auth_fails
|
106
|
+
response = stub(:code => '500', :message => "Internal Server Error")
|
107
|
+
conn = mock("Net::HTTP")
|
108
|
+
conn.stubs(:address).returns('foobar.com')
|
109
|
+
conn.stubs(:port).returns(123)
|
110
|
+
conn.stubs(:started?).returns(false)
|
111
|
+
conn.stubs(:start).returns(nil)
|
112
|
+
conn.stubs(:get).returns(response)
|
113
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
114
|
+
|
115
|
+
assert_raise(ClientException) do
|
116
|
+
SwiftClient.get_auth(@url, @user, @key)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
#test HEAD account
|
121
|
+
def test_head_account
|
122
|
+
response = stub(
|
123
|
+
:code => "200",
|
124
|
+
:header => {'x-account-object-count' => 123, 'x-account-bytes-used' => 123456, 'x-account-container-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'}
|
125
|
+
)
|
126
|
+
conn = mock("Net::HTTP")
|
127
|
+
conn.stubs(:started?).returns(true)
|
128
|
+
conn.stubs(:head).returns(response)
|
129
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
130
|
+
assert_nothing_raised do
|
131
|
+
headers = SwiftClient.head_account(@url, @token)
|
132
|
+
assert_equal headers['x-account-object-count'], 123
|
133
|
+
assert_equal headers['x-account-bytes-used'], 123456
|
134
|
+
assert_equal headers['x-account-container-count'], 12
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_head_account_fail
|
139
|
+
response = stub(
|
140
|
+
:code => "500",
|
141
|
+
:message => "Internal Error"
|
142
|
+
)
|
143
|
+
conn = mock("Net::HTTP")
|
144
|
+
conn.stubs(:address).returns("foobar.com")
|
145
|
+
conn.stubs(:port).returns(123)
|
146
|
+
conn.stubs(:started?).returns(true)
|
147
|
+
conn.stubs(:head).returns(response)
|
148
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
149
|
+
assert_raise(ClientException) do
|
150
|
+
headers = SwiftClient.head_account(@url, @token)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
#test GET account
|
155
|
+
def test_get_account
|
156
|
+
response = stub(
|
157
|
+
:code => "200",
|
158
|
+
:body => '[ { "name":".CDN_ACCESS_LOGS", "count":1, "bytes":1234 }, { "name":"First", "count":2, "bytes":2345 }, { "name":"Second", "count":3, "bytes":3456 }, { "name":"Third", "count":4, "bytes":4567 } ]',
|
159
|
+
:header => {'x-account-object-count' => 123, 'x-account-bytes-used' => 123456, 'x-account-container-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'}
|
160
|
+
)
|
161
|
+
conn = mock("Net::HTTP")
|
162
|
+
conn.stubs(:started?).returns(true)
|
163
|
+
conn.stubs(:get).returns(response)
|
164
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
165
|
+
assert_nothing_raised do
|
166
|
+
headers, result = SwiftClient.get_account(@url, @token)
|
167
|
+
assert_equal headers, response.header
|
168
|
+
assert_equal result, JSON.parse(response.body)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_get_account_no_content
|
173
|
+
response = stub(
|
174
|
+
:code => "204",
|
175
|
+
:body => nil,
|
176
|
+
:header => {'x-account-object-count' => 123, 'x-account-bytes-used' => 123456, 'x-account-container-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'}
|
177
|
+
)
|
178
|
+
conn = mock("Net::HTTP")
|
179
|
+
conn.stubs(:started?).returns(true)
|
180
|
+
conn.stubs(:get).returns(response)
|
181
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
182
|
+
assert_nothing_raised do
|
183
|
+
headers, result = SwiftClient.get_account(@url, @token)
|
184
|
+
assert_equal headers, response.header
|
185
|
+
assert_equal result, []
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_get_account_marker
|
190
|
+
response = stub(
|
191
|
+
:code => "200",
|
192
|
+
:body => '[ { "name":"Second", "count":3, "bytes":3456 }, { "name":"Third", "count":4, "bytes":4567 } ]',
|
193
|
+
:header => {'x-account-object-count' => 123, 'x-account-bytes-used' => 123456, 'x-account-container-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'}
|
194
|
+
)
|
195
|
+
conn = mock("Net::HTTP")
|
196
|
+
conn.stubs(:started?).returns(true)
|
197
|
+
conn.stubs(:get).returns(response)
|
198
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
199
|
+
assert_nothing_raised do
|
200
|
+
headers, result = SwiftClient.get_account(@url, @token, "First")
|
201
|
+
assert_equal headers, response.header
|
202
|
+
assert_equal result, JSON.parse(response.body)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_get_account_limit
|
207
|
+
response = stub(
|
208
|
+
:code => "200",
|
209
|
+
:body => '[ { "name":".CDN_ACCESS_LOGS", "count":1, "bytes":1234 }, { "name":"First", "count":2, "bytes":2345 } ]',
|
210
|
+
:header => {'x-account-object-count' => 123, 'x-account-bytes-used' => 123456, 'x-account-container-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'}
|
211
|
+
)
|
212
|
+
conn = mock("Net::HTTP")
|
213
|
+
conn.stubs(:started?).returns(true)
|
214
|
+
conn.stubs(:get).returns(response)
|
215
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
216
|
+
assert_nothing_raised do
|
217
|
+
headers, result = SwiftClient.get_account(@url, @token, nil, 2)
|
218
|
+
assert_equal headers, response.header
|
219
|
+
assert_equal result, JSON.parse(response.body)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_get_account_prefix
|
224
|
+
response = stub(
|
225
|
+
:code => "200",
|
226
|
+
:body => '[ { "name":"First", "count":2, "bytes":2345 } ]',
|
227
|
+
:header => {'x-account-object-count' => 123, 'x-account-bytes-used' => 123456, 'x-account-container-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'}
|
228
|
+
)
|
229
|
+
conn = mock("Net::HTTP")
|
230
|
+
conn.stubs(:started?).returns(true)
|
231
|
+
conn.stubs(:get).returns(response)
|
232
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
233
|
+
assert_nothing_raised do
|
234
|
+
headers, result = SwiftClient.get_account(@url, @token, nil, nil, "F")
|
235
|
+
assert_equal headers, response.header
|
236
|
+
assert_equal result, JSON.parse(response.body)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_get_account_full_listing
|
241
|
+
response1 = stub(
|
242
|
+
:code => "200",
|
243
|
+
:body => '[ { "name":".CDN_ACCESS_LOGS", "count":1, "bytes":1234 }, { "name":"First", "count":2, "bytes":2345 }, { "name":"Second", "count":3, "bytes":3456 }, { "name":"Third", "count":4, "bytes":4567 } ]',
|
244
|
+
:header => {'x-account-object-count' => 123, 'x-account-bytes-used' => 123456, 'x-account-container-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'}
|
245
|
+
)
|
246
|
+
response2 = stub(
|
247
|
+
:code => "200",
|
248
|
+
:body => '[ { "name":"Fourth", "count":1, "bytes":1234 }, { "name":"Fifth", "count":2, "bytes":2345 }, { "name":"Sixth", "count":3, "bytes":3456 }, { "name":"Seventh", "count":4, "bytes":4567 } ]',
|
249
|
+
:header => {'x-account-object-count' => 123, 'x-account-bytes-used' => 123456, 'x-account-container-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'}
|
250
|
+
)
|
251
|
+
response3 = stub(
|
252
|
+
:code => "200",
|
253
|
+
:body => '[]',
|
254
|
+
:header => {'x-account-object-count' => 123, 'x-account-bytes-used' => 123456, 'x-account-container-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'}
|
255
|
+
)
|
256
|
+
|
257
|
+
conn = mock("Net::HTTP")
|
258
|
+
conn.stubs(:started?).returns(true)
|
259
|
+
conn.stubs(:get).at_least(3).at_most(3).returns(response1, response2, response3)
|
260
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
261
|
+
assert_nothing_raised do
|
262
|
+
headers, result = SwiftClient.get_account(@url, @token, nil, nil, nil, nil, true)
|
263
|
+
assert_equal headers, response1.header
|
264
|
+
assert_equal JSON.parse(response1.body) + JSON.parse(response2.body) + JSON.parse(response3.body), result
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_get_account_fail
|
269
|
+
response = stub(
|
270
|
+
:code => "500",
|
271
|
+
:message => "Internal Error"
|
272
|
+
)
|
273
|
+
conn = mock("Net::HTTP")
|
274
|
+
conn.stubs(:address).returns("foobar.com")
|
275
|
+
conn.stubs(:port).returns(123)
|
276
|
+
conn.stubs(:started?).returns(true)
|
277
|
+
conn.stubs(:get).returns(response)
|
278
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
279
|
+
assert_raise(ClientException) do
|
280
|
+
headers = SwiftClient.get_account(@url, @token)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
#test POST account
|
285
|
+
def test_post_account
|
286
|
+
response = stub(:code => 204, :body => nil)
|
287
|
+
conn = mock("Net::HTTP")
|
288
|
+
conn.stubs(:started?).returns(true)
|
289
|
+
conn.stubs(:post).returns(response)
|
290
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
291
|
+
assert_nothing_raised do
|
292
|
+
SwiftClient.post_account(@url, @token, {"foo" => "bar"})
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def test_post_account_fail
|
297
|
+
response = stub(
|
298
|
+
:code => "500",
|
299
|
+
:message => "Internal Error"
|
300
|
+
)
|
301
|
+
conn = mock("Net::HTTP")
|
302
|
+
conn.stubs(:address).returns("foobar.com")
|
303
|
+
conn.stubs(:port).returns(123)
|
304
|
+
conn.stubs(:started?).returns(true)
|
305
|
+
conn.stubs(:post).returns(response)
|
306
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
307
|
+
assert_raise(ClientException) do
|
308
|
+
headers = SwiftClient.post_account(@url, @token, {"foo" => "bar"})
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
#test HEAD container
|
313
|
+
def test_head_container
|
314
|
+
response = stub(
|
315
|
+
:code => "204",
|
316
|
+
:header => {'x-container-object-count' => 6, 'x-container-meta-baz' => 'que', 'x-container-meta-foo' => 'bar', 'x-container-bytes-used' => 123456, 'accept-ranges' => 'bytes', 'content-length' => 83, 'content-type' => 'text/plain; charset=utf-8', 'x-trans-id' => 'txfoo123', 'date' => 'Thu, 13 Oct 2011 22:29:14 GMT'}
|
317
|
+
)
|
318
|
+
conn = mock("Net::HTTP")
|
319
|
+
conn.stubs(:started?).returns(true)
|
320
|
+
conn.stubs(:head).returns(response)
|
321
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
322
|
+
assert_nothing_raised do
|
323
|
+
headers = SwiftClient.head_container(@url, @token, 'test_container')
|
324
|
+
assert_equal headers, response.header
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def test_head_container_fail
|
329
|
+
response = stub(:code => "500", :message => "failed")
|
330
|
+
conn = mock("Net::HTTP")
|
331
|
+
conn.stubs(:address).returns("foobar.com")
|
332
|
+
conn.stubs(:port).returns(123)
|
333
|
+
conn.stubs(:started?).returns(true)
|
334
|
+
conn.stubs(:head).returns(response)
|
335
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
336
|
+
|
337
|
+
assert_raise(ClientException) do
|
338
|
+
headers, result = SwiftClient.head_container(@url, @token, 'test_container')
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
#test GET container
|
343
|
+
def test_get_container
|
344
|
+
response = stub(
|
345
|
+
:code => "200",
|
346
|
+
:header => {'x-container-object-count' => 6, 'x-container-meta-baz' => 'que', 'x-container-meta-foo' => 'bar', 'x-container-bytes-used' => 123456, 'accept-ranges' => 'bytes', 'content-length' => 83, 'content-type' => 'text/plain; charset=utf-8', 'x-trans-id' => 'txfoo123', 'date' => 'Thu, 13 Oct 2011 22:29:14 GMT'},
|
347
|
+
:body => '[ { "name":"foo.mp4", "hash":"foo_hash", "bytes":1234567, "content_type":"video/mp4", "last_modified":"2011-06-21T19:49:06.607670" }, { "name":"bar.ogv", "hash":"bar_hash", "bytes":987654, "content_type":"video/ogg", "last_modified":"2011-06-21T19:48:57.504050" }, { "name":"baz.webm", "hash":"baz_hash", "bytes":1239874, "content_type":"application/octet-stream", "last_modified":"2011-06-21T19:48:43.923990" }, { "name":"fobarbaz.html", "hash":"foobarbaz_hash", "bytes":12893467, "content_type":"text/html", "last_modified":"2011-06-21T19:54:36.555070" } ]'
|
348
|
+
)
|
349
|
+
conn = mock("Net::HTTP")
|
350
|
+
conn.stubs(:started?).returns(true)
|
351
|
+
conn.stubs(:get).returns(response)
|
352
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
353
|
+
assert_nothing_raised do
|
354
|
+
headers, result = SwiftClient.get_container(@url, @token, 'test_container')
|
355
|
+
assert_equal headers, response.header
|
356
|
+
assert_equal result, JSON.parse(response.body)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
|
361
|
+
def test_get_container_no_content
|
362
|
+
response = stub(
|
363
|
+
:code => "204",
|
364
|
+
:body => nil,
|
365
|
+
:header => {'x-container-object-count' => 123, 'x-container-bytes-used' => 123456, 'x-container-object-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'}
|
366
|
+
)
|
367
|
+
conn = mock("Net::HTTP")
|
368
|
+
conn.stubs(:started?).returns(true)
|
369
|
+
conn.stubs(:get).returns(response)
|
370
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
371
|
+
assert_nothing_raised do
|
372
|
+
headers, result = SwiftClient.get_container(@url, @token, 'test_container')
|
373
|
+
assert_equal headers, response.header
|
374
|
+
assert_equal result, []
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
def test_get_container_marker
|
379
|
+
response = stub(
|
380
|
+
:code => "200",
|
381
|
+
:body => '[ { "name":"bar.ogv", "hash":"bar_hash", "bytes":987654, "content_type":"video/ogg", "last_modified":"2011-06-21T19:48:57.504050" }, { "name":"baz.webm", "hash":"baz_hash", "bytes":1239874, "content_type":"application/octet-stream", "last_modified":"2011-06-21T19:48:43.923990" }, { "name":"fobarbaz.html", "hash":"foobarbaz_hash", "bytes":12893467, "content_type":"text/html", "last_modified":"2011-06-21T19:54:36.555070" } ]',
|
382
|
+
:header => {'x-container-object-count' => 123, 'x-container-bytes-used' => 123456, 'x-container-object-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'}
|
383
|
+
)
|
384
|
+
conn = mock("Net::HTTP")
|
385
|
+
conn.stubs(:started?).returns(true)
|
386
|
+
conn.stubs(:get).returns(response)
|
387
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
388
|
+
assert_nothing_raised do
|
389
|
+
headers, result = SwiftClient.get_container(@url, @token, "test_container", "foo.mp4")
|
390
|
+
assert_equal headers, response.header
|
391
|
+
assert_equal result, JSON.parse(response.body)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
def test_get_container_limit
|
396
|
+
response = stub(
|
397
|
+
:code => "200",
|
398
|
+
:body => '[ { "name":"foo.mp4", "hash":"foo_hash", "bytes":1234567, "content_type":"video/mp4", "last_modified":"2011-06-21T19:49:06.607670" }, { "name":"bar.ogv", "hash":"bar_hash", "bytes":987654, "content_type":"video/ogg", "last_modified":"2011-06-21T19:48:57.504050" } ]',
|
399
|
+
:header => {'x-container-object-count' => 123, 'x-container-bytes-used' => 123456, 'x-container-object-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'}
|
400
|
+
)
|
401
|
+
conn = mock("Net::HTTP")
|
402
|
+
conn.stubs(:started?).returns(true)
|
403
|
+
conn.stubs(:get).returns(response)
|
404
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
405
|
+
assert_nothing_raised do
|
406
|
+
headers, result = SwiftClient.get_container(@url, @token, 'test_container', nil, 2)
|
407
|
+
assert_equal headers, response.header
|
408
|
+
assert_equal result, JSON.parse(response.body)
|
409
|
+
assert_equal result.length, 2
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
def test_get_container_prefix
|
414
|
+
response = stub(
|
415
|
+
:code => "200",
|
416
|
+
:body => '[ { "name":"bar.ogv", "hash":"bar_hash", "bytes":987654, "content_type":"video/ogg", "last_modified":"2011-06-21T19:48:57.504050" }, { "name":"baz.webm", "hash":"baz_hash", "bytes":1239874, "content_type":"application/octet-stream", "last_modified":"2011-06-21T19:48:43.923990" }]',
|
417
|
+
:header => {'x-container-object-count' => 123, 'x-container-bytes-used' => 123456, 'x-container-object-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'}
|
418
|
+
)
|
419
|
+
conn = mock("Net::HTTP")
|
420
|
+
conn.stubs(:started?).returns(true)
|
421
|
+
conn.stubs(:get).returns(response)
|
422
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
423
|
+
assert_nothing_raised do
|
424
|
+
headers, result = SwiftClient.get_container(@url, @token, 'test_container', nil, nil, "b")
|
425
|
+
assert_equal headers, response.header
|
426
|
+
assert_equal result, JSON.parse(response.body)
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
def test_get_container_full_listing
|
431
|
+
response1 = stub(
|
432
|
+
:code => "200",
|
433
|
+
:header => {'x-container-object-count' => 6, 'x-container-meta-baz' => 'que', 'x-container-meta-foo' => 'bar', 'x-container-bytes-used' => 123456, 'accept-ranges' => 'bytes', 'content-length' => 83, 'content-type' => 'text/plain; charset=utf-8', 'x-trans-id' => 'txfoo123', 'date' => 'Thu, 13 Oct 2011 22:29:14 GMT'},
|
434
|
+
:body => '[ { "name":"foo.mp4", "hash":"foo_hash", "bytes":1234567, "content_type":"video/mp4", "last_modified":"2011-06-21T19:49:06.607670" }, { "name":"bar.ogv", "hash":"bar_hash", "bytes":987654, "content_type":"video/ogg", "last_modified":"2011-06-21T19:48:57.504050" }, { "name":"baz.webm", "hash":"baz_hash", "bytes":1239874, "content_type":"application/octet-stream", "last_modified":"2011-06-21T19:48:43.923990" }, { "name":"fobarbaz.html", "hash":"foobarbaz_hash", "bytes":12893467, "content_type":"text/html", "last_modified":"2011-06-21T19:54:36.555070" } ]'
|
435
|
+
)
|
436
|
+
response2 = stub(
|
437
|
+
:code => "200",
|
438
|
+
:header => {'x-container-object-count' => 6, 'x-container-meta-baz' => 'que', 'x-container-meta-foo' => 'bar', 'x-container-bytes-used' => 123456, 'accept-ranges' => 'bytes', 'content-length' => 83, 'content-type' => 'text/plain; charset=utf-8', 'x-trans-id' => 'txfoo123', 'date' => 'Thu, 13 Oct 2011 22:29:14 GMT'},
|
439
|
+
:body => '[ { "name":"foo2.mp4", "hash":"foo_hash", "bytes":1234567, "content_type":"video/mp4", "last_modified":"2011-06-21T19:49:06.607670" }, { "name":"bar2.ogv", "hash":"bar_hash", "bytes":987654, "content_type":"video/ogg", "last_modified":"2011-06-21T19:48:57.504050" }, { "name":"baz2.webm", "hash":"baz_hash", "bytes":1239874, "content_type":"application/octet-stream", "last_modified":"2011-06-21T19:48:43.923990" }, { "name":"fobarbaz2.html", "hash":"foobarbaz_hash", "bytes":12893467, "content_type":"text/html", "last_modified":"2011-06-21T19:54:36.555070" } ]'
|
440
|
+
)
|
441
|
+
response3 = stub(
|
442
|
+
:code => "200",
|
443
|
+
:header => {'x-container-object-count' => 6, 'x-container-meta-baz' => 'que', 'x-container-meta-foo' => 'bar', 'x-container-bytes-used' => 123456, 'accept-ranges' => 'bytes', 'content-length' => 83, 'content-type' => 'text/plain; charset=utf-8', 'x-trans-id' => 'txfoo123', 'date' => 'Thu, 13 Oct 2011 22:29:14 GMT'},
|
444
|
+
:body => '[]'
|
445
|
+
)
|
446
|
+
|
447
|
+
conn = mock("Net::HTTP")
|
448
|
+
conn.stubs(:started?).returns(true)
|
449
|
+
conn.stubs(:get).at_least(3).at_most(3).returns(response1, response2, response3)
|
450
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
451
|
+
assert_nothing_raised do
|
452
|
+
headers, result = SwiftClient.get_container(@url, @token, 'test_container', nil, nil, nil, nil, nil, true)
|
453
|
+
assert_equal headers, response1.header
|
454
|
+
assert_equal JSON.parse(response1.body) + JSON.parse(response2.body) + JSON.parse(response3.body), result
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
def test_get_container_fail
|
459
|
+
response = stub(:code => "500", :message => "failed")
|
460
|
+
conn = mock("Net::HTTP")
|
461
|
+
conn.stubs(:address).returns("foobar.com")
|
462
|
+
conn.stubs(:port).returns(123)
|
463
|
+
conn.stubs(:started?).returns(true)
|
464
|
+
conn.stubs(:get).returns(response)
|
465
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
466
|
+
|
467
|
+
assert_raise(ClientException) do
|
468
|
+
headers, result = SwiftClient.get_container(@url, @token, 'test_container')
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
#test PUT container
|
473
|
+
def test_put_container
|
474
|
+
response = stub(:code => "200")
|
475
|
+
conn = mock("Net::HTTP")
|
476
|
+
conn.stubs(:started?).returns(true)
|
477
|
+
conn.stubs(:put).returns(response)
|
478
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
479
|
+
|
480
|
+
assert_nothing_raised do
|
481
|
+
headers, result = SwiftClient.put_container(@url, @token, 'test_container')
|
482
|
+
end
|
483
|
+
end
|
484
|
+
|
485
|
+
def test_put_container_fail
|
486
|
+
response = stub(:code => "500", :message => "failed")
|
487
|
+
conn = mock("Net::HTTP")
|
488
|
+
conn.stubs(:address).returns("foobar.com")
|
489
|
+
conn.stubs(:port).returns(123)
|
490
|
+
conn.stubs(:started?).returns(true)
|
491
|
+
conn.stubs(:put).returns(response)
|
492
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
493
|
+
|
494
|
+
assert_raise(ClientException) do
|
495
|
+
headers, result = SwiftClient.put_container(@url, @token, 'test_container')
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
#test POST container
|
500
|
+
def test_post_container
|
501
|
+
response = stub(:code => "200")
|
502
|
+
conn = mock("Net::HTTP")
|
503
|
+
conn.stubs(:started?).returns(true)
|
504
|
+
conn.stubs(:post).returns(response)
|
505
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
506
|
+
|
507
|
+
assert_nothing_raised do
|
508
|
+
headers, result = SwiftClient.post_container(@url, @token, 'test_container', {'x-container-metadata-foo' => 'bar'})
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
def test_post_container_fail
|
513
|
+
response = stub(:code => "500", :message => "failed")
|
514
|
+
conn = mock("Net::HTTP")
|
515
|
+
conn.stubs(:address).returns("foobar.com")
|
516
|
+
conn.stubs(:port).returns(123)
|
517
|
+
conn.stubs(:started?).returns(true)
|
518
|
+
conn.stubs(:post).returns(response)
|
519
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
520
|
+
|
521
|
+
assert_raise(ClientException) do
|
522
|
+
headers, result = SwiftClient.post_container(@url, @token, 'test_container', {'x-container-metadata-foo' => 'bar'})
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
#test DELETE container
|
527
|
+
def test_delete_container
|
528
|
+
response = stub(:code => "200", :body => "")
|
529
|
+
conn = mock("Net::HTTP")
|
530
|
+
conn.stubs(:started?).returns(true)
|
531
|
+
conn.stubs(:delete).returns(response)
|
532
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
533
|
+
|
534
|
+
assert_nothing_raised do
|
535
|
+
SwiftClient.delete_container(@url, @token, 'test_container')
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
def test_delete_container_fails
|
540
|
+
response = stub(:code => "500", :message => "failed")
|
541
|
+
conn = mock("Net::HTTP")
|
542
|
+
conn.stubs(:address).returns("foobar.com")
|
543
|
+
conn.stubs(:port).returns(123)
|
544
|
+
conn.stubs(:started?).returns(true)
|
545
|
+
conn.stubs(:delete).returns(response)
|
546
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
547
|
+
|
548
|
+
assert_raise(ClientException) do
|
549
|
+
SwiftClient.delete_container(@url, @token, 'test_container')
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
#test HEAD object
|
554
|
+
def test_head_object
|
555
|
+
response = stub(:code => "204", :header => {'etag' => 'etag_foobarbaz', 'accept-ranges' => 'bytes', 'content-length' => 67773, 'content-type' => 'application/javascript', 'x-trans-id' => 'txfoobar', 'date' => 'Fri, 14 Oct 2011 01:21:42 GMT'})
|
556
|
+
conn = mock("Net::HTTP")
|
557
|
+
conn.stubs(:port).returns(123)
|
558
|
+
conn.stubs(:started?).returns(true)
|
559
|
+
conn.stubs(:head).returns(response)
|
560
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
561
|
+
|
562
|
+
assert_nothing_raised do
|
563
|
+
headers = SwiftClient.head_object(@url, @token, 'test_container', 'test_object')
|
564
|
+
assert response.header, headers
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
def test_head_object_fails
|
569
|
+
response = stub(:code => "500", :message => "failed")
|
570
|
+
conn = mock("Net::HTTP")
|
571
|
+
conn.stubs(:address).returns("foobar.com")
|
572
|
+
conn.stubs(:port).returns(123)
|
573
|
+
conn.stubs(:started?).returns(true)
|
574
|
+
conn.stubs(:head).returns(response)
|
575
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
576
|
+
|
577
|
+
assert_raise(ClientException) do
|
578
|
+
headers = SwiftClient.head_object(@url, @token, 'test_container', 'test_object')
|
579
|
+
end
|
580
|
+
end
|
581
|
+
|
582
|
+
#test GET object
|
583
|
+
def test_get_object
|
584
|
+
response = stub(
|
585
|
+
:code => "200",
|
586
|
+
:header => {'etag' => 'etag_foobarbaz', 'accept-ranges' => 'bytes', 'content-length' => 67773, 'content-type' => 'application/javascript', 'x-trans-id' => 'txfoobar', 'date' => 'Fri, 14 Oct 2011 01:21:42 GMT'},
|
587
|
+
:body => "this is the body"
|
588
|
+
)
|
589
|
+
conn = mock("Net::HTTP")
|
590
|
+
conn.stubs(:port).returns(123)
|
591
|
+
conn.stubs(:address).returns("foobar.com")
|
592
|
+
conn.stubs(:started?).returns(true)
|
593
|
+
conn.stubs(:request_get).returns(response)
|
594
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
595
|
+
|
596
|
+
assert_nothing_raised do
|
597
|
+
headers, body = SwiftClient.get_object(@url, @token, 'test_container', 'test_object')
|
598
|
+
assert_equal response.header, headers
|
599
|
+
assert_equal body, "this is the body"
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
def test_get_object_fails
|
604
|
+
response = stub(:code => "404", :message => "object not found", :body => "")
|
605
|
+
conn = mock("Net::HTTP")
|
606
|
+
conn.stubs(:port).returns(123)
|
607
|
+
conn.stubs(:address).returns("foobar.com")
|
608
|
+
conn.stubs(:started?).returns(true)
|
609
|
+
conn.stubs(:request_get).returns(response)
|
610
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
611
|
+
|
612
|
+
assert_raise(ClientException) do
|
613
|
+
headers, body = SwiftClient.get_object(@url, @token, 'test_container', 'test_object')
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
617
|
+
#test PUT object
|
618
|
+
def test_put_object
|
619
|
+
response = stub(
|
620
|
+
:code => "201",
|
621
|
+
:header => {"Content-Length" => 118, "Content-Type" => "text/html; charset=UTF-8", "Etag" => "asfasdfsdafasd2313241ukyhuyhj", "X-Trans-Id" => "txfoo1231231231232123"},
|
622
|
+
:message => "created",
|
623
|
+
:body => ""
|
624
|
+
)
|
625
|
+
conn = mock("Net::HTTP")
|
626
|
+
conn.stubs(:port).returns(123)
|
627
|
+
conn.stubs(:address).returns("foobar.com")
|
628
|
+
conn.stubs(:started?).returns(true)
|
629
|
+
conn.stubs(:put).returns(response)
|
630
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
631
|
+
assert_nothing_raised do
|
632
|
+
SwiftClient.put_object(@url, @token, 'test_container', 'test_object', 'some data to put', 16)
|
633
|
+
end
|
634
|
+
end
|
635
|
+
|
636
|
+
def test_put_object_fails
|
637
|
+
response = stub(
|
638
|
+
:code => "500",
|
639
|
+
:message => "internal server error",
|
640
|
+
:body => ""
|
641
|
+
)
|
642
|
+
conn = mock("Net::HTTP")
|
643
|
+
conn.stubs(:port).returns(123)
|
644
|
+
conn.stubs(:address).returns("foobar.com")
|
645
|
+
conn.stubs(:started?).returns(true)
|
646
|
+
conn.stubs(:put).returns(response)
|
647
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
648
|
+
assert_raise(ClientException) do
|
649
|
+
SwiftClient.put_object(@url, @token, 'test_container', 'test_object', 'some data to put', 16)
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
653
|
+
#test POST object
|
654
|
+
def test_post_object
|
655
|
+
response = stub(
|
656
|
+
:code => "201",
|
657
|
+
:header => {"Content-Length" => 118, "Content-Type" => "text/html; charset=UTF-8", "Etag" => "asfasdfsdafasd2313241ukyhuyhj", "X-Trans-Id" => "txfoo1231231231232123", "X-Object-Meta-Foo" => "Bar"},
|
658
|
+
:message => "created",
|
659
|
+
:body => ""
|
660
|
+
)
|
661
|
+
conn = mock("Net::HTTP")
|
662
|
+
conn.stubs(:port).returns(123)
|
663
|
+
conn.stubs(:address).returns("foobar.com")
|
664
|
+
conn.stubs(:started?).returns(true)
|
665
|
+
conn.stubs(:post).returns(response)
|
666
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
667
|
+
assert_nothing_raised do
|
668
|
+
headers = SwiftClient.post_object(@url, @token, 'test_container', 'test_object', {"Foo" => "Bar"})
|
669
|
+
end
|
670
|
+
end
|
671
|
+
|
672
|
+
def test_post_object_fails
|
673
|
+
response = stub(
|
674
|
+
:code => "404",
|
675
|
+
:message => "no such object",
|
676
|
+
:body => ""
|
677
|
+
)
|
678
|
+
conn = mock("Net::HTTP")
|
679
|
+
conn.stubs(:port).returns(123)
|
680
|
+
conn.stubs(:address).returns("foobar.com")
|
681
|
+
conn.stubs(:started?).returns(true)
|
682
|
+
conn.stubs(:post).returns(response)
|
683
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
684
|
+
assert_raise(ClientException) do
|
685
|
+
SwiftClient.post_object(@url, @token, 'test_container', 'test_object', {"foo" => "bar"})
|
686
|
+
end
|
687
|
+
end
|
688
|
+
|
689
|
+
#test DELETE object
|
690
|
+
def test_delete_object
|
691
|
+
response = stub(
|
692
|
+
:code => "204",
|
693
|
+
:message => "no content",
|
694
|
+
:body => ""
|
695
|
+
)
|
696
|
+
conn = mock("Net::HTTP")
|
697
|
+
conn.stubs(:started?).returns(true)
|
698
|
+
conn.stubs(:delete).returns(response)
|
699
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
700
|
+
assert_nothing_raised do
|
701
|
+
SwiftClient.delete_object(@url, @token, 'test_container', 'test_object')
|
702
|
+
end
|
703
|
+
end
|
704
|
+
|
705
|
+
def test_delete_object_fails
|
706
|
+
response = stub(
|
707
|
+
:code => "404",
|
708
|
+
:message => "no such object",
|
709
|
+
:body => ""
|
710
|
+
)
|
711
|
+
conn = mock("Net::HTTP")
|
712
|
+
conn.stubs(:port).returns(123)
|
713
|
+
conn.stubs(:address).returns("foobar.com")
|
714
|
+
conn.stubs(:started?).returns(true)
|
715
|
+
conn.stubs(:delete).returns(response)
|
716
|
+
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
717
|
+
assert_raise(ClientException) do
|
718
|
+
SwiftClient.delete_object(@url, @token, 'test_container', 'test_object')
|
719
|
+
end
|
720
|
+
end
|
721
|
+
|
722
|
+
def test_retry_failse
|
723
|
+
auth_response = ['http://foo.bar:1234/v1/AUTH_test', 'AUTH_test', {'x-storage-url' => 'http://foo.bar:1234/v1/AUTH_test', 'x-storage-token' => 'AUTH_test', 'x-auth-token' => 'AUTH_test', 'content-length' => 0, 'date' => 'Tue, 11 Oct 2011 20:54:06 GMT'}]
|
724
|
+
SwiftClient.expects(:get_auth).returns(auth_response)
|
725
|
+
SwiftClient.any_instance.stubs(:http_connection).raises(ClientException.new("foobar"))
|
726
|
+
sc = SwiftClient.new(@url, @user, @key)
|
727
|
+
sc.get_auth
|
728
|
+
assert_raise(ClientException) do
|
729
|
+
sc.get_container("test_container")
|
730
|
+
end
|
731
|
+
end
|
732
|
+
|
733
|
+
def test_oop_swiftclient
|
734
|
+
auth_response = ['http://foo.bar:1234/v1/AUTH_test', 'AUTH_test', {'x-storage-url' => 'http://foo.bar:1234/v1/AUTH_test', 'x-storage-token' => 'AUTH_test', 'x-auth-token' => 'AUTH_test', 'content-length' => 0, 'date' => 'Tue, 11 Oct 2011 20:54:06 GMT'}]
|
735
|
+
account_response = [
|
736
|
+
{'x-account-object-count' => 123, 'x-account-bytes-used' => 123456, 'x-account-container-count' => 12, 'accept-ranges' => 'bytes', 'content-length' => 12345, 'content-type' => 'application/json; charset=utf-8', 'x-trans-id' => 'txfoobar', 'date' => 'Thu, 13 Oct 2011 21:04:14 GMT'},
|
737
|
+
JSON.parse('[ { "name":".CDN_ACCESS_LOGS", "count":1, "bytes":1234 }, { "name":"First", "count":2, "bytes":2345 }, { "name":"Second", "count":3, "bytes":3456 }, { "name":"Third", "count":4, "bytes":4567 } ]')
|
738
|
+
]
|
739
|
+
container_response = [
|
740
|
+
{'x-container-object-count' => 6, 'x-container-meta-baz' => 'que', 'x-container-meta-foo' => 'bar', 'x-container-bytes-used' => 123456, 'accept-ranges' => 'bytes', 'content-length' => 83, 'content-type' => 'text/plain; charset=utf-8', 'x-trans-id' => 'txfoo123', 'date' => 'Thu, 13 Oct 2011 22:29:14 GMT'},
|
741
|
+
JSON.parse('[ { "name":"foo.mp4", "hash":"foo_hash", "bytes":1234567, "content_type":"video/mp4", "last_modified":"2011-06-21T19:49:06.607670" }, { "name":"bar.ogv", "hash":"bar_hash", "bytes":987654, "content_type":"video/ogg", "last_modified":"2011-06-21T19:48:57.504050" }, { "name":"baz.webm", "hash":"baz_hash", "bytes":1239874, "content_type":"application/octet-stream", "last_modified":"2011-06-21T19:48:43.923990" }, { "name":"fobarbaz.html", "hash":"foobarbaz_hash", "bytes":12893467, "content_type":"text/html", "last_modified":"2011-06-21T19:54:36.555070" } ]')
|
742
|
+
]
|
743
|
+
object_response = [
|
744
|
+
{'Last-Modified' => 'Tue, 01 Jan 2011 00:00:01 GMT', 'Etag' => 'somelarge123hashthingy123foobar', 'Accept-Ranges' => 'bytes', 'Content-Length' => 29, 'Content-Type' => 'application/x-www-form-urlencoded', 'X-Trans-Id' => 'txffffffff00000001231231232112321', 'Date' => 'Tue, 01 Jan 2011 00:00:02 GMT', 'foo' => 'bar'},
|
745
|
+
"some data that is from swift"
|
746
|
+
]
|
747
|
+
SwiftClient.expects(:http_connection).returns(Net::HTTPExceptions, [@parsed, @conn])
|
748
|
+
SwiftClient.expects(:get_auth).returns(auth_response)
|
749
|
+
SwiftClient.expects(:get_account).returns(account_response)
|
750
|
+
SwiftClient.expects(:head_account).returns(account_response[0])
|
751
|
+
SwiftClient.expects(:post_account).returns(nil)
|
752
|
+
SwiftClient.expects(:get_container).returns(container_response)
|
753
|
+
SwiftClient.expects(:head_container).returns(container_response[0])
|
754
|
+
SwiftClient.expects(:put_container).returns(nil)
|
755
|
+
SwiftClient.expects(:post_container).returns(nil)
|
756
|
+
SwiftClient.expects(:delete_container).returns(nil)
|
757
|
+
SwiftClient.expects(:get_object).returns(object_response)
|
758
|
+
SwiftClient.expects(:head_object).returns(object_response[0])
|
759
|
+
SwiftClient.expects(:put_object).returns(nil)
|
760
|
+
SwiftClient.expects(:post_object).returns(nil)
|
761
|
+
SwiftClient.expects(:delete_object).returns(nil)
|
762
|
+
|
763
|
+
assert_nothing_raised do
|
764
|
+
sc = SwiftClient.new(@url, @user, @key)
|
765
|
+
#test account
|
766
|
+
sc.get_auth
|
767
|
+
get_a = sc.get_account
|
768
|
+
assert_equal 123456, get_a[0]['x-account-bytes-used']
|
769
|
+
assert_equal 123, get_a[0]['x-account-object-count']
|
770
|
+
assert_equal 'First', get_a[1][1]['name']
|
771
|
+
head_a = sc.head_account
|
772
|
+
assert_equal 123456, head_a['x-account-bytes-used']
|
773
|
+
assert_equal 123, head_a['x-account-object-count']
|
774
|
+
sc.post_account({'foo'=>'bar'})
|
775
|
+
#test container
|
776
|
+
get_c = sc.get_container('test_container')
|
777
|
+
assert_equal 'foo.mp4', get_c[1][0]['name']
|
778
|
+
assert_equal 6, get_c[0]['x-container-object-count']
|
779
|
+
assert_equal 'bar', get_c[0]['x-container-meta-foo']
|
780
|
+
head_c = sc.head_container('test_container')
|
781
|
+
assert_equal 6, head_c['x-container-object-count']
|
782
|
+
assert_equal 'bar', head_c['x-container-meta-foo']
|
783
|
+
sc.put_container('test_container')
|
784
|
+
sc.post_container('test_container', {'foo' => 'bar'})
|
785
|
+
sc.delete_container('test_container')
|
786
|
+
#test object
|
787
|
+
get_o = sc.get_object('test_container', 'test_object')
|
788
|
+
assert_equal "some data that is from swift", get_o[1]
|
789
|
+
assert_equal "somelarge123hashthingy123foobar", get_o[0]['Etag']
|
790
|
+
head_o = sc.head_object('test_container', 'test_object')
|
791
|
+
assert_equal "somelarge123hashthingy123foobar", head_o['Etag']
|
792
|
+
sc.put_object('test_container', 'test_object', 'some data to put up')
|
793
|
+
sc.post_object('test_container', 'test_object', {"foo" => "bar"})
|
794
|
+
sc.delete_object('test_container', 'test_object')
|
795
|
+
end
|
796
|
+
end
|
797
|
+
end
|