2 * "$Id: testspeed.c 7727 2008-07-14 18:02:21Z mike $"
4 * Scheduler speed test for CUPS.
6 * Copyright 2007-2010 by Apple Inc.
7 * Copyright 1997-2005 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
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/".
17 * main() - Send multiple IPP requests and report on the average response
19 * do_test() - Run a test on a specific host...
20 * usage() - Show program usage...
24 * Include necessary headers...
27 #include <cups/string-private.h>
28 #include <cups/cups.h>
29 #include <cups/language.h>
30 #include <cups/debug-private.h>
31 #include <sys/types.h>
40 static int do_test(const char *server
, int port
,
41 http_encryption_t encryption
, int requests
,
43 static void usage(void) __attribute__((noreturn
));
47 * 'main()' - Send multiple IPP requests and report on the average response
52 main(int argc
, /* I - Number of command-line arguments */
53 char *argv
[]) /* I - Command-line arguments */
55 int i
; /* Looping var */
56 char *server
, /* Server to use */
57 *ptr
; /* Pointer to port in server */
58 int port
; /* Port to use */
59 http_encryption_t encryption
; /* Encryption to use */
60 int requests
; /* Number of requests to send */
61 int children
; /* Number of children to fork */
62 int good_children
; /* Number of children that exited normally */
63 int pid
; /* Child PID */
64 int status
; /* Child status */
65 time_t start
, /* Start time */
67 double elapsed
; /* Elapsed time */
68 int verbose
; /* Verbosity */
72 * Parse command-line options...
77 server
= (char *)cupsServer();
79 encryption
= HTTP_ENCRYPT_IF_REQUESTED
;
82 for (i
= 1; i
< argc
; i
++)
83 if (argv
[i
][0] == '-')
85 for (ptr
= argv
[i
] + 1; *ptr
; ptr
++)
88 case 'c' : /* Number of children */
93 children
= atoi(argv
[i
]);
96 case 'r' : /* Number of requests */
101 requests
= atoi(argv
[i
]);
104 case 'E' : /* Enable encryption */
105 encryption
= HTTP_ENCRYPT_REQUIRED
;
108 case 'v' : /* Verbose logging */
121 if (server
[0] != '/' && (ptr
= strrchr(server
, ':')) != NULL
)
129 * Then create child processes to act as clients...
134 printf("testspeed: Simulating %d clients with %d requests to %s with "
135 "%sencryption...\n", children
, requests
, server
,
136 encryption
== HTTP_ENCRYPT_IF_REQUESTED
? "no " : "");
142 return (do_test(server
, port
, encryption
, requests
, verbose
));
143 else if (children
== 1)
144 good_children
= do_test(server
, port
, encryption
, requests
, verbose
) ? 0 : 1;
147 char options
[255], /* Command-line options for child */
148 reqstr
[255], /* Requests string for child */
149 serverstr
[255]; /* Server:port string for child */
152 snprintf(reqstr
, sizeof(reqstr
), "%d", requests
);
154 if (port
== 631 || server
[0] == '/')
155 strlcpy(serverstr
, server
, sizeof(serverstr
));
157 snprintf(serverstr
, sizeof(serverstr
), "%s:%d", server
, port
);
159 strlcpy(options
, "-cr", sizeof(options
));
161 if (encryption
== HTTP_ENCRYPT_REQUIRED
)
162 strlcat(options
, "E", sizeof(options
));
165 strlcat(options
, "v", sizeof(options
));
167 for (i
= 0; i
< children
; i
++)
171 if ((pid
= fork()) == 0)
177 execlp(argv
[0], argv
[0], options
, "0", reqstr
, serverstr
, (char *)NULL
);
182 printf("testspeed: Fork failed: %s\n", strerror(errno
));
186 printf("testspeed: Started child %d...\n", pid
);
190 * Wait for children to finish...
193 puts("testspeed: Waiting for children to finish...");
195 for (good_children
= 0;;)
199 if (pid
< 0 && errno
!= EINTR
)
202 printf("testspeed: Ended child %d (%d)...\n", pid
, status
/ 256);
210 * Compute the total run time...
213 if (good_children
> 0)
216 elapsed
= end
- start
;
217 i
= good_children
* requests
;
219 printf("testspeed: %dx%d=%d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
220 good_children
, requests
, i
, elapsed
, elapsed
/ i
, i
/ elapsed
);
224 * Exit with no errors...
232 * 'do_test()' - Run a test on a specific host...
235 static int /* O - Exit status */
236 do_test(const char *server
, /* I - Server to use */
237 int port
, /* I - Port number to use */
238 http_encryption_t encryption
, /* I - Encryption to use */
239 int requests
, /* I - Number of requests to send */
240 int verbose
) /* I - Verbose output? */
242 int i
; /* Looping var */
243 http_t
*http
; /* Connection to server */
244 ipp_t
*request
; /* IPP Request */
245 struct timeval start
, /* Start time */
247 double reqtime
, /* Time for this request */
248 elapsed
; /* Elapsed time */
249 int op
; /* Current operation */
250 static ipp_op_t ops
[4] = /* Operations to test... */
260 * Connect to the server...
263 if ((http
= httpConnectEncrypt(server
, port
, encryption
)) == NULL
)
265 printf("testspeed(%d): unable to connect to server - %s\n", (int)getpid(),
271 * Do multiple requests...
274 for (elapsed
= 0.0, i
= 0; i
< requests
; i
++)
277 * Build a request which requires the following attributes:
280 * attributes-natural-language
282 * In addition, IPP_GET_JOBS needs a printer-uri attribute.
286 request
= ippNewRequest(op
);
288 gettimeofday(&start
, NULL
);
291 printf("testspeed(%d): %.6f %s ", (int)getpid(), elapsed
,
297 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
298 NULL
, "ipp://localhost/printers/");
301 ippDelete(cupsDoRequest(http
, request
, "/"));
305 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
306 NULL
, "ipp://localhost/printers/test");
307 ippDelete(cupsDoFileRequest(http
, request
, "/printers/test",
308 "../data/testprint.ps"));
312 gettimeofday(&end
, NULL
);
314 reqtime
= (end
.tv_sec
- start
.tv_sec
) +
315 0.000001 * (end
.tv_usec
- start
.tv_usec
);
318 switch (cupsLastError())
324 printf("succeeded: %s (%.6f)\n", cupsLastErrorString(), reqtime
);
331 printf("testspeed(%d): %s ", (int)getpid(),
332 ippOpString(ops
[i
& 3]));
334 printf("failed: %s\n", cupsLastErrorString());
342 printf("testspeed(%d): %d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
343 (int)getpid(), i
, elapsed
, elapsed
/ i
, i
/ elapsed
);
350 * 'usage()' - Show program usage...
356 puts("Usage: testspeed [-c children] [-h] [-r requests] [-v] [-E] "
364 * End of "$Id: testspeed.c 7727 2008-07-14 18:02:21Z mike $".