Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Insertions to mongo databases #776

Merged
merged 25 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
dcef091
Early approach to supporting Mongo data generation
hghianni May 17, 2023
5adf795
Take into account database name when inserting data
hghianni May 31, 2023
27dbcb5
Merge branch 'master' into mongo-support
hghianni Jun 12, 2023
d9b4417
Continue with the repository type handling
hghianni Jun 20, 2023
c93a04d
Add tests, refactors, docs
hghianni Jun 26, 2023
0ed6ca3
Merge branch 'master' into mongo-support
hghianni Jun 28, 2023
3bd7250
Momentary fix to handle multiple databases
hghianni Jun 28, 2023
cf8f900
Change option extractMongoExecutionInfo to be false by default
hghianni Jun 28, 2023
dac9264
Solve failing tests
hghianni Jun 28, 2023
d39a3d6
Update options file
hghianni Jun 28, 2023
ea42184
Decrease iterations of MongoEMGenerationTest to avoid timeout
hghianni Jun 28, 2023
d06f9c3
Change failed queries to be only the queries executed in an empty col…
hghianni Jun 29, 2023
5530399
Change surefire config to debug why MongoEMGenerationTest fails
hghianni Jun 30, 2023
7236b31
Force mongo tests to run on different processes and rollback previous…
hghianni Jul 2, 2023
c6814dc
Handle implicit and operation
hghianni Jul 2, 2023
db97943
Docs and renamed FailedQuery
hghianni Jul 3, 2023
7ae976f
Merge branch 'master' into mongo-support
hghianni Jul 3, 2023
38ac955
Merge branch 'master' into mongo-support
hghianni Jul 8, 2023
074b90f
Adapt to work with External controllers
hghianni Jul 11, 2023
82d745f
Force fields of type of collection to be not optional
hghianni Jul 14, 2023
6ff1c81
Handle Spring field annotation
hghianni Jul 14, 2023
e3b700d
Merge branch 'master' into mongo-support
hghianni Jul 30, 2023
60ac39f
Address comments
hghianni Jul 30, 2023
803d808
Add test & fix
hghianni Jul 31, 2023
d05664f
Use new dto in test
hghianni Jul 31, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,7 @@ public class ControllerConstants {

public static final String DATABASE_COMMAND = "/databaseCommand";

public static final String MONGO_INSERTION = "/mongoInsertion";

public static final String POST_SEARCH_ACTION = "/postSearchAction";
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.evomaster.client.java.controller.api.dto;

import org.evomaster.client.java.controller.api.dto.database.execution.ExecutionDto;

import org.evomaster.client.java.controller.api.dto.database.execution.MongoExecutionDto;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -19,4 +19,6 @@ public class ExtraHeuristicsDto {
public List<HeuristicEntryDto> heuristics = new ArrayList<>();

public ExecutionDto databaseExecutionDto;

public MongoExecutionDto mongoExecutionDto;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.evomaster.client.java.controller.api.dto.database.execution;


import java.util.ArrayList;
import java.util.List;

public class MongoExecutionDto {
public List<MongoFailedQuery> failedQueries = new ArrayList<>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.evomaster.client.java.controller.api.dto.database.execution;


public class MongoFailedQuery {
/**
* The database to insert the document into.
*/
private final String database;
/**
* The collection to insert the document into.
*/
private final String collection;
/**
* The type of the new document. Should map the type of the documents of the collection.
*/
private String documentsType;

public MongoFailedQuery(String database, String collection, String documentsType) {
this.database = database;
this.collection = collection;
this.documentsType = documentsType;
}

public MongoFailedQuery(){
this.database = "";
this.collection = "";
this.documentsType = "";
}

public String getDatabase() {return database;}
public String getCollection() {return collection;}
public String getDocumentsType() {
return documentsType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.evomaster.client.java.controller.api.dto.database.operations;

import java.util.ArrayList;
import java.util.List;

public class MongoDatabaseCommandDto {
public List<MongoInsertionDto> insertions = new ArrayList<>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.evomaster.client.java.controller.api.dto.database.operations;

public class MongoInsertionDto {
/**
* The database to insert the document into.
*/
public String databaseName;
/**
* The collection to insert the document into.
*/
public String collectionName;
hghianni marked this conversation as resolved.
Show resolved Hide resolved
/**
* The type of the new document. Should map the type of the documents of the collection.
*/
public String data;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.evomaster.client.java.controller.api.dto.database.operations;

import java.util.ArrayList;
import java.util.List;

public class MongoInsertionResultsDto {
/**
* whether the insertion at the index of a sequence of Mongo insertions (i.e., {@link MongoDatabaseCommandDto#insertions})
* executed successfully
*/
public List<Boolean> executionResults = new ArrayList<>();
hghianni marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ public final void setExecutingInitSql(boolean executingInitSql) {
ExecutionTracer.setExecutingInitSql(executingInitSql);
}

@Override
public final void setExecutingInitMongo(boolean executingInitMongo) {
ExecutionTracer.setExecutingInitMongo(executingInitMongo);
}

@Override
public final void setExecutingAction(boolean executingAction){
ExecutionTracer.setExecutingAction(executingAction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,14 @@ public final void setExecutingInitSql(boolean executingInitSql) {
ExecutionTracer.setExecutingInitSql(executingInitSql);
}

@Override
public final void setExecutingInitMongo(boolean executingInitMongo) {
checkInstrumentation();
serverController.setExecutingInitMongo(executingInitMongo);
// sync executingInitMongo on the local ExecutionTracer
ExecutionTracer.setExecutingInitMongo(executingInitMongo);
}

@Override
public final void setExecutingAction(boolean executingAction){
checkInstrumentation();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import org.evomaster.client.java.controller.api.dto.database.operations.InsertionDto;
import org.evomaster.client.java.controller.api.dto.database.operations.InsertionResultsDto;
import org.evomaster.client.java.controller.api.dto.database.operations.MongoInsertionDto;
import org.evomaster.client.java.controller.api.dto.database.operations.MongoInsertionResultsDto;
import org.evomaster.client.java.controller.db.DbCleaner;
import org.evomaster.client.java.controller.internal.db.DbSpecification;

Expand Down Expand Up @@ -85,6 +87,7 @@ default void setupForGeneratedTest(){}
*/
InsertionResultsDto execInsertionsIntoDatabase(List<InsertionDto> insertions, InsertionResultsDto... previous);

MongoInsertionResultsDto execInsertionsIntoMongoDatabase(List<MongoInsertionDto> insertions);

/**
* <p>
Expand Down Expand Up @@ -173,6 +176,8 @@ default void extractRPCSchema(){}

List<DbSpecification> getDbSpecifications();

default Object getMongoConnection() {return null;}


/**
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import org.evomaster.client.java.controller.api.dto.*;
import org.evomaster.client.java.controller.api.dto.database.operations.DatabaseCommandDto;
import org.evomaster.client.java.controller.api.dto.database.operations.InsertionResultsDto;
import org.evomaster.client.java.controller.api.dto.database.operations.MongoDatabaseCommandDto;
import org.evomaster.client.java.controller.api.dto.database.operations.MongoInsertionResultsDto;
import org.evomaster.client.java.controller.api.dto.problem.*;
import org.evomaster.client.java.controller.mongo.MongoScriptRunner;
import org.evomaster.client.java.controller.problem.*;
import org.evomaster.client.java.controller.db.QueryResult;
import org.evomaster.client.java.controller.db.SqlScriptRunner;
Expand Down Expand Up @@ -366,6 +369,7 @@ public Response runSut(SutRunDto dto, @Context HttpServletRequest httpServletReq
return Response.status(500).entity(WrappedResponseDto.withError(msg)).build();
}
noKillSwitch(() -> sutController.initSqlHandler());
noKillSwitch(() -> sutController.initMongoHandler());
} else {
//TODO as starting should be blocking, need to check
//if initialized, and wait if not
Expand Down Expand Up @@ -759,4 +763,62 @@ going to be instrumented (as not in org.evomaster)
sutController.setExecutingInitSql(false);
}
}

@Path(ControllerConstants.MONGO_INSERTION)
@Consumes(Formats.JSON_V1)
@POST
public Response executeMongoInsertion(MongoDatabaseCommandDto dto, @Context HttpServletRequest httpServletRequest) {

assert trackRequestSource(httpServletRequest);

try {

sutController.setExecutingInitMongo(true);

SimpleLogger.debug("Received mongo database command");

Object connection = noKillSwitch(sutController::getMongoConnection);
if (connection == null) {
String msg = "No active database connection";
SimpleLogger.warn(msg);
return Response.status(400).entity(WrappedResponseDto.withError(msg)).build();
}

if (dto.insertions == null || dto.insertions.isEmpty()) {
String msg = "No input command";
SimpleLogger.warn(msg);
return Response.status(400).entity(WrappedResponseDto.withError(msg)).build();
}

if (dto.insertions.stream().anyMatch(i -> i.collectionName.isEmpty() || i.databaseName.isEmpty())) {
String msg = "Insertion with no target collection or database";
SimpleLogger.warn(msg);
return Response.status(400).entity(WrappedResponseDto.withError(msg)).build();
}

MongoInsertionResultsDto mongoInsertionResultsDto = null;


try {
mongoInsertionResultsDto = MongoScriptRunner.executeInsert(connection, dto.insertions);
} catch (Exception e) {
String msg = "Failed to execute database command: " + e.getMessage();
SimpleLogger.warn(msg);
return Response.status(400).entity(WrappedResponseDto.withError(msg)).build();
}

if (mongoInsertionResultsDto != null) {
return Response.status(200).entity(WrappedResponseDto.withData(mongoInsertionResultsDto)).build();
} else {
return Response.status(204).entity(WrappedResponseDto.withNoData()).build();
}

} catch (RuntimeException e) {
String msg = "Thrown exception: " + e.getMessage();
SimpleLogger.error(msg, e);
return Response.status(500).entity(WrappedResponseDto.withError(msg)).build();
} finally {
sutController.setExecutingInitMongo(false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import org.evomaster.client.java.controller.api.dto.database.execution.ExecutionDto;
import org.evomaster.client.java.controller.api.dto.database.operations.InsertionDto;
import org.evomaster.client.java.controller.api.dto.database.operations.InsertionResultsDto;
import org.evomaster.client.java.controller.api.dto.database.operations.MongoInsertionDto;
import org.evomaster.client.java.controller.api.dto.database.operations.MongoInsertionResultsDto;
import org.evomaster.client.java.controller.api.dto.database.schema.DbSchemaDto;
import org.evomaster.client.java.controller.api.dto.database.schema.ExtraConstraintsDto;
import org.evomaster.client.java.controller.api.dto.MockDatabaseDto;
Expand All @@ -28,6 +30,7 @@
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.mongo.MongoScriptRunner;
import org.evomaster.client.java.controller.problem.ProblemInfo;
import org.evomaster.client.java.controller.problem.RPCProblem;
import org.evomaster.client.java.controller.problem.rpc.CustomizedNotNullAnnotationForRPCDto;
Expand Down Expand Up @@ -227,6 +230,21 @@ public InsertionResultsDto execInsertionsIntoDatabase(List<InsertionDto> inserti
}
}

@Override
public MongoInsertionResultsDto execInsertionsIntoMongoDatabase(List<MongoInsertionDto> insertions) {

Object connection = getMongoConnection();
if (connection == null) {
throw new IllegalStateException("No connection to mongo database");
}

try {
return MongoScriptRunner.executeInsert(connection, insertions);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public int getActionIndex(){
return actionIndex;
}
Expand Down Expand Up @@ -259,6 +277,16 @@ public final void initSqlHandler() {
sqlHandler.setSchema(getSqlDatabaseSchema());
}

public final void initMongoHandler() {
// This is needed because the replacement use to get this info occurs during the start of the SUT.

List<AdditionalInfo> list = getAdditionalInfoList();
if(!list.isEmpty()) {
AdditionalInfo last = list.get(list.size() - 1);
last.getMongoCollectionInfoData().forEach(mongoHandler::handle);
}
}


/**
* TODO further handle multiple connections
Expand Down Expand Up @@ -348,9 +376,9 @@ private void computeSQLHeuristics(ExtraHeuristicsDto dto) {
}

public final void computeMongoHeuristics(ExtraHeuristicsDto dto){
if(mongoHandler.isCalculateHeuristics()){
List<AdditionalInfo> list = getAdditionalInfoList();

List<AdditionalInfo> list = getAdditionalInfoList();
if(mongoHandler.isCalculateHeuristics()){
if(!list.isEmpty()) {
AdditionalInfo last = list.get(list.size() - 1);
last.getMongoInfoData().forEach(it -> {
Expand All @@ -373,6 +401,14 @@ public final void computeMongoHeuristics(ExtraHeuristicsDto dto){
))
.forEach(h -> dto.heuristics.add(h));
}

if(mongoHandler.isExtractMongoExecution()){
if(!list.isEmpty()) {
AdditionalInfo last = list.get(list.size() - 1);
last.getMongoCollectionInfoData().forEach(mongoHandler::handle);
}
dto.mongoExecutionDto = mongoHandler.getExecutionDto();
}
}

/**
Expand Down Expand Up @@ -1121,6 +1157,8 @@ public final String getDatabaseDriverName(){

public abstract void setExecutingInitSql(boolean executingInitSql);

public abstract void setExecutingInitMongo(boolean executingInitMongo);

public abstract void setExecutingAction(boolean executingAction);

public abstract BootTimeInfoDto getBootTimeInfoDto();
Expand Down
Loading
Loading