swiftiply 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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