rfuzz 0.6

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 (136) hide show
  1. data/COPYING +55 -0
  2. data/LICENSE +55 -0
  3. data/README +252 -0
  4. data/Rakefile +48 -0
  5. data/doc/rdoc/classes/RFuzz.html +146 -0
  6. data/doc/rdoc/classes/RFuzz/HttpClient.html +481 -0
  7. data/doc/rdoc/classes/RFuzz/HttpClient.src/M000010.html +24 -0
  8. data/doc/rdoc/classes/RFuzz/HttpClient.src/M000011.html +34 -0
  9. data/doc/rdoc/classes/RFuzz/HttpClient.src/M000012.html +49 -0
  10. data/doc/rdoc/classes/RFuzz/HttpClient.src/M000013.html +49 -0
  11. data/doc/rdoc/classes/RFuzz/HttpClient.src/M000014.html +57 -0
  12. data/doc/rdoc/classes/RFuzz/HttpClient.src/M000015.html +37 -0
  13. data/doc/rdoc/classes/RFuzz/HttpClient.src/M000016.html +26 -0
  14. data/doc/rdoc/classes/RFuzz/HttpClient.src/M000017.html +34 -0
  15. data/doc/rdoc/classes/RFuzz/HttpClient.src/M000018.html +18 -0
  16. data/doc/rdoc/classes/RFuzz/HttpClient.src/M000019.html +26 -0
  17. data/doc/rdoc/classes/RFuzz/HttpEncoding.html +294 -0
  18. data/doc/rdoc/classes/RFuzz/HttpEncoding.src/M000001.html +26 -0
  19. data/doc/rdoc/classes/RFuzz/HttpEncoding.src/M000002.html +18 -0
  20. data/doc/rdoc/classes/RFuzz/HttpEncoding.src/M000003.html +26 -0
  21. data/doc/rdoc/classes/RFuzz/HttpEncoding.src/M000004.html +18 -0
  22. data/doc/rdoc/classes/RFuzz/HttpEncoding.src/M000005.html +32 -0
  23. data/doc/rdoc/classes/RFuzz/HttpEncoding.src/M000006.html +18 -0
  24. data/doc/rdoc/classes/RFuzz/HttpEncoding.src/M000007.html +20 -0
  25. data/doc/rdoc/classes/RFuzz/HttpEncoding.src/M000008.html +20 -0
  26. data/doc/rdoc/classes/RFuzz/HttpEncoding.src/M000009.html +32 -0
  27. data/doc/rdoc/classes/RFuzz/HttpResponse.html +180 -0
  28. data/doc/rdoc/classes/RFuzz/Notifier.html +252 -0
  29. data/doc/rdoc/classes/RFuzz/Notifier.src/M000044.html +17 -0
  30. data/doc/rdoc/classes/RFuzz/Notifier.src/M000045.html +17 -0
  31. data/doc/rdoc/classes/RFuzz/Notifier.src/M000046.html +17 -0
  32. data/doc/rdoc/classes/RFuzz/Notifier.src/M000047.html +17 -0
  33. data/doc/rdoc/classes/RFuzz/Notifier.src/M000048.html +17 -0
  34. data/doc/rdoc/classes/RFuzz/Notifier.src/M000049.html +17 -0
  35. data/doc/rdoc/classes/RFuzz/RandomGenerator.html +362 -0
  36. data/doc/rdoc/classes/RFuzz/RandomGenerator.src/M000032.html +21 -0
  37. data/doc/rdoc/classes/RFuzz/RandomGenerator.src/M000033.html +23 -0
  38. data/doc/rdoc/classes/RFuzz/RandomGenerator.src/M000036.html +22 -0
  39. data/doc/rdoc/classes/RFuzz/RandomGenerator.src/M000037.html +20 -0
  40. data/doc/rdoc/classes/RFuzz/RandomGenerator.src/M000038.html +22 -0
  41. data/doc/rdoc/classes/RFuzz/RandomGenerator.src/M000039.html +20 -0
  42. data/doc/rdoc/classes/RFuzz/RandomGenerator.src/M000040.html +18 -0
  43. data/doc/rdoc/classes/RFuzz/RandomGenerator.src/M000041.html +18 -0
  44. data/doc/rdoc/classes/RFuzz/RandomGenerator.src/M000042.html +22 -0
  45. data/doc/rdoc/classes/RFuzz/RandomGenerator.src/M000043.html +18 -0
  46. data/doc/rdoc/classes/RFuzz/Sampler.html +383 -0
  47. data/doc/rdoc/classes/RFuzz/Sampler.src/M000056.html +19 -0
  48. data/doc/rdoc/classes/RFuzz/Sampler.src/M000057.html +23 -0
  49. data/doc/rdoc/classes/RFuzz/Sampler.src/M000058.html +26 -0
  50. data/doc/rdoc/classes/RFuzz/Sampler.src/M000059.html +18 -0
  51. data/doc/rdoc/classes/RFuzz/Sampler.src/M000060.html +18 -0
  52. data/doc/rdoc/classes/RFuzz/Sampler.src/M000061.html +18 -0
  53. data/doc/rdoc/classes/RFuzz/Sampler.src/M000062.html +18 -0
  54. data/doc/rdoc/classes/RFuzz/Sampler.src/M000063.html +19 -0
  55. data/doc/rdoc/classes/RFuzz/Sampler.src/M000064.html +18 -0
  56. data/doc/rdoc/classes/RFuzz/Sampler.src/M000065.html +23 -0
  57. data/doc/rdoc/classes/RFuzz/Sampler.src/M000066.html +18 -0
  58. data/doc/rdoc/classes/RFuzz/Sampler.src/M000067.html +20 -0
  59. data/doc/rdoc/classes/RFuzz/Session.html +415 -0
  60. data/doc/rdoc/classes/RFuzz/Session.src/M000020.html +31 -0
  61. data/doc/rdoc/classes/RFuzz/Session.src/M000021.html +18 -0
  62. data/doc/rdoc/classes/RFuzz/Session.src/M000022.html +18 -0
  63. data/doc/rdoc/classes/RFuzz/Session.src/M000023.html +34 -0
  64. data/doc/rdoc/classes/RFuzz/Session.src/M000024.html +19 -0
  65. data/doc/rdoc/classes/RFuzz/Session.src/M000025.html +19 -0
  66. data/doc/rdoc/classes/RFuzz/Session.src/M000026.html +26 -0
  67. data/doc/rdoc/classes/RFuzz/Session.src/M000027.html +29 -0
  68. data/doc/rdoc/classes/RFuzz/Session.src/M000028.html +19 -0
  69. data/doc/rdoc/classes/RFuzz/Session.src/M000029.html +18 -0
  70. data/doc/rdoc/classes/RFuzz/Session.src/M000030.html +18 -0
  71. data/doc/rdoc/classes/RFuzz/Session.src/M000031.html +23 -0
  72. data/doc/rdoc/classes/RFuzz/StatsTracker.html +242 -0
  73. data/doc/rdoc/classes/RFuzz/StatsTracker.src/M000050.html +19 -0
  74. data/doc/rdoc/classes/RFuzz/StatsTracker.src/M000051.html +19 -0
  75. data/doc/rdoc/classes/RFuzz/StatsTracker.src/M000052.html +18 -0
  76. data/doc/rdoc/classes/RFuzz/StatsTracker.src/M000053.html +18 -0
  77. data/doc/rdoc/classes/RFuzz/StatsTracker.src/M000054.html +28 -0
  78. data/doc/rdoc/classes/RFuzz/StatsTracker.src/M000055.html +18 -0
  79. data/doc/rdoc/created.rid +1 -0
  80. data/doc/rdoc/files/COPYING.html +168 -0
  81. data/doc/rdoc/files/LICENSE.html +168 -0
  82. data/doc/rdoc/files/README.html +473 -0
  83. data/doc/rdoc/files/lib/rfuzz/client_rb.html +111 -0
  84. data/doc/rdoc/files/lib/rfuzz/random_rb.html +116 -0
  85. data/doc/rdoc/files/lib/rfuzz/rfuzz_rb.html +109 -0
  86. data/doc/rdoc/files/lib/rfuzz/session_rb.html +111 -0
  87. data/doc/rdoc/files/lib/rfuzz/stats_rb.html +113 -0
  88. data/doc/rdoc/fr_class_index.html +35 -0
  89. data/doc/rdoc/fr_file_index.html +34 -0
  90. data/doc/rdoc/fr_method_index.html +93 -0
  91. data/doc/rdoc/index.html +24 -0
  92. data/doc/rdoc/rdoc-style.css +208 -0
  93. data/examples/amazon_headers.rb +38 -0
  94. data/examples/hpricot_pudding.rb +22 -0
  95. data/examples/kill_routes.rb +26 -0
  96. data/examples/mongrel_test_suite/lib/gen.rb +24 -0
  97. data/examples/mongrel_test_suite/test/camping/static_files.rb +9 -0
  98. data/examples/mongrel_test_suite/test/camping/upload_file.rb +9 -0
  99. data/examples/mongrel_test_suite/test/camping/upload_progress.rb +9 -0
  100. data/examples/mongrel_test_suite/test/http/base_protocol.rb +23 -0
  101. data/examples/mongrel_test_suite/test/nitro/upload_file.rb +9 -0
  102. data/examples/mongrel_test_suite/test/nitro/upload_progress.rb +9 -0
  103. data/examples/mongrel_test_suite/test/rails/static_files.rb +9 -0
  104. data/examples/mongrel_test_suite/test/rails/upload_file.rb +9 -0
  105. data/examples/mongrel_test_suite/test/rails/upload_progress.rb +9 -0
  106. data/examples/perftest.rb +30 -0
  107. data/ext/fuzzrnd/ext_help.h +14 -0
  108. data/ext/fuzzrnd/extconf.rb +6 -0
  109. data/ext/fuzzrnd/fuzzrnd.c +149 -0
  110. data/ext/http11_client/ext_help.h +14 -0
  111. data/ext/http11_client/extconf.rb +6 -0
  112. data/ext/http11_client/http11_client.c +288 -0
  113. data/ext/http11_client/http11_parser.c +629 -0
  114. data/ext/http11_client/http11_parser.h +46 -0
  115. data/ext/http11_client/http11_parser.rl +169 -0
  116. data/lib/rfuzz/client.rb +498 -0
  117. data/lib/rfuzz/random.rb +110 -0
  118. data/lib/rfuzz/rfuzz.rb +12 -0
  119. data/lib/rfuzz/session.rb +154 -0
  120. data/lib/rfuzz/stats.rb +159 -0
  121. data/resources/defaults.yaml +2 -0
  122. data/resources/words.txt +3310 -0
  123. data/test/coverage/index.html +388 -0
  124. data/test/coverage/lib-rfuzz-client_rb.html +1127 -0
  125. data/test/coverage/lib-rfuzz-random_rb.html +739 -0
  126. data/test/coverage/lib-rfuzz-session_rb.html +783 -0
  127. data/test/coverage/lib-rfuzz-stats_rb.html +788 -0
  128. data/test/server.rb +101 -0
  129. data/test/test_client.rb +164 -0
  130. data/test/test_fuzzrnd.rb +31 -0
  131. data/test/test_httpparser.rb +48 -0
  132. data/test/test_random.rb +75 -0
  133. data/test/test_session.rb +33 -0
  134. data/test/test_stats.rb +45 -0
  135. data/tools/rakehelp.rb +119 -0
  136. metadata +201 -0
