rack-rabbit 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/EXAMPLES.md +212 -0
  4. data/Gemfile +14 -0
  5. data/Gemfile.lock +42 -0
  6. data/LICENSE +21 -0
  7. data/README.md +412 -0
  8. data/Rakefile +5 -0
  9. data/bin/rack-rabbit +96 -0
  10. data/bin/rr +99 -0
  11. data/lib/rack-rabbit.rb +63 -0
  12. data/lib/rack-rabbit/adapter.rb +85 -0
  13. data/lib/rack-rabbit/adapter/amqp.rb +114 -0
  14. data/lib/rack-rabbit/adapter/bunny.rb +87 -0
  15. data/lib/rack-rabbit/adapter/mock.rb +92 -0
  16. data/lib/rack-rabbit/client.rb +181 -0
  17. data/lib/rack-rabbit/config.rb +260 -0
  18. data/lib/rack-rabbit/handler.rb +44 -0
  19. data/lib/rack-rabbit/message.rb +95 -0
  20. data/lib/rack-rabbit/middleware/program_name.rb +34 -0
  21. data/lib/rack-rabbit/response.rb +43 -0
  22. data/lib/rack-rabbit/server.rb +263 -0
  23. data/lib/rack-rabbit/signals.rb +62 -0
  24. data/lib/rack-rabbit/subscriber.rb +77 -0
  25. data/lib/rack-rabbit/worker.rb +84 -0
  26. data/rack-rabbit.gemspec +26 -0
  27. data/test/apps/config.ru +7 -0
  28. data/test/apps/custom.conf +27 -0
  29. data/test/apps/custom.ru +7 -0
  30. data/test/apps/empty.conf +1 -0
  31. data/test/apps/error.ru +7 -0
  32. data/test/apps/mirror.ru +19 -0
  33. data/test/apps/sinatra.ru +37 -0
  34. data/test/apps/sleep.ru +21 -0
  35. data/test/test_case.rb +154 -0
  36. data/test/unit/middleware/test_program_name.rb +32 -0
  37. data/test/unit/test_client.rb +275 -0
  38. data/test/unit/test_config.rb +403 -0
  39. data/test/unit/test_handler.rb +92 -0
  40. data/test/unit/test_message.rb +213 -0
  41. data/test/unit/test_response.rb +59 -0
  42. data/test/unit/test_signals.rb +45 -0
  43. data/test/unit/test_subscriber.rb +140 -0
  44. metadata +91 -0
