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

[rackspace|queues] Addition of Rackspace Cloud Queues

This commit is contained in:
Brian Hartsock 2013-07-19 21:38:31 -04:00
parent 901f70c525
commit b915caf1bf
33 changed files with 1213 additions and 1 deletions

View file

@ -23,6 +23,8 @@ class Rackspace < Fog::Bin
Fog::Rackspace::Databases
when :monitoring
Fog::Rackspace::Monitoring
when :queues
Fog::Rackspace::Queues
else
raise ArgumentError, "Unrecognized service: #{key}"
end
@ -56,6 +58,8 @@ class Rackspace < Fog::Bin
Fog::Rackspace::BlockStorage.new
when :monitoring
Fog::Rackspace::Monitoring.new
when :queues
Fog::Rackspace::Queues.new
else
raise ArgumentError, "Unrecognized service: #{key.inspect}"
end

View file

@ -62,7 +62,7 @@ module Fog
class InternalServerError < ServiceError; end
class Conflict < ServiceError; end
class ServiceUnavailable < ServiceError; end
class MethodNotAllowed < ServiceError; end
class BadRequest < ServiceError
#TODO - Need to find a better way to print out these validation errors when they are thrown
attr_reader :validation_errors
@ -91,6 +91,7 @@ module Fog
service(:identity, 'rackspace/identity', 'Identity')
service(:databases, 'rackspace/databases', 'Databases')
service(:monitoring, 'rackspace/monitoring', 'Monitoring')
service(:queues, 'rackspace/queues', 'Queues')
def self.authenticate(options, connection_options = {})
rackspace_auth_url = options[:rackspace_auth_url]

View file

@ -0,0 +1,92 @@
require 'fog/core/model'
module Fog
module Rackspace
class Queues
class Claim < Fog::Model
identity :identity
attribute :grace
attribute :ttl
attribute :limit
attribute :messages
def save
if identity.nil?
create
else
update
end
end
def destroy
requires :identity, :queue
service.delete_claim(queue.name, identity)
#Since Claims aren't a server side collection, we should remove
# the claim from the collection.
collection.delete(self)
true
end
def messages=(messages)
#HACK - Models require a collection, but I don't really want to expose
# the messages collection to users here.
message_collection = Fog::Rackspace::Queues::Messages.new({
:service => service,
:queue => queue,
:client_id => service.client_id,
:echo => true
})
attributes[:messages] = messages.collect do |message|
if message.instance_of? Fog::Rackspace::Queues::Message
message
else
Fog::Rackspace::Queues::Message.new(
message.merge({
:service => service,
:collection => message_collection
}.merge(message))
)
end
end
end
private
def queue
collection.queue
end
def create
requires :queue, :ttl, :grace, :collection
options = {}
options[:limit] = limit unless limit.nil?
response = service.create_claim(queue.identity, ttl, grace, options)
if [200, 201].include? response.status
self.identity = response.headers['Location'].split('/').last
self.messages = response.body
#Since Claims aren't a server side collection, we need to
# add the claim to the collection
collection << self
true
else
false
end
end
def update
requires :identity, :queue, :ttl
service.update_claim(queue.identity, identity, ttl)
true
end
end
end
end
end

View file

@ -0,0 +1,40 @@
require 'fog/core/collection'
require 'fog/rackspace/models/queues/claim'
module Fog
module Rackspace
class Queues
class Claims < Fog::Collection
model Fog::Rackspace::Queues::Claim
attr_accessor :queue
def all
self
end
def create(attributes = {})
object = new(attributes)
if object.save
object
else
false
end
end
def get(claim_id)
requires :queue
data = service.get_claim(queue.identity, claim_id).body
new(data)
rescue Fog::Rackspace::Queues::NotFound
nil
# HACK - This has been escalated to the Rackspace Queues team, as this
# behavior is not normal HTTP behavior.
rescue Fog::Rackspace::Queues::ServiceError
nil
end
end
end
end
end

View file

@ -0,0 +1,51 @@
require 'fog/core/model'
module Fog
module Rackspace
class Queues
class Message < Fog::Model
attribute :age
attribute :ttl
attribute :body
attribute :href
attribute :claim_id
def identity
if href
href.split('/').last
else
nil
end
end
def save
requires :queue, :client_id, :body, :ttl
raise "Message has already been created and may not be updated." unless identity.nil?
data = service.create_message(client_id, queue.name, body, ttl).body
self.href = data['resources'][0]
true
end
def destroy
requires :identity, :queue
options = {}
options[:claim_id] = claim_id unless claim_id.nil?
service.delete_message(queue.name, identity, options)
true
end
private
def queue
collection.queue
end
def client_id
collection.client_id
end
end
end
end
end

