sanford 0.4.0 → 0.6.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.
@@ -6,7 +6,7 @@ module Sanford::Config
6
6
  desc "Sanford::Config"
7
7
  subject{ Sanford::Config }
8
8
 
9
- should have_instance_methods :services_file
9
+ should have_instance_methods :services_file, :logger
10
10
  end
11
11
 
12
12
  end
@@ -9,8 +9,8 @@ class Sanford::Host::Configuration
9
9
  end
10
10
  subject{ @configuration }
11
11
 
12
- should have_instance_methods :name, :ip, :port, :pid_dir, :logger, :verbose_logging, :logger,
13
- :error_proc
12
+ should have_instance_methods :name, :ip, :port, :pid_file, :logger,
13
+ :verbose_logging, :logger, :error_proc
14
14
 
15
15
  should "default name to the class name of the host" do
16
16
  assert_equal 'EmptyHost', subject.name
@@ -24,10 +24,6 @@ class Sanford::Host::Configuration
24
24
  assert_nil subject.port
25
25
  end
26
26
 
27
- should "default pid_dir to the current working directory" do
28
- assert_equal Pathname.new(Dir.pwd), subject.pid_dir
29
- end
30
-
31
27
  should "default logger to a null logger" do
32
28
  assert_instance_of Sanford::NullLogger, subject.logger
33
29
  end
@@ -1,52 +1,35 @@
1
1
  require 'assert'
2
2
 
3
- require 'sanford/manager'
4
-
5
3
  class Sanford::HostData
6
4
 
7
5
  class BaseTest < Assert::Context
8
6
  desc "Sanford::HostData"
9
7
  setup do
8
+ TestHost.init_has_been_called = false
10
9
  @host_data = Sanford::HostData.new(TestHost)
11
10
  end
11
+ teardown do
12
+ TestHost.init_has_been_called = false
13
+ end
12
14
  subject{ @host_data }
13
15
 
14
- should have_instance_methods :name, :ip, :port, :pid_dir, :logger, :verbose,
15
- :error_proc, :handler_class_for, :setup
16
+ should have_instance_methods :name, :logger, :verbose, :error_proc,
17
+ :handler_class_for
16
18
 
17
19
  should "default it's configuration from the service host, but allow overrides" do
18
- host_data = Sanford::HostData.new(TestHost, :ip => '1.2.3.4', :port => 12345)
20
+ host_data = Sanford::HostData.new(TestHost, :verbose_logging => false)
19
21
 
20
- assert_equal 'TestHost', host_data.name
21
- assert_equal '1.2.3.4', host_data.ip
22
- assert_equal 12345, host_data.port
22
+ assert_equal TestHost.receives_keep_alive, host_data.keep_alive
23
+ assert_equal false, host_data.verbose
23
24
  end
24
25
 
25
26
  should "ignore nil values passed as overrides" do
26
- host_data = Sanford::HostData.new(TestHost, :ip => nil)
27
-
28
- assert_not_nil host_data.ip
29
- end
30
-
31
- should "raise a custom exception when passed invalid host" do
32
- assert_raises(Sanford::InvalidHostError) do
33
- Sanford::Manager.new(InvalidHost)
34
- end
35
- end
36
-
37
- end
38
-
39
- class SetupTest < BaseTest
40
- desc "after calling setup"
41
- setup do
42
- TestHost.setup_has_been_called = false
43
- @host_data.setup
27
+ host_data = Sanford::HostData.new(TestHost, :verbose_logging => nil)
28
+ assert_not_nil host_data.verbose
44
29
  end
45
30
 
46
31
  should "have called the setup proc" do
47
- assert_equal true, TestHost.setup_has_been_called
48
-
49
- TestHost.setup_has_been_called = false
32
+ assert_equal true, TestHost.init_has_been_called
50
33
  end
51
34
 
52
35
  should "constantize a host's handlers" do
@@ -58,7 +41,7 @@ class Sanford::HostData
58
41
  assert_equal TestHost::Multiply, handlers['v1']['multiply']
59
42
  end
