sanford 0.15.1 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,10 +2,9 @@ require 'assert'
2
2
  require 'sanford/server'
3
3
 
4
4
  require 'dat-tcp/server_spy'
5
+ require 'much-plugin'
5
6
  require 'ns-options/assert_macros'
6
7
  require 'sanford/route'
7
- require 'sanford-protocol/fake_connection'
8
- require 'test/support/fake_server_connection'
9
8
 
10
9
  module Sanford::Server
11
10
 
@@ -21,12 +20,17 @@ module Sanford::Server
21
20
  should have_imeths :configuration
22
21
  should have_imeths :name, :ip, :port, :pid_file
23
22
  should have_imeths :receives_keep_alive
23
+ should have_imeths :worker_class, :worker_params
24
+ should have_imeths :num_workers, :workers
24
25
  should have_imeths :verbose_logging, :logger
26
+ should have_imeths :shutdown_timeout
25
27
  should have_imeths :init, :error
26
- should have_imeths :on_worker_start, :on_worker_shutdown
27
- should have_imeths :on_worker_sleep, :on_worker_wakeup
28
28
  should have_imeths :router, :template_source
29
29
 
30
+ should "use much-plugin" do
31
+ assert_includes MuchPlugin, Sanford::Server
32
+ end
33
+
30
34
  should "know its configuration" do
31
35
  config = subject.configuration
32
36
  assert_instance_of Configuration, config
@@ -57,9 +61,9 @@ module Sanford::Server
57
61
  should "allow reading/writing its configuration pid file" do
58
62
  new_pid_file = Factory.string
59
63
  subject.pid_file(new_pid_file)
60
- expected = Pathname.new(new_pid_file)
61
- assert_equal expected, subject.configuration.pid_file
62
- assert_equal expected, subject.pid_file
64
+ exp = Pathname.new(new_pid_file)
65
+ assert_equal exp, subject.configuration.pid_file
66
+ assert_equal exp, subject.pid_file
63
67
  end
64
68
 
65
69
  should "allow reading/writing its configuration receives keep alive" do
@@ -69,6 +73,34 @@ module Sanford::Server
69
73
  assert_equal new_keep_alive, subject.receives_keep_alive
70
74
  end
71
75
 
76
+ should "allow reading/writing its configuration worker class" do
77
+ new_worker_class = Class.new
78
+ subject.worker_class(new_worker_class)
79
+ assert_equal new_worker_class, subject.configuration.worker_class
80
+ assert_equal new_worker_class, subject.worker_class
81
+ end
82
+
83
+ should "allow reading/writing its configuration worker params" do
84
+ new_worker_params = { Factory.string => Factory.string }
85
+ subject.worker_params(new_worker_params)
86
+ assert_equal new_worker_params, subject.configuration.worker_params
87
+ assert_equal new_worker_params, subject.worker_params
88
+ end
89
+
90
+ should "allow reading/writing its configuration num workers" do
91
+ new_num_workers = Factory.integer
92
+ subject.num_workers(new_num_workers)
93
+ assert_equal new_num_workers, subject.configuration.num_workers
94
+ assert_equal new_num_workers, subject.num_workers
95
+ end
96
+
97
+ should "alias workers as num workers" do
98
+ new_workers = Factory.integer
99
+ subject.workers(new_workers)
100
+ assert_equal new_workers, subject.configuration.num_workers
101
+ assert_equal new_workers, subject.workers
102
+ end
103
+
72
104
  should "allow reading/writing its configuration verbose logging" do
73
105
  new_verbose = Factory.boolean
74
106
  subject.verbose_logging(new_verbose)
@@ -83,6 +115,13 @@ module Sanford::Server
83
115
  assert_equal new_logger, subject.logger
84
116
  end
85
117
 
118
+ should "allow reading/writing its configuration shutdown timeout" do
119
+ new_shutdown_timeout = Factory.integer
120
+ subject.shutdown_timeout(new_shutdown_timeout)
121
+ assert_equal new_shutdown_timeout, subject.configuration.shutdown_timeout
122
+ assert_equal new_shutdown_timeout, subject.shutdown_timeout
123
+ end
124
+
86
125
  should "allow adding init procs to its configuration" do