View file

@ -0,0 +1,54 @@
require 'fog/core/collection'
require 'fog/rackspace/models/queues/message'
module Fog
module Rackspace
class Queues
class Messages < Fog::Collection
model Fog::Rackspace::Queues::Message
attr_accessor :client_id
attr_accessor :queue
attr_accessor :echo
attr_accessor :limit
attr_accessor :marker
attr_accessor :include_claimed
def all
requires :client_id, :queue
response = service.list_messages(client_id, queue.name, options)
if response.status == 204
data = []
else
data = response.body['messages']
end
load(data)
end
def get(message_id)
requires :client_id, :queue
data = service.get_message(client_id, queue.name, message_id).body
new(data)
rescue Fog::Rackspace::Queues::NotFound
nil
# HACK - This has been escalated to the Rackspace Queues team, as this
# behavior is not normal HTTP behavior.
rescue Fog::Rackspace::Queues::ServiceError
nil
end
private
def options
data = {}
data[:echo] = echo.to_s unless echo.nil?
data[:limit] = limit.to_s unless limit.nil?
data[:marker] = marker.to_s unless marker.nil?
data[:include_claimed] = include_claimed.to_s unless include_claimed.nil?
data
end
end
end
end
end

View file

@ -0,0 +1,73 @@
require 'fog/core/model'
module Fog
module Rackspace
class Queues
class Queue < Fog::Model
identity :name
def messages
@messages ||= begin
Fog::Rackspace::Queues::Messages.new({
:service => service,
:queue => self,
:client_id => service.client_id,
:echo => true
})
end
end
def stats
service.get_queue_stats(name).body['messages']
end
def claims
@claims ||= begin
Fog::Rackspace::Queues::Claims.new({
:service => service,
:queue => self
})
end
end
#Helper method to enqueue a single message
def enqueue(body, ttl, options = {})
messages.create(options.merge(options.merge({:body => body, :ttl => ttl})))
end
#Helper method to claim (dequeue) a single message, including destroying it
def dequeue(ttl, grace, options = {})
claim = claims.create(
options.merge(
{
:limit => 1,
:ttl => ttl,
:grace => grace
}))
if claim
message = claim.messages.first
yield message
message.destroy
true
else
false
end
end
def save
requires :name
data = service.create_queue(name)
true
end
def destroy
requires :name
service.delete_queue(name)
true
end
end
end
end
end

View file

@ -0,0 +1,32 @@
require 'fog/core/collection'
require 'fog/rackspace/models/queues/queue'
module Fog
module Rackspace
class Queues
class Queues < Fog::Collection
model Fog::Rackspace::Queues::Queue
def all
response = service.list_queues
if service.list_queues.status == 204
data = []
else
data = service.list_queues.body['queues']
end
load(data)
end
def get(queue_name)
#204 no content is returned on success. That's why no data is passed
# from the GET to the constructor.
service.get_queue(queue_name)
new({:name => queue_name})
rescue Fog::Rackspace::Queues::NotFound
nil
end
end
end
end
end

130
lib/fog/rackspace/queues.rb Normal file
View file

