cloudfiles 1.4.18 → 1.5.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/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
|