diff --git a/fuzzer.py b/fuzzer.py index cc5b42f..e8c726a 100644 --- a/fuzzer.py +++ b/fuzzer.py @@ -198,14 +198,11 @@ def get_test_case_source(f_name: str, test_case: Params, i: int, indent: int): output = invoke(f_name, test_case) - if type(output) == str: - output = f"'{output}'" - return f"""{space}def test_{f_name_orig}_{i}(self): -{space}{single_indent}assert {call_statement(f_name_orig, test_case)} == {output}""" +{space}{single_indent}assert {call_statement(f_name_orig, test_case)} == {repr(output)}""" -def get_test_class(f_name: str, case: set[Params]) -> str: +def get_test_class(f_name: str, cases: set[Params]) -> str: f_name_orig = BranchTransformer.to_original_name(f_name) test_class = (f"from unittest import TestCase\n\nfrom {module_of[f_name]} import {f_name_orig}\n\n\n" diff --git a/genetic.py b/genetic.py index df62020..8977494 100644 --- a/genetic.py +++ b/genetic.py @@ -14,7 +14,7 @@ CXPROB = 0.5 TOURNSIZE = 3 NPOP = 300 NGEN = 200 -REPS = 10 +REPS = 1 to_test: str = "" @@ -40,14 +40,8 @@ def generate(f_name: str): toolbox = base.Toolbox() toolbox.register("attr_test_case", get_test_case_generator(to_test, instrument.functions[to_test])) - toolbox.register("individual", - tools.initIterate, - creator.Individual, - lambda: toolbox.attr_test_case()) - toolbox.register("population", - tools.initRepeat, - list, - toolbox.individual) + toolbox.register("individual", tools.initIterate, creator.Individual, lambda: toolbox.attr_test_case()) + toolbox.register("population", tools.initRepeat, list, toolbox.individual) toolbox.register("evaluate", compute_fitness) def mate(tc1, tc2): @@ -77,6 +71,8 @@ def generate(f_name: str): coverage.append(cov) print(coverage) + return set(list(instrument.archive_true_branches.values()) + + list(instrument.archive_false_branches.values())) def compute_fitness(individual: list) -> tuple[float]: @@ -87,12 +83,17 @@ def compute_fitness(individual: list) -> tuple[float]: instrument.distances_true = {} instrument.distances_false = {} + # the archive_true_branches and archive_false_branches are reset after + # each generation. This is intentional as they are used to archive branches that + # have already been covered, and their presence increases the fitness value of + # test cases that would re-cover them + # Run the function under test try: out = instrument.invoke(to_test, x) except AssertionError: - print(to_test, x, "=", "[FAILS] fitness = 10000") - return 10000, + print(to_test, x, "=", "[FAILS] fitness = 100.0") + return 100.0, fitness = 0.0 @@ -103,13 +104,14 @@ def compute_fitness(individual: list) -> tuple[float]: instrument.archive_true_branches[branch] = x if branch not in instrument.archive_true_branches: fitness += normalize(instrument.distances_true[branch]) - - for branch in range(range_start, range_end): - if branch in instrument.distances_false: + elif branch in instrument.distances_false: if instrument.distances_false[branch] == 0 and branch not in instrument.archive_false_branches: instrument.archive_false_branches[branch] = x if branch not in instrument.archive_false_branches: fitness += normalize(instrument.distances_false[branch]) + else: + fitness += 1.0 + print(to_test, x, "=", out, "fitness =", fitness) return fitness, @@ -117,9 +119,8 @@ def compute_fitness(individual: list) -> tuple[float]: def main(): instrument.load_benchmark(save_instrumented=False) # instrument all files in benchmark f_name = "railencrypt_instrumented" - generate(f_name) + cases = generate(f_name) with open(os.path.join(OUT_DIR, f_name + ".py"), "w") as f: - cases = get_test_cases(f_name, instrument.functions[f_name], 100) f.write(get_test_class(f_name, cases)) diff --git a/instrument.py b/instrument.py index 227b3d2..8dcff3b 100644 --- a/instrument.py +++ b/instrument.py @@ -211,10 +211,7 @@ def load_benchmark(save_instrumented=True): def call_statement(f_name: str, f_args: Params) -> str: arg_list: list[str] = [] for k, v in f_args.items(): - if type(v) == str: - arg_list.append(f"{k}='{v}'") # quote strings - else: - arg_list.append(f"{k}={v}") + arg_list.append(f"{k}={repr(v)}") # quote strings return f"{f_name}({', '.join(arg_list)})" diff --git a/tests/railencrypt_instrumented.py b/tests/railencrypt_instrumented.py index 6a16de6..dc1bdd1 100644 --- a/tests/railencrypt_instrumented.py +++ b/tests/railencrypt_instrumented.py @@ -5,301 +5,10 @@ from benchmark.railfence_cipher import railencrypt class Test_railencrypt(TestCase): def test_railencrypt_1(self): - assert railencrypt(st='FKglwgJ(p', k=840) == 'FKglwgJ(p' + assert railencrypt(st='6u#%', k=3) == '6u%#' def test_railencrypt_2(self): - assert railencrypt(st='gvj', k=379) == 'gvj' + assert railencrypt(st='6uD*z(', k=3) == '6zu*(D' def test_railencrypt_3(self): - assert railencrypt(st='', k=755) == '' - - def test_railencrypt_4(self): - assert railencrypt(st='9pS', k=577) == '9pS' - - def test_railencrypt_5(self): - assert railencrypt(st='`j4z_:S', k=169) == '`j4z_:S' - - def test_railencrypt_6(self): - assert railencrypt(st='? }qW^W', k=892) == '? }qW^W' - - def test_railencrypt_7(self): - assert railencrypt(st='ns(ob!Pb', k=389) == 'ns(ob!Pb' - - def test_railencrypt_8(self): - assert railencrypt(st='r$&=(', k=427) == 'r$&=(' - - def test_railencrypt_9(self): - assert railencrypt(st='2A/L~[%4', k=339) == '2A/L~[%4' - - def test_railencrypt_10(self): - assert railencrypt(st='M>'', k=210) == 'M>'' - - def test_railencrypt_11(self): - assert railencrypt(st='=5]'146#', k=143) == '=5]'146#' - - def test_railencrypt_12(self): - assert railencrypt(st='c?g!b', k=675) == 'c?g!b' - - def test_railencrypt_13(self): - assert railencrypt(st='U"i-', k=547) == 'U"i-' - - def test_railencrypt_14(self): - assert railencrypt(st='+e[', k=328) == '+e[' - - def test_railencrypt_15(self): - assert railencrypt(st='@ICWq0.[D', k=944) == '@ICWq0.[D' - - def test_railencrypt_16(self): - assert railencrypt(st='~a}By', k=141) == '~a}By' - - def test_railencrypt_17(self): - assert railencrypt(st='', k=574) == '' - - def test_railencrypt_18(self): - assert railencrypt(st='#7oR+_$*', k=457) == '#7oR+_$*' - - def test_railencrypt_19(self): - assert railencrypt(st='/c', k=900) == '/c' - - def test_railencrypt_20(self): - assert railencrypt(st='r', k=492) == 'r' - - def test_railencrypt_21(self): - assert railencrypt(st='vh]lR', k=242) == 'vh]lR' - - def test_railencrypt_22(self): - assert railencrypt(st='**hH2', k=270) == '**hH2' - - def test_railencrypt_23(self): - assert railencrypt(st=')>On.', k=70) == ')>On.' - - def test_railencrypt_24(self): - assert railencrypt(st='djQ*5r_Uk', k=420) == 'djQ*5r_Uk' - - def test_railencrypt_25(self): - assert railencrypt(st='{+xw', k=405) == '{+xw' - - def test_railencrypt_26(self): - assert railencrypt(st='RGvx~r', k=976) == 'RGvx~r' - - def test_railencrypt_27(self): - assert railencrypt(st='<$', k=154) == '<$' - - def test_railencrypt_28(self): - assert railencrypt(st=')>On.', k=221) == ')>On.' - - def test_railencrypt_29(self): - assert railencrypt(st='IH!=Y`l*', k=885) == 'IH!=Y`l*' - - def test_railencrypt_30(self): - assert railencrypt(st='w::L', k=641) == 'w::L' - - def test_railencrypt_31(self): - assert railencrypt(st=')>On.', k=885) == ')>On.' - - def test_railencrypt_32(self): - assert railencrypt(st='!CIXRTgh', k=754) == '!CIXRTgh' - - def test_railencrypt_33(self): - assert railencrypt(st='?NGYChStM', k=850) == '?NGYChStM' - - def test_railencrypt_34(self): - assert railencrypt(st=' X$qR?', k=389) == ' X$qR?' - - def test_railencrypt_35(self): - assert railencrypt(st='dA$PGkO', k=453) == 'dA$PGkO' - - def test_railencrypt_36(self): - assert railencrypt(st=',gN', k=663) == ',gN' - - def test_railencrypt_37(self): - assert railencrypt(st='', k=885) == '' - - def test_railencrypt_38(self): - assert railencrypt(st='3kDF>S%/', k=816) == '3kDF>S%/' - - def test_railencrypt_39(self): - assert railencrypt(st='h{I