serverside 0.2.9 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +56 -0
- data/Rakefile +12 -52
- data/bin/serverside +1 -1
- data/lib/serverside/application.rb +2 -1
- data/lib/serverside/caching.rb +62 -50
- data/lib/serverside/controllers.rb +91 -0
- data/lib/serverside/core_ext.rb +6 -0
- data/lib/serverside/daemon.rb +25 -5
- data/lib/serverside/request.rb +17 -11
- data/lib/serverside/routing.rb +11 -10
- data/lib/serverside/server.rb +14 -6
- data/lib/serverside/static.rb +7 -18
- data/lib/serverside/template.rb +20 -12
- data/spec/caching_spec.rb +318 -0
- data/spec/cluster_spec.rb +140 -0
- data/{test/spec → spec}/connection_spec.rb +4 -4
- data/{test/spec/controller_spec.rb → spec/controllers_spec.rb} +15 -12
- data/{test/spec → spec}/core_ext_spec.rb +23 -18
- data/spec/daemon_spec.rb +99 -0
- data/{test/spec → spec}/request_spec.rb +45 -45
- data/spec/routing_spec.rb +240 -0
- data/spec/server_spec.rb +40 -0
- data/spec/static_spec.rb +279 -0
- data/spec/template_spec.rb +129 -0
- metadata +21 -35
- data/lib/serverside/controller.rb +0 -67
- data/test/functional/primitive_static_server_test.rb +0 -61
- data/test/functional/request_body_test.rb +0 -93
- data/test/functional/routing_server.rb +0 -14
- data/test/functional/routing_server_test.rb +0 -41
- data/test/functional/static_profile.rb +0 -17
- data/test/functional/static_rfuzz.rb +0 -31
- data/test/functional/static_server.rb +0 -7
- data/test/functional/static_server_test.rb +0 -31
- data/test/spec/caching_spec.rb +0 -139
- data/test/test_helper.rb +0 -2
- data/test/unit/cluster_test.rb +0 -129
- data/test/unit/connection_test.rb +0 -48
- data/test/unit/core_ext_test.rb +0 -46
- data/test/unit/daemon_test.rb +0 -75
- data/test/unit/request_test.rb +0 -278
- data/test/unit/routing_test.rb +0 -171
- data/test/unit/server_test.rb +0 -28
- data/test/unit/static_test.rb +0 -171
- data/test/unit/template_test.rb +0 -78
@@ -1,93 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
-
require 'net/http'
|
3
|
-
|
4
|
-
$r = nil
|
5
|
-
ServerSide::Router.route(:path => '/') {$r = self; send_response(200, 'text', 'OK')}
|
6
|
-
t = Thread.new {ServerSide::HTTP::Server.new('0.0.0.0', 17651, ServerSide::Router)}
|
7
|
-
sleep 0.1
|
8
|
-
|
9
|
-
class RequestBodyTest < Test::Unit::TestCase
|
10
|
-
|
11
|
-
def test_basic
|
12
|
-
h = Net::HTTP.new('localhost', 17651)
|
13
|
-
|
14
|
-
resp = h.post('/try', 'q=node_state&f=xml', {'Content-Type' => 'application/x-www-form-urlencoded'})
|
15
|
-
assert_equal 'OK', resp.body
|
16
|
-
assert_not_nil $r
|
17
|
-
assert_equal :post, $r.method
|
18
|
-
assert_not_nil $r.body
|
19
|
-
assert_equal 'q=node_state&f=xml', $r.body
|
20
|
-
assert_equal 'application/x-www-form-urlencoded', $r.content_type
|
21
|
-
assert_equal 18, $r.content_length
|
22
|
-
end
|
23
|
-
|
24
|
-
def text_to_multipart(key, value)
|
25
|
-
return "Content-Disposition: form-data; name=\"#{key.uri_escape}\"\r\n\r\n#{value}\r\n"
|
26
|
-
end
|
27
|
-
|
28
|
-
def file_to_multipart(key, filename, mime_type, content)
|
29
|
-
return "Content-Disposition: form-data; name=\"#{key.uri_escape}\"; filename=\"#{filename}\"\r\n" +
|
30
|
-
"Content-Transfer-Encoding: binary\r\nContent-Type: #{mime_type}\r\n\r\n#{content}\r\n"
|
31
|
-
end
|
32
|
-
|
33
|
-
def upload_file(*fns)
|
34
|
-
params = []
|
35
|
-
fns.each_with_index do |fn, idx|
|
36
|
-
params << file_to_multipart("file#{idx}", File.basename(fn),
|
37
|
-
"text/#{File.extname(fn).gsub('.', '')}", IO.read(fn))
|
38
|
-
end
|
39
|
-
|
40
|
-
boundary = '349832898984244898448024464570528145'
|
41
|
-
query =
|
42
|
-
params.map{|p| '--' + boundary + "\r\n" + p}.join('') + "--" + boundary + "--\r\n"
|
43
|
-
Net::HTTP.start('localhost', 17651).
|
44
|
-
post2("/", query, "Content-type" => "multipart/form-data; boundary=" + boundary)
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_upload
|
48
|
-
upload_file(__FILE__)
|
49
|
-
assert_equal :post, $r.method
|
50
|
-
assert_not_nil $r.parameters[:file0]
|
51
|
-
assert_equal "text/rb", $r.parameters[:file0][:type]
|
52
|
-
assert_equal IO.read(__FILE__), $r.parameters[:file0][:content]
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_multiple_uploads
|
56
|
-
readme_fn = File.dirname(__FILE__) + '/../../README'
|
57
|
-
upload_file(__FILE__, readme_fn)
|
58
|
-
assert_equal :post, $r.method
|
59
|
-
assert_not_nil $r.parameters[:file0]
|
60
|
-
assert_not_nil $r.parameters[:file1]
|
61
|
-
assert_equal "text/rb", $r.parameters[:file0][:type]
|
62
|
-
assert_equal "text/", $r.parameters[:file1][:type]
|
63
|
-
assert_equal IO.read(__FILE__), $r.parameters[:file0][:content]
|
64
|
-
assert_equal IO.read(readme_fn), $r.parameters[:file1][:content]
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_mixed_form_data
|
68
|
-
params = [
|
69
|
-
file_to_multipart("file", File.basename(__FILE__), "text/rb", IO.read(__FILE__)),
|
70
|
-
text_to_multipart('warning','1'),
|
71
|
-
text_to_multipart('profile','css2'),
|
72
|
-
text_to_multipart('usermedium','all')
|
73
|
-
]
|
74
|
-
|
75
|
-
boundary = '349832898984244898448024464570528145'
|
76
|
-
query =
|
77
|
-
params.map{|p| '--' + boundary + "\r\n" + p}.join('') + "--" + boundary + "--\r\n"
|
78
|
-
Net::HTTP.start('localhost', 17651).
|
79
|
-
post2("/", query, "Content-type" => "multipart/form-data; boundary=" + boundary)
|
80
|
-
|
81
|
-
assert_equal :post, $r.method
|
82
|
-
|
83
|
-
assert_not_nil $r.parameters[:file]
|
84
|
-
assert_equal "text/rb", $r.parameters[:file][:type]
|
85
|
-
assert_equal File.basename(__FILE__), $r.parameters[:file][:filename]
|
86
|
-
assert_equal IO.read(__FILE__), $r.parameters[:file][:content]
|
87
|
-
|
88
|
-
assert_equal '1', $r.parameters[:warning]
|
89
|
-
assert_equal 'css2', $r.parameters[:profile]
|
90
|
-
assert_equal 'all', $r.parameters[:usermedium]
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
-
require 'fileutils'
|
3
|
-
|
4
|
-
FileUtils.cd(File.dirname(__FILE__))
|
5
|
-
|
6
|
-
trap('INT') {exit}
|
7
|
-
|
8
|
-
ServerSide::Router.route(:path => '^/static/:path') {serve_static('.'/@parameters[:path])}
|
9
|
-
ServerSide::Router.route(:path => '/hello$') {send_response(200, 'text', 'Hello world!')}
|
10
|
-
ServerSide::Router.route(:path => '/xml') do
|
11
|
-
redirect('http://feeds.feedburner.com/RobbyOnRails')
|
12
|
-
end
|
13
|
-
|
14
|
-
ServerSide::HTTP::Server.new('0.0.0.0', 4401, ServerSide::Router)
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
-
require 'net/http'
|
3
|
-
|
4
|
-
class StaticServerTest < Test::Unit::TestCase
|
5
|
-
def test_basic
|
6
|
-
ServerSide::Router.route(:path => '^/static/:path') {serve_static('.'/@parameters[:path])}
|
7
|
-
ServerSide::Router.route(:path => '/hello$') {send_response(200, 'text', 'Hello world!')}
|
8
|
-
ServerSide::Router.route(:path => '/xml/:flavor/feed.xml') do
|
9
|
-
redirect('http://feeds.feedburner.com/RobbyOnRails')
|
10
|
-
end
|
11
|
-
|
12
|
-
t = Thread.new {ServerSide::HTTP::Server.new('0.0.0.0', 17654, ServerSide::Router)}
|
13
|
-
sleep 0.1
|
14
|
-
|
15
|
-
h = Net::HTTP.new('localhost', 17654)
|
16
|
-
resp, data = h.get('/hello', nil)
|
17
|
-
assert_equal 200, resp.code.to_i
|
18
|
-
assert_equal "Hello world!", data
|
19
|
-
|
20
|
-
h = Net::HTTP.new('localhost', 17654)
|
21
|
-
resp, data = h.get('/static/qqq.zzz', nil)
|
22
|
-
assert_equal 404, resp.code.to_i
|
23
|
-
assert_equal "File not found.", data
|
24
|
-
|
25
|
-
h = Net::HTTP.new('localhost', 17654)
|
26
|
-
resp, data = h.get("/static/#{__FILE__}", nil)
|
27
|
-
assert_equal 200, resp.code.to_i
|
28
|
-
assert_equal IO.read(__FILE__), data
|
29
|
-
assert_equal 'text/plain', resp['Content-Type']
|
30
|
-
# Net::HTTP includes this header in the request, so our server returns
|
31
|
-
# likewise.
|
32
|
-
assert_equal 'close', resp['Connection']
|
33
|
-
|
34
|
-
h = Net::HTTP.new('localhost', 17654)
|
35
|
-
resp, data = h.get('/xml/rss/feed.xml', nil)
|
36
|
-
assert_equal 302, resp.code.to_i
|
37
|
-
assert_equal 'http://feeds.feedburner.com/RobbyOnRails', resp['Location']
|
38
|
-
|
39
|
-
t.exit
|
40
|
-
end
|
41
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'serverside'
|
3
|
-
require 'fileutils'
|
4
|
-
|
5
|
-
FileUtils.cd(File.dirname(__FILE__))
|
6
|
-
|
7
|
-
pid = fork do
|
8
|
-
trap('TERM') {exit}
|
9
|
-
require 'profile'
|
10
|
-
ServerSide::HTTP::Server.new('0.0.0.0', 8000, nil)
|
11
|
-
end
|
12
|
-
|
13
|
-
puts "Please wait..."
|
14
|
-
`ab -n 1000 http://localhost:8000/#{File.basename(__FILE__)}`
|
15
|
-
puts
|
16
|
-
Process.kill('TERM', pid)
|
17
|
-
puts
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# Simple script that hits a host port and URI with a bunch of connections
|
2
|
-
# and measures the timings.
|
3
|
-
|
4
|
-
require 'rubygems'
|
5
|
-
require 'rfuzz/client'
|
6
|
-
require 'rfuzz/stats'
|
7
|
-
include RFuzz
|
8
|
-
|
9
|
-
if ARGV.length != 4
|
10
|
-
STDERR.puts "usage: ruby perftest.rb host port uri count"
|
11
|
-
exit 1
|
12
|
-
end
|
13
|
-
|
14
|
-
host, port, uri, count = ARGV[0], ARGV[1], ARGV[2], ARGV[3].to_i
|
15
|
-
|
16
|
-
codes = {}
|
17
|
-
cl = HttpClient.new(host, port, :notifier => StatsTracker.new)
|
18
|
-
count.times do
|
19
|
-
begin
|
20
|
-
resp = cl.get(uri)
|
21
|
-
code = resp.http_status.to_i
|
22
|
-
codes[code] ||= 0
|
23
|
-
codes[code] += 1
|
24
|
-
rescue => e
|
25
|
-
puts e.message
|
26
|
-
puts e.backtrace.first
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
puts cl.notifier.to_s
|
31
|
-
puts "Status Codes: #{codes.inspect}"
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
-
require 'net/http'
|
3
|
-
|
4
|
-
class StaticServerTest < Test::Unit::TestCase
|
5
|
-
|
6
|
-
class StaticRequest < ServerSide::HTTP::Request
|
7
|
-
def respond
|
8
|
-
serve_static('.'/@path)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_basic
|
13
|
-
t = Thread.new {ServerSide::HTTP::Server.new('0.0.0.0', 17654, StaticRequest)}
|
14
|
-
sleep 0.1
|
15
|
-
|
16
|
-
h = Net::HTTP.new('localhost', 17654)
|
17
|
-
resp, data = h.get('/qqq.zzz', nil)
|
18
|
-
assert_equal 404, resp.code.to_i
|
19
|
-
assert_equal "File not found.", data
|
20
|
-
|
21
|
-
h = Net::HTTP.new('localhost', 17654)
|
22
|
-
resp, data = h.get("/#{__FILE__}", nil)
|
23
|
-
assert_equal 200, resp.code.to_i
|
24
|
-
assert_equal IO.read(__FILE__), data
|
25
|
-
assert_equal 'text/plain', resp['Content-Type']
|
26
|
-
# Net::HTTP includes this header in the request, so our server returns
|
27
|
-
# likewise.
|
28
|
-
assert_equal 'close', resp['Connection']
|
29
|
-
t.exit
|
30
|
-
end
|
31
|
-
end
|
data/test/spec/caching_spec.rb
DELETED
@@ -1,139 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), '../../lib/serverside')
|
2
|
-
require 'stringio'
|
3
|
-
include ServerSide::HTTP
|
4
|
-
|
5
|
-
class DummyRequest < Request
|
6
|
-
attr_accessor :socket
|
7
|
-
include Caching
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
super(StringIO.new)
|
11
|
-
@headers = {}
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
context "Caching::validate_cache" do
|
16
|
-
specify "should set etag and last-modified response headers" do
|
17
|
-
r = DummyRequest.new
|
18
|
-
t = Time.now
|
19
|
-
r.validate_cache('aaaa', t) {
|
20
|
-
r.send_response(200, 'text/plain', 'hi', nil, {'F' => 1})
|
21
|
-
}
|
22
|
-
r.socket.rewind
|
23
|
-
resp = r.socket.read
|
24
|
-
|
25
|
-
resp.should_match /ETag:\s"aaaa"\r\n/
|
26
|
-
resp.should_match /Last-Modified:\s#{t.httpdate}\r\n/
|
27
|
-
resp.should_match /F:\s1\r\n/
|
28
|
-
end
|
29
|
-
|
30
|
-
specify "should send not modified response if client includes a suitable validator" do
|
31
|
-
r = DummyRequest.new
|
32
|
-
t = Time.now
|
33
|
-
r.headers['If-None-Match'] = '"bbbb"'
|
34
|
-
r.validate_cache('bbbb', t) {raise "This should not be called"}
|
35
|
-
r.socket.rewind
|
36
|
-
resp = r.socket.read
|
37
|
-
|
38
|
-
resp.should_match /^HTTP\/1.1\s304 Not Modified\r\n/
|
39
|
-
resp.should_match /ETag:\s"bbbb"\r\n/
|
40
|
-
resp.should_match /Last-Modified:\s#{t.httpdate}\r\n/
|
41
|
-
|
42
|
-
r = DummyRequest.new
|
43
|
-
t = Time.now
|
44
|
-
r.headers['If-Modified-Since'] = t.httpdate
|
45
|
-
r.validate_cache('cccc', t) {raise "This should not be called"}
|
46
|
-
r.socket.rewind
|
47
|
-
resp = r.socket.read
|
48
|
-
|
49
|
-
resp.should_match /^HTTP\/1.1\s304 Not Modified\r\n/
|
50
|
-
resp.should_match /ETag:\s"cccc"\r\n/
|
51
|
-
resp.should_match /Last-Modified:\s#{t.httpdate}\r\n/
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
context "Caching::send_not_modified" do
|
56
|
-
specify "should send back a valid 304 response with headers" do
|
57
|
-
r = DummyRequest.new
|
58
|
-
t = Time.now
|
59
|
-
r.send_not_modified('dddd', t.httpdate, 240)
|
60
|
-
r.socket.rewind
|
61
|
-
resp = r.socket.read
|
62
|
-
|
63
|
-
resp.should_match /^HTTP\/1.1\s304 Not Modified\r\n/
|
64
|
-
resp.should_match /ETag:\s"dddd"\r\n/
|
65
|
-
resp.should_match /Last-Modified:\s#{t.httpdate}\r\n/
|
66
|
-
resp.should_match /Cache-Control:\smax-age=240\r\n/
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
context "Caching::valid_client_cache?" do
|
71
|
-
specify "should check if-none-match validator for etag" do
|
72
|
-
r = DummyRequest.new
|
73
|
-
t = Time.now
|
74
|
-
r.valid_client_cache?('eeee', t).should_be_nil
|
75
|
-
r.headers['If-None-Match'] = '"abc"'
|
76
|
-
r.valid_client_cache?('eeee', t).should_be_nil
|
77
|
-
r.headers['If-None-Match'] = '"eeee"'
|
78
|
-
r.valid_client_cache?('eeee', t).should_not_be_nil
|
79
|
-
r.headers['If-None-Match'] = '"aaa", "bbb", "ccc"'
|
80
|
-
r.valid_client_cache?('eeee', t).should_be_nil
|
81
|
-
r.headers['If-None-Match'] = '"aaa", "eeee", "ccc"'
|
82
|
-
r.valid_client_cache?('eeee', t).should_not_be_nil
|
83
|
-
end
|
84
|
-
|
85
|
-
specify "should check if-none-match validator for wildcard" do
|
86
|
-
r = DummyRequest.new
|
87
|
-
r.headers['If-None-Match'] = '*'
|
88
|
-
r.valid_client_cache?('eeee', nil).should_not_be_nil
|
89
|
-
r.headers['If-None-Match'] = '*, "aaaa"'
|
90
|
-
r.valid_client_cache?('eeee', nil).should_not_be_nil
|
91
|
-
end
|
92
|
-
|
93
|
-
specify "should check if-modified-since validator for etag" do
|
94
|
-
r = DummyRequest.new
|
95
|
-
t = Time.now
|
96
|
-
r.headers['If-Modified-Since'] = (t-1).httpdate
|
97
|
-
r.valid_client_cache?('eeee', t.httpdate).should_be false
|
98
|
-
r.headers['If-Modified-Since'] = t.httpdate
|
99
|
-
r.valid_client_cache?('eeee', t.httpdate).should_not_be false
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
context "Caching::cache_etags" do
|
104
|
-
specify "should return an empty array if no If-None-Match header is included" do
|
105
|
-
r = DummyRequest.new
|
106
|
-
r.cache_etags.should_be_a_kind_of Array
|
107
|
-
r.cache_etags.should_equal []
|
108
|
-
end
|
109
|
-
|
110
|
-
specify "should return all etags included in the If-None-Match header" do
|
111
|
-
r = DummyRequest.new
|
112
|
-
r.headers['If-None-Match'] = '*'
|
113
|
-
r.cache_etags.should_equal ['*']
|
114
|
-
r.headers['If-None-Match'] = '*, "XXX-YYY","AAA-BBB"'
|
115
|
-
r.cache_etags.should_equal ['*', 'XXX-YYY', 'AAA-BBB']
|
116
|
-
r.headers['If-None-Match'] = '"abcd-EFGH"'
|
117
|
-
r.cache_etags.should_equal ['abcd-EFGH']
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context "Caching::cache_stamps" do
|
122
|
-
specify "should return nil if no If-Modified-Since header is included" do
|
123
|
-
r = DummyRequest.new
|
124
|
-
r.cache_stamp.should_be_nil
|
125
|
-
end
|
126
|
-
|
127
|
-
specify "should return nil if no an invalid stamp is specified" do
|
128
|
-
r = DummyRequest.new
|
129
|
-
r.headers['If-Modified-Since'] = 'invalid stamp'
|
130
|
-
r.cache_stamp.should_be_nil
|
131
|
-
end
|
132
|
-
|
133
|
-
specify "should return the stamp specified in the If-Modified-Since header" do
|
134
|
-
r = DummyRequest.new
|
135
|
-
t = Time.now
|
136
|
-
r.headers['If-Modified-Since'] = t.httpdate
|
137
|
-
r.cache_stamp.to_i.should_equal t.to_i
|
138
|
-
end
|
139
|
-
end
|
data/test/test_helper.rb
DELETED
data/test/unit/cluster_test.rb
DELETED
@@ -1,129 +0,0 @@
|
|
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
|
@@ -1,48 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
-
require 'stringio'
|
3
|
-
|
4
|
-
class ConnectionTest < Test::Unit::TestCase
|
5
|
-
class ServerSide::HTTP::Connection
|
6
|
-
attr_reader :socket, :request_class, :thread
|
7
|
-
end
|
8
|
-
|
9
|
-
class DummyRequest1 < ServerSide::HTTP::Request
|
10
|
-
@@instance_count = 0
|
11
|
-
|
12
|
-
def initialize(socket)
|
13
|
-
@@instance_count += 1
|
14
|
-
super(socket)
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.instance_count
|
18
|
-
@@instance_count
|
19
|
-
end
|
20
|
-
|
21
|
-
def process
|
22
|
-
@socket[:count] ||= 0
|
23
|
-
@socket[:count] += 1
|
24
|
-
@socket[:count] < 1000
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class DummySocket < Hash
|
29
|
-
attr_accessor :closed
|
30
|
-
def close; @closed = true; end
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_new
|
34
|
-
r = ServerSide::HTTP::Connection.new('hello', ServerSide::HTTP::Request)
|
35
|
-
sleep 0.1
|
36
|
-
assert_equal 'hello', r.socket
|
37
|
-
assert_equal ServerSide::HTTP::Request, r.request_class
|
38
|
-
assert_equal false, r.thread.alive?
|
39
|
-
|
40
|
-
c = DummySocket.new
|
41
|
-
r = ServerSide::HTTP::Connection.new(c, DummyRequest1)
|
42
|
-
assert_equal DummyRequest1, r.request_class
|
43
|
-
r.thread.join
|
44
|
-
assert_equal 1000, c[:count]
|
45
|
-
assert_equal 1000, DummyRequest1.instance_count
|
46
|
-
assert_equal true, c.closed
|
47
|
-
end
|
48
|
-
end
|
data/test/unit/core_ext_test.rb
DELETED
@@ -1,46 +0,0 @@
|
|
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
|
33
|
-
|
34
|
-
class ProcTest < Test::Unit::TestCase
|
35
|
-
def test_proc_tag
|
36
|
-
l = lambda {puts "hello"}
|
37
|
-
assert_equal 'proc_' + l.object_id.to_s(36).sub('-', '_'), l.proc_tag
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
class ObjectTest < Test::Unit::TestCase
|
42
|
-
def test_const_tag
|
43
|
-
v = "mau mau"
|
44
|
-
assert_equal 'C' + v.object_id.to_s(36).upcase.sub('-', '_'), v.const_tag
|
45
|
-
end
|
46
|
-
end
|
data/test/unit/daemon_test.rb
DELETED
@@ -1,75 +0,0 @@
|
|
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
|