mongrel_esi 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. data/Rakefile +15 -8
  2. data/bin/mongrel_esi +0 -0
  3. data/ext/esi/common.rl +32 -27
  4. data/ext/esi/esi_parser.c +11 -4
  5. data/ext/esi/parser.c +4536 -901
  6. data/ext/esi/parser.h +7 -0
  7. data/ext/esi/parser.rl +171 -53
  8. data/ext/esi/run-test.rb +0 -0
  9. data/ext/esi/test/common.rl +32 -27
  10. data/ext/esi/test/parser.c +322 -1342
  11. data/ext/esi/test/parser.h +7 -0
  12. data/ext/esi/test/parser.rl +171 -53
  13. data/ext/esi/test/test.c +13 -4
  14. data/ext/esi/test1.rb +35 -3
  15. data/lib/esi/cache.rb +2 -1
  16. data/lib/esi/config.rb +37 -0
  17. data/lib/esi/dispatcher.rb +3 -5
  18. data/lib/esi/invalidator.rb +3 -0
  19. data/lib/esi/logger.rb +0 -7
  20. data/lib/esi/parser.rb +70 -0
  21. data/lib/esi/processor.rb +88 -0
  22. data/lib/esi/proxy.rb +104 -0
  23. data/lib/esi/response.rb +106 -0
  24. data/lib/esi/router.rb +3 -0
  25. data/lib/esi/tag/attempt.rb +3 -0
  26. data/lib/esi/tag/base.rb +3 -1
  27. data/lib/esi/tag/except.rb +2 -0
  28. data/lib/esi/tag/include.rb +131 -132
  29. data/lib/esi/tag/invalidate.rb +2 -0
  30. data/lib/esi/tag/try.rb +3 -0
  31. data/test/integration/basic_test.rb +0 -1
  32. data/test/integration/docs/esi_max_age_varies.html +10 -0
  33. data/test/integration/handler_test.rb +31 -5
  34. data/test/integration/help.rb +13 -1
  35. data/test/load_test.rb +133 -0
  36. data/test/unit/include_request_test.rb +1 -1
  37. data/test/unit/parser_test.rb +41 -5
  38. data/test/unit/response_test.rb +184 -0
  39. metadata +50 -224
  40. data/doc/rdoc/classes/ESI/Cache.html +0 -178
  41. data/doc/rdoc/classes/ESI/Cache.src/M000060.html +0 -17
  42. data/doc/rdoc/classes/ESI/Cache.src/M000061.html +0 -20
  43. data/doc/rdoc/classes/ESI/Config/CacheConfig.html +0 -212
  44. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000055.html +0 -19
  45. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000056.html +0 -19
  46. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000057.html +0 -18
  47. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000058.html +0 -18
  48. data/doc/rdoc/classes/ESI/Config/CacheConfig.src/M000059.html +0 -18
  49. data/doc/rdoc/classes/ESI/Config/ConfigRouter.html +0 -187
  50. data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000052.html +0 -19
  51. data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000053.html +0 -21
  52. data/doc/rdoc/classes/ESI/Config/ConfigRouter.src/M000054.html +0 -21
  53. data/doc/rdoc/classes/ESI/Config.html +0 -291
  54. data/doc/rdoc/classes/ESI/Config.src/M000043.html +0 -18
  55. data/doc/rdoc/classes/ESI/Config.src/M000044.html +0 -18
  56. data/doc/rdoc/classes/ESI/Config.src/M000045.html +0 -35
  57. data/doc/rdoc/classes/ESI/Config.src/M000046.html +0 -38
  58. data/doc/rdoc/classes/ESI/Config.src/M000047.html +0 -23
  59. data/doc/rdoc/classes/ESI/Config.src/M000048.html +0 -18
  60. data/doc/rdoc/classes/ESI/Config.src/M000049.html +0 -20
  61. data/doc/rdoc/classes/ESI/Config.src/M000050.html +0 -18
  62. data/doc/rdoc/classes/ESI/Config.src/M000051.html +0 -24
  63. data/doc/rdoc/classes/ESI/Dispatcher.html +0 -172
  64. data/doc/rdoc/classes/ESI/Dispatcher.src/M000062.html +0 -23
  65. data/doc/rdoc/classes/ESI/Dispatcher.src/M000063.html +0 -20
  66. data/doc/rdoc/classes/ESI/Fragment.html +0 -218
  67. data/doc/rdoc/classes/ESI/Fragment.src/M000076.html +0 -21
  68. data/doc/rdoc/classes/ESI/Fragment.src/M000077.html +0 -18
  69. data/doc/rdoc/classes/ESI/Fragment.src/M000078.html +0 -18
  70. data/doc/rdoc/classes/ESI/Handler.html +0 -236
  71. data/doc/rdoc/classes/ESI/Handler.src/M000079.html +0 -19
  72. data/doc/rdoc/classes/ESI/Handler.src/M000080.html +0 -161
  73. data/doc/rdoc/classes/ESI/Handler.src/M000081.html +0 -24
  74. data/doc/rdoc/classes/ESI/Handler.src/M000082.html +0 -18
  75. data/doc/rdoc/classes/ESI/Handler.src/M000083.html +0 -26
  76. data/doc/rdoc/classes/ESI/Handler.src/M000084.html +0 -30
  77. data/doc/rdoc/classes/ESI/Invalidator.html +0 -131
  78. data/doc/rdoc/classes/ESI/Invalidator.src/M000004.html +0 -41
  79. data/doc/rdoc/classes/ESI/Log.html +0 -251
  80. data/doc/rdoc/classes/ESI/Log.src/M000005.html +0 -18
  81. data/doc/rdoc/classes/ESI/Log.src/M000006.html +0 -18
  82. data/doc/rdoc/classes/ESI/Log.src/M000007.html +0 -18
  83. data/doc/rdoc/classes/ESI/Log.src/M000008.html +0 -18
  84. data/doc/rdoc/classes/ESI/Log.src/M000009.html +0 -18
  85. data/doc/rdoc/classes/ESI/Log.src/M000010.html +0 -18
  86. data/doc/rdoc/classes/ESI/Log.src/M000011.html +0 -18
  87. data/doc/rdoc/classes/ESI/Log.src/M000012.html +0 -18
  88. data/doc/rdoc/classes/ESI/Log.src/M000013.html +0 -18
  89. data/doc/rdoc/classes/ESI/MemcachedCache.html +0 -314
  90. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000034.html +0 -24
  91. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000035.html +0 -22
  92. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000036.html +0 -19
  93. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000037.html +0 -23
  94. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000038.html +0 -18
  95. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000039.html +0 -19
  96. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000040.html +0 -18
  97. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000041.html +0 -18
  98. data/doc/rdoc/classes/ESI/MemcachedCache.src/M000042.html +0 -17
  99. data/doc/rdoc/classes/ESI/Router.html +0 -229
  100. data/doc/rdoc/classes/ESI/Router.src/M000073.html +0 -36
  101. data/doc/rdoc/classes/ESI/Router.src/M000074.html +0 -25
  102. data/doc/rdoc/classes/ESI/Router.src/M000075.html +0 -24
  103. data/doc/rdoc/classes/ESI/RubyCache.html +0 -278
  104. data/doc/rdoc/classes/ESI/RubyCache.src/M000064.html +0 -20
  105. data/doc/rdoc/classes/ESI/RubyCache.src/M000065.html +0 -22
  106. data/doc/rdoc/classes/ESI/RubyCache.src/M000066.html +0 -21
  107. data/doc/rdoc/classes/ESI/RubyCache.src/M000067.html +0 -22
  108. data/doc/rdoc/classes/ESI/RubyCache.src/M000068.html +0 -18
  109. data/doc/rdoc/classes/ESI/RubyCache.src/M000069.html +0 -22
  110. data/doc/rdoc/classes/ESI/RubyCache.src/M000070.html +0 -18
  111. data/doc/rdoc/classes/ESI/RubyCache.src/M000071.html +0 -18
  112. data/doc/rdoc/classes/ESI/RubyCache.src/M000072.html +0 -18
  113. data/doc/rdoc/classes/ESI/Tag/Attempt.html +0 -113
  114. data/doc/rdoc/classes/ESI/Tag/Base.html +0 -267
  115. data/doc/rdoc/classes/ESI/Tag/Base.src/M000028.html +0 -26
  116. data/doc/rdoc/classes/ESI/Tag/Base.src/M000029.html +0 -23
  117. data/doc/rdoc/classes/ESI/Tag/Base.src/M000030.html +0 -22
  118. data/doc/rdoc/classes/ESI/Tag/Base.src/M000031.html +0 -18
  119. data/doc/rdoc/classes/ESI/Tag/Base.src/M000032.html +0 -22
  120. data/doc/rdoc/classes/ESI/Tag/Base.src/M000033.html +0 -23
  121. data/doc/rdoc/classes/ESI/Tag/Except.html +0 -184
  122. data/doc/rdoc/classes/ESI/Tag/Except.src/M000020.html +0 -21
  123. data/doc/rdoc/classes/ESI/Tag/Except.src/M000021.html +0 -20
  124. data/doc/rdoc/classes/ESI/Tag/Except.src/M000022.html +0 -18
  125. data/doc/rdoc/classes/ESI/Tag/Include.html +0 -189
  126. data/doc/rdoc/classes/ESI/Tag/Include.src/M000017.html +0 -20
  127. data/doc/rdoc/classes/ESI/Tag/Include.src/M000018.html +0 -18
  128. data/doc/rdoc/classes/ESI/Tag/Include.src/M000019.html +0 -125
  129. data/doc/rdoc/classes/ESI/Tag/IncludeRequest/Error.html +0 -155
  130. data/doc/rdoc/classes/ESI/Tag/IncludeRequest/Error.src/M000016.html +0 -19
  131. data/doc/rdoc/classes/ESI/Tag/IncludeRequest.html +0 -199
  132. data/doc/rdoc/classes/ESI/Tag/IncludeRequest.src/M000014.html +0 -18
  133. data/doc/rdoc/classes/ESI/Tag/IncludeRequest.src/M000015.html +0 -42
  134. data/doc/rdoc/classes/ESI/Tag/Invalidate.html +0 -171
  135. data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000025.html +0 -19
  136. data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000026.html +0 -51
  137. data/doc/rdoc/classes/ESI/Tag/Invalidate.src/M000027.html +0 -19
  138. data/doc/rdoc/classes/ESI/Tag/Try.html +0 -161
  139. data/doc/rdoc/classes/ESI/Tag/Try.src/M000023.html +0 -40
  140. data/doc/rdoc/classes/ESI/Tag/Try.src/M000024.html +0 -18
  141. data/doc/rdoc/classes/ESI/Tag.html +0 -137
  142. data/doc/rdoc/classes/ESI.html +0 -169
  143. data/doc/rdoc/classes/MultiDirHandler.html +0 -198
  144. data/doc/rdoc/classes/MultiDirHandler.src/M000001.html +0 -20
  145. data/doc/rdoc/classes/MultiDirHandler.src/M000002.html +0 -28
  146. data/doc/rdoc/classes/MultiDirHandler.src/M000003.html +0 -22
  147. data/doc/rdoc/classes/Net/An/HTTP.html +0 -137
  148. data/doc/rdoc/classes/Net/An/HTTP.src/M000087.html +0 -17
  149. data/doc/rdoc/classes/Net/An/IORequest.html +0 -139
  150. data/doc/rdoc/classes/Net/An/IORequest.src/M000088.html +0 -17
  151. data/doc/rdoc/classes/Net/An/IOResponse.html +0 -139
  152. data/doc/rdoc/classes/Net/An/IOResponse.src/M000085.html +0 -17
  153. data/doc/rdoc/classes/Net/An/IOSocket.html +0 -137
  154. data/doc/rdoc/classes/Net/An/IOSocket.src/M000086.html +0 -17
  155. data/doc/rdoc/classes/Net/An.html +0 -114
  156. data/doc/rdoc/classes/Net.html +0 -119
  157. data/doc/rdoc/created.rid +0 -1
  158. data/doc/rdoc/files/COPYING.html +0 -168
  159. data/doc/rdoc/files/LICENSE.html +0 -605
  160. data/doc/rdoc/files/README.html +0 -361
  161. data/doc/rdoc/files/lib/esi/cache_rb.html +0 -113
  162. data/doc/rdoc/files/lib/esi/config_rb.html +0 -108
  163. data/doc/rdoc/files/lib/esi/dispatcher_rb.html +0 -109
  164. data/doc/rdoc/files/lib/esi/handler_rb.html +0 -121
  165. data/doc/rdoc/files/lib/esi/invalidator_rb.html +0 -117
  166. data/doc/rdoc/files/lib/esi/logger_rb.html +0 -108
  167. data/doc/rdoc/files/lib/esi/router_rb.html +0 -101
  168. data/doc/rdoc/files/lib/esi/tag/attempt_rb.html +0 -101
  169. data/doc/rdoc/files/lib/esi/tag/base_rb.html +0 -108
  170. data/doc/rdoc/files/lib/esi/tag/except_rb.html +0 -101
  171. data/doc/rdoc/files/lib/esi/tag/include_rb.html +0 -109
  172. data/doc/rdoc/files/lib/esi/tag/invalidate_rb.html +0 -109
  173. data/doc/rdoc/files/lib/esi/tag/try_rb.html +0 -108
  174. data/doc/rdoc/files/lib/multi_dirhandler_rb.html +0 -109
  175. data/doc/rdoc/files/lib/net/ahttp_rb.html +0 -109
  176. data/doc/rdoc/fr_class_index.html +0 -55
  177. data/doc/rdoc/fr_file_index.html +0 -44
  178. data/doc/rdoc/fr_method_index.html +0 -114
  179. data/doc/rdoc/index.html +0 -24
  180. data/doc/rdoc/rdoc-style.css +0 -208
  181. data/ext/esi/parser.rb +0 -49
  182. data/ext/esi/ruby_esi.rl +0 -135
  183. data/lib/esi/handler.rb +0 -221
  184. data/lib/net/ahttp.rb +0 -36
