sanford 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,7 +2,6 @@ require 'benchmark'
2
2
  require 'sanford-protocol'
3
3
  require 'sanford/error_handler'
4
4
  require 'sanford/logger'
5
- require 'sanford/runner'
6
5
 
7
6
  module Sanford
8
7
 
@@ -46,7 +46,7 @@ module Sanford
46
46
 
47
47
  def response_from_exception(exception)
48
48
  case(exception)
49
- when Sanford::Protocol::BadMessageError, Sanford::Protocol::BadRequestError
49
+ when Sanford::Protocol::BadMessageError, Sanford::Protocol::Request::InvalidError
50
50
  build_response :bad_request, :message => exception.message
51
51
  when Sanford::NotFoundError
52
52
  build_response :not_found
@@ -48,7 +48,7 @@ module Sanford
48
48
  thread = @server.start(@client_fds)
49
49
  log "#{@server.name} server started and ready."
50
50
  thread.join
51
- exec_restart_cmd if @server.paused?
51
+ run_restart_cmd if @server.paused?
52
52
  rescue StandardError => exception
53
53
  log "Error: #{exception.message}"
54
54
  log "#{@server.name} server never started."
@@ -66,12 +66,12 @@ module Sanford
66
66
  @logger.info "[Sanford] #{message}"
67
67
  end
68
68
 
69
- def exec_restart_cmd
69
+ def run_restart_cmd
70
70
  log "Restarting #{@server.name} daemon..."
71
71
  ENV['SANFORD_SERVER_FD'] = @server.file_descriptor.to_s
72
72
  ENV['SANFORD_CLIENT_FDS'] = @server.client_file_descriptors.join(',')
73
73
  ENV['SANFORD_SKIP_DAEMONIZE'] = 'yes'
74
- @restart_cmd.exec
74
+ @restart_cmd.run
75
75
  end
76
76
 
77
77
  def default_if_blank(value, default, &block)
@@ -91,21 +91,22 @@ module Sanford
91
91
  def initialize
92
92
  require 'rubygems'
93
93
  @dir = get_pwd
94
- @argv = [ Gem.ruby, $0, ARGV.dup ].flatten
94
+ @argv = [Gem.ruby, $0, ARGV.dup].flatten
95
95
  end
96
96
 
97
- def exec
97
+ def run
98
98
  Dir.chdir self.dir
99
99
  Kernel.exec(*self.argv)
100
100
  end
101
101
 
102
- protected
102
+ private
103
103
 
104
104
  # Trick from puma/unicorn. Favor PWD because it contains an unresolved
105
105
  # symlink. This is useful when restarting after deploying; the original
106
106
  # directory may be removed, but the symlink is pointing to a new
107
107
  # directory.
108
108
  def get_pwd
109
+ return Dir.pwd if ENV['PWD'].nil?
109
110
  env_stat = File.stat(ENV['PWD'])
110
111
  pwd_stat = File.stat(Dir.pwd)
111
112
  if env_stat.ino == pwd_stat.ino && env_stat.dev == pwd_stat.dev
@@ -7,14 +7,13 @@ module Sanford
7
7
  attr_reader :routes
8
8
 
9
9
  def initialize(&block)
10
- @service_handler_ns = nil
11
10
  @routes = []
12
11
  self.instance_eval(&block) if !block.nil?
13
12
  end
14
13
 
15
14
  def service_handler_ns(value = nil)
16
- @view_handler_ns = value if !value.nil?
17
- @view_handler_ns
15
+ @service_handler_ns = value if !value.nil?
16
+ @service_handler_ns
18
17
  end
19
18
 
20
19
  def service(name, handler_name)
@@ -19,7 +19,6 @@ module Sanford
19
19
 
20
20
  def initialize(handler_class, args = nil)
21
21
  @handler_class = handler_class
22
- @handler = @handler_class.new(self)
23
22
 
24
23
  a = args || {}
25
24
  @request = a[:request]
@@ -27,6 +26,8 @@ module Sanford
27
26
  @logger = a[:logger] || Sanford::NullLogger.new
28
27
  @router = a[:router] || Sanford::Router.new
