2 * "$Id: testspeed.c 7727 2008-07-14 18:02:21Z mike $"
4 * Scheduler speed test for the Common UNIX Printing System (CUPS).
6 * Copyright 2007-2008 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.h>
28 #include <cups/cups.h>
29 #include <cups/language.h>
30 #include <cups/debug.h>
31 #include <sys/types.h>
41 static int do_test(const char *server
, int port
,
42 http_encryption_t encryption
, int requests
,
44 static void usage(void);
48 * 'main()' - Send multiple IPP requests and report on the average response
53 main(int argc
, /* I - Number of command-line arguments */
54 char *argv
[]) /* I - Command-line arguments */
56 int i
; /* Looping var */
57 char *server
, /* Server to use */
58 *ptr
; /* Pointer to port in server */
59 int port
; /* Port to use */
60 http_encryption_t encryption
; /* Encryption to use */
61 int requests
; /* Number of requests to send */
62 int children
; /* Number of children to fork */
63 int good_children
; /* Number of children that exited normally */
64 int pid
; /* Child PID */
65 int status
; /* Child status */
66 time_t start
, /* Start time */
68 double elapsed
; /* Elapsed time */
69 int verbose
; /* Verbosity */
73 * Parse command-line options...
78 server
= (char *)cupsServer();
80 encryption
= HTTP_ENCRYPT_IF_REQUESTED
;
83 for (i
= 1; i
< argc
; i
++)
84 if (argv
[i
][0] == '-')
86 for (ptr
= argv
[i
] + 1; *ptr
; ptr
++)
89 case 'c' : /* Number of children */
94 children
= atoi(argv
[i
]);
97 case 'r' : /* Number of requests */
102 requests
= atoi(argv
[i
]);
105 case 'E' : /* Enable encryption */
106 encryption
= HTTP_ENCRYPT_REQUIRED
;
109 case 'v' : /* Verbose logging */
122 if (server
[0] != '/' && (ptr
= strrchr(server
, ':')) != NULL
)
130 * Then create child processes to act as clients...
135 printf("testspeed: Simulating %d clients with %d requests to %s with "
136 "%sencryption...\n", children
, requests
, server
,
137 encryption
== HTTP_ENCRYPT_IF_REQUESTED
? "no " : "");
143 return (do_test(server
, port
, encryption
, requests
, verbose
));
144 else if (children
== 1)
145 good_children
= do_test(server
, port
, encryption
, requests
, verbose
) ? 0 : 1;
148 char options
[255], /* Command-line options for child */
149 reqstr
[255], /* Requests string for child */
150 serverstr
[255]; /* Server:port string for child */
153 snprintf(reqstr
, sizeof(reqstr
), "%d", requests
);
155 if (port
== 631 || server
[0] == '/')
156 strlcpy(serverstr
, server
, sizeof(serverstr
));
158 snprintf(serverstr
, sizeof(serverstr
), "%s:%d", server
, port
);
160 strlcpy(options
, "-cr", sizeof(options
));
162 if (encryption
== HTTP_ENCRYPT_REQUIRED
)
163 strlcat(options
, "E", sizeof(options
));
166 strlcat(options
, "v", sizeof(options
));
168 for (i
= 0; i
< children
; i
++)
172 if ((pid
= fork()) == 0)
178 execlp(argv
[0], argv
[0], options
, "0", reqstr
, serverstr
, (char *)NULL
);
183 printf("testspeed: Fork failed: %s\n", strerror(errno
));
187 printf("testspeed: Started child %d...\n", pid
);
191 * Wait for children to finish...
194 puts("testspeed: Waiting for children to finish...");
196 for (good_children
= 0;;)
200 if (pid
< 0 && errno
!= EINTR
)
203 printf("testspeed: Ended child %d (%d)...\n", pid
, status
/ 256);
211 * Compute the total run time...
214 if (good_children
> 0)
217 elapsed
= end
- start
;
218 i
= good_children
* requests
;
220 printf("testspeed: %dx%d=%d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
221 good_children
, requests
, i
, elapsed
, elapsed
/ i
, i
/ elapsed
);
225 * Exit with no errors...
233 * 'do_test()' - Run a test on a specific host...
236 static int /* O - Exit status */
237 do_test(const char *server
, /* I - Server to use */
238 int port
, /* I - Port number to use */
239 http_encryption_t encryption
, /* I - Encryption to use */
240 int requests
, /* I - Number of requests to send */
241 int verbose
) /* I - Verbose output? */
243 int i
; /* Looping var */
244 http_t
*http
; /* Connection to server */
245 ipp_t
*request
; /* IPP Request */
246 struct timeval start
, /* Start time */
248 double reqtime
, /* Time for this request */
249 elapsed
; /* Elapsed time */
250 int op
; /* Current operation */
251 static ipp_op_t ops
[4] = /* Operations to test... */
261 * Connect to the server...
264 if ((http
= httpConnectEncrypt(server
, port
, encryption
)) == NULL
)
266 printf("testspeed(%d): unable to connect to server - %s\n", (int)getpid(),
272 * Do multiple requests...
275 for (elapsed
= 0.0, i
= 0; i
< requests
; i
++)
278 * Build a request which requires the following attributes:
281 * attributes-natural-language
283 * In addition, IPP_GET_JOBS needs a printer-uri attribute.
287 request
= ippNewRequest(op
);
289 gettimeofday(&start
, NULL
);
292 printf("testspeed(%d): %.6f %s ", (int)getpid(), elapsed
,
298 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
299 NULL
, "ipp://localhost/printers/");
302 ippDelete(cupsDoRequest(http
, request
, "/"));
306 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
307 NULL
, "ipp://localhost/printers/test");
308 ippDelete(cupsDoFileRequest(http
, request
, "/printers/test",
309 "../data/testprint.ps"));
313 gettimeofday(&end
, NULL
);
315 reqtime
= (end
.tv_sec
- start
.tv_sec
) +
316 0.000001 * (end
.tv_usec
- start
.tv_usec
);
319 switch (cupsLastError())
325 printf("succeeded: %s (%.6f)\n", cupsLastErrorString(), reqtime
);
332 printf("testspeed(%d): %s ", (int)getpid(),
333 ippOpString(ops
[i
& 3]));
335 printf("failed: %s\n", cupsLastErrorString());
343 printf("testspeed(%d): %d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
344 (int)getpid(), i
, elapsed
, elapsed
/ i
, i
/ elapsed
);
351 * 'usage()' - Show program usage...
357 puts("Usage: testspeed [-c children] [-h] [-r requests] [-v] [-E] "
365 * End of "$Id: testspeed.c 7727 2008-07-14 18:02:21Z mike $".