serverside 0.1.59
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +97 -0
- data/COPYING +18 -0
- data/README +51 -0
- data/Rakefile +92 -0
- data/bin/serverside +74 -0
- data/doc/rdoc/classes/Daemon.html +253 -0
- data/doc/rdoc/classes/Daemon/Base.html +146 -0
- data/doc/rdoc/classes/Daemon/Cluster.html +308 -0
- data/doc/rdoc/classes/Daemon/Cluster/PidFile.html +228 -0
- data/doc/rdoc/classes/Daemon/PidFile.html +178 -0
- data/doc/rdoc/classes/ServerSide.html +160 -0
- data/doc/rdoc/classes/ServerSide/Application.html +147 -0
- data/doc/rdoc/classes/ServerSide/Application/Base.html +196 -0
- data/doc/rdoc/classes/ServerSide/Application/Static.html +154 -0
- data/doc/rdoc/classes/ServerSide/Connection.html +128 -0
- data/doc/rdoc/classes/ServerSide/Connection/Base.html +343 -0
- data/doc/rdoc/classes/ServerSide/Connection/Const.html +229 -0
- data/doc/rdoc/classes/ServerSide/Connection/Static.html +172 -0
- data/doc/rdoc/classes/ServerSide/Server.html +162 -0
- data/doc/rdoc/classes/ServerSide/StaticFiles.html +208 -0
- data/doc/rdoc/classes/ServerSide/StaticFiles/Const.html +179 -0
- data/doc/rdoc/classes/String.html +210 -0
- data/doc/rdoc/classes/Symbol.html +156 -0
- data/doc/rdoc/created.rid +1 -0
- data/doc/rdoc/files/CHANGELOG.html +260 -0
- data/doc/rdoc/files/COPYING.html +129 -0
- data/doc/rdoc/files/README.html +171 -0
- data/doc/rdoc/files/lib/serverside/application_rb.html +109 -0
- data/doc/rdoc/files/lib/serverside/cluster_rb.html +101 -0
- data/doc/rdoc/files/lib/serverside/connection_rb.html +101 -0
- data/doc/rdoc/files/lib/serverside/core_ext_rb.html +107 -0
- data/doc/rdoc/files/lib/serverside/daemon_rb.html +108 -0
- data/doc/rdoc/files/lib/serverside/server_rb.html +108 -0
- data/doc/rdoc/files/lib/serverside/static_rb.html +101 -0
- data/doc/rdoc/files/lib/serverside_rb.html +131 -0
- data/doc/rdoc/fr_class_index.html +44 -0
- data/doc/rdoc/fr_file_index.html +37 -0
- data/doc/rdoc/fr_method_index.html +60 -0
- data/doc/rdoc/index.html +24 -0
- data/doc/rdoc/rdoc-style.css +208 -0
- data/lib/serverside.rb +13 -0
- data/lib/serverside/application.rb +40 -0
- data/lib/serverside/cluster.rb +72 -0
- data/lib/serverside/connection.rb +115 -0
- data/lib/serverside/core_ext.rb +27 -0
- data/lib/serverside/daemon.rb +67 -0
- data/lib/serverside/server.rb +18 -0
- data/lib/serverside/static.rb +96 -0
- data/test/functional/primitive_static_server_test.rb +37 -0
- data/test/functional/static_profile.rb +17 -0
- data/test/functional/static_rfuzz.rb +67 -0
- data/test/functional/static_server_test.rb +25 -0
- data/test/test_helper.rb +2 -0
- data/test/unit/application_test.rb +16 -0
- data/test/unit/cluster_test.rb +129 -0
- data/test/unit/connection_test.rb +193 -0
- data/test/unit/core_ext_test.rb +32 -0
- data/test/unit/daemon_test.rb +75 -0
- data/test/unit/server_test.rb +26 -0
- data/test/unit/static_test.rb +143 -0
- metadata +140 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
class StaticServerTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_basic
|
7
|
+
t = Thread.new {ServerSide::Server.new('0.0.0.0', 17654, ServerSide::Connection::Static)}
|
8
|
+
sleep 0.1
|
9
|
+
|
10
|
+
h = Net::HTTP.new('localhost', 17654)
|
11
|
+
resp, data = h.get('/qqq.zzz', nil)
|
12
|
+
assert_equal 404, resp.code.to_i
|
13
|
+
assert_equal "Couldn't open file /qqq.zzz.", data
|
14
|
+
|
15
|
+
h = Net::HTTP.new('localhost', 17654)
|
16
|
+
resp, data = h.get("/#{__FILE__}", nil)
|
17
|
+
assert_equal 200, resp.code.to_i
|
18
|
+
assert_equal IO.read(__FILE__), data
|
19
|
+
assert_equal 'text/plain', resp['Content-Type']
|
20
|
+
# Net::HTTP includes this header in the request, so our server returns
|
21
|
+
# likewise.
|
22
|
+
assert_equal 'close', resp['Connection']
|
23
|
+
t.exit
|
24
|
+
end
|
25
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class ApplicationTest < Test::Unit::TestCase
|
4
|
+
class App1 < ServerSide::Application::Base
|
5
|
+
configure(:port => 8001)
|
6
|
+
end
|
7
|
+
|
8
|
+
class App2 < ServerSide::Application::Base
|
9
|
+
configure(:port => 8002)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_config
|
13
|
+
assert_equal 8001, App1.configuration[:port]
|
14
|
+
assert_equal 8002, App2.configuration[:port]
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
class ClusterTest < Test::Unit::TestCase
|
5
|
+
FN = Daemon::Cluster::PidFile::FN
|
6
|
+
|
7
|
+
def test_pid_fn
|
8
|
+
assert_equal 'serverside_cluster.pid', Daemon::Cluster::PidFile::FN
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_pid_delete
|
12
|
+
FileUtils.touch(FN)
|
13
|
+
assert_equal true, File.file?(FN)
|
14
|
+
Daemon::Cluster::PidFile.delete
|
15
|
+
assert_equal false, File.file?(FN)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_pid_store_pid
|
19
|
+
FileUtils.rm(FN) if File.file?(FN)
|
20
|
+
Daemon::Cluster::PidFile.store_pid(1111)
|
21
|
+
assert_equal "1111\n", IO.read(FN)
|
22
|
+
Daemon::Cluster::PidFile.store_pid(2222)
|
23
|
+
assert_equal "1111\n2222\n", IO.read(FN)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_pid_recall_pids
|
27
|
+
FileUtils.rm(FN) if File.file?(FN)
|
28
|
+
assert_raise(Errno::ENOENT) {Daemon::Cluster::PidFile.recall_pids}
|
29
|
+
File.open(FN, 'w') {|f| f.puts 3333; f.puts 4444}
|
30
|
+
assert_equal [3333, 4444], Daemon::Cluster::PidFile.recall_pids
|
31
|
+
|
32
|
+
FileUtils.rm(FN)
|
33
|
+
Daemon::Cluster::PidFile.store_pid(6666)
|
34
|
+
Daemon::Cluster::PidFile.store_pid(7777)
|
35
|
+
assert_equal [6666, 7777], Daemon::Cluster::PidFile.recall_pids
|
36
|
+
end
|
37
|
+
|
38
|
+
class DummyCluster < Daemon::Cluster
|
39
|
+
FN = 'result'
|
40
|
+
|
41
|
+
def self.server_loop(port)
|
42
|
+
at_exit {File.open(FN, 'a') {|f| f.puts port}}
|
43
|
+
loop {sleep 60}
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.ports
|
47
|
+
5555..5556
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_fork_server
|
52
|
+
FileUtils.rm(DummyCluster::FN) if File.file?(DummyCluster::FN)
|
53
|
+
pid = DummyCluster.fork_server(1111)
|
54
|
+
sleep 1
|
55
|
+
Process.kill('TERM', pid)
|
56
|
+
sleep 0.1
|
57
|
+
assert_equal true, File.file?(DummyCluster::FN)
|
58
|
+
File.open(DummyCluster::FN, 'r') do |f|
|
59
|
+
assert_equal 1111, f.gets.to_i
|
60
|
+
assert_equal true, f.eof?
|
61
|
+
end
|
62
|
+
FileUtils.rm(DummyCluster::FN) if File.file?(DummyCluster::FN)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_start_servers
|
66
|
+
FileUtils.rm(DummyCluster::FN) if File.file?(DummyCluster::FN)
|
67
|
+
DummyCluster.start_servers
|
68
|
+
sleep 0.5
|
69
|
+
pids = Daemon::Cluster::PidFile.recall_pids
|
70
|
+
assert_equal 2, pids.length
|
71
|
+
pids.each {|pid| Process.kill('TERM', pid)}
|
72
|
+
sleep 0.5
|
73
|
+
File.open(DummyCluster::FN, 'r') do |f|
|
74
|
+
p1, p2 = f.gets.to_i, f.gets.to_i
|
75
|
+
assert_equal true, DummyCluster.ports.include?(p1)
|
76
|
+
assert_equal true, DummyCluster.ports.include?(p2)
|
77
|
+
assert p1 != p2
|
78
|
+
assert_equal true, f.eof?
|
79
|
+
end
|
80
|
+
FileUtils.rm(DummyCluster::FN) if File.file?(DummyCluster::FN)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_stop_servers
|
84
|
+
DummyCluster.start_servers
|
85
|
+
sleep 0.5
|
86
|
+
pids = Daemon::Cluster::PidFile.recall_pids
|
87
|
+
DummyCluster.stop_servers
|
88
|
+
sleep 0.5
|
89
|
+
assert_equal false, File.file?(FN)
|
90
|
+
File.open(DummyCluster::FN, 'r') do |f|
|
91
|
+
p1, p2 = f.gets.to_i, f.gets.to_i
|
92
|
+
assert_equal true, DummyCluster.ports.include?(p1)
|
93
|
+
assert_equal true, DummyCluster.ports.include?(p2)
|
94
|
+
assert p1 != p2
|
95
|
+
assert_equal true, f.eof?
|
96
|
+
end
|
97
|
+
FileUtils.rm(DummyCluster::FN) if File.file?(DummyCluster::FN)
|
98
|
+
end
|
99
|
+
|
100
|
+
class DummyCluster2 < Daemon::Cluster
|
101
|
+
def self.daemon_loop
|
102
|
+
@@a = true
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.start_servers
|
106
|
+
@@b = true
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.stop_servers
|
110
|
+
@@c = true
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.a; @@a; end
|
114
|
+
def self.b; @@b; end
|
115
|
+
def self.c; @@c; end
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_start
|
119
|
+
DummyCluster2.start
|
120
|
+
assert_equal true, DummyCluster2.a
|
121
|
+
assert_equal true, DummyCluster2.b
|
122
|
+
|
123
|
+
DummyCluster2.stop
|
124
|
+
assert_equal true, DummyCluster2.c
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_stop
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
class ConnectionTest < Test::Unit::TestCase
|
5
|
+
class DummyConnection1 < ServerSide::Connection::Base
|
6
|
+
attr_reader :count, :conn
|
7
|
+
|
8
|
+
def process
|
9
|
+
@count ||= 0
|
10
|
+
@count += 1
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_new
|
15
|
+
r = DummyConnection1.new('hello')
|
16
|
+
assert_equal 'hello', r.conn
|
17
|
+
assert_equal 1, r.count
|
18
|
+
end
|
19
|
+
|
20
|
+
class DummyConnection
|
21
|
+
attr_reader :opened
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@opened = true
|
25
|
+
end
|
26
|
+
|
27
|
+
def close
|
28
|
+
@opened = false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class DummyConnection2 < ServerSide::Connection::Base
|
33
|
+
attr_accessor :count, :persistent
|
34
|
+
|
35
|
+
def parse_request
|
36
|
+
@count ||= 0
|
37
|
+
@count += 1
|
38
|
+
@persistent = @count < 1000
|
39
|
+
end
|
40
|
+
|
41
|
+
def respond
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_process
|
46
|
+
c = DummyConnection.new
|
47
|
+
r = DummyConnection2.new(c)
|
48
|
+
sleep 0.2
|
49
|
+
assert_equal false, c.opened
|
50
|
+
assert_equal 1000, r.count
|
51
|
+
end
|
52
|
+
|
53
|
+
class ServerSide::Connection::Base
|
54
|
+
attr_accessor :conn, :method, :query, :version, :path, :parameters,
|
55
|
+
:headers, :persistent
|
56
|
+
end
|
57
|
+
|
58
|
+
class DummyConnection3 < ServerSide::Connection::Base
|
59
|
+
def initialize
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_parse_request_invalid
|
64
|
+
r = DummyConnection3.new
|
65
|
+
r.conn = StringIO.new('POST /test')
|
66
|
+
assert_nil r.parse_request
|
67
|
+
r.conn = StringIO.new('invalid string')
|
68
|
+
assert_nil r.parse_request
|
69
|
+
r.conn = StringIO.new('GET HTTP/1.1')
|
70
|
+
assert_nil r.parse_request
|
71
|
+
r.conn = StringIO.new('GET /test http')
|
72
|
+
assert_nil r.parse_request
|
73
|
+
r.conn = StringIO.new('GET /test HTTP')
|
74
|
+
assert_nil r.parse_request
|
75
|
+
r.conn = StringIO.new('GET /test HTTP/')
|
76
|
+
assert_nil r.parse_request
|
77
|
+
r.conn = StringIO.new('POST /test HTTP/1.1')
|
78
|
+
assert_nil r.parse_request
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_parse_request
|
82
|
+
r = DummyConnection3.new
|
83
|
+
r.conn = StringIO.new("POST /test HTTP/1.1\r\n\r\n")
|
84
|
+
assert_kind_of Hash, r.parse_request
|
85
|
+
assert_equal :post, r.method
|
86
|
+
assert_equal '/test', r.path
|
87
|
+
assert_nil r.query
|
88
|
+
assert_equal '1.1', r.version
|
89
|
+
assert_equal({}, r.parameters)
|
90
|
+
assert_equal({}, r.headers)
|
91
|
+
assert_equal true, r.persistent
|
92
|
+
|
93
|
+
# trailing slash in path
|
94
|
+
r = DummyConnection3.new
|
95
|
+
r.conn = StringIO.new("POST /test/asdf/qw/?time=24%20hours HTTP/1.1\r\n\r\n")
|
96
|
+
assert_kind_of Hash, r.parse_request
|
97
|
+
assert_equal :post, r.method
|
98
|
+
assert_equal '/test/asdf/qw', r.path
|
99
|
+
assert_equal 'time=24%20hours', r.query
|
100
|
+
assert_equal '1.1', r.version
|
101
|
+
assert_equal({:time => '24 hours'}, r.parameters)
|
102
|
+
assert_equal({}, r.headers)
|
103
|
+
assert_equal true, r.persistent
|
104
|
+
|
105
|
+
r.conn = StringIO.new("GET /cex?q=node_state HTTP/1.1\r\n\r\n")
|
106
|
+
assert_kind_of Hash, r.parse_request
|
107
|
+
assert_equal :get, r.method
|
108
|
+
assert_equal '/cex', r.path
|
109
|
+
assert_equal 'q=node_state', r.query
|
110
|
+
assert_equal({:q => 'node_state'}, r.parameters)
|
111
|
+
|
112
|
+
r.conn = StringIO.new("GET / HTTP/1.0\r\n\r\n")
|
113
|
+
assert_kind_of Hash, r.parse_request
|
114
|
+
assert_equal false, r.persistent
|
115
|
+
|
116
|
+
r.conn = StringIO.new("GET / HTTP/invalid\r\n\r\n")
|
117
|
+
assert_kind_of Hash, r.parse_request
|
118
|
+
assert_equal 'invalid', r.version
|
119
|
+
assert_equal false, r.persistent
|
120
|
+
|
121
|
+
r.conn = StringIO.new("GET / HTTP/1.1\r\nConnection: close\r\n\r\n")
|
122
|
+
assert_kind_of Hash, r.parse_request
|
123
|
+
assert_equal '1.1', r.version
|
124
|
+
assert_equal 'close', r.headers['Connection']
|
125
|
+
assert_equal false, r.persistent
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_send_response
|
129
|
+
r = DummyConnection3.new
|
130
|
+
# simple case
|
131
|
+
r.conn = StringIO.new
|
132
|
+
r.persistent = true
|
133
|
+
r.send_response(200, 'text', 'Hello there!')
|
134
|
+
r.conn.rewind
|
135
|
+
assert_equal "HTTP/1.1 200\r\nContent-Type: text\r\nContent-Length: 12\r\n\r\nHello there!",
|
136
|
+
r.conn.read
|
137
|
+
|
138
|
+
# include content-length
|
139
|
+
r.conn = StringIO.new
|
140
|
+
r.persistent = true
|
141
|
+
r.send_response(404, 'text/html', '<h1>404!</h1>', 10) # incorrect length
|
142
|
+
r.conn.rewind
|
143
|
+
assert_equal "HTTP/1.1 404\r\nContent-Type: text/html\r\nContent-Length: 10\r\n\r\n<h1>404!</h1>",
|
144
|
+
r.conn.read
|
145
|
+
|
146
|
+
# headers
|
147
|
+
r.conn = StringIO.new
|
148
|
+
r.persistent = true
|
149
|
+
r.send_response(404, 'text/html', '<h1>404!</h1>', nil, {'ETag' => 'xxyyzz'})
|
150
|
+
r.conn.rewind
|
151
|
+
assert_equal "HTTP/1.1 404\r\nContent-Type: text/html\r\nETag: xxyyzz\r\nContent-Length: 13\r\n\r\n<h1>404!</h1>",
|
152
|
+
r.conn.read
|
153
|
+
|
154
|
+
# no body
|
155
|
+
r.conn = StringIO.new
|
156
|
+
r.persistent = true
|
157
|
+
r.send_response(404, 'text/html', nil, nil, {'Set-Cookie' => 'abc=123'})
|
158
|
+
r.conn.rewind
|
159
|
+
assert_equal "HTTP/1.1 404\r\nConnection: close\r\nContent-Type: text/html\r\nSet-Cookie: abc=123\r\n\r\n",
|
160
|
+
r.conn.read
|
161
|
+
assert_equal false, r.persistent
|
162
|
+
|
163
|
+
# not persistent
|
164
|
+
r.conn = StringIO.new
|
165
|
+
r.persistent = false
|
166
|
+
r.send_response(200, 'text', 'Hello there!')
|
167
|
+
r.conn.rewind
|
168
|
+
assert_equal "HTTP/1.1 200\r\nConnection: close\r\nContent-Type: text\r\nContent-Length: 12\r\n\r\nHello there!",
|
169
|
+
r.conn.read
|
170
|
+
|
171
|
+
# socket error
|
172
|
+
r.conn = nil
|
173
|
+
r.persistent = true
|
174
|
+
assert_nothing_raised {r.send_response(200, 'text', 'Hello there!')}
|
175
|
+
assert_equal false, r.persistent
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_stream
|
179
|
+
r = DummyConnection3.new
|
180
|
+
r.conn = StringIO.new
|
181
|
+
r.stream 'hey there'
|
182
|
+
r.conn.rewind
|
183
|
+
assert_equal 'hey there', r.conn.read
|
184
|
+
|
185
|
+
r.conn = StringIO.new
|
186
|
+
r.persistent = true
|
187
|
+
r.send_response(404, 'text/html', nil, nil, {'Set-Cookie' => 'abc=123'})
|
188
|
+
r.stream('hey there')
|
189
|
+
r.conn.rewind
|
190
|
+
assert_equal "HTTP/1.1 404\r\nConnection: close\r\nContent-Type: text/html\r\nSet-Cookie: abc=123\r\n\r\nhey there",
|
191
|
+
r.conn.read
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class StringTest < Test::Unit::TestCase
|
4
|
+
def test_uri_escape
|
5
|
+
assert_equal 'hello', 'hello'.uri_escape
|
6
|
+
assert_equal 'hello+world', 'hello world'.uri_escape
|
7
|
+
assert_equal 'Hello%2C+my+name+is+Inigo+Montoya%21',
|
8
|
+
'Hello, my name is Inigo Montoya!'.uri_escape
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_uri_unescape
|
12
|
+
assert_equal 'hello', 'hello'.uri_unescape
|
13
|
+
assert_equal 'hello world', 'hello+world'.uri_unescape
|
14
|
+
assert_equal 'Hello, my name is Inigo Montoya!',
|
15
|
+
'Hello%2C+my+name+is+Inigo+Montoya%21'.uri_unescape
|
16
|
+
assert_equal '%&asdf#231&?fgs!', '%&asdf#231&?fgs!'.uri_escape.uri_unescape
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_slash
|
20
|
+
assert_equal 'sharon/eylon', 'sharon'/'/eylon'
|
21
|
+
assert_equal 'sharon/122', 'sharon/'/122
|
22
|
+
assert_equal 'test/schmest', 'test'/:schmest
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class SymbolTest < Test::Unit::TestCase
|
27
|
+
def test_to_s
|
28
|
+
assert_equal 'hello', :hello.to_s
|
29
|
+
assert_equal 'yow_za', :yow_za.to_s
|
30
|
+
assert_equal :yow_za.to_s.object_id, :yow_za.to_s.object_id
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class DaemonTest < Test::Unit::TestCase
|
4
|
+
class TestDaemon < Daemon::Base
|
5
|
+
def self.start
|
6
|
+
@count = 0
|
7
|
+
loop {@count += 1; sleep 0.1}
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.result_fn
|
11
|
+
File.join(Daemon::WorkingDirectory, 'test.result')
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.stop
|
15
|
+
File.open(result_fn, 'w') {|f| f << @count}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def teardown
|
20
|
+
Daemon.control(TestDaemon, :stop) rescue nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_working_directory
|
24
|
+
assert_equal FileUtils.pwd, Daemon::WorkingDirectory
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_pid_fn
|
28
|
+
assert_equal File.join(Daemon::WorkingDirectory, 'daemon.base.pid'),
|
29
|
+
Daemon::Base.pid_fn
|
30
|
+
|
31
|
+
assert_equal File.join(Daemon::WorkingDirectory, 'daemontest.testdaemon.pid'),
|
32
|
+
TestDaemon.pid_fn
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_pid_file_store
|
36
|
+
Daemon::PidFile.store(TestDaemon, 1234)
|
37
|
+
assert_equal IO.read(TestDaemon.pid_fn).to_i, 1234
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_pid_file_recall
|
41
|
+
FileUtils.rm(TestDaemon.pid_fn) rescue nil
|
42
|
+
assert_raise(RuntimeError) {Daemon::PidFile.recall(TestDaemon)}
|
43
|
+
Daemon::PidFile.store(TestDaemon, 5321)
|
44
|
+
assert_equal 5321, Daemon::PidFile.recall(TestDaemon)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_start_stop
|
48
|
+
FileUtils.rm(TestDaemon.result_fn) rescue nil
|
49
|
+
Daemon.control(TestDaemon, :start)
|
50
|
+
sleep 0.2
|
51
|
+
assert_equal true, File.file?(TestDaemon.pid_fn)
|
52
|
+
sleep 0.5
|
53
|
+
assert_nothing_raised {Daemon::PidFile.recall(TestDaemon)}
|
54
|
+
Daemon.control(TestDaemon, :stop)
|
55
|
+
sleep 0.5
|
56
|
+
assert_equal true, File.file?(TestDaemon.result_fn)
|
57
|
+
FileUtils.rm(TestDaemon.result_fn) rescue nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_restart
|
61
|
+
FileUtils.rm(TestDaemon.result_fn) rescue nil
|
62
|
+
Daemon.control(TestDaemon, :start)
|
63
|
+
sleep 0.5
|
64
|
+
pid1 = Daemon::PidFile.recall(TestDaemon)
|
65
|
+
Daemon.control(TestDaemon, :restart)
|
66
|
+
sleep 0.5
|
67
|
+
pid2 = Daemon::PidFile.recall(TestDaemon)
|
68
|
+
assert pid1 != pid2
|
69
|
+
Daemon.control(TestDaemon, :stop)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_invalid_control_cmd
|
73
|
+
assert_raise(RuntimeError) {Daemon.control(TestDaemon, :invalid)}
|
74
|
+
end
|
75
|
+
end
|