1 /****************************************************************************
2  *                                                                          *
3  * The contents of this file are subject to the WebStone Public License     *
4  * Version 1.0 (the "License"); you may not use this file except in         *
5  * compliance with the License. You may obtain a copy of the License        *
6  * at http://www.mindcraft.com/webstone/license10.html                      *
7  *                                                                          *
8  * Software distributed under the License is distributed on an "AS IS"      *
9  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See      *
10  * the License for the specific language governing rights and limitations   *
11  * under the License.                                                       *
12  *                                                                          *
13  * The Original Code is WebStone 2.5.                                       *
14  *                                                                          *
15  * The Initial Developer of the Original Code is Silicon Graphics, Inc.     *
16  * and Mindcraft, Inc.. Portions created by Silicon Graphics. and           *
17  * Mindcraft. are Copyright (C) 1995-1998 Silicon Graphics, Inc. and        *
18  * Mindcraft, Inc. All Rights Reserved.                                     *
19  *                                                                          *
20  * Contributor(s): ______________________________________.                  *
21  *                                                                          *
22  * @(#) bench.c 2.4@(#)                                                     *
23  ***************************************************************************/
24 
25 #ifndef __BENCH_H__
26 #define __BENCH_H__
27 
28 
29 #include <stdio.h>
30 #include <stdarg.h>
31 
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif	/* HAVE_UNISTD_H */
35 
36 #ifndef WIN32
37 #include <sys/time.h>
38 #endif /* WIN32 */
39 
40 #define USECINSEC	    1000000
41 #define MSECINSEC	    1000
42 #define MAX_ACCEPT_SECS	    180	/* maximum time master will wait for listen() */
43 
44 #define NCCARGS		    4096
45 #define MAXCLIENTS	    1024
46 #define MAXUSERNAME	    25
47 #define MAXPASSWD	    20
48 #define BUFSIZE		    4096
49 
50 #define MAXTOTALPROCS	    MAXCLIENTS		/* overall max # of procs */
51 #define MAXPROCSPERNODE	    MAXCLIENTS		/* max # of procs/node */
52 
53 /*
54  * This is the number of times a webclient will try to connect to the
55  * webmaster.  It will sleep CONNECT_TRY_DELAY_SEC between each attempt.
56  * If you have a slow network between master and clients or slow client
57  * systems then you might try increasing this.
58  */
59 #define MAX_MASTER_CONNECT_TRIES 30
60 #define CONNECT_TRY_DELAY_SEC    1
61 
62 #define CONTENT_LENGTH_STRING	"CONTENT-LENGTH:"
63 #define OKSTR		    "OK"
64 #define OKSTRLEN	    ((int)strlen(OKSTR))
65 #define GOSTR		    "GO"
66 #define GOSTRLEN	    ((int)strlen(GOSTR))
67 #define READYSTR	    "READY"
68 #define READYSTRLEN	    ((int)strlen(READYSTR))
69 #define ABORTSTR	    "ABORT"
70 #define ABORTSTRLEN	    ((int)strlen(ABORTSTR))
71 #define ENDTOKEN	   "EndOfFileList\n"
72 #define ENDTOKENSTRLEN	((int)strlen(ENDTOKEN))
73 
74 
75 #define MAXNUMOFFILES 1	    /* max # of files per page */
76 #define URL_SIZE	    1024
77 #define MAXNUMOFPAGES	    100
78 
79 
80 /*
81  * SIZEOF_TIMEVALTEXT needs to be at least as long as the number of characters
82  * in LONG_MAX.
83  */
84 #define SIZEOF_TIMEVALTEXT  18
85 
86 
87 /*
88  * SIZEOF_DOUBLETEXT needs to be at least as long as the number of characters
89  * in DBL_MAX when it is printed without scientific notation.
90  */
91 #define SIZEOF_DOUBLETEXT   400
92 
93 
94 #define SIZEOF_RQSTSTATSTEXT ((7 *  SIZEOF_TIMEVALTEXT) + \
95 			      (12 * SIZEOF_DOUBLETEXT) + 1)
96 #define SIZEOF_STATSTEXTBASE    (SIZEOF_RQSTSTATSTEXT + \
97 			     (3 * SIZEOF_TIMEVALTEXT) + \
98 			     (2 * SIZEOF_DOUBLETEXT) + 1)
99 #define SIZEOF_STATSTEXT   (SIZEOF_STATSTEXTBASE + MAXNUMOFPAGES * SIZEOF_DOUBLETEXT)
100 #define SIZEOF_PAGESTATSTEXT (SIZEOF_RQSTSTATSTEXT + \
101 			      (0 * SIZEOF_TIMEVALTEXT) + \
102 			      (3 * SIZEOF_DOUBLETEXT) + 1)
103 
104 /*
105  * The values of the debug variable are:
106  *		DEBUG_OFF		-- No debugging output.
107  *		DEBUG_TRACE		-- All D_TRACE() statements.  Intended for function
108  *							entry and exit.
109  *		DEBUG_ALL		-- Enable all debugging output.  This can be quite
110  *							voluminous and severely impact performance.
111  */
112 #define DEBUG_OFF	0
113 #define DEBUG_TRACE	1
114 #define DEBUG_MORE	2
115 #define DEBUG_ALL	(DEBUG_TRACE | DEBUG_MORE)
116 
117 #define DEBUGGING_ON	(debug == DEBUG_ALL)
118 #define TRACING_ON		(debug & DEBUG_TRACE)
119 #define DEBUGGING_ANY	(debug)
120 
121 #define TRACE			TRACING_ON && d_printf
122 #define D_PRINTF		DEBUGGING_ON && d_printf
123 #define D_STRVAL(arg)	((arg) == NULL ? "(NULL)" : arg)
124 
125 
126 #ifdef USE_TIMEZONE
127 typedef struct rqst_timer {
128     struct timeval		entertime;
129     struct timezone		entertimezone;
130     struct timeval		beforeconnect;
131     struct timezone		beforeconnectzone;
132     struct timeval		afterconnect;
133     struct timezone		afterconnectzone;
134     struct timeval		beforeheader;
135     struct timezone		beforeheaderzone;
136     struct timeval		afterheader;
137     struct timezone		afterheaderzone;
138     struct timeval		afterbody;
139     struct timezone		afterbodyzone;
140     struct timeval		exittime;
141     struct timezone		exittimezone;
142     long unsigned int	totalbytes;
143     long unsigned int	bodybytes;
144     int					valid;
145     long unsigned int 	page_number;
146 } rqst_timer_t;
147 #else
148 typedef struct rqst_timer {
149     struct timeval		entertime;
150     struct timeval		beforeconnect;
151     struct timeval		afterconnect;
152     struct timeval		beforeheader;
153     struct timeval		afterheader;
154     struct timeval		afterbody;
155     struct timeval		exittime;
156     long unsigned int	totalbytes;
157     long unsigned int	bodybytes;
158     int					valid;
159     long unsigned int 	page_number;
160 } rqst_timer_t;
161 #endif /* USE_TIMEZONE */
162 
163 extern void rqtimer_init(rqst_timer_t *);
164 
165 #ifdef USE_TIMEZONE
166 typedef struct rqst_stats {
167 	struct timeval		totalresponsetime;
168 	struct timezone		totalresponsetimezone;
169 	double				totalresponsetimesq;
170 	struct timeval		minresponsetime;
171 	struct timezone		minresponsetimezone;
172 	struct timeval		maxresponsetime;
173 	struct timezone		maxresponsetimezone;
174 	struct timeval		totalconnecttime;
175 	struct timezone		totalconnecttimezone;
176 	double				totalconnecttimesq;
177 	struct timeval		minconnecttime;
178 	struct timezone		minconnecttimezone;
179 	struct timeval		maxconnecttime;
180 	struct timezone		maxconnecttimezone;
181 	long unsigned int	totalconnects;
182 	long unsigned int	totalerrs;
183 	struct timeval		totalerrortime;
184 	struct timezone		totalerrortimezone;
185 	double				totalbytes;
186 	double				totalbytessq;
187 	double				minbytes;
188 	double				maxbytes;
189 	double				totalbody;
190 	double				totalbodysq;
191 	double				minbody;
192 	double				maxbody;
193 }	rqst_stats_t;
194 #else
195 typedef	struct rqst_stats	{
196 	struct timeval		totalresponsetime;
197 	double				totalresponsetimesq;
198 	struct timeval		minresponsetime;
199 	struct timeval		maxresponsetime;
200 	struct timeval		totalconnecttime;
201 	double				totalconnecttimesq;
202 	struct timeval		minconnecttime;
203 	struct timeval		maxconnecttime;
204 	long unsigned int	totalconnects;
205 	long unsigned int	totalerrs;
206 	struct timeval		totalerrortime;
207 	double				totalbytes;
208 	double				totalbytessq;
209 	double				minbytes;
210 	double				maxbytes;
211 	double				totalbody;
212 	double				totalbodysq;
213 	double				minbody;
214 	double				maxbody;
215 } rqst_stats_t;
216 #endif /* USE_TIMEZONE */
217 
218 extern void rqstat_init(rqst_stats_t *);
219 extern void rqstat_sum(rqst_stats_t *, rqst_stats_t *);
220 extern void rqstat_print(rqst_stats_t *);
221 extern void rqstat_fprint(FILE *, rqst_stats_t *);
222 extern void rqstat_times(rqst_stats_t *, rqst_timer_t *);
223 
224 #ifdef USE_TIMEZONE
225 typedef struct stats {
226     rqst_stats_t		rs;
227     struct timeval		starttime;			/* start of test run */
228     struct timezone		starttimezone;
229     struct timeval		endtime;			/* end of test run */
230     struct timezone		endtimezone;
231     struct timeval		datatime;
232     struct timezone		datatimezone;
233     long unsigned int	totalpages;
234     unsigned int		total_num_of_files;
235     unsigned int		page_numbers[MAXNUMOFPAGES];
236 } stats_t;
237 #else
238 typedef struct stats {
239     rqst_stats_t		rs;
240     struct timeval		starttime;			/* start of test run */
241     struct timeval		endtime;			/* end of test run */
242     struct timeval		datatime;
243     long unsigned int	totalpages;
244     unsigned int		total_num_of_files;
245     unsigned int		page_numbers[MAXNUMOFPAGES];
246 } stats_t;
247 #endif /* USE_TIMEZONE */
248 
249 extern void stats_init(stats_t *);
250 extern stats_t * text_to_stats(char *);
251 extern char * stats_to_text(const stats_t *);
252 
253 
254 /*
255  * page_stats: structure to hold data for each "page" we are retrieving from
256  *             the web server.
257  * 	rs         -- Request statistics for this page
258  *  totalpages -- The number of times this page was fetched from the web
259  *                server.  At the end of the run this should be equal (or
260  *                very close) to the page's "weight".
261  *  page_valid -- temporary flag used to indicate that a page was successfully
262  *                retrieved from the web server.
263  */
264 typedef struct page_stats {
265     rqst_stats_t		rs;
266     long unsigned int	totalpages;
267     unsigned int		page_size;
268     int					page_valid;
269 } page_stats_t;
270 
271 extern void page_stats_init(page_stats_t *);
272 extern page_stats_t * text_to_page_stats(char *);
273 extern char * page_stats_to_text(const page_stats_t *);
274 
275 
276 /*
277  * This structure defines a page to be retrieved from the web server.
278  *
279  * load_num     -- the weight assigned to a URL in the "filelist" file.
280  * num_of_files -- this is unused (it will always be set to 1) since we don't
281  *                 currently support the ability to group several files on
282  *                 one "page".
283  * filename     -- this is the name of the file to be retrieved from the web
284  *                 server.
285  * servername   -- if this line came from a "filelist" file and is of the
286  *                 form "http://server/file" then this will be the "server"
287  *                 Thus each line in the "filelist" file can hit a different
288  *                 web server.  If, instead, the line was of the form
289  *                 "/dir1/file.html" then this will be NULL and the web
290  *                 server specified on the webclient command line will be
291  *                 used instead.
292  * port_number  -- if this line came from a "filelist" file and is of the form
293  *                 "http://server:port/file.html" then this will be the port
294  *                 specified in that line.  If, the line was of the form
295  *                 "http://server/file.html" then this will default to 80.
296  *                 If the line was just "/file.html" then this will be set
297  *                 to 0 and the port specified on the webclient command line
298  *                 will be used instead.
299  *
300  */
301 typedef struct page_list {
302     int 		load_num;
303     int 		num_of_files;
304     char		*(filename[MAXNUMOFFILES]);
305     char		*(servername[MAXNUMOFFILES]);
306     int			port_number[MAXNUMOFFILES];
307 }page_list_t;
308 
309 
310 
311 /* shared variables */
312 extern THREAD FILE *debugfile;
313 extern int debug;
314 
315 extern int	savefile;
316 extern int	timeexpired;
317 extern long int number_of_pages;
318 
319 /* routines in bench.c */
320 
321 extern void *mymalloc(size_t size);
322 extern int recvdata(SOCKET sock, char *ptr, int nbytes);
323 extern int senddata(SOCKET sock, char *ptr, int nbytes);
324 extern void rqstat_times(rqst_stats_t *rs, rqst_timer_t *rt);
325 /* note several others listed above */
326 
327 /* routines in errexit.c */
328 
329 void errexit(const char *, ...);
330 extern int returnerr(const char *, ...);
331 extern int d_printf(const char *, ...);
332 extern char *neterrstr(void);
333 
334 /* routines in get.c */
335 
336 extern int  get(char *loc, NETPORT port, char *url, rqst_timer_t *timer);
337 
338 /* routines in parse_file_list.c */
339 
340 extern void parse_file_list (FILE *fp, page_list_t *page_list,
341 		 long int *num_of_pages, long int *num_of_files);
342 extern long int load_percent(page_list_t *page_list, long int number_of_pages);
343 
344 /* routines in statistics.c (formerly statistics.h) */
345 
346 extern double	mean(const double, const int);
347 extern double	variance(const double, const double, const int);
348 extern double	stddev(const double, const double, const int);
349 
350 /* routines in timefunc.c (formerly timefunc.h) */
351 
352 extern double	timevaldouble(struct timeval *);
353 extern void	doubletimeval(const double, struct timeval *);
354 
355 extern void	addtime(struct timeval *, struct timeval *);
356 extern void	compdifftime(struct timeval *, struct timeval *, struct timeval *);
357 extern void	mintime(struct timeval *, struct timeval *);
358 extern void	maxtime(struct timeval *, struct timeval *);
359 extern void	avgtime(struct timeval *, int, struct timeval *);
360 extern void	variancetime(struct timeval *, double, int, struct timeval *);
361 extern void	stddevtime(struct timeval *, double, int, struct timeval *);
362 
363 extern void	sqtime(struct timeval *, struct timeval *);
364 
365 extern double	thruputpersec(const double, struct timeval *);
366 
367 /* routines in webclient.c */
368 
369 extern SOCKET connectsock(char *host, NETPORT portnum, char *protocol);
370 
371 #endif /* !__BENCH_H__ */
372