count different categories of total mutants

pull/2302/head
bohendo 10 months ago
parent 007789ff92
commit 3c468b6eaf
No known key found for this signature in database
  1. 72
      slither/tools/mutator/mutators/abstract_mutator.py

@ -23,6 +23,10 @@ class AbstractMutator(
VALID_MUTANTS_COUNT = 0 VALID_MUTANTS_COUNT = 0
VALID_RR_MUTANTS_COUNT = 0 VALID_RR_MUTANTS_COUNT = 0
VALID_CR_MUTANTS_COUNT = 0 VALID_CR_MUTANTS_COUNT = 0
# total revert/comment/tweak mutants that were generated and compiled
total_mutant_counts = [0, 0, 0]
# total valid revert/comment/tweak mutants
valid_mutant_counts = [0, 0, 0]
def __init__( # pylint: disable=too-many-arguments def __init__( # pylint: disable=too-many-arguments
self, self,
@ -73,12 +77,12 @@ class AbstractMutator(
"""TODO Documentation""" """TODO Documentation"""
return {} return {}
def mutate(self) -> Tuple[int, int, int, int, List[int]]: def mutate(self) -> Tuple[List[int], List[int], List[int]]:
# call _mutate function from different mutators # call _mutate function from different mutators
(all_patches) = self._mutate() (all_patches) = self._mutate()
if "patches" not in all_patches: if "patches" not in all_patches:
logger.debug("No patches found by %s", self.NAME) logger.debug("No patches found by %s", self.NAME)
return (0, 0, self.dont_mutate_line) return ([0,0,0], [0,0,0], self.dont_mutate_line)
for file in all_patches["patches"]: for file in all_patches["patches"]:
original_txt = self.slither.source_code[file].encode("utf8") original_txt = self.slither.source_code[file].encode("utf8")
@ -87,7 +91,8 @@ class AbstractMutator(
logger.info(yellow(f"Mutating {file} with {self.NAME} \n")) logger.info(yellow(f"Mutating {file} with {self.NAME} \n"))
for patch in patches: for patch in patches:
# test the patch # test the patch
flag = test_patch(
patchIsValid = test_patch(
file, file,
patch, patch,
self.test_command, self.test_command,
@ -97,36 +102,41 @@ class AbstractMutator(
self.solc_remappings, self.solc_remappings,
self.verbose, self.verbose,
) )
# if RR or CR and valid mutant, add line no.
if self.NAME in ("RR", "CR") and flag: # count the valid mutants, flag RR/CR mutants to skip further mutations
if patchIsValid == 0:
if self.NAME == 'RR': if self.NAME == 'RR':
self.VALID_RR_MUTANTS_COUNT += 1 self.valid_mutant_counts[0] += 1
if self.NAME == 'CR': self.dont_mutate_line.append(patch['line_number'])
self.VALID_CR_MUTANTS_COUNT += 1 elif self.NAME == 'CR':
logger.info(yellow("Severe mutant is valid, skipping further mutations")) self.valid_mutant_counts[1] += 1
self.dont_mutate_line.append(patch["line_number"]) self.dont_mutate_line.append(patch['line_number'])
else:
# count the valid and invalid mutants self.valid_mutant_counts[2] += 1
if not flag:
self.INVALID_MUTANTS_COUNT += 1 patched_txt,_ = apply_patch(original_txt, patch, 0)
continue diff = create_diff(self.compilation_unit, original_txt, patched_txt, file)
logger.info(yellow("Severe mutant is invalid, continuing further mutations")) if not diff:
self.VALID_MUTANTS_COUNT += 1 logger.info(f"Impossible to generate patch; empty {patches}")
patched_txt, _ = apply_patch(original_txt, patch, 0)
diff = create_diff(self.compilation_unit, original_txt, patched_txt, file) # add valid mutant patches to a output file
if not diff: with open(
logger.info(f"Impossible to generate patch; empty {patches}") self.output_folder + "/patches_file.txt", "a", encoding="utf8"
) as patches_file:
# add valid mutant patches to a output file patches_file.write(diff + "\n")
with open(
self.output_folder + "/patches_file.txt", "a", encoding="utf8" # count the total number of mutants that we were able to compile
) as patches_file: if patchIsValid != 2:
patches_file.write(diff + "\n") if self.NAME == 'RR':
self.total_mutant_counts[0] += 1
elif self.NAME == 'CR':
self.total_mutant_counts[1] += 1
else:
self.total_mutant_counts[2] += 1
# logger.info(yellow(f"{self.VALID_MUTANTS_COUNT} valid mutants, {self.INVALID_MUTANTS_COUNT} invalid mutants")) # logger.info(yellow(f"{self.VALID_MUTANTS_COUNT} valid mutants, {self.INVALID_MUTANTS_COUNT} invalid mutants"))
return ( return (
self.INVALID_MUTANTS_COUNT, self.total_mutant_counts,
self.VALID_MUTANTS_COUNT, self.valid_mutant_counts,
self.VALID_RR_MUTANTS_COUNT,
self.VALID_CR_MUTANTS_COUNT,
self.dont_mutate_line self.dont_mutate_line
) )

Loading…
Cancel
Save