1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

Add mocking support to Swift HP provider calls.

This commit is contained in:
Rupak Ganguly 2011-07-29 11:33:28 -04:00
parent 8d859aa1b4
commit 786a5cbc75
12 changed files with 302 additions and 2 deletions

View file

@ -40,5 +40,12 @@ module Fog
end end
end end
class Mock
def self.etag
Fog::Mock.random_hex(32)
end
end
end end
end end

View file

@ -59,11 +59,20 @@ module Fog
class Mock class Mock
include Utils include Utils
def self.acls(type)
type
end
def self.data def self.data
@data ||= Hash.new do |hash, key| @data ||= Hash.new do |hash, key|
hash[key] = {} hash[key] = {
end :acls => {
:container => {},
:object => {}
},
:containers => {}
}
end
end end
def self.reset def self.reset

View file

@ -18,6 +18,26 @@ module Fog
end end
end end
class Mock # :nodoc:all
def delete_container(container_name)
response = Excon::Response.new
if self.data[:containers][container_name].nil?
response.status = 404
raise(Excon::Errors.status_error({:expects => 204}, response))
elsif self.data[:containers][container_name] && !self.data[:containers][container_name][:objects].empty?
response.status = 409
raise(Excon::Errors.status_error({:expects => 204}, response))
else
self.data[:containers].delete(container_name)
response.status = 204
end
response
end
end
end end
end end
end end

View file

@ -19,6 +19,23 @@ module Fog
end end
end end
class Mock # :nodoc:all
def delete_object(container_name, object_name, options = {})
response = Excon::Response.new
if container = self.data[:containers][container_name]
response.status = 204
container[:objects].delete(object_name)
else
response.status = 404
raise(Excon::Errors.status_error({:expects => 204}, response))
end
response
end
end
end end
end end
end end

View file

@ -40,6 +40,54 @@ module Fog
end end
end end
class Mock # :nodoc:all
def get_container(container_name, options = {})
unless container_name
raise ArgumentError.new('container_name is required')
end
if options['delimiter']
Fog::Mock.not_implemented
end
response = Excon::Response.new
obj_count = 0
obj_total_bytes = 0
if container = self.data[:containers][container_name]
contents = container[:objects].values.sort {|x,y| x['Key'] <=> y['Key']}.reject do |object|
(options['prefix'] && object['Key'][0...options['prefix'].length] != options['prefix']) ||
(options['marker'] && object['Key'] <= options['marker'])
end.map do |object|
obj_count = obj_count + 1
obj_total_bytes = obj_total_bytes + object['Content-Length'].to_i
data = {
'name' => object['Key'],
'hash' => object['ETag'],
'bytes' => object['Content-Length'].to_i,
'content_type' => object['Content-Type'],
'last_modified' => Time.parse(object['Date'])
}
data
end
response.status = 200
response.body = contents
response.headers = {
'X-Container-Object-Count' => obj_count,
'X-Container-Bytes-Used' => obj_total_bytes,
'Accept-Ranges' => 'bytes',
'Content-Type' => container['Content-Type'],
'Content-Length' => container['Content-Length']
}
else
response.status = 404
raise(Excon::Errors.status_error({:expects => 200}, response))
end
response
end
end
end end
end end
end end

View file

@ -29,6 +29,43 @@ module Fog
end end
end end
class Mock # :nodoc:all
def get_containers(options = {})
response = Excon::Response.new
acc_cont_count = 0
acc_obj_count = 0
acc_obj_bytes = 0
containers = self.data[:containers].map do |key, container|
acc_cont_count = acc_cont_count + 1
obj_count = 0
container[:objects].values.map do |object|
acc_obj_count = acc_obj_count + 1
acc_obj_bytes = acc_obj_bytes + object['Content-Length'].to_i
obj_count = obj_count + 1
container['Object-Count'] = obj_count
end
data = {
'name' => key,
'count' => container['Object-Count'],
'bytes' => container['Content-Length'].to_i
}
data
end
response.body = containers
response.headers = {
'X-Account-Object-Count' => acc_obj_count,
'X-Account-Bytes-Used' => acc_obj_bytes,
'X-Account-Container-Count' => acc_cont_count,
'Accept-Ranges' => 'bytes'
}
response.status = 200
response
end
end
end end
end end
end end

View file