87
126
  new_init_proc = proc{ Factory.string }
88
127
  subject.init(&new_init_proc)
@@ -95,22 +134,6 @@ module Sanford::Server
95
134
  assert_includes new_error_proc, subject.configuration.error_procs
96
135
  end
97
136
 
98
- should "allow reading/writing its configuration worker procs" do
99
- p = proc{}
100
-
101
- subject.on_worker_start(&p)
102
- assert_equal [p], subject.configuration.worker_start_procs
103
-
104
- subject.on_worker_shutdown(&p)
105
- assert_equal [p], subject.configuration.worker_shutdown_procs
106
-
107
- subject.on_worker_sleep(&p)
108
- assert_equal [p], subject.configuration.worker_sleep_procs
109
-
110
- subject.on_worker_wakeup(&p)
111
- assert_equal [p], subject.configuration.worker_wakeup_procs
112
- end
113
-
114
137
  should "allow reading/writing its configuration router" do
115
138
  new_router = Factory.string
116
139
  subject.router(new_router)
@@ -142,28 +165,20 @@ module Sanford::Server
142
165
  @server_class.name Factory.string
143
166
  @server_class.ip Factory.string
144
167
  @server_class.port Factory.integer
168
+ @server_class.num_workers Factory.integer
169
+ @server_class.worker_params(Factory.string => Factory.string)
170
+ @server_class.shutdown_timeout Factory.integer
145
171
 
146
172
  @error_procs = Factory.integer(3).times.map{ proc{} }
147
173
  @error_procs.each{ |p| @server_class.error(&p) }
148
174
 
149
- @start_procs = Factory.integer(3).times.map{ proc{} }
150
- @shutdown_procs = Factory.integer(3).times.map{ proc{} }
151
- @sleep_procs = Factory.integer(3).times.map{ proc{} }
152
- @wakeup_procs = Factory.integer(3).times.map{ proc{} }
153
- @start_procs.each { |p| @server_class.on_worker_start(&p) }
154
- @shutdown_procs.each { |p| @server_class.on_worker_shutdown(&p) }
155
- @sleep_procs.each { |p| @server_class.on_worker_sleep(&p) }
156
- @wakeup_procs.each { |p| @server_class.on_worker_wakeup(&p) }
157
-
158
175
  @server_class.router do
159
176
  service Factory.string, TestHandler.to_s
160
177
  end
161
178
 
162
- @dat_tcp_server_spy = nil
163
- Assert.stub(DatTCP::Server, :new) do |&block|
164
- @dat_tcp_server_spy = DatTCP::ServerSpy.new
165
- @dat_tcp_server_spy.serve_proc = block
166
- @dat_tcp_server_spy
179
+ @dtcp_spy = nil
180
+ Assert.stub(DatTCP::Server, :new) do |*args|
181
+ @dtcp_spy = DatTCP::ServerSpy.new(*args)
167
182
  end
168
183
 
169
184
  @server = @server_class.new
@@ -184,34 +199,36 @@ module Sanford::Server
184
199
 
185
200
  should "know its server data" do
186
201
  configuration = subject.class.configuration
187
- sd = subject.server_data
202
+ data = subject.server_data
188
203
 
189
- assert_instance_of Sanford::ServerData, sd
190
- assert_equal configuration.name, sd.name
191
- assert_equal configuration.ip, sd.ip
192
- assert_equal configuration.port, sd.port
193
- assert_equal configuration.verbose_logging, sd.verbose_logging
194
- assert_equal configuration.receives_keep_alive, sd.receives_keep_alive
195
- assert_equal configuration.error_procs, sd.error_procs
196
- assert_equal configuration.worker_start_procs, sd.worker_start_procs
197
- assert_equal configuration.worker_shutdown_procs, sd.worker_shutdown_procs
198
- assert_equal configuration.worker_sleep_procs, sd.worker_sleep_procs
199
- assert_equal configuration.worker_wakeup_procs, sd.worker_wakeup_procs
200
- assert_equal configuration.routes, sd.routes.values
204
+ assert_instance_of Sanford::ServerData, data
205
+ assert_equal configuration.name, data.name
206
+ assert_equal configuration.ip, data.ip
207
+ assert_equal configuration.port, data.port
208
+ assert_equal configuration.worker_class, data.worker_class
209
+ assert_equal configuration.worker_params, data.worker_params
210
+ assert_equal configuration.verbose_logging, data.verbose_logging
211
+ assert_equal configuration.receives_keep_alive, data.receives_keep_alive
212
+ assert_equal configuration.error_procs, data.error_procs
213
+ assert_equal configuration.routes, data.routes.values
201
214
 
