sanford 0.15.1 → 0.16.0

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.
@@ -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