sanford 0.1.0 → 0.2.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/bench/report.txt +34 -4
- data/bench/runner.rb +122 -1
- data/bench/services.rb +5 -2
- data/lib/sanford/error_handler.rb +60 -0
- data/lib/sanford/exceptions.rb +11 -10
- data/lib/sanford/host.rb +79 -101
- data/lib/sanford/host_data.rb +55 -0
- data/lib/sanford/logger.rb +23 -0
- data/lib/sanford/manager.rb +13 -22
- data/lib/sanford/rake.rb +1 -0
- data/lib/sanford/runner.rb +50 -0
- data/lib/sanford/server.rb +31 -15
- data/lib/sanford/service_handler.rb +34 -43
- data/lib/sanford/test_runner.rb +47 -0
- data/lib/sanford/version.rb +1 -1
- data/lib/sanford/worker.rb +124 -0
- data/lib/sanford.rb +49 -6
- data/sanford.gemspec +1 -1
- data/test/helper.rb +1 -0
- data/test/support/fake_connection.rb +18 -0
- data/test/support/helpers.rb +6 -10
- data/test/support/service_handlers.rb +56 -68
- data/test/support/services.rb +55 -10
- data/test/system/managing_test.rb +18 -18
- data/test/system/request_handling_test.rb +10 -100
- data/test/unit/config_test.rb +1 -43
- data/test/unit/error_handler_test.rb +133 -0
- data/test/unit/host_configuration_test.rb +41 -0
- data/test/unit/host_data_test.rb +65 -0
- data/test/unit/host_test.rb +20 -112
- data/test/unit/{host/version_group_test.rb → host_version_group_test.rb} +0 -0
- data/test/unit/hosts_test.rb +56 -0
- data/test/unit/manager_test.rb +3 -3
- data/test/unit/runner_test.rb +26 -0
- data/test/unit/server_test.rb +10 -2
- data/test/unit/service_handler_test.rb +126 -115
- data/test/unit/worker_test.rb +195 -0
- metadata +28 -16
- data/lib/sanford/config.rb +0 -33
- data/lib/sanford/connection.rb +0 -70
- data/lib/sanford/exception_handler.rb +0 -43
- data/test/unit/connection_test.rb +0 -23
- data/test/unit/exception_handler_test.rb +0 -69
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'sanford-protocol'
|
3
|
+
|
4
|
+
require 'sanford/logger'
|
5
|
+
|
6
|
+
module Sanford
|
7
|
+
|
8
|
+
class Runner
|
9
|
+
|
10
|
+
ResponseArgs = Struct.new(:status, :data)
|
11
|
+
|
12
|
+
attr_reader :handler_class, :request, :logger
|
13
|
+
|
14
|
+
def initialize(handler_class, request, logger = nil)
|
15
|
+
@handler_class, @request = handler_class, request
|
16
|
+
@logger = logger || Sanford::NullLogger.new
|
17
|
+
@handler = @handler_class.new(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
def run
|
21
|
+
response_args = catch_halt do
|
22
|
+
@handler.init
|
23
|
+
@handler.run
|
24
|
+
end
|
25
|
+
Sanford::Protocol::Response.new(response_args.status, response_args.data)
|
26
|
+
end
|
27
|
+
|
28
|
+
module HaltMethods
|
29
|
+
|
30
|
+
# It's best to keep what `halt` and `catch_halt` return in the same format.
|
31
|
+
# Currently this is a `ResponseArgs` object. This is so no matter how the
|
32
|
+
# block returns (either by throwing or running normally), you get the same
|
33
|
+
# thing kind of object.
|
34
|
+
|
35
|
+
def halt(status, options = nil)
|
36
|
+
options = OpenStruct.new(options || {})
|
37
|
+
response_status = [ status, options.message ]
|
38
|
+
throw :halt, ResponseArgs.new(response_status, options.data)
|
39
|
+
end
|
40
|
+
|
41
|
+
def catch_halt(&block)
|
42
|
+
catch(:halt){ ResponseArgs.new(*block.call) }
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
include HaltMethods
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/lib/sanford/server.rb
CHANGED
@@ -1,37 +1,53 @@
|
|
1
|
-
# Sanford's server uses DatTCP for a TCP Server. When a client connects, the
|
2
|
-
# `serve` method is called. Sanford creates a new instance of a connection
|
3
|
-
# handler and hands it the service host and client socket. This is because the
|
4
|
-
# `serve` method can be accessed by multiple threads, so we essentially create a
|
5
|
-
# new connection handler per thread.
|
6
|
-
#
|
7
1
|
require 'dat-tcp'
|
2
|
+
require 'sanford-protocol'
|
8
3
|
|
9
|
-
require 'sanford/
|
4
|
+
require 'sanford/host_data'
|
5
|
+
require 'sanford/worker'
|
10
6
|
|
11
7
|
module Sanford
|
12
8
|
|
13
9
|
class Server
|
14
10
|
include DatTCP::Server
|
15
11
|
|
16
|
-
attr_reader :
|
12
|
+
attr_reader :host_data
|
17
13
|
|
18
|
-
def initialize(
|
19
|
-
@
|
20
|
-
super(
|
14
|
+
def initialize(host, options = {})
|
15
|
+
@host_data = host.kind_of?(Sanford::HostData) ? host : Sanford::HostData.new(host)
|
16
|
+
super(@host_data.ip, @host_data.port, options)
|
21
17
|
end
|
22
18
|
|
23
19
|
def name
|
24
|
-
|
20
|
+
@host_data.name
|
25
21
|
end
|
26
22
|
|
23
|
+
# `serve` can be called at the same time by multiple threads. Thus we create
|
24
|
+
# a new instance of the handler for every request.
|
27
25
|
def serve(socket)
|
28
|
-
|
29
|
-
connection.process
|
26
|
+
Sanford::Worker.new(@host_data, Connection.new(socket)).run
|
30
27
|
end
|
31
28
|
|
32
29
|
def inspect
|
33
30
|
reference = '0x0%x' % (self.object_id << 1)
|
34
|
-
"#<#{self.class}:#{reference} @service_host=#{
|
31
|
+
"#<#{self.class}:#{reference} @service_host=#{@host_data.inspect}>"
|
32
|
+
end
|
33
|
+
|
34
|
+
class Connection
|
35
|
+
|
36
|
+
DEFAULT_TIMEOUT = 1
|
37
|
+
|
38
|
+
def initialize(socket)
|
39
|
+
@connection = Sanford::Protocol::Connection.new(socket)
|
40
|
+
@timeout = (ENV['SANFORD_TIMEOUT'] || DEFAULT_TIMEOUT).to_f
|
41
|
+
end
|
42
|
+
|
43
|
+
def read_data
|
44
|
+
@connection.read(@timeout)
|
45
|
+
end
|
46
|
+
|
47
|
+
def write_data(data)
|
48
|
+
@connection.write data
|
49
|
+
end
|
50
|
+
|
35
51
|
end
|
36
52
|
|
37
53
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'ostruct'
|
2
1
|
require 'sanford-protocol'
|
3
2
|
|
4
3
|
module Sanford
|
@@ -15,77 +14,69 @@ module Sanford
|
|
15
14
|
false
|
16
15
|
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
def initialize(logger, request)
|
21
|
-
@logger = logger
|
22
|
-
@request = request
|
17
|
+
def initialize(runner)
|
18
|
+
@sanford_runner = runner
|
23
19
|
end
|
24
20
|
|
25
21
|
def init
|
22
|
+
self.run_callback 'before_init'
|
26
23
|
self.init!
|
24
|
+
self.run_callback 'after_init'
|
27
25
|
end
|
28
26
|
|
29
27
|
def init!
|
30
28
|
end
|
31
29
|
|
32
|
-
# This method has very specific handling when before/after callbacks halt.
|
33
|
-
# It should always return a response tuple: `[ status, data ]`
|
34
|
-
# * If `before_run` halts, then the handler is not 'run' (it's `init` and
|
35
|
-
# `run` methods are not called) and it's response tuple is returned.
|
36
|
-
# * If `after_run` halts, then it's response tuple is returned, even if
|
37
|
-
# calling `before_run` or 'running' the handler generated a response
|
38
|
-
# tuple.
|
39
|
-
# * If `before_run` and `after_run` do not halt, then the response tuple
|
40
|
-
# from 'running' is used.
|
41
30
|
def run
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
[ 200, data ]
|
47
|
-
end
|
48
|
-
after_response_tuple = self.run_callback 'after_run'
|
49
|
-
(response_tuple = after_response_tuple) if after_response_tuple
|
50
|
-
response_tuple
|
31
|
+
self.run_callback 'before_run'
|
32
|
+
data = self.run!
|
33
|
+
self.run_callback 'after_run'
|
34
|
+
[ 200, data ]
|
51
35
|
end
|
52
36
|
|
53
37
|
def run!
|
54
38
|
raise NotImplementedError
|
55
39
|
end
|
56
40
|
|
41
|
+
def inspect
|
42
|
+
reference = '0x0%x' % (self.object_id << 1)
|
43
|
+
"#<#{self.class}:#{reference} @request=#{self.request.inspect}>"
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def before_init
|
49
|
+
end
|
50
|
+
|
51
|
+
def after_init
|
52
|
+
end
|
53
|
+
|
57
54
|
def before_run
|
58
55
|
end
|
59
56
|
|
60
57
|
def after_run
|
61
58
|
end
|
62
59
|
|
63
|
-
|
64
|
-
|
60
|
+
# Helpers
|
61
|
+
|
62
|
+
def halt(*args)
|
63
|
+
@sanford_runner.halt(*args)
|
65
64
|
end
|
66
65
|
|
67
|
-
def
|
68
|
-
|
69
|
-
"#<#{self.class}:#{reference} @request=#{self.request.inspect}>"
|
66
|
+
def request
|
67
|
+
@sanford_runner.request
|
70
68
|
end
|
71
69
|
|
72
|
-
|
70
|
+
def params
|
71
|
+
self.request.params
|
72
|
+
end
|
73
73
|
|
74
|
-
def
|
75
|
-
|
76
|
-
response_status = [ status, options.message ]
|
77
|
-
throw(:halt, [ response_status, options.data ])
|
74
|
+
def logger
|
75
|
+
@sanford_runner.logger
|
78
76
|
end
|
79
77
|
|
80
|
-
|
81
|
-
|
82
|
-
# also need to be sure to return nil if nothing is thrown, so that it
|
83
|
-
# is not considered as a response.
|
84
|
-
def run_callback(name)
|
85
|
-
catch(:halt) do
|
86
|
-
self.send(name.to_s)
|
87
|
-
nil
|
88
|
-
end
|
78
|
+
def run_callback(callback)
|
79
|
+
self.send(callback.to_s)
|
89
80
|
end
|
90
81
|
|
91
82
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'sanford-protocol'
|
2
|
+
|
3
|
+
require 'sanford/logger'
|
4
|
+
require 'sanford/runner'
|
5
|
+
|
6
|
+
module Sanford
|
7
|
+
|
8
|
+
class TestRunner
|
9
|
+
include Sanford::Runner::HaltMethods
|
10
|
+
|
11
|
+
attr_reader :handler, :response, :request, :logger
|
12
|
+
|
13
|
+
def initialize(handler_class, params = {}, logger = nil)
|
14
|
+
@handler_class = handler_class
|
15
|
+
@request = params.kind_of?(Sanford::Protocol::Request) ? params : test_request(params)
|
16
|
+
@logger = logger || Sanford::NullLogger.new
|
17
|
+
|
18
|
+
@handler = @handler_class.new(self)
|
19
|
+
@response = build_response catch(:halt){ @handler.init; nil }
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
@response ||= build_response catch_halt{ @handler.run }
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def test_request(params)
|
29
|
+
Sanford::Protocol::Request.new('test_version', 'test_service', params)
|
30
|
+
end
|
31
|
+
|
32
|
+
def build_response(response_args)
|
33
|
+
Sanford::Protocol::Response.new(response_args.status, response_args.data) if response_args
|
34
|
+
end
|
35
|
+
|
36
|
+
module Helpers
|
37
|
+
module_function
|
38
|
+
|
39
|
+
def test_runner(*args)
|
40
|
+
TestRunner.new(*args)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/lib/sanford/version.rb
CHANGED
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'sanford-protocol'
|
3
|
+
|
4
|
+
require 'sanford/error_handler'
|
5
|
+
require 'sanford/logger'
|
6
|
+
require 'sanford/runner'
|
7
|
+
|
8
|
+
module Sanford
|
9
|
+
|
10
|
+
class Worker
|
11
|
+
|
12
|
+
ProcessedService = Struct.new(:request, :handler_class, :response, :exception, :time_taken)
|
13
|
+
|
14
|
+
attr_reader :logger
|
15
|
+
|
16
|
+
def initialize(host_data, connection)
|
17
|
+
@host_data, @connection = host_data, connection
|
18
|
+
|
19
|
+
@logger = Sanford::Logger.new(@host_data.logger, @host_data.verbose)
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
processed_service = nil
|
24
|
+
self.log_received
|
25
|
+
benchmark = Benchmark.measure do
|
26
|
+
processed_service = self.run!
|
27
|
+
end
|
28
|
+
processed_service.time_taken = self.round_time(benchmark.real)
|
29
|
+
self.log_complete(processed_service)
|
30
|
+
self.raise_if_debugging!(processed_service.exception)
|
31
|
+
processed_service
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
|
36
|
+
def run!
|
37
|
+
request, handler_class, response, exception = nil, nil, nil, nil
|
38
|
+
begin
|
39
|
+
request = Sanford::Protocol::Request.parse(@connection.read_data)
|
40
|
+
self.log_request(request)
|
41
|
+
handler_class = @host_data.handler_class_for(request.version, request.name)
|
42
|
+
self.log_handler_class(handler_class)
|
43
|
+
response = Sanford::Runner.new(handler_class, request, @host_data.logger).run
|
44
|
+
rescue Exception => exception
|
45
|
+
error_handler = Sanford::ErrorHandler.new(exception, @host_data, request)
|
46
|
+
response = error_handler.run
|
47
|
+
self.log_exception(error_handler.exception)
|
48
|
+
ensure
|
49
|
+
@connection.write_data response.to_hash
|
50
|
+
end
|
51
|
+
ProcessedService.new(request, handler_class, response, exception)
|
52
|
+
end
|
53
|
+
|
54
|
+
def raise_if_debugging!(exception)
|
55
|
+
raise exception if exception && ENV['SANFORD_DEBUG']
|
56
|
+
end
|
57
|
+
|
58
|
+
def log_received
|
59
|
+
self.logger.verbose.info("Received request")
|
60
|
+
end
|
61
|
+
|
62
|
+
def log_request(request)
|
63
|
+
self.logger.verbose.info(" Version: #{request.version.inspect}")
|
64
|
+
self.logger.verbose.info(" Service: #{request.name.inspect}")
|
65
|
+
self.logger.verbose.info(" Params: #{request.params.inspect}")
|
66
|
+
end
|
67
|
+
|
68
|
+
def log_handler_class(handler_class)
|
69
|
+
self.logger.verbose.info(" Handler: #{handler_class}")
|
70
|
+
end
|
71
|
+
|
72
|
+
def log_complete(processed_service)
|
73
|
+
self.logger.verbose.info "Completed in #{processed_service.time_taken}ms " \
|
74
|
+
"#{processed_service.response.status}\n"
|
75
|
+
self.logger.summary.info self.summary_line(processed_service).to_s
|
76
|
+
end
|
77
|
+
|
78
|
+
def log_exception(exception)
|
79
|
+
self.logger.verbose.error("#{exception.class}: #{exception.message}")
|
80
|
+
self.logger.verbose.error(exception.backtrace.join("\n"))
|
81
|
+
end
|
82
|
+
|
83
|
+
def summary_line(processed_service)
|
84
|
+
SummaryLine.new.tap do |line|
|
85
|
+
if (request = processed_service.request)
|
86
|
+
line.add 'version', request.version
|
87
|
+
line.add 'service', request.name
|
88
|
+
line.add 'params', request.params
|
89
|
+
end
|
90
|
+
line.add 'handler', processed_service.handler_class
|
91
|
+
line.add 'status', processed_service.response.status.code if processed_service.response
|
92
|
+
line.add 'duration', processed_service.time_taken
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
ROUND_PRECISION = 2
|
97
|
+
ROUND_MODIFIER = 10 ** ROUND_PRECISION
|
98
|
+
def round_time(time_in_seconds)
|
99
|
+
(time_in_seconds * 1000 * ROUND_MODIFIER).to_i / ROUND_MODIFIER.to_f
|
100
|
+
end
|
101
|
+
|
102
|
+
class SummaryLine
|
103
|
+
|
104
|
+
def initialize
|
105
|
+
@hash = {}
|
106
|
+
end
|
107
|
+
|
108
|
+
def add(key, value)
|
109
|
+
@hash[key] = value.inspect if value
|
110
|
+
end
|
111
|
+
|
112
|
+
# change the key's order in the array to change the order to change the
|
113
|
+
# order they appear in when logged
|
114
|
+
def to_s
|
115
|
+
[ 'version', 'service', 'handler', 'status', 'duration', 'params' ].map do |key|
|
116
|
+
"#{key}=#{@hash[key]}" if @hash[key]
|
117
|
+
end.compact.join(" ")
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
data/lib/sanford.rb
CHANGED
@@ -1,12 +1,26 @@
|
|
1
1
|
module Sanford; end
|
2
2
|
|
3
|
-
require '
|
4
|
-
require '
|
3
|
+
require 'ns-options'
|
4
|
+
require 'pathname'
|
5
|
+
require 'set'
|
6
|
+
|
5
7
|
require 'sanford/host'
|
8
|
+
require 'sanford/server'
|
9
|
+
require 'sanford/service_handler'
|
6
10
|
require 'sanford/version'
|
7
11
|
|
12
|
+
ENV['SANFORD_SERVICES_CONFIG'] ||= 'config/services'
|
13
|
+
|
8
14
|
module Sanford
|
9
15
|
|
16
|
+
def self.register(host)
|
17
|
+
@hosts.add(host)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.hosts
|
21
|
+
@hosts
|
22
|
+
end
|
23
|
+
|
10
24
|
def self.config
|
11
25
|
Sanford::Config
|
12
26
|
end
|
@@ -17,14 +31,43 @@ module Sanford
|
|
17
31
|
end
|
18
32
|
|
19
33
|
def self.init
|
34
|
+
@hosts ||= Hosts.new
|
20
35
|
require self.config.services_config
|
21
36
|
end
|
22
37
|
|
23
|
-
|
24
|
-
|
38
|
+
module Config
|
39
|
+
include NsOptions::Proxy
|
40
|
+
|
41
|
+
option :services_config, Pathname, :default => ENV['SANFORD_SERVICES_CONFIG']
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
class Hosts
|
46
|
+
|
47
|
+
def initialize(values = [])
|
48
|
+
@set = Set.new(values)
|
49
|
+
end
|
50
|
+
|
51
|
+
# We want class names to take precedence over a configured name, so that if
|
52
|
+
# a user specifies a specific class, they always get it
|
53
|
+
def find(name)
|
54
|
+
self.find_by_class_name(name) || self.find_by_name(name)
|
55
|
+
end
|
56
|
+
|
57
|
+
def find_by_class_name(class_name)
|
58
|
+
@set.detect{|host_class| host_class.to_s == class_name.to_s }
|
59
|
+
end
|
60
|
+
|
61
|
+
def find_by_name(name)
|
62
|
+
@set.detect{|host_class| host_class.name == name.to_s }
|
63
|
+
end
|
64
|
+
|
65
|
+
def method_missing(method, *args, &block)
|
66
|
+
@set.send(method, *args, &block)
|
67
|
+
end
|
25
68
|
|
26
|
-
|
27
|
-
|
69
|
+
def respond_to?(method)
|
70
|
+
super || @set.respond_to?(method)
|
28
71
|
end
|
29
72
|
|
30
73
|
end
|
data/sanford.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
|
|
19
19
|
|
20
20
|
gem.add_dependency("daemons", ["~>1.1"])
|
21
21
|
gem.add_dependency("dat-tcp", ["~>0.1"])
|
22
|
-
gem.add_dependency("ns-options", ["~>1.0
|
22
|
+
gem.add_dependency("ns-options", ["~>1.0"])
|
23
23
|
gem.add_dependency("sanford-protocol", ["~>0.5"])
|
24
24
|
|
25
25
|
gem.add_development_dependency("assert", ["~>1.0"])
|
data/test/helper.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
class FakeConnection
|
2
|
+
|
3
|
+
attr_reader :read_data, :response
|
4
|
+
|
5
|
+
def self.with_request(version, name, params = {})
|
6
|
+
request = Sanford::Protocol::Request.new(version, name, params)
|
7
|
+
self.new(request.to_hash)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(read_data)
|
11
|
+
@read_data = read_data
|
12
|
+
end
|
13
|
+
|
14
|
+
def write_data(data)
|
15
|
+
@response = Sanford::Protocol::Response.parse(data)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/test/support/helpers.rb
CHANGED
@@ -3,19 +3,17 @@ module Test
|
|
3
3
|
module Environment
|
4
4
|
|
5
5
|
def self.store_and_clear_hosts
|
6
|
-
@previous_hosts = Sanford.
|
7
|
-
Sanford.
|
6
|
+
@previous_hosts = Sanford.hosts.instance_variable_get("@set").dup
|
7
|
+
Sanford.hosts.clear
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.restore_hosts
|
11
|
-
Sanford.
|
11
|
+
Sanford.instance_variable_set("@hosts", Sanford::Hosts.new(@previous_hosts))
|
12
12
|
@previous_hosts = nil
|
13
13
|
end
|
14
14
|
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
17
|
module ForkServerHelper
|
20
18
|
|
21
19
|
def start_server(server, &block)
|
@@ -37,18 +35,16 @@ module Test
|
|
37
35
|
|
38
36
|
end
|
39
37
|
|
40
|
-
|
41
|
-
|
42
38
|
module ForkManagerHelper
|
43
39
|
|
44
40
|
# start a Sanford server using Sanford's manager in a forked process
|
45
41
|
def call_sanford_manager(*args, &block)
|
46
42
|
pid = fork do
|
47
|
-
STDOUT.reopen('/dev/null')
|
43
|
+
STDOUT.reopen('/dev/null') unless ENV['SANFORD_DEBUG']
|
48
44
|
trap("TERM"){ exit }
|
49
45
|
Sanford::Manager.call(*args)
|
50
46
|
end
|
51
|
-
sleep 1 # give time for the command to run
|
47
|
+
sleep 1.5 # give time for the command to run
|
52
48
|
yield
|
53
49
|
ensure
|
54
50
|
if pid
|
@@ -64,7 +60,7 @@ module Test
|
|
64
60
|
end
|
65
61
|
|
66
62
|
def expected_pid_file(host, ip, port)
|
67
|
-
host.
|
63
|
+
host.pid_dir.join("#{ip}_#{port}_#{host}.pid")
|
68
64
|
end
|
69
65
|
|
70
66
|
end
|