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
@@ -1,5 +1,7 @@
package org.evomaster.client.java.controller.redis;

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.

@aszyrej @jgaleotti shouldn't we have at least 1 E2E test to verify these new functionalities?

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.

@aszyrej @jgaleotti or is Redis support not there yet for having first E2Es on it?

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.

@arcuri82 We are creating separate PRs for adding the e2e tests (to make the PRs shorter).
Should e2e tests be included in the same PR where an experimental functionality is being added?

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.

@jgaleotti it is fine, separated PR is OK for now. but for future, make sense to have them together. can't be sure an implementation is correct if no E2E yet :)


import com.fasterxml.jackson.databind.JsonNode;

import java.util.Map;
import java.util.Set;

Expand All @@ -9,10 +11,13 @@
* Fields or members will be set depending on the type of key.
* String keys may have a String value in the future, but currently it is not needed to store that information.
* Set keys will have the set members. Hash keys will have the fields.
* JSON keys will have the parsed JSON document, needed to navigate JSONPath expressions
* (e.g. JSON.GET/JSON.ARRLEN/JSON.ARRINDEX and similar commands).
*/
public class RedisValueData {
private Map<String, String> fields;
private Set<String> members;
private JsonNode jsonValue;

public RedisValueData(Map<String, String> fields) {
this.fields = fields;
Expand All @@ -22,6 +27,10 @@ public RedisValueData(Set<String> members) {
this.members = members;
}

public RedisValueData(JsonNode jsonValue) {
this.jsonValue = jsonValue;
}


public Set<String> getMembers() {
return members;
Expand All @@ -30,4 +39,8 @@ public Set<String> getMembers() {
public Map<String, String> getFields() {
return fields;
}
}

public JsonNode getJsonValue() {
return jsonValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ void testHeuristicDistanceForStringExists() {

RedisCommand similarKeyCmd = new RedisCommand(
RedisCommand.RedisCommandType.EXISTS,
new String[]{"key<user:3>"},
new String[]{"user:3"},
true,
10
);
RedisCommand differentKeyCmd = new RedisCommand(
RedisCommand.RedisCommandType.EXISTS,
new String[]{"key<user:82bd3bff-4567-40f4-a42e-27f87276199f>"},
new String[]{"user:82bd3bff-4567-40f4-a42e-27f87276199f"},
true,
10
);
Expand Down Expand Up @@ -94,7 +94,7 @@ void testHeuristicDistanceForStringExists() {
void testResetClearsCommands() {
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.EXISTS,
new String[]{"key<user:1>"},
new String[]{"user:1"},
true,
5
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void setup() {
void testKeysPatternExactMatch() {
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.KEYS,
new String[]{"key<user*>"},
new String[]{"user*"},
true,
5
);
Expand All @@ -46,7 +46,7 @@ void testKeysPatternExactMatch() {
void testKeysPatternNoMatch() {
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.KEYS,
new String[]{"key<thiskeydoesnotexist*>"},
new String[]{"thiskeydoesnotexist*"},
true,
5
);
Expand All @@ -65,14 +65,14 @@ void testKeysPatternNoMatch() {
void testExistsCommandSimilarity() {
RedisCommand closeKey = new RedisCommand(
RedisCommand.RedisCommandType.EXISTS,
new String[]{"key<user:3>"},
new String[]{"user:3"},
true,
5
);

RedisCommand farKey = new RedisCommand(
RedisCommand.RedisCommandType.EXISTS,
new String[]{"key<abcxyz>"},
new String[]{"abcxyz"},
true,
5
);
Expand All @@ -93,7 +93,7 @@ void testExistsCommandSimilarity() {
void testHGetFieldExists() {
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.HGET,
new String[]{"key<profile>", "key<name>"},
new String[]{"profile", "name"},
true,
3
);
Expand All @@ -114,7 +114,7 @@ void testHGetFieldExists() {
void testHGetFieldNotExists() {
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.HGET,
new String[]{"key<profile>", "key<age>"},
new String[]{"profile", "age"},
true,
3
);
Expand All @@ -133,19 +133,19 @@ void testHGetFieldNotExists() {
void testHGetFieldDistance() {
RedisCommand lowerDistanceCmd = new RedisCommand(
RedisCommand.RedisCommandType.HGET,
new String[]{"key<profile>", "key<weight>"},
new String[]{"profile", "weight"},
true,
3
);
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.HGET,
new String[]{"key<profile>", "key<age>"},
new String[]{"profile", "age"},
true,
3
);
RedisCommand greaterDistanceCmd = new RedisCommand(
RedisCommand.RedisCommandType.HGET,
new String[]{"key<user>", "key<direction>"},
new String[]{"user", "direction"},
true,
3
);
Expand All @@ -168,7 +168,7 @@ void testHGetFieldDistance() {
void testSInterSetsIntersectionAndNoIntersection() {
RedisCommand cmdIntersect = new RedisCommand(
RedisCommand.RedisCommandType.SINTER,
new String[]{"key<setA>", "key<setB>"},
new String[]{"setA", "setB"},
true,
1
);
Expand All @@ -184,7 +184,7 @@ void testSInterSetsIntersectionAndNoIntersection() {

RedisCommand cmdNoIntersect = new RedisCommand(
RedisCommand.RedisCommandType.SINTER,
new String[]{"key<setC>", "key<setD>"},
new String[]{"setC", "setD"},
true,
1
);
Expand All @@ -203,7 +203,7 @@ void testSInterSetsIntersectionAndNoIntersection() {

RedisCommand cmdNoIntersectFarDistance = new RedisCommand(
RedisCommand.RedisCommandType.SINTER,
new String[]{"key<setE>", "key<setF>"},
new String[]{"setE", "setF"},
true,
1
);
Expand All @@ -225,7 +225,7 @@ void testSInterSetsIntersectionAndNoIntersection() {
void testSInterSeveralSets() {
RedisCommand cmdIntersect = new RedisCommand(
RedisCommand.RedisCommandType.SINTER,
new String[]{"key<setA>", "key<setB>", "key<setC>", "key<setD>"},
new String[]{"setA", "setB", "setC", "setD"},
true,
1
);
Expand Down Expand Up @@ -260,13 +260,13 @@ void testSInterSeveralSets() {
void testSMembersSimilarity() {
RedisCommand similar = new RedisCommand(
RedisCommand.RedisCommandType.SMEMBERS,
new String[]{"key<user:set1>"},
new String[]{"user:set1"},
true,
2
);
RedisCommand different = new RedisCommand(
RedisCommand.RedisCommandType.SMEMBERS,
new String[]{"key<orders>"},
new String[]{"orders"},
true,
2
);
Expand All @@ -288,14 +288,14 @@ void testSMembersSimilarity() {
void testGetCommandSimilarity() {
RedisCommand similar = new RedisCommand(
RedisCommand.RedisCommandType.GET,
new String[]{"key<session:1234>"},
new String[]{"session:1234"},
true,
1
);

RedisCommand different = new RedisCommand(
RedisCommand.RedisCommandType.GET,
new String[]{"key<orders>"},
new String[]{"orders"},
true,
1
);
Expand All @@ -317,7 +317,7 @@ void testGetCommandSimilarity() {
void testComputeDistanceHandlesInternalExceptionOk() {
RedisCommand malformedHGet = new RedisCommand(
RedisCommand.RedisCommandType.HGET,
new String[]{"key<profile>"},
new String[]{"profile"},
true,
3
);
Expand All @@ -338,7 +338,7 @@ void testComputeDistanceHandlesInternalExceptionOk() {
void testUnsupportedCommandTypeReturnsMaxDistance() {
RedisCommand unsupported = new RedisCommand(
RedisCommand.RedisCommandType.SET,
new String[]{"key<foo>", "key<bar>"},
new String[]{"foo", "bar"},
true,
1
);
Expand All @@ -358,7 +358,7 @@ void testUnsupportedCommandTypeReturnsMaxDistance() {
void testHGetAllCommand() {
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.HGETALL,
new String[]{"key<profile>"},
new String[]{"profile"},
true,
1
);
Expand All @@ -376,7 +376,7 @@ void testHGetAllCommand() {
void testKeyMatchAgainstEmptyDatabase() {
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.GET,
new String[]{"key<anykey>"},
new String[]{"anykey"},
true,
1
);
Expand All @@ -394,7 +394,7 @@ void testKeyMatchAgainstEmptyDatabase() {
void testKeysInvalidPatternIsHandledOk() {
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.KEYS,
new String[]{"key<[abc>"},
new String[]{"[abc"},
true,
1
);
Expand All @@ -416,7 +416,7 @@ void testKeysInvalidPatternIsHandledOk() {
void testKeysAgainstEmptyDatabase() {
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.KEYS,
new String[]{"key<user*>"},
new String[]{"user*"},
true,
1
);
Expand Down Expand Up @@ -453,7 +453,7 @@ void testSInterWithNoKeysReturnsMaxDistance() {
void testSInterAgainstEmptyDatabase() {
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.SINTER,
new String[]{"key<setA>", "key<setB>"},
new String[]{"setA", "setB"},
true,
1
);
Expand All @@ -471,7 +471,7 @@ void testSInterAgainstEmptyDatabase() {
void testSInterWithMissingSetKeyReturnsMaxDistance() {
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.SINTER,
new String[]{"key<setA>", "key<setB>"},
new String[]{"setA", "setB"},
true,
1
);
Expand All @@ -490,7 +490,7 @@ void testSInterWithMissingSetKeyReturnsMaxDistance() {
void testSInterWithAllEmptySetsReturnsMaxDistance() {
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.SINTER,
new String[]{"key<setA>", "key<setB>"},
new String[]{"setA", "setB"},
true,
1
);
Expand All @@ -510,7 +510,7 @@ void testSInterWithAllEmptySetsReturnsMaxDistance() {
void testSInterOneEmptySetAmongNonEmptySetsDoesNotThrow() {
RedisCommand cmd = new RedisCommand(
RedisCommand.RedisCommandType.SINTER,
new String[]{"key<setA>", "key<setB>"},
new String[]{"setA", "setB"},
true,
1
);
Expand Down
5 changes: 5 additions & 0 deletions client-java/instrumentation/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@
<version>${springboot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.evomaster.client.java.instrumentation;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

Expand Down Expand Up @@ -37,6 +36,16 @@ public enum RedisCommandType {
* <a href="https://redis.io/docs/latest/commands/exists/">EXISTS Documentation</a>
*/
EXISTS("exists", "mixed", true),
/**
* Runs a search query on an index and performs aggregate transformations on the results.
* <a href="https://redis.io/docs/latest/commands/ft.aggregate/">FT.AGGREGATE Documentation</a>
*/
FT_AGGREGATE("ft.aggregate", "search", true),
/**
* Searches the index with a textual query, returning either documents or just ids.
* <a href="https://redis.io/docs/latest/commands/ft.search/">FT.SEARCH Documentation</a>
*/
FT_SEARCH("ft.search", "search", true),
/**
* Get the value of key.
* <a href="https://redis.io/docs/latest/commands/get/">GET Documentation</a>
Expand All @@ -52,6 +61,13 @@ public enum RedisCommandType {
* <a href="https://redis.io/docs/latest/commands/hgetall/">HGETALL Documentation</a>
*/
HGETALL("hgetall", "hash", true),
/**
* Sets the specified fields to their respective values in the hash stored at key.
* This command overwrites the values of specified fields that exist in the hash.
* If key doesn't exist, a new key holding a hash is created.
* <a href="https://redis.io/docs/latest/commands/hset/">HSET Documentation</a>
*/
HSET("hset", "hash", false),
/**
* Increments the number stored at key by one.
* If the key does not exist, it is set to 0 before performing the operation.
Expand All @@ -60,13 +76,6 @@ public enum RedisCommandType {
* This operation is limited to 64-bit signed integers.
* <a href="https://redis.io/docs/latest/commands/incr/">INCR Documentation</a>
*/
HSET("hset", "hash", false),
/**
* Sets the specified fields to their respective values in the hash stored at key.
* This command overwrites the values of specified fields that exist in the hash.
* If key doesn't exist, a new key holding a hash is created.
* <a href="https://redis.io/docs/latest/commands/hset/">HSET Documentation</a>
*/
INCR("incr", "string", false),
/**
* Returns all keys matching pattern.
Expand Down Expand Up @@ -181,8 +190,7 @@ public boolean shouldCalculateHeuristic() {
private final RedisCommandType type;

/**
* Keys or values used in query. Keys are used in most queries. Values are used in Set commands.
* Keys are wrapped in {@literal key<...>} while values in {@literal value<...>}
* Already-parsed argument values, in the order the command received them.
*/
private final String[] args;

Expand Down Expand Up @@ -215,11 +223,7 @@ public String[] getArgs() {
}

public List<String> extractArgs(){
List<String> parameters = new ArrayList<>();
for(String arg : args){
parameters.add(arg.substring(arg.indexOf('<')+1, arg.indexOf('>')));
}
return parameters;
return Arrays.asList(args);
}

public boolean getSuccessfullyExecuted() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public static List<MethodReplacementClass> getList() {
new ByteClassReplacement(),
new CharacterClassReplacement(),
new CollectionClassReplacement(),
new ConnectionClassReplacement(),
new CqlSessionClassReplacement(),
new CursorPreparerClassReplacement(),
new DateClassReplacement(),
Expand Down
Loading
Loading