@@ -1,3 +1,5 @@
1
+ # Copyright (c) 2008 Todd A. Fisher
2
+ # see LICENSE
1
3
  require 'rubygems'
2
4
  gem 'hpricot'
3
5
  require 'hpricot'
data/lib/esi/tag/try.rb CHANGED
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2008 Todd A. Fisher
2
+ # see LICENSE
3
+
1
4
  require 'esi/logger'
2
5
 
3
6
  module ESI
@@ -25,7 +25,6 @@ class BasicTest < Test::Unit::TestCase
25
25
  :enable_for_surrogate_only => false,
26
26
  :invalidator => false
27
27
  )
28
- handler = ESI::Handler.new(dispatcher)
29
28
  end
30
29
  end
31
30
 
@@ -0,0 +1,10 @@
1
+ <html>
2
+ <head>
3
+ </head>
4
+ <body>
5
+ <h1>This is a test document</h1>
6
+ <div>Some content before</div><esi:include src="/fragments/test1.html" max-age="600+600"/>
7
+ <div>Some content before</div><esi:include src="/content/test2.html" max-age="0+0"/>
8
+ <div>Some content before</div><esi:include src="/content/test2.html" max-age="0"/>
9
+ </body>
10
+ </html>
@@ -177,6 +177,17 @@ class HandlerTest < Test::Unit::TestCase
177
177
  end
