flood_profile.h (88 lines of code) (raw):

/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Originally developed by Aaron Bannert and Justin Erenkrantz, eBuilt. */ #ifndef __profile_h #define __profile_h #include <apr_network_io.h> /* Required for apr_socket_t */ #include <apr_tables.h> /* Required for apr_table_t */ #include <apr_pools.h> #include <apr_uri.h> #include "flood_config.h" /* Required for config_t */ /* Symbolic definitions for response verification results. * 0 is valid, non-zero is a type of invalid. */ #define FLOOD_VALID 0 #define FLOOD_INVALID 1 /* The type of buffers that are allowable internally in the flood * architecture. Normally, test clients will not be concerned with * this. */ enum buffer_type_e { HEAP, POOL, FD, MMAP }; typedef enum buffer_type_e buffer_type_e; /* Allowable HTTP methods that the flood architecture currently has * knowledge of. */ enum method_e { GET, POST, HEAD, OTHER }; typedef enum method_e method_e; /** * Holds the socket information. */ typedef void socket_t; /* Define a single request that can be transmitted with the flood * architecture. */ struct request_t { /* The basic components to connect to the server */ char * uri; method_e method; int keepalive; /* a boolean */ /* Following only valid when method == POST */ apr_size_t payloadsize; void * payload; apr_size_t contenttypesize; char * contenttype; apr_uri_t *parsed_uri; apr_uri_t *parsed_proxy_uri; /* Raw buffer connection * FIXME: apr_bucket_t? */ buffer_type_e rbuftype; void * rbuf; apr_size_t rbufsize; /* If this is set, we want to keep the *entire* response. */ int wantresponse; /* Mandatory for keepalives - although we aren't handling keepalives * just yet... */ socket_t *rsock; apr_pool_t *pool; }; typedef struct request_t request_t; /* Define a single response that may be returned with the flood * architecture. */ struct response_t { /* a boolean */ int keepalive; /* a boolean */ int chunked; char *chunk; /* Raw buffer connection * FIXME: apr_bucket_t? */ buffer_type_e rbuftype; char *rbuf; apr_size_t rbufsize; apr_table_t *headers; }; typedef struct response_t response_t; /* Define a timer. */ struct flood_timer_t { apr_time_t begin; apr_time_t connect; apr_time_t write; apr_time_t read; apr_time_t close; }; typedef struct flood_timer_t flood_timer_t; /** * profile_t holds all stateful data needed during the running of * a test. For example, if we wanted to test a single URL 10 times * and then quit, profile_t would hold that URL plus a counter. * The actual data stored in profile_t is specific to the implementation * of the test. */ typedef void profile_t; /** * Opaque data to hold any type of reporting data. */ typedef void report_t; struct profile_events_t { /* Profile Events */ /** * Reads a config_t object and creates any state necessary for this * run of a test profile. This routine is typically run only once * per single instance of a test profile. * Returns: State object for this instance of a test profile. */ apr_status_t (*profile_init)(profile_t **profile, config_t *config, const char *profile_name, apr_pool_t *pool); /** * Reads the profile state (profile_t), retrieves the next request * (really the next URL) in this test profile, and prepares a * request. * Returns: A prepared HTTP Request object, ready to send. */ apr_status_t (*get_next_url)(request_t **request, profile_t *profile); /** * Construct the request to be sent to the server. */ apr_status_t (*create_req)(profile_t *p, request_t *r); /** * Does any post processing on this request cycle. This is where * SetCookie handling goes, or any other client-side-state. * (also stuff like "Follow Location: redirects). * Returns APR_SUCCESS or else some APR_* error. */ apr_status_t (*postprocess)(profile_t *profile, request_t *req, response_t *resp); /** * Test to see if this test profile will continue with further tests or * complete. * Returns: boolean */ int (*loop_condition)(profile_t *profile); /** * Destroy this profile. Cleanup routines that complement the above * profile_init function. This function is called only after the * test has successfully completed. * Returns: apr_status_t signifying completion status */ apr_status_t (*profile_destroy)(profile_t *profile); /* Reporting Events */ /** * Create/initialize a report structure that will be associated with * this profile and will exist for the same lifetime as this profile. * However, the data stored in this report is not coupled with the * profile data, and the implementation may vary. * Returns: APR_SUCCESS and sets report to the new instance, or * an appropriate error otherwise. */ apr_status_t (*report_init)(report_t **report, config_t *config, const char *profile_name, apr_pool_t *pool); /** * Callback to this test profile so it can report on this particular * HTTP transaction. It is guaranteed that this function is called only once * per HTTP transaction, and immediatly after "verify_resp" is called. * Returns: boolean status of this function. */ apr_status_t (*process_stats)(report_t *report, int verified, request_t *req, response_t *resp, flood_timer_t *timer); /** * Generate a report on all statistical information * gathered during this run of the profile. */ apr_status_t (*report_stats)(report_t *report); /** * Destroy the report structure associated with this proile. * Returns: APR_SUCCESS or an appropriate error. */ apr_status_t (*destroy_report)(report_t *report); /* Socket Events */ /** * Create and initialize the communication channel that * we'll use for this test. */ apr_status_t (*socket_init)(socket_t **sock, apr_pool_t *pool); /** * Opens the communication channel to the server. */ apr_status_t (*begin_conn)(socket_t *sock, request_t *req, apr_pool_t *pool); /** * Actually sends the request to the server. Implementation will fit * an HTTP function or some OS performance capability. */ apr_status_t (*send_req)(socket_t *sock, request_t *req, apr_pool_t *pool); /** * Receives the request from the server. Implementation will test * some function of HTTP or some OS performance capability. */ apr_status_t (*recv_resp)(response_t **resp, socket_t *sock, apr_pool_t *pool); /** * Tears down the communication channel to the server. Called once per pass * through main request/response loop. Implementation typically closes * the socket. */ apr_status_t (*end_conn)(socket_t *sock, request_t *req, response_t *resp); /** * Destroy the given request, which should be the request used * during this pass of the test. This is called at the end * of every successful pass through the test loop. */ apr_status_t (*request_destroy)(request_t *req); /** * Destroy the given response, which should be the response used * during this pass of the test. This is called at the end * of every successful pass through the test loop. * Returns: apr_status_t signifying completion status */ apr_status_t (*response_destroy)(response_t *resp); /** * Destroy the socket used during with this pass, for some * request/response pair. This is called at the end of * every successful pass through the test loop. * Returns: apr_status_t signifying completion status */ apr_status_t (*socket_destroy)(socket_t *socket); /* Verify Events */ /** * Tests this HTTP transaction (both Request and Response) to see if it * is valid for this particular test profile. Also may need access to the * state data for this test profile. * Returns: boolean determining if this request/response was valid. */ apr_status_t (*verify_resp)(int *verified, profile_t *profile, request_t *req, response_t *resp); }; typedef struct profile_events_t profile_events_t; apr_status_t run_profile(apr_pool_t *pool, config_t *config, const char *profile_name); #endif /* __profile_h */