202
- assert_instance_of configuration.logger.class, sd.logger
215
+ assert_instance_of configuration.logger.class, data.logger
203
216
  end
204
217
 
205
218
  should "know its dat tcp server" do
206
- assert_not_nil @dat_tcp_server_spy
207
- assert_not_nil @dat_tcp_server_spy.serve_proc
219
+ data = subject.server_data
208
220
 
209
- assert_equal @start_procs, @dat_tcp_server_spy.worker_start_procs
210
- assert_equal @shutdown_procs, @dat_tcp_server_spy.worker_shutdown_procs
211
- assert_equal @sleep_procs, @dat_tcp_server_spy.worker_sleep_procs
212
- assert_equal @wakeup_procs, @dat_tcp_server_spy.worker_wakeup_procs
221
+ assert_not_nil @dtcp_spy
222
+ assert_equal data.worker_class, @dtcp_spy.worker_class
223
+ assert_equal data.num_workers, @dtcp_spy.num_workers
224
+ assert_equal data.dtcp_logger, @dtcp_spy.logger
225
+ assert_equal data.shutdown_timeout, @dtcp_spy.shutdown_timeout
226
+ exp = data.worker_params.merge({
227
+ :sanford_server_data => data
228
+ })
229
+ assert_equal exp, @dtcp_spy.worker_params
213
230
 
214
- assert_equal @dat_tcp_server_spy, subject.dat_tcp_server
231
+ assert_equal @dtcp_spy, subject.dat_tcp_server
215
232
  end
216
233
 
217
234
  should "demeter its server data" do
@@ -229,13 +246,13 @@ module Sanford::Server
229
246
 
230
247
  should "call listen on its dat tcp server using `listen`" do
231
248
  subject.listen
232
- assert_true @dat_tcp_server_spy.listen_called
249
+ assert_true @dtcp_spy.listen_called
233
250
  end
234
251
 
235
252
  should "use its configured ip and port by default when listening" do
236
253
  subject.listen
237
- assert_equal subject.server_data.ip, @dat_tcp_server_spy.ip
238
- assert_equal subject.server_data.port, @dat_tcp_server_spy.port
254
+ assert_equal subject.server_data.ip, @dtcp_spy.ip
255
+ assert_equal subject.server_data.port, @dtcp_spy.port
239
256
  end
240
257
 
241
258
  should "write its ip and port back to its server data" do
@@ -251,60 +268,60 @@ module Sanford::Server
251
268
  should "pass any args to its dat tcp server using `listen`" do
252
269
  ip, port = Factory.string, Factory.integer
253
270
  subject.listen(ip, port)
254
- assert_equal ip, @dat_tcp_server_spy.ip
255
- assert_equal port, @dat_tcp_server_spy.port
271
+ assert_equal ip, @dtcp_spy.ip
272
+ assert_equal port, @dtcp_spy.port
256
273
 
257
274
  file_descriptor = Factory.integer
258
275
  subject.listen(file_descriptor)
259
- assert_equal file_descriptor, @dat_tcp_server_spy.file_descriptor
276
+ assert_equal file_descriptor, @dtcp_spy.file_descriptor
260
277
  end
261
278
 
262
279
  should "know its ip, port and file descriptor" do
263
- assert_equal @dat_tcp_server_spy.ip, subject.ip
264
- assert_equal @dat_tcp_server_spy.port, subject.port
280
+ assert_equal @dtcp_spy.ip, subject.ip
281
+ assert_equal @dtcp_spy.port, subject.port
265
282
  subject.listen
