cloudfiles 1.4.18 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -34,8 +34,11 @@ module CloudFiles
34
34
  # Retrieves Metadata for the object
35
35
  def object_metadata
36
36
  @object_metadata ||= (
37
- response = self.container.connection.storage_request("HEAD", @storagepath)
38
- raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist" unless (response.code =~ /^20/)
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
- response = self.container.connection.storage_request("GET", @storagepath, headers)
95
- raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist" unless (response.code =~ /^20/)
96
- response.body
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
- self.container.connection.storage_request("GET", @storagepath, headers, nil) do |response|
119
- raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist. Response code #{response.code}" unless (response.code =~ /^20./)
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
- response = self.container.connection.storage_request("POST", @storagepath, headers)
144
- raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist" if (response.code == "404")
145
- raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code =~ /^20/)
146
- true
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
- response = self.container.connection.storage_request("PUT", @storagepath, headers)
168
- raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist" if (response.code == "404")
169
- raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code =~ /^20/)
170
- true
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
- response = self.container.connection.storage_request("PUT", @storagepath, headers, data)
215
- code = response.code
216
- raise CloudFiles::Exception::InvalidResponse, "Invalid content-length header sent" if (code == "412")
217
- raise CloudFiles::Exception::MisMatchedChecksum, "Mismatched etag" if (code == "422")
218
- raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{code}" unless (code =~ /^20./)
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
- response = self.container.connection.cdn_request("DELETE", @storagepath, headers)
245
- raise CloudFiles::Exception::Connection, "Error Unable to Purge Object: #{@name}" unless (response.code.to_s =~ /^20.$/)
246
- true
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
- response = self.container.connection.storage_request("PUT", new_path, headers)
363
- code = response.code
364
- raise CloudFiles::Exception::InvalidResponse, "Invalid response code #{response.code}" unless (response.code =~ /^20/)
365
- return CloudFiles::Container.new(self.container.connection, new_container).object(new_name)
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.
@@ -1,3 +1,3 @@
1
1
  module CloudFiles
2
- VERSION = '1.4.18'
2
+ VERSION = '1.5.0'
3
3
  end
@@ -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
- response.stubs(:code).returns('204')
10
- server = mock(:use_ssl= => true, :verify_mode= => true, :start => true, :finish => true)
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
- response.stubs(:code).returns('204')
21
- server = mock(:use_ssl= => true, :verify_mode= => true, :start => true, :finish => true)
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
- response = mock()
31
- response.stubs(:code).returns('499')
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