-
Notifications
You must be signed in to change notification settings - Fork 397
Expand file tree
/
Copy pathTestEnvironment.java
More file actions
139 lines (117 loc) · 4.92 KB
/
TestEnvironment.java
File metadata and controls
139 lines (117 loc) · 4.92 KB
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package sqlancer.reducer;
import sqlancer.*;
import sqlancer.common.query.Query;
import sqlancer.reducer.VirtualDB.VirtualDBGlobalState;
import sqlancer.reducer.VirtualDB.VirtualDBProvider;
import sqlancer.reducer.VirtualDB.VirtualDBQuery;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* TODO: Make Connection a generic type OR Fake a conn QUERY AND CONNECTION BOTH ARE FAKE. FAKE QUERY sub class
*/
public class TestEnvironment {
private final String databaseName = "virtual_db";
private final MainOptions options = new MainOptions();
private VirtualDBProvider provider = null;
private VirtualDBGlobalState state, newGlobalState;
private Reducer<VirtualDBGlobalState> reducer = null;
enum ReducerType {
USING_STATEMENT_REDUCER, USING_AST_BASED_REDUCER
};
private TestEnvironment(ReducerType type) throws Exception {
setUpTestingEnvironment();
if (type == ReducerType.USING_STATEMENT_REDUCER) {
reducer = new StatementReducer<>(provider);
} else if (type == ReducerType.USING_AST_BASED_REDUCER) {
reducer = new ASTBasedReducer<>(provider);
}
}
public static TestEnvironment getStatementReducerEnv() throws Exception {
return new TestEnvironment(ReducerType.USING_STATEMENT_REDUCER);
}
public static TestEnvironment getASTBasedReducerEnv() throws Exception {
return new TestEnvironment(ReducerType.USING_AST_BASED_REDUCER);
}
/**
* @param queries:
* List of Query<?>
*
* @return String of queries that appended together with '\n' separated (no '\n' at the last line)
*/
public static String getQueriesString(List<Query<?>> queries) {
return queries.stream().map(Query::getQueryString).collect(Collectors.joining("\n"));
}
private VirtualDBGlobalState createGlobalState() {
try {
return provider.getGlobalStateClass().getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new AssertionError(e);
}
}
@SuppressWarnings("rawtypes")
private void initVirtualDBProvider() {
try {
ServiceLoader<DatabaseProvider> loader = ServiceLoader.load(DatabaseProvider.class);
for (DatabaseProvider<?, ?, ?> provider : loader) {
if (provider.getDBMSName().equals(databaseName)) {
this.provider = (VirtualDBProvider) provider;
break;
}
}
if (provider == null) {
throw new AssertionError("testing provider not registered");
}
} catch (Exception e) {
throw new AssertionError(e);
}
}
private void setUpTestingEnvironment() throws Exception {
initVirtualDBProvider();
state = createGlobalState();
StateToReproduce stateToReproduce = provider.getStateToReproduce(databaseName);
state.setState(stateToReproduce);
state.setDatabaseName(databaseName);
// A really hacky way to enable reducer...
Field field = options.getClass().getDeclaredField("useReducer");
field.setAccessible(true);
field.set(options, true);
state.setMainOptions(options);
// Main.StateLogger logger = new Main.StateLogger(databaseName, provider, options);
// state.setStateLogger(logger);
try (SQLConnection con = provider.createDatabase(state)) {
state.setConnection(con);
newGlobalState = createGlobalState();
Main.StateLogger newLogger = new Main.StateLogger(databaseName, provider, options);
newGlobalState.setStateLogger(newLogger);
state.setStateLogger(newLogger);
newGlobalState.setState(stateToReproduce);
newGlobalState.setDatabaseName(databaseName);
newGlobalState.setMainOptions(options);
}
}
public void setInitialStatementsFromStrings(List<String> statements) {
List<Query<?>> queries = new ArrayList<>();
for (String s : statements) {
queries.add(new VirtualDBQuery(s));
}
state.getState().setStatements(queries);
}
public void setBugInducingCondition(Function<List<Query<?>>, Boolean> bugInducingCondition) {
state.setBugInducingCondition(bugInducingCondition);
newGlobalState.setBugInducingCondition(bugInducingCondition);
}
public void runReduce() throws Exception {
Reproducer<VirtualDBGlobalState> reproducer = provider.generateAndTestDatabase(newGlobalState);
reducer.reduce(state, reproducer, newGlobalState);
}
public List<Query<?>> getReducedStatements() {
return newGlobalState.getState().getStatements();
}
public List<Query<?>> getInitialStatements() {
return state.getState().getStatements();
}
}