void dointeractive() {
  LOG("Runid: " + Inttostring(bott->Getrunid()) + " Type: Interactive");

  retbott.Settype(RESULT_REPORT);
  retbott.Setrunid(bott->Getrunid());
  Interactive * usrprogram = new Interactive;
  usrprogram->Setlanguage(bott->Getlanguage());
  usrprogram->Setsource(bott->Getsrc());
  problem = new PConfig(bott->Getpid(), "interactive");
  usrprogram->SetValidator_source(
      Loadallfromfile(problem->Getvalidator_filename()));
  usrprogram->SetValidator_language(problem->Getvalidator_language());

  usrprogram->Setcase_time_limit(bott->Getcase_limit());
  usrprogram->Settotal_time_limit(bott->Gettime_limit());
  usrprogram->Setmemory_limit(bott->Getmemory_limit());
  usrprogram->Setout_filename(CONFIG->GetTmpfile_path() + tmpnam());

  usrprogram->Run();
  retbott.Setce_info(usrprogram->Getce_info());
  retbott.Settime_used(usrprogram->Gettime_used());
  retbott.Setmemory_used(usrprogram->Getmemory_used());
  retbott.Setresult(usrprogram->Getresult());

  retbott.Setout_filename("results/" + Inttostring(retbott.Getrunid()));
  retbott.toFile();
  delete usrprogram;
  delete problem;
  send_result(retbott.Getout_filename());
}
Beispiel #2
0
/**
 * Start virtual judger
 */
void VirtualJudger::run() {
  log("Judger started");
  initHandShake();
  while (true) {
    socket->receiveFile(tmpfilename);
    Bott * bott = new Bott(tmpfilename);
    log((string) "Received a new task, problem: " + bott->Getvid() + ".");
    string result_filename = Bott::RESULTS_DIRECTORY +
        intToString(bott->Getrunid());
    if (bott->Gettype() == NEED_JUDGE) {
      // Currently for vjudge, only NEED_JUDGE is supported
      try {
        if (bott->Getsrc().length() < MIN_SOURCE_LENGTH) {
          // source code too short, may cause problem in remote OJ, such as PKU
          bott->Setout_filename(result_filename);
          generateSpecialResult(bott, "Compile Error");
          bott->Setce_info("Source code too short, minimum length: " +
              intToString(MIN_SOURCE_LENGTH));
          bott->save();
        } else {
          judge(bott, result_filename);
        }
      } catch (Exception & e) {
        // Exception occurs, set to Judge Error
        log((string) "Judge error! Reason: " + e.what());

        // reuse bott file
        bott->Setout_filename(result_filename);
        generateSpecialResult(bott, "Judge Error");
        bott->save();
      } catch (exception & e) {
        // Exception occurs, set to Judge Error
        log((string) "Judge error! Reason: " + e.what());

        // reuse bott file
        bott->Setout_filename(result_filename);
        generateSpecialResult(bott, "Judge Error");
        bott->save();
      }
      delete bott;
    } else {
      delete bott;
      throw Exception("Type not supported.");
    }
    socket->sendFile(result_filename);
  }
}
void dojudge(int type) {
  LOG("Runid: " + Inttostring(bott->Getrunid()) + " Type: " +
      Inttostring(type));
  vector <string> in_files;
  if (!getalldata(bott->Getpid(), in_files, type) || in_files.size() == 0) {
    retbott.Settype(RESULT_REPORT);
    retbott.Setrunid(bott->Getrunid());
    retbott.Settime_used(0);
    retbott.Setmemory_used(0);
    retbott.Setresult("Judge Error (No Data)");
    retbott.Setout_filename("results/" + Inttostring(retbott.Getrunid()));
    retbott.toFile();
    send_result(retbott.Getout_filename());
    return;
  }
  string inpfile = CONFIG->GetTmpfile_path() + tmpnam();
  string stdout_file = CONFIG->GetTmpfile_path() + tmpnam();
  retbott.Settype(RESULT_REPORT);
  retbott.Setrunid(bott->Getrunid());
  usrprogram = new Program;
  usrprogram->Setlanguage(bott->Getlanguage());
  usrprogram->Setsource(bott->Getsrc());
  usrprogram->Sethas_input(true);
  usrprogram->Setin_filename(inpfile);
  usrprogram->Setout_filename(CONFIG->GetTmpfile_path() + tmpnam());
  usrprogram->Seterr_filename(CONFIG->GetTmpfile_path() + tmpnam());
  if (type == NEED_JUDGE)
    usrprogram->Settotal_time_limit(bott->Gettime_limit());
  else usrprogram->Settotal_time_limit(bott->Getcase_limit() * in_files.size());
  usrprogram->Setcase_time_limit(bott->Getcase_limit());
  usrprogram->Setmemory_limit(bott->Getmemory_limit());
  bool aced, peed, jeed = false, has = false;
  aced = peed = true;
  cmp = new Comparator;
  cmp->Setin_filename(inpfile);
  cmp->Setout_filename(usrprogram->Getout_filename());
  cmp->Setisspj(bott->Getspj());
  cmp->Setpid(bott->Getpid());
  for (unsigned int i = 0; i < in_files.size(); i++) {
    system(((string) "cp " + in_files[i] + ".in " + inpfile).c_str());
    LOG((string) "Do " + in_files[i]);
    usrprogram->Run();
    if (usrprogram->Getresult() != "Normal") {
      retbott.Setresult(usrprogram->Getresult());
      has = true;
      break;
    } else {
      system(((string) "cp " + in_files[i] + ".out " + stdout_file).c_str());
      system(((string) "chmod 755 " + stdout_file).c_str());
      system(((string) "chmod 755 " + inpfile).c_str());
      cmp->Setstdout_filename(stdout_file);
      cmp->Setsrc_filename(usrprogram->Getsrc_filename());
      int cres = cmp->Compare();
      system(((string) "rm " + stdout_file).c_str());
      system(((string) "chmod 600 " + inpfile).c_str());
      if (cres == PE_STATUS) aced = false;
      else if (cres == JE_STATUS) {
        jeed = false;
        break;
      } else if (cres != AC_STATUS) {
        aced = peed = false;
        break;
      }
    }
  }
  retbott.Setce_info(usrprogram->Getce_info());
  retbott.Settime_used(usrprogram->Gettime_used());
  retbott.Setmemory_used(usrprogram->Getmemory_used());
  if (has) retbott.Setresult(usrprogram->Getresult());
  else if (jeed) retbott.Setresult("Judge Error (No SPJ)");
  else if (aced) {
    if (type == DO_PRETEST) retbott.Setresult("Pretest Passed");
    else retbott.Setresult("Accepted");
  } else if (peed) retbott.Setresult("Presentation Error");
  else retbott.Setresult("Wrong Answer");
  retbott.Setout_filename("results/" + Inttostring(retbott.Getrunid()));
  retbott.toFile();
  delete cmp;
  delete usrprogram;
  send_result(retbott.Getout_filename());
}
Beispiel #4
0
/**
 * Send a submit to remote, and store the judge result
 * @param bott      Submit info
 * @param filename  File store the result
 */
