mongrel 1.1.5-x86-mingw32

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 (73) hide show
  1. data.tar.gz.sig +4 -0
  2. data/CHANGELOG +18 -0
  3. data/COPYING +55 -0
  4. data/LICENSE +55 -0
  5. data/Manifest +69 -0
  6. data/README +74 -0
  7. data/TODO +5 -0
  8. data/bin/mongrel_rails +283 -0
  9. data/examples/builder.rb +29 -0
  10. data/examples/camping/README +3 -0
  11. data/examples/camping/blog.rb +294 -0
  12. data/examples/camping/tepee.rb +149 -0
  13. data/examples/httpd.conf +474 -0
  14. data/examples/mime.yaml +3 -0
  15. data/examples/mongrel.conf +9 -0
  16. data/examples/mongrel_simple_ctrl.rb +92 -0
  17. data/examples/mongrel_simple_service.rb +116 -0
  18. data/examples/monitrc +57 -0
  19. data/examples/random_thrash.rb +19 -0
  20. data/examples/simpletest.rb +52 -0
  21. data/examples/webrick_compare.rb +20 -0
  22. data/ext/http11/ext_help.h +14 -0
  23. data/ext/http11/extconf.rb +6 -0
  24. data/ext/http11/http11.c +402 -0
  25. data/ext/http11/http11_parser.c +1221 -0
  26. data/ext/http11/http11_parser.h +49 -0
  27. data/ext/http11/http11_parser.java.rl +170 -0
  28. data/ext/http11/http11_parser.rl +152 -0
  29. data/ext/http11/http11_parser_common.rl +54 -0
  30. data/ext/http11_java/Http11Service.java +13 -0
  31. data/ext/http11_java/org/jruby/mongrel/Http11.java +266 -0
  32. data/ext/http11_java/org/jruby/mongrel/Http11Parser.java +572 -0
  33. data/lib/http11.so +0 -0
  34. data/lib/mongrel.rb +355 -0
  35. data/lib/mongrel/camping.rb +107 -0
  36. data/lib/mongrel/cgi.rb +181 -0
  37. data/lib/mongrel/command.rb +222 -0
  38. data/lib/mongrel/configurator.rb +388 -0
  39. data/lib/mongrel/const.rb +110 -0
  40. data/lib/mongrel/debug.rb +203 -0
  41. data/lib/mongrel/gems.rb +22 -0
  42. data/lib/mongrel/handlers.rb +468 -0
  43. data/lib/mongrel/header_out.rb +28 -0
  44. data/lib/mongrel/http_request.rb +155 -0
  45. data/lib/mongrel/http_response.rb +163 -0
  46. data/lib/mongrel/init.rb +10 -0
  47. data/lib/mongrel/mime_types.yml +616 -0
  48. data/lib/mongrel/rails.rb +185 -0
  49. data/lib/mongrel/stats.rb +89 -0
  50. data/lib/mongrel/tcphack.rb +18 -0
  51. data/lib/mongrel/uri_classifier.rb +76 -0
  52. data/mongrel-public_cert.pem +20 -0
  53. data/mongrel.gemspec +242 -0
  54. data/setup.rb +1585 -0
  55. data/test/mime.yaml +3 -0
  56. data/test/mongrel.conf +1 -0
  57. data/test/test_cgi_wrapper.rb +26 -0
  58. data/test/test_command.rb +86 -0
  59. data/test/test_conditional.rb +107 -0
  60. data/test/test_configurator.rb +88 -0
  61. data/test/test_debug.rb +25 -0
  62. data/test/test_handlers.rb +126 -0
  63. data/test/test_http11.rb +156 -0
  64. data/test/test_redirect_handler.rb +45 -0
  65. data/test/test_request_progress.rb +100 -0
  66. data/test/test_response.rb +127 -0
  67. data/test/test_stats.rb +35 -0
  68. data/test/test_uriclassifier.rb +261 -0
  69. data/test/test_ws.rb +115 -0
  70. data/test/testhelp.rb +79 -0
  71. data/tools/trickletest.rb +45 -0
  72. metadata +197 -0
  73. metadata.gz.sig +1 -0