data/COPYING ADDED
@@ -0,0 +1,55 @@
1
+ RFuzz HTTP Destroyer (RFuzz) is copyrighted free software by Zed A. Shaw
2
+ <zedshaw at zedshaw dot com> You can redistribute it and/or modify it under
3
+ either the terms of the GPL or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise make them
13
+ Freely Available, such as by posting said modifications to Usenet or an
14
+ equivalent medium, or by allowing the author to include your
15
+ modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) rename any non-standard executables so the names do not conflict with
21
+ standard executables, which must also be provided.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or executable
26
+ form, provided that you do at least ONE of the following:
27
+
28
+ a) distribute the executables and library files of the software,
29
+ together with instructions (in the manual page or equivalent) on where
30
+ to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of the
33
+ software.
34
+
35
+ c) give non-standard executables non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under this terms.
43
+
44
+ 5. The scripts and library files supplied as input to or produced as
45
+ output from the software do not automatically fall under the
46
+ copyright of the software, but belong to whomever generated them,
47
+ and may be sold commercially, and may be aggregated with this
48
+ software.
49
+
50
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
51
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
52
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53
+ PURPOSE.
54
+
55
+
data/LICENSE ADDED
@@ -0,0 +1,55 @@
1
+ RFuzz HTTP Destroyer (RFuzz) is copyrighted free software by Zed A. Shaw
2
+ <zedshaw at zedshaw dot com> You can redistribute it and/or modify it under
3
+ either the terms of the GPL or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise make them
13
+ Freely Available, such as by posting said modifications to Usenet or an
14
+ equivalent medium, or by allowing the author to include your
15
+ modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) rename any non-standard executables so the names do not conflict with
21
+ standard executables, which must also be provided.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or executable
26
+ form, provided that you do at least ONE of the following:
27
+
28
+ a) distribute the executables and library files of the software,
29
+ together with instructions (in the manual page or equivalent) on where
30
+ to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of the
33
+ software.
34
+
35
+ c) give non-standard executables non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under this terms.
43
+
44
+ 5. The scripts and library files supplied as input to or produced as
45
+ output from the software do not automatically fall under the
46
+ copyright of the software, but belong to whomever generated them,
47
+ and may be sold commercially, and may be aggregated with this
48
+ software.
49
+
50
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
51
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
52
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53
+ PURPOSE.
54
+
55
+
data/README ADDED
@@ -0,0 +1,252 @@
1
+ = RFuzz HTTP Destroyer
2
+
3
+ RFuzz is the start of a Ruby based HTTP thrasher, destroyer, fuzzer, and client
4
+ based on the Mongrel project's HTTP parser and the statistical analysis of
5
+ being very mean to a web server.
6
+
7
+ At the moment is has a working and fairly extensive HTTP 1.1 client and some
8
+ basic statistics math borrowed from the Mongrel project.
9
+
10
+ In order for the test cases to run you need to start any Rails project on
11
+ port 3000. Future releases will have tests starting built-in Mongrel servers to
12
+ validate client functionality.
13
+
14
+
15
+ == Motivation
16
+
17
+ The motivation for RFuzz comes from little scripts I've written during Mongrel
18
+ development to "fuzz" or attack the Mongrel code.
19
+
20
+ RFuzz will simply use the built-in ultra-correct HTTP client and a Ruby DSL to
21
+ let you write scripts that exploit servers, thrash them with random data, or
22
+ simply run simple test suites.
23
+
24
+ It may also perform analysis of performance data and work as a simply load or
25
+ pen testing tool. This is only a secondary goal though since there's plenty of
26
+ good tools for that.
27
+
28
+ == Downloading
29
+
30
+ Right now RFuzz just sits on my server, so you can download
31
+ http://www.zedshaw.com/projects/rfuzz/rfuzz-0.4.gem or
32
+ http://www.zedshaw.com/projects/rfuzz/rfuzz-0.4.tgz
33
+ for the 0.4 version.
34
+
35
+ Once it can actually be used to fuzz a system I'll make a RubyForge project.
36
+
37
+ == RFuzz HTTP Client
38
+
39
+ It also comes from not being satisfied with the stock net/http library. While
40
+ this library is good for high-level HTTP access to resources, it is much too
41
+ abstract and protective to be used in a fuzzing tool.
42
+
43
+ In a tool such as RFuzz you need to have the following features in an HTTP
44
+ client library:
45
+
46
+ 1. No protection from exceptions to analyze exactly what's happening.
47
+ 2. Ability to "throttle" the client to simulate different kinds of request loads.
48
+ 3. No threading or additional overhead to test the impact of threads, but thread safe.
49
+ 4. Ability to encode the majority of the request as data elements for loading.
50
+ 5. Fast and exact HTTP parser to validate the server's response is correct.
51
+ 6. Tracks cookies between requests to keep session data going.
52
+
53
+ RFuzz::HttpClient supports all of these features already, with cookies being
54
+ the weakest right now.
55
+
56
+ === Using The Client
57
+
58
+ The client is designed that you create an RFuzz::HttpClient object once with
59
+ all the common parameters and the host you want to talk with, and then you call
60
+ a series of methods on the client object that match the HTTP methods GET, POST,
61
+ PUT, DELETE, and HEAD. You can add more methods if you like (see the documentation).
62
+
63
+ Here's a simple example:
64
+
65
+ require 'rfuzz/client'
66
+
67
+ cl = RFuzz::HttpClient.new("www.google.com", 80, :query => {"q" => "zed shaw"})
68
+
69
+ resp = cl.get("/search")
70
+ resp.http_body.grep(/zed/)
71
+ => ["<html><head><meta HTTP-EQUIV=\"content-type\" CONTENT=\"text/html;
72
+ charset=ISO-8859-1\"><title>zed shaw - Google Search</title><style><!--\n"]
73
+
74
+ resp = cl.get("/search", :query => {"q" => "frank"})
75
+ => ["<html><head><meta HTTP-EQUIV=\"content-type\" CONTENT=\"text/html;
76
+ charset=ISO-8859-1\"><title>frank - Google Search</title><style><!--\n"]
77
+
78
+ Notice that we made a client that actually had a default :query to just search for
79
+ my name (Zed Shaw) and then we only had to cl.get("/search"). In the second
80
+ query though we just set :query to something else (a search for "frank") and it
81
+ automatically overrides the parameters. This makes it possible to set common
82
+ parameters, cookies, and headers in blocks of requests to reduce repetition.
83
+
84
+ === Client Limitations
85
+
86
+ You can use the HTTP client right now to do HTTP requests and it is probably a
87
+ lot easier than net/http for most requests that don't require complex POST bodies
88
+ encoding. It also contains full documentation and has a full suite of encoding
89
+ and decoding libraries. It can't handle large HTTP bodies yet.
90
+
91
+ It can't also parse cookies properly yet, so the above example kind of works, but the
92
+ cookie isn't returned right.
93
+
94
+ == Randomness Generator
95
+
96
+ RFuzz features a RandomGenerator class that uses the ArcFour random number
97
+ generation algorithm to generate lots of random garbage very fast in various
98
+ formats. RFuzz will use this to send the garbage it needs to the application
99
+ in an attempt to find forms that can't handle nastiness, badly implemented
100
+ servers, etc. It's amazing how many bugs you actually can find by sending
101
+ junk to an application.
102
+
103
+ The types of randomness you can generate are:
104
+
105
+ * words -- RFuzz includes a simple word list, but you can add your own.
106
+ * base64 -- Arrays of base64 encoded junk.
107
+ * byte_array -- Arrays of just junk.
108
+ * uris -- Arrays of URIs composed of words strung together with /.
109
+ * ints -- Random integers (with an allowed maximum).
110
+ * floats -- Random floats.
111
+ * headers,queries -- Hashes of key=value where the keys and values can be any of the above.
112
+
113
+ The ArcFour fuzzrnd random generator is in a C extension so it's small and fast.
114
+ A big advantage of fuzzrnd is that it generates the same stream of random bytes
115
+ for the same input seeds. This lets you set a seed and then if you find an
116
+ error replay the same attack but still have random data.
117
+
118
+ An example of using RandomGenerator is:
119
+
120
+ g = RFuzz::RandomGenerator.new(open("resources/words.txt").read.split("\n"))
121
+ h = g.headers(2,4,type=:ints)
122
+ => [{1398667391=>2615968266, 465122870=>2683411899, 2100652296=>4131806743,
123
+ 158954822=>2544978312}, {3126281447=>2247028995, 269763016=>1444943723,
124
+ 2401569363=>1661839605, 2811294153=>400252371}]
125
+
126
+ As you can see this produces 2 hashes consisting of 4 key=value pairs with integers in them. You can quickly replace type=:ints with type=:words and get:
127
+
128
+ => [{"Europeanizes"=>"Byronize's", "royalization's"=>"Americanizer's",
129
+ "celiorrhea"=>"unliteralized", "unvictimized"=>"doctrinize"},
130
+ {"pouder"=>"unchloridized", "chattelize"=>"unmodernize",
131
+ "uncrystallizability"=>"uncenter", "Egyptianization's"=>"ostracization's"}]
132
+
133
+ Using the included dictionary of words.
134
+
135
+ = Fuzzing Sessions And Statistics
136
+
137
+ The main way that you'll use RFuzz is to use the RFuzz::Session class to
138
+ perform RFuzz runs and store the results in various .csv files for analysis
139
+ later. RFuzz makes the stance that it shouldn't be used for analyzing the
140
+ data, but rather it should generate information that you can put through
141
+ a better tool. Examples of such tools are R, gnuplot, ploticus, or a spreadsheet.
142
+
143
+ The Session class is initialized in a similar fashion to the HttpClient, except
144
+ you can't set the :notifier (it's used to collect statistics about the requests).
145
+ Once you have a Session object you call it's Session#run method to do a run
146
+ of a set of samples and then put your tests inside a block.
147
+
148
+ When a run is done it saves the results to two CSV files so you can analyze them.
149
+
150
+ Here's a small sample of how Session is used:
151
+
152
+ require 'rfuzz/session'
153
+ include RFuzz
154
+ s = Session.new :host => "localhost", :port => 3000
155
+ s.run 5, :save_as => ["runs.csv","counts.csv"] do |c,r|
156
+ uris = r.uris(50,r.num(30))
157
+ uris.each do |u|
158
+ s.count_errors(:words) do
159
+ resp = c.get(u)
160
+ s.count resp.http_status
161
+ end
162
+ end
163
+ end
164
+
165
+ If you run this (having a server at localhost:3000) you'll find two
166
+ files in the current directory: runs.csv and counts.csv. These files
167
+ might look like this:
168
+
169
+ -- runs.csv --
170
+ run,name,sum,sumsq,n,mean,sd,min,max
171
+ 0,request,0.517807,0.010310748693,50.0,0.01035614,0.0100491312529583,0.001729,0.074479
172
+ 1,request,0.48696,0.010552774434,50.0,0.0097392,0.0108892135376889,0.001667,0.081887
173
+ 2,request,0.322049,0.004898592637,50.0,0.00644098,0.00759199560893725,0.000806,0.057761
174
+ 3,request,0.271233,0.004324191489,50.0,0.00542466,0.00763028964494234,0.000828,0.057182
175
+ 4,request,0.27697,0.001659079814,50.0,0.0055394,0.00159611899203497,0.000791,0.010722
176
+
177
+ -- counts.csv --
178
+ run,404,200
179
+ 0,46,4
180
+ 1,41,9
181
+ 2,48,2
182
+ 3,42,8
183
+ 4,49,1
184
+
185
+ You can then easily load these two files into any tool you want to analyze
186
+ the results.
187
+
188
+ === Counts vs. Samples vs. Runs
189
+
190
+ Something many people don't do correctly which RFuzz tries to implicitly
191
+ enforce is that doing just one run isn't as useful as doing a set of
192
+ runs. You might not be familiar with the terminology, so let's cover that
193
+ first.
194
+
195
+ * count -- Just a simple count of some variable during a run.
196
+ * sample -- A sample is the result of taking a measurement during a run.
197
+ * run -- This is a test that you perform and then collect counts and samples for.
198
+
199
+ In the above sample script, we are doing the following:
200
+
201
+ * 5 runs.
202
+ * That do GET requests for up to 50 randomly selected URIs.
203
+ * Counting errors, HTTP status codes.
204
+ * And gathers stats on the request timing (Session does this automatically).
205
+
206
+ If you were to structure this into a data structure it would like this:
207
+
208
+ [
209
+ ["run", "name", "sum", "sumsq", "n", "mean", "sd", "min", "max"],
210
+ [0, :request, 0.605363, 0.0149, 50.0, 0.0121, 0.0124, 0.00851, 0.095579],
211
+ [1, :request, 0.520827, 0.0116, 50.0, 0.0104, 0.0112, 0.00189, 0.088004],
212
+ ...
213
+ ]
214
+
215
+ Taking a look at this, we have run 0, run 1, ... and then each "row" has a
216
+ set of satistics we've gathered on the HTTP request (shown as "name"). These
217
+ statistics are actually generated from the random 50 URI requests we built
218
+ with this set of code:
219
+
220
+ uris = r.uris(50,r.num(30))
221
+
222
+ Which means that each row is the statistics collected as each request is made
223
+ from the 50 randomly generated URIs. If I were to write this out it'd be:
224
+
225
+ 1. Generate 50 random URIs.
226
+ 2. Request URIs 1-50, record how long each one takes.
227
+ 3. Average (with standard deviation) the times for each request.
228
+ 4. Store this as one "run".
229
+ 5. Repeat until all the runs are done.
230
+
231
+ By doing this you cut down on the amount of information you need to analyze
232
+ to figure out if a server is behaving correctly. Instead of wading through
233
+ tons of data about each request, you just analyze the "meta-statistics" about
234
+ the runs.
235
+
236
+ === Sample Runs Reduce Error
237
+
238
+ The reason for doing a series of runs and analyzing their standard deviation (sd)
239
+ and means is that it reduces the chance that one long run was just done at the
240
+ wrong time or in the wrong situation. If you just ran a test once with the
241
+ same settings every time you might not find out until later that there was
242
+ some confounding element which made the test invalid.
243
+
244
+
245
+ == Source Code
246
+
247
+ The .tgz file (mentioned Downloading) has the source if you're interested. Remember
248
+ that *you must have a rails app on 3000* for the tests to run. Just a limitation
249
+ right now until I hook Mongrel into the test framework as the feedback loop.
250
+
251
+ You can also view http://www.zedshaw.com/projects/rfuzz/coverage/ for the rcov
252
+ generated coverage report which is also a decent source browser.
@@ -0,0 +1,48 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/clean'
4
+ require 'rake/gempackagetask'
5
+ require 'rake/rdoctask'
6
+ require 'tools/rakehelp'
7
+ require 'fileutils'
8
+ include FileUtils
9
+
10
+ setup_tests
11
+ setup_clean ["pkg", "lib/*.bundle", "*.gem", ".config"]
12
+
13
+ setup_rdoc ['README', 'LICENSE', 'COPYING', 'lib/**/*.rb', 'doc/**/*.rdoc']
14
+
15
+ setup_extension('http11_client','http11_client')
16
+ setup_extension('fuzzrnd','fuzzrnd')
17
+
18
+ desc "Does a full compile, test run"
19
+ task :default => [:http11_client, :fuzzrnd, :test]
20
+
21
+ version="0.6"
22
+ name="rfuzz"
23
+
24
+ setup_gem(name, version) do |spec|
25
+ spec.summary = "The rfuzz web server destructor"
26
+ spec.description = spec.summary
27
+ spec.author="Zed A. Shaw"
28
+ spec.add_dependency("mongrel",">= 0.3.13.3")
29
+ spec.files += Dir.glob("resources/**/*")
30
+ spec.files += Dir.glob("ext/**/*.rl")
31
+ end
32
+
33
+
34
+ task :ragel do
35
+ sh %{/usr/local/bin/ragel ext/http11_client/http11_parser.rl | /usr/local/bin/rlcodegen -G2 -o ext/http11_client/http11_parser.c}
36
+ end
37
+
38
+ task :install => [:test, :package] do
39
+ sh %{sudo gem install pkg/#{name}-#{version}.gem}
40
+ end
41
+
42
+ task :uninstall => [:clean] do
43
+ sh %{sudo gem uninstall #{name}}
44
+ end
45
+
46
+ task :project => [:clean, :ragel, :default, :test, :rdoc, :rcov, :package] do
47
+ sh %{scp -r doc/rdoc test/coverage @rubyforge.org:/var/www/gforge-projects/rfuzz/}
48
+ end
@@ -0,0 +1,146 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>Module: RFuzz</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="classHeader">
50
+ <table class="header-table">
51
+ <tr class="top-aligned-row">
52
+ <td><strong>Module</strong></td>
53
+ <td class="class-name-in-header">RFuzz</td>
54
+ </tr>
55
+ <tr class="top-aligned-row">
56
+ <td><strong>In:</strong></td>
57
+ <td>
58
+ <a href="../files/lib/rfuzz/random_rb.html">
59
+ lib/rfuzz/random.rb
60
+ </a>
61
+ <br />
62
+ <a href="../files/lib/rfuzz/client_rb.html">
63
+ lib/rfuzz/client.rb
64
+ </a>
65
+ <br />
66
+ <a href="../files/lib/rfuzz/stats_rb.html">
67
+ lib/rfuzz/stats.rb
68
+ </a>
69
+ <br />
70
+ <a href="../files/lib/rfuzz/session_rb.html">
71
+ lib/rfuzz/session.rb
72
+ </a>
73
+ <br />
74
+ </td>
75
+ </tr>
76
+
77
+ </table>
78
+ </div>
79
+ <!-- banner header -->
80
+
81
+ <div id="bodyContent">
82
+
83
+
84
+
85
+ <div id="contextContent">
86
+
87
+ <div id="description">
88
+ <p>
89
+ A very simple little class for doing some basic fast statistics sampling.
90
+ You feed it either samples of numeric data you want measured or you call <a
91
+ href="RFuzz/Sampler.html#M000067">Sampler.tick</a> to get it to add a time
92
+ delta between the last time you called it. When you&#8217;re done either
93
+ call sum, sumsq, n, min, max, mean or sd to get the information. The other
94
+ option is to just call dump and see everything.
95
+ </p>
96
+ <p>
97
+ It does all of this very fast and doesn&#8217;t take up any memory since
98
+ the samples are not stored but instead all the values are calculated on the
99
+ fly.
100
+ </p>
101
+
102
+ </div>
103
+
104
+
105
+ </div>
106
+
107
+
108
+ </div>
109
+
110
+
111
+ <!-- if includes -->
112
+
113
+ <div id="section">
114
+
115
+ <div id="class-list">
116
+ <h3 class="section-bar">Classes and Modules</h3>
117
+
118
+ Module <a href="RFuzz/HttpEncoding.html" class="link">RFuzz::HttpEncoding</a><br />
119
+ Class <a href="RFuzz/HttpClient.html" class="link">RFuzz::HttpClient</a><br />
120
+ Class <a href="RFuzz/HttpResponse.html" class="link">RFuzz::HttpResponse</a><br />
121
+ Class <a href="RFuzz/Notifier.html" class="link">RFuzz::Notifier</a><br />
122
+ Class <a href="RFuzz/RandomGenerator.html" class="link">RFuzz::RandomGenerator</a><br />
123
+ Class <a href="RFuzz/Sampler.html" class="link">RFuzz::Sampler</a><br />
124
+ Class <a href="RFuzz/Session.html" class="link">RFuzz::Session</a><br />
125
+ Class <a href="RFuzz/StatsTracker.html" class="link">RFuzz::StatsTracker</a><br />
126
+
127
+ </div>
128
+
129
+
130
+
131
+
132
+
133
+
134
+
135
+ <!-- if method_list -->
136
+
137
+
138
+ </div>
139
+
140
+
141
+ <div id="validator-badges">
142
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
143
+ </div>
144
+
145
+ </body>
146
+ </html>