Skip to content

Commit

Permalink
Merge branch 'master' into taint-array
Browse files Browse the repository at this point in the history
  • Loading branch information
seran committed May 15, 2023
2 parents 147e9fc + 0ecd3c1 commit dbcbac8
Show file tree
Hide file tree
Showing 94 changed files with 3,810 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class HeuristicEntryDto {
* The type of extra heuristic.
* Note: for the moment, we only have heuristics on SQL commands
*/
public enum Type {SQL}
public enum Type {SQL, MONGO}

/**
* Should we try to minimize or maximize the heuristic?
Expand Down
10 changes: 10 additions & 0 deletions client-java/controller/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,16 @@
<artifactId>libthrift</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>bson</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.evomaster.client.java.controller.db.SqlScriptRunner;
import org.evomaster.client.java.controller.db.SqlScriptRunnerCached;
import org.evomaster.client.java.controller.internal.db.DbSpecification;
import org.evomaster.client.java.controller.internal.db.MongoHandler;
import org.evomaster.client.java.controller.internal.db.SchemaExtractor;
import org.evomaster.client.java.controller.internal.db.SqlHandler;
import org.evomaster.client.java.controller.problem.ProblemInfo;
Expand Down Expand Up @@ -70,6 +71,8 @@ public abstract class SutController implements SutHandler, CustomizationHandler

private final SqlHandler sqlHandler = new SqlHandler();

private final MongoHandler mongoHandler = new MongoHandler();

private Server controllerServer;

/**
Expand Down Expand Up @@ -275,6 +278,7 @@ public final boolean doEmploySmartDbClean(){

public final void resetExtraHeuristics() {
sqlHandler.reset();
mongoHandler.reset();
}

public final List<ExtraHeuristicsDto> getExtraHeuristics() {
Expand All @@ -290,6 +294,13 @@ public final ExtraHeuristicsDto computeExtraHeuristics() {

ExtraHeuristicsDto dto = new ExtraHeuristicsDto();

computeSQLHeuristics(dto);
computeMongoHeuristics(dto);

return dto;
}

private void computeSQLHeuristics(ExtraHeuristicsDto dto) {
if(sqlHandler.isCalculateHeuristics() || sqlHandler.isExtractSqlExecution()){
/*
TODO refactor, once we move SQL analysis into Core
Expand Down Expand Up @@ -332,8 +343,34 @@ public final ExtraHeuristicsDto computeExtraHeuristics() {
accessedTables.addAll(executionDto.updatedData.keySet());
}
}
}

return dto;
public final void computeMongoHeuristics(ExtraHeuristicsDto dto){
if(mongoHandler.isCalculateHeuristics()){

List<AdditionalInfo> list = getAdditionalInfoList();
if(!list.isEmpty()) {
AdditionalInfo last = list.get(list.size() - 1);
last.getMongoInfoData().forEach(it -> {
try {
mongoHandler.handle(it);
} catch (Exception e){
SimpleLogger.error("FAILED TO HANDLE MONGO COMMAND");
assert false;
}
});
}

mongoHandler.getDistances().stream()
.map(p ->
new HeuristicEntryDto(
HeuristicEntryDto.Type.MONGO,
HeuristicEntryDto.Objective.MINIMIZE_TO_ZERO,
p.bson.toString(),
p.distance
))
.forEach(h -> dto.heuristics.add(h));
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package org.evomaster.client.java.controller.internal.db;

import org.evomaster.client.java.controller.mongo.MongoHeuristicsCalculator;
import org.evomaster.client.java.instrumentation.MongoInfo;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

/**
* Class used to act upon Mongo commands executed by the SUT
*/
public class MongoHandler {

/**
* Info about Find operations executed
*/
private final List<MongoInfo> operations;

/**
* Whether to use execution's info or not
*/
private volatile boolean extractMongoExecution;

/**
* The heuristics based on the Mongo execution
*/
private final List<MongoOperationDistance> distances;

/**
* Whether to calculate heuristics based on execution or not
*/
private volatile boolean calculateHeuristics;

public MongoHandler() {
distances = new ArrayList<>();
operations = new ArrayList<>();
extractMongoExecution = true;
calculateHeuristics = true;
}

public void reset() {
operations.clear();
distances.clear();
}

public void handle(MongoInfo info) {
if (!extractMongoExecution) {
return;
}

operations.add(info);
}

public List<MongoOperationDistance> getDistances() {

operations.stream().filter(info -> info.getQuery() != null).forEach(mongoInfo -> {
double dist;
try {
dist = computeDistance(mongoInfo);
} catch (Exception e) {
dist = Double.MAX_VALUE;
}
distances.add(new MongoOperationDistance(mongoInfo.getQuery(), dist));
});

operations.clear();

return distances;
}

private double computeDistance(MongoInfo info) {
Object collection = info.getCollection();
Iterable<?> documents = getDocuments(collection);

MongoHeuristicsCalculator calculator = new MongoHeuristicsCalculator();

double min = Double.MAX_VALUE;

for (Object doc : documents) {
double dist = calculator.computeExpression(info.getQuery(), doc);
if (dist == 0) return 0;
if (dist < min) min = dist;
}
return min;
}

private static Iterable<?> getDocuments(Object collection) {
try {
Class<?> collectionClass = collection.getClass().getClassLoader().loadClass("com.mongodb.client.MongoCollection");
return (Iterable<?>) collectionClass.getMethod("find").invoke(collection);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException |
ClassNotFoundException e) {
throw new RuntimeException("Failed to retrieve all documents from a mongo collection", e);
}
}

public boolean isCalculateHeuristics() {
return calculateHeuristics;
}

public boolean isExtractMongoExecution() {
return extractMongoExecution;
}

public void setCalculateHeuristics(boolean calculateHeuristics) {
this.calculateHeuristics = calculateHeuristics;
}

public void setExtractMongoExecution(boolean extractMongoExecution) {
this.extractMongoExecution = extractMongoExecution;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.evomaster.client.java.controller.internal.db;

public class MongoOperationDistance {

public final Object bson;

public final double distance;


public MongoOperationDistance(Object bson, double distance) {
this.bson= bson;
this.distance = distance;
}
}
Loading

0 comments on commit dbcbac8

Please sign in to comment.