@ -0,0 +1,130 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rackspace'))
module Fog
module Rackspace
class Queues < Fog::Service
include Fog::Rackspace::Errors
class ServiceError < Fog::Rackspace::Errors::ServiceError; end
class InternalServerError < Fog::Rackspace::Errors::InternalServerError; end
class BadRequest < Fog::Rackspace::Errors::BadRequest; end
class MethodNotAllowed < Fog::Rackspace::Errors::BadRequest; end
requires :rackspace_api_key, :rackspace_username, :rackspace_queues_client_id
recognizes :rackspace_auth_url
recognizes :rackspace_auth_token
recognizes :rackspace_endpoint
recognizes :rackspace_region
recognizes :rackspace_queues_url
model_path 'fog/rackspace/models/queues'
model :queue
collection :queues
model :message
collection :messages
model :claim
collection :claims
request_path 'fog/rackspace/requests/queues'
request :list_queues
request :get_queue
request :create_queue
request :delete_queue
request :get_queue_stats
request :list_messages
request :get_message
request :create_message
request :delete_message
request :create_claim
request :get_claim
request :update_claim
request :delete_claim
class Mock < Fog::Rackspace::Service
def request(params)
Fog::Mock.not_implemented
end
end
class Real < Fog::Rackspace::Service
def service_name
:cloudQueues
end
def region
@rackspace_region
end
def initialize(options = {})
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
@rackspace_queues_client_id = options[:rackspace_queues_client_id]
@rackspace_auth_url = options[:rackspace_auth_url]
@rackspace_must_reauthenticate = false
@connection_options = options[:connection_options] || {}
@rackspace_endpoint = Fog::Rackspace.normalize_url(options[:rackspace_queues_url] || options[:rackspace_endpoint])
unless v2_authentication?
raise Fog::Errors::NotImplemented.new("V2 authentication required for Queues")
end
authenticate
deprecation_warnings(options)
@persistent = options[:persistent] || false
@connection = Fog::Connection.new(endpoint_uri.to_s, @persistent, @connection_options)
end
def request(params, parse_json = true, &block)
super(params, parse_json, &block)
rescue Excon::Errors::NotFound => error
raise NotFound.slurp(error, region)
rescue Excon::Errors::BadRequest => error
raise BadRequest.slurp error
rescue Excon::Errors::InternalServerError => error
raise InternalServerError.slurp error
rescue Excon::Errors::MethodNotAllowed => error
raise MethodNotAllowed.slurp error
rescue Excon::Errors::HTTPStatusError => error
raise ServiceError.slurp error
end
def endpoint_uri(service_endpoint_url=nil)
@uri = super(@rackspace_endpoint || service_endpoint_url, :rackspace_queues_url)
end
def authenticate(options={})
super({
:rackspace_api_key => @rackspace_api_key,
:rackspace_username => @rackspace_username,
:rackspace_auth_url => @rackspace_auth_url,
:connection_options => @connection_options
})
end
def client_id
@rackspace_queues_client_id
end
def client_id=(client_id)
@rackspace_queues_client_id = client_id
end
private
def deprecation_warnings(options)
Fog::Logger.deprecation("The :rackspace_endpoint option is deprecated. Please use :rackspace_queues_url for custom endpoints") if options[:rackspace_endpoint]
# if [DFW_ENDPOINT, ORD_ENDPOINT, LON_ENDPOINT].include?(@rackspace_endpoint) && v2_authentication?
# regions = @identity_service.service_catalog.display_service_regions(service_name)
# Fog::Logger.deprecation("Please specify region using :rackspace_region rather than :rackspace_endpoint. Valid region for :rackspace_region are #{regions}.")
# end
end
end
end
end
end

View file

@ -0,0 +1,24 @@
module Fog
module Rackspace
class Queues
class Real
def create_claim(queue_name, ttl, grace, options = {})
body = {
:ttl => ttl,
:grace => grace
}
query = {}
query[:limit] = options[:limit] if options.has_key? :limit
request(
:body => Fog::JSON.encode(body),
:expects => [200, 201, 204],
:method => 'POST',
:path => "queues/#{queue_name}/claims",
:query => query
)
end
end
end
end
end

View file

@ -0,0 +1,21 @@
module Fog
module Rackspace
class Queues
class Real
def create_message(client_id, queue_name, body, ttl)
data = [{
:ttl => ttl,
:body => body
}]
request(
:body => Fog::JSON.encode(data),
:expects => 201,
:method => 'POST',
:path => "queues/#{queue_name}/messages",
:headers => { 'Client-ID' => client_id }
)
end
end
end
end
end

View file

@ -0,0 +1,16 @@
module Fog
module Rackspace
class Queues
class Real
def create_queue(queue_name)
request(
:body => Fog::JSON.encode({}),
:expects => 201,
:method => 'PUT',
:path => "queues/#{queue_name}"
)
end
end
end
end
end

View file

@ -0,0 +1,15 @@
module Fog
module Rackspace
class Queues
class Real
def delete_claim(queue_name, claim_id)
request(
:expects => 204,
:method => 'DELETE',
:path => "queues/#{queue_name}/claims/#{claim_id}"
)
end
end
end
end
end

View file

