/** * 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); }