60
43
 
61
- should "look up handler classes with #handler_class_for" do
44
+ should "look up handler classes with #handler_class_for" do
62
45
  assert_equal TestHost::Echo, subject.handler_class_for('v1', 'echo')
63
46
  end
64
47
 
@@ -12,8 +12,8 @@ module Sanford::Host
12
12
  end
13
13
  subject{ MyHost.instance }
14
14
 
15
- should have_instance_methods :configuration, :name, :ip, :port, :pid_dir, :logger,
16
- :verbose_logging, :error, :setup, :version, :versioned_services
15
+ should have_instance_methods :configuration, :name, :ip, :port, :pid_file,
16
+ :logger, :verbose_logging, :error, :init, :version, :versioned_services
17
17
 
18
18
  should "get and set it's configuration options with their matching methods" do
19
19
  subject.name 'my_awesome_host'
@@ -36,7 +36,7 @@ module Sanford::Host
36
36
 
37
37
  should "proxy it's method to it's instance" do
38
38
  assert_equal subject.instance.name, subject.name
39
- assert subject.respond_to?(:pid_dir)
39
+ assert subject.respond_to?(:pid_file)
40
40
  end
41
41
 
42
42
  should "have registered the class with sanford's known hosts" do
@@ -0,0 +1,45 @@
1
+ require 'assert'
2
+
3
+ require 'sanford/cli'
4
+
5
+ class Sanford::Manager::PIDFile
6
+
7
+ class BaseTest < Assert::Context
8
+ desc "Sanford::Manager::PIDFile"
9
+ setup do
10
+ @pid_file = Sanford::Manager::PIDFile.new("tmp/my.pid")
11
+ end
12
+ teardown do
13
+ FileUtils.rm_rf("tmp/my.pid")
14
+ end
15
+ subject{ @pid_file }
16
+
17
+ should have_instance_methods :pid, :to_s, :write, :remove
18
+
19
+ should "return it's path with #to_s" do
20
+ assert_equal "tmp/my.pid", subject.to_s
21
+ end
22
+
23
+ should "write the pid file with #write" do
24
+ subject.write
25
+
26
+ assert File.exists?("tmp/my.pid")
27
+ assert_equal "#{Process.pid}\n", File.read("tmp/my.pid")
28
+ end
29
+
30
+ should "return the value stored in the pid value with #pid" do
31
+ subject.write
32
+
33
+ assert_equal Process.pid, subject.pid
34
+ end
35
+
36
+ should "remove the file with #remove" do
37
+ subject.write
38
+ subject.remove
39
+
40
+ assert_not File.exists?("tmp/my.pid")
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -1,21 +1,146 @@
1
1
  require 'assert'
2
2
 
3
- require 'sanford/manager'
3
+ require 'sanford/cli'
4
4
 
5
- class Sanford::Manager
5
+ module Sanford::Manager
6
6
 
7
7
  class BaseTest < Assert::Context
8
8
  desc "Sanford::Manager"
9
+ subject{ Sanford::Manager }
10
+
11
+ should have_instance_methods :call, :get_handler_class
12
+
13
+ should "return ServerHandler or SignalHandler with get_handler_class" do
14
+ assert_equal Sanford::Manager::ServerHandler, subject.get_handler_class('run')
15
+ assert_equal Sanford::Manager::ServerHandler, subject.get_handler_class('start')
16
+ assert_equal Sanford::Manager::SignalHandler, subject.get_handler_class('stop')
17
+ assert_equal Sanford::Manager::SignalHandler, subject.get_handler_class('restart')
18
+ end
19
+
20
+ end
21
+
22
+ class ServerHandlerTest < BaseTest
23
+ desc "ServerHandler"
24
+ setup do
25
+ @handler = Sanford::Manager::ServerHandler.new({ :host => 'TestHost' })
26
+ end
27
+ subject{ @handler }
28
+
29
+ should have_instance_methods :run, :start
30
+
31
+ should "raise an error when a host can't be found matching the `host` option" do
32
+ assert_raises(Sanford::NoHostError) do
33
+ Sanford::Manager::ServerHandler.new({ :host => 'poop' })
34
+ end
35
+ end
36
+
37
+ should "raise an error when a host is invalid for running a server" do
38
+ assert_raises(Sanford::InvalidHostError) do
39
+ Sanford::Manager::ServerHandler.new({ :host => 'InvalidHost' })
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ class SignalHandlertest < BaseTest
46
+ desc "SignalHandler"
47
+ setup do
48
+ @handler = Sanford::Manager::SignalHandler.new({ :pid => -1 })
49
+ end
50
+ subject{ @handler }
51
+
52
+ should have_instance_methods :stop, :restart
53
+
54
+ should "raise an error when a pid can't be found" do
55
+ assert_raises(Sanford::NoPIDError) do
56
+ Sanford::Manager::SignalHandler.new
57
+ end
58
+ end
59
+ end
60
+
61
+ class ConfigTest < BaseTest
62
+ desc "Config"
9
63
  setup do