178
178
  end
179
179
 
180
+ def test_failing_response_from_surrogate
181
+ Net::HTTP.start("localhost", 9997) do |h|
182
+ res = h.get("/500")
183
+ assert_not_nil res
184
+ assert_not_nil res.header
185
+ assert_not_nil res.body
186
+ assert_equal "<html><body>Internal Server Error</body></html>", res.body
187
+ assert_equal Net::HTTPInternalServerError, res.header.class, res.body
188
+ end
189
+ end
190
+
180
191
  def test_static_failover
181
192
  Net::HTTP.start("localhost", 9997) do |h|
182
193
  res = h.get("/content/static-failover.html")
@@ -216,10 +227,6 @@ class HandlerTest < Test::Unit::TestCase
216
227
  end
217
228
  end
218
229
 
219
- def test_markup_in_except_passed_through
220
- # TODO
221
- end
222
-
223
230
  def test_surrogate_control_header
224
231
  # first tell the esi handler to use the surrogate control header
225
232
  $esi_dispatcher.config.config.send(:store,:enable_for_surrogate_only, true)
@@ -259,12 +266,31 @@ class HandlerTest < Test::Unit::TestCase
259
266
 
260
267
  Net::HTTP.start("localhost", 9997) do |h|
261
268
  res = h.get("/esi_invalidate.html")