266
- assert_equal @dat_tcp_server_spy.ip, subject.ip
267
- assert_equal @dat_tcp_server_spy.port, subject.port
283
+ assert_equal @dtcp_spy.ip, subject.ip
284
+ assert_equal @dtcp_spy.port, subject.port
268
285
 
269
- assert_equal @dat_tcp_server_spy.file_descriptor, subject.file_descriptor
286
+ assert_equal @dtcp_spy.file_descriptor, subject.file_descriptor
270
287
  subject.listen(Factory.integer)
271
- assert_equal @dat_tcp_server_spy.file_descriptor, subject.file_descriptor
288
+ assert_equal @dtcp_spy.file_descriptor, subject.file_descriptor
272
289
  end
273
290
 
274
291
  should "call start on its dat tcp server using `start`" do
275
- client_fds = [ Factory.integer ]
292
+ client_fds = [Factory.integer]
276
293
  subject.start(client_fds)
277
- assert_true @dat_tcp_server_spy.start_called
278
- assert_equal client_fds, @dat_tcp_server_spy.client_file_descriptors
294
+ assert_true @dtcp_spy.start_called
295
+ assert_equal client_fds, @dtcp_spy.client_file_descriptors
279
296
  end
280
297
 
281
298
  should "know its client file descriptors" do
282
- expected = @dat_tcp_server_spy.client_file_descriptors
283
- assert_equal expected, subject.client_file_descriptors
284
- subject.start([ Factory.integer ])
285
- expected = @dat_tcp_server_spy.client_file_descriptors
286
- assert_equal expected, subject.client_file_descriptors
299
+ exp = @dtcp_spy.client_file_descriptors
300
+ assert_equal exp, subject.client_file_descriptors
301
+ subject.start([Factory.integer])
302
+ exp = @dtcp_spy.client_file_descriptors
303
+ assert_equal exp, subject.client_file_descriptors
287
304
  end
288
305
 
289
306
  should "call pause on its dat tcp server using `pause`" do
290
307
  wait = Factory.boolean
291
308
  subject.pause(wait)
292
- assert_true @dat_tcp_server_spy.pause_called
293
- assert_equal wait, @dat_tcp_server_spy.waiting_for_pause
309
+ assert_true @dtcp_spy.pause_called
310
+ assert_equal wait, @dtcp_spy.waiting_for_pause
294
311
  end
295
312
 
296
313
  should "call stop on its dat tcp server using `stop`" do
297
314
  wait = Factory.boolean
298
315
  subject.stop(wait)
299
- assert_true @dat_tcp_server_spy.stop_called
300
- assert_equal wait, @dat_tcp_server_spy.waiting_for_stop
316
+ assert_true @dtcp_spy.stop_called
317
+ assert_equal wait, @dtcp_spy.waiting_for_stop
301
318
  end
302
319
 
303
320
  should "call halt on its dat tcp server using `halt`" do
304
321
  wait = Factory.boolean
305
322
  subject.halt(wait)
306
- assert_true @dat_tcp_server_spy.halt_called
307
- assert_equal wait, @dat_tcp_server_spy.waiting_for_halt
323
+ assert_true @dtcp_spy.halt_called
324
+ assert_equal wait, @dtcp_spy.waiting_for_halt
308
325
  end
309
326
 
310
327
  should "know if its been paused" do
@@ -323,7 +340,7 @@ module Sanford::Server
323
340
  desc "configuring its tcp server"
324
341
  setup do
325
342
  @tcp_server = TCPServerSpy.new
326
- Assert.stub(@dat_tcp_server_spy, :listen) do |*args, &block|
343
+ Assert.stub(@dtcp_spy, :listen) do |*args, &block|
327
344
  @configure_tcp_server_proc = block
328
345
  end
329
346
  @server.listen
@@ -332,106 +349,10 @@ module Sanford::Server
332
349
  subject{ @tcp_server }
333
350
 
334
351
  should "set the TCP_NODELAY option" do