29
28
  @template_source = a[:template_source] || Sanford::NullTemplateSource.new
29
+
30
+ @handler = @handler_class.new(self)
30
31
  end
31
32
 
32
33
  def run
@@ -1,6 +1,7 @@
1
1
  require 'dat-tcp'
2
2
  require 'ns-options'
3
3
  require 'ns-options/boolean'
4
+ require 'pathname'
4
5
  require 'sanford-protocol'
5
6
  require 'socket'
6
7
  require 'sanford/logger'
@@ -18,10 +18,10 @@ module Sanford
18
18
 
19
19
  args = (args || {}).dup
20
20
  super(handler_class, {
21
- :request => args.delete(:request),
22
- :params => args.delete(:params),
23
- :logger => args.delete(:logger),
24
- :router => args.delete(:router),
21
+ :request => args.delete(:request),
22
+ :params => normalize_params(args.delete(:params) || {}),
23
+ :logger => args.delete(:logger),
24
+ :router => args.delete(:router),
25
25
  :template_source => args.delete(:template_source)
26
26
  })
27
27
  args.each{ |key, value| @handler.send("#{key}=", value) }
@@ -40,11 +40,18 @@ module Sanford
40
40
 
41
41
  private
42
42
 
43
+ # Stringify and encode/decode to ensure params are valid and are
44
+ # in the format they would normally be when a handler is built and run.
45
+ def normalize_params(params)
46
+ p = Sanford::Protocol::StringifyParams.new(params)
47
+ Sanford::Protocol.msg_body.decode(Sanford::Protocol.msg_body.encode(p))
48
+ end
49
+
43
50
  def build_and_serialize_response(&block)
44
51
  build_response(&block).tap do |response|
45
52
  # attempt to serialize (and then throw away) the response data
46
- # this will error on the developer if BSON can't serialize their response
47
- Sanford::Protocol::BsonBody.new.encode(response.to_hash) if response
53
+ # this will error on the developer if it can't serialize their response
54
+ Sanford::Protocol.msg_body.encode(response.to_hash) if response
48
55
  end
49
56
  end
50
57
 
@@ -1,3 +1,3 @@
1
1
  module Sanford
2
- VERSION = "0.13.0"
2
+ VERSION = "0.14.0"
3
3
  end
data/sanford.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |gem|
20
20
 
21
21
  gem.add_dependency("dat-tcp", ["~> 0.6"])
22
22
  gem.add_dependency("ns-options", ["~> 1.1"])
23
- gem.add_dependency("sanford-protocol", ["~> 0.10"])
23
+ gem.add_dependency("sanford-protocol", ["~> 0.11"])
24
24
 
25
- gem.add_development_dependency("assert", ["~> 2.12"])
25
+ gem.add_development_dependency("assert", ["~> 2.14"])
26
26
  end
@@ -99,8 +99,8 @@ class Sanford::ErrorHandler
99
99
  assert_equal 'bad message', response.status.message
100
100
  end
101
101
 
102
- should "build a 400 response with a protocol BadRequestError" do
103
- exception = generate_exception(Sanford::Protocol::BadRequestError, 'bad request')
102
+ should "build a 400 response with a protocol request invalid error" do
103
+ exception = generate_exception(Sanford::Protocol::Request::InvalidError, 'bad request')
104
104
  response = Sanford::ErrorHandler.new(exception, @server_data).run
105
105
 
106
106
  assert_equal 400, response.code
@@ -87,8 +87,8 @@ class Sanford::Process
87
87
  ENV['SANFORD_PORT'] = ''
88
88
  ENV['SANFORD_SERVER_FD'] = ''
89
89
  process = @process_class.new(@server_spy)
90
- assert_equal @server_spy.configured_ip, subject.server_ip
91
- assert_equal @server_spy.configured_port, subject.server_port
90
+ assert_equal @server_spy.configured_ip, process.server_ip
91
+ assert_equal @server_spy.configured_port, process.server_port
92
92
  assert_nil process.server_fd
93
93
  end
94
94
 
@@ -105,7 +105,7 @@ class Sanford::Process
105
105
 
106
106
  should "not daemonize by default" do
