예제 #1
0
 public boolean ok(String out, String reference) {
   try {
     File fo = File.createTempFile("homeworkeval", ".out");
     File fr = File.createTempFile("homeworkeval", ".ref");
     log.fine("Running custom validator.");
     save(out, fo);
     save(reference, fr);
     ArrayList<String> c = new ArrayList<String>();
     c.add(command);
     c.add(fo.getPath());
     c.add(fr.getPath());
     ProcessBuilder pb = new ProcessBuilder(c);
     Process p = pb.start();
     int rc = p.waitFor();
     fo.delete();
     fr.delete();
     log.fine("Custom validator " + command + " says " + rc);
     return rc == 0;
   } catch (Exception e) {
     // Assume NOK. Don't propagate info to the client.
     log.finer("exc: " + UtilSrv.describe(e));
     return false;
   }
 }
예제 #2
0
 public int run(PbTest[] tests, int timelimit, int memlimit) throws ServerException {
   allStdout = new ArrayList<String>();
   allStderr = new ArrayList<String>();
   int correct = 0;
   for (int i = 0; i < tests.length; ++i) {
     try {
       exec(runCmd, tests[i].in, timelimit, memlimit);
       allStdout.add(stdout);
       allStderr.add(stderr);
       if (!stderr.isEmpty()) {
         log.fine("NOK, stderr: " + stderr);
         continue;
       }
       if (!validator.ok(stdout, tests[i].out)) continue;
       log.fine("OK");
       ++correct;
     } catch (Exception e) {
       // Assume incorrect. Do NOT propagate anyhing from the exception to
       // the client, just put it in the log.
       log.finer("exc: " + UtilSrv.describe(e));
     }
   }
   return correct;
 }
예제 #3
0
  /**
   * Executes a command as {@code user}. Saves the stdout/stderr in the corresponding fields and
   * returns the return code of the child process.
   *
   * @param cmd The command to execute
   * @param data The data to send to the stdin of the process
   * @param timelimt How many seconds the command can run
   * @param memlimit How many megabytes the command can use
   */
  private int exec(String cmdS, String data, int timelimit, int memlimit) throws Exception {
    ArrayList<String> cmd = new ArrayList<String>(cmdPrefix);
    cmd.add("-m");
    cmd.add("" + memlimit);
    cmd.add("-c");
    cmd.add("" + timelimit);
    cmd.add("-w");
    cmd.add("" + (3 * timelimit + 1));
    cmd.add("-x");
    cmd.add(cmdS);
    String tmp = "";
    for (String cs : cmd) tmp += " \"" + cs + "\"";
    log.fine("exec " + tmp);
    ProcessBuilder pb = new ProcessBuilder(cmd);
    pb.directory(workDir);
    Process p = pb.start();
    OutputStreamWriter writer = new OutputStreamWriter(p.getOutputStream());
    StreamReader rOut = new StreamReader(p.getInputStream());
    StreamReader rErr = new StreamReader(p.getErrorStream());
    rOut.start();
    rErr.start();

    // TODO I think this may block for big tests. Check and Fix.
    // send and receive data "in parallel"
    writer.write(data);
    writer.flush();
    writer.close();
    rOut.join();
    rErr.join();
    stdout = rOut.result;
    stderr = rErr.result;
    if (rOut.exception != null) throw rOut.exception;
    if (rErr.exception != null) throw rErr.exception;

    // log.finer("out: " + stdout);
    // log.finer("err: " + stderr);
    // log.finer("done exec");
    return p.waitFor();
  }
예제 #4
0
 public String[] getErr() {
   return allStderr.toArray(new String[0]);
 }
예제 #5
0
 public String[] getOut() {
   return allStdout.toArray(new String[0]);
 }