Example #1
0
/**
 * Main testing thread
 */
static void
testing_thread (gpointer __data, gpointer __user_data)
{
  wt_task_t *task = __data;

  char pchar[65536];

  /* Directories for current testing stuff */
  char cur_testing_dir[4096];
  char cur_data_dir[4096];
  char lock_file[4096];

  int points = 0, rc;
  char errors[MAX_TESTS * (MAX_ERRCODE + 1)];
  FILE *stream;

  assarr_t *all_params;

  /* Update status of the task */
  TASK_SET_STATUS (*task, TS_RUNNING);

  INF_DEBUG_LOG ("Started new thread for testing task %ld\n", task->sid);

  all_params = assarr_create ();

  /* Calculating current testing and data directories */
  snprintf (cur_testing_dir, BUF_SIZE (cur_testing_dir),
            "%s/%ld", testing_dir, task->sid);
  snprintf (cur_data_dir, BUF_SIZE (cur_data_dir), "%s/%s/%s", data_dir,
            problems_dir, (char*) TASK_INPUT_PARAM (*task, "PROBLEMID"));

  /* Delete all unwanted data */
  unlinkdir (cur_testing_dir);

  /* Create global testing root. */
  /* Deny reading of this root to deny getting listing of this catalogue */
  /* to executable solutions. */
  fmkdir (testing_dir, 00773);

  /* Create current testing directory */
  mutex_lock (lck_mutex);
  snprintf (lock_file, BUF_SIZE (lock_file), "%s/lock", cur_testing_dir);
  fmkdir (cur_testing_dir, 00777);
  flock_set (lock_file);
  mutex_unlock (lck_mutex);

  /* Some initialization */
  points = 0;
  strcpy (errors, "");

  /* Start logging */
  print_common_info (task);

  /*
   * TODO: Add TASK_SET_RESULT_MESSAGE() in case of testing crash
   */

  INF_DEBUG_LOG ("Task %ld. Check for required parameters\n", task->sid);

  /* Check for required data */
  if (!check_required_params (task, pchar))
    {
      strcpy (errors, "CR");
      TASK_LOG (*task, "\n========\n"
                       "Fatal error: Required params aren't defined: %s! "
                       "Testing aborted.\n", pchar);
      REPORT (all_params, "Required params aren't defined: %s.", pchar);
      goto __done_;
    }

  /****
   * TESTING STUFF
   */

  /*
   * Step 0: Saving solution source to file
   */

  INF_DEBUG_LOG ("Task %ld. Step 0: Save solution\n", task->sid);

  if (!save_solution (task, cur_testing_dir))
    {
      strcpy (errors, "CR");
      TASK_LOG (*task, "\n========\nFatal error: unable to save solution! "
                        "Testing aborted.\n");
      REPORT (all_params, "Error saving solution.");
      goto __done_;
    }

  /*
   * Step 1: Compiling colution
   */
  INF_DEBUG_LOG ("Task %ld. Step 1: Compile solution\n", task->sid);

  rc = compile_solution (task, cur_testing_dir, cur_data_dir, all_params);

  TESTING_CHECK_ACTIVE;

  if (rc < 0)
    {
      /* Fatal errors while compile */
      INF_DEBUG_LOG ("[EE] Task %ld. Ctirical error during solution "
                     "compilation process\n");
      points = 0;
      strcpy (errors, "CR");
      TASK_LOG (*task, "\n========\nFatal error while compiling solution. "
                       "Testing aborted.\n");
      goto __done_;
    }

  if (!rc)
    {
      /* Simple compilation error */
      points = 0;
      strcpy (errors, "CE");
      goto __done_;
    }

  /*
   * Step 2: Exec solution at all tests
   */
  testing_main_loop (task, cur_data_dir, cur_testing_dir,
                     &points, errors, all_params);

  TESTING_CHECK_ACTIVE;

__done_:

  /* Updating avaliable parameters */
  snprintf (pchar, BUF_SIZE (pchar), "%d", points);
  assarr_set_value (all_params, "POINTS", strdup (pchar));
  assarr_set_value (all_params, "ERRORS", strdup (errors));

  /* Set output parameters for WebInterface */
  set_output_params (task, all_params);

  /* Some uinitialization */
  assarr_destroy (all_params, assarr_deleter_free_ref_data);

  if (strcmp (errors, "OK"))
    {
      snprintf (pchar, BUF_SIZE (pchar), "Points: %d. Errors: %s",
                points, errors);
    }
  else
    {
      int bonus = atoi (TASK_INPUT_PARAM (*task, "BONUS"));
      snprintf (pchar, BUF_SIZE (pchar), "Points: %d. Bonus: %d",
                points - bonus, bonus);
    }
  TASK_SET_RESULT_MESSAGE (*task, pchar);

  if (strcmp (errors, "CE") && strcmp (errors, "CR"))
    {
      TASK_LOG (*task, "\n========\nTesting completed: %s\n", pchar);
    }

  /* Save log */
  snprintf (pchar, BUF_SIZE (pchar), "%s/%s",
            cur_testing_dir, SOLUTION_ERRORS_LOG);
  stream = fopen (pchar, "w");
  if (stream)
    {
      fprintf (stream, "%s", log_banner);
      TASK_LOG_FLUSH (*task, stream);
      fclose (stream);
    }
  chmod (pchar, 00660);

  INF_DEBUG_LOG ("Task %ld tested\n", task->sid);

  /* Now task is completely tested */
  TASK_SET_STATUS (*task, TS_FINISHED);

  goto __all_done_;

__free_:
  assarr_destroy (all_params, assarr_deleter_free_ref_data);
  TASK_SET_STATUS (*task, TS_INTERRUPTED);

__all_done_:
  flock_clear (lock_file);

  unlink_unwanted_testing_dirs ();

  INF_DEBUG_LOG ("Leave testing thread\n");
}
boolean_t
unpack_package_from_stream(char *a_idsName, char *a_pkginst, char *a_tempDir)
{
	int		dparts;
	char		instdir[PATH_MAX];

	/* entry assertions */

	assert(a_idsName != (char *)NULL);
	assert(a_pkginst != (char *)NULL);
	assert(a_tempDir != (char *)NULL);

	/* entry debug information */

	echoDebug(DBG_UNPACKSTRM_ENTRY);
	echoDebug(DBG_UNPACKSTRM_ARGS, a_pkginst, a_idsName, a_tempDir);

	/* find the specified package in the datastream */

	dparts = ds_findpkg(a_idsName, a_pkginst);
	if (dparts < 1) {
		progerr(gettext(ERR_DSARCH), a_pkginst);
		return (B_FALSE);
		/*NOTREACHED*/
	}

	/*
	 * read in next part from stream, even if we decide
	 * later that we don't need it
	 */

	/* create directory to hold this package instance */

	if (snprintf(instdir, sizeof (instdir), "%s/%s", a_tempDir, a_pkginst)
	    >= PATH_MAX) {
		progerr(ERR_CREATE_PATH_2, a_tempDir, a_pkginst);
		return (B_FALSE);
	}

	switch (fmkdir(instdir, 0755)) {
	case 0:	/* directory created */
		break;
	case 1: /* could not remove existing non-directory node */
		progerr(ERR_REMOVE, instdir, strerror(errno));
		return (B_FALSE);
	case 2: /* could not create specified new directory */
	default:
		progerr(ERR_UNPACK_FMKDIR, instdir, strerror(errno));
		return (B_FALSE);
	}

	/* unpack package instance from stream to dir created */

	echoDebug(DBG_UNPACKSTRM_UNPACKING, a_pkginst, a_idsName, instdir);

	if (chdir(instdir)) {
		progerr(ERR_CHDIR, instdir);
		return (B_FALSE);
	}

	dparts--;
	if (ds_next(a_idsName, instdir)) {
		progerr(ERR_UNPACK_DSREAD, dparts+1, a_idsName, instdir,
			a_pkginst);
		return (B_FALSE);
	}

	if (chdir(get_PKGADM())) {
		progerr(gettext(ERR_CHDIR), get_PKGADM());
		return (B_FALSE);
	}

	return (B_TRUE);
}