]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/testspeed.c
Import CUPS v1.7.1
[thirdparty/cups.git] / scheduler / testspeed.c
CommitLineData
ef416fc2 1/*
61515785 2 * "$Id: testspeed.c 10995 2013-05-29 11:51:03Z msweet $"
ef416fc2 3 *
71e16022 4 * Scheduler speed test for CUPS.
ef416fc2 5 *
71e16022 6 * Copyright 2007-2010 by Apple Inc.
ef416fc2 7 * Copyright 1997-2005 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
bc44d920 10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 14 *
15 * Contents:
16 *
e1d6a774 17 * main() - Send multiple IPP requests and report on the average response
18 * time.
19 * do_test() - Run a test on a specific host...
20 * usage() - Show program usage...
ef416fc2 21 */
22
23/*
24 * Include necessary headers...
25 */
26
71e16022 27#include <cups/string-private.h>
ef416fc2 28#include <cups/cups.h>
29#include <cups/language.h>
71e16022 30#include <cups/debug-private.h>
75bd9771
MS
31#include <sys/types.h>
32#include <sys/time.h>
33#include <sys/wait.h>
ef416fc2 34
35
36/*
37 * Local functions...
38 */
39
dd1abb6b
MS
40static int do_test(const char *server, int port,
41 http_encryption_t encryption, int requests,
23ef1cac 42 const char *opstring, int verbose);
85dda01c 43static void usage(void) __attribute__((noreturn));
ef416fc2 44
45
46/*
47 * 'main()' - Send multiple IPP requests and report on the average response
48 * time.
49 */
50
51int
52main(int argc, /* I - Number of command-line arguments */
53 char *argv[]) /* I - Command-line arguments */
54{
55 int i; /* Looping var */
dd1abb6b
MS
56 char *server, /* Server to use */
57 *ptr; /* Pointer to port in server */
58 int port; /* Port to use */
ef416fc2 59 http_encryption_t encryption; /* Encryption to use */
60 int requests; /* Number of requests to send */
61 int children; /* Number of children to fork */
dd1abb6b 62 int good_children; /* Number of children that exited normally */
ef416fc2 63 int pid; /* Child PID */
64 int status; /* Child status */
65 time_t start, /* Start time */
66 end; /* End time */
67 double elapsed; /* Elapsed time */
68 int verbose; /* Verbosity */
23ef1cac 69 const char *opstring; /* Operation name */
ef416fc2 70
71
72 /*
73 * Parse command-line options...
74 */
75
76 requests = 100;
77 children = 5;
dd1abb6b
MS
78 server = (char *)cupsServer();
79 port = ippPort();
ef416fc2 80 encryption = HTTP_ENCRYPT_IF_REQUESTED;
81 verbose = 0;
23ef1cac 82 opstring = NULL;
ef416fc2 83
84 for (i = 1; i < argc; i ++)
dd1abb6b 85 if (argv[i][0] == '-')
ef416fc2 86 {
dd1abb6b
MS
87 for (ptr = argv[i] + 1; *ptr; ptr ++)
88 switch (*ptr)
89 {
23ef1cac
MS
90 case 'E' : /* Enable encryption */
91 encryption = HTTP_ENCRYPT_REQUIRED;
92 break;
93
dd1abb6b
MS
94 case 'c' : /* Number of children */
95 i ++;
96 if (i >= argc)
97 usage();
98
99 children = atoi(argv[i]);
100 break;
101
23ef1cac 102 case 'o' : /* Operation */
dd1abb6b
MS
103 i ++;
104 if (i >= argc)
105 usage();
106
23ef1cac 107 opstring = argv[i];
dd1abb6b
MS
108 break;
109
23ef1cac
MS
110 case 'r' : /* Number of requests */
111 i ++;
112 if (i >= argc)
113 usage();
114
115 requests = atoi(argv[i]);
dd1abb6b
MS
116 break;
117
118 case 'v' : /* Verbose logging */
119 verbose ++;
120 break;
121
122 default :
123 usage();
124 break;
125 }
ef416fc2 126 }
dd1abb6b 127 else
ef416fc2 128 {
dd1abb6b 129 server = argv[i];
ef416fc2 130
dd1abb6b
MS
131 if (server[0] != '/' && (ptr = strrchr(server, ':')) != NULL)
132 {
133 *ptr++ = '\0';
134 port = atoi(ptr);
135 }
ef416fc2 136 }
ef416fc2 137
138 /*
139 * Then create child processes to act as clients...
140 */
141
dd1abb6b
MS
142 if (children > 0)
143 {
144 printf("testspeed: Simulating %d clients with %d requests to %s with "
145 "%sencryption...\n", children, requests, server,
146 encryption == HTTP_ENCRYPT_IF_REQUESTED ? "no " : "");
147 }
ef416fc2 148
149 start = time(NULL);
150
dd1abb6b 151 if (children < 1)
23ef1cac 152 return (do_test(server, port, encryption, requests, opstring, verbose));
dd1abb6b 153 else if (children == 1)
23ef1cac
MS
154 good_children = do_test(server, port, encryption, requests, opstring,
155 verbose) ? 0 : 1;
ef416fc2 156 else
157 {
dd1abb6b
MS
158 char options[255], /* Command-line options for child */
159 reqstr[255], /* Requests string for child */
160 serverstr[255]; /* Server:port string for child */
161
162
163 snprintf(reqstr, sizeof(reqstr), "%d", requests);
164
165 if (port == 631 || server[0] == '/')
166 strlcpy(serverstr, server, sizeof(serverstr));
167 else
168 snprintf(serverstr, sizeof(serverstr), "%s:%d", server, port);
169
170 strlcpy(options, "-cr", sizeof(options));
171
172 if (encryption == HTTP_ENCRYPT_REQUIRED)
173 strlcat(options, "E", sizeof(options));
174
175 if (verbose)
176 strlcat(options, "v", sizeof(options));
177
ef416fc2 178 for (i = 0; i < children; i ++)
dd1abb6b
MS
179 {
180 fflush(stdout);
181
ef416fc2 182 if ((pid = fork()) == 0)
183 {
184 /*
185 * Child goes here...
186 */
187
23ef1cac
MS
188 if (opstring)
189 execlp(argv[0], argv[0], options, "0", reqstr, "-o", opstring,
190 serverstr, (char *)NULL);
191 else
192 execlp(argv[0], argv[0], options, "0", reqstr, serverstr, (char *)NULL);
193
dd1abb6b 194 exit(errno);
ef416fc2 195 }
196 else if (pid < 0)
197 {
dd1abb6b 198 printf("testspeed: Fork failed: %s\n", strerror(errno));
ef416fc2 199 break;
200 }
201 else
dd1abb6b
MS
202 printf("testspeed: Started child %d...\n", pid);
203 }
ef416fc2 204
205 /*
206 * Wait for children to finish...
207 */
208
dd1abb6b
MS
209 puts("testspeed: Waiting for children to finish...");
210
211 for (good_children = 0;;)
ef416fc2 212 {
213 pid = wait(&status);
214
215 if (pid < 0 && errno != EINTR)
216 break;
217
dd1abb6b
MS
218 printf("testspeed: Ended child %d (%d)...\n", pid, status / 256);
219
220 if (!status)
221 good_children ++;
ef416fc2 222 }
223 }
224
225 /*
226 * Compute the total run time...
227 */
228
dd1abb6b
MS
229 if (good_children > 0)
230 {
231 end = time(NULL);
232 elapsed = end - start;
233 i = good_children * requests;
ef416fc2 234
dd1abb6b
MS
235 printf("testspeed: %dx%d=%d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
236 good_children, requests, i, elapsed, elapsed / i, i / elapsed);
237 }
ef416fc2 238
239 /*
240 * Exit with no errors...
241 */
242
91c84a35 243 return (0);
ef416fc2 244}
245
246
247/*
248 * 'do_test()' - Run a test on a specific host...
249 */
250
e1d6a774 251static int /* O - Exit status */
ef416fc2 252do_test(const char *server, /* I - Server to use */
dd1abb6b 253 int port, /* I - Port number to use */
ef416fc2 254 http_encryption_t encryption, /* I - Encryption to use */
255 int requests, /* I - Number of requests to send */
23ef1cac 256 const char *opstring, /* I - Operation string */
ef416fc2 257 int verbose) /* I - Verbose output? */
258{
259 int i; /* Looping var */
260 http_t *http; /* Connection to server */
dd1abb6b 261 ipp_t *request; /* IPP Request */
ef416fc2 262 struct timeval start, /* Start time */
263 end; /* End time */
dd1abb6b
MS
264 double reqtime, /* Time for this request */
265 elapsed; /* Elapsed time */
266 int op; /* Current operation */
23ef1cac 267 static ipp_op_t ops[5] = /* Operations to test... */
ef416fc2 268 {
269 IPP_PRINT_JOB,
23ef1cac 270 CUPS_GET_DEFAULT,
ef416fc2 271 CUPS_GET_PRINTERS,
272 CUPS_GET_CLASSES,
273 IPP_GET_JOBS
274 };
275
276
277 /*
278 * Connect to the server...
279 */
280
dd1abb6b 281 if ((http = httpConnectEncrypt(server, port, encryption)) == NULL)
ef416fc2 282 {
dd1abb6b
MS
283 printf("testspeed(%d): unable to connect to server - %s\n", (int)getpid(),
284 strerror(errno));
ef416fc2 285 return (1);
286 }
287
ef416fc2 288 /*
289 * Do multiple requests...
290 */
291
292 for (elapsed = 0.0, i = 0; i < requests; i ++)
293 {
ef416fc2 294 /*
295 * Build a request which requires the following attributes:
296 *
297 * attributes-charset
298 * attributes-natural-language
299 *
300 * In addition, IPP_GET_JOBS needs a printer-uri attribute.
301 */
302
23ef1cac
MS
303 if (opstring)
304 op = ippOpValue(opstring);
305 else
306 op = ops[i % (sizeof(ops) / sizeof(ops[0]))];
307
dd1abb6b 308 request = ippNewRequest(op);
ef416fc2 309
310 gettimeofday(&start, NULL);
311
dd1abb6b
MS
312 if (verbose)
313 printf("testspeed(%d): %.6f %s ", (int)getpid(), elapsed,
314 ippOpString(op));
315
316 switch (op)
ef416fc2 317 {
318 case IPP_GET_JOBS :
319 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
320 NULL, "ipp://localhost/printers/");
321
322 default :
dd1abb6b 323 ippDelete(cupsDoRequest(http, request, "/"));
ef416fc2 324 break;
325
326 case IPP_PRINT_JOB :
327 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
328 NULL, "ipp://localhost/printers/test");
dd1abb6b
MS
329 ippDelete(cupsDoFileRequest(http, request, "/printers/test",
330 "../data/testprint.ps"));
ef416fc2 331 break;
332 }
333
334 gettimeofday(&end, NULL);
335
dd1abb6b
MS
336 reqtime = (end.tv_sec - start.tv_sec) +
337 0.000001 * (end.tv_usec - start.tv_usec);
338 elapsed += reqtime;
339
340 switch (cupsLastError())
341 {
342 case IPP_OK :
343 case IPP_NOT_FOUND :
344 if (verbose)
345 {
346 printf("succeeded: %s (%.6f)\n", cupsLastErrorString(), reqtime);
347 fflush(stdout);
348 }
349 break;
ef416fc2 350
dd1abb6b
MS
351 default :
352 if (!verbose)
353 printf("testspeed(%d): %s ", (int)getpid(),
354 ippOpString(ops[i & 3]));
355
356 printf("failed: %s\n", cupsLastErrorString());
357 httpClose(http);
358 return (1);
359 }
ef416fc2 360 }
361
ef416fc2 362 httpClose(http);
363
364 printf("testspeed(%d): %d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
365 (int)getpid(), i, elapsed, elapsed / i, i / elapsed);
366
367 return (0);
368}
369
370
371/*
372 * 'usage()' - Show program usage...
373 */
374
e1d6a774 375static void
ef416fc2 376usage(void)
377{
23ef1cac
MS
378 puts("Usage: testspeed [-c children] [-h] [-o operation] [-r requests] [-v] "
379 "[-E] hostname[:port]");
ef416fc2 380 exit(0);
381}
382
383
384
385/*
61515785 386 * End of "$Id: testspeed.c 10995 2013-05-29 11:51:03Z msweet $".
ef416fc2 387 */