10
- @manager = Sanford::Manager.new(TestHost)
64
+ @config = Sanford::Manager::Config.new({ :host => 'TestHost' })
65
+ end
66
+ subject{ @config }
67
+
68
+ should have_instance_methods :host_name, :host, :ip, :port, :pid, :pid_file
69
+ should have_instance_methods :file_descriptor, :client_file_descriptors
70
+ should have_instance_methods :restart_dir
71
+ should have_instance_methods :listen_args, :has_listen_args?, :found_host?
72
+
73
+ should "find a host based on the `host` option" do
74
+ assert_equal TestHost, subject.host
75
+ assert_equal true, subject.found_host?
76
+ end
77
+
78
+ should "set the ip, port and pid file based on the host's configuration" do
79
+ assert_equal TestHost.ip, subject.ip
80
+ assert_equal TestHost.port, subject.port
81
+ assert_equal TestHost.pid_file.to_s, subject.pid_file.to_s
82
+ end
83
+
84
+ should "use the first host if no host option is provided" do
85
+ manager = Sanford::Manager::Config.new({ :port => 1 })
86
+ assert_equal Sanford.hosts.first, manager.host
87
+ end
88
+
89
+ should "return the file descriptor or ip and port with listen_args" do
90
+ config = Sanford::Manager::Config.new({
91
+ :file_descriptor => 1,
92
+ :ip => 'localhost', :port => 1234
93
+ })
94
+ assert_equal [ config.file_descriptor ], config.listen_args
95
+ assert_equal true, subject.has_listen_args?
96
+
97
+ config = Sanford::Manager::Config.new({ :ip => 'localhost', :port => 1234 })
98
+ assert_equal [ config.ip, config.port ], config.listen_args
99
+ assert_equal true, subject.has_listen_args?
100
+
101
+ config = Sanford::Manager::Config.new({ :host => 'InvalidHost' })
102
+ assert_equal false, config.has_listen_args?
103
+ end
104
+
105
+ should "build a NullHost when a host can't be found" do
106
+ config = Sanford::Manager::Config.new({ :host => 'poop' })
107
+ assert_instance_of Sanford::Manager::NullHost, config.host
108
+ assert_equal false, config.found_host?
109
+ end
110
+
111
+ should "split a string list of client file descriptors into an array" do
112
+ config = Sanford::Manager::Config.new({ :client_fds => '1,2,3' })
113
+ assert_equal [ 1, 2, 3 ], config.client_file_descriptors
114
+ end
115
+
116
+ end
117
+
118
+ class EnvVarsTest < ConfigTest
119
+ desc "with env vars set"
120
+ setup do
121
+ ENV['SANFORD_HOST'] = 'TestHost'
122
+ ENV['SANFORD_IP'] = '127.0.0.1'
123
+ ENV['SANFORD_PORT'] = '12345'
124
+ @config = Sanford::Manager::Config.new({
125
+ :host => 'InvalidHost',
126
+ :port => 54678
127
+ })
128
+ end
129
+ teardown do
130
+ ENV.delete('SANFORD_HOST')
131
+ ENV.delete('SANFORD_IP')
132
+ ENV.delete('SANFORD_PORT')
133
+ end
134
+
135
+ should "use the env vars over passed in options or the host's configuration" do
136
+ assert_equal TestHost, subject.host
137
+ assert_equal '127.0.0.1', subject.ip
138
+ assert_equal 12345, subject.port
11
139
  end