335
- expected = [ ::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, true ]
336
- assert_includes expected, @tcp_server.set_socket_option_calls
337
- end
338
-
339
- end
340
-
341
- class ServeTests < InitTests
342
- desc "serve"
343
- setup do
344
- @socket = Factory.binary
345
-
346
- @connection = FakeServerConnection.new
347
- Assert.stub(Connection, :new).with(@socket){ @connection }
348
-
349
- @connection_handler_spy = ConnectionHandlerSpy.new
350
- Assert.stub(Sanford::ConnectionHandler, :new).tap do |s|
351
- s.with(@server.server_data, @connection){ @connection_handler_spy }
352
- end
353
-
354
- @serve_proc = @dat_tcp_server_spy.serve_proc
355
- end
356
- subject{ @serve_proc }
357
-
358
- should "run a connection_handler when called with a socket" do
359
- Assert.stub(@server.server_data, :receives_keep_alive){ false }
360
- @connection.read_data = Factory.boolean
361
- assert_false @connection_handler_spy.run_called
362
- subject.call(@socket)
363
- assert_true @connection_handler_spy.run_called
364
- end
365
-
366
- should "not run a keep-alive connection when configured to receive them" do
367
- Assert.stub(@server.server_data, :receives_keep_alive){ true }
368
- @connection.read_data = nil # nothing to read makes it a keep-alive
369
- assert_false @connection_handler_spy.run_called
370
- subject.call(@socket)
371
- assert_false @connection_handler_spy.run_called
372
- end
373
-
374
- should "run a keep-alive connection when configured to receive them" do
375
- Assert.stub(@server.server_data, :receives_keep_alive){ false }
376
- @connection.read_data = nil # nothing to read makes it a keep-alive
377
- assert_false @connection_handler_spy.run_called
378
- subject.call(@socket)
379
- assert_true @connection_handler_spy.run_called
380
- end
381
-
382
- end
383
-
384
- class ConnectionTests < UnitTests
385
- desc "Connection"
386
- setup do
387
- fake_socket = Factory.string
388
- @protocol_conn = Sanford::Protocol::FakeConnection.new(Factory.binary)
389
- Assert.stub(Sanford::Protocol::Connection, :new).with(fake_socket) do
390
- @protocol_conn
391
- end
392
- @connection = Connection.new(fake_socket)
393
- end
394
- subject{ @connection }
395
-
396
- should have_imeths :read_data, :write_data, :peek_data
397
- should have_imeths :close_write
398
-
399
- should "default its timeout" do
400
- assert_equal 1.0, subject.timeout
401
- end
402
-
403
- should "allowing reading from the protocol connection" do
404
- result = subject.read_data
405
- assert_equal @protocol_conn.read_data, result
406
- assert_equal @protocol_conn.read_timeout, subject.timeout
352
+ exp = [ ::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, true ]
353
+ assert_includes exp, @tcp_server.set_socket_option_calls
407
354
  end
408
355
 
409
- should "allowing writing to the protocol connection" do
410
- data = Factory.binary
411
- subject.write_data(data)
412
- assert_equal @protocol_conn.write_data, data
413
- end
414
-
415
- should "allowing peeking from the protocol connection" do
416
- result = subject.peek_data
417
- assert_equal @protocol_conn.peek_data, result
418
- assert_equal @protocol_conn.peek_timeout, subject.timeout
419
- end
420
-
421
- should "allow closing the write stream on the protocol connection" do
422
- assert_false @protocol_conn.closed_write
423
- subject.close_write
424
- assert_true @protocol_conn.closed_write
425
- end
426
-
427
- end
428
-
429
- class TCPCorkTests < UnitTests
430
- desc "TCPCork"
431
- subject{ TCPCork }
432
-
433
- should have_imeths :apply, :remove
434
-
435
356
  end
436
357
 
437
358
  class ConfigurationTests < UnitTests
@@ -452,9 +373,9 @@ module Sanford::Server
452
373
  should have_options :verbose_logging, :logger
453
374
  should have_options :template_source
454
375
  should have_accessors :init_procs, :error_procs
376
+ should have_accessors :worker_class, :worker_params, :num_workers
377
+ should have_accessors :shutdown_timeout
455
378
  should have_accessors :router
