Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -30,6 +30,8 @@ public class ControllerConstants {

public static final String MONGO_INSERTION = "/mongoInsertion";

public static final String REDIS_INSERTION = "/redisInsertion";

public static final String POST_SEARCH_ACTION = "/postSearchAction";

public static final String DERIVE_PARAMS = "/deriveParams";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.evomaster.client.java.controller.api.dto;

import org.evomaster.client.java.controller.api.dto.database.execution.RedisExecutionsDto;
import org.evomaster.client.java.controller.api.dto.database.execution.SqlExecutionsDto;
import org.evomaster.client.java.controller.api.dto.database.execution.MongoExecutionsDto;
import java.util.ArrayList;
Expand All @@ -21,4 +22,6 @@ public class ExtraHeuristicsDto {
public SqlExecutionsDto sqlSqlExecutionsDto;

public MongoExecutionsDto mongoExecutionsDto;

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

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

/**
* Each time a Redis command is executed, we keep track of those that return no data.
* This class summarizes every failed command in a given execution.
*/
public class RedisExecutionsDto {
Comment thread
aszyrej marked this conversation as resolved.

public RedisExecutionsDto() {}

public List<RedisFailedCommand> failedCommands = new ArrayList<>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.evomaster.client.java.controller.api.dto.database.execution;

/**
* Each time a Redis command is executed and returns no data, we keep track of which keys were involved,
* as well as relevant information such as the command type.
*/
public class RedisFailedCommand {
Comment thread
aszyrej marked this conversation as resolved.

/**
* Command keyword. Corresponds to a RedisCommandType label.
*/
public String command;

/**
* Command type. Corresponds to a RedisCommandType dataType.
*/
public String type;

/**
* Key involved. Could be null if the command does not have a key in the arguments. For example: KEYS (pattern).
*/
public String key;
Comment thread
jgaleotti marked this conversation as resolved.

public RedisFailedCommand() {}

public RedisFailedCommand(String command, String key, String type) {
this.command = command;
this.key = key;
this.type = type;
}
}
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;

/**
* Class used to execute Redis commands.
* Each item in the insertions list corresponds to a command to be executed.
*/
public class RedisDatabaseCommandsDto {
public List<RedisInsertionDto> insertions = new ArrayList<>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.evomaster.client.java.controller.api.dto.database.operations;

/**
* Contains data to be inserted into Redis.
*/
public class RedisInsertionDto {
Comment thread
jgaleotti marked this conversation as resolved.

/** The Redis key.*/
public String key;

/** The serialized value to set for that key. */
public String value;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.evomaster.client.java.controller.api.dto.database.operations;

import java.util.List;

/**
* The execution result of {@link RedisDatabaseCommandsDto} that performs insertions.
*/
public class RedisInsertionResultsDto {
Comment thread
aszyrej marked this conversation as resolved.

public RedisInsertionResultsDto() {}

/**
* Whether the insertion at the index of a sequence of Redis insertions (i.e., {@link RedisDatabaseCommandsDto#insertions})
* executed successfully.
*/
public List<Boolean> executionResults;
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ public final void setExecutingInitMongo(boolean executingInitMongo) {
ExecutionTracer.setExecutingInitMongo(executingInitMongo);
}

@Override
public final void setExecutingInitRedis(boolean executingInitRedis) {
ExecutionTracer.setExecutingInitRedis(executingInitRedis);
}

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

@Override
public final void setExecutingInitRedis(boolean executingInitRedis) {
checkInstrumentation();
serverController.setExecutingInitRedis(executingInitRedis);
// sync executingInitRedis on the local ExecutionTracer
ExecutionTracer.setExecutingInitRedis(executingInitRedis);
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are those functions calling *InitMongo? is it a copy&paste bug? and if so, why no test case failed?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I missed these copy-paste errors in my review. And yes, there should be a test failing due to this.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apologize for this copy paste error, already changed the code. Since we do not generate heuristics on insertion commands, this didn't affect the logic for Redis data generation.
As for a new test for this code... I don't believe it's possible to test this in an e2e context or even an integration one without adding some debug methods to access the data for testing.


@Override
public final void setExecutingAction(boolean executingAction){
checkInstrumentation();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package org.evomaster.client.java.controller;

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.operations.*;
import org.evomaster.client.java.controller.api.dto.problem.rpc.ScheduleTaskInvocationResultDto;
import org.evomaster.client.java.controller.redis.ReflectionBasedRedisClient;
import org.evomaster.client.java.sql.DbCleaner;
Expand Down Expand Up @@ -91,6 +88,8 @@ default void setupForGeneratedTest(){}

MongoInsertionResultsDto execInsertionsIntoMongoDatabase(List<MongoInsertionDto> insertions);

RedisInsertionResultsDto execInsertionsIntoRedisDatabase(List<RedisInsertionDto> insertions);

/**
* <p>
* return an instance of a client of an RPC service.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
import org.evomaster.client.java.controller.api.ControllerConstants;
import org.evomaster.client.java.controller.api.Formats;
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.database.operations.*;
import org.evomaster.client.java.controller.api.dto.problem.*;
import org.evomaster.client.java.controller.api.dto.problem.param.DeriveParamResponseDto;
import org.evomaster.client.java.controller.api.dto.problem.param.DerivedParamChangeReqDto;
Expand All @@ -15,6 +12,8 @@
import org.evomaster.client.java.controller.api.dto.problem.rpc.ScheduleTaskInvocationsResult;
import org.evomaster.client.java.controller.mongo.MongoScriptRunner;
import org.evomaster.client.java.controller.problem.*;
import org.evomaster.client.java.controller.redis.RedisCommandExecutor;
import org.evomaster.client.java.controller.redis.ReflectionBasedRedisClient;
import org.evomaster.client.java.sql.QueryResult;
import org.evomaster.client.java.sql.SqlScriptRunner;
import org.evomaster.client.java.controller.problem.rpc.schema.LocalAuthSetupSchema;
Expand Down Expand Up @@ -928,4 +927,62 @@ public Response executeMongoInsertion(MongoDatabaseCommandDto dto, @Context Http
sutController.setExecutingInitMongo(false);
}
}

@Path(ControllerConstants.REDIS_INSERTION)
@Consumes(Formats.JSON_V1)
@POST
public Response executeRedisInsertion(
RedisDatabaseCommandsDto dto,
@Context HttpServletRequest httpServletRequest) {

assert trackRequestSource(httpServletRequest);

try {
sutController.setExecutingInitRedis(true);

ReflectionBasedRedisClient connection =
noKillSwitch(sutController::getRedisConnection);

if (connection == null) {
String msg = "No active Redis 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();
}

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

if (!redisResultsDto.executionResults.isEmpty()) {
return Response.status(200)
.entity(WrappedResponseDto.withData(redisResultsDto)).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.setExecutingInitRedis(false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@
import org.evomaster.client.java.controller.api.dto.constraint.ElementConstraintsDto;
import org.evomaster.client.java.controller.api.dto.database.execution.SqlExecutionsDto;
import org.evomaster.client.java.controller.api.dto.database.execution.SqlExecutionLogDto;
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.operations.*;
import org.evomaster.client.java.controller.api.dto.database.schema.DbInfoDto;
import org.evomaster.client.java.controller.api.dto.database.schema.ExtraConstraintsDto;
import org.evomaster.client.java.controller.api.dto.MockDatabaseDto;
Expand All @@ -30,6 +27,7 @@
import org.evomaster.client.java.controller.api.dto.problem.rpc.RPCTestDto;
import org.evomaster.client.java.controller.internal.db.OpenSearchHandler;
import org.evomaster.client.java.controller.internal.db.redis.RedisHandler;
import org.evomaster.client.java.controller.redis.RedisCommandExecutor;
import org.evomaster.client.java.controller.redis.ReflectionBasedRedisClient;
import org.evomaster.client.java.sql.DbCleaner;
import org.evomaster.client.java.sql.SqlScriptRunner;
Expand Down Expand Up @@ -299,6 +297,17 @@ public MongoInsertionResultsDto execInsertionsIntoMongoDatabase(List<MongoInsert
}
}

@Override
public RedisInsertionResultsDto execInsertionsIntoRedisDatabase(
List<RedisInsertionDto> insertions) {

ReflectionBasedRedisClient connection = getRedisConnection();
if (connection == null) {
throw new IllegalStateException("No connection to Redis");
}
return RedisCommandExecutor.executeInsert(connection, insertions);
}

public int getActionIndex(){
return actionIndex;
}
Expand Down Expand Up @@ -379,6 +388,7 @@ public final boolean doEmploySmartDbClean(){
public final void resetExtraHeuristics() {
sqlHandler.reset();
mongoHandler.reset();
redisHandler.reset();
}

/**
Expand Down Expand Up @@ -548,7 +558,7 @@ public final void computeOpenSearchHeuristics(ExtraHeuristicsDto dto, List<Addit
}

public final void computeRedisHeuristics(ExtraHeuristicsDto dto, List<AdditionalInfo> additionalInfoList){
if(redisHandler.isCalculateHeuristics()){
if (redisHandler.isCalculateHeuristics()) {
if(!additionalInfoList.isEmpty()) {
AdditionalInfo last = additionalInfoList.get(additionalInfoList.size() - 1);
last.getRedisCommandData().forEach(it -> {
Expand All @@ -573,6 +583,10 @@ public final void computeRedisHeuristics(ExtraHeuristicsDto dto, List<Additional
))
.forEach(h -> dto.heuristics.add(h));
}

if (redisHandler.isExtractRedisExecution()) {
dto.redisExecutionsDto = redisHandler.getExecutionDto();
}
}

/**
Expand Down Expand Up @@ -1609,6 +1623,8 @@ public abstract List<TargetInfo> getTargetInfos(Collection<Integer> ids,

public abstract void setExecutingInitMongo(boolean executingInitMongo);

public abstract void setExecutingInitRedis(boolean executingInitRedis);

public abstract void setExecutingAction(boolean executingAction);


Expand Down
Loading
Loading