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.
@@ -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