@@ -0,0 +1,156 @@
1
+ # Copyright (c) 2005 Zed A. Shaw
2
+ # You can redistribute it and/or modify it under the same terms as Ruby.
3
+ #
4
+ # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
+ # for more information.
6
+
7
+ require 'test/testhelp'
8
+
9
+ include Mongrel
10
+
11
+ class HttpParserTest < Test::Unit::TestCase
12
+
13
+ def test_parse_simple
14
+ parser = HttpParser.new
15
+ req = {}
16
+ http = "GET / HTTP/1.1\r\n\r\n"
17
+ nread = parser.execute(req, http, 0)
18
+
19
+ assert nread == http.length, "Failed to parse the full HTTP request"
20
+ assert parser.finished?, "Parser didn't finish"
21
+ assert !parser.error?, "Parser had error"
22
+ assert nread == parser.nread, "Number read returned from execute does not match"
23
+
24
+ assert_equal 'HTTP/1.1', req['SERVER_PROTOCOL']
25
+ assert_equal '/', req['REQUEST_PATH']
26
+ assert_equal 'HTTP/1.1', req['HTTP_VERSION']
27
+ assert_equal '/', req['REQUEST_URI']
28
+ assert_equal 'CGI/1.2', req['GATEWAY_INTERFACE']
29
+ assert_equal 'GET', req['REQUEST_METHOD']
30
+ assert_nil req['FRAGMENT']
31
+ assert_nil req['QUERY_STRING']
32
+
33
+ parser.reset
34
+ assert parser.nread == 0, "Number read after reset should be 0"
35
+ end
36
+
37
+ def test_parse_dumbfuck_headers
38
+ parser = HttpParser.new
39
+ req = {}
40
+ should_be_good = "GET / HTTP/1.1\r\naaaaaaaaaaaaa:++++++++++\r\n\r\n"
41
+ nread = parser.execute(req, should_be_good, 0)
42
+ assert_equal should_be_good.length, nread
43
+ assert parser.finished?
44
+ assert !parser.error?
45
+
46
+ nasty_pound_header = "GET / HTTP/1.1\r\nX-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n\tAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMu\r\n\tdWswHhcNMDYwNzI3MTQxMzI4WhcNMDcwNzI3MTQxMzI4WjBbMQswCQYDVQQGEwJV\r\n\tSzERMA8GA1UEChMIZVNjaWVuY2UxEzARBgNVBAsTCk1hbmNoZXN0ZXIxCzAJBgNV\r\n\tBAcTmrsogriqMWLAk1DMRcwFQYDVQQDEw5taWNoYWVsIHBhcmQYJKoZIhvcNAQEB\r\n\tBQADggEPADCCAQoCggEBANPEQBgl1IaKdSS1TbhF3hEXSl72G9J+WC/1R64fAcEF\r\n\tW51rEyFYiIeZGx/BVzwXbeBoNUK41OK65sxGuflMo5gLflbwJtHBRIEKAfVVp3YR\r\n\tgW7cMA/s/XKgL1GEC7rQw8lIZT8RApukCGqOVHSi/F1SiFlPDxuDfmdiNzL31+sL\r\n\t0iwHDdNkGjy5pyBSB8Y79dsSJtCW/iaLB0/n8Sj7HgvvZJ7x0fr+RQjYOUUfrePP\r\n\tu2MSpFyf+9BbC/aXgaZuiCvSR+8Snv3xApQY+fULK/xY8h8Ua51iXoQ5jrgu2SqR\r\n\twgA7BUi3G8LFzMBl8FRCDYGUDy7M6QaHXx1ZWIPWNKsCAwEAAaOCAiQwggIgMAwG\r\n\tA1UdEwEB/wQCMAAwEQYJYIZIAYb4QgEBBAQDAgWgMA4GA1UdDwEB/wQEAwID6DAs\r\n\tBglghkgBhvhCAQ0EHxYdVUsgZS1TY2llbmNlIFVzZXIgQ2VydGlmaWNhdGUwHQYD\r\n\tVR0OBBYEFDTt/sf9PeMaZDHkUIldrDYMNTBZMIGaBgNVHSMEgZIwgY+AFAI4qxGj\r\n\tloCLDdMVKwiljjDastqooXSkcjBwMQswCQYDVQQGEwJVSzERMA8GA1UEChMIZVNj\r\n\taWVuY2UxEjAQBgNVBAsTCUF1dGhvcml0eTELMAkGA1UEAxMCQ0ExLTArBgkqhkiG\r\n\t9w0BCQEWHmNhLW9wZXJhdG9yQGdyaWQtc3VwcG9ydC5hYy51a4IBADApBgNVHRIE\r\n\tIjAggR5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMudWswGQYDVR0gBBIwEDAO\r\n\tBgwrBgEEAdkvAQEBAQYwPQYJYIZIAYb4QgEEBDAWLmh0dHA6Ly9jYS5ncmlkLXN1\r\n\tcHBvcnQuYWMudmT4sopwqlBWsvcHViL2NybC9jYWNybC5jcmwwPQYJYIZIAYb4QgEDBDAWLmh0\r\n\tdHA6Ly9jYS5ncmlkLXN1cHBvcnQuYWMudWsvcHViL2NybC9jYWNybC5jcmwwPwYD\r\n\tVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NhLmdyaWQt5hYy51ay9wdWIv\r\n\tY3JsL2NhY3JsLmNybDANBgkqhkiG9w0BAQUFAAOCAQEAS/U4iiooBENGW/Hwmmd3\r\n\tXCy6Zrt08YjKCzGNjorT98g8uGsqYjSxv/hmi0qlnlHs+k/3Iobc3LjS5AMYr5L8\r\n\tUO7OSkgFFlLHQyC9JzPfmLCAugvzEbyv4Olnsr8hbxF1MbKZoQxUZtMVu29wjfXk\r\n\thTeApBv7eaKCWpSp7MCbvgzm74izKhu3vlDk9w6qVrxePfGgpKPqfHiOoGhFnbTK\r\n\twTC6o2xq5y0qZ03JonF7OJspEd3I5zKY3E+ov7/ZhW6DqT8UFvsAdjvQbXyhV8Eu\r\n\tYhixw1aKEPzNjNowuIseVogKOLXxWI5vAi5HgXdS0/ES5gDGsABo4fqovUKlgop3\r\n\tRA==\r\n\t-----END CERTIFICATE-----\r\n\r\n"
47
+ parser = HttpParser.new
48
+ req = {}
49
+ #nread = parser.execute(req, nasty_pound_header, 0)
50
+ #assert_equal nasty_pound_header.length, nread
51
+ #assert parser.finished?
52
+ #assert !parser.error?
53
+ end
54
+
55
+ def test_parse_error
56
+ parser = HttpParser.new
57
+ req = {}
58
+ bad_http = "GET / SsUTF/1.1"
59
+
60
+ error = false
61
+ begin
62
+ nread = parser.execute(req, bad_http, 0)
63
+ rescue => details
64
+ error = true
65
+ end
66
+
67
+ assert error, "failed to throw exception"
68
+ assert !parser.finished?, "Parser shouldn't be finished"
69
+ assert parser.error?, "Parser SHOULD have error"
70
+ end
71
+
72
+ def test_fragment_in_uri
73
+ parser = HttpParser.new
74
+ req = {}
75
+ get = "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n"
76
+ assert_nothing_raised do
77
+ parser.execute(req, get, 0)
78
+ end
79
+ assert parser.finished?
80
+ assert_equal '/forums/1/topics/2375?page=1', req['REQUEST_URI']
81
+ assert_equal 'posts-17408', req['FRAGMENT']
82
+ end
83
+
84
+ # lame random garbage maker
85
+ def rand_data(min, max, readable=true)
86
+ count = min + ((rand(max)+1) *10).to_i
87
+ res = count.to_s + "/"
88
+
89
+ if readable
90
+ res << Digest::SHA1.hexdigest(rand(count * 100).to_s) * (count / 40)
91
+ else
92
+ res << Digest::SHA1.digest(rand(count * 100).to_s) * (count / 20)
93
+ end
94
+
95
+ return res
96
+ end
97
+
98
+
99
+ def test_horrible_queries
100
+ parser = HttpParser.new
101
+
102
+ # then that large header names are caught
103
+ 10.times do |c|
104
+ get = "GET /#{rand_data(10,120)} HTTP/1.1\r\nX-#{rand_data(1024, 1024+(c*1024))}: Test\r\n\r\n"
105
+ assert_raises Mongrel::HttpParserError do
106
+ parser.execute({}, get, 0)
107
+ parser.reset
108
+ end
109
+ end
110
+
111
+ # then that large mangled field values are caught
112
+ 10.times do |c|
113
+ get = "GET /#{rand_data(10,120)} HTTP/1.1\r\nX-Test: #{rand_data(1024, 1024+(c*1024), false)}\r\n\r\n"
114
+ assert_raises Mongrel::HttpParserError do
115
+ parser.execute({}, get, 0)
116
+ parser.reset
117
+ end
118
+ end
119
+
120
+ # then large headers are rejected too
121
+ get = "GET /#{rand_data(10,120)} HTTP/1.1\r\n"
122
+ get << "X-Test: test\r\n" * (80 * 1024)
123
+ assert_raises Mongrel::HttpParserError do
124
+ parser.execute({}, get, 0)
125
+ parser.reset
126
+ end
127
+
128
+ # finally just that random garbage gets blocked all the time
129
+ 10.times do |c|
130
+ get = "GET #{rand_data(1024, 1024+(c*1024), false)} #{rand_data(1024, 1024+(c*1024), false)}\r\n\r\n"
131
+ assert_raises Mongrel::HttpParserError do
132
+ parser.execute({}, get, 0)
133
+ parser.reset
134
+ end
135
+ end
136
+
137
+ end
138
+
139
+
140
+
141
+ def test_query_parse
142
+ res = HttpRequest.query_parse("zed=1&frank=#{HttpRequest.escape('&&& ')}")
143
+ assert res["zed"], "didn't get the request right"
144
+ assert res["frank"], "no frank"
145
+ assert_equal "1", res["zed"], "wrong result"
146
+ assert_equal "&&& ", HttpRequest.unescape(res["frank"]), "wrong result"
147
+
148
+ res = HttpRequest.query_parse("zed=1&zed=2&zed=3&frank=11;zed=45")
149
+ assert res["zed"], "didn't get the request right"
150
+ assert res["frank"], "no frank"
151
+ assert_equal 4,res["zed"].length, "wrong number for zed"
152
+ assert_equal "11",res["frank"], "wrong number for frank"
153
+ end
154
+
155
+ end
156
+
@@ -0,0 +1,45 @@
1
+ # Copyright (c) 2005 Zed A. Shaw
2
+ # You can redistribute it and/or modify it under the same terms as Ruby.
3
+ #
4
+ # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
+ # for more information.
6
+
7
+ require 'test/testhelp'
8
+
9
+ class RedirectHandlerTest < Test::Unit::TestCase
10
+
11
+ def setup
12
+ @port = process_based_port
13
+ redirect_test_io do
14
+ @server = Mongrel::HttpServer.new('127.0.0.1', @port)
15
+ end
16
+ @server.run
17
+ @client = Net::HTTP.new('127.0.0.1', @port)
18
+ end
19
+
20
+ def teardown
21
+ @server.stop(true)
22
+ end
23
+
24
+ def test_simple_redirect
25
+ tester = Mongrel::RedirectHandler.new('/yo')
26
+ @server.register("/test", tester)
27
+
28
+ sleep(1)
29
+ res = @client.request_get('/test')
30
+ assert res != nil, "Didn't get a response"
31
+ assert_equal ['/yo'], res.get_fields('Location')
32
+ end
33
+
34
+ def test_rewrite
35
+ tester = Mongrel::RedirectHandler.new(/(\w+)/, '+\1+')
36
+ @server.register("/test", tester)
37
+
38
+ sleep(1)
39
+ res = @client.request_get('/test/something')
40
+ assert_equal ['/+test+/+something+'], res.get_fields('Location')
41
+ end
42
+
43
+ end
44
+
45
+
@@ -0,0 +1,100 @@
1
+ # Copyright (c) 2005 Zed A. Shaw
2
+ # You can redistribute it and/or modify it under the same terms as Ruby.
3
+ #
4
+ # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
+ # for more information.
6
+
7
+ require 'test/testhelp'
8
+
9
+ class UploadBeginHandler < Mongrel::HttpHandler
10
+ attr_reader :request_began, :request_progressed, :request_processed
11
+
12
+ def initialize
13
+ @request_notify = true
14
+ end
15
+
16
+ def reset
17
+ @request_began = false
18
+ @request_progressed = false
19
+ @request_processed = false
20
+ end
21
+
22
+ def request_begins(params)
23
+ @request_began = true
24
+ end
25
+
26
+ def request_progress(params,len,total)
27
+ @request_progressed = true
28
+ end
29
+
30
+ def process(request, response)
31
+ @request_processed = true
32
+ response.start do |head,body|
33
+ body.write("test")
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ class RequestProgressTest < Test::Unit::TestCase
40
+ def setup
41
+ @port = process_based_port
42
+ redirect_test_io do
43
+ @server = Mongrel::HttpServer.new("127.0.0.1", @port)
44
+ end
45
+ @handler = UploadBeginHandler.new
46
+ @server.register("/upload", @handler)
47
+ @server.run
48
+ end
49
+
50
+ def teardown
51
+ @server.stop(true)
52
+ end
53
+
54
+ def test_begin_end_progress
55
+ Net::HTTP.get("localhost", "/upload", @port)
56
+ assert @handler.request_began
57
+ assert @handler.request_progressed
58
+ assert @handler.request_processed
59
+ end
60
+
61
+ def call_and_assert_handlers_in_turn(handlers)
62
+ # reset all handlers
63
+ handlers.each { |h| h.reset }
64
+
65
+ # make the call
66
+ Net::HTTP.get("localhost", "/upload", @port)
67
+
68
+ # assert that each one was fired
69
+ handlers.each { |h|
70
+ assert h.request_began && h.request_progressed && h.request_processed,
71
+ "Callbacks NOT fired for #{h}"
72
+ }
73
+ end
74
+
75
+ def test_more_than_one_begin_end_progress
76
+ handlers = [@handler]
77
+
78
+ second = UploadBeginHandler.new
79
+ @server.register("/upload", second)
80
+ handlers << second
81
+ call_and_assert_handlers_in_turn(handlers)
82
+
83
+ # check three handlers
84
+ third = UploadBeginHandler.new
85
+ @server.register("/upload", third)
86
+ handlers << third
87
+ call_and_assert_handlers_in_turn(handlers)
88
+
89
+ # remove handlers to make sure they've all gone away
90
+ @server.unregister("/upload")
91
+ handlers.each { |h| h.reset }
92
+ Net::HTTP.get("localhost", "/upload", @port)
93
+ handlers.each { |h|
94
+ assert !h.request_began && !h.request_progressed && !h.request_processed
95
+ }
96
+
97
+ # re-register upload to the state before this test
98
+ @server.register("/upload", @handler)
99
+ end
100
+ end
@@ -0,0 +1,127 @@
1
+ # Copyright (c) 2005 Zed A. Shaw
2
+ # You can redistribute it and/or modify it under the same terms as Ruby.
3
+ #
4
+ # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
+ # for more information.
6
+
7
+ require 'test/testhelp'
8
+
9
+ include Mongrel
10
+
11
+ class ResponseTest < Test::Unit::TestCase
12
+
13
+ def test_response_headers
14
+ out = StringIO.new
15
+ resp = HttpResponse.new(out)
16
+ resp.status = 200
17
+ resp.header["Accept"] = "text/plain"
18
+ resp.header["X-Whatever"] = "stuff"
19
+ resp.body.write("test")
20
+ resp.finished
21
+
22
+ assert out.length > 0, "output didn't have data"
23
+ end
24
+
25
+ def test_response_200
26
+ io = StringIO.new
27
+ resp = HttpResponse.new(io)
28
+ resp.start do |head,out|
29
+ head["Accept"] = "text/plain"
30
+ out.write("tested")
31
+ out.write("hello!")
32
+ end
33
+
34
+ resp.finished
35
+ assert io.length > 0, "output didn't have data"
36
+ end
37
+
38
+ def test_response_duplicate_header_squash
39
+ io = StringIO.new
40
+ resp = HttpResponse.new(io)
41
+ resp.start do |head,out|
42
+ head["Content-Length"] = 30
43
+ head["Content-Length"] = 0
44
+ end
45
+
46
+ resp.finished
47
+
48
+ assert_equal io.length, 95, "too much output"
49
+ end
50
+
51
+
52
+ def test_response_some_duplicates_allowed
53
+ allowed_duplicates = ["Set-Cookie", "Set-Cookie2", "Warning", "WWW-Authenticate"]
54
+ io = StringIO.new
55
+ resp = HttpResponse.new(io)
56
+ resp.start do |head,out|
57
+ allowed_duplicates.each do |dup|
58
+ 10.times do |i|
59
+ head[dup] = i
60
+ end
61
+ end
62
+ end
63
+
64
+ resp.finished
65
+
66
+ assert_equal io.length, 734, "wrong amount of output"
67
+ end
68
+
69
+ def test_response_404
70
+ io = StringIO.new
71
+
72
+ resp = HttpResponse.new(io)
73
+ resp.start(404) do |head,out|
74
+ head['Accept'] = "text/plain"
75
+ out.write("NOT FOUND")
76
+ end
77
+
78
+ resp.finished
79
+ assert io.length > 0, "output didn't have data"
80
+ end
81
+
82
+ def test_response_file
83
+ contents = "PLAIN TEXT\r\nCONTENTS\r\n"
84
+ require 'tempfile'
85
+ tmpf = Tempfile.new("test_response_file")
86
+ tmpf.binmode
87
+ tmpf.write(contents)
88
+ tmpf.rewind
89
+
90
+ io = StringIO.new
91
+ resp = HttpResponse.new(io)
92
+ resp.start(200) do |head,out|
93
+ head['Content-Type'] = 'text/plain'
94
+ resp.send_header
95
+ resp.send_file(tmpf.path)
96
+ end
97
+ io.rewind
98
+ tmpf.close
99
+
100
+ assert io.length > 0, "output didn't have data"
101
+ assert io.read[-contents.length..-1] == contents, "output doesn't end with file payload"
102
+ end
103
+
104
+ def test_response_with_custom_reason
105
+ reason = "You made a bad request"
106
+ io = StringIO.new
107
+ resp = HttpResponse.new(io)
108
+ resp.start(400, false, reason) { |head,out| }
109
+ resp.finished
110
+
111
+ io.rewind
112
+ assert_match(/.* #{reason}$/, io.readline.chomp, "wrong custom reason phrase")
113
+ end
114
+
115
+ def test_response_with_default_reason
116
+ code = 400
117
+ io = StringIO.new
118
+ resp = HttpResponse.new(io)
119
+ resp.start(code) { |head,out| }
120
+ resp.finished
121
+
122
+ io.rewind
123
+ assert_match(/.* #{HTTP_STATUS_CODES[code]}$/, io.readline.chomp, "wrong default reason phrase")
124
+ end
125
+
126
+ end
127
+
@@ -0,0 +1,35 @@
1
+ # Copyright (c) 2005 Zed A. Shaw
2
+ # You can redistribute it and/or modify it under the same terms as Ruby.
3
+ #
4
+ # Additional work donated by contributors. See http://mongrel.rubyforge.org/attributions.html
5
+ # for more information.
6
+
7
+ require 'test/testhelp'
8
+
9
+ class StatsTest < Test::Unit::TestCase
10
+
11
+ def test_sampling_speed
12
+ out = StringIO.new
13
+
14
+ s = Mongrel::Stats.new("test")
15
+ t = Mongrel::Stats.new("time")
16
+
17
+ 100.times { s.sample(rand(20)); t.tick }
18
+
19
+ s.dump("FIRST", out)
20
+ t.dump("FIRST", out)
21
+
22
+ old_mean = s.mean
23
+ old_sd = s.sd
24
+
25
+ s.reset
26
+ t.reset
27
+ 100.times { s.sample(rand(30)); t.tick }
28
+
29
+ s.dump("SECOND", out)
30
+ t.dump("SECOND", out)
31
+ assert_not_equal old_mean, s.mean
32
+ assert_not_equal old_mean, s.sd
33
+ end
34
+
35
+ end