12
- subject{ @manager }
13
140
 
14
- should have_instance_methods :host_data, :process_name, :call
15
- should have_class_methods :call
16
141
  end
17
142
 
18
- # Sanford::Manager#call methods are tested in the test/system/managing_test.rb
19
- # they require mocking the Daemons gem
143
+ # ServerHandler run/start and SignalHandler stop/restart are tested with
144
+ # system tests: test/system/managing_test.rb
20
145
 
21
146
  end
@@ -11,6 +11,7 @@ class Sanford::Runner
11
11
  subject{ @runner }
12
12
 
13
13
  should have_instance_methods :handler_class, :request, :logger, :run
14
+ should have_class_methods :run
14
15
 
15
16
  should "run the handler and return the response it generates when `run` is called" do
16
17
  response = subject.run
@@ -21,6 +22,15 @@ class Sanford::Runner
21
22
  assert_equal 'joe.test@example.com', response.data['email']
22
23
  end
23
24
 
25
+ should "be able to build a runner with a handler class and params" do
26
+ response = nil
27
+ assert_nothing_raised do
28
+ response = Sanford::Runner.run(BasicServiceHandler, {})
29
+ end
30
+
31
+ assert_equal 200, response.code
32
+ end
33
+
24
34
  end
25
35
 
26
36
  end
@@ -1,24 +1,43 @@
1
1
  require 'assert'
2
2
 
3
3
  require 'sanford/server'
4
- require 'sanford/manager'
5
4
 
6
5
  class Sanford::Server
7
6
 
8
7
  class BaseTest < Assert::Context
9
8
  desc "Sanford::Server"
10
9
  setup do
11
- @server = Sanford::Server.new(TestHost)
10
+ @server = Sanford::Server.new(TestHost, { :keep_alive => true })
12
11
  end
13
12
  subject{ @server }
14
13
 
14
+ should have_instance_methods :sanford_host, :sanford_host_data, :sanford_host_options
15
+ should have_instance_methods :on_run
16
+
15
17
  should "include DatTCP::Server" do
16
18
  assert_includes DatTCP::Server, subject.class.included_modules
17
19
  end
18
20
 
19
- should "use the service host's ip and port" do
20
- assert_equal TestHost.ip, subject.host
21
- assert_equal TestHost.port, subject.port
21
+ should "save it's host and host options but not initialize a host data yet" do
22
+ assert_equal TestHost, subject.sanford_host
23
+ assert_equal true, subject.sanford_host_options[:receives_keep_alive]
24
+ assert_nil subject.sanford_host_data
25
+ end
26
+
27
+ end
28
+
29
+ class RunTest < BaseTest
30
+ desc "run"
31
+ setup do
32
+ @server.listen(TestHost.ip, TestHost.port)
33
+ @server.run
34
+ end
35
+ teardown do
36
+ @server.stop
37
+ end
38
+
39
+ should "have initialized a host data instance" do
40
+ assert_instance_of Sanford::HostData, subject.sanford_host_data
22
41
  end
23
42
 
24
43
  end
@@ -14,11 +14,30 @@ module Sanford::ServiceHandler
14
14
  subject{ @handler }
15
15
 
16
16
  should have_instance_methods :init, :init!, :run, :run!
17
+ should have_class_methods :run
17
18
 
18
19
  should "raise a NotImplementedError if run! is not overwritten" do
19
20
  assert_raises(NotImplementedError){ subject.run! }
20
21
  end
21
22
 
