/[hyperestraier]/upstream/0.5.0/estload.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /upstream/0.5.0/estload.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Fri Jul 29 21:52:03 2005 UTC (18 years, 10 months ago) by dpavlin
File MIME type: text/plain
File size: 9711 byte(s)
import of HyperEstraier 0.5.0

1 dpavlin 1 /*************************************************************************************************
2     * The load tester for web applications
3     * Copyright (C) 2004-2005 Mikio Hirabayashi
4     * This file is part of Hyper Estraier.
5     * Hyper Estraier is free software; you can redistribute it and/or modify it under the terms of
6     * the GNU Lesser General Public License as published by the Free Software Foundation; either
7     * version 2.1 of the License or any later version. Hyper Estraier is distributed in the hope
8     * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
9     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10     * License for more details.
11     * You should have received a copy of the GNU Lesser General Public License along with Hyper
12     * Estraier; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
13     * Boston, MA 02111-1307 USA.
14     *************************************************************************************************/
15    
16    
17     #include "estraier.h"
18     #include "estmtdb.h"
19     #include "estnode.h"
20     #include "myconf.h"
21    
22     #define AGENTNAME "estload" /* name of the user agent */
23     #define IOBUFSIZ 8192 /* size of a buffer for I/O */
24    
25     typedef struct { /* type of structure for a target URL */
26     char *host; /* hostname */
27     char *addr; /* IP address */
28     int port; /* port number */
29     char *auth; /* authority */
30     char *path; /* path */
31     char *query; /* query string */
32     } TARGET;
33    
34     typedef struct { /* type of structure for a worker thread */
35     int id; /* ID number */
36     int ims; /* interval time in milliseconds */
37     int pb; /* to print received data */
38     int qb; /* to be quiet */
39     CBLIST *targets; /* list of targets */
40     int alive; /* to be alive */
41     } MISSION;
42    
43    
44     /* global variables */
45     const char *g_progname; /* program name */
46    
47    
48     /* function prototypes */
49     int main(int argc, char **argv);
50     static void usage(void);
51     static void printferror(const char *format, ...);
52     static void printfinfo(const char *format, ...);
53     static int procmain(const char *file, int tnum, int lnum, int ims, int pb, int qb);
54     static void *procthread(void *arg);
55    
56    
57     /* main routine */
58     int main(int argc, char **argv){
59     char *file;
60     int i, tnum, lnum, ims, pb, qb, rv;
61     cbstdiobin();
62     g_progname = argv[0];
63     if(!est_init_net_env()){
64     printferror("could not initialize network environment");
65     exit(1);
66     }
67     file = NULL;
68     tnum = 1;
69     lnum = 1;
70     ims = 0;
71     pb = FALSE;
72     qb = FALSE;
73     for(i = 1; i < argc; i++){
74     if(!file && argv[i][0] == '-'){
75     if(!strcmp(argv[i], "-t")){
76     if(++i >= argc) usage();
77     tnum = atoi(argv[i]);
78     } else if(!strcmp(argv[i], "-l")){
79     if(++i >= argc) usage();
80     lnum = atoi(argv[i]);
81     } else if(!strcmp(argv[i], "-i")){
82     if(++i >= argc) usage();
83     ims = atoi(argv[i]);
84     } else if(!strcmp(argv[i], "-p")){
85     pb = TRUE;
86     } else if(!strcmp(argv[i], "-q")){
87     qb = TRUE;
88     } else {
89     usage();
90     }
91     } else if(!file){
92     file = argv[i];
93     } else {
94     usage();
95     }
96     }
97     if(!file || tnum < 1 || lnum < 1) usage();
98     rv = procmain(file, tnum, lnum, ims, pb, qb);
99     return rv;
100     }
101    
102    
103     /* print the usage and exit */
104     static void usage(void){
105     fprintf(stderr, "%s: stresser for web applications\n", g_progname);
106     fprintf(stderr, "\n");
107     fprintf(stderr, "usage:\n");
108     fprintf(stderr, " %s [-t num] [-l num] [-i num] [-p] [-q] [file|url]\n", g_progname);
109     fprintf(stderr, "\n");
110     exit(1);
111     }
112    
113    
114     /* print formatted error string and flush the buffer */
115     static void printferror(const char *format, ...){
116     va_list ap;
117     va_start(ap, format);
118     fprintf(stderr, "%s: ERROR: ", g_progname);
119     vfprintf(stderr, format, ap);
120     fputc('\n', stderr);
121     fflush(stderr);
122     va_end(ap);
123     }
124    
125    
126     /* print formatted information string and flush the buffer */
127     static void printfinfo(const char *format, ...){
128     va_list ap;
129     va_start(ap, format);
130     printf("%s: INFO: ", g_progname);
131     vprintf(format, ap);
132     putchar('\n');
133     fflush(stdout);
134     va_end(ap);
135     }
136    
137    
138     /* proc the main command */
139     static int procmain(const char *file, int tnum, int lnum, int ims, int pb, int qb){
140     pthread_t *threads;
141     MISSION *missions;
142     TARGET target;
143     CBLIST *list;
144     CBMAP *elems;
145     const char *line, *host, *pstr, *auth, *path, *query;
146     int i, j, cnt, pnum, err;
147     double etime;
148     if(cbstrfwimatch(file, "http://")){
149     list = cblistopen();
150     cblistpush(list, file, -1);
151     } else if(!(list = cbreadlines(file))){
152     printferror("%s: could not open", file);
153     return 1;
154     }
155     threads = cbmalloc(tnum * sizeof(pthread_t));
156     missions = cbmalloc(tnum * sizeof(MISSION));
157     for(i = 0; i < tnum; i++){
158     missions[i].id = i + 1;
159     missions[i].ims = ims;
160     missions[i].pb = pb;
161     missions[i].qb = qb;
162     missions[i].targets = cblistopen();
163     }
164     cnt = 0;
165     for(i = 0; i < lnum; i++){
166     for(j = 0; j < cblistnum(list); j++){
167     line = cblistval(list, j, NULL);
168     if((line[0] == '\0')) continue;
169     elems = cburlbreak(line);
170     host = cbmapget(elems, "host", -1, NULL);
171     pnum = (pstr = cbmapget(elems, "port", -1, NULL)) ? atoi(pstr) : 80;
172     auth = cbmapget(elems, "authority", -1, NULL);
173     path = cbmapget(elems, "path", -1, NULL);
174     query = cbmapget(elems, "query", -1, NULL);
175     if(!host || pnum < 1){
176     printferror("%s: invalid URL", line);
177     cbmapclose(elems);
178     continue;
179     }
180     if(!auth) auth = "";
181     if(!path) path = "/";
182     if(!query) query = "";
183     if(!(target.addr = est_get_host_addr(host))){
184     printferror("%s: unknown host", host);
185     cbmapclose(elems);
186     continue;
187     }
188     target.host = cbmemdup(host, -1);
189     target.port = pnum;
190     target.auth = cbmemdup(auth, -1);
191     target.path = cbmemdup(path, -1);
192     target.query = cbmemdup(query, -1);
193     cblistpush(missions[cnt++%tnum].targets, (char *)&target, sizeof(TARGET));
194     cbmapclose(elems);
195     }
196     }
197     cblistclose(list);
198     err = FALSE;
199     etime = est_gettimeofday();
200     if(tnum > 1){
201     for(i = 0; i < tnum; i++){
202     missions[i].alive = FALSE;
203     if(pthread_create(threads + i, NULL, procthread, missions + i) == 0){
204     missions[i].alive = TRUE;
205     } else {
206     printferror("thread creation failed");
207     err = TRUE;
208     }
209     }
210     for(i = 0; i < tnum; i++){
211     if(!missions[i].alive) continue;
212     if(pthread_join(threads[i], NULL) != 0){
213     printferror("thread join failed");
214     err = TRUE;
215     }
216     }
217     } else {
218     procthread(missions);
219     }
220     etime = est_gettimeofday() - etime;
221     if(cnt > 0 && !err)
222     printfinfo("finished: elepsed time: %.3f sec. (average: %.3f)",
223     etime / 1000, etime / cnt / 1000);
224     for(i = 0; i < tnum; i++){
225     for(j = 0; j < cblistnum(missions[i].targets); j++){
226     target = *(TARGET *)cblistval(missions[i].targets, j, NULL);
227     free(target.query);
228     free(target.path);
229     free(target.auth);
230     free(target.addr);
231     free(target.host);
232     }
233     cblistclose(missions[i].targets);
234     }
235     free(missions);
236     free(threads);
237     return err ? 1 : 0;
238     }
239    
240    
241     /* process as a child thread */
242     static void *procthread(void *arg){
243     CBLIST *targets;
244     TARGET target;
245     char iobuf[IOBUFSIZ], *wp, *tmp;
246     int i, id, ims, pb, qb, clsock, size;
247     double etime;
248     targets = ((MISSION *)arg)->targets;
249     id = ((MISSION *)arg)->id;
250     ims = ((MISSION *)arg)->ims;
251     pb = ((MISSION *)arg)->pb;
252     qb = ((MISSION *)arg)->qb;
253     if(cblistnum(targets) < 1) return NULL;
254     printfinfo("%d: started", id);
255     etime = est_gettimeofday();
256     for(i = 0; i < cblistnum(targets); i++){
257     target = *(TARGET *)cblistval(targets, i, NULL);
258     if(!qb) printfinfo("%d(%d/%d): http://%s:%d%s%s%s",
259     id, i + 1, cblistnum(targets), target.host, target.port,
260     target.path, target.query[0] != '\0' ? "?" : "", target.query);
261     if((clsock = est_get_client_sock(target.addr, target.port)) != -1){
262     wp = iobuf;
263     wp += sprintf(wp, "GET %s%s%s HTTP/1.0\r\n",
264     target.path, target.query[0] != '\0' ? "?" : "", target.query);
265     wp += sprintf(wp, "Host: %s:%d\r\n", target.host, target.port);
266     wp += sprintf(wp, "Connection: close\r\n");
267     if(target.auth[0] != '\0'){
268     tmp = cbbaseencode(target.auth, -1);
269     wp += sprintf(wp, "Authorization: Basic %s\r\n", tmp);
270     free(tmp);
271     }
272     wp += sprintf(wp, "Referer: http://%s:%d%s%s%s\r\n", target.host, target.port,
273     target.path, target.query[0] != '\0' ? "?" : "", target.query);
274     wp += sprintf(wp, "User-Agent: %s/%s\r\n", AGENTNAME, est_version);
275     wp += sprintf(wp, "\r\n");
276     est_sock_send_all(clsock, iobuf, wp - iobuf);
277     while((size = recv(clsock, iobuf, IOBUFSIZ, 0)) > 0){
278     if(pb) fwrite(iobuf, 1, size, stdout);
279     }
280     est_sock_down(clsock);
281     } else {
282     printferror("%d(%d/%d): connection failed", id, i + 1, cblistnum(targets));
283     }
284     if(ims > 0) est_usleep(ims * 1000);
285     }
286     etime = est_gettimeofday() - etime;
287     printfinfo("%d: finished: elapsed time: %.3f sec. (average: %.3f)",
288     id, etime / 1000, etime / cblistnum(targets) / 1000);
289     return NULL;
290     }
291    
292    
293    
294     /* END OF FILE */

  ViewVC Help
Powered by ViewVC 1.1.26