269
+ assert_not_nil res
270
+ assert_not_nil res.header
271
+ assert_not_nil res.body
272
+ assert_equal Net::HTTPOK, res.header.class
262
273
  end
263
-
274
+
264
275
  assert !cached?( FRAGMENT_TEST1_URI ), "Error Fragment 1 should not be cached!"
265
276
  assert !cached?( FRAGMENT_TEST2_URI ), "Error Fragment 2 should not be cached!"
266
277
  end
267
278
 
279
+ def test_max_age_include_attribute_cache_ttl
280
+ Net::HTTP.start("localhost", 9997) do |h|
281
+ res = h.get("/esi_max_age_varies.html")
282
+ assert_not_nil res
283
+ assert_not_nil res.header
284
+ assert_not_nil res.body
285
+ assert_equal Net::HTTPOK, res.header.class
286
+ assert_match $fragment_test1, res.body, "Fragment not found"
287
+ assert_match $fragment_test2, res.body, "Fragment not found"
288
+ end
289
+
290
+ assert cached?( FRAGMENT_TEST1_URI ), "Error Fragment should be cached!"
291
+ assert !cached?( FRAGMENT_TEST2_URI ), "Error Fragment should not be cached!"
292
+ end
293
+
268
294
 
269
295
  end
270
296
 
