-
Notifications
You must be signed in to change notification settings - Fork 3
/
delta_debugging.py
79 lines (61 loc) · 2.17 KB
/
delta_debugging.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
from queue import Queue
import logging
from utils import *
def ddmin(c, n, test):
"""
The original delta debugging algorithm
:param c: Current input
:param n: Current granularity
:param test: Test function used to determine if a particular input leads to a fault, a return value of True
indicates a failure
:return: Minimal subset of c leading to a failure
"""
logger = logging.getLogger('network-testing')
logger.info(f'\nRunning minimization on set {str_repr(c)} with granularity {n}\n')
if not n <= len(c):
return c
split = [c[i * (len(c) // n) + min(i, len(c) % n):(i + 1) * (len(c) // n) + min(i + 1, len(c) % n)] for i in
range(n)]
comps = [[i for i in c if i not in delta] for delta in split]
for delta in split:
if test(delta):
return ddmin(delta, 2, test)
for comp in comps:
if test(comp):
return ddmin(comp, max(n - 1, 2), test)
if n < len(c):
return ddmin(c, min(len(c), 2 * n), test)
else:
return c
def ddmin_iter(c, test_f, test_tc, f_to_tc):
"""
Iterative delta debugging algorithm
:param c: Starting input
:param test_f: Higher level test function
:param test_tc: Lower level test function
:param f_to_tc: Function to convert from high to low level
:return: A list of minimal failure-inducing subsets for c
"""
logger = logging.getLogger('network-testing')
min_sets = []
q = Queue()
q.put(c)
while not q.empty():
h = q.get()
faulty_feature_set = False
for ms in min_sets:
if all([f in f_to_tc(h) for f in ms]):
for f in ms:
q.put([x for x in h if x != f])
faulty_feature_set = True
break
if faulty_feature_set:
continue
if test_f(h):
min_features = ddmin(h, 2, test_f)
min_set = ddmin(f_to_tc(min_features), 2, test_tc)
logger.info(f'New minimal subset: {str_repr(min_set)}\n')
min_sets.append(min_set)
for f in min_features:
q.put([x for x in h if x != f])
return min_sets