void VirtualJudger::judge(Bott * bott, string filename) {
  // login
  if (!logged_in) { // Not logged in, try login
    clearCookies();
    login();
    log("Logged in.");
    logged_in = true;
  }

  // submit
  int submit_status = submit(bott);
  if (submit_status == SUBMIT_OTHER_ERROR) {
    // first time fail, blame login status...
    log((string) "Submit error. Assume not logged in.");
    logged_in = false;
    clearCookies();
    login();
    log("Logged in.");
    logged_in = true;
    submit_status = submit(bott);
    if (submit_status == SUBMIT_OTHER_ERROR) {
      // second time fail, blame frequency
      if (info->GetOj() == "CodeChef") {
        // CodeChef's restriction is harsh... 30 seconds cool down required
        log("Submit error. Assume should sleep for a while, "
            "sleeping 30 seconds.");
        sleep(30);
      } else {
        log("Submit error. Assume should sleep for a while, sleeping " +
            intToString(VirtualJudger::SLEEP_INTERVAL) + " seconds.");
        sleep(VirtualJudger::SLEEP_INTERVAL);
      }
      submit_status = submit(bott);
    }
  } else if (submit_status == SUBMIT_INVALID_LANGUAGE &&
      (info->GetOj() == "SPOJ" || info->GetOj() == "CodeChef") &&
      convertLanguage(bott->Getlanguage()) == "41") {
    // Special HACK for Invalid Language on SPOJ/CodeChef, since they have two
    // C++ types and each covers a certain subset of problems
    log((string) "Try another C++ for SPOJ/CodeChef");
    bott->Setlanguage(1);
    submit_status = submit(bott);
  }
  if (submit_status != SUBMIT_OTHER_ERROR) log("Submitted.");

  // check submit status
  sleep(1); // sleep 1 second, just in case remote status table is not refreshed
  Bott * result;
  if (submit_status == SUBMIT_NORMAL) {
    // get status
    result = getStatus(bott);
    result->Setrunid(bott->Getrunid());
    if (result->Getresult() == "Compile Error") {
      try {
        result->Setce_info(getCEinfo(result));
      } catch (...) {
        log("Failed to get CE info, use empty one instead.");
        result->Setce_info("");
      }
    }
  } else {
    result = new Bott;
    result->Setrunid(bott->Getrunid());
    switch (submit_status) {
      case SUBMIT_SAME_CODE:
        generateSpecialResult(result, "Judge Error (Same Code)");
        break;
      case SUBMIT_INVALID_LANGUAGE:
        generateSpecialResult(result, "Judge Error (Invalid Language)");
        break;
      case SUBMIT_COMPILE_ERROR:
        generateSpecialResult(result, "Compile Error");
        break;
      default:
        log("Submit Error.");
        generateSpecialResult(result, "Judge Error");
    }
  }
  result->Setout_filename(filename);
  result->save();
  log("Done judging. Result: " + result->Getresult() + ", remote runid: " +
      result->Getremote_runid());
  delete result;
}