Flood Design Document
----------------------------------------
Flood is an experimental multi-purpose HTTP load-testing tool.
The design of flood is intended to be modular in the extreme to
support testing of a wide variety of website applications.
Flood is also intended to be scalable and accurate.
------------------------------
Functional Requirements:
------------------------------
The following is a list of functions we intend to incorporate into flood:
1) Timing Metrics
a) TCP connect() time
b) Time to send request (time to fill local buffers)
c) Time until first response chunk was received
(tests network latency at the application layer (HTTP))
d) Time to receive a full response
e) (optional) Local Processing times, such as time to generate the Request
2) Simple response error detection
3) Load testing a set of URLs:
a) Random
b) Round-Robin
c) Sequenced (with cookie propogation)
d) Chaining of the above strategies
4) Distributed load generation (using rsh/ssh)
5) Complex response validation
a) grep/regexp matching
b) higher-level validation?
6) Complex request generation
a) Spider a site to generate a list of URLs
b) Read a CERN log to generate URL paths from real users
(could also add weights to the URLs depending on the occurance in the logs)
c) Read a tcpdump/sniff packet trace to generate URL paths
------------------------------
Functional Specifications:
------------------------------
With the above functional goals in mind, the following components will have
to be designed and implemented:
1) Request/Response framework
- Every hit to the site passes through this sequence of calls.
2) Timer hooks in the framework as well as a generic timer facility
- Hooks are placed to properly gauge request generation time, network
I/O time, round-trip time, network latency as well as bandwidth,
local processing time, etc...
- Hook facilities also allow module authors to time various aspects of
their processes, and aggregate them into the final report.
3) Simple distributed processing environment:
- Patterned after distributed models like cvs or rsync that use
rsh/ssh to invoke a remote process. Statistics from this remote
process must be regular and should ideally follow a standardized
reporting format.
4) Simple Reporting Format (? might be overengineering ?)
- A simple format used to report statistics between modules, may they
be remote processes or otherwise out-of-process.
- I envision this being some really simple XML schema that all processes
use to report data back to the terminal, where the originating process
collects this data, processes, and reports in various formats (XML,
human-readable, etc...)
(more to come)
------------------------------
Design Specifications:
------------------------------
------------------------------
Modular Test Framework
Flood provides the control logic that will invoke a test procedure and
collect reported statistics. Tests are modular, and conform to this
simple invocation interface. In order to simplify the task of a module
developer, flood also provides an extensive support library.
------------------------------
Test Invocation:
Tests are invoked with a standard interface.
[ proposal:
typedef unsigned int testid_t; /* unique test id across this invocation of flood
(including fork()s and remote invocations */
apr_status_t invoke_test(config_t * config, /* to be defined */
testid_t testid);
]
------------------------------
Transaction Reporting:
All tests will collect and process operating statistics and report these
back to the controlling process via standard calls. The following statistics
are required from every module and for each HTTP transaction:
- TCP Handshake time ( time spent in connect() )
- Application-layer latency (Time to receive first HTTP bytes)
- Idle time (total time spent waiting for data)
- Response time (total time to receive the HTTP Response)
? - Total Transaction Time
[ proposal:
apr_status_t report_stats(const char * test_name, /* short name/description */
int test_number, /* unique to this test */
apr_status_t test_result, /* success, failure */
apr_interval_t tcp,
apr_interval_t first_resp,
apr_interval_t idle,
apr_interval_t total_resp,
apr_interval_t total);
]
------------------------------
Module Configuration:
[ mentioned above in "config_t", needs to be elaborated here.
- what is the config syntax?
- what is the definition of config_t?
- what support functions do modules use to retrieve config values?
- what if a needed key/value is missing?
]
------------------------------
Flood Support Library:
The support library provides many of the functions necessary to write
a conforming test module.
[ define this more, or move documentation to another file...
I hate to suggest it, but maybe preparsed XML (apr supports it, no?)
]
------------------------------
Local Parallel Tests:
Given the above scenarios, one may wish to perform many tests in parallel.
Flood provides two major way to accomplish this: Threaded and Forked.
These two methods can actually be performed at the same time, allowing
for fine-grain control of local resources to maximize test throughput.
Threaded:
The process is instructed to make a number of user-space threads,
each of which will perform a complex event chain as described above. For
the purpose of this document, each thread that performs an actual test
is called a "worker".
Forked:
The process is instructed to make multiple duplicate copies of itself
using the fork() system command, each of which can run one test
or can run a threaded/parallelized group of tests. For the purpose
of this document, each fork()ed process is called a "child".
------------------------------
Distributed Tests:
Further parallelization of the tests is possible, given access to a number
of remote machines. Flood can invoke a remote instance of itself with
either the "rsh" or "ssh" remote shell commands. These instances of flood
are special, in that they do not report directly back to the user, but
instead communicate their statistical information back to the main
flood process, which aggregates the information and generates a human
readable report.
------------------------------
Interprocess Communication:
In such a largely scalable and distributable system, one of the larger
hurdles will be interprocess communication. One can imagine scenarios
where a main flood process has spawned many remote instances, each of
which (including the original) will fork into many children processes,
each of which will run multiple parallelized testing event chains.
When this massive invocation has completed, the user will be presented
with a single unified report. To deal with this communication, a
protocol must be designed to facilitate IPC.
[ propose a protocol here, perhaps XML? ]
----------------------------------------
$Id$