Beispiel #1
0
  public void execute()
      throws IOException, DocumentException, ParseException, InterruptedException,
          SubmissionException {
    FileReader r = new FileReader(problemJson);
    //		ProblemWithTestCases problemWithTestCases;
    //		try {
    //			problemWithTestCases = new ProblemReader().read(r);
    //		} finally {
    //			r.close();
    //		}

    ProblemAndTestCaseList problemWithTestCases = new ProblemAndTestCaseList();

    try {
      JSONConversion.readProblemAndTestCaseData(
          problemWithTestCases,
          ReflectionFactory.forClass(Problem.class),
          ReflectionFactory.forClass(TestCase.class),
          r);
    } finally {
      r.close();
    }

    // Set fake problem id and course id
    problemWithTestCases.getProblem().setProblemId(1);
    problemWithTestCases.getProblem().setCourseId(1);

    // Start a server thread for communicating with the builder
    ServerSocket serverSocket = new ServerSocket(OutOfProcessSubmitService.DEFAULT_PORT);
    this.serverTask = new ServerTask(serverSocket);
    Thread serverThread = new Thread(serverTask);
    serverThread.start();

    try {
      testAll(fileNameList, problemWithTestCases);
    } finally {
      serverTask.shutdown();
      serverThread.join();
      serverSocket.close();
    }
  }
