swiftiply 0.5.1 → 0.6.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/CONTRIBUTORS +2 -0
- data/README +1 -1
- data/bin/echo_client +26 -0
- data/bin/swiftiply +21 -8
- data/ext/fastfilereader/extconf.rb +161 -0
- data/ext/fastfilereader/mapper.cpp +200 -0
- data/ext/fastfilereader/mapper.h +59 -0
- data/ext/fastfilereader/rubymain.cpp +127 -0
- data/external/test_support.rb +13 -0
- data/setup.rb +7 -2
- data/src/fastfilereader.rb +109 -0
- data/src/swiftcore/Swiftiply.rb +432 -103
- data/src/swiftcore/Swiftiply/support_pagecache.rb +56 -0
- data/src/swiftcore/Swiftiply/swiftiply_client.rb +57 -0
- data/src/swiftcore/evented_mongrel.rb +32 -4
- data/src/swiftcore/swiftiplied_mongrel.rb +50 -38
- data/src/swiftcore/types.rb +1583 -0
- data/swiftiply.gemspec +4 -4
- data/test/TC_ProxyBag.rb +185 -0
- data/test/TC_Swiftiply.rb +458 -0
- data/test/TC_Swiftiply/mongrel/evented_hello.rb +25 -0
- data/test/TC_Swiftiply/mongrel/swiftiplied_hello.rb +25 -0
- data/test/TC_Swiftiply/mongrel/threaded_hello.rb +25 -0
- data/test/TC_Swiftiply/slow_echo_client +26 -0
- metadata +34 -121
- data/src/ramaze/adapter/evented_mongrel.rb +0 -2
- data/src/ramaze/adapter/swiftiplied_mongrel.rb +0 -2
- data/test/rails/README +0 -182
- data/test/rails/Rakefile +0 -10
- data/test/rails/app/controllers/application.rb +0 -6
- data/test/rails/app/controllers/tests_controller.rb +0 -15
- data/test/rails/app/helpers/application_helper.rb +0 -3
- data/test/rails/config/boot.rb +0 -45
- data/test/rails/config/database.yml +0 -36
- data/test/rails/config/environment.rb +0 -60
- data/test/rails/config/environments/development.rb +0 -21
- data/test/rails/config/environments/production.rb +0 -18
- data/test/rails/config/environments/production_no_caching.rb +0 -18
- data/test/rails/config/environments/test.rb +0 -19
- data/test/rails/config/routes.rb +0 -23
- data/test/rails/doc/README_FOR_APP +0 -2
- data/test/rails/observe_ram.rb +0 -10
- data/test/rails/public/404.html +0 -30
- data/test/rails/public/500.html +0 -30
- data/test/rails/public/dispatch.cgi +0 -10
- data/test/rails/public/dispatch.fcgi +0 -24
- data/test/rails/public/dispatch.rb +0 -10
- data/test/rails/public/favicon.ico +0 -0
- data/test/rails/public/images/rails.png +0 -0
- data/test/rails/public/index.html +0 -277
- data/test/rails/public/javascripts/application.js +0 -2
- data/test/rails/public/javascripts/controls.js +0 -833
- data/test/rails/public/javascripts/dragdrop.js +0 -942
- data/test/rails/public/javascripts/effects.js +0 -1088
- data/test/rails/public/javascripts/prototype.js +0 -2515
- data/test/rails/public/robots.txt +0 -1
- data/test/rails/script/about +0 -3
- data/test/rails/script/breakpointer +0 -3
- data/test/rails/script/console +0 -3
- data/test/rails/script/destroy +0 -3
- data/test/rails/script/generate +0 -3
- data/test/rails/script/performance/benchmarker +0 -3
- data/test/rails/script/performance/profiler +0 -3
- data/test/rails/script/plugin +0 -3
- data/test/rails/script/process/inspector +0 -3
- data/test/rails/script/process/reaper +0 -3
- data/test/rails/script/process/spawner +0 -3
- data/test/rails/script/runner +0 -3
- data/test/rails/script/server +0 -3
- data/test/rails/test/test_helper.rb +0 -28
- data/test/ramaze/conf/benchmark.yaml +0 -35
- data/test/ramaze/conf/debug.yaml +0 -34
- data/test/ramaze/conf/live.yaml +0 -33
- data/test/ramaze/conf/silent.yaml +0 -31
- data/test/ramaze/conf/stage.yaml +0 -33
- data/test/ramaze/main.rb +0 -18
- data/test/ramaze/public/404.jpg +0 -0
- data/test/ramaze/public/css/coderay.css +0 -105
- data/test/ramaze/public/css/ramaze_error.css +0 -42
- data/test/ramaze/public/error.zmr +0 -77
- data/test/ramaze/public/favicon.ico +0 -0
- data/test/ramaze/public/js/jquery.js +0 -1923
- data/test/ramaze/public/ramaze.png +0 -0
- data/test/ramaze/src/controller/main.rb +0 -8
- data/test/ramaze/src/element/page.rb +0 -17
- data/test/ramaze/src/model.rb +0 -6
- data/test/ramaze/template/index.xhtml +0 -6
- data/test/ramaze/yaml.db +0 -0
data/swiftiply.gemspec
CHANGED
@@ -11,20 +11,20 @@ spec = Gem::Specification.new do |s|
|
|
11
11
|
s.name = 'swiftiply'
|
12
12
|
s.author = %q(Kirk Haines)
|
13
13
|
s.email = %q(wyhaines@gmail.com)
|
14
|
-
s.version = '0.
|
14
|
+
s.version = '0.6.0'
|
15
15
|
s.summary = %q(A fast clustering proxy for web applications.)
|
16
16
|
s.platform = Gem::Platform::RUBY
|
17
17
|
|
18
18
|
s.has_rdoc = true
|
19
19
|
s.rdoc_options = %w(--title Swiftcore::Swiftiply --main README --line-numbers)
|
20
20
|
s.extra_rdoc_files = %w(README)
|
21
|
-
|
21
|
+
s.extensions << 'ext/fastfilereader/extconf.rb'
|
22
22
|
s.files = Dir['**/*']
|
23
23
|
s.executables = %w(swiftiply mongrel_rails swiftiply_mongrel_rails)
|
24
24
|
s.require_paths = %w(src)
|
25
25
|
|
26
|
-
s.requirements << "Eventmachine 0.
|
27
|
-
s.add_dependency('eventmachine')
|
26
|
+
s.requirements << "Eventmachine 0.8.1 or higher."
|
27
|
+
s.add_dependency('eventmachine','>= 0.8.1')
|
28
28
|
s.test_files = []
|
29
29
|
|
30
30
|
s.rubyforge_project = %q(swiftiply)
|
data/test/TC_ProxyBag.rb
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'external/test_support'
|
3
|
+
SwiftcoreTestSupport.set_src_dir
|
4
|
+
require 'rbconfig'
|
5
|
+
require 'net/http'
|
6
|
+
require 'swiftcore/Swiftiply'
|
7
|
+
require 'yaml'
|
8
|
+
|
9
|
+
class TC_ProxyBag < Test::Unit::TestCase
|
10
|
+
@@testdir = SwiftcoreTestSupport.test_dir(__FILE__)
|
11
|
+
Ruby = File.join(::Config::CONFIG['bindir'],::Config::CONFIG['ruby_install_name']) << ::Config::CONFIG['EXEEXT']
|
12
|
+
|
13
|
+
DeleteQueue = []
|
14
|
+
KillQueue = []
|
15
|
+
|
16
|
+
ConfBase = YAML.load(<<ECONF)
|
17
|
+
cluster_address: 127.0.0.1
|
18
|
+
cluster_port: 29998
|
19
|
+
daemonize: false
|
20
|
+
map:
|
21
|
+
- incoming:
|
22
|
+
- 127.0.0.1
|
23
|
+
outgoing: 127.0.0.1:29999
|
24
|
+
docroot: #{@@testdir}/TC_ProxyBag/test_serve_static_file
|
25
|
+
default: true
|
26
|
+
redeployable: false
|
27
|
+
ECONF
|
28
|
+
|
29
|
+
def get_url(hostname,port,url)
|
30
|
+
Net::HTTP.start(hostname,port) {|http| http.get(url)}
|
31
|
+
end
|
32
|
+
|
33
|
+
def post_url(hostname,port,url,data = nil)
|
34
|
+
Net::HTTP.start(hostname,port) {|http| http.post(url,data)}
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete_url(hostname,port,url)
|
38
|
+
Net::HTTP.start(hostname,port) {|http| http.delete(url)}
|
39
|
+
end
|
40
|
+
|
41
|
+
def setup
|
42
|
+
Dir.chdir(@@testdir)
|
43
|
+
SwiftcoreTestSupport.announce(:proxybag,"ProxyBag")
|
44
|
+
end
|
45
|
+
|
46
|
+
def teardown
|
47
|
+
while f = DeleteQueue.pop do
|
48
|
+
File.delete f if f
|
49
|
+
end
|
50
|
+
|
51
|
+
while p = KillQueue.pop do
|
52
|
+
Process.kill("SIGKILL",p) if p
|
53
|
+
Process.wait p if p
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_update_ctime
|
58
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
59
|
+
t = pb.update_ctime
|
60
|
+
assert_instance_of(Time,t)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_now
|
64
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
65
|
+
n = pb.update_ctime
|
66
|
+
assert_instance_of(Time,pb.now)
|
67
|
+
assert_equal(n,pb.now)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_set_key
|
71
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
72
|
+
assert_nothing_raised do
|
73
|
+
pb.set_key(:a,'abc')
|
74
|
+
end
|
75
|
+
assert_equal('abc',pb.instance_variable_get('@keys')[:a])
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_get_key
|
79
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
80
|
+
assert_nothing_raised do
|
81
|
+
pb.set_key(:b,'def')
|
82
|
+
end
|
83
|
+
assert_equal('def',pb.get_key(:b))
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_add_id
|
87
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
88
|
+
assert_nothing_raised do
|
89
|
+
pb.add_id(:abcdef,12345)
|
90
|
+
end
|
91
|
+
assert_equal(12345,pb.instance_variable_get('@id_map')[:abcdef])
|
92
|
+
assert_equal(:abcdef,pb.instance_variable_get('@reverse_id_map')[12345])
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_remove_id
|
96
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
97
|
+
assert_nothing_raised do
|
98
|
+
pb.remove_id(:abcdef)
|
99
|
+
end
|
100
|
+
assert_nil(pb.instance_variable_get('@id_map')[:abcdef])
|
101
|
+
assert_nil(pb.instance_variable_get('@reverse_id_map')[12345])
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_add_incoming_mapping
|
105
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
106
|
+
assert_nothing_raised do
|
107
|
+
pb.add_incoming_mapping(:abcdef,12345)
|
108
|
+
end
|
109
|
+
assert_equal(:abcdef,pb.instance_variable_get('@incoming_map')[12345])
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_remove_incoming_mapping
|
113
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
114
|
+
assert_nothing_raised do
|
115
|
+
pb.remove_incoming_mapping(12345)
|
116
|
+
end
|
117
|
+
assert_nil(pb.instance_variable_get('@incoming_map')[12345])
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_add_incoming_docroot
|
121
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
122
|
+
assert_nothing_raised do
|
123
|
+
pb.add_incoming_docroot('/abc/123',:abcdef)
|
124
|
+
end
|
125
|
+
assert_equal('/abc/123',pb.instance_variable_get('@docroot_map')[:abcdef])
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_remove_incoming_docroot
|
129
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
130
|
+
assert_nothing_raised do
|
131
|
+
pb.remove_incoming_docroot(:abcdef)
|
132
|
+
end
|
133
|
+
assert_nil(pb.instance_variable_get('@docroot_map')[:abcdef])
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_add_incoming_redeployable
|
137
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
138
|
+
assert_nothing_raised do
|
139
|
+
pb.add_incoming_redeployable(16384,:abcdef)
|
140
|
+
end
|
141
|
+
assert_equal(16384,pb.instance_variable_get('@redeployable_map')[:abcdef])
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_remove_incoming_redeployable
|
145
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
146
|
+
assert_nothing_raised do
|
147
|
+
pb.remove_incoming_redeployable(:abcdef)
|
148
|
+
end
|
149
|
+
assert_nil(pb.instance_variable_get('@redeployable_map')[:abcdef])
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_add_log
|
153
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
154
|
+
assert_nothing_raised do
|
155
|
+
pb.add_log('/foo/bar',:abcdef)
|
156
|
+
end
|
157
|
+
assert_equal('/foo/bar',pb.instance_variable_get('@log_map')[:abcdef])
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_default_name
|
161
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
162
|
+
assert_nothing_raised do
|
163
|
+
pb.default_name = 'test'
|
164
|
+
end
|
165
|
+
assert_equal('test',pb.instance_variable_get('@default_name'))
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_server_unavailable_timeout
|
169
|
+
pb = Swiftcore::Swiftiply::ProxyBag
|
170
|
+
assert_nothing_raised do
|
171
|
+
pb.server_unavailable_timeout = 3
|
172
|
+
end
|
173
|
+
assert_equal(3,pb.instance_variable_get('@server_unavailable_timeout'))
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_find_static_file
|
177
|
+
dr = Dir.pwd
|
178
|
+
path_info = "testfile#{Time.now.to_i}"
|
179
|
+
File.open(path_info,'w') {|fh| fh.puts "alfalfa leafcutter bee"}
|
180
|
+
assert_equal(File.join(dr,path_info),Swiftcore::Swiftiply::ProxyBag.find_static_file(dr,path_info,'foo'))
|
181
|
+
assert_nil(Swiftcore::Swiftiply::ProxyBag.find_static_file(dr,'xyzzy','foo'))
|
182
|
+
File.delete(path_info)
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
@@ -0,0 +1,458 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'external/test_support'
|
3
|
+
SwiftcoreTestSupport.set_src_dir
|
4
|
+
require 'rbconfig'
|
5
|
+
require 'net/http'
|
6
|
+
require 'swiftcore/Swiftiply'
|
7
|
+
require 'yaml'
|
8
|
+
|
9
|
+
class TC_Swiftiply < Test::Unit::TestCase
|
10
|
+
@@testdir = SwiftcoreTestSupport.test_dir(__FILE__)
|
11
|
+
Ruby = File.join(::Config::CONFIG['bindir'],::Config::CONFIG['ruby_install_name']) << ::Config::CONFIG['EXEEXT']
|
12
|
+
|
13
|
+
DeleteQueue = []
|
14
|
+
KillQueue = []
|
15
|
+
|
16
|
+
ConfBase = YAML.load(<<ECONF)
|
17
|
+
cluster_address: 127.0.0.1
|
18
|
+
cluster_port: 29998
|
19
|
+
daemonize: false
|
20
|
+
map:
|
21
|
+
- incoming:
|
22
|
+
- 127.0.0.1
|
23
|
+
outgoing: 127.0.0.1:29999
|
24
|
+
docroot: #{@@testdir}/TC_Swiftiply/test_serve_static_file
|
25
|
+
default: true
|
26
|
+
redeployable: false
|
27
|
+
ECONF
|
28
|
+
|
29
|
+
def get_url(hostname,port,url)
|
30
|
+
Net::HTTP.start(hostname,port) {|http| http.get(url)}
|
31
|
+
end
|
32
|
+
|
33
|
+
def post_url(hostname,port,url,data = nil)
|
34
|
+
Net::HTTP.start(hostname,port) {|http| http.post(url,data)}
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete_url(hostname,port,url)
|
38
|
+
Net::HTTP.start(hostname,port) {|http| http.delete(url)}
|
39
|
+
end
|
40
|
+
|
41
|
+
def setup
|
42
|
+
Dir.chdir(@@testdir)
|
43
|
+
SwiftcoreTestSupport.announce(:swiftiply_functional,"Functional Swiftiply Testing")
|
44
|
+
end
|
45
|
+
|
46
|
+
def teardown
|
47
|
+
while f = DeleteQueue.pop do
|
48
|
+
File.delete f if f
|
49
|
+
end
|
50
|
+
|
51
|
+
while p = KillQueue.pop do
|
52
|
+
Process.kill("SIGKILL",p) if p
|
53
|
+
Process.wait p if p
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Test serving a small file (no chunked encoding) and a large file (chunked
|
58
|
+
# encoding).
|
59
|
+
|
60
|
+
def test_serve_static_file
|
61
|
+
puts "\nTesting Static File Delivery"
|
62
|
+
dc = File.join(Dir.pwd,'TC_Swiftiply')
|
63
|
+
dr = File.join(dc,'test_serve_static_file')
|
64
|
+
|
65
|
+
smallfile_name = "smallfile#{Time.now.to_i}"
|
66
|
+
smallfile_path = File.join(dr,smallfile_name)
|
67
|
+
File.open(smallfile_path,'w') {|fh| fh.puts "alfalfa leafcutter bee"}
|
68
|
+
DeleteQueue << smallfile_path
|
69
|
+
|
70
|
+
bigfile_name = "bigfile#{Time.now.to_i}"
|
71
|
+
bigfile_path = File.join(dr,bigfile_name)
|
72
|
+
File.open(bigfile_path,'w+') {|fh| fh.write("#{'I am a duck. ' * 6}\n" * 1000)}
|
73
|
+
DeleteQueue << bigfile_path
|
74
|
+
|
75
|
+
conf_file = File.join(dc,'test_serve_static_file.conf')
|
76
|
+
File.open(conf_file,'w+') {|fh| fh.write ConfBase.to_yaml}
|
77
|
+
DeleteQueue << conf_file
|
78
|
+
|
79
|
+
assert_nothing_raised("setup failed") do
|
80
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
81
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/swiftiply -c test_serve_static_file.conf"])
|
82
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
83
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/echo_client 127.0.0.1:29999"])
|
84
|
+
# Make sure everything has time to start, connect, etc... before
|
85
|
+
# the tests are executed.
|
86
|
+
sleep 1
|
87
|
+
end
|
88
|
+
|
89
|
+
response = get_url('127.0.0.1',29998,smallfile_name)
|
90
|
+
assert_equal("alfalfa leafcutter bee\n",response.body)
|
91
|
+
|
92
|
+
response = get_url('127.0.0.1',29998,bigfile_name)
|
93
|
+
assert_equal("I am a duck. I am a duck. ",response.body[0..25])
|
94
|
+
assert_equal("I am a duck. \n",response.body[-14..-1])
|
95
|
+
assert_equal(79000,response.body.length)
|
96
|
+
|
97
|
+
# Hit it a bunch of times.
|
98
|
+
|
99
|
+
ab = `which ab`.chomp
|
100
|
+
unless ab == ''
|
101
|
+
r = `#{ab} -n 10000 -c 25 http://127.0.0.1:29998/#{smallfile_name}`
|
102
|
+
r =~ /^(Requests per second.*)$/
|
103
|
+
puts "10k files, concurrency of 25\n#{$1}"
|
104
|
+
end
|
105
|
+
|
106
|
+
# And it is still correct?
|
107
|
+
response = get_url('127.0.0.1',29998,smallfile_name)
|
108
|
+
assert_equal("alfalfa leafcutter bee\n",response.body)
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_serve_static_file_from_cachedir
|
112
|
+
puts "\nTesting Static File Delivery From Cachedir"
|
113
|
+
dc = File.join(Dir.pwd,'TC_Swiftiply')
|
114
|
+
dr = File.join(dc,'test_serve_static_file_from_cachedir')
|
115
|
+
|
116
|
+
smallfile_name = "smallfile#{Time.now.to_i}"
|
117
|
+
smallfile_path = File.join(dr,'public',smallfile_name)
|
118
|
+
File.open(smallfile_path,'w') {|fh| fh.puts "alfalfa leafcutter bee"}
|
119
|
+
DeleteQueue << smallfile_path
|
120
|
+
|
121
|
+
smallfile_name2 = "smallfile2#{Time.now.to_i}"
|
122
|
+
smallfile_path2 = File.join(dr,'public',smallfile_name2)
|
123
|
+
File.open("#{smallfile_path2}.htm",'w') {|fh| fh.puts "alfalfa leafcutter bee"}
|
124
|
+
DeleteQueue << "#{smallfile_path2}.htm"
|
125
|
+
|
126
|
+
smallfile_name3 = "smallfile3#{Time.now.to_i}"
|
127
|
+
smallfile_path3 = File.join(dr,'public',smallfile_name3)
|
128
|
+
File.open("#{smallfile_path3}.cgi",'w') {|fh| fh.puts "alfalfa leafcutter bee"}
|
129
|
+
DeleteQueue << "#{smallfile_path3}.cgi"
|
130
|
+
|
131
|
+
bigfile_name = "bigfile#{Time.now.to_i}"
|
132
|
+
bigfile_path = File.join(dr,'public',bigfile_name)
|
133
|
+
File.open("#{bigfile_path}.html",'w+') {|fh| fh.write("#{'I am a duck. ' * 6}\n" * 1000)}
|
134
|
+
DeleteQueue << "#{bigfile_path}.html"
|
135
|
+
|
136
|
+
conf_file = File.join(dc,'test_serve_static_file_from_cachedir.conf')
|
137
|
+
File.open(conf_file,'w+') do |fh|
|
138
|
+
conf = YAML.load(ConfBase.to_yaml)
|
139
|
+
conf['map'].first['docroot'] = 'test_serve_static_file_from_cachedir'
|
140
|
+
conf['map'].first['cache_directory'] = 'public'
|
141
|
+
conf['map'].first['cache_extensions'] = ['html','htm','cgi']
|
142
|
+
fh.write conf.to_yaml
|
143
|
+
end
|
144
|
+
DeleteQueue << conf_file
|
145
|
+
|
146
|
+
assert_nothing_raised("setup failed") do
|
147
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
148
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/swiftiply -c test_serve_static_file_from_cachedir.conf"])
|
149
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
150
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/echo_client 127.0.0.1:29999"])
|
151
|
+
# Make sure everything has time to start, connect, etc... before
|
152
|
+
# the tests are executed.
|
153
|
+
sleep 1
|
154
|
+
end
|
155
|
+
|
156
|
+
response = get_url('127.0.0.1',29998,smallfile_name)
|
157
|
+
assert_equal("alfalfa leafcutter bee\n",response.body)
|
158
|
+
|
159
|
+
response = get_url('127.0.0.1',29998,bigfile_name)
|
160
|
+
assert_equal("I am a duck. I am a duck. ",response.body[0..25])
|
161
|
+
assert_equal("I am a duck. \n",response.body[-14..-1])
|
162
|
+
assert_equal(79000,response.body.length)
|
163
|
+
|
164
|
+
response = get_url('127.0.0.1',29998,smallfile_name2)
|
165
|
+
assert_equal("alfalfa leafcutter bee\n",response.body)
|
166
|
+
|
167
|
+
response = get_url('127.0.0.1',29998,smallfile_name3)
|
168
|
+
assert_equal("alfalfa leafcutter bee\n",response.body)
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
# Test a vanilla proxy configuration with multiple verbs.
|
173
|
+
|
174
|
+
def test_serve_normal_proxy
|
175
|
+
puts "\nTesting Normal Proxy Action"
|
176
|
+
dc = File.join(Dir.pwd,'TC_Swiftiply')
|
177
|
+
dr = File.join(dc,'test_serve_normal_proxy')
|
178
|
+
|
179
|
+
conf_file = File.join(dc,'test_serve_normal_proxy.conf')
|
180
|
+
File.open(conf_file,'w+') {|fh| fh.write ConfBase.to_yaml}
|
181
|
+
DeleteQueue << conf_file
|
182
|
+
|
183
|
+
assert_nothing_raised("setup failed") do
|
184
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
185
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/swiftiply -c test_serve_normal_proxy.conf"])
|
186
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
187
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/echo_client 127.0.0.1:29999"])
|
188
|
+
sleep 1
|
189
|
+
end
|
190
|
+
|
191
|
+
# Normal request
|
192
|
+
response = get_url('127.0.0.1',29998,'/xyzzy')
|
193
|
+
assert_equal("GET /xyzzy HTTP/1.1\r\nAccept: */*\r\nHost: 127.0.0.1:29998\r\n\r\n",response.body)
|
194
|
+
|
195
|
+
# With query string params.
|
196
|
+
response = get_url('127.0.0.1',29998,'/foo/bar/bam?Q=1234')
|
197
|
+
assert_equal("GET /foo/bar/bam?Q=1234 HTTP/1.1\r\nAccept: */*\r\nHost: 127.0.0.1:29998\r\n\r\n",response.body)
|
198
|
+
|
199
|
+
# POST request
|
200
|
+
response = post_url('127.0.0.1',29998,'/xyzzy')
|
201
|
+
assert_equal("POST /xyzzy HTTP/1.1\r\nAccept: */*\r\nHost: 127.0.0.1:29998\r\n\r\n",response.body)
|
202
|
+
|
203
|
+
# And another verb; different verbs should be irrelevant
|
204
|
+
response = delete_url('127.0.0.1',29998,'/xyzzy')
|
205
|
+
assert_equal("DELETE /xyzzy HTTP/1.1\r\nAccept: */*\r\n",response.body[0..36])
|
206
|
+
|
207
|
+
# A non-matching hostname, to trigger default handling
|
208
|
+
response = get_url('localhost',29998,'/xyzzy')
|
209
|
+
assert_equal("GET /xyzzy HTTP/1.1\r\nAccept: */*\r\nHost: localhost:29998\r\n\r\n",response.body)
|
210
|
+
end
|
211
|
+
|
212
|
+
# Test redeployable requests.
|
213
|
+
|
214
|
+
def test_redeployable
|
215
|
+
puts "\nTesting Redeployable Requests"
|
216
|
+
dc = File.join(Dir.pwd,'TC_Swiftiply')
|
217
|
+
dr = File.join(dc,'test_redeployable')
|
218
|
+
|
219
|
+
conf_file = File.join(dc,'test_redeployable.conf')
|
220
|
+
File.open(conf_file,'w+') do |fh|
|
221
|
+
conf = YAML.load(ConfBase.to_yaml)
|
222
|
+
conf['map'].first['redeployable'] = 'true'
|
223
|
+
fh.write conf.to_yaml
|
224
|
+
end
|
225
|
+
DeleteQueue << conf_file
|
226
|
+
|
227
|
+
secpid = nil
|
228
|
+
assert_nothing_raised("setup failed") do
|
229
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
230
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/swiftiply -c test_redeployable.conf"])
|
231
|
+
secpid = SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
232
|
+
:cmd => ["#{Ruby} -I../../src slow_echo_client 127.0.0.1:29999"])
|
233
|
+
sleep 1
|
234
|
+
end
|
235
|
+
|
236
|
+
response = nil
|
237
|
+
urlthread = Thread.start {response = get_url('127.0.0.1',29998,'/slo_gin_fizz')}
|
238
|
+
|
239
|
+
sleep 1
|
240
|
+
|
241
|
+
Process.kill "SIGKILL",secpid
|
242
|
+
secpid = nil
|
243
|
+
assert_nothing_raised("setup failed") do
|
244
|
+
|
245
|
+
secpid = SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
246
|
+
:cmd => ["#{Ruby} -I../../src slow_echo_client 127.0.0.1:29999"])
|
247
|
+
end
|
248
|
+
|
249
|
+
urlthread.join
|
250
|
+
assert_equal("GET /slo_gin_fizz HTTP/1.1\r\nAccept: */*\r\nHost: 127.0.0.1:29998\r\n\r\n",response.body)
|
251
|
+
|
252
|
+
sleep 1
|
253
|
+
|
254
|
+
bigdata = 'x' * 69990
|
255
|
+
bigdata << 'y' * 10
|
256
|
+
response = nil
|
257
|
+
|
258
|
+
# First, make sure that an ininterrupted request of this size is handled.
|
259
|
+
|
260
|
+
assert_nothing_raised do
|
261
|
+
response = post_url('127.0.0.1',29998,'/slo_gin_fizz',bigdata)
|
262
|
+
end
|
263
|
+
|
264
|
+
response.body =~ /(xxxxx*)/
|
265
|
+
xs_len = $1.length
|
266
|
+
response.body =~ /(yyyyy*)/
|
267
|
+
ys_len = $1.length
|
268
|
+
assert_equal(69990,xs_len)
|
269
|
+
assert_equal(10,ys_len)
|
270
|
+
|
271
|
+
# Now do the interrupted request.
|
272
|
+
|
273
|
+
sleep 1
|
274
|
+
|
275
|
+
urlthread = Thread.start {response = post_url('127.0.0.1',29998,'/slo_gin_fizz',bigdata)}
|
276
|
+
|
277
|
+
sleep 1
|
278
|
+
|
279
|
+
Process.kill "SIGKILL",secpid
|
280
|
+
secpid = nil
|
281
|
+
assert_nothing_raised("setup failed") do
|
282
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
283
|
+
:cmd => ["#{Ruby} -I../../src slow_echo_client 127.0.0.1:29999"])
|
284
|
+
end
|
285
|
+
|
286
|
+
assert_raise(EOFError) do
|
287
|
+
# Net::HTTP should have blown up trying to get a result. The
|
288
|
+
# request was too big to be redeployed, so the connection should
|
289
|
+
# have been dropped with nothing returned.
|
290
|
+
urlthread.join
|
291
|
+
end
|
292
|
+
ensure
|
293
|
+
Process.kill("SIGKILL",secpid) if secpid
|
294
|
+
end
|
295
|
+
|
296
|
+
def test_serve_normal_proxy_with_authentication
|
297
|
+
puts "\nTesting Normal Proxy Action With Backend Authentication"
|
298
|
+
dc = File.join(Dir.pwd,'TC_Swiftiply')
|
299
|
+
dr = File.join(dc,'test_serve_normal_proxy_with_authentication')
|
300
|
+
|
301
|
+
conf_file = File.join(dc,'test_serve_normal_proxy_with_authentication.conf')
|
302
|
+
File.open(conf_file,'w+') do |fh|
|
303
|
+
conf = YAML.load(ConfBase.to_yaml)
|
304
|
+
conf['map'].first['key'] = 'abcdef1234'
|
305
|
+
fh.write conf.to_yaml
|
306
|
+
end
|
307
|
+
DeleteQueue << conf_file
|
308
|
+
|
309
|
+
assert_nothing_raised("setup failed") do
|
310
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
311
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/swiftiply -c test_serve_normal_proxy_with_authentication.conf"])
|
312
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
313
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/echo_client 127.0.0.1:29999 abcdef1234"])
|
314
|
+
sleep 1
|
315
|
+
end
|
316
|
+
|
317
|
+
# Normal request
|
318
|
+
response = get_url('127.0.0.1',29998,'/xyzzy')
|
319
|
+
assert_equal("GET /xyzzy HTTP/1.1\r\nAccept: */*\r\nHost: 127.0.0.1:29998\r\n\r\n",response.body)
|
320
|
+
end
|
321
|
+
|
322
|
+
def test_sensible_error1
|
323
|
+
puts "\n---------------------------------"
|
324
|
+
puts "| Raising an error; this is OK! |"
|
325
|
+
puts "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
|
326
|
+
sleep 1
|
327
|
+
|
328
|
+
dc = File.join(Dir.pwd,'TC_Swiftiply')
|
329
|
+
dr = dc
|
330
|
+
|
331
|
+
conf_file = File.join(dc,'test_sensible_error1.conf')
|
332
|
+
File.open(conf_file,'w+') {|fh| fh.write ConfBase.to_yaml }
|
333
|
+
DeleteQueue << conf_file
|
334
|
+
|
335
|
+
assert_nothing_raised("setup failed") do
|
336
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
337
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/swiftiply -c test_sensible_error1.conf"])
|
338
|
+
sleep 1
|
339
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
340
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/swiftiply -c test_sensible_error1.conf"])
|
341
|
+
sleep 1
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
def test_evented_mongrel
|
346
|
+
puts "\nTesting Evented Mongrel"
|
347
|
+
|
348
|
+
assert_nothing_raised("setup failed") do
|
349
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => File.join('TC_Swiftiply','mongrel'),
|
350
|
+
:cmd => ["#{Ruby} -I../../../src evented_hello.rb"])
|
351
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => File.join('TC_Swiftiply','mongrel'),
|
352
|
+
:cmd => ["#{Ruby} -I../../../src threaded_hello.rb"])
|
353
|
+
end
|
354
|
+
|
355
|
+
sleep 1
|
356
|
+
|
357
|
+
response = get_url('127.0.0.1',29998,'/hello')
|
358
|
+
assert_equal("hello!\n",response.body)
|
359
|
+
|
360
|
+
response = get_url('127.0.0.1',29998,'/dir')
|
361
|
+
assert_equal("<html><head><title>Directory Listing",response.body[0..35])
|
362
|
+
|
363
|
+
ab = `which ab`.chomp
|
364
|
+
unless ab == ''
|
365
|
+
puts "\nThreaded Mongrel..."
|
366
|
+
rt = `#{ab} -n 10000 -c 25 http://127.0.0.1:29997/hello`
|
367
|
+
rt =~ /^(Requests per second.*)$/
|
368
|
+
rts = $1
|
369
|
+
puts "\nEvented Mongrel..."
|
370
|
+
re = `#{ab} -n 10000 -c 25 http://127.0.0.1:29998/hello`
|
371
|
+
re =~ /^(Requests per second.*)$/
|
372
|
+
res = $1
|
373
|
+
puts "\nThreaded Mongrel, no proxies, concurrency of 25\n#{rts}"
|
374
|
+
puts "Evented Mongrel, no proxies, concurrency of 25\n#{res}"
|
375
|
+
sleep 1
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
def test_swiftiplied_mongrel
|
380
|
+
puts "\nTesting Swiftiplied Mongrel"
|
381
|
+
|
382
|
+
dc = File.join(Dir.pwd,'TC_Swiftiply')
|
383
|
+
dr = File.join(dc,'test_serve_normal_proxy')
|
384
|
+
|
385
|
+
conf_file = File.join(dc,'test_serve_mongrel.conf')
|
386
|
+
File.open(conf_file,'w+') {|fh| fh.write ConfBase.to_yaml}
|
387
|
+
DeleteQueue << conf_file
|
388
|
+
|
389
|
+
assert_nothing_raised("setup failed") do
|
390
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
391
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/swiftiply -c test_serve_mongrel.conf"])
|
392
|
+
sleep 1
|
393
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => File.join('TC_Swiftiply','mongrel'),
|
394
|
+
:cmd => ["#{Ruby} -I../../../src swiftiplied_hello.rb"])
|
395
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => File.join('TC_Swiftiply','mongrel'),
|
396
|
+
:cmd => ["#{Ruby} -I../../../src swiftiplied_hello.rb"])
|
397
|
+
sleep 1
|
398
|
+
end
|
399
|
+
|
400
|
+
response = get_url('127.0.0.1',29998,'/hello')
|
401
|
+
assert_equal("hello!\n",response.body)
|
402
|
+
|
403
|
+
response = get_url('127.0.0.1',29998,'/dir')
|
404
|
+
assert_equal("<html><head><title>Directory Listing",response.body[0..35])
|
405
|
+
|
406
|
+
ab = `which ab`.chomp
|
407
|
+
unless ab == ''
|
408
|
+
r = `#{ab} -n 10000 -c 25 http://127.0.0.1:29998/hello`
|
409
|
+
r =~ /^(Requests per second.*)$/
|
410
|
+
puts "Swiftiply -> Swiftiplied Mongrel, concurrency of 25\n#{$1}"
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
414
|
+
def test_HUP
|
415
|
+
puts "\nTesting HUP handling"
|
416
|
+
dc = File.join(Dir.pwd,'TC_Swiftiply')
|
417
|
+
dr = File.join(dc,'test_serve_static_file')
|
418
|
+
|
419
|
+
conf_file = File.join(dc,'test_HUP.conf')
|
420
|
+
File.open(conf_file,'w+') do |fh|
|
421
|
+
conf = YAML.load(ConfBase.to_yaml)
|
422
|
+
conf['map'].first.delete('docroot')
|
423
|
+
fh.write conf.to_yaml
|
424
|
+
end
|
425
|
+
DeleteQueue << conf_file
|
426
|
+
|
427
|
+
smallfile_name = "xyzzy"
|
428
|
+
smallfile_path = File.join(dr,smallfile_name)
|
429
|
+
File.open(smallfile_path,'w') {|fh| fh.puts "alfalfa leafcutter bee"}
|
430
|
+
DeleteQueue << smallfile_path
|
431
|
+
|
432
|
+
swiftiply_pid = nil
|
433
|
+
assert_nothing_raised("setup failed") do
|
434
|
+
KillQueue << swiftiply_pid = SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
435
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/swiftiply -c test_HUP.conf"])
|
436
|
+
KillQueue << SwiftcoreTestSupport::create_process(:dir => 'TC_Swiftiply',
|
437
|
+
:cmd => ["#{Ruby} -I../../src ../../bin/echo_client 127.0.0.1:29999"])
|
438
|
+
sleep 1
|
439
|
+
end
|
440
|
+
|
441
|
+
# Normal request for a sanity check.
|
442
|
+
response = get_url('127.0.0.1',29998,'/xyzzy')
|
443
|
+
assert_equal("GET /xyzzy HTTP/1.1\r\nAccept: */*\r\nHost: 127.0.0.1:29998\r\n\r\n",response.body)
|
444
|
+
|
445
|
+
# Now rewrite the conf file to be a little different.
|
446
|
+
File.open(conf_file,'w+') {|fh| fh.write ConfBase.to_yaml }
|
447
|
+
|
448
|
+
# Reload the config
|
449
|
+
Process.kill 'SIGHUP',swiftiply_pid
|
450
|
+
|
451
|
+
# This request should pull the file from the docroot, since it the
|
452
|
+
# docroot was not deleted from the config that was just read.
|
453
|
+
response = get_url('127.0.0.1',29998,'/xyzzy')
|
454
|
+
|
455
|
+
assert_equal("alfalfa leafcutter bee\n",response.body)
|
456
|
+
end
|
457
|
+
|
458
|
+
end
|