]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/testspeed.c
Fix source file header text duplication text duplication.
[thirdparty/cups.git] / scheduler / testspeed.c
index 559dfa8e45d494bf66b469e3dcb204966dd2a7db..c1863b23044359b4a76cf10c9bf632214044227d 100644 (file)
@@ -1,57 +1,37 @@
 /*
- * "$Id: testspeed.c 5305 2006-03-18 03:05:12Z mike $"
+ * Scheduler speed test for CUPS.
  *
- *   Scheduler speed test for the Common UNIX Printing System (CUPS).
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2005 by Easy Software Products.
  *
- *   Copyright 1997-2005 by Easy Software Products.
- *
- *   These coded instructions, statements, and computer programs are the
- *   property of Easy Software Products and are protected by Federal
- *   copyright law.  Distribution and use rights are outlined in the file
- *   "LICENSE.txt" which should have been included with this file.  If this
- *   file is missing or damaged please contact Easy Software Products
- *   at:
- *
- *       Attn: CUPS Licensing Information
- *       Easy Software Products
- *       44141 Airport View Drive, Suite 204
- *       Hollywood, Maryland 20636 USA
- *
- *       Voice: (301) 373-9600
- *       EMail: cups-info@cups.org
- *         WWW: http://www.cups.org
- *
- * Contents:
- *
- *   main()    - Send multiple IPP requests and report on the average response
- *               time.
- *   do_test() - Run a test on a specific host...
- *   usage()   - Show program usage...
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file.  If this file is
+ * missing or damaged, see the license at "http://www.cups.org/".
  */
 
 /*
  * Include necessary headers...
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
+#include <cups/string-private.h>
+#include <cups/cups.h>
+#include <cups/language.h>
+#include <cups/debug-private.h>
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/wait.h>
-#include <cups/cups.h>
-#include <cups/language.h>
-#include <cups/debug.h>
-#include <errno.h>
 
 
 /*
  * Local functions...
  */
 
-static int     do_test(const char *server, http_encryption_t encryption,
-                       int requests, int verbose);
-static void    usage(void);
+static int     do_test(const char *server, int port,
+                       http_encryption_t encryption, int requests,
+                       const char *opstring, int verbose);
+static void    usage(void) __attribute__((noreturn));
 
 
 /*
@@ -64,16 +44,20 @@ main(int  argc,                             /* I - Number of command-line arguments */
      char *argv[])                     /* I - Command-line arguments */
 {
   int          i;                      /* Looping var */
-  const char   *server;                /* Server to use */
+  char         *server,                /* Server to use */
+               *ptr;                   /* Pointer to port in server */
+  int          port;                   /* Port to use */
   http_encryption_t encryption;                /* Encryption to use */
   int          requests;               /* Number of requests to send */
   int          children;               /* Number of children to fork */
+  int          good_children;          /* Number of children that exited normally */
   int          pid;                    /* Child PID */
   int          status;                 /* Child status */
   time_t       start,                  /* Start time */
                end;                    /* End time */
   double       elapsed;                /* Elapsed time */
   int          verbose;                /* Verbosity */
+  const char   *opstring;              /* Operation name */
 
 
  /*
@@ -82,81 +66,150 @@ main(int  argc,                            /* I - Number of command-line arguments */
 
   requests   = 100;
   children   = 5;
-  server     = cupsServer();
+  server     = (char *)cupsServer();
+  port       = ippPort();
   encryption = HTTP_ENCRYPT_IF_REQUESTED;
   verbose    = 0;
+  opstring   = NULL;
 
   for (i = 1; i < argc; i ++)
-    if (!strcmp(argv[i], "-c"))
+    if (argv[i][0] == '-')
     {
-      i ++;
-      if (i >= argc)
-        usage();
-
-      children = atoi(argv[i]);
+      for (ptr = argv[i] + 1; *ptr; ptr ++)
+        switch (*ptr)
+       {
+         case 'E' : /* Enable encryption */
+             encryption = HTTP_ENCRYPT_REQUIRED;
+             break;
+
+         case 'c' : /* Number of children */
+             i ++;
+             if (i >= argc)
+               usage();
+
+             children = atoi(argv[i]);
+             break;
+
+          case 'o' : /* Operation */
+             i ++;
+             if (i >= argc)
+               usage();
+
+             opstring = argv[i];
+             break;
+
+          case 'r' : /* Number of requests */
+             i ++;
+             if (i >= argc)
+               usage();
+
+             requests = atoi(argv[i]);
+             break;
+
+          case 'v' : /* Verbose logging */
+              verbose ++;
+             break;
+
+          default :
+              usage();
+             break;
+        }
     }
-    else if (!strcmp(argv[i], "-r"))
+    else
     {
-      i ++;
-      if (i >= argc)
-        usage();
+      server = argv[i];
 
-      requests = atoi(argv[i]);
+      if (server[0] != '/' && (ptr = strrchr(server, ':')) != NULL)
+      {
+        *ptr++ = '\0';
+       port   = atoi(ptr);
+      }
     }
-    else if (!strcmp(argv[i], "-E"))
-      encryption = HTTP_ENCRYPT_REQUIRED;
-    else if (!strcmp(argv[i], "-v"))
-      verbose ++;
-    else if (argv[i][0] == '-')
-      usage();
-    else
-      server = argv[i];
 
  /*
   * Then create child processes to act as clients...
   */
 
-  printf("testspeed: Simulating %d clients with %d requests to %s with %s encryption...\n",
-         children, requests, server,
-        encryption == HTTP_ENCRYPT_IF_REQUESTED ? "no" : "");
+  if (children > 0)
+  {
+    printf("testspeed: Simulating %d clients with %d requests to %s with "
+           "%sencryption...\n", children, requests, server,
+          encryption == HTTP_ENCRYPT_IF_REQUESTED ? "no " : "");
+  }
 
   start = time(NULL);
 
-  if (children == 1)
-  {
-    do_test(server, encryption, requests, verbose);
-  }
+  if (children < 1)
+    return (do_test(server, port, encryption, requests, opstring, verbose));
+  else if (children == 1)
+    good_children = do_test(server, port, encryption, requests, opstring,
+                            verbose) ? 0 : 1;
   else
   {
+    char       options[255],           /* Command-line options for child */
+               reqstr[255],            /* Requests string for child */
+               serverstr[255];         /* Server:port string for child */
+
+
+    snprintf(reqstr, sizeof(reqstr), "%d", requests);
+
+    if (port == 631 || server[0] == '/')
+      strlcpy(serverstr, server, sizeof(serverstr));
+    else
+      snprintf(serverstr, sizeof(serverstr), "%s:%d", server, port);
+
+    strlcpy(options, "-cr", sizeof(options));
+
+    if (encryption == HTTP_ENCRYPT_REQUIRED)
+      strlcat(options, "E", sizeof(options));
+
+    if (verbose)
+      strlcat(options, "v", sizeof(options));
+
     for (i = 0; i < children; i ++)
+    {
+      fflush(stdout);
+
       if ((pid = fork()) == 0)
       {
        /*
        * Child goes here...
        */
 
-       exit(do_test(server, encryption, requests, verbose));
+        if (opstring)
+         execlp(argv[0], argv[0], options, "0", reqstr, "-o", opstring,
+                serverstr, (char *)NULL);
+        else
+         execlp(argv[0], argv[0], options, "0", reqstr, serverstr, (char *)NULL);
+
+       exit(errno);
       }
       else if (pid < 0)
       {
-       perror("fork failed");
+       printf("testspeed: Fork failed: %s\n", strerror(errno));
        break;
       }
       else
-       printf("testspeed(%d): Started...\n", pid);
+       printf("testspeed: Started child %d...\n", pid);
+    }
 
    /*
     * Wait for children to finish...
     */
 
-    for (;;)
+    puts("testspeed: Waiting for children to finish...");
+
+    for (good_children = 0;;)
     {
       pid = wait(&status);
 
       if (pid < 0 && errno != EINTR)
        break;
 
-      printf("testspeed(%d): Ended (%d)...\n", pid, status);
+      printf("testspeed: Ended child %d (%d)...\n", pid, status / 256);
+
+      if (!status)
+        good_children ++;
     }
   }
 
@@ -164,18 +217,21 @@ main(int  argc,                           /* I - Number of command-line arguments */
   * Compute the total run time...
   */
 
-  end     = time(NULL);
-  elapsed = end - start;
-  i       = children * requests;
+  if (good_children > 0)
+  {
+    end     = time(NULL);
+    elapsed = end - start;
+    i       = good_children * requests;
 
-  printf("testspeed: %dx%d=%d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
-         children, requests, i, elapsed, elapsed / i, i / elapsed);
+    printf("testspeed: %dx%d=%d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
+          good_children, requests, i, elapsed, elapsed / i, i / elapsed);
+  }
 
  /*
   * Exit with no errors...
   */
 
-  return (status);
+  return (0);
 }
 
 
@@ -185,21 +241,24 @@ main(int  argc,                           /* I - Number of command-line arguments */
 
 static int                             /* O - Exit status */
 do_test(const char        *server,     /* I - Server to use */
+        int               port,                /* I - Port number to use */
         http_encryption_t encryption,  /* I - Encryption to use */
        int               requests,     /* I - Number of requests to send */
+       const char        *opstring,    /* I - Operation string */
        int               verbose)      /* I - Verbose output? */
 {
   int          i;                      /* Looping var */
   http_t       *http;                  /* Connection to server */
-  ipp_t                *request,               /* IPP Request */
-               *response;              /* IPP Response */
-  cups_lang_t  *language;              /* Default language */
+  ipp_t                *request;               /* IPP Request */
   struct timeval start,                        /* Start time */
                end;                    /* End time */
-  double       elapsed;                /* Elapsed time */
-  static ipp_op_t ops[4] =             /* Operations to test... */
+  double       reqtime,                /* Time for this request */
+               elapsed;                /* Elapsed time */
+  int          op;                     /* Current operation */
+  static ipp_op_t ops[5] =             /* Operations to test... */
                {
                  IPP_PRINT_JOB,
+                 CUPS_GET_DEFAULT,
                  CUPS_GET_PRINTERS,
                  CUPS_GET_CLASSES,
                  IPP_GET_JOBS
@@ -210,26 +269,19 @@ do_test(const char        *server,        /* I - Server to use */
   * Connect to the server...
   */
 
-  http = httpConnectEncrypt(server, ippPort(), encryption);
-
-  if (http == NULL)
+  if ((http = httpConnectEncrypt(server, port, encryption)) == NULL)
   {
-    perror("testspeed: unable to connect to server");
+    printf("testspeed(%d): unable to connect to server - %s\n", (int)getpid(),
+           strerror(errno));
     return (1);
   }
 
-  language = cupsLangDefault();
-
  /*
   * Do multiple requests...
   */
 
   for (elapsed = 0.0, i = 0; i < requests; i ++)
   {
-    if (verbose && (i % 10) == 0)
-      printf("testspeed(%d): %d%% complete...\n", (int)getpid(),
-             i * 100 / requests);
-
    /*
     * Build a request which requires the following attributes:
     *
@@ -239,47 +291,65 @@ do_test(const char        *server,        /* I - Server to use */
     * In addition, IPP_GET_JOBS needs a printer-uri attribute.
     */
 
-    request = ippNew();
-
-    request->request.op.operation_id = ops[i & 3];
-    request->request.op.request_id   = 1;
-
-    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                "attributes-charset", NULL, cupsLangEncoding(language));
+    if (opstring)
+      op = ippOpValue(opstring);
+    else
+      op = ops[i % (int)(sizeof(ops) / sizeof(ops[0]))];
 
-    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
-                "attributes-natural-language", NULL, language->language);
+    request = ippNewRequest(op);
 
     gettimeofday(&start, NULL);
 
-    switch (request->request.op.operation_id)
+    if (verbose)
+      printf("testspeed(%d): %.6f %s ", (int)getpid(), elapsed,
+            ippOpString(op));
+
+    switch (op)
     {
       case IPP_GET_JOBS :
          ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                        NULL, "ipp://localhost/printers/");
 
       default :
-         response = cupsDoRequest(http, request, "/");
+         ippDelete(cupsDoRequest(http, request, "/"));
           break;
 
       case IPP_PRINT_JOB :
          ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                        NULL, "ipp://localhost/printers/test");
-         response = cupsDoFileRequest(http, request, "/printers/test",
-                                      "../data/testprint.ps");
+         ippDelete(cupsDoFileRequest(http, request, "/printers/test",
+                                     "../data/testprint.ps"));
           break;
     }
 
     gettimeofday(&end, NULL);
 
-    if (response != NULL)
-      ippDelete(response);
+    reqtime = (end.tv_sec - start.tv_sec) +
+              0.000001 * (end.tv_usec - start.tv_usec);
+    elapsed += reqtime;
+
+    switch (cupsLastError())
+    {
+      case IPP_OK :
+      case IPP_NOT_FOUND :
+          if (verbose)
+         {
+           printf("succeeded: %s (%.6f)\n", cupsLastErrorString(), reqtime);
+           fflush(stdout);
+         }
+          break;
+
+      default :
+          if (!verbose)
+           printf("testspeed(%d): %s ", (int)getpid(),
+                  ippOpString(ops[i & 3]));
 
-    elapsed += (end.tv_sec - start.tv_sec) +
-               0.000001 * (end.tv_usec - start.tv_usec);
+         printf("failed: %s\n", cupsLastErrorString());
+          httpClose(http);
+         return (1);
+    }
   }
 
-  cupsLangFree(language);
   httpClose(http);
 
   printf("testspeed(%d): %d requests in %.1fs (%.3fs/r, %.1fr/s)\n",
@@ -296,12 +366,7 @@ do_test(const char        *server, /* I - Server to use */
 static void
 usage(void)
 {
-  puts("Usage: testspeed [-c children] [-h] [-r requests] [-v] [-E] hostname");
+  puts("Usage: testspeed [-c children] [-h] [-o operation] [-r requests] [-v] "
+       "[-E] hostname[:port]");
   exit(0);
 }
-
-
-
-/*
- * End of "$Id: testspeed.c 5305 2006-03-18 03:05:12Z mike $".
- */