Skip to content

Commit 9ba5a2d

Browse files
Merge branch 'master' into feature/jsonPatch
2 parents a16199d + 026f117 commit 9ba5a2d

36 files changed

Lines changed: 802 additions & 35 deletions

File tree

client-java/instrumentation-shared/src/main/java/org/evomaster/client/java/instrumentation/shared/ReplacementCategory.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ public enum ReplacementCategory {
3737
*/
3838
MONGO,
3939

40+
/**
41+
* Replacements to handle CASSANDRA command intereception
42+
*/
43+
CASSANDRA,
44+
4045
/**
4146
* Replacements to handle OPENSEARCH command interceptions
4247
*/

client-java/instrumentation/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,11 @@
205205
<artifactId>mongodb-driver-sync</artifactId>
206206
<scope>test</scope>
207207
</dependency>
208+
<dependency>
209+
<groupId>org.apache.cassandra</groupId>
210+
<artifactId>java-driver-core</artifactId>
211+
<scope>test</scope>
212+
</dependency>
208213
<dependency>
209214
<groupId>org.neo4j.driver</groupId>
210215
<artifactId>neo4j-java-driver</artifactId>

client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/AdditionalInfo.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ public StatementDescription(String line, String method) {
106106

107107
private final Set<MongoFindCommand> mongoFindCommandData = new CopyOnWriteArraySet<>();
108108

109+
private final Set<ExecutedCqlCommand> executedCqlCommandData = new CopyOnWriteArraySet<>();
110+
109111
private final Set<Neo4JRunCommand> neo4JRunCommandData = new CopyOnWriteArraySet<>();
110112

111113
private final Set<OpenSearchCommand> openSearchCommandData = new CopyOnWriteArraySet<>();
@@ -124,6 +126,10 @@ public Set<MongoFindCommand> getMongoInfoData(){
124126
return Collections.unmodifiableSet(mongoFindCommandData);
125127
}
126128

129+
public Set<ExecutedCqlCommand> getCqlInfoData(){
130+
return Collections.unmodifiableSet(executedCqlCommandData);
131+
}
132+
127133
public Set<Neo4JRunCommand> getNeo4JInfoData(){
128134
return Collections.unmodifiableSet(neo4JRunCommandData);
129135
}
@@ -152,6 +158,10 @@ public void addMongoInfo(MongoFindCommand info){
152158
mongoFindCommandData.add(info);
153159
}
154160

161+
public void addCqlInfo(ExecutedCqlCommand info){
162+
executedCqlCommandData.add(info);
163+
}
164+
155165
public void addNeo4JInfo(Neo4JRunCommand info){
156166
neo4JRunCommandData.add(info);
157167
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package org.evomaster.client.java.instrumentation;
2+
3+
import java.io.Serializable;
4+
import java.util.Objects;
5+
6+
/**
7+
* Info related to CQL command execution
8+
*/
9+
public class ExecutedCqlCommand implements Serializable {
10+
11+
/**
12+
* A constant to represent that execution time could not be obtained.
13+
*/
14+
public static final long FAILURE_EXECUTION_TIME = -1L;
15+
16+
/**
17+
* The actual CQL string with the command that was executed
18+
*/
19+
private final String cqlCommand;
20+
21+
/**
22+
* Whether the CQL command failed, for any reason
23+
*/
24+
private final boolean threwCqlException;
25+
26+
/**
27+
* Execution time
28+
*/
29+
private final long executionTime;
30+
31+
public ExecutedCqlCommand(String cqlCommand, boolean threwCqlException, long executionTime) {
32+
this.cqlCommand = cqlCommand;
33+
this.threwCqlException = threwCqlException;
34+
this.executionTime = executionTime;
35+
}
36+
37+
public String getCqlCommand() {
38+
return cqlCommand;
39+
}
40+
41+
public boolean hasThrownCqlException() {
42+
return threwCqlException;
43+
}
44+
45+
public long getExecutionTime() {
46+
return executionTime;
47+
}
48+
49+
@Override
50+
public boolean equals(Object o) {
51+
if (this == o) return true;
52+
if (o == null || getClass() != o.getClass()) return false;
53+
ExecutedCqlCommand executedCqlCommand = (ExecutedCqlCommand) o;
54+
return threwCqlException == executedCqlCommand.threwCqlException && Objects.equals(cqlCommand, executedCqlCommand.cqlCommand);
55+
}
56+
57+
@Override
58+
public int hashCode() {
59+
return Objects.hash(cqlCommand, threwCqlException);
60+
}
61+
}

client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/InstrumentationController.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ public static void setExecutingInitMongo(boolean executingInitMongo){
5151
ExecutionTracer.setExecutingInitMongo(executingInitMongo);
5252
}
5353

54+
public static void setExecutingInitCassandra(boolean executingInitCassandra){
55+
ExecutionTracer.setExecutingInitCassandra(executingInitCassandra);
56+
}
57+
5458
public static void setExecutingInitRedis(boolean executingInitRedis){
5559
ExecutionTracer.setExecutingInitRedis(executingInitRedis);
5660
}

client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/coverage/methodreplacement/ReplacementList.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public static List<MethodReplacementClass> getList() {
3131
new ByteClassReplacement(),
3232
new CharacterClassReplacement(),
3333
new CollectionClassReplacement(),
34+
new CqlSessionClassReplacement(),
3435
new CursorPreparerClassReplacement(),
3536
new DateClassReplacement(),
3637
new DateFormatClassReplacement(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package org.evomaster.client.java.instrumentation.coverage.methodreplacement.thirdpartyclasses;
2+
3+
import org.evomaster.client.java.instrumentation.ExecutedCqlCommand;
4+
import org.evomaster.client.java.instrumentation.coverage.methodreplacement.Replacement;
5+
import org.evomaster.client.java.instrumentation.coverage.methodreplacement.ThirdPartyMethodReplacementClass;
6+
import org.evomaster.client.java.instrumentation.coverage.methodreplacement.UsageFilter;
7+
import org.evomaster.client.java.instrumentation.shared.ReplacementCategory;
8+
import org.evomaster.client.java.instrumentation.shared.ReplacementType;
9+
import org.evomaster.client.java.instrumentation.staticstate.ExecutionTracer;
10+
11+
import java.lang.reflect.InvocationTargetException;
12+
import java.lang.reflect.Method;
13+
14+
public class CqlSessionClassReplacement extends ThirdPartyMethodReplacementClass {
15+
private static final CqlSessionClassReplacement singleton = new CqlSessionClassReplacement();
16+
17+
public static final String CASSANDRA_FIND_STRING_SYNC = "cassandraExecuteStringSync";
18+
19+
@Override
20+
protected String getNameOfThirdPartyTargetClass() {
21+
return "com.datastax.oss.driver.api.core.CqlSession";
22+
}
23+
24+
@Replacement(type = ReplacementType.TRACKER, id = CASSANDRA_FIND_STRING_SYNC, usageFilter = UsageFilter.ANY, category = ReplacementCategory.CASSANDRA, castTo = "com.datastax.oss.driver.api.core.cql.ResultSet")
25+
public static Object execute(Object cqlSession, String query) {
26+
return handleCqlExecute(CASSANDRA_FIND_STRING_SYNC, cqlSession, query);
27+
}
28+
29+
private static Object handleCqlExecute(String id, Object cqlSession, String query) {
30+
long start = System.currentTimeMillis();
31+
try {
32+
Method executeMethod = retrieveExecuteMethod(id, cqlSession);
33+
Object result = executeMethod.invoke(cqlSession, query);
34+
long end = System.currentTimeMillis();
35+
long executionTime = end - start;
36+
ExecutedCqlCommand info = new ExecutedCqlCommand(query, false, executionTime);
37+
ExecutionTracer.addCqlInfo(info);
38+
return result;
39+
} catch (IllegalAccessException e) {
40+
throw new RuntimeException(e);
41+
} catch (InvocationTargetException e) {
42+
throw (RuntimeException) e.getCause();
43+
}
44+
}
45+
46+
private static Method retrieveExecuteMethod(String id, Object cqlSession){
47+
return getOriginal(singleton, id, cqlSession);
48+
}
49+
50+
}

client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/external/AgentController.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
/**
1616
* Code running in the Java Agent to receive and respond to the
17-
* requests from the the SUT controller.
17+
* requests from the SUT controller.
1818
*/
1919
public class AgentController {
2020

@@ -94,6 +94,10 @@ public static void start(int port){
9494
handleExecutingInitMongo();
9595
sendCommand(Command.ACK);
9696
break;
97+
case EXECUTING_INIT_CASSANDRA:
98+
handleExecutingInitCassandra();
99+
sendCommand(Command.ACK);
100+
break;
97101
case EXECUTING_INIT_REDIS:
98102
handleExecutingInitRedis();
99103
sendCommand(Command.ACK);
@@ -184,6 +188,16 @@ private static void handleExecutingInitMongo() {
184188
}
185189
}
186190

191+
private static void handleExecutingInitCassandra() {
192+
try {
193+
Object msg = in.readObject();
194+
Boolean executingInitCassandra = (Boolean) msg;
195+
InstrumentationController.setExecutingInitCassandra(executingInitCassandra);
196+
} catch (Exception e){
197+
SimpleLogger.error("Failure in handling executing-init-cassandra: "+e.getMessage());
198+
}
199+
}
200+
187201
private static void handleExecutingInitRedis() {
188202
try {
189203
Object msg = in.readObject();

client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/external/Command.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public enum Command implements Serializable {
1919
KILL_SWITCH,
2020
EXECUTING_INIT_SQL,
2121
EXECUTING_INIT_MONGO,
22+
EXECUTING_INIT_CASSANDRA,
2223
EXECUTING_INIT_REDIS,
2324
EXECUTING_ACTION,
2425
BOOT_TIME_INFO,

client-java/instrumentation/src/main/java/org/evomaster/client/java/instrumentation/staticstate/ExecutionTracer.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public class ExecutionTracer {
3535

3636
private static boolean executingInitMongo = false;
3737

38+
private static boolean executingInitCassandra = false;
39+
3840
private static boolean executingInitRedis = false;
3941

4042
private static boolean executingInitNeo4J = false;
@@ -202,6 +204,10 @@ public static void setExecutingInitMongo(boolean executingInitMongo) {
202204
ExecutionTracer.executingInitMongo = executingInitMongo;
203205
}
204206

207+
public static void setExecutingInitCassandra(boolean executingInitCassandra) {
208+
ExecutionTracer.executingInitCassandra = executingInitCassandra;
209+
}
210+
205211
public static void setExecutingInitRedis(boolean executingInitRedis) {
206212
ExecutionTracer.executingInitRedis = executingInitRedis;
207213
}
@@ -442,6 +448,11 @@ public static void addMongoInfo(MongoFindCommand info){
442448
getCurrentAdditionalInfo().addMongoInfo(info);
443449
}
444450

451+
public static void addCqlInfo(ExecutedCqlCommand info){
452+
if (!executingInitCassandra)
453+
getCurrentAdditionalInfo().addCqlInfo(info);
454+
}
455+
445456
public static void addNeo4JInfo(Neo4JRunCommand info){
446457
if (!executingInitNeo4J)
447458
getCurrentAdditionalInfo().addNeo4JInfo(info);

0 commit comments

Comments
 (0)