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:
parent
8d859aa1b4
commit
786a5cbc75
12 changed files with 302 additions and 2 deletions
|
@ -40,5 +40,12 @@ module Fog
|
|||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def self.etag
|
||||
Fog::Mock.random_hex(32)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -59,10 +59,19 @@ module Fog
|
|||
|
||||
class Mock
|
||||
include Utils
|
||||
def self.acls(type)
|
||||
type
|
||||
end
|
||||
|
||||
def self.data
|
||||
@data ||= Hash.new do |hash, key|
|
||||
hash[key] = {}
|
||||
hash[key] = {
|
||||
:acls => {
|
||||
:container => {},
|
||||
:object => {}
|
||||
},
|
||||
:containers => {}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -18,6 +18,26 @@ module Fog
|
|||
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
|
||||
|
|
|
@ -19,6 +19,23 @@ module Fog
|
|||
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
|
||||
|
|
|
@ -40,6 +40,54 @@ module Fog
|
|||
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
|
||||
|
|
|
@ -29,6 +29,43 @@ module Fog
|
|||
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
|
||||
|
|
|
@ -20,6 +20,62 @@ module Fog
|
|||
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
|
||||
|
|
|
@ -24,6 +24,17 @@ module Fog
|
|||
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
|
||||
|
|
|
@ -21,6 +21,17 @@ module Fog
|
|||
end
|
||||
|
||||
end
|
||||
|
||||
class Mock # :nodoc:all
|
||||
|
||||
def head_containers
|
||||
response = get_containers
|
||||
response.body = nil
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -19,6 +19,17 @@ module Fog
|
|||
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
|
||||
|
|
|
@ -19,6 +19,30 @@ module Fog
|
|||
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
|
||||
|
|
|
@ -25,6 +25,55 @@ module Fog
|
|||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue