2 * Scheduler speed test for CUPS.
4 * Copyright 2007-2014 by Apple Inc.
5 * Copyright 1997-2005 by Easy Software Products.
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
11 * Include necessary headers...
14 #include <cups/string-private.h>
15 #include <cups/cups.h>
16 #include <cups/language.h>
17 #include <cups/debug-private.h>
18 #include <sys/types.h>
27 static int do_test(const char *server
, int port
,
28 http_encryption_t encryption
, int requests
,
29 const char *opstring
, int verbose
);
30 static void usage(void) __attribute__((noreturn
));
34 * 'main()' - Send multiple IPP requests and report on the average response
39 main(int argc
, /* I - Number of command-line arguments */
40 char *argv
[]) /* I - Command-line arguments */
42 int i
; /* Looping var */
43 char *server
, /* Server to use */
44 *ptr
; /* Pointer to port in server */
45 int port
; /* Port to use */
46 http_encryption_t encryption
; /* Encryption to use */
47 int requests
; /* Number of requests to send */
48 int children
; /* Number of children to fork */
49 int good_children
; /* Number of children that exited normally */
50 int pid
; /* Child PID */
51 int status
; /* Child status */
52 time_t start
, /* Start time */
54 double elapsed
; /* Elapsed time */
55 int verbose
; /* Verbosity */
56 const char *opstring
; /* Operation name */
60 * Parse command-line options...
65 server
= (char *)cupsServer();
67 encryption
= HTTP_ENCRYPT_IF_REQUESTED
;
71 for (i
= 1; i
< argc
; i
++)
72 if (argv
[i
][0] == '-')
74 for (ptr
= argv
[i
] + 1; *ptr
; ptr
++)
77 case 'E' : /* Enable encryption */
78 encryption
= HTTP_ENCRYPT_REQUIRED
;
81 case 'c' : /* Number of children */
86 children
= atoi(argv
[i
]);
89 case 'o' : /* Operation */
97 case 'r' : /* Number of requests */
102 requests
= atoi(argv
[i
]);
105 case 'v' : /* Verbose logging */
118 if (server
[0] != '/' && (ptr
= strrchr(server
, ':')) != NULL
)
126 * Then create child processes to act as clients...
131 printf("testspeed: Simulating %d clients with %d requests to %s with "
132 "%sencryption...\n", children
, requests
, server
,
133 encryption
== HTTP_ENCRYPT_IF_REQUESTED
? "no " : "");
139 return (do_test(server
, port
, encryption
, requests
, opstring
, verbose
));
140 else if (children
== 1)
141 good_children
= do_test(server
, port
, encryption
, requests
, opstring
,
145 char options
[255], /* Command-line options for child */
146 reqstr
[255], /* Requests string for child */
147 serverstr
[255]; /* Server:port string for child */
150 snprintf(reqstr
, sizeof(reqstr
), "%d", requests
);
152 if (port
== 631 || server
[0] == '/')
153 strlcpy(serverstr
, server
, sizeof(serverstr
));
155 snprintf(serverstr
, sizeof(serverstr
), "%s:%d", server
, port
);
157 strlcpy(options
, "-cr", sizeof(options
));
159 if (encryption
== HTTP_ENCRYPT_REQUIRED
)
160 strlcat(options
, "E", sizeof(options
));
163 strlcat(options
, "v", sizeof(options
));
165 for (i
= 0; i
< children
; i
++)
169 if ((pid
= fork()) == 0)
176 execlp(argv
[0], argv
[0], options
, "0", reqstr
, "-o", opstring
,
177 serverstr
, (char *)NULL
);
179 execlp(argv
[0], argv
[0], options
, "0", reqstr
, serverstr
, (char *)NULL
);
185 printf("testspeed: Fork failed: %s\n", strerror(errno
));
189 printf("testspeed: Started child %d...\n", pid
);
193 * Wait for children to finish...
196 puts("testspeed: Waiting for children to finish...");
198 for (good_children
= 0;;)
202 if (pid
< 0 && errno
!= EINTR
)
205 printf("testspeed: Ended child %d (%d)...\n", pid
, status
/ 256);
213 * Compute the total run time...
216 if (good_children
> 0)
219 elapsed
= end
- start
;
220 i
= good_children
* requests
;
222 printf("testspeed: %dx%d=%d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
223 good_children
, requests
, i
, elapsed
, elapsed
/ i
, i
/ elapsed
);
227 * Exit with no errors...
235 * 'do_test()' - Run a test on a specific host...
238 static int /* O - Exit status */
239 do_test(const char *server
, /* I - Server to use */
240 int port
, /* I - Port number to use */
241 http_encryption_t encryption
, /* I - Encryption to use */
242 int requests
, /* I - Number of requests to send */
243 const char *opstring
, /* I - Operation string */
244 int verbose
) /* I - Verbose output? */
246 int i
; /* Looping var */
247 http_t
*http
; /* Connection to server */
248 ipp_t
*request
; /* IPP Request */
249 struct timeval start
, /* Start time */
251 double reqtime
, /* Time for this request */
252 elapsed
; /* Elapsed time */
253 int op
; /* Current operation */
254 static ipp_op_t ops
[5] = /* Operations to test... */
265 * Connect to the server...
268 if ((http
= httpConnectEncrypt(server
, port
, encryption
)) == NULL
)
270 printf("testspeed(%d): unable to connect to server - %s\n", (int)getpid(),
276 * Do multiple requests...
279 for (elapsed
= 0.0, i
= 0; i
< requests
; i
++)
282 * Build a request which requires the following attributes:
285 * attributes-natural-language
287 * In addition, IPP_GET_JOBS needs a printer-uri attribute.
291 op
= ippOpValue(opstring
);
293 op
= ops
[i
% (int)(sizeof(ops
) / sizeof(ops
[0]))];
295 request
= ippNewRequest(op
);
297 gettimeofday(&start
, NULL
);
300 printf("testspeed(%d): %.6f %s ", (int)getpid(), elapsed
,
306 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
307 NULL
, "ipp://localhost/printers/");
310 ippDelete(cupsDoRequest(http
, request
, "/"));
314 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
315 NULL
, "ipp://localhost/printers/test");
316 ippDelete(cupsDoFileRequest(http
, request
, "/printers/test",
317 "../data/testprint.ps"));
321 gettimeofday(&end
, NULL
);
323 reqtime
= (end
.tv_sec
- start
.tv_sec
) +
324 0.000001 * (end
.tv_usec
- start
.tv_usec
);
327 switch (cupsLastError())
333 printf("succeeded: %s (%.6f)\n", cupsLastErrorString(), reqtime
);
340 printf("testspeed(%d): %s ", (int)getpid(),
341 ippOpString(ops
[i
& 3]));
343 printf("failed: %s\n", cupsLastErrorString());
351 printf("testspeed(%d): %d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
352 (int)getpid(), i
, elapsed
, elapsed
/ i
, i
/ elapsed
);
359 * 'usage()' - Show program usage...
365 puts("Usage: testspeed [-c children] [-h] [-o operation] [-r requests] [-v] "
366 "[-E] hostname[:port]");