sanford 0.4.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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