Beispiel #2
0
  private void testOne(ProblemAndTestCaseList problemWithTestCases, String fileName)
      throws IOException, SubmissionException, InterruptedException {
    String programText = readProgram(fileName);

    OOPBuildServiceSubmission future =
        new OOPBuildServiceSubmission(
            new Submission(
                problemWithTestCases.getProblem(),
                Arrays.asList(problemWithTestCases.getTestCaseList()),
                programText));

    serverTask.submit(future);

    SubmissionResult result;
    while (true) {
      result = future.poll();
      if (result != null) {
        break;
      }
      Thread.sleep(200L);
    }

    if (fileName.startsWith("./")) {
      fileName = fileName.substring(2);
    }

    System.out.println("program: " + fileName);
    if (result.getCompilationResult().getOutcome() != CompilationOutcome.SUCCESS) {
      System.out.println("compiled: false");
      return;
    }
    System.out.println("compiled: true");

    for (int i = 0; i < problemWithTestCases.getTestCaseList().length; i++) {
      TestCase testCase = problemWithTestCases.getTestCaseList()[i];
      TestResult testResult = result.getTestResults()[i];

      String outcome;
      switch (testResult.getOutcome()) {
        case PASSED:
          outcome = "passed";
          break;
        case FAILED_WITH_EXCEPTION:
          outcome = "crashed";
          break;
        case FAILED_FROM_TIMEOUT:
          outcome = "timeout";
          break;
        default:
          outcome = "failed";
          break;
      }
      System.out.println("test " + testCase.getTestCaseName() + ":" + outcome);
      if (testResult.getOutcome() != TestOutcome.PASSED) {
        String output = testResult.getStdout();
        if (!output.endsWith("\n")) {
          output = output + "\n";
        }
        System.out.print(output);
      }
    }
  }
  @Override
  public ShareExercisesResult submitExercises(
      Problem[] problems, String repoUsername, String repoPassword)
      throws CloudCoderAuthenticationException {
    logger.warn("Sharing " + problems.length + " exercises");

    // create the result place holder
    ShareExercisesResult result = new ShareExercisesResult(problems.length);

    if (problems.length == 0) {
      result.failAll("No problems to be shared!");
      return result;
    }

    // Only a course instructor may share an exercise.
    User authenticatedUser =
        ServletUtil.checkClientIsAuthenticated(
            getThreadLocalRequest(), GetCoursesAndProblemsServiceImpl.class);
    Course course = new Course();
    course.setId(problems[0].getCourseId());
    Database.getInstance().reloadModelObject(course);
    CourseRegistrationList regList =
        Database.getInstance().findCourseRegistrations(authenticatedUser, course);
    if (!regList.isInstructor()) {
      result.failAll("You must be an instructor to share an exercise");
      return result;
    }

    // Get the exercise repository URL
    ConfigurationSetting repoUrlSetting =
        Database.getInstance().getConfigurationSetting(ConfigurationSettingName.PUB_REPOSITORY_URL);
    if (repoUrlSetting == null) {
      result.failAll("URL of exercise repository is not configured");
      return result;
    }
    String repoUrl = repoUrlSetting.getValue();
    if (repoUrl.endsWith("/")) {
      repoUrl = repoUrl.substring(0, repoUrl.length() - 1);
    }

    HttpPost post = new HttpPost(repoUrl + "/exercisedata");

    // Encode an Authorization header using the provided repository username and password.
    String authHeaderValue =
        "Basic "
            + DatatypeConverter.printBase64Binary(
                (repoUsername + ":" + repoPassword).getBytes(Charset.forName("UTF-8")));
    // System.out.println("Authorization: " + authHeaderValue);
    post.addHeader("Authorization", authHeaderValue);

    // Now go through and upload each problem
    // For now, we do this one at a time
    // In the future we could send problems and test cases
    // to the repo in bulk, and add a new web service to handle it

    for (Problem p : problems) {
      // Look up the test cases
      List<TestCase> testCaseList = Database.getInstance().getTestCasesForProblem(p.getProblemId());
      ProblemAndTestCaseList exercise = new ProblemAndTestCaseList();
      exercise.setProblem(p);
      exercise.setTestCaseList(testCaseList);

      // Convert the exercise to a JSON string
      StringEntity entity;
      StringWriter sw = new StringWriter();
      try {
        JSONConversion.writeProblemAndTestCaseData(exercise, sw);
        entity = new StringEntity(sw.toString(), ContentType.create("application/json", "UTF-8"));
      } catch (IOException e) {
        // fail remaining test cases and return our results thus far
        // some exercises may have been successfully shared
        result.failRemaining("Could not convert exercise to JSON: " + e.getMessage());
        return result;
      }
      post.setEntity(entity);

      // POST the exercise to the repository
      HttpClient client = new DefaultHttpClient();
      try {
        HttpResponse response = client.execute(post);

        StatusLine statusLine = response.getStatusLine();

        if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
          // Update the exercise's shared flag so we have a record that it was shared.
          exercise.getProblem().setShared(true);
          exercise.getProblem().setProblemAuthorship(ProblemAuthorship.IMPORTED);
          Database.getInstance().storeProblemAndTestCaseList(exercise, course, authenticatedUser);
          result.success();
        } else if (statusLine.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
          result.failRemaining(
              "Authentication with repository failed - incorrect username/password?");
          return result;
        } else {
          result.failRemaining(
              "Failed to publish exercise to repository: " + statusLine.getReasonPhrase());
          return result;
        }
      } catch (ClientProtocolException e) {
        result.failRemaining("Error sending exercise to repository: " + e.getMessage());
        return result;
      } catch (IOException e) {
        result.failRemaining("Error sending exercise to repository: " + e.getMessage());
        return result;
      } finally {
        client.getConnectionManager().shutdown();
      }
    }
    result.allSucceeded(
        "Successfully uploaded " + problems.length + " exercise to repository.  Thanks!");
    return result;
  }
  @Override
  public ProblemAndTestCaseList importExercise(Course course, String exerciseHash)
      throws CloudCoderAuthenticationException {
    if (course == null || exerciseHash == null) {
      throw new IllegalArgumentException();
    }

    // Make sure a user is authenticated
    User user =
        ServletUtil.checkClientIsAuthenticated(
            getThreadLocalRequest(), GetCoursesAndProblemsServiceImpl.class);

    // Find user's registration in the course: if user is not instructor,
    // import is not allowed
    CourseRegistrationList reg = Database.getInstance().findCourseRegistrations(user, course);
    if (!reg.isInstructor()) {
      throw new CloudCoderAuthenticationException(
          "Only an instructor can import a problem in a course");
    }

    // Attempt to load the problem from the exercise repository.
    ConfigurationSetting repoUrlSetting =
        Database.getInstance().getConfigurationSetting(ConfigurationSettingName.PUB_REPOSITORY_URL);
    if (repoUrlSetting == null) {
      logger.error("Repository URL configuration setting is not set");
      return null;
    }

    // GET the exercise from the repository
    HttpGet get = new HttpGet(repoUrlSetting.getValue() + "/exercisedata/" + exerciseHash);
    ProblemAndTestCaseList exercise = null;

    HttpClient client = new DefaultHttpClient();
    try {
      HttpResponse response = client.execute(get);

      HttpEntity entity = response.getEntity();

      ContentType contentType = ContentType.getOrDefault(entity);
      Reader reader = new InputStreamReader(entity.getContent(), contentType.getCharset());

      exercise = new ProblemAndTestCaseList();
      exercise.setTestCaseList(new TestCase[0]);
      JSONConversion.readProblemAndTestCaseData(
          exercise,
          ReflectionFactory.forClass(Problem.class),
          ReflectionFactory.forClass(TestCase.class),
          reader);

      // Set the course id
      exercise.getProblem().setCourseId(course.getId());
    } catch (IOException e) {
      logger.error("Error importing exercise from repository", e);
      return null;
    } finally {
      client.getConnectionManager().shutdown();
    }

    // Set "when assigned" and "when due" to reasonable default values
    long now = System.currentTimeMillis();
    exercise.getProblem().setWhenAssigned(now);
    exercise.getProblem().setWhenDue(now + 48L * 60L * 60L * 1000L);

    // Set problem authorship as IMPORTED
    exercise.getProblem().setProblemAuthorship(ProblemAuthorship.IMPORTED);

    // For IMPORTED problems, parent_hash is actually the hash of the problem
    // itself.  If the problem is modified (and the authorship changed
    // to IMPORTED_AND_MODIFIED), then the (unchanged) parent_hash value
    // really does reflect the "parent" problem.
    exercise.getProblem().setParentHash(exerciseHash);

    // Store the exercise in the database
    exercise = Database.getInstance().storeProblemAndTestCaseList(exercise, course, user);

    return exercise;
  }
  /* (non-Javadoc)
   * @see org.cloudcoder.app.client.rpc.GetCoursesAndProblemsService#submitExercise(org.cloudcoder.app.shared.model.ProblemAndTestCaseList, java.lang.String, java.lang.String)
   */
  @Override
  public OperationResult submitExercise(
      ProblemAndTestCaseList exercise, String repoUsername, String repoPassword)
      throws CloudCoderAuthenticationException {
    logger.warn("Sharing exercise: " + exercise.getProblem().getTestname());

    // Only a course instructor may share an exercise.
    User authenticatedUser =
        ServletUtil.checkClientIsAuthenticated(
            getThreadLocalRequest(), GetCoursesAndProblemsServiceImpl.class);
    Course course = new Course();
    course.setId(exercise.getProblem().getCourseId());
    Database.getInstance().reloadModelObject(course);
    CourseRegistrationList regList =
        Database.getInstance().findCourseRegistrations(authenticatedUser, course);
    if (!regList.isInstructor()) {
      return new OperationResult(false, "You must be an instructor to share an exercise");
    }

    // Get the exercise repository URL
    ConfigurationSetting repoUrlSetting =
        Database.getInstance().getConfigurationSetting(ConfigurationSettingName.PUB_REPOSITORY_URL);
    if (repoUrlSetting == null) {
      return new OperationResult(false, "URL of exercise repository is not configured");
    }
    String repoUrl = repoUrlSetting.getValue();
    if (repoUrl.endsWith("/")) {
      repoUrl = repoUrl.substring(0, repoUrl.length() - 1);
    }

    HttpPost post = new HttpPost(repoUrl + "/exercisedata");

    // Encode an Authorization header using the provided repository username and password.
    String authHeaderValue =
        "Basic "
            + DatatypeConverter.printBase64Binary(
                (repoUsername + ":" + repoPassword).getBytes(Charset.forName("UTF-8")));
    // System.out.println("Authorization: " + authHeaderValue);
    post.addHeader("Authorization", authHeaderValue);

    // Convert the exercise to a JSON string
    StringEntity entity;
    StringWriter sw = new StringWriter();
    try {
      JSONConversion.writeProblemAndTestCaseData(exercise, sw);
      entity = new StringEntity(sw.toString(), ContentType.create("application/json", "UTF-8"));
    } catch (IOException e) {
      return new OperationResult(false, "Could not convert exercise to JSON: " + e.getMessage());
    }
    post.setEntity(entity);

    // POST the exercise to the repository
    HttpClient client = new DefaultHttpClient();
    try {
      HttpResponse response = client.execute(post);

      StatusLine statusLine = response.getStatusLine();

      if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
        // Update the exercise's shared flag so we have a record that it was shared.
        exercise.getProblem().setShared(true);
        Database.getInstance().storeProblemAndTestCaseList(exercise, course, authenticatedUser);

        return new OperationResult(
            true, "Exercise successfully published to the repository - thank you!");
      } else if (statusLine.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
        return new OperationResult(
            false, "Authentication with repository failed - incorrect username/password?");
      } else {
        return new OperationResult(
            false, "Failed to publish exercise to repository: " + statusLine.getReasonPhrase());
      }
    } catch (ClientProtocolException e) {
      return new OperationResult(false, "Error sending exercise to repository: " + e.getMessage());
    } catch (IOException e) {
      return new OperationResult(false, "Error sending exercise to repository: " + e.getMessage());
    } finally {
      client.getConnectionManager().shutdown();
    }
  }