def compile(compile_string, path):
    """ Runs given string and raises exception if it returned any error. """
    exitcode, stdout, stderr = execute_process(compile_string, testdir=path)
    if exitcode:  # Compilation fails if returned non-zero exit code
        if exitcode != -9:
            raise CompilationError(stderr)
        else:
            raise CompilationLimitExceeded()
def unlambda_tester(task, path):
  solution_file = os.path.join(path, task.filenames[0])
  test_number = 1
  for template, output in task.tests:
    substitute_and_write_solution(template, task.source, solution_file)
    exitcode, stdout, stderr = execute_process(task.execute_string, testdir = path)
    if exitcode != 0 and exitcode != -9:
      logger.warning('Testing crashed: %s' % stderr)
      raise Crash("Program crashed on test #%s" % test_number)
    elif exitcode == -9:
      raise TimeLimitExceeded()
    elif not task.checker(output, stdout):
      raise WrongAnswer("Failed on test #%s" % test_number)
    test_number += 1
def default_tester(task, path):
  """Tests a user's solution of the task using a default execution line for
  task's language.

  This function tests solutions which are sent by users using a default
  command line for executing tasks of this language.

  Args:
    task: Task to be tested. It's assumed that task.execute_string has command
        line to execute a solution.
    path: Path to testing area.

  Returns:
    None.

  Raises:
    Crash: User's solution crashed.
    WrongAnswer: User's solution returned a wrong answer.
  """
  test_number = 1
  for input, output in task.tests:
    task.before_test(path, test_number)
    exitcode, stdout, stderr = execute_process(task.execute_string, input, testdir = path, timelimit = task.test_timelimit)
    if exitcode != 0 and not is_timeout(exitcode):
      logger.warning('Testing crashed: %s stdout %s, stderr %s' % (exitcode, stdout, stderr))
      if len(task.test_descriptions) < test_number:
        message = "Program crashed on test #%s\n%s" % (test_number, stderr)
      else:
        message = "Program crashed on #%s\n%s\n%s" % (test_number, task.test_descriptions[test_number - 1], stderr)
      raise Crash(message)
    elif is_timeout(exitcode):
      if len(task.test_descriptions) < test_number:
        message = "Code execution time limit exceeded on test #%s" % test_number
      else:
        message = "Code execution time limit exceeded on test #%s\n%s" % (test_number, task.test_descriptions[test_number - 1])
      raise TimeLimitExceeded(message)
    elif not task.checker(output, stdout):
      if len(task.test_descriptions) < test_number:
        message = "Failed on test #%s" % test_number
      else:
        message = "Failed on test #%s\n%s" % (test_number, task.test_descriptions[test_number - 1])
      raise WrongAnswer(message)
    test_number += 1