serverside 0.2.9 → 0.3.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/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
|