@@ -1,4 +1,5 @@
1
1
  # modified version from mongrel
2
+ require 'rubygems'
2
3
  # This code is moving into integration test folder
3
4
  $:.unshift File.join(File.dirname(__FILE__), "..", "..", "lib")
4
5
  $:.unshift File.join(File.dirname(__FILE__), "..", "..", "ext")
@@ -101,6 +102,16 @@ class Basic404HandlerWithoutHeader < Mongrel::HttpHandler
101
102
  end
102
103
  end
103
104
 
105
+ class Basic500Handler < Mongrel::HttpHandler
106
+ include Mongrel::HttpHandlerPlugin
107
+ def process(request, response)
108
+ response.start(500,true) do |head,out|
109
+ head["Surrogate-Control"] = %q(max-age=0, content="ESI/1.0 ESI-INV/1.0")
110
+ out << %q(<html><body>Internal Server Error</body></html>)
111
+ end
112
+ end
113
+ end
114
+
104
115
  class AjaxCacheHandler < Mongrel::HttpHandler
105
116
  include Mongrel::HttpHandlerPlugin
106
117
  def process(request, response)
@@ -200,7 +211,8 @@ module ESI
200
211
  { :uri => '/post_redirect_test', :handler => PostRedirectHandler.new },
201
212
  { :uri => '/404', :handler => Basic404Handler.new },
202
213
  { :uri => '/404-no-surrogate', :handler => Basic404HandlerWithoutHeader.new },
203
- { :uri => '/invalidate', :handler => InvalidateHandler.new }
214
+ { :uri => '/invalidate', :handler => InvalidateHandler.new },
215
+ { :uri => '/500', :handler => Basic500Handler.new }
204
216
  ]
205
217
  },
