int main(int argc , char ** argv) {
  const int queue_timeout =  180;
  const int submit_timeout = 180;
  const int status_timeout = 180;
  const int number_of_jobs = 250;
  const int submit_threads = number_of_jobs / 10 ;
  const int status_threads = number_of_jobs + 1;
  const char * job = util_alloc_abs_path(argv[1]);
  rng_type * rng = rng_alloc( MZRAN , INIT_CLOCK );
  test_work_area_type * work_area = test_work_area_alloc("job_queue");
  job_type **jobs = alloc_jobs( rng , number_of_jobs , job);

  job_queue_type * queue = job_queue_alloc(number_of_jobs, "OK", "ERROR");
  queue_driver_type * driver = queue_driver_alloc_local();
  job_queue_manager_type * queue_manager = job_queue_manager_alloc( queue );

  job_queue_set_driver(queue, driver);
  job_queue_manager_start_queue(queue_manager, 0, false , true);

  {
    thread_pool_type * status_pool = thread_pool_alloc( status_threads , true );
    thread_pool_type * submit_pool = thread_pool_alloc( submit_threads , true );

    submit_jobs( queue , number_of_jobs , jobs , submit_pool );
    status_jobs( queue , number_of_jobs , jobs , status_pool );

    if (!thread_pool_try_join( submit_pool , submit_timeout ))
      util_exit("Joining submit pool failed \n");
    thread_pool_free( submit_pool );

    job_queue_submit_complete(queue);

    if (!thread_pool_try_join( status_pool , status_timeout))
      util_exit("Joining status pool failed \n");
    thread_pool_free( status_pool );
  }

  if (!job_queue_manager_try_wait(queue_manager , queue_timeout))
    util_exit("job_queue never completed \n");

  job_queue_manager_free(queue_manager);
  job_queue_free(queue);
  queue_driver_free(driver);
  check_jobs( number_of_jobs , jobs );
  test_work_area_free(work_area);
  rng_free( rng );
}
int main(int argc, char *argv[])
{
   char diagnosis[DRMAA_ERROR_STRING_BUFFER];
   char *s, jobid[100];
   int drmaa_errno, i;
   int ret = 0;
   struct timeval start_s, finish_s, wait_s;
  
   if (argc<2) {
      usage();
      return 1;
   }

   i = 1;
   do {
      if (!strcmp("-help", argv[i]) ||
          !strcmp("-h", argv[i])) {
         usage();
         return 0;

      } else if (!strcmp("-jobs", argv[i])) {
         i++; 
         if (argc < i+1) {
            usage();
            return 1;
         }
         njobs = atoi(argv[i]);
         i++; 

      } else if (!strcmp("-native", argv[i])) {
         i++; 
         if (argc < i+1) {
            usage();
            return 1;
         }
         native_spec = argv[i];
         i++; 

      } else if (!strcmp("-threads", argv[i])) {
         if (argc < i+1) {
            usage();
            return 1;
         }
         i++; 
         nthreads = atoi(argv[i]);
         i++; 

      } else if (!strcmp("-quiet", argv[i])) {
         i++; 
         if (argc < i+1) {
            usage();
            return 1;
         }
         if (!strcmp("yes", argv[i]) || !strcmp("y", argv[i])) 
            quiet = 1;
         else if (!strcmp("no", argv[i]) || !strcmp("n", argv[i])) 
            quiet = 0;
         else {
            usage();
            return 1;
         }
         i++; 

      } else if (!strcmp("-wait", argv[i])) {
         i++; 
         if (argc < i+1) {
            usage();
            return 1;
         }
         if (!strcmp("yes", argv[i]) || !strcmp("y", argv[i])) 
            dowait = 1;
         else if (!strcmp("no", argv[i]) || !strcmp("n", argv[i])) 
            dowait = 0;
         else {
            usage();
            return 1;
         }
         i++; 

      } else if (!strcmp("-scenario", argv[i])) {
         i++; 
         if (argc < i+1) {
            usage();
            return 1;
         }
         s = strchr(argv[i], '.');
         *s = '\0';
         if (strcmp("queue", argv[i]) && strcmp("type", argv[i]) && 
             strcmp("number", argv[i]) && strcmp("pe", argv[i])) {
            usage();
            return 1;
         }
         scenario = strdup(argv[i]);
        
         s++;
         if (strcmp("hostgroup", s) && strcmp("resource", s) && 
             strcmp("none", s) && strcmp("softresource", s) && 
             strcmp("softhostgroup", s)) {
            usage();
            return 1;
         }
         site_b = strdup(s);
         i++; 

      } else {
         job_path = argv[i];
         i++; 
         if (job_path[0]=='-') {
            usage();
            return 1;
         }

         if (argv[i]) {
            job_args = &argv[i];
         }
      }
   } while (i < argc && !job_path);

   if (!job_path) {
      usage();
      return 1;
   }

#if 0
   printf("job_path: \"%s\"\n", job_path);
   printf("njobs:    %d\n", njobs);
   printf("nthreads: %d\n", nthreads);
   printf("native:   %s\n", native_spec);
   printf("dowait:   %s\n", dowait?"yes":"no");
   printf("quiet:    %s\n", quiet?"yes":"no");
   printf("scenario: %s\n", scenario?scenario:"<no such>");
   printf("site_b:   %s\n", site_b?site_b:"<no such>");
   printf("1st arg:  %s\n", job_args?job_args[0]:"<noargs>");
#endif

   if (drmaa_init(NULL, diagnosis, sizeof(diagnosis)-1) != DRMAA_ERRNO_SUCCESS) {
      fprintf(stderr, "drmaa_init() failed: %s\n", diagnosis);
      return 1;
   }

   get_gmt(&start_s);

   if (!scenario) {
      if (!getuid()) {
         fprintf(stderr, "switching to ah114088:gridware\n");
         setegid(339);
         seteuid(115088);
      }

      if (!(jt = create_job_template(job_path, NULL, 0))) {
         fprintf(stderr, "create_sleeper_job_template() failed\n");
         return 1;
      }

      if (nthreads==1) {
         if (submit_jobs(&argv[i]))
             return 1;
      } else {
         pthread_t *ids = NULL;
         ids = (pthread_t *)malloc(sizeof (pthread_t) * nthreads);

         for (i = 0; i < nthreads; i++) {
            if (pthread_create(&ids[i], NULL, submit_jobs, NULL)) {
               fprintf(stderr, "pthread_create() failed: %s\n", strerror(errno));
	       free(ids);
               return 1;
            }
         }

         for (i = 0; i < nthreads; i++) {
            pthread_join(ids[i], NULL);
         }
      }
   
      drmaa_delete_job_template(jt, NULL, 0);

      if (!getuid()) {
         fprintf(stderr, "switching to root:root\n");
         seteuid(0);
         setegid(0);
      }

   } else {
      if (submit_by_project("project1") || submit_by_project("project2") ||
          submit_by_project("project3") || submit_by_project("project4"))
            return 1;
   }

   get_gmt(&finish_s);
   printf("submission took %8.3f seconds\n", DELTA_SECONDS(start_s, finish_s)); 

   if (dowait) {
      int success = 1;

      for (i=0; i<njobs * nthreads; i++) {
         int stat;
         int aborted, exited, exit_status, signaled;

         drmaa_errno = drmaa_wait(DRMAA_JOB_IDS_SESSION_ANY, jobid, sizeof(jobid)-1, 
            &stat, DRMAA_TIMEOUT_WAIT_FOREVER, NULL, diagnosis, sizeof(diagnosis)-1);

         if (drmaa_errno != DRMAA_ERRNO_SUCCESS) {
            fprintf(stderr, "drmaa_wait() failed: %s\n", diagnosis);
            return 1;
         }

         /*
          * report how job finished 
          */
         drmaa_wifaborted(&aborted, stat, NULL, 0);
         if (aborted) {
            printf("job \"%s\" never ran\n", jobid);
            success = 0;
         } else {
            drmaa_wifexited(&exited, stat, NULL, 0);
            if (exited) {
               drmaa_wexitstatus(&exit_status, stat, NULL, 0);
               if (exit_status != 0) {
                  success = 0;
                  printf("job \"%s\" with exit status %d\n", jobid, exit_status);
               } else {
                  if (!quiet)
                     printf("job \"%s\" finished regularly\n", jobid);
               }
            } else {
               success = 0;
               drmaa_wifsignaled(&signaled, stat, NULL, 0);
               if (signaled) {
                  char termsig[DRMAA_SIGNAL_BUFFER+1];
                  drmaa_wtermsig(termsig, DRMAA_SIGNAL_BUFFER, stat, NULL, 0);
                  printf("job \"%s\" finished due to signal %s\n", jobid, termsig);
               } else
                  printf("job \"%s\" finished with unclear conditions\n", jobid);
            }
         }
      }

      if (!success)
         ret = 1;

      get_gmt(&wait_s);
      printf("wait took %8.3f seconds\n", DELTA_SECONDS(finish_s, wait_s)); 
      printf("jobs took %8.3f seconds\n", DELTA_SECONDS(start_s, wait_s)); 
   }

   if (drmaa_exit(diagnosis, sizeof(diagnosis)-1) != DRMAA_ERRNO_SUCCESS) {
      fprintf(stderr, "drmaa_exit() failed: %s\n", diagnosis);
      return 1;
   }
   
  return ret;
}