@ -0,0 +1,18 @@
module Fog
module Rackspace
class Queues
class Real
def delete_message(queue_name, message_id, options = {})
query = {}
query[:claim_id] = options[:claim_id] if options.has_key? :claim_id
request(
:expects => 204,
:method => 'DELETE',
:path => "queues/#{queue_name}/messages/#{message_id}",
:query => query
)
end
end
end
end
end

View file

@ -0,0 +1,15 @@
module Fog
module Rackspace
class Queues
class Real
def delete_queue(queue_name)
request(
:expects => 204,
:method => 'DELETE',
:path => "queues/#{queue_name}"
)
end
end
end
end
end

View file

@ -0,0 +1,15 @@
module Fog
module Rackspace
class Queues
class Real
def get_claim(queue_name, claim_id)
request(
:expects => 200,
:method => 'GET',
:path => "queues/#{queue_name}/claims/#{claim_id}"
)
end
end
end
end
end

View file

@ -0,0 +1,16 @@
module Fog
module Rackspace
class Queues
class Real
def get_message(client_id, queue_name, message_id)
request(
:expects => 200,
:method => 'GET',
:path => "queues/#{queue_name}/messages/#{message_id}",
:headers => { 'Client-ID' => client_id }
)
end
end
end
end
end

View file

@ -0,0 +1,15 @@
module Fog
module Rackspace
class Queues
class Real
def get_queue(queue_name)
request(
:expects => [200, 204],
:method => 'GET',
:path => "queues/#{queue_name}"
)
end
end
end
end
end

View file

@ -0,0 +1,15 @@
module Fog
module Rackspace
class Queues
class Real
def get_queue_stats(queue_name)
request(
:expects => 200,
:method => 'GET',
:path => "queues/#{queue_name}/stats"
)
end
end
end
end
end

View file

@ -0,0 +1,17 @@
module Fog
module Rackspace
class Queues
class Real
def list_messages(client_id, queue_name, options = {})
request(
:expects => [200, 204],
:method => 'GET',
:path => "queues/#{queue_name}/messages",
:headers => { 'Client-ID' => client_id },
:query => options
)
end
end
end
end
end

View file

@ -0,0 +1,15 @@
module Fog
module Rackspace
class Queues
class Real
def list_queues
request(
:expects => [200, 204],
:method => 'GET',
:path => 'queues'
)
end
end
end
end
end

View file

@ -0,0 +1,19 @@
module Fog
module Rackspace
class Queues
class Real
def update_claim(queue_name, claim_id, ttl)
body = {
:ttl => ttl
}
request(
:body => Fog::JSON.encode(body),
:expects => 204,
:method => 'PATCH',
:path => "queues/#{queue_name}/claims/#{claim_id}"
)
end
end
end
end
end

View file