206
218
  { :host_port => { :host => '127.0.0.1', :port => 9997 },
data/test/load_test.rb ADDED
@@ -0,0 +1,133 @@
1
+ require 'net/http'
2
+ require 'open-uri'
3
+
4
+ # test the currency load
5
+ class LoadTest
6
+ TEST_HOST='http://127.0.0.1:8000'
7
+ TEST_PATH='/'
8
+ EXPECTED_RESPONSE=File.read(File.join(File.dirname(__FILE__),'sample.html'))
9
+
10
+ def initialize(trials)
11
+ @trials = trials
12
+ @trial = 0
13
+ @reports = {}
14
+ end
15
+
16
+ def request_url
17
+ TEST_HOST + TEST_PATH
18
+ end
19
+
20
+ # see: http://warrenseen.com/blog/2006/03/13/how-to-calculate-standard-deviation/
21
+ def variance(population)
22
+ n = 0
23
+ mean = 0.0
24
+ s = 0.0
25
+ population.each { |x|
26
+ n = n + 1
27
+ delta = x - mean
28
+ mean = mean + (delta / n)
29
+ s = s + delta * (x - mean)
30
+ }
31
+ # if you want to calculate std deviation
32
+ # of a sample change this to "s / (n-1)"
33
+ return s / (n-1)
34
+ end
35
+
36
+ # calculate the standard deviation of a population
37
+ # accepts: an array, the population
38
+ # returns: the standard deviation
39
+ def standard_deviation(population)
40
+ Math.sqrt(variance(population).abs)
41
+ end
42
+
43
+ def report( type, image_path = "benchmark100.png", font_path="/usr/share/fonts/bitstream-vera/Vera.ttf" )
44
+ require 'rubygems'
45
+ require 'gruff'
46
+ extras = {}
47
+ g = Gruff::Line.new(2048)
48
+ g.title = "MongrelESI Serial vs Parallel"
49
+ g.font = font_path if font_path # my linux system's font
50
+ @reports[type].each do|key,values|
51
+ total = 0
52
+ values.each {|t| total += t }
53
+ # average = total / values.size
54
+ # std = standard_deviation(values)
55
+ g.data(key,values)
56
+ # puts "#{key}: #{average} seconds (#{std})"
57
+ # extras[key] = {:std => std, :average => average}
58
+ end
59
+ labels = {}
60
+ @trials.each_with_index do|t,index|
61
+ labels[index] = t.to_s
62
+ end
63
+ g.labels = labels
64
+ g.write(image_path)
65
+ end
66
+
67
+ def assert_equal( s1, s2 )
68
+ if s1 != s2
69
+ File.open("s1.html","w") do|f|
70
+ f << s1
71
+ end
72
+ File.open("s2.html","w") do|f|
73
+ f << s2
74
+ end
75
+ raise "Error response not matching expected library failure! 's1.html' Not equal to 's2.html'"
76
+ end
77
+ end
78
+
79
+ def assert_not_nil( v )
80
+ raise "Error: value should not be nil!" if v.nil?
81
+ end
82
+
83
+ def test_trial(trials,report_tag,url)
84
+ require 'net/http'
85
+ require 'open-uri'
86
+
87
+ timer = Time.now
88
+ threads = []
89
+
90
+ trials.times do
91
+ threads << Thread.new do
92
+ t = Time.now
93
+ assert_equal( EXPECTED_RESPONSE, open(url).read )
94
+ (Time.now - t)
95
+ end
96
+ end
97
+
98
+ times = []
99
+ threads.each do|t|
100
+ times << t.value
101
+ end
102
+
103
+ duration = Time.now - timer
104
+ #average = (duration / trials)
105
+ average = 0
106
+ times.each { |t| average += t }
107
+ average /= times.size
108
+
109
+ std = standard_deviation(times)
110
+
111
+ puts "Running net/http(#{report_tag}): #{trials} in #{average} seconds (#{std}), #{times.inspect}"
112
+ @reports[:avg]["#{report_tag}"] ||= []
113
+ @reports[:avg]["#{report_tag}"] << average
114
+ @reports[:std]["#{report_tag}"] ||= []
115
+ @reports[:std]["#{report_tag}"] << std
116
+ @reports[:raw]["#{report_tag}-#{trials}"] ||= []
117
+ @reports[:raw]["#{report_tag}-#{trials}"] += times
118
+ end
119
+
120
+ def run
121
+ @reports = {:avg => {}, :std => {}, :raw => {}}
122
+ @trials.each do|trial|
123
+ test_trial(trial,:piped,'http://127.0.0.1:8000/')
124
+ test_trial(trial,:serial,'http://127.0.0.1:8001/')
125
+ end
126
+ end
127
+ end
128
+
129
+ test = LoadTest.new([2,5,10]) #,80,100,200,300,400])
130
+ test.run
131
+ test.report(:avg, 'benchmark-averages-50.png')
132
+ test.report(:std, 'benchmark-std-50.png')
133
+ test.report(:raw, 'benchmark-times-50.png')
@@ -4,7 +4,7 @@ class IncludeRequestTest < Test::Unit::TestCase
4
4
  include TestServer
5
5
 
6
6
  def request(path,alt=nil,headers={})
7
- ir = ESI::Tag::IncludeRequest.new(headers)
7
+ ir = ESI::Tag::Include::Request.new(headers)
8
8
  buffer = ""
9
9
  status = 0
10
10
  info = nil
@@ -1,9 +1,10 @@
1
1
  require File.join(File.dirname(__FILE__),'help.rb')
2
+ require 'esi/response'
2
3
 
3
4
  $run_sample_once = false
4
5
  class ParseOutputTest < Test::Unit::TestCase
5
6
  include TestServer
6
-
7
+
7
8
  def setup_extra
8
9
  @sample_file = File.join(File.dirname(__FILE__),'esi-sample.html')
9
10
  if !$run_sample_once
@@ -28,7 +29,7 @@ class ParseOutputTest < Test::Unit::TestCase
28
29
  @parser.esi_tag.close(@parser.output)
29
30
  rescue Object => e
30
31
  puts @parser.esi_tag.name
31
- puts e.message
32
+ puts e.message, e.backtrace.join("\n")
32
33
  end
33
34
  @parser.esi_tag = nil
34
35
  else
@@ -102,9 +103,19 @@ class ParseOutputTest < Test::Unit::TestCase
102
103
  assert_equal input, output
103
104
  end
104
105
 
106
+ class OutputAdapter
107
+ def initialize(output)
108
+ @output = output
109
+ end
110
+ def << (msg)
111
+ @output.call msg
112
+ end
113
+ end
114
+
105
115
  def test_with_tags
106
116
  sample = @sample_file
107
117
  cache = ESI::RubyCache.new
118
+
108
119
  File.open('out-sample.html','w') do|output|
109
120
  parser = ESI::CParser.new
110
121
  parser.output_handler {|s| output << s }
@@ -120,10 +131,10 @@ class ParseOutputTest < Test::Unit::TestCase
120
131
 
121
132
  parser.end_tag_handler do|tag_name|
122
133
  if parser.esi_tag.name == tag_name.gsub(/esi:/,'')
123
- parser.esi_tag.close(parser.output)
134
+ parser.esi_tag.close(OutputAdapter.new(parser.output))
124
135
  parser.esi_tag = nil
125
136
  else
126
- parser.esi_tag.close_child(parser.output,tag_name)
137
+ parser.esi_tag.close_child(OutputAdapter.new(parser.output),tag_name)
127
138
  end
128
139
  end
129
140
  File.open(sample,'r') do|input|
@@ -245,7 +256,7 @@ some inputsome more input<br/>
245
256
  parser.start_tag_handler do|tag_name, attrs|
246
257
  tags << {:name => tag_name, :attributes => attrs}
247
258
  end
248
- parser.process "<p>some input</p><esi:include/>some more input\nsome input<esi:include src='hello'/>some more input"
259
+ parser.process "<p>some input</p><esi:include />some more input\nsome input<esi:include src='hello'/>some more input"
249
260
  parser.finish
250
261
  assert_equal %Q(<p>some input</p>some more input
251
262
  some inputsome more input), output
@@ -471,6 +482,31 @@ input = %Q(
471
482
  assert end_called
472
483
  end
473
484
 
485
+ def test_attribute_values
486
+ output = ""
487
+ parser = ESI::CParser.new
488
+ parser.output_handler {|s| output << s }
489
+ parser.process 'start:<esi:include src="foobar?hi=cool"/>:finish'
490
+ parser.finish
491
+ assert_equal "start::finish", output
492
+ output = ""
493
+ parser.process 'start:<esi:include src="foo bar"/>:finish'
494
+ parser.finish
495
+ assert_equal "start::finish", output
496
+ output = ""
497
+ parser.process 'start:<esi:include src="foobar?hi=!@#$%^&*()-+~`"/>:finish'
498
+ parser.finish
499
+ assert_equal "start::finish", output
500
+ output = ""
501
+ parser.process 'start:<esi:try src="foobar?hi=!@#$%^&*()-+~`">cool</esi:try>:finish'
502
+ parser.finish
503
+ assert_equal "start:cool:finish", output
504
+ output = ""
505
+ parser.process 'start:<esi:try>cool</esi:try>:finish'
506
+ parser.finish
507
+ assert_equal "start:cool:finish", output
508
+ end
509
+
474
510
  # def test_setup
475
511
  # puts @output
476
512
  # end
@@ -0,0 +1,184 @@
1
+ require File.join(File.dirname(__FILE__),'help.rb')
2
+
3
+ require 'esi/response'
4
+ require 'esi/esi'
5
+
6
+ class ResponseTest < Test::Unit::TestCase
7
+
8
+ def test_response_to_response
9
+ output = StringIO.new
10
+
11
+ r1 = ESI::Response.new( output )
12
+ r2 = ESI::Response.new( r1.active_buffer )
13
+
14
+ buffer = r2.reserve_buffer
15
+ t = Thread.new do
16
+ buffer << "hello"
17
+ sleep(0.01) # make it count
18
+ buffer.close_write
19
+ end
20
+
21
+ r2.wait_thread(t)
22
+
23
+ r2.flush
24
+
25
+ r1.flush
26
+
27
+ output.rewind
28
+
29
+ assert_equal "hello", output.read
30
+
31
+ end
32
+
33
+ def test_esi_parser
34
+ output = []
35
+ @response = ESI::Response.new( output )
36
+ @parser = ESI::CParser.new
37
+ @count = 0
38
+
39
+ @parser.end_tag_handler do|tag_name|
40
+ @response.close_active_buffer
41
+ tag_buffer = @response.reserve_buffer
42
+ thread = Thread.new(tag_buffer,@count) do|buffer,count|
43
+ buffer << "#{count}: sample"
44
+ buffer.close_write
45
+ end
46
+ @response.wait_thread( thread )
47
+ end
48
+
49
+ input = StringIO.new(INPUT_STREAM)
50
+ lines = input.readlines
51
+
52
+ @parser.output_handler do|chars|
53
+ @response.open_active_buffer
54
+ @response.active_buffer << chars
55
+ @response.send if @response.back_buffer_ready? or @response.active_buffer.size > 1024
56
+ end
57
+
58
+ for line in lines do
59
+ @parser.process line
60
+ @count += 1
61
+ end
62
+
63
+ @parser.finish
64
+ @response.flush
65
+ # puts output.join("")
66
+ # puts output.join("").split("\n").size
67
+
68
+ # break it back up into lines
69
+ lines = output.join("").split("\n")
70
+ assert_equal 35, lines.size
71
+
72
+ assert_match(/hello there world/,lines[1])
73
+ assert_match(/sample/,lines[3])
74
+ assert_match(/sample/,lines[7])
75
+ assert_match(/sample/,lines[13])
76
+ assert_match(/and some more here/,lines[15])
77
+ assert_match(/sample/,lines[19])
78
+ assert_match(/sample/,lines[20])
79
+ assert_match(/sample/,lines[21])
80
+ assert_match(/sample/,lines[22])
81
+ assert_match(/and some more here/,lines[24])
82
+ assert_match(/sample/,lines[25])
83
+ assert_match(/sample/,lines[31])
84
+
85
+ end
86
+
87
+ def test_sample
88
+ lines = INPUT_STREAM.split("\n")
89
+
90
+ timer = Time.now
91
+ request_delay = 0.01 # each request takes
92
+ request_vary = 0.0005 # the request delay varies
93
+ response_delay = 0.00005 # the delay in reading the surrogate request
94
+ output = []
95
+ response = ESI::Response.new( output )
96
+
97
+ count = 0
98
+
99
+ lines.each do|line|
100
+ line += "\n"
101
+
102
+ sleep response_delay
103
+
104
+ if line.match(/<esi:/)
105
+ response.close_active_buffer
106
+ msg_buffer = response.reserve_buffer
107
+
108
+ thread = Thread.new(msg_buffer,count) do|buffer,count|
109
+ sleep( (request_delay + (rand > 0.5 ? (-1* request_vary) : request_vary)).abs) # some busy work
110
+ message = "#{count}: sample\n"
111
+ buffer << message
112
+ buffer.close_write
113
+ end
114
+
115
+ response.wait_thread( thread )
116
+ else
117
+ response.open_active_buffer
118
+ response.active_buffer << "#{count}: #{line}"
119
+ end
120
+ count += 1
121
+ response.send if response.back_buffer_ready? or response.active_buffer.size > 1024
122
+ end
123
+
124
+ response.flush
125
+
126
+ output = output.join("").split("\n")
127
+
128
+ assert_equal 35, output.size
129
+ assert_match(/\s/,output[0])
130
+ assert_match(/hello there world/,output[1])
131
+ assert_match(/sample/,output[3])
132
+ assert_match(/sample/,output[7])
133
+ assert_match(/sample/,output[13])
134
+ assert_match(/and some more here/,output[15])
135
+ assert_match(/sample/,output[19])
136
+ assert_match(/sample/,output[20])
137
+ assert_match(/sample/,output[21])
138
+ assert_match(/sample/,output[22])
139
+ assert_match(/and some more here/,output[24])
140
+ assert_match(/sample/,output[25])
141
+ assert_match(/sample/,output[31])
142
+ assert_match(/\s/,output[34])
143
+
144
+ #puts output.join("\n")
145
+ #puts "total time: #{Time.now - timer} seconds, with a request delay of #{request_delay} seconds with variance of #{request_vary} and total of #{count} lines taking #{response_delay} seconds each to read."
146
+ end
147
+
148
+ # define a sample buffer here:
149
+ INPUT_STREAM = %Q(
150
+ hello there world
151
+
152
+ <esi:include src='/foo/'/>
153
+
154
+ some more bytes here
155
+
156
+ <esi:include src='/bar/'/>
157
+
158
+ and some more here
159
+
160
+ some more bytes here
161
+
162
+ <esi:include src='/bar/'/>
163
+
164
+ and some more here
165
+
166
+ some more bytes here
167
+
168
+ <esi:include src='/bar/'/>
169
+ <esi:include src='/bar/'/>
170
+ <esi:include src='/bar/'/>
171
+ <esi:include src='/bar/'/>
172
+
173
+ and some more here
174
+ <esi:include src='/bar/'/>
175
+
176
+ and some more here
177
+
178
+ some more bytes here
179
+
180
+ <esi:include src='/bar/'/>
181
+
182
+ and some more here
183
+ )
184
+ end