107
107
  process = @process_class.new(@server_spy)
108
- assert_false subject.daemonize?
108
+ assert_false process.daemonize?
109
109
  end
110
110
 
111
111
  should "daemonize if turned on" do
@@ -212,8 +212,8 @@ class Sanford::Process
212
212
  assert_true @server_spy.thread.join_called
213
213
  end
214
214
 
215
- should "not have exec'd the restart cmd" do
216
- assert_false @restart_cmd_spy.exec_called
215
+ should "not run the restart cmd" do
216
+ assert_false @restart_cmd_spy.run_called
217
217
  end
218
218
 
219
219
  should "have removed the PID file" do
@@ -297,15 +297,12 @@ class Sanford::Process
297
297
  @process.run
298
298
  end
299
299
 
300
- should "have set env vars for execing the restart cmd" do
300
+ should "set env vars for restarting and run the restart cmd" do
301
301
  assert_equal @server_spy.file_descriptor.to_s, ENV['SANFORD_SERVER_FD']
302
302
  expected = @server_spy.client_file_descriptors.join(',')
303
303
  assert_equal expected, ENV['SANFORD_CLIENT_FDS']
304
304
  assert_equal 'yes', ENV['SANFORD_SKIP_DAEMONIZE']
305
- end
306
-
307
- should "have exec'd the restart cmd" do
308
- assert_true @restart_cmd_spy.exec_called
305
+ assert_true @restart_cmd_spy.run_called
309
306
  end
310
307
 
311
308
  end
@@ -313,32 +310,85 @@ class Sanford::Process
313
310
  class RestartCmdTests < UnitTests
314
311
  desc "RestartCmd"
315
312
  setup do
316
- @restart_cmd = Sanford::RestartCmd.new
313
+ @current_pwd = ENV['PWD']
314
+ ENV['PWD'] = Factory.path
317
315
 
318
- @chdir_called = false
319
- Assert.stub(Dir, :chdir).with(@restart_cmd.dir){ @chdir_called = true }
316
+ @ruby_pwd_stat = File.stat(Dir.pwd)
317
+ env_pwd_stat = File.stat('/dev/null')
318
+ Assert.stub(File, :stat).with(Dir.pwd){ @ruby_pwd_stat }
319
+ Assert.stub(File, :stat).with(ENV['PWD']){ env_pwd_stat }
320
320
 
321
- @exec_called = false
322
- Assert.stub(Kernel, :exec).with(*@restart_cmd.argv){ @exec_called = true }
321
+ @chdir_called_with = nil
322
+ Assert.stub(Dir, :chdir){ |*args| @chdir_called_with = args }
323
+
324
+ @exec_called_with = false
325
+ Assert.stub(Kernel, :exec){ |*args| @exec_called_with = args }
326
+
327
+ @cmd_class = Sanford::RestartCmd
328
+ end
329
+ teardown do
330
+ ENV['PWD'] = @current_pwd
323
331
  end
324
332
  subject{ @restart_cmd }
325
333
 
334
+ end
335
+
336
+ class RestartCmdInitTests < RestartCmdTests
337
+ desc "when init"
338
+ setup do
339
+ @restart_cmd = @cmd_class.new
340
+ end
341
+
326
342
  should have_readers :argv, :dir
343
+ should have_imeths :run
344
+
345
+ should "know its argv" do
346
+ assert_equal [Gem.ruby, $0, ARGV].flatten, subject.argv
347
+ end
327
348
 
328
- should "know its argv and dir" do
329
- expected = [ Gem.ruby, $0, ARGV ].flatten
330
- assert_equal expected, subject.argv
349
+ should "change the dir and run a kernel exec when run" do
350
+ subject.run
351
+ assert_equal [subject.dir], @chdir_called_with
352
+ assert_equal subject.argv, @exec_called_with
353
+ end
354
+
355
+ end
356
+
357
+ class RestartCmdWithPWDEnvNoMatchTests < RestartCmdTests
358
+ desc "when init with a PWD env variable that doesn't point to ruby working dir"
359
+ setup do
360
+ @restart_cmd = @cmd_class.new
361
+ end
362
+
363
+ should "know its dir" do
331
364
  assert_equal Dir.pwd, subject.dir
