mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
New version for testing connections against a local server for easier setting
up N idle and Z active connections in a controlled manner. This requires a a HTTP server that supports the server end. I have a modified sws for this (from the curl test suite) and I may commit the changes required for that soonish.
This commit is contained in:
parent
e1269e3156
commit
2100311f41
123
hiper/hiper.c
123
hiper/hiper.c
@ -7,7 +7,11 @@
|
|||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
* Connect to N sites simultanouesly and download data.
|
* Connect N connections. Z are idle, and X are active. Transfer as fast as
|
||||||
|
* possible.
|
||||||
|
*
|
||||||
|
* Run for a specific amount of time (10 secs for now). Output detailed timing
|
||||||
|
* information.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -20,12 +24,13 @@
|
|||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
/* The number of simultanoues connections/transfers we do */
|
#define MICROSEC 1000000 /* number of microseconds in one second */
|
||||||
#define NCONNECTIONS 2000
|
|
||||||
|
|
||||||
/* The least number of connections we are interested in, so when we go below
|
/* The maximum number of simultanoues connections/transfers we support */
|
||||||
this amount we can just as well stop */
|
#define NCONNECTIONS 50000
|
||||||
#define NMARGIN 50
|
|
||||||
|
/* The maximum time (in microseconds) we run the test */
|
||||||
|
#define RUN_FOR_THIS_LONG (10*MICROSEC)
|
||||||
|
|
||||||
/* Number of loops (seconds) we allow the total download amount and alive
|
/* Number of loops (seconds) we allow the total download amount and alive
|
||||||
connections to remain the same until we bail out. Set this slightly higher
|
connections to remain the same until we bail out. Set this slightly higher
|
||||||
@ -39,11 +44,20 @@ struct globalinfo {
|
|||||||
struct connection {
|
struct connection {
|
||||||
CURL *e;
|
CURL *e;
|
||||||
int id; /* just a counter for easy browsing */
|
int id; /* just a counter for easy browsing */
|
||||||
char url[80];
|
char *url;
|
||||||
size_t dlcounter;
|
size_t dlcounter;
|
||||||
struct globalinfo *global;
|
struct globalinfo *global;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* on port 8999 we run a modified (fork-) sws that supports pure idle and full
|
||||||
|
stream mode */
|
||||||
|
#define PORT "8999"
|
||||||
|
|
||||||
|
#define HOST "192.168.1.13"
|
||||||
|
|
||||||
|
#define URL_IDLE "http://" HOST ":" PORT "/1000"
|
||||||
|
#define URL_ACTIVE "http://" HOST ":" PORT "/1001"
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
writecallback(void *ptr, size_t size, size_t nmemb, void *data)
|
writecallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||||
{
|
{
|
||||||
@ -124,7 +138,7 @@ static void timer_continue(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static long total; /* amount of us from start to stop */
|
static long total; /* amount of us from start to stop */
|
||||||
static void timer_stop(void)
|
static void timer_total(void)
|
||||||
{
|
{
|
||||||
struct timeval stop;
|
struct timeval stop;
|
||||||
/* Capture the time of the operation stopped moment, now calculate how long
|
/* Capture the time of the operation stopped moment, now calculate how long
|
||||||
@ -147,35 +161,36 @@ long performalive;
|
|||||||
long performselect;
|
long performselect;
|
||||||
long topselect;
|
long topselect;
|
||||||
|
|
||||||
|
int num_total;
|
||||||
|
int num_idle;
|
||||||
|
int num_active;
|
||||||
|
|
||||||
static void report(void)
|
static void report(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
long active = total - paused;
|
long active = total - paused;
|
||||||
long numdl = 0;
|
long numdl = 0;
|
||||||
|
|
||||||
for(i=0; i < NCONNECTIONS; i++) {
|
for(i=0; i < num_total; i++) {
|
||||||
if(conns[i].dlcounter)
|
if(conns[i].dlcounter)
|
||||||
numdl++;
|
numdl++;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Summary from %d simultanoues transfers:\n",
|
printf("Summary from %d simultanoues transfers (%d active)\n",
|
||||||
NCONNECTIONS);
|
num_total, num_active);
|
||||||
|
printf("%d out of %d connections provided data\n", numdl, num_total);
|
||||||
|
|
||||||
printf("Total time %ldus - Paused %ldus = Active %ldus =\n Active/total"
|
printf("Total time: %ldus select(): %ldus curl_multi_perform(): %ldus\n",
|
||||||
" %ldus\n",
|
total, paused, active);
|
||||||
total, paused, active, active/NCONNECTIONS);
|
|
||||||
|
|
||||||
printf(" Active/(connections that delivered data) = %ldus\n",
|
printf("%d calls to curl_multi_perform() average %d alive "
|
||||||
active/numdl);
|
|
||||||
|
|
||||||
printf("%d out of %d connections provided data\n", numdl, NCONNECTIONS);
|
|
||||||
|
|
||||||
printf("%d calls to curl_multi_perform(), average %d alive. "
|
|
||||||
"Average time: %dus\n",
|
"Average time: %dus\n",
|
||||||
perform, performalive/perform, active/perform);
|
perform, performalive/perform, active/perform);
|
||||||
|
|
||||||
printf("%d calls to select(), average %d alive\n",
|
printf("%d calls to select(), average %d alive "
|
||||||
selects, selectsalive/selects);
|
"Average time: %dus\n",
|
||||||
|
selects, selectsalive/selects,
|
||||||
|
paused/selects);
|
||||||
printf(" Average number of readable connections per select() return: %d\n",
|
printf(" Average number of readable connections per select() return: %d\n",
|
||||||
performselect/selects);
|
performselect/selects);
|
||||||
printf(" Max number of readable connections for a single select() "
|
printf(" Max number of readable connections for a single select() "
|
||||||
@ -184,9 +199,10 @@ static void report(void)
|
|||||||
|
|
||||||
printf("%ld select() timeouts\n", timeouts);
|
printf("%ld select() timeouts\n", timeouts);
|
||||||
|
|
||||||
for(i=1; i< NCONNECTIONS; i++) {
|
for(i=1; i< num_total; i++) {
|
||||||
if(timecount[i].laps) {
|
if(timecount[i].laps) {
|
||||||
printf("Time %d connections, average %ld max %ld (%ld laps) average/conn: %ld\n",
|
printf("Time %d connections, average %ld max %ld (%ld laps) "
|
||||||
|
"average/conn: %ld\n",
|
||||||
i,
|
i,
|
||||||
timecount[i].time_us/timecount[i].laps,
|
timecount[i].time_us/timecount[i].laps,
|
||||||
timecount[i].maxtime,
|
timecount[i].maxtime,
|
||||||
@ -204,9 +220,6 @@ int main(int argc, char **argv)
|
|||||||
CURLMcode mcode = CURLM_OK;
|
CURLMcode mcode = CURLM_OK;
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
int i;
|
||||||
FILE *urls;
|
|
||||||
int startindex=0;
|
|
||||||
char buffer[256];
|
|
||||||
|
|
||||||
int prevalive=-1;
|
int prevalive=-1;
|
||||||
int prevsamecounter=0;
|
int prevsamecounter=0;
|
||||||
@ -214,50 +227,38 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
memset(&info, 0, sizeof(struct globalinfo));
|
memset(&info, 0, sizeof(struct globalinfo));
|
||||||
|
|
||||||
if(argc < 2) {
|
if(argc < 3) {
|
||||||
printf("Usage: hiper [file] [start index]\n");
|
printf("Usage: hiper [num idle] [num active]\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
urls = fopen(argv[1], "r");
|
num_idle = atoi(argv[1]);
|
||||||
if(!urls)
|
num_active = atoi(argv[2]);
|
||||||
/* failed to open list of urls */
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if(argc > 2)
|
num_total = num_idle + num_active;
|
||||||
startindex = atoi(argv[2]);
|
|
||||||
|
|
||||||
if(startindex) {
|
if(num_total >= NCONNECTIONS) {
|
||||||
/* Pass this many lines before we start using URLs from the file. On
|
printf("Increase NCONNECTIONS!\n");
|
||||||
repeated invokes, try using different indexes to avoid torturing the
|
return 2;
|
||||||
same servers. */
|
|
||||||
while(startindex--) {
|
|
||||||
if(!fgets(buffer, sizeof(buffer), urls))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init the multi stack */
|
/* init the multi stack */
|
||||||
multi_handle = curl_multi_init();
|
multi_handle = curl_multi_init();
|
||||||
|
|
||||||
for(i=0; i< NCONNECTIONS; i++) {
|
for(i=0; i< num_total; i++) {
|
||||||
CURL *e;
|
CURL *e;
|
||||||
char *nl;
|
char *nl;
|
||||||
|
|
||||||
memset(&conns[i], 0, sizeof(struct connection));
|
memset(&conns[i], 0, sizeof(struct connection));
|
||||||
|
|
||||||
/* read a line from the file of URLs */
|
if(i < num_idle)
|
||||||
if(!fgets(conns[i].url, sizeof(conns[i].url), urls))
|
conns[i].url = URL_IDLE;
|
||||||
/* failed to read a line */
|
else
|
||||||
break;
|
conns[i].url = URL_ACTIVE;
|
||||||
|
|
||||||
/* strip off trailing newlines */
|
|
||||||
nl = strchr(conns[i].url, '\n');
|
|
||||||
if(nl)
|
|
||||||
*nl=0; /* cut */
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
printf("%d: Add URL %s\n", i, conns[i].url);
|
printf("%d: Add URL %s\n", i, conns[i].url);
|
||||||
|
#endif
|
||||||
e = curl_easy_init();
|
e = curl_easy_init();
|
||||||
conns[i].e = e;
|
conns[i].e = e;
|
||||||
conns[i].id = i;
|
conns[i].id = i;
|
||||||
@ -279,7 +280,7 @@ int main(int argc, char **argv)
|
|||||||
while(CURLM_CALL_MULTI_PERFORM ==
|
while(CURLM_CALL_MULTI_PERFORM ==
|
||||||
curl_multi_perform(multi_handle, &still_running));
|
curl_multi_perform(multi_handle, &still_running));
|
||||||
|
|
||||||
printf("Starting timer!\n");
|
printf("Starting timer, expects to run for %ldus\n", RUN_FOR_THIS_LONG);
|
||||||
timer_start();
|
timer_start();
|
||||||
|
|
||||||
while(still_running) {
|
while(still_running) {
|
||||||
@ -307,9 +308,10 @@ int main(int argc, char **argv)
|
|||||||
selectsalive += still_running;
|
selectsalive += still_running;
|
||||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Output this here to make it outside the timer */
|
/* Output this here to make it outside the timer */
|
||||||
printf("Running: %d (%d bytes)\n", still_running, info.dlcounter);
|
printf("Running: %d (%d bytes)\n", still_running, info.dlcounter);
|
||||||
|
#endif
|
||||||
timer_continue();
|
timer_continue();
|
||||||
|
|
||||||
switch(rc) {
|
switch(rc) {
|
||||||
@ -332,9 +334,9 @@ int main(int argc, char **argv)
|
|||||||
topselect = rc;
|
topselect = rc;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(still_running < NMARGIN) {
|
|
||||||
printf("Only %d connections left alive, existing\n",
|
if(total > RUN_FOR_THIS_LONG) {
|
||||||
still_running);
|
printf("Stopped after %ldus\n", total);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,10 +363,9 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
prevalive = still_running;
|
prevalive = still_running;
|
||||||
prevtotal = info.dlcounter;
|
prevtotal = info.dlcounter;
|
||||||
|
timer_total(); /* calculate the total time spent so far */
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_stop();
|
|
||||||
|
|
||||||
curl_multi_cleanup(multi_handle);
|
curl_multi_cleanup(multi_handle);
|
||||||
|
|
||||||
/* cleanup all the easy handles */
|
/* cleanup all the easy handles */
|
||||||
|
Loading…
Reference in New Issue
Block a user