@ -20,6 +20,62 @@ module Fog
end end
end end
class Mock # :nodoc:all
def get_object(container_name, object_name, options = {}, &block)
unless container_name
raise ArgumentError.new('container_name is required')
end
unless object_name
raise ArgumentError.new('object_name is required')
end
response = Excon::Response.new
if (container = self.data[:containers][container_name])
if (object = container[:objects][object_name])
if options['If-Match'] && options['If-Match'] != object['ETag']
response.status = 412
elsif options['If-Modified-Since'] && options['If-Modified-Since'] > Time.parse(object['Last-Modified'])
response.status = 304
elsif options['If-None-Match'] && options['If-None-Match'] == object['ETag']
response.status = 304
elsif options['If-Unmodified-Since'] && options['If-Unmodified-Since'] < Time.parse(object['Last-Modified'])
response.status = 412
else
response.status = 200
for key, value in object
case key
when 'Cache-Control', 'Content-Disposition', 'Content-Encoding', 'Content-Length', 'Content-MD5', 'Content-Type', 'ETag', 'Expires', 'Last-Modified', /^X-Object-Meta-/
response.headers[key] = value
end
end
unless block_given?
response.body = object[:body]
else
data = StringIO.new(object[:body])
remaining = data.length
while remaining > 0
chunk = data.read([remaining, Excon::CHUNK_SIZE].min)
block.call(chunk)
remaining -= Excon::CHUNK_SIZE
end
end
end
else
response.status = 404
response.body = "The resource could not be found."
raise(Excon::Errors.status_error({:expects => 200}, response))
end
else
response.status = 404
response.body = "The resource could not be found."
raise(Excon::Errors.status_error({:expects => 200}, response))
end
response
end
end
end end
end end
end end

View file

@ -24,6 +24,17 @@ module Fog
end end
end end
class Mock # :nodoc:all
def head_container(container_name)
response = get_container(container_name)
response.body = nil
response
end
end
end end
end end
end end

View file

@ -21,6 +21,17 @@ module Fog
end end
end end
class Mock # :nodoc:all
def head_containers
response = get_containers
response.body = nil
response
end
end
end end
end end
end end

View file

@ -19,6 +19,17 @@ module Fog
end end
end end
class Mock # :nodoc:all
def head_object(container_name, object_name, options = {})
response = get_object(container_name, object_name, options)
response.body = nil
response
end
end
end end
end end
end end

View file

@ -19,6 +19,30 @@ module Fog
end end
end end
class Mock # :nodoc:all
def put_container(container_name, options = {})
acl = options['X-Container-Read'] || 'private'
if !['private', 'public-read'].include?(acl)
raise Excon::Errors::BadRequest.new('invalid X-Container-Read')
else
self.data[:acls][:container][container_name] = self.class.acls(acl)
end
response = Excon::Response.new
container = {
:objects => {},
}
if self.data[:containers][container_name]
response.status = 202
else
response.status = 201
self.data[:containers][container_name] = container
end
response
end
end
end end
end end
end end

View file

@ -25,6 +25,55 @@ module Fog
end end
end end
class Mock # :nodoc:all
def put_object(container_name, object_name, data, options = {})
### Take care of case of copy operation
if source = options['X-Copy-From'] && data.nil?
# split source container and object
# dup object into target object
else
data = Fog::Storage.parse_data(data)
unless data[:body].is_a?(String)
data[:body] = data[:body].read
end
end
response = Excon::Response.new
if (container = self.data[:containers][container_name])
response.status = 201
object = {
:body => data[:body],
'Content-Type' => options['Content-Type'] || data[:headers]['Content-Type'],
'ETag' => Fog::HP::Mock.etag,
'Key' => object_name,
'Date' => Fog::Time.now.to_date_header,
'Content-Length' => options['Content-Length'] || data[:headers]['Content-Length'],
}
for key, value in options
case key
when 'Cache-Control', 'Content-Disposition', 'Content-Encoding', 'Content-MD5', 'Expires', /^X-Object-Meta-/
object[key] = value
end
end
container[:objects][object_name] = object
response.headers = {
'Content-Length' => object['Content-Length'],
'Content-Type' => object['Content-Type'],
'ETag' => object['ETag'],
'Date' => object['Date']
}
else
response.status = 404
raise(Excon::Errors.status_error({:expects => 201}, response))
end
response
end
end
end end
end end
end end