332
365
  end
333
366
 
334
- should "change the dir when exec'd" do
335
- subject.exec
336
- assert_true @chdir_called
367
+ end
368
+
369
+ class RestartCmdWithPWDEnvInitTests < RestartCmdTests
370
+ desc "when init with a PWD env variable that points to the ruby working dir"
371
+ setup do
372
+ # make ENV['PWD'] point to the same file as Dir.pwd
373
+ Assert.stub(File, :stat).with(ENV['PWD']){ @ruby_pwd_stat }
374
+ @restart_cmd = @cmd_class.new
337
375
  end
338
376
 
339
- should "kernel exec its argv when exec'd" do
340
- subject.exec
341
- assert_true @exec_called
377
+ should "know its dir" do
378
+ assert_equal ENV['PWD'], subject.dir
379
+ end
380
+
381
+ end
382
+
383
+ class RestartCmdWithNoPWDEnvInitTests < RestartCmdTests
384
+ desc "when init with a PWD env variable set"
385
+ setup do
386
+ ENV.delete('PWD')
387
+ @restart_cmd = @cmd_class.new
388
+ end
389
+
390
+ should "know its dir" do
391
+ assert_equal Dir.pwd, subject.dir
342
392
  end
343
393
 
344
394
  end
@@ -417,14 +467,14 @@ class Sanford::Process
417
467
  end
418
468
 
419
469
  class RestartCmdSpy
420
- attr_reader :exec_called
470
+ attr_reader :run_called
421
471
 
422
472
  def initialize
423
- @exec_called = false
473
+ @run_called = false
424
474
  end
425
475
 
426
- def exec
427
- @exec_called = true
476
+ def run
477
+ @run_called = true
428
478
  end
429
479
  end
430
480
 
@@ -16,6 +16,7 @@ class Sanford::Route
16
16
  subject{ @route }
17
17
 
18
18
  should have_readers :name, :handler_class_name, :handler_class
19
+ should have_imeths :validate!, :run
19
20
 
20
21
  should "know its name and handler class name" do
21
22
  assert_equal @name, subject.name
@@ -6,7 +6,7 @@ require 'test/support/factory'
6
6
  class Sanford::Router
7
7
 
8
8
  class UnitTests < Assert::Context
9
- desc "Sanford::Host"
9
+ desc "Sanford::Router"
10
10
  setup do
11
11
  @router = Sanford::Router.new
12
12
  end
@@ -22,48 +22,80 @@ class Sanford::TestRunner
22
22
  setup do
23
23
  @params = { Factory.string => Factory.integer }
24
24
  @args = {
25
- :request => 'a-request',
26
- :params => @params,
27
- :logger => 'a-logger',
28
- :router => 'a-router',
29
- :template_source => 'a-source'
25
+ :request => Factory.string,
26
+ :params => @params,
27
+ :logger => Factory.string,
28
+ :router => Factory.string,
29
+ :template_source => Factory.string,
30
+ :custom_value => Factory.integer
30
31
  }
31
- @runner = @runner_class.new(@handler_class, @args)
32
+ @original_args = @args.dup
33
+ @runner = @runner_class.new(@handler_class, @args)
34
+ @handler = @runner.handler
32
35
  end
33
36
  subject{ @runner }
34
37
 
35
38
  should have_readers :response
36
39
  should have_imeths :run
37
40
 
38
- should "raise an invalid error when not passed a service handler" do
39
- assert_raises(Sanford::InvalidServiceHandlerError) do
40
- @runner_class.new(Class.new)
41
- end
41
+ should "know its standard attributes" do
42
+ assert_equal @args[:request], subject.request
43
+ assert_equal @params, subject.params
44
+ assert_equal @args[:logger], subject.logger
45
+ assert_equal @args[:router], subject.router
46
+ assert_equal @args[:template_source], subject.template_source
47
+ end
48
+
49
+ should "write any non-standard args to its handler" do
50
+ assert_equal @args[:custom_value], @handler.custom_value
42
51
  end
43
52
 
