fake_sqs 0.0.3 → 0.0.4
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.
- 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
|