count valid RR ad CR mutants

pull/2302/head
bohendo 9 months ago
parent e3365a7f95
commit 007789ff92
No known key found for this signature in database
  1. 15
      slither/tools/mutator/__main__.py
  2. 20
      slither/tools/mutator/mutators/abstract_mutator.py
  3. 8
      slither/tools/mutator/utils/testing_generated_mutant.py

@ -196,7 +196,11 @@ def main() -> (None): # pylint: disable=too-many-statements,too-many-branches,t
# total count of mutants
total_count = 0
# count of valid mutants
v_count = 0
valid_count = 0
# count of valid revert mutants
RR_count = 0
# count of valid comment mutants
CR_count = 0
# lines those need not be mutated (taken from RR and CR)
dont_mutate_lines = []
@ -212,6 +216,7 @@ def main() -> (None): # pylint: disable=too-many-statements,too-many-branches,t
if contract_instance == "":
logger.error("Can't find the contract")
else:
logger.info(yellow(f"\nMutating contract {contract_instance}"))
for M in mutators_list:
m = M(
compilation_unit_of_main_file,
@ -224,8 +229,10 @@ def main() -> (None): # pylint: disable=too-many-statements,too-many-branches,t
output_folder,
dont_mutate_lines,
)
(count_valid, count_invalid, lines_list) = m.mutate()
v_count += count_valid
(count_invalid, count_valid, count_valid_rr, count_valid_cr, lines_list) = m.mutate()
valid_count += count_valid
RR_count += count_valid_rr
CR_count += count_valid_cr
total_count += count_valid + count_invalid
dont_mutate_lines = lines_list
if not quick_flag:
@ -244,7 +251,7 @@ def main() -> (None): # pylint: disable=too-many-statements,too-many-branches,t
# output
logger.info(
yellow(
f"Done mutating, '{filename}'. Valid mutant count: '{v_count}' and Total mutant count '{total_count}'.\n"
f"Done mutating, '{filename}'. Total mutants: {total_count}, Total Valid: '{valid_count}', Valid reverts: {RR_count}, Valid comments: {CR_count}.\n"
)
)

@ -19,8 +19,10 @@ class AbstractMutator(
): # pylint: disable=too-few-public-methods,too-many-instance-attributes
NAME = ""
HELP = ""
VALID_MUTANTS_COUNT = 0
INVALID_MUTANTS_COUNT = 0
VALID_MUTANTS_COUNT = 0
VALID_RR_MUTANTS_COUNT = 0
VALID_CR_MUTANTS_COUNT = 0
def __init__( # pylint: disable=too-many-arguments
self,
@ -71,7 +73,7 @@ class AbstractMutator(
"""TODO Documentation"""
return {}
def mutate(self) -> Tuple[int, int, List[int]]:
def mutate(self) -> Tuple[int, int, int, int, List[int]]:
# call _mutate function from different mutators
(all_patches) = self._mutate()
if "patches" not in all_patches:
@ -97,11 +99,18 @@ class AbstractMutator(
)
# if RR or CR and valid mutant, add line no.
if self.NAME in ("RR", "CR") and flag:
if self.NAME == 'RR':
self.VALID_RR_MUTANTS_COUNT += 1
if self.NAME == 'CR':
self.VALID_CR_MUTANTS_COUNT += 1
logger.info(yellow("Severe mutant is valid, skipping further mutations"))
self.dont_mutate_line.append(patch["line_number"])
# count the valid and invalid mutants
if not flag:
self.INVALID_MUTANTS_COUNT += 1
continue
logger.info(yellow("Severe mutant is invalid, continuing further mutations"))
self.VALID_MUTANTS_COUNT += 1
patched_txt, _ = apply_patch(original_txt, patch, 0)
diff = create_diff(self.compilation_unit, original_txt, patched_txt, file)
@ -113,8 +122,11 @@ class AbstractMutator(
self.output_folder + "/patches_file.txt", "a", encoding="utf8"
) as patches_file:
patches_file.write(diff + "\n")
# logger.info(yellow(f"{self.VALID_MUTANTS_COUNT} valid mutants, {self.INVALID_MUTANTS_COUNT} invalid mutants"))
return (
self.VALID_MUTANTS_COUNT,
self.INVALID_MUTANTS_COUNT,
self.dont_mutate_line,
self.VALID_MUTANTS_COUNT,
self.VALID_RR_MUTANTS_COUNT,
self.VALID_CR_MUTANTS_COUNT,
self.dont_mutate_line
)

@ -83,18 +83,18 @@ def test_patch( # pylint: disable=too-many-arguments
if compile_generated_mutant(file, mappings):
if run_test_cmd(command, file, timeout):
create_mutant_file(file, index, generator_name)
print(
logger.info(
green(
f"String '{patch['old_string']}' replaced with '{patch['new_string']}' at line no. '{patch['line_number']}' ---> VALID"
f"[{generator_name}] Line {patch['line_number']}: '{patch['old_string']}' ==> '{patch['new_string']}' --> VALID"
)
)
return True
reset_file(file)
if verbose:
print(
logger.info(
red(
f"String '{patch['old_string']}' replaced with '{patch['new_string']}' at line no. '{patch['line_number']}' ---> INVALID"
f"[{generator_name}] Line {patch['line_number']}: '{patch['old_string']}' ==> '{patch['new_string']}' --> INVALID"
)
)
return False

Loading…
Cancel
Save