Skip to content
Permalink
Browse files

Merge branch 'master' into clustering

  • Loading branch information
bogdanmarculescu committed Mar 16, 2020
2 parents 10a9fe3 + f8cf7f7 commit fbb28c8cdf19fd5fdc9ea2efb0115b2be34f5871
@@ -12,9 +12,15 @@

public class ParserUtils {


/**
* We only use the selects that refer to objects in the data base that are meaninful for testing purposes,
* when code access to a sequence for example when getting the next id for a new object in the table,
* then we don't want to use that select as a target.
* @param sql
* @return
*/
public static boolean isSelect(String sql) {
return startsWithIgnoreCase(sql, "select");
return startsWithIgnoreCase(sql, "select") && !isASequence(sql);
}

public static boolean isDelete(String sql) {
@@ -33,6 +39,10 @@ private static boolean startsWithIgnoreCase(String input, String prefix){
return input!= null && input.trim().toLowerCase().startsWith(prefix);
}

private static boolean isASequence(String input) {
return input!= null && input.trim().toLowerCase().matches(".*(currval|nextval).*");
}


public static Expression getWhere(Statement statement) {

@@ -6,12 +6,14 @@
import org.evomaster.client.java.controller.api.dto.TestResultsDto;
import org.evomaster.client.java.controller.api.dto.database.execution.ExecutionDto;
import org.evomaster.client.java.controller.db.SqlScriptRunner;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;

import static io.restassured.RestAssured.given;
import static org.evomaster.client.java.controller.api.ControllerConstants.BASE_PATH;
import static org.evomaster.client.java.controller.api.ControllerConstants.TEST_RESULTS;
import static org.junit.jupiter.api.Assertions.*;
import java.sql.SQLException;

/**
* Created by arcuri82 on 24-Apr-19.
@@ -39,20 +41,7 @@ public void testDeleteTable() throws Exception {
InstrumentedSutStarter starter = getInstrumentedSutStarter();

try {
String url = start(starter);
url += BASE_PATH;

startNewTest(url);

ExecutionDto dto = getSqlExecutionDto(0,url);

assertTrue(dto == null || dto.deletedData == null || dto.deletedData.isEmpty());

startNewActionInSameTest(url, 1);

SqlScriptRunner.execCommand(getConnection(), "Delete FROM Foo");

dto = getSqlExecutionDto(1,url);
ExecutionDto dto = executeCommand(starter, "Delete FROM Foo");

assertNotNull(dto);
assertNotNull(dto.deletedData);
@@ -64,7 +53,6 @@ public void testDeleteTable() throws Exception {
}
}


@Test
public void testInsertTable() throws Exception {

@@ -73,20 +61,7 @@ public void testInsertTable() throws Exception {
InstrumentedSutStarter starter = getInstrumentedSutStarter();

try {
String url = start(starter);
url += BASE_PATH;

startNewTest(url);

ExecutionDto dto = getSqlExecutionDto(0,url);

assertTrue(dto == null || dto.insertedData == null || dto.insertedData.isEmpty());

startNewActionInSameTest(url, 1);

SqlScriptRunner.execCommand(getConnection(), "insert into Foo (x) values (42)");

dto = getSqlExecutionDto(1,url);
ExecutionDto dto = executeCommand(starter, "insert into Foo (x) values (42)");

assertNotNull(dto);
assertNotNull(dto.insertedData);
@@ -98,6 +73,7 @@ public void testInsertTable() throws Exception {
}
}


@Test
public void testUpdateTable() throws Exception {

@@ -106,28 +82,81 @@ public void testUpdateTable() throws Exception {
InstrumentedSutStarter starter = getInstrumentedSutStarter();

try {
String url = start(starter);
url += BASE_PATH;
ExecutionDto dto = executeCommand(starter, "update Foo set x=42");

assertNotNull(dto);
assertNotNull(dto.updatedData);
assertEquals(1, dto.updatedData.size());
assertTrue(dto.updatedData.containsKey("Foo"));

} finally {
starter.stop();
}
}

startNewTest(url);

ExecutionDto dto = getSqlExecutionDto(0,url);
/**
* When creating an object in a table which includes an auto-incremental id,
* then the select currval is used to calculate the id for the new object
* @throws Exception
*/
@Test
public void givenASelectNextValueInASequenceThenTheQueryIsIgnoredToCalculateHeuristics() throws Exception {

assertTrue(dto == null || dto.updatedData == null || dto.updatedData.isEmpty());
SqlScriptRunner.execCommand(getConnection(), "CREATE SEQUENCE foo_id_seq;");
SqlScriptRunner.execCommand(getConnection(), "CREATE TABLE foo (id integer NOT NULL DEFAULT nextval('foo_id_seq'));");

startNewActionInSameTest(url, 1);
InstrumentedSutStarter starter = getInstrumentedSutStarter();

SqlScriptRunner.execCommand(getConnection(), "update Foo set x=42");
try {

dto = getSqlExecutionDto(1,url);
ExecutionDto dto = executeCommand(starter, "SELECT currval('foo_id_seq')");

assertNotNull(dto);
assertNotNull(dto.updatedData);
assertEquals(1, dto.updatedData.size());
assertTrue(dto.updatedData.containsKey("Foo"));
assertNotNull(dto.queriedData);
assertEquals(0, dto.queriedData.size());

} finally {
starter.stop();
}
}

private ExecutionDto executeCommand(InstrumentedSutStarter starter, String sqlCommand) throws SQLException {
String url = startInstrumentedSutStarterAndNewTest(starter);
ExecutionDto dto = getSqlExecutionDto(0, url);

assertDataIsEmpty(dto);

startNewActionInSameTest(url, 1);

SqlScriptRunner.execCommand(getConnection(), sqlCommand);

return getSqlExecutionDto(1, url);
}

private void assertDataIsEmpty(ExecutionDto dto) {
assertUpdatedDataIsEmpty(dto);
assertDeletedDataIsEmpty(dto);
assertInsertedDataIsEmpty(dto);
}

@NotNull
private String startInstrumentedSutStarterAndNewTest(InstrumentedSutStarter starter) {
String url = start(starter);
url += BASE_PATH;
startNewTest(url);
return url;
}

private void assertUpdatedDataIsEmpty(ExecutionDto dto) {
assertTrue(dto == null || dto.updatedData == null || dto.updatedData.isEmpty());
}

private void assertDeletedDataIsEmpty(ExecutionDto dto) {
assertTrue(dto == null || dto.deletedData == null || dto.deletedData.isEmpty());
}

private void assertInsertedDataIsEmpty(ExecutionDto dto) {
assertTrue(dto == null || dto.insertedData == null || dto.insertedData.isEmpty());
}
}
@@ -10,6 +10,7 @@ import org.evomaster.core.search.service.Randomness
import org.evomaster.core.search.service.mutator.geneMutation.ArchiveMutator
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.lang.IllegalStateException


class ArrayGene<T>(
@@ -74,7 +75,11 @@ class ArrayGene<T>(


override fun isMutable(): Boolean {
//it wouldn't make much sense to have 0, but let's just be safe here
/*
if maxSize is 0, then array cannot be mutated, as it will always be empty.
If it is greater than 0, it can always be mutated, regardless of whether the
elements can be mutated: we can mutate between empty and 1-element arrays
*/
return maxSize > 0
}

@@ -99,6 +104,10 @@ class ArrayGene<T>(

override fun standardMutation(randomness: Randomness, apc: AdaptiveParameterControl, allGenes: List<Gene>) {

if(!isMutable()){
throw IllegalStateException("Cannot mutate a immutable array")
}

if(elements.isEmpty() || (elements.size < maxSize && randomness.nextBoolean(MODIFY_SIZE))){
val gene = template.copy() as T
gene.parent = this
@@ -124,6 +133,10 @@ class ArrayGene<T>(
targets: Set<Int>
) {

if(!isMutable()){
throw IllegalStateException("Cannot mutate a immutable array")
}

if (!archiveMutator.enableArchiveMutation()){
standardMutation(randomness, apc, allGenes)
return
@@ -47,6 +47,10 @@ open class ObjectGene(name: String, val fields: List<out Gene>, val refType: Str
}
}

override fun isMutable(): Boolean {
return fields.any { it.isMutable() }
}

override fun containsSameValueAs(other: Gene): Boolean {
if (other !is ObjectGene) {
throw IllegalArgumentException("Invalid gene type ${other.javaClass}")
@@ -100,7 +100,12 @@ class OptionalGene(name: String,
isActive = true
} else {

if (randomness.nextBoolean(INACTIVE)) {
if (randomness.nextBoolean(INACTIVE) || !gene.isMutable()) {
/*
the idea here is that we deactivate an element only with small
probability. however, if a gene is not mutable, the only mutation
we can do is to switch from active to inactive, and vice-versa
*/
isActive = false
} else {
gene.standardMutation(randomness, apc, allGenes)

0 comments on commit fbb28c8

Please sign in to comment.
You can’t perform that action at this time.