A code autograder for student homework submissions
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
1.4 KiB

  1. module KGrader
  2. class Jail
  3. def initialize(root)
  4. @root = root
  5. @salt = nil
  6. end
  7. def reset
  8. FileUtils.rm_rf @root
  9. end
  10. def init
  11. FileUtils.mkdir_p @root
  12. @salt = rand(100000000).to_s
  13. end
  14. def stage(source, target)
  15. FileUtils.cp source, File.join(@root, target)
  16. end
  17. def exec(command, logpath)
  18. pid = execute command, logpath
  19. Process.waitpid pid, 0
  20. $?.exited? && $?.exitstatus == 0
  21. end
  22. def run_test(script, logpath)
  23. grade_rd, grade_wr = IO.pipe
  24. cmt_rd, cmt_wr = IO.pipe
  25. command = ['ruby', '-r', '../lib/kgrader/runtime.rb', script, @salt]
  26. pid = execute command, logpath do |options|
  27. [grade_rd, cmt_rd].each &:close
  28. options[3] = grade_wr
  29. options[4] = cmt_wr
  30. end
  31. [grade_wr, cmt_wr].each &:close
  32. Process.waitpid pid, 0
  33. grade = grade_rd.read.strip.to_i
  34. comments = cmt_rd.read.split("\n")
  35. [grade_rd, cmt_rd].each &:close
  36. return grade, comments
  37. end
  38. private
  39. def execute(command, logpath)
  40. Process.fork do
  41. fp = File.open(logpath, 'a')
  42. Dir.chdir @root
  43. options = {
  44. :in => :close, :out => fp, :err => fp, :close_others => true,
  45. :rlimit_nproc => 64
  46. }
  47. yield options if block_given?
  48. Process.exec *command, options
  49. end
  50. end
  51. end
  52. end