23
+ should "allow running a handler class with the class method #run" do
24
+ response = HaltServiceHandler.run({
25
+ 'code' => 648,
26
+ 'data' => true
27
+ })
28
+ assert_equal 648, response.code
29
+ assert_equal true, response.data
30
+ end
31
+
32
+ end
33
+
34
+ class RunHandlerTest < BaseTest
35
+ desc "run_handler helper"
36
+
37
+ should "allow easily running another handler" do
38
+ response = test_runner(RunOtherHandler).run
39
+ assert_equal 'RunOtherHandler', response.data
40
+ end
22
41
  end
23
42
 
24
43
  class WithMethodFlagsTest < BaseTest
@@ -4,27 +4,12 @@ require 'sanford-protocol/test/helpers'
4
4
 
5
5
  class Sanford::Worker
6
6
 
7
- # turn off the protocol's debugging (in case it's on) and turn on Sanford's
8
- # debugging
9
- class SetupContextToRaiseExceptions < Assert::Context
10
- setup do
11
- @env_sanford_protocol_debug = ENV['SANFORD_PROTOCOL_DEBUG']
12
- @env_sanford_debug = ENV['SANFORD_DEBUG']
13
- ENV.delete('SANFORD_PROTOCOL_DEBUG')
14
- ENV['SANFORD_DEBUG'] = '1'
15
- end
16
- teardown do
17
- ENV['SANFORD_DEBUG'] = @env_sanford_debug
18
- ENV['SANFORD_PROTOCOL_DEBUG'] = @env_sanford_protocol_debug
19
- end
20
- end
21
-
22
- class BaseTest < SetupContextToRaiseExceptions
7
+ class BaseTest < Assert::Context
23
8
  include Sanford::Protocol::Test::Helpers
24
9
 
25
10
  desc "Sanford::Worker"
26
11
  setup do
27
- @host_data = Sanford::HostData.new(TestHost).tap{|hd| hd.setup }
12
+ @host_data = Sanford::HostData.new(TestHost)
28
13
  @connection = FakeConnection.with_request('version', 'service', {})
29
14
  @worker = Sanford::Worker.new(@host_data, @connection)
30
15
  end
@@ -34,180 +19,6 @@ class Sanford::Worker
34
19
 
35
20
  end
36
21
 
