def compile(self, job, file_cacher): """See TaskType.compile.""" language = get_language(job.language) source_ext = language.source_extension if not check_files_number(job, 1, or_more=True): return # Prepare the files to copy in the sandbox and to add to the # compilation command. files_to_get = {} source_filenames = [] # The stub, that must have been provided (copy and add to compilation). if self._uses_grader(): stub_filename = self.STUB_BASENAME + source_ext if not check_manager_present(job, stub_filename): return source_filenames.append(stub_filename) files_to_get[stub_filename] = job.managers[stub_filename].digest # User's submitted file(s) (copy and add to compilation). for codename, file_ in iteritems(job.files): source_filename = codename.replace(".%l", source_ext) source_filenames.append(source_filename) files_to_get[source_filename] = file_.digest # Any other useful manager (just copy). for filename, manager in iteritems(job.managers): if is_manager_for_compilation(filename, language): files_to_get[filename] = manager.digest # Prepare the compilation command executable_filename = self._executable_filename(iterkeys(job.files)) commands = language.get_compilation_commands( source_filenames, executable_filename) # Create the sandbox. sandbox = create_sandbox(file_cacher, name="compile") job.sandboxes.append(sandbox.get_root_path()) # Copy all required files in the sandbox. for filename, digest in iteritems(files_to_get): sandbox.create_file_from_storage(filename, digest) # Run the compilation. box_success, compilation_success, text, stats = \ compilation_step(sandbox, commands) # Retrieve the compiled executables. job.success = box_success job.compilation_success = compilation_success job.text = text job.plus = stats if box_success and compilation_success: digest = sandbox.get_file_to_storage( executable_filename, "Executable %s for %s" % (executable_filename, job.info)) job.executables[executable_filename] = \ Executable(executable_filename, digest) # Cleanup. delete_sandbox(sandbox, job.success)
def compile(self, job, file_cacher): """See TaskType.compile.""" language = get_language(job.language) source_ext = language.source_extension if not check_files_number(job, 1, or_more=True): return # Prepare the files to copy in the sandbox and to add to the # compilation command. files_to_get = {} source_filenames = [] # The stub, that must have been provided (copy and add to compilation). stub_filename = self.STUB_BASENAME + source_ext if not check_manager_present(job, stub_filename): return source_filenames.append(stub_filename) files_to_get[stub_filename] = job.managers[stub_filename].digest # User's submitted file(s) (copy and add to compilation). for codename, file_ in iteritems(job.files): source_filename = codename.replace(".%l", source_ext) source_filenames.append(source_filename) files_to_get[source_filename] = file_.digest # Any other useful manager (just copy). for filename, manager in iteritems(job.managers): if is_manager_for_compilation(filename, language): files_to_get[filename] = manager.digest # Prepare the compilation command executable_filename = self._executable_filename(iterkeys(job.files)) commands = language.get_compilation_commands( source_filenames, executable_filename) # Create the sandbox. sandbox = create_sandbox(file_cacher, name="compile") job.sandboxes.append(sandbox.get_root_path()) # Copy all required files in the sandbox. for filename, digest in iteritems(files_to_get): sandbox.create_file_from_storage(filename, digest) # Run the compilation. box_success, compilation_success, text, stats = \ compilation_step(sandbox, commands) # Retrieve the compiled executables. job.success = box_success job.compilation_success = compilation_success job.text = text job.plus = stats if box_success and compilation_success: digest = sandbox.get_file_to_storage( executable_filename, "Executable %s for %s" % (executable_filename, job.info)) job.executables[executable_filename] = \ Executable(executable_filename, digest) # Cleanup. delete_sandbox(sandbox, job.success)
def compile(self, job, file_cacher): """See TaskType.compile.""" language = get_language(job.language) source_ext = language.source_extension if not check_files_number(job, 1): return user_file_format = next(iterkeys(job.files)) user_source_filename = user_file_format.replace(".%l", source_ext) executable_filename = user_file_format.replace(".%l", "") # Create the list of filenames to be passed to the compiler. If we use # a grader, it needs to be in first position in the command line, and # we check that it exists. source_filenames = [user_source_filename] if self._uses_grader(): grader_source_filename = Batch.GRADER_BASENAME + source_ext if not check_manager_present(job, grader_source_filename): return source_filenames.insert(0, grader_source_filename) # Prepare the compilation command. commands = language.get_compilation_commands(source_filenames, executable_filename) # Create the sandbox. sandbox = create_sandbox(file_cacher, name="compile") job.sandboxes.append(sandbox.path) # Copy required files in the sandbox (includes the grader if present). sandbox.create_file_from_storage(user_source_filename, job.files[user_file_format].digest) for filename, manager in iteritems(job.managers): if is_manager_for_compilation(filename, language): sandbox.create_file_from_storage(filename, manager.digest) # Run the compilation. box_success, compilation_success, text, stats = \ compilation_step(sandbox, commands) # Retrieve the compiled executables. job.success = box_success job.compilation_success = compilation_success job.text = text job.plus = stats if box_success and compilation_success: digest = sandbox.get_file_to_storage( executable_filename, "Executable %s for %s" % (executable_filename, job.info)) job.executables[executable_filename] = \ Executable(executable_filename, digest) # Cleanup. delete_sandbox(sandbox, job.success)
def compile(self, job, file_cacher): """See TaskType.compile.""" language = get_language(job.language) source_ext = language.source_extension if not check_files_number(job, 1, or_more=True): return executable_filename = self._executable_filename(iterkeys(job.files)) # Create the list of filenames to be passed to the compiler. If we use # a grader, it needs to be in first position in the command line, and # we check that it exists. source_filenames = [codename.replace(".%l", source_ext) for codename in iterkeys(job.files)] if self._uses_grader(): grader_source_filename = self.GRADER_BASENAME + source_ext if not check_manager_present(job, grader_source_filename): return source_filenames.insert(0, grader_source_filename) # Prepare the compilation command. commands = language.get_compilation_commands( source_filenames, executable_filename) # Create the sandbox. sandbox = create_sandbox(file_cacher, name="compile") job.sandboxes.append(sandbox.get_root_path()) # Copy required files in the sandbox (includes the grader if present). for codename, file_ in iteritems(job.files): filename = codename.replace(".%l", source_ext) sandbox.create_file_from_storage(filename, file_.digest) for filename, manager in iteritems(job.managers): if is_manager_for_compilation(filename, language): sandbox.create_file_from_storage(filename, manager.digest) # Run the compilation. box_success, compilation_success, text, stats = \ compilation_step(sandbox, commands) # Retrieve the compiled executables. job.success = box_success job.compilation_success = compilation_success job.text = text job.plus = stats if box_success and compilation_success: digest = sandbox.get_file_to_storage( executable_filename, "Executable %s for %s" % (executable_filename, job.info)) job.executables[executable_filename] = \ Executable(executable_filename, digest) # Cleanup. delete_sandbox(sandbox, job.success)
def test_single_command_sandbox_failed(self): with patch("cms.grading.steps.compilation.generic_step", return_value=None): success, compilation_success, text, stats = compilation_step( self.sandbox, ONE_COMMAND) # Sandbox should never fail. If it does, should notify the admin. self.assertLoggedError() self.assertFalse(success) self.assertIsNone(compilation_success) self.assertIsNone(text) self.assertIsNone(stats)
def test_single_command_sandbox_failed(self): with patch("cms.grading.steps.compilation.generic_step", return_value=None): success, compilation_success, text, stats = compilation_step( self.sandbox, ONE_COMMAND) # Sandbox should never fail. If it does, should notify the admin. self.assertLoggedError() self.assertFalse(success) self.assertIsNone(compilation_success) self.assertIsNone(text) self.assertIsNone(stats)
def test_single_command_success(self): expected_stats = get_stats( 0.1, 0.5, 1000 * 1024, Sandbox.EXIT_OK, stdout="o", stderr="你好") with patch("cms.grading.steps.compilation.generic_step", return_value=expected_stats) as mock_generic_step: success, compilation_success, text, stats = compilation_step( self.sandbox, ONE_COMMAND) mock_generic_step.assert_called_once_with( self.sandbox, ONE_COMMAND, "compilation", collect_output=True) self.assertLoggedError(False) self.assertTrue(success) self.assertTrue(compilation_success) self.assertEqual(text, [COMPILATION_MESSAGES.get("success").message]) self.assertEqual(stats, expected_stats)
def test_single_command_success(self): expected_stats = get_stats( 0.1, 0.5, 1000 * 1024, Sandbox.EXIT_OK, stdout="o", stderr="你好") with patch("cms.grading.steps.compilation.generic_step", return_value=expected_stats) as mock_generic_step: success, compilation_success, text, stats = compilation_step( self.sandbox, ONE_COMMAND) mock_generic_step.assert_called_once_with( self.sandbox, ONE_COMMAND, "compilation", collect_output=True) self.assertLoggedError(False) self.assertTrue(success) self.assertTrue(compilation_success) self.assertEqual(text, [COMPILATION_MESSAGES.get("success").message]) self.assertEqual(stats, expected_stats)
def test_single_command_compilation_failed_timeout(self): # This case is a "success" for the sandbox (it's the user's fault), # but compilation is unsuccessful (no executable). expected_stats = get_stats( 0.1, 0.5, 1000 * 1024, Sandbox.EXIT_TIMEOUT, stdout="o", stderr="e") with patch("cms.grading.steps.compilation.generic_step", return_value=expected_stats): success, compilation_success, text, stats = compilation_step( self.sandbox, ONE_COMMAND) # User's fault, no error needs to be logged. self.assertLoggedError(False) self.assertTrue(success) self.assertFalse(compilation_success) self.assertEqual(text, [COMPILATION_MESSAGES.get("timeout").message]) self.assertEqual(stats, expected_stats)
def test_single_command_compilation_failed_timeout(self): # This case is a "success" for the sandbox (it's the user's fault), # but compilation is unsuccessful (no executable). expected_stats = get_stats( 0.1, 0.5, 1000 * 1024, Sandbox.EXIT_TIMEOUT, stdout="o", stderr="e") with patch("cms.grading.steps.compilation.generic_step", return_value=expected_stats): success, compilation_success, text, stats = compilation_step( self.sandbox, ONE_COMMAND) # User's fault, no error needs to be logged. self.assertLoggedError(False) self.assertTrue(success) self.assertFalse(compilation_success) self.assertEqual(text, [COMPILATION_MESSAGES.get("timeout").message]) self.assertEqual(stats, expected_stats)
def compile(self, job, file_cacher): """See TaskType.compile.""" language = get_language(job.language) source_ext = language.source_extension header_ext = language.header_extension if not check_files_number(job, 2): return files_to_get = {} source_filenames = [] # Manager. manager_filename = "manager%s" % source_ext if not check_manager_present(job, manager_filename): return source_filenames.append(manager_filename) files_to_get[manager_filename] = \ job.managers[manager_filename].digest # Manager's header. if header_ext is not None: manager_filename = "manager%s" % header_ext if not check_manager_present(job, manager_filename): return source_filenames.append(manager_filename) files_to_get[manager_filename] = \ job.managers[manager_filename].digest # User's submissions and headers. for filename, file_ in job.files.items(): source_filename = filename.replace(".%l", source_ext) source_filenames.append(source_filename) files_to_get[source_filename] = file_.digest # Headers (fixing compile error again here). if header_ext is not None: header_filename = filename.replace(".%l", header_ext) if not check_manager_present(job, header_filename): return source_filenames.append(header_filename) files_to_get[header_filename] = \ job.managers[header_filename].digest # Get compilation command. executable_filename = "manager" commands = language.get_compilation_commands(source_filenames, executable_filename) # Create the sandbox and put the required files in it. sandbox = create_sandbox(file_cacher, name="compile") job.sandboxes.append(sandbox.get_root_path()) for filename, digest in files_to_get.items(): sandbox.create_file_from_storage(filename, digest) # Run the compilation. box_success, compilation_success, text, stats = \ compilation_step(sandbox, commands) # Retrieve the compiled executables job.success = box_success job.compilation_success = compilation_success job.text = text job.plus = stats if box_success and compilation_success: digest = sandbox.get_file_to_storage( executable_filename, "Executable %s for %s" % (executable_filename, job.info)) job.executables[executable_filename] = \ Executable(executable_filename, digest) # Cleanup delete_sandbox(sandbox, job.success, job.keep_sandbox)
def compile(self, job, file_cacher): """See TaskType.compile.""" language = get_language(job.language) source_ext = language.source_extension header_ext = language.header_extension if not check_files_number(job, 2): return files_to_get = {} source_filenames = [] # Manager. manager_filename = "manager%s" % source_ext if not check_manager_present(job, manager_filename): return source_filenames.append(manager_filename) files_to_get[manager_filename] = \ job.managers[manager_filename].digest # Manager's header. if header_ext is not None: manager_filename = "manager%s" % header_ext if not check_manager_present(job, manager_filename): return source_filenames.append(manager_filename) files_to_get[manager_filename] = \ job.managers[manager_filename].digest # User's submissions and headers. for filename, file_ in iteritems(job.files): source_filename = filename.replace(".%l", source_ext) source_filenames.append(source_filename) files_to_get[source_filename] = file_.digest # Headers (fixing compile error again here). if header_ext is not None: header_filename = filename.replace(".%l", header_ext) if not check_manager_present(job, header_filename): return source_filenames.append(header_filename) files_to_get[header_filename] = \ job.managers[header_filename].digest # Get compilation command. executable_filename = "manager" commands = language.get_compilation_commands( source_filenames, executable_filename) # Create the sandbox and put the required files in it. sandbox = create_sandbox(file_cacher, name="compile") job.sandboxes.append(sandbox.get_root_path()) for filename, digest in iteritems(files_to_get): sandbox.create_file_from_storage(filename, digest) # Run the compilation. box_success, compilation_success, text, stats = \ compilation_step(sandbox, commands) # Retrieve the compiled executables job.success = box_success job.compilation_success = compilation_success job.text = text job.plus = stats if box_success and compilation_success: digest = sandbox.get_file_to_storage( executable_filename, "Executable %s for %s" % (executable_filename, job.info)) job.executables[executable_filename] = \ Executable(executable_filename, digest) # Cleanup delete_sandbox(sandbox, job.success)
def compile(self, job, file_cacher): """See TaskType.compile.""" language = get_language(job.language) source_ext = language.source_extension if not check_files_number(job, 1, or_more=True): return # Create the list of filenames to be passed to the compiler. If we use # a grader, it needs to be in first position in the command line, and # we check that it exists. filenames_to_compile = [] filenames_and_digests_to_get = {} # The grader, that must have been provided (copy and add to # compilation). if self._uses_grader(): grader_filename = self.GRADER_BASENAME + source_ext if not check_manager_present(job, grader_filename): return filenames_to_compile.append(grader_filename) filenames_and_digests_to_get[grader_filename] = \ job.managers[grader_filename].digest # User's submitted file(s) (copy and add to compilation). for codename, file_ in job.files.items(): filename = codename.replace(".%l", source_ext) filenames_to_compile.append(filename) filenames_and_digests_to_get[filename] = file_.digest # Any other useful manager (just copy). for filename, manager in job.managers.items(): if is_manager_for_compilation(filename, language): filenames_and_digests_to_get[filename] = manager.digest # Prepare the compilation command. executable_filename = self._executable_filename(job.files.keys()) commands = language.get_compilation_commands(filenames_to_compile, executable_filename) # Create the sandbox. sandbox = create_sandbox(file_cacher, name="compile") job.sandboxes.append(sandbox.get_root_path()) # Copy required files in the sandbox (includes the grader if present). for filename, digest in filenames_and_digests_to_get.items(): sandbox.create_file_from_storage(filename, digest) # Run the compilation. box_success, compilation_success, text, stats = \ compilation_step(sandbox, commands) # Retrieve the compiled executables. job.success = box_success job.compilation_success = compilation_success job.text = text job.plus = stats if box_success and compilation_success: digest = sandbox.get_file_to_storage( executable_filename, "Executable %s for %s" % (executable_filename, job.info)) job.executables[executable_filename] = \ Executable(executable_filename, digest) # Cleanup. delete_sandbox(sandbox, job.success, job.keep_sandbox)
def compile(self, job, file_cacher): """See TaskType.compile.""" language = get_language(job.language) source_ext = language.source_extension if not check_files_number(job, 1, or_more=True): return # Create the list of filenames to be passed to the compiler. If we use # a grader, it needs to be in first position in the command line, and # we check that it exists. filenames_to_compile = [] filenames_and_digests_to_get = {} # The grader, that must have been provided (copy and add to # compilation). if self._uses_grader(): grader_filename = self.GRADER_BASENAME + source_ext if not check_manager_present(job, grader_filename): return filenames_to_compile.append(grader_filename) filenames_and_digests_to_get[grader_filename] = \ job.managers[grader_filename].digest # User's submitted file(s) (copy and add to compilation). for codename, file_ in job.files.items(): filename = codename.replace(".%l", source_ext) filenames_to_compile.append(filename) filenames_and_digests_to_get[filename] = file_.digest # Any other useful manager (just copy). for filename, manager in job.managers.items(): if is_manager_for_compilation(filename, language): filenames_and_digests_to_get[filename] = manager.digest # Prepare the compilation command. executable_filename = self._executable_filename(job.files.keys()) commands = language.get_compilation_commands( filenames_to_compile, executable_filename) # Create the sandbox. sandbox = create_sandbox(file_cacher, name="compile") job.sandboxes.append(sandbox.get_root_path()) # Copy required files in the sandbox (includes the grader if present). for filename, digest in filenames_and_digests_to_get.items(): sandbox.create_file_from_storage(filename, digest) # Run the compilation. box_success, compilation_success, text, stats = \ compilation_step(sandbox, commands) # Retrieve the compiled executables. job.success = box_success job.compilation_success = compilation_success job.text = text job.plus = stats if box_success and compilation_success: digest = sandbox.get_file_to_storage( executable_filename, "Executable %s for %s" % (executable_filename, job.info)) job.executables[executable_filename] = \ Executable(executable_filename, digest) # Cleanup. delete_sandbox(sandbox, job.success, job.keep_sandbox)