fake_sqs 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,172 @@
1
+ module FakeSQS
2
+ class Server
3
+
4
+ attr_reader :port, :host, :queues, :responder
5
+
6
+ def initialize(options = {})
7
+ @host = options.fetch(:host)
8
+ @port = options.fetch(:port)
9
+ @queues = options.fetch(:queues)
10
+ @responder = options.fetch(:responder)
11
+ end
12
+
13
+ def call(action, *args)
14
+ public_send(action, *args)
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}"
169
+ end
170
+
171
+ end
172
+ end
@@ -0,0 +1,18 @@
1
+ module FakeSQS
2
+ class ShowOutput
3
+
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ request = Rack::Request.new(env)
10
+ result = @app.call(env)
11
+ puts request.params.to_yaml
12
+ puts
13
+ puts *result.last
14
+ result
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module FakeSQS
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,45 @@
1
+ require 'sinatra/base'
2
+
3
+ module FakeSQS
4
+ class WebInterface < Sinatra::Base
5
+
6
+ configure do
7
+ set :sqs, FakeSQS.server(port: settings.port, host: settings.bind)
8
+ end
9
+
10
+ helpers do
11
+
12
+ def action
13
+ underscore(params.fetch("Action"))
14
+ end
15
+
16
+ def underscore(string)
17
+ string.gsub(/([A-Z])/) { |m| "_#{m[0]}".downcase }.sub(/^_/, '')
18
+ end
19
+
20
+ end
21
+
22
+ get "/" do
23
+ 200
24
+ end
25
+
26
+ delete "/" do
27
+ settings.sqs.reset
28
+ 200
29
+ end
30
+
31
+ put "/" do
32
+ settings.sqs.expire
33
+ 200
34
+ end
35
+
36
+ post "/" do
37
+ settings.sqs.call(action, params)
38
+ end
39
+
40
+ post "/:queue" do |queue|
41
+ settings.sqs.call(action, queue, params)
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,59 @@
1
+ require 'support/aws'
2
+
3
+ describe "Actions for Messages", :acceptance do
4
+
5
+ before do
6
+ sqs.queues.create("test")
7
+ end
8
+
9
+ let(:sqs) { AWS::SQS.new }
10
+ let(:queue) { sqs.queues.named("test") }
11
+
12
+ specify "SendMessage" do
13
+ msg = "this is my message"
14
+ result = queue.send_message(msg)
15
+ result.md5.should eq Digest::MD5.hexdigest(msg)
16
+ end
17
+
18
+ specify "ReceiveMessage" do
19
+ body = "test 123"
20
+ queue.send_message(body)
21
+ message = queue.receive_message
22
+ message.body.should eq body
23
+ end
24
+
25
+ specify "DeleteMessage" do
26
+ queue.send_message("test")
27
+
28
+ message1 = queue.receive_message
29
+ message1.delete
30
+
31
+ let_messages_in_flight_expire
32
+
33
+ message2 = queue.receive_message
34
+ message2.should be_nil
35
+ end
36
+
37
+ specify "DeleteMessageBatch" do
38
+ queue.send_message("test1")
39
+ queue.send_message("test2")
40
+
41
+ message1 = queue.receive_message
42
+ message2 = queue.receive_message
43
+ queue.batch_delete(message1, message2)
44
+
45
+ let_messages_in_flight_expire
46
+
47
+ message3 = queue.receive_message
48
+ message3.should be_nil
49
+ end
50
+
51
+ specify "SendMessageBatch" do
52
+ bodies = %w(a b c)
53
+ queue.batch_send(*bodies)
54
+
55
+ messages = queue.receive_message(:limit => 10)
56
+ messages.map(&:body).should match_array bodies
57
+ end
58
+
59
+ end
@@ -0,0 +1,44 @@
1
+ require 'support/aws'
2
+
3
+ describe "Actions for Queues", :acceptance do
4
+
5
+ let(:sqs) { AWS::SQS.new }
6
+
7
+ specify "CreateQueue" do
8
+ queue = sqs.queues.create("test-create-queue")
9
+ queue.url.should eq "http://0.0.0.0:4567/test-create-queue"
10
+ end
11
+
12
+ specify "GetQueueUrl" do
13
+ sqs.queues.create("test-get-queue-url")
14
+ queue = sqs.queues.named("test-get-queue-url")
15
+ queue.url.should eq "http://0.0.0.0:4567/test-get-queue-url"
16
+ end
17
+
18
+ specify "ListQueues" do
19
+ sqs.queues.create("test-list-1")
20
+ sqs.queues.create("test-list-2")
21
+ queues = sqs.queues.map(&:url).should eq [
22
+ "http://0.0.0.0:4567/test-list-1",
23
+ "http://0.0.0.0:4567/test-list-2"
24
+ ]
25
+ end
26
+
27
+ specify "ListQueues with prefix" do
28
+ sqs.queues.create("test-list-1")
29
+ sqs.queues.create("test-list-2")
30
+ sqs.queues.create("other-list-3")
31
+ queues = sqs.queues.with_prefix("test").map(&:url).should eq [
32
+ "http://0.0.0.0:4567/test-list-1",
33
+ "http://0.0.0.0:4567/test-list-2"
34
+ ]
35
+ end
36
+
37
+ specify "DeleteQueue" do
38
+ url = sqs.queues.create("test-delete").url
39
+ sqs.should have(1).queues
40
+ sqs.queues[url].delete
41
+ sqs.should have(0).queues
42
+ end
43
+
44
+ end
@@ -0,0 +1,99 @@
1
+ require 'aws-sdk'
2
+ require 'fake_sqs'
3
+ require 'faraday'
4
+ require 'uri'
5
+ require 'thin'
6
+
7
+ Thread.abort_on_exception = true
8
+
9
+ ENV['RACK_ENV'] = 'test'
10
+
11
+ require 'webmock/rspec'
12
+ WebMock.disable_net_connect!(:allow_localhost => true)
13
+
14
+ Thin::Logging.silent = true
15
+
16
+ class FakeServer
17
+
18
+ attr_reader :url
19
+
20
+ def initialize(url = "http://localhost:4567")
21
+ @url = url
22
+ end
23
+
24
+ def uri
25
+ @uri ||= URI.parse(url)
26
+ end
27
+
28
+ def port
29
+ uri.port
30
+ end
31
+
32
+ def host
33
+ uri.host
34
+ end
35
+
36
+ def ssl?
37
+ uri.scheme == "https"
38
+ end
39
+
40
+ def start
41
+ return if @started
42
+ @started = true
43
+ @fake_sqs_thread = Thread.new {
44
+ load File.expand_path('../../../bin/fake_sqs', __FILE__)
45
+ Sinatra::Application.run!
46
+ }
47
+ wait_until_up
48
+ end
49
+
50
+ def stop
51
+ @fake_sqs_thread.kill
52
+ end
53
+
54
+ def reset
55
+ Faraday.delete(url)
56
+ end
57
+
58
+ def expire_messages_in_flight
59
+ Faraday.put(url)
60
+ end
61
+
62
+ def wait_until_up(tries = 0)
63
+ fail "Server didn't start in time" if tries > 200
64
+ response = Faraday.get(url)
65
+ if response.status != 200
66
+ wait_until_up(tries + 1)
67
+ end
68
+ rescue Faraday::Error::ConnectionFailed
69
+ wait_until_up(tries + 1)
70
+ end
71
+
72
+ end
73
+
74
+ $fake_server = FakeServer.new
75
+
76
+ module FakeServerHelper
77
+
78
+ def let_messages_in_flight_expire
79
+ $fake_server.expire_messages_in_flight
80
+ end
81
+
82
+ end
83
+
84
+ AWS.config(
85
+ :use_ssl => $fake_server.ssl?,
86
+ :sqs_endpoint => $fake_server.host,
87
+ :sqs_port => $fake_server.port,
88
+ :access_key_id => "access key id",
89
+ :secret_access_key => "secret access key"
90
+ )
91
+
92
+
93
+ RSpec.configure do |config|
94
+ config.treat_symbols_as_metadata_keys_with_true_values = true
95
+ config.before(:suite) { $fake_server.start }
96
+ config.after(:suite) { $fake_server.stop }
97
+ config.before(:each, :acceptance) { $fake_server.reset }
98
+ config.include FakeServerHelper
99
+ end