37
- class EchoTest < BaseTest
38
- desc "running a request for the echo server"
39
- setup do
40
- @connection = FakeConnection.with_request('v1', 'echo', { :message => 'test' })
41
- @worker = Sanford::Worker.new(@host_data, @connection)
42
- end
43
-
44
- should "return a successful response and echo the params sent to it" do
45
- assert_nothing_raised{ @worker.run }
46
- response = @connection.response
47
-
48
- assert_equal 200, response.status.code
49
- assert_equal nil, response.status.message
50
- assert_equal 'test', response.data
51
- end
52
-
53
- end
54
-
55
- class MissingServiceVersionTest < BaseTest
56
- desc "running a request with no service version"
57
- setup do
58
- request_hash = Sanford::Protocol::Request.new('v1', 'what', {}).to_hash
59
- request_hash.delete('version')
60
- @connection = FakeConnection.new(request_hash)
61
- @worker = Sanford::Worker.new(@host_data, @connection)
62
- end
63
-
64
- should "return a bad request response" do
65
- assert_raises(Sanford::Protocol::BadRequestError) do
66
- @worker.run
67
- end
68
- response = @connection.response
69
-
70
- assert_equal 400, response.status.code
71
- assert_match "request", response.status.message
72
- assert_match "version", response.status.message
73
- assert_equal nil, response.data
74
- end
75
-
76
- end
77
-
78
- class MissingServiceNameTest < BaseTest
79
- desc "running a request with no service name"
80
- setup do
81
- request_hash = Sanford::Protocol::Request.new('v1', 'what', {}).to_hash
82
- request_hash.delete('name')
83
- @connection = FakeConnection.new(request_hash)
84
- @worker = Sanford::Worker.new(@host_data, @connection)
85
- end
86
-
87
- should "return a bad request response" do
88
- assert_raises(Sanford::Protocol::BadRequestError) do
89
- @worker.run
90
- end
91
- response = @connection.response
92
-
93
- assert_equal 400, response.status.code
94
- assert_match "request", response.status.message
95
- assert_match "name", response.status.message
96
- assert_equal nil, response.data
97
- end
98
-
99
- end
100
-
101
- class NotFoundServiceTest < BaseTest
102
- desc "running a request with no matching service name"
103
- setup do
104
- @connection = FakeConnection.with_request('v1', 'what', {})
105
- @worker = Sanford::Worker.new(@host_data, @connection)
106
- end
107
-
108
- should "return a bad request response" do
109
- assert_raises(Sanford::NotFoundError) do
110
- @worker.run
111
- end
112
- response = @connection.response
113
-
114
- assert_equal 404, response.status.code
115
- assert_equal nil, response.status.message
116
- assert_equal nil, response.data
117
- end
118
-
119
- end
120
-
121
- class ErrorServiceTest < BaseTest
122
- desc "running a request that errors on the server"
123
- setup do
124
- @connection = FakeConnection.with_request('v1', 'bad', {})
125
- @worker = Sanford::Worker.new(@host_data, @connection)
126
- end
127
-
128
- should "return a bad request response" do
129
- assert_raises(RuntimeError) do
130
- @worker.run
131
- end
132
- response = @connection.response
133
-
134
- assert_equal 500, response.status.code
135
- assert_match "error", response.status.message
136
- assert_equal nil, response.data
137
- end
138
-
139
- end
140
-
141
- class HaltTest < BaseTest
142
- desc "running a request that halts"
143
- setup do
144
- @connection = FakeConnection.with_request('v1', 'halt_it', {})
145
- @worker = Sanford::Worker.new(@host_data, @connection)
146
- end
147
-
148
- should "return the response that was halted" do
149
- assert_nothing_raised{ @worker.run }
150
- response = @connection.response
151
-
152
- assert_equal 728, response.status.code
153
- assert_equal "I do what I want", response.status.message
154
- assert_equal [ 1, true, 'yes' ], response.data
155
- end
156
-
157
- end
158
-
159
- class AuthorizeRequestTest < BaseTest
160
- desc "running a request that halts in a callback"
161
- setup do
162
- @connection = FakeConnection.with_request('v1', 'authorized', {})
163
- @worker = Sanford::Worker.new(@host_data, @connection)
164
- end
165
-
166
- should "return the response that was halted" do
167
- assert_nothing_raised{ @worker.run }
168
- response = @connection.response
169
-
170
- assert_equal 401, response.status.code
171
- assert_equal "Not authorized", response.status.message
172
- assert_equal nil, response.data
173
- end
174
-
175
- end
176
-
177
- class WithCustomErrorHandlerTest < BaseTest
178
- desc "running a request that triggers our custom error handler"
179
- setup do
180
- @connection = FakeConnection.with_request('v1', 'custom_error', {})
181
- @worker = Sanford::Worker.new(@host_data, @connection)
182
- end
183
-
184
- should "return the response that was halted" do
185
- assert_raises(::MyCustomError){ @worker.run }
186
- response = @connection.response
187
-
188
- assert_equal 987, response.status.code
189
- assert_equal "custom error!", response.status.message
190
- assert_equal nil, response.data
191
- end
192
-
193
- end
194
-
195
- class WithBadResponseHashTest < BaseTest
196
- desc "running a request that builds an object that can't be encoded"
197
- setup do
198
- @connection = FakeConnection.with_request('v1', 'echo', { :message => 'cant encode' }, true)
199
- @worker = Sanford::Worker.new(@host_data, @connection)
200
- end
201
-
202
- should "return the response that was halted" do
203
- assert_raises(RuntimeError){ @worker.run }
204
- response = @connection.response
205
-
206
- assert_equal 500, response.status.code
207
- assert_equal "An unexpected error occurred.", response.status.message
208
- assert_equal nil, response.data
209
- end
210
-
211
- end
22
+ # `Worker`'s logic is tested in the system test: `request_handling_test.rb`
212
23
 
213
24
  end