sanford 0.10.1 → 0.11.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.
- data/Gemfile +1 -1
- data/README.md +41 -56
- data/Rakefile +0 -1
- data/bench/client.rb +8 -3
- data/bench/{services.rb → config.sanford} +11 -6
- data/bench/{runner.rb → report.rb} +2 -2
- data/bench/report.txt +32 -32
- data/lib/sanford/cli.rb +42 -28
- data/lib/sanford/config_file.rb +79 -0
- data/lib/sanford/{worker.rb → connection_handler.rb} +28 -20
- data/lib/sanford/error_handler.rb +7 -7
- data/lib/sanford/pid_file.rb +42 -0
- data/lib/sanford/process.rb +136 -0
- data/lib/sanford/process_signal.rb +20 -0
- data/lib/sanford/route.rb +48 -0
- data/lib/sanford/router.rb +36 -0
- data/lib/sanford/runner.rb +30 -58
- data/lib/sanford/sanford_runner.rb +19 -9
- data/lib/sanford/server.rb +211 -42
- data/lib/sanford/server_data.rb +47 -0
- data/lib/sanford/service_handler.rb +8 -46
- data/lib/sanford/template_source.rb +19 -2
- data/lib/sanford/test_runner.rb +27 -28
- data/lib/sanford/version.rb +1 -1
- data/lib/sanford.rb +1 -23
- data/sanford.gemspec +4 -5
- data/test/helper.rb +3 -20
- data/test/support/app_server.rb +142 -0
- data/test/support/config.sanford +7 -0
- data/test/support/config_invalid_run.sanford +3 -0
- data/test/support/config_no_run.sanford +0 -0
- data/test/support/fake_server_connection.rb +58 -0
- data/test/support/pid_file_spy.rb +19 -0
- data/test/support/template.erb +1 -0
- data/test/system/server_tests.rb +378 -0
- data/test/system/service_handler_tests.rb +224 -0
- data/test/unit/cli_tests.rb +187 -0
- data/test/unit/config_file_tests.rb +59 -0
- data/test/unit/connection_handler_tests.rb +254 -0
- data/test/unit/error_handler_tests.rb +30 -35
- data/test/unit/pid_file_tests.rb +70 -0
- data/test/unit/process_signal_tests.rb +61 -0
- data/test/unit/process_tests.rb +428 -0
- data/test/unit/route_tests.rb +92 -0
- data/test/unit/router_tests.rb +65 -0
- data/test/unit/runner_tests.rb +61 -15
- data/test/unit/sanford_runner_tests.rb +162 -28
- data/test/unit/sanford_tests.rb +0 -8
- data/test/unit/server_data_tests.rb +87 -0
- data/test/unit/server_tests.rb +502 -21
- data/test/unit/service_handler_tests.rb +114 -219
- data/test/unit/template_engine_tests.rb +1 -1
- data/test/unit/template_source_tests.rb +56 -16
- data/test/unit/test_runner_tests.rb +206 -0
- metadata +67 -67
- data/bench/tasks.rb +0 -41
- data/lib/sanford/config.rb +0 -28
- data/lib/sanford/host.rb +0 -129
- data/lib/sanford/host_data.rb +0 -65
- data/lib/sanford/hosts.rb +0 -38
- data/lib/sanford/manager.rb +0 -275
- data/test/support/fake_connection.rb +0 -36
- data/test/support/helpers.rb +0 -17
- data/test/support/service_handlers.rb +0 -154
- data/test/support/services.rb +0 -123
- data/test/support/simple_client.rb +0 -62
- data/test/system/request_handling_tests.rb +0 -306
- data/test/unit/config_tests.rb +0 -56
- data/test/unit/host_data_tests.rb +0 -71
- data/test/unit/host_tests.rb +0 -141
- data/test/unit/hosts_tests.rb +0 -50
- data/test/unit/manager_tests.rb +0 -195
- data/test/unit/worker_tests.rb +0 -24
data/test/unit/server_tests.rb
CHANGED
@@ -1,48 +1,529 @@
|
|
1
1
|
require 'assert'
|
2
2
|
require 'sanford/server'
|
3
3
|
|
4
|
-
|
4
|
+
require 'dat-tcp/server_spy'
|
5
|
+
require 'ns-options/assert_macros'
|
6
|
+
require 'sanford/route'
|
7
|
+
require 'sanford-protocol/fake_connection'
|
8
|
+
require 'test/support/fake_server_connection'
|
9
|
+
|
10
|
+
module Sanford::Server
|
5
11
|
|
6
12
|
class UnitTests < Assert::Context
|
7
13
|
desc "Sanford::Server"
|
8
14
|
setup do
|
9
|
-
@
|
15
|
+
@server_class = Class.new do
|
16
|
+
include Sanford::Server
|
17
|
+
end
|
18
|
+
end
|
19
|
+
subject{ @server_class }
|
20
|
+
|
21
|
+
should have_imeths :configuration
|
22
|
+
should have_imeths :name, :ip, :port, :pid_file
|
23
|
+
should have_imeths :receives_keep_alive
|
24
|
+
should have_imeths :verbose_logging, :logger
|
25
|
+
should have_imeths :init, :error
|
26
|
+
should have_imeths :router
|
27
|
+
should have_imeths :template_source, :build_template_source
|
28
|
+
|
29
|
+
should "know its configuration" do
|
30
|
+
config = subject.configuration
|
31
|
+
assert_instance_of Configuration, config
|
32
|
+
assert_same config, subject.configuration
|
33
|
+
end
|
34
|
+
|
35
|
+
should "allow reading/writing its configuration name" do
|
36
|
+
new_name = Factory.string
|
37
|
+
subject.name(new_name)
|
38
|
+
assert_equal new_name, subject.configuration.name
|
39
|
+
assert_equal new_name, subject.name
|
40
|
+
end
|
41
|
+
|
42
|
+
should "allow reading/writing its configuration ip" do
|
43
|
+
new_ip = Factory.string
|
44
|
+
subject.ip(new_ip)
|
45
|
+
assert_equal new_ip, subject.configuration.ip
|
46
|
+
assert_equal new_ip, subject.ip
|
47
|
+
end
|
48
|
+
|
49
|
+
should "allow reading/writing its configuration port" do
|
50
|
+
new_port = Factory.integer
|
51
|
+
subject.port(new_port)
|
52
|
+
assert_equal new_port, subject.configuration.port
|
53
|
+
assert_equal new_port, subject.port
|
54
|
+
end
|
55
|
+
|
56
|
+
should "allow reading/writing its configuration pid file" do
|
57
|
+
new_pid_file = Factory.string
|
58
|
+
subject.pid_file(new_pid_file)
|
59
|
+
expected = Pathname.new(new_pid_file)
|
60
|
+
assert_equal expected, subject.configuration.pid_file
|
61
|
+
assert_equal expected, subject.pid_file
|
62
|
+
end
|
63
|
+
|
64
|
+
should "allow reading/writing its configuration receives keep alive" do
|
65
|
+
new_keep_alive = Factory.boolean
|
66
|
+
subject.receives_keep_alive(new_keep_alive)
|
67
|
+
assert_equal new_keep_alive, subject.configuration.receives_keep_alive
|
68
|
+
assert_equal new_keep_alive, subject.receives_keep_alive
|
69
|
+
end
|
70
|
+
|
71
|
+
should "allow reading/writing its configuration verbose logging" do
|
72
|
+
new_verbose = Factory.boolean
|
73
|
+
subject.verbose_logging(new_verbose)
|
74
|
+
assert_equal new_verbose, subject.configuration.verbose_logging
|
75
|
+
assert_equal new_verbose, subject.verbose_logging
|
76
|
+
end
|
77
|
+
|
78
|
+
should "allow reading/writing its configuration logger" do
|
79
|
+
new_logger = Factory.string
|
80
|
+
subject.logger(new_logger)
|
81
|
+
assert_equal new_logger, subject.configuration.logger
|
82
|
+
assert_equal new_logger, subject.logger
|
83
|
+
end
|
84
|
+
|
85
|
+
should "allow adding init procs to its configuration" do
|
86
|
+
new_init_proc = proc{ Factory.string }
|
87
|
+
subject.init(&new_init_proc)
|
88
|
+
assert_includes new_init_proc, subject.configuration.init_procs
|
89
|
+
end
|
90
|
+
|
91
|
+
should "allow adding error procs to its configuration" do
|
92
|
+
new_error_proc = proc{ Factory.string }
|
93
|
+
subject.error(&new_error_proc)
|
94
|
+
assert_includes new_error_proc, subject.configuration.error_procs
|
95
|
+
end
|
96
|
+
|
97
|
+
should "allow reading/writing its configuration router" do
|
98
|
+
new_router = Factory.string
|
99
|
+
subject.router(new_router)
|
100
|
+
assert_equal new_router, subject.configuration.router
|
101
|
+
assert_equal new_router, subject.router
|
102
|
+
end
|
103
|
+
|
104
|
+
should "allow configuring the router by passing a block to `router`" do
|
105
|
+
new_router = Factory.string
|
106
|
+
|
107
|
+
block_scope = nil
|
108
|
+
subject.router(new_router){ block_scope = self }
|
109
|
+
assert_equal new_router, subject.router
|
110
|
+
assert_equal new_router, block_scope
|
111
|
+
end
|
112
|
+
|
113
|
+
should "allow setting the configuration template source" do
|
114
|
+
new_template_source = Factory.string
|
115
|
+
subject.template_source(new_template_source)
|
116
|
+
assert_equal new_template_source, subject.configuration.template_source
|
117
|
+
assert_equal new_template_source, subject.template_source
|
118
|
+
end
|
119
|
+
|
120
|
+
should "allow setting its template source with a path and block" do
|
121
|
+
new_path = Factory.string
|
122
|
+
yielded = nil
|
123
|
+
subject.build_template_source(new_path){ |s| yielded = s }
|
124
|
+
assert_equal new_path, subject.configuration.template_source.path
|
125
|
+
assert_equal subject.configuration.template_source, yielded
|
126
|
+
end
|
127
|
+
|
128
|
+
should "allow setting its template source with only a path" do
|
129
|
+
new_path = Factory.string
|
130
|
+
subject.build_template_source(new_path)
|
131
|
+
assert_equal new_path, subject.configuration.template_source.path
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
class InitTests < UnitTests
|
137
|
+
desc "when init"
|
138
|
+
setup do
|
139
|
+
@server_class.name Factory.string
|
140
|
+
@server_class.ip Factory.string
|
141
|
+
@server_class.port Factory.integer
|
142
|
+
@server_class.error{ Factory.string }
|
143
|
+
@server_class.router do
|
144
|
+
service Factory.string, TestHandler.to_s
|
145
|
+
end
|
146
|
+
|
147
|
+
@dat_tcp_server_spy = DatTCP::ServerSpy.new
|
148
|
+
Assert.stub(DatTCP::Server, :new) do |&block|
|
149
|
+
@dat_tcp_server_spy.serve_proc = block
|
150
|
+
@dat_tcp_server_spy
|
151
|
+
end
|
152
|
+
|
153
|
+
@server = @server_class.new
|
10
154
|
end
|
11
155
|
subject{ @server }
|
12
156
|
|
13
|
-
should have_readers :
|
14
|
-
should have_imeths :
|
157
|
+
should have_readers :server_data, :dat_tcp_server
|
158
|
+
should have_imeths :name, :ip, :port
|
159
|
+
should have_imeths :file_descriptor, :client_file_descriptors
|
160
|
+
should have_imeths :listen, :start, :pause, :stop, :halt
|
161
|
+
should have_imeths :paused?
|
162
|
+
|
163
|
+
should "have validated its configuration" do
|
164
|
+
assert_true subject.class.configuration.valid?
|
165
|
+
end
|
166
|
+
|
167
|
+
should "know its server data" do
|
168
|
+
configuration = subject.class.configuration
|
169
|
+
sd = subject.server_data
|
170
|
+
|
171
|
+
assert_instance_of Sanford::ServerData, sd
|
172
|
+
assert_equal configuration.name, sd.name
|
173
|
+
assert_equal configuration.ip, sd.ip
|
174
|
+
assert_equal configuration.port, sd.port
|
175
|
+
assert_equal configuration.verbose_logging, sd.verbose_logging
|
176
|
+
assert_equal configuration.receives_keep_alive, sd.receives_keep_alive
|
177
|
+
assert_equal configuration.error_procs, sd.error_procs
|
178
|
+
assert_equal configuration.routes, sd.routes.values
|
179
|
+
assert_instance_of configuration.logger.class, sd.logger
|
180
|
+
end
|
181
|
+
|
182
|
+
should "know its dat tcp server" do
|
183
|
+
assert_equal @dat_tcp_server_spy, subject.dat_tcp_server
|
184
|
+
assert_not_nil @dat_tcp_server_spy.serve_proc
|
185
|
+
end
|
186
|
+
|
187
|
+
should "know its name, pid file and logger" do
|
188
|
+
assert_equal subject.server_data.name, subject.name
|
189
|
+
assert_equal subject.server_data.pid_file, subject.pid_file
|
190
|
+
assert_equal subject.server_data.logger, subject.logger
|
191
|
+
end
|
192
|
+
|
193
|
+
should "call listen on its dat tcp server using `listen`" do
|
194
|
+
subject.listen
|
195
|
+
assert_true @dat_tcp_server_spy.listen_called
|
196
|
+
end
|
197
|
+
|
198
|
+
should "use its configured ip and port by default when listening" do
|
199
|
+
subject.listen
|
200
|
+
assert_equal subject.server_data.ip, @dat_tcp_server_spy.ip
|
201
|
+
assert_equal subject.server_data.port, @dat_tcp_server_spy.port
|
202
|
+
end
|
203
|
+
|
204
|
+
should "pass any args to its dat tcp server using `listen`" do
|
205
|
+
ip, port = Factory.string, Factory.integer
|
206
|
+
subject.listen(ip, port)
|
207
|
+
assert_equal ip, @dat_tcp_server_spy.ip
|
208
|
+
assert_equal port, @dat_tcp_server_spy.port
|
209
|
+
|
210
|
+
file_descriptor = Factory.integer
|
211
|
+
subject.listen(file_descriptor)
|
212
|
+
assert_equal file_descriptor, @dat_tcp_server_spy.file_descriptor
|
213
|
+
end
|
214
|
+
|
215
|
+
should "know its ip, port and file descriptor" do
|
216
|
+
assert_equal @dat_tcp_server_spy.ip, subject.ip
|
217
|
+
assert_equal @dat_tcp_server_spy.port, subject.port
|
218
|
+
subject.listen
|
219
|
+
assert_equal @dat_tcp_server_spy.ip, subject.ip
|
220
|
+
assert_equal @dat_tcp_server_spy.port, subject.port
|
221
|
+
|
222
|
+
assert_equal @dat_tcp_server_spy.file_descriptor, subject.file_descriptor
|
223
|
+
subject.listen(Factory.integer)
|
224
|
+
assert_equal @dat_tcp_server_spy.file_descriptor, subject.file_descriptor
|
225
|
+
end
|
226
|
+
|
227
|
+
should "call start on its dat tcp server using `start`" do
|
228
|
+
client_fds = [ Factory.integer ]
|
229
|
+
subject.start(client_fds)
|
230
|
+
assert_true @dat_tcp_server_spy.start_called
|
231
|
+
assert_equal client_fds, @dat_tcp_server_spy.client_file_descriptors
|
232
|
+
end
|
233
|
+
|
234
|
+
should "know its client file descriptors" do
|
235
|
+
expected = @dat_tcp_server_spy.client_file_descriptors
|
236
|
+
assert_equal expected, subject.client_file_descriptors
|
237
|
+
subject.start([ Factory.integer ])
|
238
|
+
expected = @dat_tcp_server_spy.client_file_descriptors
|
239
|
+
assert_equal expected, subject.client_file_descriptors
|
240
|
+
end
|
241
|
+
|
242
|
+
should "call pause on its dat tcp server using `pause`" do
|
243
|
+
wait = Factory.boolean
|
244
|
+
subject.pause(wait)
|
245
|
+
assert_true @dat_tcp_server_spy.pause_called
|
246
|
+
assert_equal wait, @dat_tcp_server_spy.waiting_for_pause
|
247
|
+
end
|
248
|
+
|
249
|
+
should "call stop on its dat tcp server using `stop`" do
|
250
|
+
wait = Factory.boolean
|
251
|
+
subject.stop(wait)
|
252
|
+
assert_true @dat_tcp_server_spy.stop_called
|
253
|
+
assert_equal wait, @dat_tcp_server_spy.waiting_for_stop
|
254
|
+
end
|
255
|
+
|
256
|
+
should "call halt on its dat tcp server using `halt`" do
|
257
|
+
wait = Factory.boolean
|
258
|
+
subject.halt(wait)
|
259
|
+
assert_true @dat_tcp_server_spy.halt_called
|
260
|
+
assert_equal wait, @dat_tcp_server_spy.waiting_for_halt
|
261
|
+
end
|
262
|
+
|
263
|
+
should "know if its been paused" do
|
264
|
+
assert_false subject.paused?
|
265
|
+
subject.listen
|
266
|
+
assert_true subject.paused?
|
267
|
+
subject.start
|
268
|
+
assert_false subject.paused?
|
269
|
+
subject.pause
|
270
|
+
assert_true subject.paused?
|
271
|
+
end
|
272
|
+
|
273
|
+
end
|
274
|
+
|
275
|
+
class ConfigureTCPServerTests < InitTests
|
276
|
+
desc "configuring its tcp server"
|
277
|
+
setup do
|
278
|
+
@tcp_server = TCPServerSpy.new
|
279
|
+
Assert.stub(@dat_tcp_server_spy, :listen) do |*args, &block|
|
280
|
+
@configure_tcp_server_proc = block
|
281
|
+
end
|
282
|
+
@server.listen
|
283
|
+
@configure_tcp_server_proc.call(@tcp_server)
|
284
|
+
end
|
285
|
+
subject{ @tcp_server }
|
15
286
|
|
16
|
-
should "
|
17
|
-
|
287
|
+
should "set the TCP_NODELAY option" do
|
288
|
+
expected = [ ::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, true ]
|
289
|
+
assert_includes expected, @tcp_server.set_socket_option_calls
|
18
290
|
end
|
19
291
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
292
|
+
end
|
293
|
+
|
294
|
+
class ServeTests < InitTests
|
295
|
+
desc "serve"
|
296
|
+
setup do
|
297
|
+
@socket = Factory.binary
|
298
|
+
|
299
|
+
@connection = FakeServerConnection.new
|
300
|
+
Assert.stub(Connection, :new).with(@socket){ @connection }
|
301
|
+
|
302
|
+
@connection_handler_spy = ConnectionHandlerSpy.new
|
303
|
+
Assert.stub(Sanford::ConnectionHandler, :new).tap do |s|
|
304
|
+
s.with(@server.server_data, @connection){ @connection_handler_spy }
|
305
|
+
end
|
306
|
+
|
307
|
+
@serve_proc = @dat_tcp_server_spy.serve_proc
|
308
|
+
end
|
309
|
+
subject{ @serve_proc }
|
310
|
+
|
311
|
+
should "run a connection_handler when called with a socket" do
|
312
|
+
Assert.stub(@server.server_data, :receives_keep_alive){ false }
|
313
|
+
@connection.read_data = Factory.boolean
|
314
|
+
assert_false @connection_handler_spy.run_called
|
315
|
+
subject.call(@socket)
|
316
|
+
assert_true @connection_handler_spy.run_called
|
317
|
+
end
|
318
|
+
|
319
|
+
should "not run a keep-alive connection when configured to receive them" do
|
320
|
+
Assert.stub(@server.server_data, :receives_keep_alive){ true }
|
321
|
+
@connection.read_data = nil # nothing to read makes it a keep-alive
|
322
|
+
assert_false @connection_handler_spy.run_called
|
323
|
+
subject.call(@socket)
|
324
|
+
assert_false @connection_handler_spy.run_called
|
325
|
+
end
|
326
|
+
|
327
|
+
should "run a keep-alive connection when configured to receive them" do
|
328
|
+
Assert.stub(@server.server_data, :receives_keep_alive){ false }
|
329
|
+
@connection.read_data = nil # nothing to read makes it a keep-alive
|
330
|
+
assert_false @connection_handler_spy.run_called
|
331
|
+
subject.call(@socket)
|
332
|
+
assert_true @connection_handler_spy.run_called
|
24
333
|
end
|
25
334
|
|
26
335
|
end
|
27
336
|
|
28
|
-
class
|
29
|
-
desc "
|
337
|
+
class ConnectionTests < UnitTests
|
338
|
+
desc "Connection"
|
30
339
|
setup do
|
31
|
-
|
32
|
-
@
|
340
|
+
fake_socket = Factory.string
|
341
|
+
@protocol_conn = Sanford::Protocol::FakeConnection.new(Factory.binary)
|
342
|
+
Assert.stub(Sanford::Protocol::Connection, :new).with(fake_socket) do
|
343
|
+
@protocol_conn
|
344
|
+
end
|
345
|
+
@connection = Connection.new(fake_socket)
|
33
346
|
end
|
34
|
-
|
35
|
-
|
347
|
+
subject{ @connection }
|
348
|
+
|
349
|
+
should have_imeths :read_data, :write_data, :peek_data
|
350
|
+
should have_imeths :close_write
|
351
|
+
|
352
|
+
should "default its timeout" do
|
353
|
+
assert_equal 1.0, subject.timeout
|
354
|
+
end
|
355
|
+
|
356
|
+
should "allowing reading from the protocol connection" do
|
357
|
+
result = subject.read_data
|
358
|
+
assert_equal @protocol_conn.read_data, result
|
359
|
+
assert_equal @protocol_conn.read_timeout, subject.timeout
|
36
360
|
end
|
37
361
|
|
38
|
-
should "
|
39
|
-
|
362
|
+
should "allowing writing to the protocol connection" do
|
363
|
+
data = Factory.binary
|
364
|
+
subject.write_data(data)
|
365
|
+
assert_equal @protocol_conn.write_data, data
|
366
|
+
end
|
367
|
+
|
368
|
+
should "allowing peeking from the protocol connection" do
|
369
|
+
result = subject.peek_data
|
370
|
+
assert_equal @protocol_conn.peek_data, result
|
371
|
+
assert_equal @protocol_conn.peek_timeout, subject.timeout
|
372
|
+
end
|
373
|
+
|
374
|
+
should "allow closing the write stream on the protocol connection" do
|
375
|
+
assert_false @protocol_conn.closed_write
|
376
|
+
subject.close_write
|
377
|
+
assert_true @protocol_conn.closed_write
|
40
378
|
end
|
41
379
|
|
42
380
|
end
|
43
381
|
|
44
|
-
|
45
|
-
|
46
|
-
|
382
|
+
class TCPCorkTests < UnitTests
|
383
|
+
desc "TCPCork"
|
384
|
+
subject{ TCPCork }
|
385
|
+
|
386
|
+
should have_imeths :apply, :remove
|
387
|
+
|
388
|
+
end
|
389
|
+
|
390
|
+
class ConfigurationTests < UnitTests
|
391
|
+
include NsOptions::AssertMacros
|
392
|
+
|
393
|
+
desc "Configuration"
|
394
|
+
setup do
|
395
|
+
@configuration = Configuration.new.tap do |c|
|
396
|
+
c.name Factory.string
|
397
|
+
c.ip Factory.string
|
398
|
+
c.port Factory.integer
|
399
|
+
end
|
400
|
+
end
|
401
|
+
subject{ @configuration }
|
402
|
+
|
403
|
+
should have_options :name, :ip, :port, :pid_file
|
404
|
+
should have_options :receives_keep_alive
|
405
|
+
should have_options :verbose_logging, :logger
|
406
|
+
should have_options :template_source
|
407
|
+
should have_accessors :init_procs, :error_procs
|
408
|
+
should have_accessors :router
|
409
|
+
should have_imeths :routes
|
410
|
+
should have_imeths :to_hash
|
411
|
+
should have_imeths :valid?, :validate!
|
412
|
+
|
413
|
+
should "be an ns-options proxy" do
|
414
|
+
assert_includes NsOptions::Proxy, subject.class
|
415
|
+
end
|
416
|
+
|
417
|
+
should "default its options" do
|
418
|
+
config = Configuration.new
|
419
|
+
assert_nil config.name
|
420
|
+
assert_equal '0.0.0.0', config.ip
|
421
|
+
assert_nil config.port
|
422
|
+
assert_nil config.pid_file
|
423
|
+
|
424
|
+
assert_false config.receives_keep_alive
|
425
|
+
|
426
|
+
assert_true config.verbose_logging
|
427
|
+
assert_instance_of Sanford::NullLogger, config.logger
|
428
|
+
assert_instance_of Sanford::NullTemplateSource, config.template_source
|
429
|
+
|
430
|
+
assert_equal [], config.init_procs
|
431
|
+
assert_equal [], config.error_procs
|
432
|
+
|
433
|
+
assert_instance_of Sanford::Router, config.router
|
434
|
+
assert_empty config.router.routes
|
435
|
+
end
|
436
|
+
|
437
|
+
should "not be valid by default" do
|
438
|
+
assert_false subject.valid?
|
439
|
+
end
|
440
|
+
|
441
|
+
should "know its routes" do
|
442
|
+
assert_equal subject.router.routes, subject.routes
|
443
|
+
subject.router.service(Factory.string, TestHandler.to_s)
|
444
|
+
assert_equal subject.router.routes, subject.routes
|
445
|
+
end
|
446
|
+
|
447
|
+
should "include its routes, error procs and template source in its hash" do
|
448
|
+
config_hash = subject.to_hash
|
449
|
+
assert_equal subject.error_procs, config_hash[:error_procs]
|
450
|
+
assert_equal subject.routes, config_hash[:routes]
|
451
|
+
template_source = subject.template_source
|
452
|
+
assert_instance_of template_source.class, config_hash[:template_source]
|
453
|
+
assert_equal template_source.path, config_hash[:template_source].path
|
454
|
+
end
|
455
|
+
|
456
|
+
should "call its init procs when validated" do
|
457
|
+
called = false
|
458
|
+
subject.init_procs << proc{ called = true }
|
459
|
+
subject.validate!
|
460
|
+
assert_true called
|
461
|
+
end
|
462
|
+
|
463
|
+
should "ensure its required options have been set when validated" do
|
464
|
+
subject.name = nil
|
465
|
+
assert_raises(InvalidError){ subject.validate! }
|
466
|
+
subject.name = Factory.string
|
467
|
+
|
468
|
+
subject.ip = nil
|
469
|
+
assert_raises(InvalidError){ subject.validate! }
|
470
|
+
subject.ip = Factory.string
|
471
|
+
|
472
|
+
subject.port = nil
|
473
|
+
assert_raises(InvalidError){ subject.validate! }
|
474
|
+
subject.port = Factory.integer
|
475
|
+
|
476
|
+
assert_nothing_raised{ subject.validate! }
|
477
|
+
end
|
478
|
+
|
479
|
+
should "validate its routes when validated" do
|
480
|
+
subject.router.service(Factory.string, TestHandler.to_s)
|
481
|
+
subject.routes.each{ |route| assert_nil route.handler_class }
|
482
|
+
subject.validate!
|
483
|
+
subject.routes.each{ |route| assert_not_nil route.handler_class }
|
484
|
+
end
|
485
|
+
|
486
|
+
should "be valid after being validated" do
|
487
|
+
assert_false subject.valid?
|
488
|
+
subject.validate!
|
489
|
+
assert_true subject.valid?
|
490
|
+
end
|
491
|
+
|
492
|
+
should "only be able to be validated once" do
|
493
|
+
called = 0
|
494
|
+
subject.init_procs << proc{ called += 1 }
|
495
|
+
subject.validate!
|
496
|
+
assert_equal 1, called
|
497
|
+
subject.validate!
|
498
|
+
assert_equal 1, called
|
499
|
+
end
|
500
|
+
|
501
|
+
end
|
502
|
+
|
503
|
+
TestHandler = Class.new
|
504
|
+
|
505
|
+
class TCPServerSpy
|
506
|
+
attr_reader :set_socket_option_calls
|
507
|
+
|
508
|
+
def initialize
|
509
|
+
@set_socket_option_calls = []
|
510
|
+
end
|
511
|
+
|
512
|
+
def setsockopt(*args)
|
513
|
+
@set_socket_option_calls << args
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
class ConnectionHandlerSpy
|
518
|
+
attr_reader :run_called
|
519
|
+
|
520
|
+
def initialize
|
521
|
+
@run_called = false
|
522
|
+
end
|
523
|
+
|
524
|
+
def run
|
525
|
+
@run_called = true
|
526
|
+
end
|
527
|
+
end
|
47
528
|
|
48
529
|
end
|