fake_sqs 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -1
- data/bin/fake_sqs +2 -2
- data/fake_sqs.gemspec +0 -1
- data/lib/fake_sqs.rb +18 -6
- data/lib/fake_sqs/actions/create_queue.rb +21 -0
- data/lib/fake_sqs/actions/delete_message.rb +21 -0
- data/lib/fake_sqs/actions/delete_message_batch.rb +34 -0
- data/lib/fake_sqs/actions/delete_queue.rb +18 -0
- data/lib/fake_sqs/actions/get_queue_url.rb +21 -0
- data/lib/fake_sqs/actions/list_queues.rb +22 -0
- data/lib/fake_sqs/actions/receive_message.rb +28 -0
- data/lib/fake_sqs/actions/send_message.rb +22 -0
- data/lib/fake_sqs/actions/send_message_batch.rb +39 -0
- data/lib/fake_sqs/api.rb +43 -0
- data/lib/fake_sqs/catch_errors.rb +19 -0
- data/lib/fake_sqs/error_response.rb +55 -0
- data/lib/fake_sqs/error_responses.yml +31 -0
- data/lib/fake_sqs/server.rb +6 -162
- data/lib/fake_sqs/show_output.rb +2 -0
- data/lib/fake_sqs/version.rb +1 -1
- data/lib/fake_sqs/web_interface.rb +6 -10
- data/spec/support/aws.rb +0 -3
- data/spec/unit/api_spec.rb +49 -0
- data/spec/unit/catch_errors_spec.rb +43 -0
- data/spec/unit/error_response_spec.rb +65 -0
- metadata +21 -18
data/.rspec
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
--format
|
1
|
+
--format progress
|
2
2
|
--color
|
data/bin/fake_sqs
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'fake_sqs'
|
4
|
-
require 'fake_sqs/web_interface'
|
5
4
|
require 'optparse'
|
6
5
|
|
7
6
|
options = { :port => 4567, :host => "0.0.0.0", :verbose => false }
|
@@ -48,5 +47,6 @@ end
|
|
48
47
|
app.set :port, options[:port]
|
49
48
|
app.set :bind, options[:host]
|
50
49
|
app.set :server, options[:server] if options[:server]
|
51
|
-
|
50
|
+
server = FakeSQS.server(port: options[:port], host: options[:host])
|
51
|
+
app.set :api, FakeSQS.api(server: server)
|
52
52
|
app.run!
|
data/fake_sqs.gemspec
CHANGED
@@ -23,7 +23,6 @@ Gem::Specification.new do |gem|
|
|
23
23
|
gem.add_development_dependency "rspec"
|
24
24
|
gem.add_development_dependency "rake"
|
25
25
|
gem.add_development_dependency "aws-sdk"
|
26
|
-
gem.add_development_dependency "webmock"
|
27
26
|
gem.add_development_dependency "faraday"
|
28
27
|
gem.add_development_dependency "thin"
|
29
28
|
gem.add_development_dependency "verbose_hash_fetch"
|
data/lib/fake_sqs.rb
CHANGED
@@ -1,15 +1,27 @@
|
|
1
|
-
require 'fake_sqs/
|
2
|
-
require 'fake_sqs/
|
3
|
-
require 'fake_sqs/
|
4
|
-
require 'fake_sqs/
|
1
|
+
require 'fake_sqs/api'
|
2
|
+
require 'fake_sqs/catch_errors'
|
3
|
+
require 'fake_sqs/error_response'
|
4
|
+
require 'fake_sqs/message'
|
5
5
|
require 'fake_sqs/queue'
|
6
6
|
require 'fake_sqs/queue_factory'
|
7
|
-
require 'fake_sqs/
|
7
|
+
require 'fake_sqs/queues'
|
8
|
+
require 'fake_sqs/responder'
|
9
|
+
require 'fake_sqs/server'
|
10
|
+
require 'fake_sqs/version'
|
11
|
+
require 'fake_sqs/web_interface'
|
8
12
|
|
9
13
|
module FakeSQS
|
10
14
|
|
11
15
|
def self.server(options = {})
|
12
|
-
Server.new(options
|
16
|
+
Server.new(options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.api(options = {})
|
20
|
+
API.new(
|
21
|
+
server: options.fetch(:server),
|
22
|
+
queues: queues,
|
23
|
+
responder: responder
|
24
|
+
)
|
13
25
|
end
|
14
26
|
|
15
27
|
def self.queues
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module FakeSQS
|
2
|
+
module Actions
|
3
|
+
class CreateQueue
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@server = options.fetch(:server)
|
7
|
+
@queues = options.fetch(:queues)
|
8
|
+
@responder = options.fetch(:responder)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(params)
|
12
|
+
name = params.fetch("QueueName")
|
13
|
+
queue = @queues.create(name, params)
|
14
|
+
@responder.call :CreateQueue do |xml|
|
15
|
+
xml.QueueUrl @server.url_for(queue.name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module FakeSQS
|
2
|
+
module Actions
|
3
|
+
class DeleteMessage
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@server = options.fetch(:server)
|
7
|
+
@queues = options.fetch(:queues)
|
8
|
+
@responder = options.fetch(:responder)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(name, params)
|
12
|
+
queue = @queues.get(name)
|
13
|
+
|
14
|
+
receipt = params.fetch("ReceiptHandle")
|
15
|
+
queue.delete_message(receipt)
|
16
|
+
@responder.call :DeleteMessage
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module FakeSQS
|
2
|
+
module Actions
|
3
|
+
class DeleteMessageBatch
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@server = options.fetch(:server)
|
7
|
+
@queues = options.fetch(:queues)
|
8
|
+
@responder = options.fetch(:responder)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(name, params)
|
12
|
+
queue = @queues.get(name)
|
13
|
+
receipts = params.select { |k,v| k =~ /DeleteMessageBatchRequestEntry\.\d+\.ReceiptHandle/ }
|
14
|
+
|
15
|
+
deleted = []
|
16
|
+
|
17
|
+
receipts.each do |key, value|
|
18
|
+
id = key.split('.')[1]
|
19
|
+
queue.delete_message(value)
|
20
|
+
deleted << params.fetch("DeleteMessageBatchRequestEntry.#{id}.Id")
|
21
|
+
end
|
22
|
+
|
23
|
+
@responder.call :DeleteMessageBatch do |xml|
|
24
|
+
deleted.each do |id|
|
25
|
+
xml.DeleteMessageBatchResultEntry do
|
26
|
+
xml.Id id
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module FakeSQS
|
2
|
+
module Actions
|
3
|
+
class DeleteQueue
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@server = options.fetch(:server)
|
7
|
+
@queues = options.fetch(:queues)
|
8
|
+
@responder = options.fetch(:responder)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(name, params)
|
12
|
+
@queues.delete(name, params)
|
13
|
+
@responder.call :DeleteQueue
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module FakeSQS
|
2
|
+
module Actions
|
3
|
+
class GetQueueUrl
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@server = options.fetch(:server)
|
7
|
+
@queues = options.fetch(:queues)
|
8
|
+
@responder = options.fetch(:responder)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(params)
|
12
|
+
name = params.fetch("QueueName")
|
13
|
+
queue = @queues.get(name, params)
|
14
|
+
@responder.call :GetQueueUrl do |xml|
|
15
|
+
xml.QueueUrl @server.url_for(queue.name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module FakeSQS
|
2
|
+
module Actions
|
3
|
+
class ListQueues
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@server = options.fetch(:server)
|
7
|
+
@queues = options.fetch(:queues)
|
8
|
+
@responder = options.fetch(:responder)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(params)
|
12
|
+
found = @queues.list(params)
|
13
|
+
@responder.call :ListQueues do |xml|
|
14
|
+
found.each do |queue|
|
15
|
+
xml.QueueUrl @server.url_for(queue.name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module FakeSQS
|
2
|
+
module Actions
|
3
|
+
class ReceiveMessage
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@server = options.fetch(:server)
|
7
|
+
@queues = options.fetch(:queues)
|
8
|
+
@responder = options.fetch(:responder)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(name, params)
|
12
|
+
queue = @queues.get(name)
|
13
|
+
messages = queue.receive_message(params)
|
14
|
+
@responder.call :ReceiveMessage do |xml|
|
15
|
+
messages.each do |receipt, message|
|
16
|
+
xml.Message do
|
17
|
+
xml.MessageId message.id
|
18
|
+
xml.ReceiptHandle receipt
|
19
|
+
xml.MD5OfMessageBody message.md5
|
20
|
+
xml.Body message.body
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module FakeSQS
|
2
|
+
module Actions
|
3
|
+
class SendMessage
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@server = options.fetch(:server)
|
7
|
+
@queues = options.fetch(:queues)
|
8
|
+
@responder = options.fetch(:responder)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(name, params)
|
12
|
+
queue = @queues.get(name)
|
13
|
+
message = queue.send_message(params)
|
14
|
+
@responder.call :SendMessage do |xml|
|
15
|
+
xml.MD5OfMessageBody message.md5
|
16
|
+
xml.MessageId message.id
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module FakeSQS
|
2
|
+
module Actions
|
3
|
+
class SendMessageBatch
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@server = options.fetch(:server)
|
7
|
+
@queues = options.fetch(:queues)
|
8
|
+
@responder = options.fetch(:responder)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(name, params)
|
12
|
+
queue = @queues.get(name)
|
13
|
+
|
14
|
+
messages = params.select { |k,v| k =~ /SendMessageBatchRequestEntry\.\d+\.MessageBody/ }
|
15
|
+
|
16
|
+
results = {}
|
17
|
+
|
18
|
+
messages.each do |key, value|
|
19
|
+
id = key.split('.')[1]
|
20
|
+
msg_id = params.fetch("SendMessageBatchRequestEntry.#{id}.Id")
|
21
|
+
delay = params["SendMessageBatchRequestEntry.#{id}.DelaySeconds"]
|
22
|
+
message = queue.send_message("MessageBody" => value, "DelaySeconds" => delay)
|
23
|
+
results[msg_id] = message
|
24
|
+
end
|
25
|
+
|
26
|
+
@responder.call :SendMessageBatch do |xml|
|
27
|
+
results.each do |msg_id, message|
|
28
|
+
xml.SendMessageBatchResultEntry do
|
29
|
+
xml.Id msg_id
|
30
|
+
xml.MessageId message.id
|
31
|
+
xml.MD5OfMessageBody message.md5
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/fake_sqs/api.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'fake_sqs/actions/create_queue'
|
2
|
+
require 'fake_sqs/actions/delete_queue'
|
3
|
+
require 'fake_sqs/actions/list_queues'
|
4
|
+
require 'fake_sqs/actions/get_queue_url'
|
5
|
+
require 'fake_sqs/actions/send_message'
|
6
|
+
require 'fake_sqs/actions/receive_message'
|
7
|
+
require 'fake_sqs/actions/delete_message'
|
8
|
+
require 'fake_sqs/actions/delete_message_batch'
|
9
|
+
require 'fake_sqs/actions/send_message_batch'
|
10
|
+
|
11
|
+
module FakeSQS
|
12
|
+
|
13
|
+
InvalidAction = Class.new(ArgumentError)
|
14
|
+
|
15
|
+
class API
|
16
|
+
|
17
|
+
attr_reader :queues
|
18
|
+
|
19
|
+
def initialize(options = {})
|
20
|
+
@queues = options.fetch(:queues)
|
21
|
+
@options = options
|
22
|
+
end
|
23
|
+
|
24
|
+
def call(action, *args)
|
25
|
+
if FakeSQS::Actions.const_defined?(action)
|
26
|
+
FakeSQS::Actions.const_get(action).new(@options).call(*args)
|
27
|
+
else
|
28
|
+
fail InvalidAction, "Unknown (or not yet implemented) action: #{action}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Fake actions
|
33
|
+
|
34
|
+
def reset
|
35
|
+
queues.reset
|
36
|
+
end
|
37
|
+
|
38
|
+
def expire
|
39
|
+
queues.expire
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module FakeSQS
|
4
|
+
class CatchErrors
|
5
|
+
|
6
|
+
def initialize(app, options = {})
|
7
|
+
@app = app
|
8
|
+
@response = options.fetch(:response)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
@app.call(env)
|
13
|
+
rescue => error
|
14
|
+
response = @response.new(error)
|
15
|
+
[ response.status, {}, [ response.body ] ]
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'builder'
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
module FakeSQS
|
6
|
+
class ErrorResponse
|
7
|
+
|
8
|
+
attr_reader :error
|
9
|
+
|
10
|
+
def initialize(error)
|
11
|
+
@error = error
|
12
|
+
end
|
13
|
+
|
14
|
+
def status
|
15
|
+
@status ||= statuses.fetch(code)
|
16
|
+
end
|
17
|
+
|
18
|
+
def body
|
19
|
+
xml = Builder::XmlMarkup.new(:index => 4)
|
20
|
+
xml.ErrorResponse do
|
21
|
+
xml.Error do
|
22
|
+
xml.Type type
|
23
|
+
xml.Code code
|
24
|
+
xml.Message error.to_s
|
25
|
+
xml.Detail
|
26
|
+
end
|
27
|
+
xml.RequestId SecureRandom.uuid
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def code
|
34
|
+
code = error.class.name.sub(/^FakeSQS::/, '')
|
35
|
+
if statuses.has_key?(code)
|
36
|
+
code
|
37
|
+
else
|
38
|
+
"InternalError"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def type
|
43
|
+
if status < 500
|
44
|
+
"Sender"
|
45
|
+
else
|
46
|
+
"Receiver"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def statuses
|
51
|
+
@statuses ||= YAML.load_file(File.expand_path('../error_responses.yml', __FILE__))
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
AccessDenied: 403
|
2
|
+
AuthFailure: 401
|
3
|
+
ConflictingQueryParameter: 400
|
4
|
+
InternalError: 500
|
5
|
+
InvalidAccessKeyId: 401
|
6
|
+
InvalidAction: 400
|
7
|
+
InvalidAddress: 404
|
8
|
+
InvalidAttributeName: 400
|
9
|
+
InvalidHttpRequest: 400
|
10
|
+
InvalidMessageContents: 400
|
11
|
+
InvalidParameterCombination: 400
|
12
|
+
InvalidParameterValue: 400
|
13
|
+
InvalidQueryParameter: 400
|
14
|
+
InvalidRequest: 400
|
15
|
+
InvalidSecurity: 403
|
16
|
+
InvalidSecurityToken: 400
|
17
|
+
MalformedVersion: 400
|
18
|
+
MessageTooLong: 400
|
19
|
+
MissingClientTokenId: 403
|
20
|
+
MissingCredentials: 401
|
21
|
+
MissingParameter: 400
|
22
|
+
NoSuchVersion: 400
|
23
|
+
NonExistentQueue: 400
|
24
|
+
NotAuthorizedToUseVersion: 401
|
25
|
+
QueueDeletedRecently: 400
|
26
|
+
QueueNameExists: 400
|
27
|
+
ReadCountOutOfRange: 400
|
28
|
+
RequestExpired: 400
|
29
|
+
RequestThrottled: 403
|
30
|
+
ServiceUnavailable: 503
|
31
|
+
X509ParseError: 400
|
data/lib/fake_sqs/server.rb
CHANGED
@@ -1,171 +1,15 @@
|
|
1
1
|
module FakeSQS
|
2
2
|
class Server
|
3
3
|
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :host, :port
|
5
5
|
|
6
|
-
def initialize(options
|
7
|
-
@host
|
8
|
-
@port
|
9
|
-
@queues = options.fetch(:queues)
|
10
|
-
@responder = options.fetch(:responder)
|
6
|
+
def initialize(options)
|
7
|
+
@host = options.fetch(:host)
|
8
|
+
@port = options.fetch(:port)
|
11
9
|
end
|
12
10
|
|
13
|
-
def
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
# Actions for Queues
|
18
|
-
|
19
|
-
def create_queue(params)
|
20
|
-
name = params.fetch("QueueName")
|
21
|
-
queue = queues.create(name, params)
|
22
|
-
respond :CreateQueue do |xml|
|
23
|
-
xml.QueueUrl url_for(queue.name)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def delete_queue(name, params)
|
28
|
-
queues.delete(name, params)
|
29
|
-
respond :DeleteQueue
|
30
|
-
end
|
31
|
-
|
32
|
-
def list_queues(params)
|
33
|
-
found = queues.list(params)
|
34
|
-
respond :ListQueues do |xml|
|
35
|
-
found.each do |queue|
|
36
|
-
xml.QueueUrl url_for(queue.name)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def get_queue_url(params)
|
42
|
-
name = params.fetch("QueueName")
|
43
|
-
queue = queues.get(name, params)
|
44
|
-
respond :GetQueueUrl do |xml|
|
45
|
-
xml.QueueUrl url_for(queue.name)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def get_queue_attributes(name, params)
|
50
|
-
end
|
51
|
-
|
52
|
-
def set_queue_attributes(name, params)
|
53
|
-
end
|
54
|
-
|
55
|
-
# Actions for Access Control on Queues
|
56
|
-
|
57
|
-
def add_permission(name, params)
|
58
|
-
end
|
59
|
-
|
60
|
-
def remove_persmission(name, params)
|
61
|
-
end
|
62
|
-
|
63
|
-
# Actions for Messages
|
64
|
-
|
65
|
-
def send_message(name, params)
|
66
|
-
queue = queues.get(name)
|
67
|
-
message = queue.send_message(params)
|
68
|
-
respond :SendMessage do |xml|
|
69
|
-
xml.MD5OfMessageBody message.md5
|
70
|
-
xml.MessageId message.id
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def receive_message(name, params)
|
75
|
-
queue = queues.get(name)
|
76
|
-
messages = queue.receive_message(params)
|
77
|
-
respond :ReceiveMessage do |xml|
|
78
|
-
messages.each do |receipt, message|
|
79
|
-
xml.Message do
|
80
|
-
xml.MessageId message.id
|
81
|
-
xml.ReceiptHandle receipt
|
82
|
-
xml.MD5OfMessageBody message.md5
|
83
|
-
xml.Body message.body
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def delete_message(name, params)
|
90
|
-
queue = queues.get(name)
|
91
|
-
|
92
|
-
receipt = params.fetch("ReceiptHandle")
|
93
|
-
queue.delete_message(receipt)
|
94
|
-
respond :DeleteMessage
|
95
|
-
end
|
96
|
-
|
97
|
-
def delete_message_batch(name, params)
|
98
|
-
queue = queues.get(name)
|
99
|
-
receipts = params.select { |k,v| k =~ /DeleteMessageBatchRequestEntry\.\d+\.ReceiptHandle/ }
|
100
|
-
|
101
|
-
deleted = []
|
102
|
-
|
103
|
-
receipts.each do |key, value|
|
104
|
-
id = key.split('.')[1]
|
105
|
-
queue.delete_message(value)
|
106
|
-
deleted << params.fetch("DeleteMessageBatchRequestEntry.#{id}.Id")
|
107
|
-
end
|
108
|
-
|
109
|
-
respond :DeleteMessageBatch do |xml|
|
110
|
-
deleted.each do |id|
|
111
|
-
xml.DeleteMessageBatchResultEntry do
|
112
|
-
xml.Id id
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def send_message_batch(name, params)
|
119
|
-
queue = queues.get(name)
|
120
|
-
|
121
|
-
messages = params.select { |k,v| k =~ /SendMessageBatchRequestEntry\.\d+\.MessageBody/ }
|
122
|
-
|
123
|
-
results = {}
|
124
|
-
|
125
|
-
messages.each do |key, value|
|
126
|
-
id = key.split('.')[1]
|
127
|
-
msg_id = params.fetch("SendMessageBatchRequestEntry.#{id}.Id")
|
128
|
-
delay = params["SendMessageBatchRequestEntry.#{id}.DelaySeconds"]
|
129
|
-
message = queue.send_message("MessageBody" => value, "DelaySeconds" => delay)
|
130
|
-
results[msg_id] = message
|
131
|
-
end
|
132
|
-
|
133
|
-
respond :SendMessageBatch do |xml|
|
134
|
-
results.each do |msg_id, message|
|
135
|
-
xml.SendMessageBatchResultEntry do
|
136
|
-
xml.Id msg_id
|
137
|
-
xml.MessageId message.id
|
138
|
-
xml.MD5OfMessageBody message.md5
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
|
145
|
-
def change_message_visibility(name, params)
|
146
|
-
end
|
147
|
-
|
148
|
-
def change_message_visibility_batch(name, params)
|
149
|
-
end
|
150
|
-
|
151
|
-
# Fake actions
|
152
|
-
|
153
|
-
def reset
|
154
|
-
queues.reset
|
155
|
-
end
|
156
|
-
|
157
|
-
def expire
|
158
|
-
queues.expire
|
159
|
-
end
|
160
|
-
|
161
|
-
private
|
162
|
-
|
163
|
-
def respond(*args, &block)
|
164
|
-
responder.call(*args, &block)
|
165
|
-
end
|
166
|
-
|
167
|
-
def url_for(id)
|
168
|
-
"http://#{host}:#{port}/#{id}"
|
11
|
+
def url_for(queue_id)
|
12
|
+
"http://#{host}:#{port}/#{queue_id}"
|
169
13
|
end
|
170
14
|
|
171
15
|
end
|
data/lib/fake_sqs/show_output.rb
CHANGED
data/lib/fake_sqs/version.rb
CHANGED
@@ -4,17 +4,13 @@ module FakeSQS
|
|
4
4
|
class WebInterface < Sinatra::Base
|
5
5
|
|
6
6
|
configure do
|
7
|
-
|
7
|
+
use FakeSQS::CatchErrors, response: ErrorResponse
|
8
8
|
end
|
9
9
|
|
10
10
|
helpers do
|
11
11
|
|
12
12
|
def action
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
def underscore(string)
|
17
|
-
string.gsub(/([A-Z])/) { |m| "_#{m[0]}".downcase }.sub(/^_/, '')
|
13
|
+
params.fetch("Action")
|
18
14
|
end
|
19
15
|
|
20
16
|
end
|
@@ -24,21 +20,21 @@ module FakeSQS
|
|
24
20
|
end
|
25
21
|
|
26
22
|
delete "/" do
|
27
|
-
settings.
|
23
|
+
settings.api.reset
|
28
24
|
200
|
29
25
|
end
|
30
26
|
|
31
27
|
put "/" do
|
32
|
-
settings.
|
28
|
+
settings.api.expire
|
33
29
|
200
|
34
30
|
end
|
35
31
|
|
36
32
|
post "/" do
|
37
|
-
settings.
|
33
|
+
settings.api.call(action, params)
|
38
34
|
end
|
39
35
|
|
40
36
|
post "/:queue" do |queue|
|
41
|
-
settings.
|
37
|
+
settings.api.call(action, queue, params)
|
42
38
|
end
|
43
39
|
|
44
40
|
end
|
data/spec/support/aws.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'fake_sqs/api'
|
2
|
+
|
3
|
+
class FakeSQS::Actions::TheAction
|
4
|
+
|
5
|
+
def initialize(options)
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(params)
|
10
|
+
{ :options => @options, :params => params }
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
describe FakeSQS::API do
|
16
|
+
|
17
|
+
it "delegates actions to classes" do
|
18
|
+
api = FakeSQS::API.new(:queues => [])
|
19
|
+
|
20
|
+
response = api.call("TheAction", {:foo => "bar"})
|
21
|
+
|
22
|
+
response[:options].should eq :queues => []
|
23
|
+
response[:params].should eq :foo => "bar"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "raises InvalidAction for unknown actions" do
|
27
|
+
api = FakeSQS::API.new(:queues => [])
|
28
|
+
|
29
|
+
expect {
|
30
|
+
api.call("SomethingDifferentAndUnknown", {:foo => "bar"})
|
31
|
+
}.to raise_error(FakeSQS::InvalidAction)
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
it "resets queues" do
|
36
|
+
queues = double :queues
|
37
|
+
api = FakeSQS::API.new(:queues => queues)
|
38
|
+
queues.should_receive(:reset)
|
39
|
+
api.reset
|
40
|
+
end
|
41
|
+
|
42
|
+
it "expires messages in queues" do
|
43
|
+
queues = double :queues
|
44
|
+
api = FakeSQS::API.new(:queues => queues)
|
45
|
+
queues.should_receive(:expire)
|
46
|
+
api.expire
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'fake_sqs/catch_errors'
|
2
|
+
|
3
|
+
describe FakeSQS::CatchErrors do
|
4
|
+
|
5
|
+
let(:app) { double :app }
|
6
|
+
let(:error_response) { double :error_response, :status => 500, :body => "X" }
|
7
|
+
let(:response) { double :response, :new => error_response }
|
8
|
+
subject(:catch_errors) { FakeSQS::CatchErrors.new(app, response: response) }
|
9
|
+
|
10
|
+
context "when the app behaves normally" do
|
11
|
+
|
12
|
+
let(:normal_response) { double :normal_response }
|
13
|
+
before { app.stub(:call => normal_response) }
|
14
|
+
|
15
|
+
it "doesn't modify normal responses" do
|
16
|
+
catch_errors.call({}).should eq normal_response
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when the app raises an exception" do
|
22
|
+
|
23
|
+
let(:error) { RuntimeError.new("it went wrong") }
|
24
|
+
before { app.stub(:call).and_raise(error) }
|
25
|
+
|
26
|
+
it "cathes and processes errors" do
|
27
|
+
response.should_receive(:new).with(error)
|
28
|
+
catch_errors.call({})
|
29
|
+
end
|
30
|
+
|
31
|
+
it "sets the status determined by the error response" do
|
32
|
+
error_response.stub(:status => 123)
|
33
|
+
catch_errors.call({}).fetch(0).should eq 123
|
34
|
+
end
|
35
|
+
|
36
|
+
it "set the body determined by the error response" do
|
37
|
+
error_response.stub(:body => "foobar")
|
38
|
+
catch_errors.call({}).fetch(2).should eq ["foobar"]
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'fake_sqs/error_response'
|
2
|
+
require 'active_support/core_ext/hash'
|
3
|
+
require 'verbose_hash_fetch'
|
4
|
+
|
5
|
+
describe FakeSQS::ErrorResponse do
|
6
|
+
|
7
|
+
module FakeSQS
|
8
|
+
MissingCredentials = Class.new(RuntimeError)
|
9
|
+
end
|
10
|
+
ErrorUnknownToSQS = Class.new(RuntimeError)
|
11
|
+
|
12
|
+
describe "#status" do
|
13
|
+
|
14
|
+
it "picks the right error status" do
|
15
|
+
error = FakeSQS::MissingCredentials.new("message")
|
16
|
+
response = FakeSQS::ErrorResponse.new(error)
|
17
|
+
response.status.should eq 401
|
18
|
+
end
|
19
|
+
|
20
|
+
it "uses 400 as default status" do
|
21
|
+
error = ErrorUnknownToSQS.new("message")
|
22
|
+
response = FakeSQS::ErrorResponse.new(error)
|
23
|
+
response.status.should eq 500
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#body" do
|
29
|
+
|
30
|
+
let(:error) { FakeSQS::MissingCredentials.new("the message") }
|
31
|
+
let(:response) { FakeSQS::ErrorResponse.new(error) }
|
32
|
+
let(:data) { Hash.from_xml(response.body) }
|
33
|
+
|
34
|
+
it "uses the error class name as error code" do
|
35
|
+
data.fetch("ErrorResponse").fetch("Error").fetch("Code").should eq "MissingCredentials"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "uses InternalError as code for unknown errors" do
|
39
|
+
error = ErrorUnknownToSQS.new("the message")
|
40
|
+
response = FakeSQS::ErrorResponse.new(error)
|
41
|
+
data = Hash.from_xml(response.body)
|
42
|
+
data.fetch("ErrorResponse").fetch("Error").fetch("Code").should eq "InternalError"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "uses the to_s of the error as message" do
|
46
|
+
data.fetch("ErrorResponse").fetch("Error").fetch("Message").should eq "the message"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "has a request id" do
|
50
|
+
data.fetch("ErrorResponse").fetch("RequestId").should have(36).characters
|
51
|
+
end
|
52
|
+
|
53
|
+
it "uses Sender as type for 4xx responses" do
|
54
|
+
response.stub(:status => 400)
|
55
|
+
data.fetch("ErrorResponse").fetch("Error").fetch("Type").should eq "Sender"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "uses Receiver as type for 5xx responses" do
|
59
|
+
response.stub(:status => 500)
|
60
|
+
data.fetch("ErrorResponse").fetch("Error").fetch("Type").should eq "Receiver"
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fake_sqs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sinatra
|
@@ -91,22 +91,6 @@ dependencies:
|
|
91
91
|
- - ! '>='
|
92
92
|
- !ruby/object:Gem::Version
|
93
93
|
version: '0'
|
94
|
-
- !ruby/object:Gem::Dependency
|
95
|
-
name: webmock
|
96
|
-
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
|
-
requirements:
|
99
|
-
- - ! '>='
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
version: '0'
|
102
|
-
type: :development
|
103
|
-
prerelease: false
|
104
|
-
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
|
-
requirements:
|
107
|
-
- - ! '>='
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version: '0'
|
110
94
|
- !ruby/object:Gem::Dependency
|
111
95
|
name: faraday
|
112
96
|
requirement: !ruby/object:Gem::Requirement
|
@@ -189,6 +173,19 @@ files:
|
|
189
173
|
- bin/fake_sqs
|
190
174
|
- fake_sqs.gemspec
|
191
175
|
- lib/fake_sqs.rb
|
176
|
+
- lib/fake_sqs/actions/create_queue.rb
|
177
|
+
- lib/fake_sqs/actions/delete_message.rb
|
178
|
+
- lib/fake_sqs/actions/delete_message_batch.rb
|
179
|
+
- lib/fake_sqs/actions/delete_queue.rb
|
180
|
+
- lib/fake_sqs/actions/get_queue_url.rb
|
181
|
+
- lib/fake_sqs/actions/list_queues.rb
|
182
|
+
- lib/fake_sqs/actions/receive_message.rb
|
183
|
+
- lib/fake_sqs/actions/send_message.rb
|
184
|
+
- lib/fake_sqs/actions/send_message_batch.rb
|
185
|
+
- lib/fake_sqs/api.rb
|
186
|
+
- lib/fake_sqs/catch_errors.rb
|
187
|
+
- lib/fake_sqs/error_response.rb
|
188
|
+
- lib/fake_sqs/error_responses.yml
|
192
189
|
- lib/fake_sqs/message.rb
|
193
190
|
- lib/fake_sqs/queue.rb
|
194
191
|
- lib/fake_sqs/queue_factory.rb
|
@@ -201,6 +198,9 @@ files:
|
|
201
198
|
- spec/acceptance/message_actions_spec.rb
|
202
199
|
- spec/acceptance/queue_actions_spec.rb
|
203
200
|
- spec/support/aws.rb
|
201
|
+
- spec/unit/api_spec.rb
|
202
|
+
- spec/unit/catch_errors_spec.rb
|
203
|
+
- spec/unit/error_response_spec.rb
|
204
204
|
- spec/unit/message_spec.rb
|
205
205
|
- spec/unit/queue_factory_spec.rb
|
206
206
|
- spec/unit/queue_spec.rb
|
@@ -235,6 +235,9 @@ test_files:
|
|
235
235
|
- spec/acceptance/message_actions_spec.rb
|
236
236
|
- spec/acceptance/queue_actions_spec.rb
|
237
237
|
- spec/support/aws.rb
|
238
|
+
- spec/unit/api_spec.rb
|
239
|
+
- spec/unit/catch_errors_spec.rb
|
240
|
+
- spec/unit/error_response_spec.rb
|
238
241
|
- spec/unit/message_spec.rb
|
239
242
|
- spec/unit/queue_factory_spec.rb
|
240
243
|
- spec/unit/queue_spec.rb
|