def check_task(self, task: TASK, in_and_out_files_dict: FilesDict, source_file: str, stop_after_first_false=True) -> float: log.info(f'Start checking task {task.value}') in_and_out_files = in_and_out_files_dict.get(task) if not in_and_out_files: log_and_raise_error( f'Task data for the {task.value} does not exist', log) counted_tests, passed_tests = len(in_and_out_files), 0 for in_file, out_file in in_and_out_files: is_passed = self.run_test(get_content_from_file(in_file), get_content_from_file(out_file), source_file) log.info( f'Test {in_file} for task {task.value} is passed: {str(is_passed)}' ) if is_passed: passed_tests += 1 elif stop_after_first_false: # keep existing rate, even if it's not 0, to save the information about partly passed tests log.info('Stop after first false') break rate = passed_tests / counted_tests log.info(f'Finish checking task {task.value}, rate: {str(rate)}') return rate
def apply_diffs(src_file: str, dst_file: Optional[str] = None) -> str: if not dst_file: dst_file = re.sub(r'in(?=[^in]*$)', 'out', src_file) src_diff_handler = RiversDiffHandler(get_content_from_file(src_file)) dst_diff_handler = RiversDiffHandler(get_content_from_file(dst_file)) diffs, tree_type = src_diff_handler.get_diffs_from_diff_handler( dst_diff_handler) res_tree = src_diff_handler.apply_diffs(diffs, tree_type) return get_code_from_tree(res_tree).rstrip('\n')
def __get_sources_and_goals(task: TASK, test_type: TEST_TYPE = TEST_TYPE.DIFF) -> Tuple[List[str], List[str]]: root = os.path.join(BASE_DATA_PATH, test_type.value, task.value) sources_paths = get_all_file_system_items(root, match_condition(r'source_\d+.py')) sources_paths.sort() goals_paths = get_all_file_system_items(root, match_condition(r'goal_\d+.py')) goals_paths.sort() sources = [get_content_from_file(f) for f in sources_paths] goals = [get_content_from_file(f) for f in goals_paths] return sources, goals
def __get_chains(task: TASK) -> List[Tuple[List[str], str]]: root = os.path.join(BASE_DATA_PATH, task.value) chains = get_all_file_system_items(root, match_condition(r'chain_\d+'), item_type=FILE_SYSTEM_ITEM.SUBDIR) # We have to know ids for vertexes chains.sort() res_chains = [] for chain in chains: sources_paths = get_all_file_system_items(chain, match_condition(r'source_\d+.py')) goals = get_all_file_system_items(chain, match_condition(r'goal.py')) if len(goals) != 1: log_and_raise_error(f'The chain {chain} contains more than 1 goal', log) sources_paths.sort() res_chains.append(([get_content_from_file(f) for f in sources_paths], get_content_from_file(goals[0]))) return res_chains
def __parse_file_with_statistics(self, file: str, max_number_of_fragments: int = 100) -> List[FragmentStatistics]: statistics = get_content_from_file(file, encoding=UTF_ENCODING) fragments = statistics.split(self.separator * 4) if len(fragments) < max_number_of_fragments: log_and_raise_error(f'Fragments number is {len(fragments)}, but max number of fragments is ' f'{max_number_of_fragments}', log) fragments = fragments[:max_number_of_fragments] return list(map(self.__get_statistics_from_fragment, fragments))
def anonymize_code_fragment(self, code_fragment: str): """ gorshochek works only with folders with cpp files. We create a folder with the code fragment and run gorshochek. Note: the default scripts/run.sh file in the gorshochek repository requires sudo access for docker running. We remove it for the anonymization process to avoid running sudo processes from an external process. After getting the result we delete the created folders. """ create_file(code_fragment, f'{self._input_dir}/{self._input_name}.cpp') p = subprocess.Popen( ['sh', f'./scripts/run.sh', self._data_name, self._out_name], cwd=self._local_gorshochek_path) p.wait() return get_content_from_file( f'{self._output_dir}/{self._input_name}/transformation_1.cpp')
def generate_file_for_evaluation( self, name_suffices: List[str], evaluation_fragment_file: str = EVALUATION_FRAGMENT_PATH) -> None: fragment = get_content_from_file(evaluation_fragment_file, to_strip_nl=False) fragments = [ f'{t_i[TEST_INPUT.INDEX]}.\n{fragment}' for t_i in self._test_inputs ] evaluation_content = ''.join(fragments) for name_suffix in name_suffices: evaluation_file = os.path.join( EVALUATION_PATH, f'{self._task.value}_evaluation_file_{name_suffix}{EXTENSION.TXT.value}' ) create_file(evaluation_content, evaluation_file)
def test_result_of_applying_diffs_to_students_code(self, task: TASK, subtests) -> None: in_and_out_files = get_in_and_out_files( DIFF_HANDLER_TEST_TYPES.STUDENTS_CODE, task) for i, (src_file, dst_file, out_file) in enumerate(in_and_out_files): test_info = f'Task {task.value}\nTest number {i}\nSrc file is: {src_file}\n' \ f'Dst file is: {dst_file}\n' log.info(test_info) with subtests.test(msg=f'Exception was raised\n{test_info}'): apply_diffs(src_file, dst_file) actual_out = apply_diffs(src_file, dst_file) expected_out = get_cleaned_code( get_content_from_file(out_file)).rstrip('\n') log.info( f'Actual code is:\n{actual_out}\nExpected code is:\n{expected_out}\n' ) assert expected_out == actual_out, test_info
def run_test(test_type: Union[CANONICALIZATION_TESTS_TYPES, DIFF_HANDLER_TEST_TYPES], get_code: Callable[[str], str], task: Optional[TASK] = None, additional_folder_name: str = '', to_clear_out: bool = False) -> None: files = get_test_in_and_out_files( test_type, task, additional_folder_name=additional_folder_name) count_tests = 1 for source_code, expected_code_path in files: log.info(f'Test number {count_tests}\nSource code is: {source_code}\n') actual_code = get_code(source_code) expected_code = get_content_from_file(expected_code_path) if to_clear_out: expected_code = get_cleaned_code(expected_code).rstrip('\n') log.info( f'Actual code is:\n{actual_code}\nExpected code is:\n{expected_code}\n' ) assert expected_code == actual_code count_tests += 1
def get_user_solutions(task: TASK) -> List[str]: root = os.path.join(BASE_DATA_PATH, task.value, 'user_solutions') solutions = get_all_file_system_items(root, match_condition(r'source_\d+.py')) # We have to know the order solutions.sort() return [get_content_from_file(f) for f in solutions]
def test_fragments(self, fragment_file: str) -> None: in_and_out_files_dict = create_in_and_out_dict(TASK.tasks()) language = get_language_by_extension(get_extension_from_file(fragment_file)) check_tasks(TASK.tasks(), get_content_from_file(fragment_file), in_and_out_files_dict, language, False)
def get_source_code(task: TASK, language: consts.LANGUAGE, solution: str) -> str: return get_content_from_file(os.path.join(TEST_DATA_PATH, "splitting/tasks_tests_handler", task.value, language.value, solution + ".txt"))
def get_expected_graph_representation(graph_type: GRAPH_TYPE) -> str: file_path = os.path.join(SOLUTION_SPACE_TEST_FOLDER, 'solution_space_visualizer', graph_type.value + EXTENSION.DOT.value) return get_content_from_file(file_path)
def get_canonicalized_code_from_file(file: str) -> str: canon_tree, = get_trees(get_content_from_file(file), {TREE_TYPE.CANON}) return get_code_from_tree(canon_tree).rstrip('\n')
def get_anonymized_code_from_file(file: str) -> str: anon_tree, = get_trees(get_content_from_file(file), {TREE_TYPE.ANON}, False) return get_code_from_tree(anon_tree).rstrip('\n')
def get_cleaned_code_from_file(file: str) -> str: source = get_content_from_file(file) return get_cleaned_code(source).rstrip('\n')