2 * "$Id: testspeed.c 11558 2014-02-06 18:33:34Z msweet $"
4 * Scheduler speed test for CUPS.
6 * Copyright 2007-2014 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 * Include necessary headers...
20 #include <cups/string-private.h>
21 #include <cups/cups.h>
22 #include <cups/language.h>
23 #include <cups/debug-private.h>
24 #include <sys/types.h>
33 static int do_test(const char *server
, int port
,
34 http_encryption_t encryption
, int requests
,
35 const char *opstring
, int verbose
);
36 static void usage(void) __attribute__((noreturn
));
40 * 'main()' - Send multiple IPP requests and report on the average response
45 main(int argc
, /* I - Number of command-line arguments */
46 char *argv
[]) /* I - Command-line arguments */
48 int i
; /* Looping var */
49 char *server
, /* Server to use */
50 *ptr
; /* Pointer to port in server */
51 int port
; /* Port to use */
52 http_encryption_t encryption
; /* Encryption to use */
53 int requests
; /* Number of requests to send */
54 int children
; /* Number of children to fork */
55 int good_children
; /* Number of children that exited normally */
56 int pid
; /* Child PID */
57 int status
; /* Child status */
58 time_t start
, /* Start time */
60 double elapsed
; /* Elapsed time */
61 int verbose
; /* Verbosity */
62 const char *opstring
; /* Operation name */
66 * Parse command-line options...
71 server
= (char *)cupsServer();
73 encryption
= HTTP_ENCRYPT_IF_REQUESTED
;
77 for (i
= 1; i
< argc
; i
++)
78 if (argv
[i
][0] == '-')
80 for (ptr
= argv
[i
] + 1; *ptr
; ptr
++)
83 case 'E' : /* Enable encryption */
84 encryption
= HTTP_ENCRYPT_REQUIRED
;
87 case 'c' : /* Number of children */
92 children
= atoi(argv
[i
]);
95 case 'o' : /* Operation */
103 case 'r' : /* Number of requests */
108 requests
= atoi(argv
[i
]);
111 case 'v' : /* Verbose logging */
124 if (server
[0] != '/' && (ptr
= strrchr(server
, ':')) != NULL
)
132 * Then create child processes to act as clients...
137 printf("testspeed: Simulating %d clients with %d requests to %s with "
138 "%sencryption...\n", children
, requests
, server
,
139 encryption
== HTTP_ENCRYPT_IF_REQUESTED
? "no " : "");
145 return (do_test(server
, port
, encryption
, requests
, opstring
, verbose
));
146 else if (children
== 1)
147 good_children
= do_test(server
, port
, encryption
, requests
, opstring
,
151 char options
[255], /* Command-line options for child */
152 reqstr
[255], /* Requests string for child */
153 serverstr
[255]; /* Server:port string for child */
156 snprintf(reqstr
, sizeof(reqstr
), "%d", requests
);
158 if (port
== 631 || server
[0] == '/')
159 strlcpy(serverstr
, server
, sizeof(serverstr
));
161 snprintf(serverstr
, sizeof(serverstr
), "%s:%d", server
, port
);
163 strlcpy(options
, "-cr", sizeof(options
));
165 if (encryption
== HTTP_ENCRYPT_REQUIRED
)
166 strlcat(options
, "E", sizeof(options
));
169 strlcat(options
, "v", sizeof(options
));
171 for (i
= 0; i
< children
; i
++)
175 if ((pid
= fork()) == 0)
182 execlp(argv
[0], argv
[0], options
, "0", reqstr
, "-o", opstring
,
183 serverstr
, (char *)NULL
);
185 execlp(argv
[0], argv
[0], options
, "0", reqstr
, serverstr
, (char *)NULL
);
191 printf("testspeed: Fork failed: %s\n", strerror(errno
));
195 printf("testspeed: Started child %d...\n", pid
);
199 * Wait for children to finish...
202 puts("testspeed: Waiting for children to finish...");
204 for (good_children
= 0;;)
208 if (pid
< 0 && errno
!= EINTR
)
211 printf("testspeed: Ended child %d (%d)...\n", pid
, status
/ 256);
219 * Compute the total run time...
222 if (good_children
> 0)
225 elapsed
= end
- start
;
226 i
= good_children
* requests
;
228 printf("testspeed: %dx%d=%d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
229 good_children
, requests
, i
, elapsed
, elapsed
/ i
, i
/ elapsed
);
233 * Exit with no errors...
241 * 'do_test()' - Run a test on a specific host...
244 static int /* O - Exit status */
245 do_test(const char *server
, /* I - Server to use */
246 int port
, /* I - Port number to use */
247 http_encryption_t encryption
, /* I - Encryption to use */
248 int requests
, /* I - Number of requests to send */
249 const char *opstring
, /* I - Operation string */
250 int verbose
) /* I - Verbose output? */
252 int i
; /* Looping var */
253 http_t
*http
; /* Connection to server */
254 ipp_t
*request
; /* IPP Request */
255 struct timeval start
, /* Start time */
257 double reqtime
, /* Time for this request */
258 elapsed
; /* Elapsed time */
259 int op
; /* Current operation */
260 static ipp_op_t ops
[5] = /* Operations to test... */
271 * Connect to the server...
274 if ((http
= httpConnectEncrypt(server
, port
, encryption
)) == NULL
)
276 printf("testspeed(%d): unable to connect to server - %s\n", (int)getpid(),
282 * Do multiple requests...
285 for (elapsed
= 0.0, i
= 0; i
< requests
; i
++)
288 * Build a request which requires the following attributes:
291 * attributes-natural-language
293 * In addition, IPP_GET_JOBS needs a printer-uri attribute.
297 op
= ippOpValue(opstring
);
299 op
= ops
[i
% (int)(sizeof(ops
) / sizeof(ops
[0]))];
301 request
= ippNewRequest(op
);
303 gettimeofday(&start
, NULL
);
306 printf("testspeed(%d): %.6f %s ", (int)getpid(), elapsed
,
312 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
313 NULL
, "ipp://localhost/printers/");
316 ippDelete(cupsDoRequest(http
, request
, "/"));
320 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
321 NULL
, "ipp://localhost/printers/test");
322 ippDelete(cupsDoFileRequest(http
, request
, "/printers/test",
323 "../data/testprint.ps"));
327 gettimeofday(&end
, NULL
);
329 reqtime
= (end
.tv_sec
- start
.tv_sec
) +
330 0.000001 * (end
.tv_usec
- start
.tv_usec
);
333 switch (cupsLastError())
339 printf("succeeded: %s (%.6f)\n", cupsLastErrorString(), reqtime
);
346 printf("testspeed(%d): %s ", (int)getpid(),
347 ippOpString(ops
[i
& 3]));
349 printf("failed: %s\n", cupsLastErrorString());
357 printf("testspeed(%d): %d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
358 (int)getpid(), i
, elapsed
, elapsed
/ i
, i
/ elapsed
);
365 * 'usage()' - Show program usage...
371 puts("Usage: testspeed [-c children] [-h] [-o operation] [-r requests] [-v] "
372 "[-E] hostname[:port]");
379 * End of "$Id: testspeed.c 11558 2014-02-06 18:33:34Z msweet $".