@@ -0,0 +1,32 @@
1
+ require_relative '../../test_case'
2
+
3
+ require 'rack-rabbit/middleware/program_name'
4
+
5
+ module RackRabbit
6
+ class TestProgramName < TestCase
7
+
8
+ #--------------------------------------------------------------------------
9
+
10
+ def test_program_name_changes_during_rack_handler
11
+ with_program_name("rr") do
12
+
13
+ assert_equal("rr", $PROGRAM_NAME)
14
+
15
+ during = nil
16
+ app = lambda{|env| during = $PROGRAM_NAME }
17
+
18
+ middleware = RackRabbit::Middleware::ProgramName.new(app, "default")
19
+ assert_equal("rr -- default", $PROGRAM_NAME)
20
+
21
+ middleware.call('REQUEST_METHOD' => 'method', 'REQUEST_PATH' => 'path')
22
+ assert_equal("rr -- default", $PROGRAM_NAME)
23
+ assert_equal("rr -- method path", during)
24
+
25
+ end
26
+ end
27
+
28
+ #--------------------------------------------------------------------------
29
+
30
+ end # class TestProgramName
31
+ end # module RackRabbit
32
+
@@ -0,0 +1,275 @@
1
+ require_relative '../test_case'
2
+
3
+ module RackRabbit
4
+ class TestClient < TestCase
5
+
6
+ #--------------------------------------------------------------------------
7
+
8
+ def test_GET
9
+
10
+ Timecop.freeze do
11
+
12
+ client = build_client
13
+ reply = build_message(:correlation_id => CORRELATION_ID, :status => 200, :body => "GET OK", :headers => { "additional" => "reply_header" })
14
+ rabbit = client.rabbit
15
+
16
+ prime_reply(client, reply) # prime rabbit with a pending reply message
17
+
18
+ response = client.get(QUEUE, "/path", {
19
+ :id => CORRELATION_ID, # dependency inject generated message ID
20
+ :priority => PRIORITY,
21
+ :content_type => CONTENT::JSON,
22
+ :content_encoding => CONTENT::ASCII,
23
+ :headers => { "additional" => "request_header" }
24
+ })
25
+
26
+ assert_equal(200, response.status)
27
+ assert_equal("GET OK", response.body)
28
+ assert_equal("reply_header", response.headers["additional"])
29
+
30
+ assert_equal([reply], rabbit.subscribed_messages)
31
+ assert_equal(1, rabbit.published_messages.length)
32
+ assert_equal(nil, rabbit.published_messages[0][:exchange])
33
+ assert_equal(nil, rabbit.published_messages[0][:exchange_type])
34
+ assert_equal(QUEUE, rabbit.published_messages[0][:routing_key])
35
+ assert_equal(CORRELATION_ID, rabbit.published_messages[0][:correlation_id])
36
+ assert_equal(REPLY_QUEUE, rabbit.published_messages[0][:reply_to])
37
+ assert_equal(PRIORITY, rabbit.published_messages[0][:priority])
38
+ assert_equal(CONTENT::JSON, rabbit.published_messages[0][:content_type])
39
+ assert_equal(CONTENT::ASCII, rabbit.published_messages[0][:content_encoding])
40
+ assert_equal(Time.now.to_i, rabbit.published_messages[0][:timestamp])
41
+ assert_equal("", rabbit.published_messages[0][:body])
42
+ assert_equal("GET", rabbit.published_messages[0][:headers][RackRabbit::HEADER::METHOD])
43
+ assert_equal("/path", rabbit.published_messages[0][:headers][RackRabbit::HEADER::PATH])
44
+ assert_equal("request_header", rabbit.published_messages[0][:headers]["additional"])
45
+
46
+ end # Timecop.freeze
47
+
48
+ end
49
+
50
+ #--------------------------------------------------------------------------
51
+
52
+ def test_POST
53
+
54
+ Timecop.freeze do
55
+
56
+ client = build_client
57
+ reply = build_message(:correlation_id => CORRELATION_ID, :status => 200, :body => "POST OK", :headers => { "additional" => "reply_header" })
58
+ rabbit = client.rabbit
59
+
60
+ prime_reply(client, reply) # prime rabbit with a pending reply message
61
+
62
+ response = client.post(QUEUE, "/path", BODY, {
63
+ :id => CORRELATION_ID, # dependency inject generated message ID
64
+ :priority => PRIORITY,
65
+ :content_type => CONTENT::JSON,
66
+ :content_encoding => CONTENT::ASCII,
67
+ :headers => { "additional" => "request_header" }
68
+ })
69
+
70
+ assert_equal(200, response.status)
71
+ assert_equal("POST OK", response.body)
72
+ assert_equal("reply_header", response.headers["additional"])
73
+
74
+ assert_equal([reply], rabbit.subscribed_messages)
75
+ assert_equal(1, rabbit.published_messages.length)
76
+ assert_equal(nil, rabbit.published_messages[0][:exchange])
77
+ assert_equal(nil, rabbit.published_messages[0][:exchange_type])
78
+ assert_equal(QUEUE, rabbit.published_messages[0][:routing_key])
79
+ assert_equal(CORRELATION_ID, rabbit.published_messages[0][:correlation_id])
80
+ assert_equal(REPLY_QUEUE, rabbit.published_messages[0][:reply_to])
81
+ assert_equal(PRIORITY, rabbit.published_messages[0][:priority])
82
+ assert_equal(CONTENT::JSON, rabbit.published_messages[0][:content_type])
83
+ assert_equal(CONTENT::ASCII, rabbit.published_messages[0][:content_encoding])
84
+ assert_equal(Time.now.to_i, rabbit.published_messages[0][:timestamp])
85
+ assert_equal(BODY, rabbit.published_messages[0][:body])
86
+ assert_equal("POST", rabbit.published_messages[0][:headers][RackRabbit::HEADER::METHOD])
87
+ assert_equal("/path", rabbit.published_messages[0][:headers][RackRabbit::HEADER::PATH])
88
+ assert_equal("request_header", rabbit.published_messages[0][:headers]["additional"])
89
+
90
+ end # Timecop.freeze
91
+
92
+ end
93
+
94
+ #--------------------------------------------------------------------------
95
+
96
+ def test_PUT
97
+
98
+ Timecop.freeze do
99
+
100
+ client = build_client
101
+ reply = build_message(:correlation_id => CORRELATION_ID, :status => 200, :body => "PUT OK", :headers => { "additional" => "reply_header" })
102
+ rabbit = client.rabbit
103
+
104
+ prime_reply(client, reply) # prime rabbit with a pending reply message
105
+
106
+ response = client.put(QUEUE, "/path", BODY, {
107
+ :id => CORRELATION_ID, # dependency inject generated message ID
108
+ :priority => PRIORITY,
109
+ :content_type => CONTENT::JSON,
110
+ :content_encoding => CONTENT::ASCII,
111
+ :headers => { "additional" => "request_header" }
112
+ })
113
+
114
+ assert_equal(200, response.status)
115
+ assert_equal("PUT OK", response.body)
116
+ assert_equal("reply_header", response.headers["additional"])
117
+
118
+ assert_equal([reply], rabbit.subscribed_messages)
119
+ assert_equal(1, rabbit.published_messages.length)
120
+ assert_equal(nil, rabbit.published_messages[0][:exchange])
121
+ assert_equal(nil, rabbit.published_messages[0][:exchange_type])
122
+ assert_equal(QUEUE, rabbit.published_messages[0][:routing_key])
123
+ assert_equal(CORRELATION_ID, rabbit.published_messages[0][:correlation_id])
124
+ assert_equal(REPLY_QUEUE, rabbit.published_messages[0][:reply_to])
125
+ assert_equal(PRIORITY, rabbit.published_messages[0][:priority])
126
+ assert_equal(CONTENT::JSON, rabbit.published_messages[0][:content_type])
127
+ assert_equal(CONTENT::ASCII, rabbit.published_messages[0][:content_encoding])
128
+ assert_equal(Time.now.to_i, rabbit.published_messages[0][:timestamp])
129
+ assert_equal(BODY, rabbit.published_messages[0][:body])
130
+ assert_equal("PUT", rabbit.published_messages[0][:headers][RackRabbit::HEADER::METHOD])
131
+ assert_equal("/path", rabbit.published_messages[0][:headers][RackRabbit::HEADER::PATH])
132
+ assert_equal("request_header", rabbit.published_messages[0][:headers]["additional"])
133
+
134
+ end # Timecop.freeze
135
+
136
+ end
137
+
138
+ #--------------------------------------------------------------------------
139
+
140
+ def test_DELETE
141
+
142
+ Timecop.freeze do
143
+
144
+ client = build_client
145
+ reply = build_message(:correlation_id => CORRELATION_ID, :status => 200, :body => "DELETE OK", :headers => { "additional" => "reply_header" })
146
+ rabbit = client.rabbit
147
+
148
+ prime_reply(client, reply) # prime rabbit with a pending reply message
149
+
150
+ response = client.delete(QUEUE, "/path", {
151
+ :id => CORRELATION_ID, # dependency inject generated message ID
152
+ :priority => PRIORITY,
153
+ :content_type => CONTENT::JSON,
154
+ :content_encoding => CONTENT::ASCII,
155
+ :headers => { "additional" => "request_header" }
156
+ })
157
+
158
+ assert_equal(200, response.status)
159
+ assert_equal("DELETE OK", response.body)
160
+ assert_equal("reply_header", response.headers["additional"])
161
+
162
+ assert_equal([reply], rabbit.subscribed_messages)
163
+ assert_equal(1, rabbit.published_messages.length)
164
+ assert_equal(nil, rabbit.published_messages[0][:exchange])
165
+ assert_equal(nil, rabbit.published_messages[0][:exchange_type])
166
+ assert_equal(QUEUE, rabbit.published_messages[0][:routing_key])
167
+ assert_equal(CORRELATION_ID, rabbit.published_messages[0][:correlation_id])
168
+ assert_equal(REPLY_QUEUE, rabbit.published_messages[0][:reply_to])
169
+ assert_equal(PRIORITY, rabbit.published_messages[0][:priority])
170
+ assert_equal(CONTENT::JSON, rabbit.published_messages[0][:content_type])
171
+ assert_equal(CONTENT::ASCII, rabbit.published_messages[0][:content_encoding])
172
+ assert_equal(Time.now.to_i, rabbit.published_messages[0][:timestamp])
173
+ assert_equal("", rabbit.published_messages[0][:body])
174
+ assert_equal("DELETE", rabbit.published_messages[0][:headers][RackRabbit::HEADER::METHOD])
175
+ assert_equal("/path", rabbit.published_messages[0][:headers][RackRabbit::HEADER::PATH])
176
+ assert_equal("request_header", rabbit.published_messages[0][:headers]["additional"])
177
+
178
+ end # Timecop.freeze
179
+
180
+ end
181
+
182
+ #--------------------------------------------------------------------------
183
+
184
+ def test_ENQUEUE
185
+
186
+ Timecop.freeze do
187
+
188
+ client = build_client
189
+ rabbit = client.rabbit
190
+
191
+ response = client.enqueue(QUEUE, "/path", BODY, {
192
+ :method => :PUT,
193
+ :priority => PRIORITY,
194
+ :content_type => CONTENT::JSON,
195
+ :content_encoding => CONTENT::ASCII,
196
+ :headers => { "additional" => "request_header" }
197
+ })
198
+
199
+ assert_equal(true, response)
200
+
201
+ assert_equal([], rabbit.subscribed_messages)
202
+ assert_equal(1, rabbit.published_messages.length)
203
+ assert_equal(nil, rabbit.published_messages[0][:exchange])
204
+ assert_equal(nil, rabbit.published_messages[0][:exchange_type])
205
+ assert_equal(QUEUE, rabbit.published_messages[0][:routing_key])
206
+ assert_equal(nil, rabbit.published_messages[0][:correlation_id])
207
+ assert_equal(nil, rabbit.published_messages[0][:reply_to])
208
+ assert_equal(PRIORITY, rabbit.published_messages[0][:priority])
209
+ assert_equal(CONTENT::JSON, rabbit.published_messages[0][:content_type])
210
+ assert_equal(CONTENT::ASCII, rabbit.published_messages[0][:content_encoding])
211
+ assert_equal(Time.now.to_i, rabbit.published_messages[0][:timestamp])
212
+ assert_equal(BODY, rabbit.published_messages[0][:body])
213
+ assert_equal("PUT", rabbit.published_messages[0][:headers][RackRabbit::HEADER::METHOD])
214
+ assert_equal("/path", rabbit.published_messages[0][:headers][RackRabbit::HEADER::PATH])
215
+ assert_equal("request_header", rabbit.published_messages[0][:headers]["additional"])
216
+
217
+ end # Timecop.freeze
218
+
219
+ end
220
+
221
+ #--------------------------------------------------------------------------
222
+
223
+ def test_PUBLISH
224
+
225
+ Timecop.freeze do
226
+
227
+ client = build_client
228
+ rabbit = client.rabbit
229
+
230
+ response = client.publish(EXCHANGE, "/path", BODY, {
231
+ :exchange_type => "topic",
232
+ :routing_key => ROUTE,
233
+ :method => :PUT,
234
+ :priority => PRIORITY,
235
+ :content_type => CONTENT::JSON,
236
+ :content_encoding => CONTENT::ASCII,
237
+ :headers => { "additional" => "request_header" }
238
+ })
239
+
240
+ assert_equal(true, response)
241
+
242
+ assert_equal([], rabbit.subscribed_messages)
243
+ assert_equal(1, rabbit.published_messages.length)
244
+ assert_equal(EXCHANGE, rabbit.published_messages[0][:exchange])
245
+ assert_equal("topic", rabbit.published_messages[0][:exchange_type])
246
+ assert_equal(ROUTE, rabbit.published_messages[0][:routing_key])
247
+ assert_equal(nil, rabbit.published_messages[0][:correlation_id])
248
+ assert_equal(nil, rabbit.published_messages[0][:reply_to])
249
+ assert_equal(PRIORITY, rabbit.published_messages[0][:priority])
250
+ assert_equal(CONTENT::JSON, rabbit.published_messages[0][:content_type])
251
+ assert_equal(CONTENT::ASCII, rabbit.published_messages[0][:content_encoding])
252
+ assert_equal(Time.now.to_i, rabbit.published_messages[0][:timestamp])
253
+ assert_equal(BODY, rabbit.published_messages[0][:body])
254
+ assert_equal("PUT", rabbit.published_messages[0][:headers][RackRabbit::HEADER::METHOD])
255
+ assert_equal("/path", rabbit.published_messages[0][:headers][RackRabbit::HEADER::PATH])
256
+ assert_equal("request_header", rabbit.published_messages[0][:headers]["additional"])
257
+
258
+ end # Timecop.freeze
259
+
260
+ end
261
+
262
+ #==========================================================================
263
+ # PRIVATE IMPLEMTATION HELPERS
264
+ #==========================================================================
265
+
266
+ private
267
+
268
+ def prime_reply(client, *messages)
269
+ messages.each do |m|
270
+ client.rabbit.prime(m)
271
+ end
272
+ end
273
+
274
+ end # class TestClient
275
+ end # module RackRabbit
@@ -0,0 +1,403 @@
1
+ require_relative '../test_case'
2
+
3
+ module RackRabbit
4
+ class TestConfig < TestCase
5
+
6
+ #--------------------------------------------------------------------------
7
+
8
+ def test_construct_with_defaults
9
+
10
+ config = default_config
11
+
12
+ assert_equal("127.0.0.1", config.rabbit[:host])
13
+ assert_equal("5672", config.rabbit[:port])
14
+ assert_equal("bunny", config.rabbit[:adapter])
15
+ assert_equal(nil, config.config_file)
16
+ assert_equal(DEFAULT_RACK_APP, config.rack_file)
17
+ assert_equal(nil, config.queue)
18
+ assert_equal(nil, config.exchange)
19
+ assert_equal(:direct, config.exchange_type)
20
+ assert_equal(nil, config.routing_key)
21
+ assert_equal("rr-default-null", config.app_id)
22
+ assert_equal(1, config.workers)
23
+ assert_equal(1, config.min_workers)
24
+ assert_equal(32, config.max_workers)
25
+ assert_equal(nil, config.ack)
26
+ assert_equal(nil, config.preload_app)
27
+ assert_equal(:info, config.log_level)
28
+ assert_equal(Logger, config.logger.class)
29
+ assert_equal(nil, config.daemonize)
30
+ assert_equal(nil, config.logfile)
31
+ assert_equal(nil, config.pidfile)
32
+
33
+ end
34
+
35
+ #--------------------------------------------------------------------------
36
+
37
+ def test_construct_with_options
38
+
39
+ logger = Logger.new($stdout)
40
+
41
+ config = build_config(
42
+ :rack_file => DEFAULT_RACK_APP,
43
+ :rabbit => { :host => "10.10.10.10", :port => "1234", :adapter => "amqp" },
44
+ :queue => "myqueue",
45
+ :exchange => "myexchange",
46
+ :exchange_type => "fanout",
47
+ :routing_key => "myroute",
48
+ :app_id => "myapp",
49
+ :workers => 7,
50
+ :min_workers => 3,
51
+ :max_workers => 42,
52
+ :ack => true,
53
+ :preload_app => true,
54
+ :log_level => :fatal,
55
+ :logger => logger,
56
+ :daemonize => true,
57
+ :logfile => "myapp.log",
58
+ :pidfile => "myapp.pid"
59
+ )
60
+
61
+ assert_equal("10.10.10.10", config.rabbit[:host])
62
+ assert_equal("1234", config.rabbit[:port])
63
+ assert_equal("amqp", config.rabbit[:adapter])
64
+ assert_equal(nil, config.config_file)
65
+ assert_equal(DEFAULT_RACK_APP, config.rack_file)
66
+ assert_equal("myqueue", config.queue)
67
+ assert_equal("myexchange", config.exchange)
68
+ assert_equal(:fanout, config.exchange_type)
69
+ assert_equal("myroute", config.routing_key)
70
+ assert_equal("myapp", config.app_id)
71
+ assert_equal(7, config.workers)
72
+ assert_equal(3, config.min_workers)
73
+ assert_equal(42, config.max_workers)
74
+ assert_equal(true, config.ack)
75
+ assert_equal(true, config.preload_app)
76
+ assert_equal(:fatal, config.log_level)
77
+ assert_equal(logger, config.logger)
78
+ assert_equal(true, config.daemonize)
79
+ assert_equal(File.expand_path("myapp.log"), config.logfile)
80
+ assert_equal(File.expand_path("myapp.pid"), config.pidfile)
81
+
82
+ end
83
+
84
+ #--------------------------------------------------------------------------
85
+
86
+ def test_construct_from_configuration_file
87
+
88
+ config = build_config(:config_file => CUSTOM_CONFIG)
89
+
90
+ assert_equal("10.10.10.10", config.rabbit[:host])
91
+ assert_equal("1234", config.rabbit[:port])
92
+ assert_equal("amqp", config.rabbit[:adapter])
93
+ assert_equal(CUSTOM_CONFIG, config.config_file)
94
+ assert_equal(CUSTOM_RACK_APP, config.rack_file)
95
+ assert_equal("myqueue", config.queue)
96
+ assert_equal("myexchange", config.exchange)
97
+ assert_equal(:topic, config.exchange_type)
98
+ assert_equal("myroute", config.routing_key)
99
+ assert_equal("myapp", config.app_id)
100
+ assert_equal(7, config.workers)
101
+ assert_equal(3, config.min_workers)
102
+ assert_equal(42, config.max_workers)
103
+ assert_equal(true, config.ack)
104
+ assert_equal(true, config.preload_app)
105
+ assert_equal(:fatal, config.log_level)
106
+ assert_equal("MyLogger", config.logger.class.name)
107
+ assert_equal(true, config.daemonize)
108
+ assert_equal(File.expand_path("myapp.log"), config.logfile)
109
+ assert_equal(File.expand_path("myapp.pid"), config.pidfile)
110
+
111
+ end
112
+
113
+ #--------------------------------------------------------------------------
114
+
115
+ def test_rabbit
116
+
117
+ config = default_config
118
+
119
+ assert_equal("127.0.0.1", config.rabbit[:host])
120
+ assert_equal("5672", config.rabbit[:port])
121
+ assert_equal("bunny", config.rabbit[:adapter])
122
+
123
+ config.rabbit :host => "10.10.10.10"
124
+ config.rabbit :port => "1234"
125
+ config.rabbit :adapter => "amqp"
126
+
127
+ assert_equal("10.10.10.10", config.rabbit[:host])
128
+ assert_equal("1234", config.rabbit[:port])
129
+ assert_equal("amqp", config.rabbit[:adapter])
130
+
131
+ config.rabbit :host => "1.2.3.4", :port => "5678", :adapter => "hare"
132
+
133
+ assert_equal("1.2.3.4", config.rabbit[:host])
134
+ assert_equal("5678", config.rabbit[:port])
135
+ assert_equal("hare", config.rabbit[:adapter])
136
+
137
+ end
138
+
139
+ #--------------------------------------------------------------------------
140
+
141
+ def test_config_file
142
+ config = build_config
143
+ assert_equal(nil, config.config_file)
144
+ config.config_file "examples/custom.conf"
145
+ assert_equal(File.expand_path("examples/custom.conf"), config.config_file)
146
+ end
147
+
148
+ #--------------------------------------------------------------------------
149
+
150
+ def test_rack_file
151
+ config = build_config
152
+ assert_equal(DEFAULT_RACK_APP, config.rack_file)
153
+ config.rack_file CUSTOM_RACK_APP
154
+ assert_equal(CUSTOM_RACK_APP, config.rack_file)
155
+ end
156
+
157
+ def test_rack_file_is_required
158
+ assert_raises_argument_error("missing rack config file") do
159
+ RackRabbit::Config.new(:queue => "myqueue")
160
+ end
161
+ assert_raises_argument_error("missing rack config file") do
162
+ RackRabbit::Config.new(:queue => "myqueue", :rack_file => "/no/such/path/config.ru")
163
+ end
164
+ end
165
+
166
+ def test_rack_file_default_is_relative_to_config_file
167
+ config = build_config(:config_file => EMPTY_CONFIG)
168
+ assert_equal(File.join(File.dirname(EMPTY_CONFIG), "config.ru"), config.rack_file)
169
+ end
170
+
171
+ #--------------------------------------------------------------------------
172
+
173
+ def test_queue
174
+ config = build_config
175
+ assert_equal(nil, config.queue)
176
+ config.queue "myqueue"
177
+ assert_equal("myqueue", config.queue)
178
+ end
179
+
180
+ def test_exchange
181
+ config = build_config
182
+ assert_equal(nil, config.exchange)
183
+ config.exchange "myexchange"
184
+ assert_equal("myexchange", config.exchange)
185
+ end
186
+
187
+ def test_exchange_type
188
+ config = build_config
189
+ assert_equal(:direct, config.exchange_type)
190
+ config.exchange_type :fanout
191
+ assert_equal(:fanout, config.exchange_type)
192
+ end
193
+
194
+ def test_routing_key
195
+ config = build_config
196
+ assert_equal(nil, config.routing_key)
197
+ config.routing_key "myroute"
198
+ assert_equal("myroute", config.routing_key)
199
+ end
200
+
201
+ def test_queue_or_exchange_is_required
202
+ assert_raises_argument_error("must provide EITHER a :queue OR an :exchange") do
203
+ bad = build_config(:validate => true)
204
+ end
205
+ good1 = build_config(:validate => true, :queue => "myqueue")
206
+ good2 = build_config(:validate => true, :exchange => "myexchange")
207
+ end
208
+
209
+ #--------------------------------------------------------------------------
210
+
211
+ def test_app_id
212
+ config = build_config
213
+ assert_equal("rr-default-null", config.app_id)
214
+ config.app_id "myapp"
215
+ assert_equal("myapp", config.app_id)
216
+ end
217
+
218
+ def test_app_id_defaults_include_exchange_and_queue_or_route
219
+
220
+ config = build_config(:exchange => "myexchange", :queue => "myqueue", :routing_key => "myroute")
221
+ assert_equal("rr-myexchange-myqueue", config.app_id)
222
+
223
+ config = build_config(:exchange => "myexchange", :queue => "myqueue", :routing_key => nil)
224
+ assert_equal("rr-myexchange-myqueue", config.app_id)
225
+
226
+ config = build_config(:exchange => "myexchange", :queue => nil, :routing_key => "myroute")
227
+ assert_equal("rr-myexchange-myroute", config.app_id)
228
+
229
+ config = build_config(:exchange => "myexchange", :queue => nil, :routing_key => nil)
230
+ assert_equal("rr-myexchange-null", config.app_id)
231
+
232
+ end
233
+
234
+ #--------------------------------------------------------------------------
235
+
236
+ def test_workers
237
+ config = build_config
238
+ assert_equal(1, config.workers)
239
+ config.workers 7
240
+ assert_equal(7, config.workers)
241
+ end
242
+
243
+ def test_min_workers
244
+ config = build_config
245
+ assert_equal(1, config.min_workers)
246
+ config.min_workers 8
247
+ assert_equal(8, config.min_workers)
248
+ end
249
+
250
+ def test_max_workers
251
+ config = build_config
252
+ assert_equal(32, config.max_workers)
253
+ config.max_workers 64
254
+ assert_equal(64, config.max_workers)
255
+ end
256
+
257
+ #--------------------------------------------------------------------------
258
+
259
+ def test_ack
260
+ config = build_config
261
+ assert_equal(nil, config.ack)
262
+ config.ack true
263
+ assert_equal(true, config.ack)
264
+ config.ack false
265
+ assert_equal(false, config.ack)
266
+ end
267
+
268
+ #--------------------------------------------------------------------------
269
+
270
+ def test_preload_app
271
+ config = build_config
272
+ assert_equal(nil, config.preload_app)
273
+ config.preload_app true
274
+ assert_equal(true, config.preload_app)
275
+ config.preload_app false
276
+ assert_equal(false, config.preload_app)
277
+ end
278
+
279
+ #--------------------------------------------------------------------------
280
+
281
+ def test_daemonize
282
+ config = build_config
283
+ assert_equal(nil, config.daemonize)
284
+ config.daemonize true
285
+ assert_equal(true, config.daemonize)
286
+ config.daemonize false
287
+ assert_equal(false, config.daemonize)
288
+ end
289
+
290
+ #--------------------------------------------------------------------------
291
+
292
+ def test_log_level
293
+ config = build_config
294
+ assert_equal(:info, config.log_level)
295
+ config.log_level :debug
296
+ assert_equal(:debug, config.log_level)
297
+ end
298
+
299
+ #--------------------------------------------------------------------------
300
+
301
+ def test_logger
302
+
303
+ config = default_config
304
+
305
+ assert_equal(Logger, config.logger.class)
306
+ assert_equal(true, config.logger.respond_to?(:master_pid))
307
+ assert_equal($$, config.logger.master_pid)
308
+ assert_equal(Proc, config.logger.formatter.class)
309
+ assert_equal(Logger::INFO, config.logger.level)
310
+
311
+ config.logger CustomLogger.new($stderr, Logger::WARN)
312
+
313
+ assert_equal(CustomLogger, config.logger.class)
314
+ assert_equal(false, config.logger.respond_to?(:master_pid))
315
+ assert_equal(NilClass, config.logger.formatter.class)
316
+ assert_equal(Logger::WARN, config.logger.level)
317
+
318
+ end
319
+
320
+ #--------------------------------------------------------------------------
321
+
322
+ def test_logfile
323
+ config = build_config
324
+ assert_equal(nil, config.logfile)
325
+ config.logfile "myapp.log"
326
+ assert_equal(File.expand_path("myapp.log"), config.logfile)
327
+ end
328
+
329
+ def test_logfile_defaults_when_daemonized
330
+ config = build_config(:daemonize => true, :app_id => "myapp", :skip_filesystem_checks => true)
331
+ assert_equal("/var/log/myapp.log", config.logfile)
332
+ end
333
+
334
+ #--------------------------------------------------------------------------
335
+
336
+ def test_pidfile
337
+ config = build_config
338
+ assert_equal(nil, config.pidfile)
339
+ config.pidfile "myapp.pid"
340
+ assert_equal(File.expand_path("myapp.pid"), config.pidfile)
341
+ end
342
+
343
+ def test_pidfile_defaults_when_daemonized
344
+ config = build_config(:daemonize => true, :app_id => "myapp", :skip_filesystem_checks => true)
345
+ assert_equal("/var/run/myapp.pid", config.pidfile)
346
+ end
347
+
348
+ #--------------------------------------------------------------------------
349
+
350
+ def test_before_fork
351
+ config = build_config
352
+ server = nil
353
+ config.before_fork do |s|
354
+ server = s
355
+ end
356
+ config.before_fork(:server)
357
+ assert_equal(:server, server, "verify block got called")
358
+ end
359
+
360
+ def test_after_fork
361
+ config = build_config
362
+ server = nil
363
+ worker = nil
364
+ config.after_fork do |s, w|
365
+ server = s
366
+ worker = w
367
+ end
368
+ config.after_fork(:server, :worker)
369
+ assert_equal(:server, server, "verify block got called")
370
+ assert_equal(:worker, worker, "verify block got called")
371
+ end
372
+
373
+ #--------------------------------------------------------------------------
374
+
375
+ def test_rack_env
376
+ config = build_config(:app_id => APP_ID)
377
+ assert_equal(Rack::VERSION, config.rack_env['rack.version'])
378
+ assert_equal(config.logger, config.rack_env['rack.logger'])
379
+ assert_equal($stderr, config.rack_env['rack.errors'])
380
+ assert_equal(false, config.rack_env['rack.multithread'])
381
+ assert_equal(true, config.rack_env['rack.multiprocess'])
382
+ assert_equal(false, config.rack_env['rack.run_once'])
383
+ assert_equal('http', config.rack_env['rack.url_scheme'])
384
+ assert_equal(APP_ID, config.rack_env['SERVER_NAME'])
385
+ end
386
+
387
+ #==========================================================================
388
+ # private helper methods
389
+ #==========================================================================
390
+
391
+ private
392
+
393
+ class CustomLogger < Logger
394
+ def initialize(file, level)
395
+ super(file)
396
+ self.level = level
397
+ end
398
+ end
399
+
400
+ #--------------------------------------------------------------------------
401
+
402
+ end
403
+ end