44
- should "super its standard attributes" do
45
- assert_equal 'a-request', subject.request
46
- assert_equal @params, subject.params
47
- assert_equal 'a-logger', subject.logger
48
- assert_equal 'a-router', subject.router
49
- assert_equal 'a-source', subject.template_source
53
+ should "not alter the args passed to it" do
54
+ assert_equal @original_args, @args
50
55
  end
51
56
 
52
- should "write any non-standard args on the handler" do
53
- runner = @runner_class.new(@handler_class, :custom_value => 42)
54
- assert_equal 42, runner.handler.custom_value
57
+ should "not call its service handlers before callbacks" do
58
+ assert_nil @handler.before_called
55
59
  end
56
60
 
57
- should "not have called its service handlers before callbacks" do
58
- assert_nil subject.handler.before_called
61
+ should "call its service handlers init" do
62
+ assert_true @handler.init_called
59
63
  end
60
64
 
61
- should "have called init on its service handler" do
62
- assert_true subject.handler.init_called
65
+ should "not run its service handler" do
66
+ assert_false @handler.run_called
67
+ end
68
+
69
+ should "not call its service handlers after callbacks" do
70
+ assert_nil @handler.after_called
63
71
  end
64
72
 
65
73
  should "not have a response by default" do
66
- assert_nil subject.response
74
+ assert_nil @handler.response
75
+ end
76
+
77
+ should "normalize the params passed to it" do
78
+ params = {
79
+ Factory.string => Factory.string,
80
+ Factory.string.to_sym => Factory.string.to_sym,
81
+ Factory.integer => Factory.integer
82
+ }
83
+ runner = @runner_class.new(@handler_class, :params => params)
84
+ exp = Sanford::Protocol::StringifyParams.new(params)
85
+ assert_equal exp, runner.params
86
+ end
87
+
88
+ should "raise a serialization error if the params can't be serialized" do
89
+ params = { Factory.string => Class.new }
90
+ assert_raises(BSON::InvalidDocument) do
91
+ @runner_class.new(@handler_class, :params => params)
92
+ end
93
+ end
94
+
95
+ should "raise an invalid error when passed a non service handler" do
96
+ assert_raises(Sanford::InvalidServiceHandlerError) do
97
+ @runner_class.new(Class.new)
98
+ end
67
99
  end
68
100
 
69
101
  end
@@ -80,11 +112,11 @@ class Sanford::TestRunner
80
112
  assert_instance_of Sanford::Protocol::Response, subject
81
113
  end
82
114
 
83
- should "have called run on its service handler" do
115
+ should "run its service handler" do
84
116
  assert_true @runner.handler.run_called
85
117
  end
86
118
 
87
- should "not have called its service handlers after callbacks" do
119
+ should "not call its service handler's after callbacks" do
88
120
  assert_nil @runner.handler.after_called
89
121
  end
90
122
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sanford
3
3
  version: !ruby/object:Gem::Version
4
- hash: 43
4
+ hash: 39
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 13
8
+ - 14
9
9
  - 0
10
- version: 0.13.0
10
+ version: 0.14.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Collin Redding
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2015-02-04 00:00:00 Z
19
+ date: 2015-06-22 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  requirement: &id001 !ruby/object:Gem::Requirement
@@ -54,11 +54,11 @@ dependencies:
54
54
  requirements:
55
55
  - - ~>
56
56
  - !ruby/object:Gem::Version
57
- hash: 31
57
+ hash: 29
58
58
  segments:
59
59
  - 0
60
- - 10
61
- version: "0.10"
60
+ - 11
61
+ version: "0.11"
62
62
  type: :runtime
63
63
  name: sanford-protocol
64
64
  version_requirements: *id003
@@ -69,11 +69,11 @@ dependencies:
69
69
  requirements:
70
70
  - - ~>
71
71
  - !ruby/object:Gem::Version
72
- hash: 27
72
+ hash: 31
73
73
  segments:
74
74
  - 2
75
- - 12
76
- version: "2.12"
75
+ - 14
76
+ version: "2.14"
77
77
  type: :development
78
78
  name: assert
79
79
  version_requirements: *id004