def test_get_interacting_commits_for_commit(self) -> None: """Test if retrieving of interacting commits works.""" report = self.reports[1] # YAML_DOC_BR_6 commit = CommitRepoPair( FullCommitHash("e64923e69eab82332c1bed7fe1e80e14c2c5cb7f"), "Elementalist") expected_in = { CommitRepoPair( FullCommitHash("5e030723d70f4894c21881e32dba4decec815c7e"), "Elementalist"), CommitRepoPair( FullCommitHash("bd693d7bc2e4ae5be93e300506ba1efea149e5b7"), "Elementalist") } expected_out = { CommitRepoPair( FullCommitHash("5e030723d70f4894c21881e32dba4decec815c7e"), "Elementalist"), CommitRepoPair( FullCommitHash("97c573ee98a1c2143b6876433697e363c9eca98b"), "Elementalist") } actual_in, actual_out = get_interacting_commits_for_commit( report, commit) self.assertSetEqual(expected_in, actual_in) self.assertSetEqual(expected_out, actual_out)
def test_equal_repo(self): """Tests that two different commits are not equal.""" cr_pair_1 = CommitRepoPair( FullCommitHash("4200000000000000000000000000000000000000"), "bar_repo") cr_pair_2 = CommitRepoPair( FullCommitHash("4200000000000000000000000000000000000000"), "foo_repo") self.assertFalse(cr_pair_1 == cr_pair_2)
def test_less_repo(self): """Tests that a smaller repo is less, if the commits are equal.""" cr_pair_1 = CommitRepoPair( FullCommitHash("4200000000000000000000000000000000000000"), "foo_repo") cr_pair_2 = CommitRepoPair( FullCommitHash("4200000000000000000000000000000000000000"), "boo_repo") self.assertFalse(cr_pair_1 < cr_pair_2)
def test_equal_equal(self): """Tests that two equal pairs are equal.""" cr_pair_1 = CommitRepoPair( FullCommitHash("4200000000000000000000000000000000000000"), "foo_repo") cr_pair_2 = CommitRepoPair( FullCommitHash("4200000000000000000000000000000000000000"), "foo_repo") self.assertTrue(cr_pair_1 == cr_pair_2)
def test_less_equal(self): """Tests that two equal pairs are not less.""" cr_pair_1 = CommitRepoPair( FullCommitHash("4200000000000000000000000000000000000000"), "foo_repo") cr_pair_2 = CommitRepoPair( FullCommitHash("4200000000000000000000000000000000000000"), "foo_repo") self.assertFalse(cr_pair_1 < cr_pair_2)
def test_less_commit(self): """Tests that a smaller commit is less.""" cr_pair_1 = CommitRepoPair( FullCommitHash("4100000000000000000000000000000000000000"), "foo_repo") cr_pair_2 = CommitRepoPair( FullCommitHash("4200000000000000000000000000000000000000"), "foo_repo") self.assertTrue(cr_pair_1 < cr_pair_2)
def test_calculate_szz_quality_score_weighting(self) -> None: """Test SZZ quality score calculation.""" commit_a = CommitRepoPair("A", "foo") commit_b = CommitRepoPair("B", "foo") commit_c = CommitRepoPair("C", "foo") commit_d = CommitRepoPair("D", "foo") fix_in = {commit_a, commit_b} fix_out = {commit_c} intro_in = {commit_a, commit_b, commit_d} intro_out = {commit_c} self.assertEqual( 0.75, _calculate_szz_quality_score(fix_in, fix_out, intro_in, intro_out) )
def test_calculate_szz_quality_score_perfect_match(self) -> None: """Test SZZ quality score calculation.""" commit_a = CommitRepoPair("A", "foo") commit_b = CommitRepoPair("B", "foo") commit_c = CommitRepoPair("C", "foo") commit_d = CommitRepoPair("D", "foo") fix_in = {commit_a, commit_b} fix_out = {commit_c, commit_d} intro_in = {commit_a, commit_b} intro_out = {commit_c, commit_d} self.assertEqual( 1, _calculate_szz_quality_score(fix_in, fix_out, intro_in, intro_out) )
def revisions_of_project(self) -> None: """Generate the Revision list for the selected project if select specific is enabled.""" self.strategie_forms.setCurrentIndex( GenerationStrategie.SELECT_REVISION.value) if self.selected_project != self.revision_list_project: self.revision_details.setText("Loading Revisions") self.revision_details.repaint() get_local_project_git(self.selected_project).remotes[0].fetch() git_path = get_local_project_git_path(self.selected_project) initial_commit = get_initial_commit(git_path).hash commits = get_all_revisions_between(initial_commit, 'HEAD', FullCommitHash, git_path) commit_lookup_helper = create_commit_lookup_helper( self.selected_project) project = get_project_cls_by_name(self.selected_project) repo_name = get_primary_project_source(self.selected_project).local commits = map(lambda commit: CommitRepoPair(commit, repo_name), commits) cmap = get_commit_map(self.selected_project) commit_model = CommitTableModel( list(map(commit_lookup_helper, commits)), cmap, project) self.proxy_model.setSourceModel(commit_model) self.revision_list_project = self.selected_project self.revision_details.clear() self.revision_details.update()
def create_taint_data( raw_taint_data: tp.Dict[str, tp.Any]) -> 'BlameTaintData': """Create a :class:`BlameTaintData` instance from from the corresponding yaml document section.""" commit = CommitRepoPair(FullCommitHash(raw_taint_data["commit"]), raw_taint_data["repository"]) return BlameTaintData(commit, raw_taint_data.get("region"), raw_taint_data.get("function"))
def create_data_frame_for_report( report_paths: tp.Tuple[Path, Path] ) -> tp.Tuple[pd.DataFrame, str, str]: # Look-up commit and infos about the HEAD commit of the report fix_report = load_blame_report(report_paths[0]) intro_report = load_blame_report(report_paths[1]) fix_commit = commit_lookup( CommitRepoPair( commit_map.convert_to_full_or_warn(fix_report.head_commit), prj_src.local ) ) intro_commit = commit_lookup( CommitRepoPair( commit_map.convert_to_full_or_warn(intro_report.head_commit), prj_src.local ) ) fix_in, fix_out = get_interacting_commits_for_commit( fix_report, CommitRepoPair( FullCommitHash.from_pygit_commit(fix_commit), prj_src.local ) ) intro_in, intro_out = get_interacting_commits_for_commit( intro_report, CommitRepoPair( FullCommitHash.from_pygit_commit(intro_commit), prj_src.local ) ) score = _calculate_szz_quality_score( fix_in, fix_out, intro_in, intro_out ) return ( pd.DataFrame({ 'revision': str(fix_report.head_commit), 'time_id': commit_map.short_time_id(fix_report.head_commit), 'introducer': str(intro_report.head_commit), 'score': score }, index=[0]), id_from_paths(report_paths), timestamp_from_paths(report_paths) )
def create_taint_data( raw_data: tp.Union[str, tp.Dict[str, tp.Any]]) -> BlameTaintData: # be backwards compatible with blame report version 4 if isinstance(raw_data, str): commit_hash, *repo = raw_data.split('-', maxsplit=1) crp = CommitRepoPair(FullCommitHash(commit_hash), repo[0] if repo else "Unknown") return BlameTaintData(crp) return BlameTaintData.create_taint_data(raw_data)
def create_graph() -> nx.DiGraph: repos = get_local_project_gits(self.project_name) interaction_graph = nx.DiGraph() churn_config = ChurnConfig.create_c_style_languages_config() file_pattern = re.compile(r"|".join( churn_config.get_extensions_repr(prefix=r"\.", suffix=r"$"))) blame_regex = re.compile( r"^([0-9a-f]+)\s+(?:.+\s+)?[\d]+\) ?(.*)$") for repo_name in repos: repo_path = get_local_project_git_path(self.project_name, repo_name) project_git = git["-C", str(repo_path)] head_commit = get_submodule_head(self.project_name, repo_name, self.__head_commit) file_names = project_git("ls-tree", "--full-tree", "--name-only", "-r", head_commit).split("\n") files: tp.List[Path] = [ repo_path / path for path in file_names if file_pattern.search(path) ] for file in files: nodes: tp.Set[BIGNodeTy] = set() blame_lines: str = project_git( "blame", "-w", "-s", "-l", "--root", head_commit, "--", str(file.relative_to(repo_path))) for line in blame_lines.strip().split("\n"): match = blame_regex.match(line) if not match: raise AssertionError if match.group(2): nodes.add( BlameTaintData( CommitRepoPair( FullCommitHash(match.group(1)), repo_name))) for node in nodes: interaction_graph.add_node(node, blame_taint_data=node) for commit_a, commit_b in itertools.product(nodes, repeat=2): if commit_a != commit_b: if not interaction_graph.has_edge( commit_a, commit_b): interaction_graph.add_edge(commit_a, commit_b, amount=0) interaction_graph[commit_a][commit_b][ "amount"] += 1 return interaction_graph
def test_calculate_szz_quality_score_partial_match(self) -> None: """Test SZZ quality score calculation.""" commit_a = CommitRepoPair("A", "foo") commit_b = CommitRepoPair("B", "foo") commit_c = CommitRepoPair("C", "foo") commit_d = CommitRepoPair("D", "foo") commit_e = CommitRepoPair("E", "foo") commit_f = CommitRepoPair("F", "foo") fix_in = {commit_a, commit_b, commit_e} fix_out = {commit_c, commit_d} intro_in = {commit_a, commit_b, commit_f} intro_out = {commit_c, commit_d, commit_e, commit_f} self.assertEqual( 0.5, _calculate_szz_quality_score(fix_in, fix_out, intro_in, intro_out) )
def test_gen_base_to_inter_commit_repo_pair_mapping(self) -> None: """Test if the mapping of base hash to interacting hashes works.""" base_inter_mapping = gen_base_to_inter_commit_repo_pair_mapping( self.reports[1]) elem_e6 = BlameTaintData( CommitRepoPair( FullCommitHash("e64923e69eab82332c1bed7fe1e80e14c2c5cb7f"), "Elementalist")) elem_5e = BlameTaintData( CommitRepoPair( FullCommitHash("5e030723d70f4894c21881e32dba4decec815c7e"), "Elementalist")) elem_97 = BlameTaintData( CommitRepoPair( FullCommitHash("97c573ee98a1c2143b6876433697e363c9eca98b"), "Elementalist")) elem_bd = BlameTaintData( CommitRepoPair( FullCommitHash("bd693d7bc2e4ae5be93e300506ba1efea149e5b7"), "Elementalist")) water_58 = BlameTaintData( CommitRepoPair( FullCommitHash("58ec513bd231f384038d9612ffdfb14affa6263f"), "water_lib")) fire_ea = BlameTaintData( CommitRepoPair( FullCommitHash("ead5e00960478e1d270aea5f373aece97b4b7e74"), "fire_lib")) self.assertEqual(base_inter_mapping[elem_e6][elem_5e], 1) self.assertEqual(base_inter_mapping[elem_e6][elem_97], 1) self.assertEqual(base_inter_mapping[elem_5e][elem_97], 32) self.assertEqual(base_inter_mapping[elem_5e][elem_e6], 32) self.assertEqual(base_inter_mapping[elem_5e][elem_bd], 31) self.assertEqual(base_inter_mapping[elem_5e][water_58], 5) self.assertEqual(base_inter_mapping[elem_5e][fire_ea], 5) self.assertEqual(base_inter_mapping[elem_bd][elem_5e], 1) self.assertEqual(base_inter_mapping[elem_bd][elem_97], 1) self.assertEqual(base_inter_mapping[elem_bd][elem_e6], 1)
def setUpClass(cls): cls.cr_pair = CommitRepoPair( FullCommitHash("4200000000000000000000000000000000000000"), "foo_repo")