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.
Files changed (88) hide show
  1. data/CONTRIBUTORS +2 -0
  2. data/README +1 -1
  3. data/bin/echo_client +26 -0
  4. data/bin/swiftiply +21 -8
  5. data/ext/fastfilereader/extconf.rb +161 -0
  6. data/ext/fastfilereader/mapper.cpp +200 -0
  7. data/ext/fastfilereader/mapper.h +59 -0
  8. data/ext/fastfilereader/rubymain.cpp +127 -0
  9. data/external/test_support.rb +13 -0
  10. data/setup.rb +7 -2
  11. data/src/fastfilereader.rb +109 -0
  12. data/src/swiftcore/Swiftiply.rb +432 -103
  13. data/src/swiftcore/Swiftiply/support_pagecache.rb +56 -0
  14. data/src/swiftcore/Swiftiply/swiftiply_client.rb +57 -0
  15. data/src/swiftcore/evented_mongrel.rb +32 -4
  16. data/src/swiftcore/swiftiplied_mongrel.rb +50 -38
  17. data/src/swiftcore/types.rb +1583 -0
  18. data/swiftiply.gemspec +4 -4
  19. data/test/TC_ProxyBag.rb +185 -0
  20. data/test/TC_Swiftiply.rb +458 -0
  21. data/test/TC_Swiftiply/mongrel/evented_hello.rb +25 -0
  22. data/test/TC_Swiftiply/mongrel/swiftiplied_hello.rb +25 -0
  23. data/test/TC_Swiftiply/mongrel/threaded_hello.rb +25 -0
  24. data/test/TC_Swiftiply/slow_echo_client +26 -0
  25. metadata +34 -121
  26. data/src/ramaze/adapter/evented_mongrel.rb +0 -2
  27. data/src/ramaze/adapter/swiftiplied_mongrel.rb +0 -2
  28. data/test/rails/README +0 -182
  29. data/test/rails/Rakefile +0 -10
  30. data/test/rails/app/controllers/application.rb +0 -6
  31. data/test/rails/app/controllers/tests_controller.rb +0 -15
  32. data/test/rails/app/helpers/application_helper.rb +0 -3
  33. data/test/rails/config/boot.rb +0 -45
  34. data/test/rails/config/database.yml +0 -36
  35. data/test/rails/config/environment.rb +0 -60
  36. data/test/rails/config/environments/development.rb +0 -21
  37. data/test/rails/config/environments/production.rb +0 -18
  38. data/test/rails/config/environments/production_no_caching.rb +0 -18
  39. data/test/rails/config/environments/test.rb +0 -19
  40. data/test/rails/config/routes.rb +0 -23
  41. data/test/rails/doc/README_FOR_APP +0 -2
  42. data/test/rails/observe_ram.rb +0 -10
  43. data/test/rails/public/404.html +0 -30
  44. data/test/rails/public/500.html +0 -30
  45. data/test/rails/public/dispatch.cgi +0 -10
  46. data/test/rails/public/dispatch.fcgi +0 -24
  47. data/test/rails/public/dispatch.rb +0 -10
  48. data/test/rails/public/favicon.ico +0 -0
  49. data/test/rails/public/images/rails.png +0 -0
  50. data/test/rails/public/index.html +0 -277
  51. data/test/rails/public/javascripts/application.js +0 -2
  52. data/test/rails/public/javascripts/controls.js +0 -833
  53. data/test/rails/public/javascripts/dragdrop.js +0 -942
  54. data/test/rails/public/javascripts/effects.js +0 -1088
  55. data/test/rails/public/javascripts/prototype.js +0 -2515
  56. data/test/rails/public/robots.txt +0 -1
  57. data/test/rails/script/about +0 -3
  58. data/test/rails/script/breakpointer +0 -3
  59. data/test/rails/script/console +0 -3
  60. data/test/rails/script/destroy +0 -3
  61. data/test/rails/script/generate +0 -3
  62. data/test/rails/script/performance/benchmarker +0 -3
  63. data/test/rails/script/performance/profiler +0 -3
  64. data/test/rails/script/plugin +0 -3
  65. data/test/rails/script/process/inspector +0 -3
  66. data/test/rails/script/process/reaper +0 -3
  67. data/test/rails/script/process/spawner +0 -3
  68. data/test/rails/script/runner +0 -3
  69. data/test/rails/script/server +0 -3
  70. data/test/rails/test/test_helper.rb +0 -28
  71. data/test/ramaze/conf/benchmark.yaml +0 -35
  72. data/test/ramaze/conf/debug.yaml +0 -34
  73. data/test/ramaze/conf/live.yaml +0 -33
  74. data/test/ramaze/conf/silent.yaml +0 -31
  75. data/test/ramaze/conf/stage.yaml +0 -33
  76. data/test/ramaze/main.rb +0 -18
  77. data/test/ramaze/public/404.jpg +0 -0
  78. data/test/ramaze/public/css/coderay.css +0 -105
  79. data/test/ramaze/public/css/ramaze_error.css +0 -42
  80. data/test/ramaze/public/error.zmr +0 -77
  81. data/test/ramaze/public/favicon.ico +0 -0
  82. data/test/ramaze/public/js/jquery.js +0 -1923
  83. data/test/ramaze/public/ramaze.png +0 -0
  84. data/test/ramaze/src/controller/main.rb +0 -8
  85. data/test/ramaze/src/element/page.rb +0 -17
  86. data/test/ramaze/src/model.rb +0 -6
  87. data/test/ramaze/template/index.xhtml +0 -6
  88. 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.5.1'
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.7.0 or higher."
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)
@@ -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