456
- should have_readers :worker_start_procs, :worker_shutdown_procs
457
- should have_readers :worker_sleep_procs, :worker_wakeup_procs
458
379
  should have_imeths :routes
459
380
  should have_imeths :to_hash
460
381
  should have_imeths :valid?, :validate!
@@ -463,6 +384,10 @@ module Sanford::Server
463
384
  assert_includes NsOptions::Proxy, subject.class
464
385
  end
465
386
 
387
+ should "know its default num workers" do
388
+ assert_equal 4, Configuration::DEFAULT_NUM_WORKERS
389
+ end
390
+
466
391
  should "default its options" do
467
392
  config = Configuration.new
468
393
  assert_nil config.name
@@ -476,14 +401,15 @@ module Sanford::Server
476
401
  assert_instance_of Sanford::NullLogger, config.logger
477
402
  assert_instance_of Sanford::NullTemplateSource, config.template_source
478
403
 
404
+ assert_equal DefaultWorker, config.worker_class
405
+ assert_nil config.worker_params
406
+ assert_equal Configuration::DEFAULT_NUM_WORKERS, config.num_workers
407
+
408
+ assert_nil config.shutdown_timeout
409
+
479
410
  assert_equal [], config.init_procs
480
411
  assert_equal [], config.error_procs
481
412
 
482
- assert_equal [], subject.worker_start_procs
483
- assert_equal [], subject.worker_shutdown_procs
484
- assert_equal [], subject.worker_sleep_procs
485
- assert_equal [], subject.worker_wakeup_procs
486
-
487
413
  assert_instance_of Sanford::Router, config.router
488
414
  assert_empty config.router.routes
489
415
  end
@@ -500,14 +426,14 @@ module Sanford::Server
500
426
 
501
427
  should "include its procs and router/routes in its `to_hash`" do
502
428
  config_hash = subject.to_hash
503
- assert_equal subject.init_procs, config_hash[:init_procs]
504
- assert_equal subject.error_procs, config_hash[:error_procs]
505
- assert_equal subject.worker_start_procs, config_hash[:worker_start_procs]
506
- assert_equal subject.worker_shutdown_procs, config_hash[:worker_shutdown_procs]
507
- assert_equal subject.worker_sleep_procs, config_hash[:worker_sleep_procs]
508
- assert_equal subject.worker_wakeup_procs, config_hash[:worker_wakeup_procs]
509
- assert_equal subject.router, config_hash[:router]
510
- assert_equal subject.routes, config_hash[:routes]
429
+ assert_equal subject.worker_class, config_hash[:worker_class]
430
+ assert_equal subject.worker_params, config_hash[:worker_params]
431
+ assert_equal subject.num_workers, config_hash[:num_workers]
432
+ assert_equal subject.shutdown_timeout, config_hash[:shutdown_timeout]
433
+ assert_equal subject.init_procs, config_hash[:init_procs]
434
+ assert_equal subject.error_procs, config_hash[:error_procs]
435
+ assert_equal subject.router, config_hash[:router]
436
+ assert_equal subject.routes, config_hash[:routes]
511
437
  end
512
438
 
513
439
  should "call its init procs when validated" do
@@ -533,6 +459,14 @@ module Sanford::Server
533
459
  assert_nothing_raised{ subject.validate! }
534
460
  end
535
461
 
462
+ should "validate its worker class when validated" do
463
+ subject.worker_class = Module.new
464
+ assert_raises(InvalidError){ subject.validate! }
465
+
466
+ subject.worker_class = Class.new
467
+ assert_raises(InvalidError){ subject.validate! }
468
+ end
469
+
536
470
  should "validate its routes when validated" do
537
471
  subject.router.service(Factory.string, TestHandler.to_s)
538
472
  subject.routes.each{ |route| assert_nil route.handler_class }
@@ -571,16 +505,4 @@ module Sanford::Server
571
505
  end
572
506
  end
573
507
 
574
- class ConnectionHandlerSpy
575
- attr_reader :run_called
576
-
577
- def initialize
578
- @run_called = false
579
- end
580
-
581
- def run
582
- @run_called = true
583
- end
584
- end
585
-
586
508
  end