Load cups into easysw/current.
[thirdparty/cups.git] / scheduler / testspeed.c
1 /*
2  * "$Id: testspeed.c 4800 2005-10-18 18:06:20Z mike $"
3  *
4  *   Scheduler speed test for the Common UNIX Printing System (CUPS).
5  *
6  *   Copyright 1997-2005 by Easy Software Products.
7  *
8  *   These coded instructions, statements, and computer programs are the
9  *   property of Easy Software Products and are protected by Federal
10  *   copyright law.  Distribution and use rights are outlined in the file
11  *   "LICENSE.txt" which should have been included with this file.  If this
12  *   file is missing or damaged please contact Easy Software Products
13  *   at:
14  *
15  *       Attn: CUPS Licensing Information
16  *       Easy Software Products
17  *       44141 Airport View Drive, Suite 204
18  *       Hollywood, Maryland 20636 USA
19  *
20  *       Voice: (301) 373-9600
21  *       EMail: cups-info@cups.org
22  *         WWW: http://www.cups.org
23  *
24  * Contents:
25  *
26  *   main() - Send multiple IPP requests and report on the average response
27  *            time.
28  */
29
30 /*
31  * Include necessary headers...
32  */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <ctype.h>
37 #include <sys/types.h>
38 #include <sys/time.h>
39 #include <sys/wait.h>
40 #include <cups/cups.h>
41 #include <cups/language.h>
42 #include <cups/debug.h>
43 #include <errno.h>
44
45
46 /*
47  * Local functions...
48  */
49
50 int     do_test(const char *server, http_encryption_t encryption,
51                 int requests, int verbose);
52 void    usage(void);
53
54
55 /*
56  * 'main()' - Send multiple IPP requests and report on the average response
57  *            time.
58  */
59
60 int
61 main(int  argc,                         /* I - Number of command-line arguments */
62      char *argv[])                      /* I - Command-line arguments */
63 {
64   int           i;                      /* Looping var */
65   const char    *server;                /* Server to use */
66   http_encryption_t encryption;         /* Encryption to use */
67   int           requests;               /* Number of requests to send */
68   int           children;               /* Number of children to fork */
69   int           pid;                    /* Child PID */
70   int           status;                 /* Child status */
71   time_t        start,                  /* Start time */
72                 end;                    /* End time */
73   double        elapsed;                /* Elapsed time */
74   int           verbose;                /* Verbosity */
75
76
77  /*
78   * Parse command-line options...
79   */
80
81   requests   = 100;
82   children   = 5;
83   server     = cupsServer();
84   encryption = HTTP_ENCRYPT_IF_REQUESTED;
85   verbose    = 0;
86
87   for (i = 1; i < argc; i ++)
88     if (!strcmp(argv[i], "-c"))
89     {
90       i ++;
91       if (i >= argc)
92         usage();
93
94       children = atoi(argv[i]);
95     }
96     else if (!strcmp(argv[i], "-r"))
97     {
98       i ++;
99       if (i >= argc)
100         usage();
101
102       requests = atoi(argv[i]);
103     }
104     else if (!strcmp(argv[i], "-E"))
105       encryption = HTTP_ENCRYPT_REQUIRED;
106     else if (!strcmp(argv[i], "-v"))
107       verbose ++;
108     else if (argv[i][0] == '-')
109       usage();
110     else
111       server = argv[i];
112
113  /*
114   * Then create child processes to act as clients...
115   */
116
117   printf("testspeed: Simulating %d clients with %d requests to %s with %s encryption...\n",
118          children, requests, server,
119          encryption == HTTP_ENCRYPT_IF_REQUESTED ? "no" : "");
120
121   start = time(NULL);
122
123   if (children == 1)
124   {
125     do_test(server, encryption, requests, verbose);
126   }
127   else
128   {
129     for (i = 0; i < children; i ++)
130       if ((pid = fork()) == 0)
131       {
132        /*
133         * Child goes here...
134         */
135
136         exit(do_test(server, encryption, requests, verbose));
137       }
138       else if (pid < 0)
139       {
140         perror("fork failed");
141         break;
142       }
143       else
144         printf("testspeed(%d): Started...\n", pid);
145
146    /*
147     * Wait for children to finish...
148     */
149
150     for (;;)
151     {
152       pid = wait(&status);
153
154       if (pid < 0 && errno != EINTR)
155         break;
156
157       printf("testspeed(%d): Ended (%d)...\n", pid, status);
158     }
159   }
160
161  /*
162   * Compute the total run time...
163   */
164
165   end     = time(NULL);
166   elapsed = end - start;
167   i       = children * requests;
168
169   printf("testspeed: %dx%d=%d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
170          children, requests, i, elapsed, elapsed / i, i / elapsed);
171
172  /*
173   * Exit with no errors...
174   */
175
176   return (status);
177 }
178
179
180 /*
181  * 'do_test()' - Run a test on a specific host...
182  */
183
184 int                                     /* O - Exit status */
185 do_test(const char        *server,      /* I - Server to use */
186         http_encryption_t encryption,   /* I - Encryption to use */
187         int               requests,     /* I - Number of requests to send */
188         int               verbose)      /* I - Verbose output? */
189 {
190   int           i;                      /* Looping var */
191   http_t        *http;                  /* Connection to server */
192   ipp_t         *request,               /* IPP Request */
193                 *response;              /* IPP Response */
194   cups_lang_t   *language;              /* Default language */
195   struct timeval start,                 /* Start time */
196                 end;                    /* End time */
197   double        elapsed;                /* Elapsed time */
198   static ipp_op_t ops[4] =              /* Operations to test... */
199                 {
200                   IPP_PRINT_JOB,
201                   CUPS_GET_PRINTERS,
202                   CUPS_GET_CLASSES,
203                   IPP_GET_JOBS
204                 };
205
206
207  /*
208   * Connect to the server...
209   */
210
211   http = httpConnectEncrypt(server, ippPort(), encryption);
212
213   if (http == NULL)
214   {
215     perror("testspeed: unable to connect to server");
216     return (1);
217   }
218
219   language = cupsLangDefault();
220
221  /*
222   * Do multiple requests...
223   */
224
225   for (elapsed = 0.0, i = 0; i < requests; i ++)
226   {
227     if (verbose && (i % 10) == 0)
228       printf("testspeed(%d): %d%% complete...\n", (int)getpid(),
229              i * 100 / requests);
230
231    /*
232     * Build a request which requires the following attributes:
233     *
234     *    attributes-charset
235     *    attributes-natural-language
236     *
237     * In addition, IPP_GET_JOBS needs a printer-uri attribute.
238     */
239
240     request = ippNew();
241
242     request->request.op.operation_id = ops[i & 3];
243     request->request.op.request_id   = 1;
244
245     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
246                  "attributes-charset", NULL, cupsLangEncoding(language));
247
248     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
249                  "attributes-natural-language", NULL, language->language);
250
251     gettimeofday(&start, NULL);
252
253     switch (request->request.op.operation_id)
254     {
255       case IPP_GET_JOBS :
256           ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
257                        NULL, "ipp://localhost/printers/");
258
259       default :
260           response = cupsDoRequest(http, request, "/");
261           break;
262
263       case IPP_PRINT_JOB :
264           ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
265                        NULL, "ipp://localhost/printers/test");
266           response = cupsDoFileRequest(http, request, "/printers/test",
267                                        "../data/testprint.ps");
268           break;
269     }
270
271     gettimeofday(&end, NULL);
272
273     if (response != NULL)
274       ippDelete(response);
275
276     elapsed += (end.tv_sec - start.tv_sec) +
277                0.000001 * (end.tv_usec - start.tv_usec);
278   }
279
280   cupsLangFree(language);
281   httpClose(http);
282
283   printf("testspeed(%d): %d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
284          (int)getpid(), i, elapsed, elapsed / i, i / elapsed);
285
286   return (0);
287 }
288
289
290 /*
291  * 'usage()' - Show program usage...
292  */
293
294 void
295 usage(void)
296 {
297   puts("Usage: testspeed [-c children] [-h] [-r requests] [-v] [-E] hostname");
298   exit(0);
299 }
300
301
302
303 /*
304  * End of "$Id: testspeed.c 4800 2005-10-18 18:06:20Z mike $".
305  */