@ -0,0 +1,43 @@
Shindo.tests('Fog::Rackspace::Queues | claim', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
queue = service.queues.create({
:name => "fog_queue_#{Time.now.to_i.to_s}",
})
queue.messages.create({
:ttl => VALID_TTL,
:body => { :random => :body }
})
params = {
:ttl => VALID_TTL,
:grace => VALID_GRACE
}
begin
model_tests(queue.claims, params, false) do
tests('#messages') do
returns(1) { @instance.messages.length }
returns('body') { @instance.messages.first.body['random'] }
end
tests('#update').succeeds do
@instance.ttl = VALID_TTL + 5
@instance.save
end
end
queue.messages.create({
:ttl => VALID_TTL,
:body => { :random => :body }
})
tests('destroying claimed messages').succeeds do
claim = queue.claims.create(params)
claim.messages.first.destroy
end
ensure
queue.destroy
end
end

View file

@ -0,0 +1,55 @@
Shindo.tests('Fog::Rackspace::Queues | claims', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
queue = service.queues.create({
:name => "fog_queue_#{Time.now.to_i.to_s}",
})
queue.messages.create({
:ttl => VALID_TTL,
:body => { :random => :body }
})
params = {
:ttl => VALID_TTL,
:grace => VALID_GRACE
}
begin
collection_tests(queue.claims, params, false)
tests('creating claims when there are no messages') do
before do
#clear all message from queue
queue.messages.all.each do |message|
message.destroy
end
end
tests("#create(#{params.inspect}) => with no messages does not show up in claim list") do
returns(false) { queue.claims.create(params) }
returns(true) { queue.claims.empty? }
end
end
tests('create claims when there are messages') do
before do
queue.messages.create({
:ttl => VALID_TTL,
:body => { :random => :body }
})
end
tests("#create(#{params.inspect}) => with messages does show up in claim list") do
returns(true) do
queue.claims.create(params).instance_of? Fog::Rackspace::Queues::Claim
end
returns(false) { queue.claims.empty? }
end
end
ensure
queue.destroy
end
end

View file

@ -0,0 +1,33 @@
Shindo.tests('Fog::Rackspace::Queues | message', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
queue = service.queues.create({
:name => "fog_instance_#{Time.now.to_i.to_s}",
})
options = {
:ttl => VALID_TTL,
:body => { :key => 'value' }
}
begin
model_tests(queue.messages, options, false) do
tests('#href').returns(true) do
!@instance.href.nil?
end
tests('#identity').returns(true) do
!@instance.identity.nil?
end
tests('#save => Fails to update').raises(StandardError) do
@instance.save
end
end
message = queue.messages.create(options.merge({:claim_id => '10'}))
tests('#destroy => fails if claim is not valid').raises(Fog::Rackspace::Queues::ServiceError) do
message.destroy
end
ensure
queue.destroy
end
end

View file

@ -0,0 +1,18 @@
Shindo.tests('Fog::Rackspace::Queues | messages', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
queue = service.queues.create({
:name => "fog_queue_#{Time.now.to_i.to_s}",
})
options = {
:ttl => 300,
:body => "blah"
}
collection_tests(queue.messages, options, false)
queue.destroy
end

View file

@ -0,0 +1,30 @@
Shindo.tests('Fog::Rackspace::Queues | queue', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
options = {
:name => "fog_instance_#{Time.now.to_i.to_s}",
}
model_tests(service.queues, options, false) do
tests('#stats').formats(QUEUE_STATS_FORMAT['messages']) do
@instance.stats
end
tests('#enqueue("msg", 60)') do
@instance.enqueue("msg", 60)
end
tests('#dequeue(60, 60)').returns(true) do
@instance.dequeue(60, 60) do |message|
returns("msg") { message.body }
end
end
tests('#dequeue(60, 60) => with not messages').returns(false) do
@instance.dequeue(60, 60) do |message|
end
end
end
end

View file

@ -0,0 +1,10 @@
Shindo.tests('Fog::Rackspace::Queues | queues', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
options = {
:name => "fog_instance_#{Time.now.to_i.to_s}",
}
collection_tests(service.queues, options, false)
end

View file

@ -0,0 +1,105 @@
Shindo.tests('Fog::Rackspace::Queues', ['rackspace']) do
pending if Fog.mocking?
def assert_method(url, method)
@service.instance_variable_set "@rackspace_auth_url", url
returns(method) { @service.send :authentication_method }
end
tests('#authentication_method') do
@service = Fog::Rackspace::Queues.new
assert_method nil, :authenticate_v2
assert_method 'https://identity.api.rackspacecloud.com', :authenticate_v1
assert_method 'https://identity.api.rackspacecloud.com/v1', :authenticate_v1
assert_method 'https://identity.api.rackspacecloud.com/v1.1', :authenticate_v1
assert_method 'https://identity.api.rackspacecloud.com/v2.0', :authenticate_v2
assert_method 'https://lon.identity.api.rackspacecloud.com', :authenticate_v1
assert_method 'https://lon.identity.api.rackspacecloud.com/v1', :authenticate_v1
assert_method 'https://lon.identity.api.rackspacecloud.com/v1.1', :authenticate_v1
assert_method 'https://lon.identity.api.rackspacecloud.com/v2.0', :authenticate_v2
end
tests('authentication v1') do
pending if Fog.mocking?
raises(Fog::Errors::NotImplemented) do
@service = Fog::Rackspace::Queues.new :rackspace_auth_url => 'https://identity.api.rackspacecloud.com/v1.0'
end
end
tests('authentication v2') do
pending if Fog.mocking?
tests('variables populated').succeeds do
@service = Fog::Rackspace::Queues.new :rackspace_auth_url => 'https://identity.api.rackspacecloud.com/v2.0', :connection_options => { :ssl_verify_peer => true }
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
returns(false, "path populated") { @service.instance_variable_get("@uri").nil? }
identity_service = @service.instance_variable_get("@identity_service")
returns(false, "identity service was used") { identity_service.nil? }
returns(true, "connection_options are passed") { identity_service.instance_variable_get("@connection_options").has_key?(:ssl_verify_peer) }
@service.queues
end
tests('dfw region').succeeds do
@service = Fog::Rackspace::Queues.new :rackspace_auth_url => 'https://identity.api.rackspacecloud.com/v2.0', :rackspace_region => :dfw
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
returns(true) { (@service.instance_variable_get("@uri").host =~ /dfw/) != nil }
@service.queues
end
tests('ord region').succeeds do
@service = Fog::Rackspace::Queues.new :rackspace_auth_url => 'https://identity.api.rackspacecloud.com/v2.0', :rackspace_region => :ord
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
returns(true) { (@service.instance_variable_get("@uri").host =~ /ord/) != nil }
@service.queues
end
tests('custom endpoint') do
@service = Fog::Rackspace::Queues.new :rackspace_auth_url => 'https://identity.api.rackspacecloud.com/v2.0',
:rackspace_queues_url => 'https://my-custom-endpoint.com'
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
returns(true, "uses custom endpoint") { (@service.instance_variable_get("@uri").host =~ /my-custom-endpoint\.com/) != nil }
end
end
tests('default auth') do
pending if Fog.mocking?
tests('no params').succeeds do
@service = Fog::Rackspace::Queues.new
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
returns(true) { (@service.instance_variable_get("@uri").host =~ /dfw/) != nil }
@service.queues
end
tests('specify region').succeeds do
@service = Fog::Rackspace::Queues.new :rackspace_region => :ord
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
returns(true) { (@service.instance_variable_get("@uri").host =~ /ord/ ) != nil }
@service.queues
end
tests('custom endpoint') do
@service = Fog::Rackspace::Queues.new :rackspace_queues_url => 'https://my-custom-endpoint.com'
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
returns(true, "uses custom endpoint") { (@service.instance_variable_get("@uri").host =~ /my-custom-endpoint\.com/) != nil }
end
end
tests('reauthentication') do
pending if Fog.mocking?
@service = Fog::Rackspace::Queues.new
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
@service.instance_variable_set("@auth_token", "bad_token")
returns(200) { @service.list_queues.status }
end
@service = Fog::Rackspace::Queues.new
tests('#queues').succeeds do
data = @service.queues
returns(true) { data.is_a? Array }
end
end

View file

@ -0,0 +1,63 @@
Shindo.tests('Fog::Rackspace::Queues | claim_tests', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
queue_name = 'fog' + Time.now.to_i.to_s
client_id = 'fog-client-' + Time.now.to_i.to_s
claim_id = nil
service.create_queue(queue_name)
tests('success') do
tests("#create_claim(#{queue_name}, #{VALID_TTL}, #{VALID_GRACE}) => No Messages").returns(204) do
service.create_claim(queue_name, VALID_TTL, VALID_GRACE).status
end
tests('with messages in the queue') do
before do
service.create_message(client_id, queue_name, { :message => "message-body"}, 300)
end
#TODO - Fix it so simple text bodies pass validation
tests("#create_claim(#{queue_name}, #{VALID_TTL}, #{VALID_GRACE})").formats(CREATE_CLAIM_FORMAT) do
response = service.create_claim(queue_name, VALID_TTL, VALID_GRACE)
claim_id = response.headers['Location'].split('/').last
response.body
end
tests("#get_claim(#{queue_name}, #{claim_id})").formats(CLAIM_FORMAT) do
service.get_claim(queue_name, claim_id).body
end
tests("#update_claim(#{queue_name}, #{claim_id}, 500)").succeeds do
service.update_claim(queue_name, claim_id, 500)
end
tests("#delete_claim(#{queue_name}, #{claim_id})").succeeds do
service.delete_claim(queue_name, claim_id)
end
tests("#create_claim(#{queue_name}, #{VALID_TTL}, #{VALID_GRACE}, { :limit => 1})") do
response = service.create_claim(queue_name, VALID_TTL, VALID_GRACE, { :limit => 1})
formats(CREATE_CLAIM_FORMAT) { response.body }
returns(1) { response.body.length }
end
end
end
tests('failure') do
#TODO - Escalate to queueing team
tests("#get_claim('queue_name', 'nonexistentclaim') => Does not exist").raises(Fog::Rackspace::Queues::ServiceError) do
service.get_claim(queue_name, 'nonexistentclaim')
end
end
service.delete_queue(queue_name)
end

View file

@ -0,0 +1,55 @@
VALID_TTL = 300
VALID_GRACE = 300
LINKS_FORMAT = [{
'href' => String,
'rel' => String
}]
METADATA_FORMAT = {
}
QUEUE_FORMAT = {
'metadata' => METADATA_FORMAT
}
LIST_QUEUES_FORMAT = {
'queues' => [
QUEUE_FORMAT.merge({
'name' => String,
'href' => String,
})
],
'links' => LINKS_FORMAT
}
MESSAGE_FORMAT = {
'href' => String,
'ttl' => Integer,
'age' => Integer,
'body' => Hash
}
LIST_MESSAGES_FORMAT = {
'messages' => [MESSAGE_FORMAT],
'links' => LINKS_FORMAT
}
CREATE_CLAIM_FORMAT = [
MESSAGE_FORMAT
]
CLAIM_FORMAT = {
'ttl' => Integer,
'age' => Integer,
'messages' => [
MESSAGE_FORMAT
]
}
QUEUE_STATS_FORMAT = {
'messages' => {
'free' => Integer,
'claimed' => Integer
}
}

View file

@ -0,0 +1,60 @@
Shindo.tests('Fog::Rackspace::Queues | messages_tests', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
queue_name = 'fog' + Time.now.to_i.to_s
client_id = 'fog-client-' + Time.now.to_i.to_s
message_id = nil
service.create_queue(queue_name)
begin
tests('success') do
tests("#list_message(#{client_id}, #{queue_name}, {:echo => true}) => No Content").returns(204) do
service.list_messages(client_id, queue_name, {:echo => true}).status
end
tests("#create_message(#{client_id}, #{queue_name}, '{ :blah => 'blah' }', 300)").succeeds do
response = service.create_message(client_id, queue_name, { :blah => 'blah' }, 300)
message_id = response.body['resources'][0].split('/').last
end
tests("#list_message(#{client_id}, #{queue_name}, {:echo => true}) => With Content").formats(LIST_MESSAGES_FORMAT) do
service.list_messages(client_id, queue_name, {:echo => true}).body
end
tests("#get_message(#{client_id}, #{queue_name}, #{message_id})").formats(MESSAGE_FORMAT) do
service.get_message(client_id, queue_name, message_id).body
end
#TODO - Report bad error code to queueing team
tests("#delete_message(#{queue_name}, #{message_id}, { :claim_id => '10' })").raises(Fog::Rackspace::Queues::ServiceError) do
service.delete_message(queue_name, message_id, { :claim_id => '10' })
end
tests("#delete_message(#{queue_name}, #{message_id})").succeeds do
service.delete_message(queue_name, message_id)
end
end
tests('failure') do
tests("#create_message('') => Invalid Create Critera").raises(Fog::Rackspace::Queues::BadRequest) do
service.create_message(client_id, queue_name, '', 0)
end
#TODO - Report bad error code to queueing team
tests("#get_message('queue_name', 'nonexistentmessage') => Does not exist").raises(Fog::Rackspace::Queues::ServiceError) do
service.get_message(client_id, queue_name, 'nonexistentmessage')
end
end
ensure
service.delete_queue(queue_name)
end
end

View file

@ -0,0 +1,42 @@
Shindo.tests('Fog::Rackspace::Queues | queue_tests', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
tests('success') do
queue_name = 'fog' + Time.now.to_i.to_s
tests("#list_queues").formats(LIST_QUEUES_FORMAT) do
service.list_queues.body
end
tests("#create_queue(#{queue_name})").succeeds do
service.create_queue(queue_name)
end
tests("#get_queue(#{queue_name})").formats(QUEUE_FORMAT) do
service.get_queue(queue_name).body
end
tests("#get_queue_stats(#{queue_name})").formats(QUEUE_STATS_FORMAT) do
service.get_queue_stats(queue_name).body
end
tests("#delete_queue(#{queue_name})").succeeds do
service.delete_queue(queue_name)
end
end
tests('failure') do
tests("#create_queue('') => Invalid Create Critera").raises(Fog::Rackspace::Queues::MethodNotAllowed) do
service.create_queue('')
end
tests("#get_queue('nonexistentqueue') => Does not exist").raises(Fog::Rackspace::Queues::NotFound) do
service.get_queue('nonexistentqueue')
end
end
end