Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
76bb1fb
Merge branch 'master' into feature/cql-heuristics-calculator
gonzalotguerrero Jun 19, 2026
92aa301
First calculator draft
gonzalotguerrero Jun 24, 2026
56c806a
Merge branch 'master' into feature/cql-heuristics-calculator
gonzalotguerrero Jun 24, 2026
c80e69d
Merge branch 'feature/cql-query-parser' into feature/cql-heuristics-c…
gonzalotguerrero Jun 30, 2026
6b6ad91
Fix comparison of time-related values
gonzalotguerrero Jun 30, 2026
059e9a5
Improve test class coverage
gonzalotguerrero Jun 30, 2026
8455eb6
Add support for integer constants in time-related types
gonzalotguerrero Jun 30, 2026
b6e870b
Merge branch 'master' into feature/cql-heuristics-calculator
gonzalotguerrero Jul 1, 2026
a796494
Created CassandraOperationEvaluator
gonzalotguerrero Jul 1, 2026
bcf43e2
Minor refactorings
gonzalotguerrero Jul 1, 2026
6dd2267
Add more replacements for overloaded execute method
gonzalotguerrero Jul 6, 2026
ec7e7f3
Add separate fields for keyspace and table in ExecutedCqlCommand
gonzalotguerrero Jul 6, 2026
d28282c
Merge branch 'master' into feature/cql-heuristics-calculator
gonzalotguerrero Jul 6, 2026
f8ccc59
Merge branch 'master' into feature/cql-session-replacement-v2
gonzalotguerrero Jul 6, 2026
f61c578
Merge branch 'feature/cql-heuristics-calculator' into feature/cql-ses…
gonzalotguerrero Jul 6, 2026
288be95
PR review comments
gonzalotguerrero Jul 8, 2026
8a566ee
Improve CqlParserUtils
gonzalotguerrero Jul 8, 2026
c9028dd
Merge branch 'master' into feature/cql-heuristics-calculator
gonzalotguerrero Jul 8, 2026
d19881f
Divide regex to improve readability
gonzalotguerrero Jul 9, 2026
5263ce5
Merge branch 'feature/cql-heuristics-calculator' into feature/cql-ses…
gonzalotguerrero Jul 9, 2026
432b4c7
Merge pull request #1629 from WebFuzzing/feature/cql-session-replacem…
arcuri82 Jul 10, 2026
2cc704e
Evaluator and parsers refactorings
gonzalotguerrero Jul 13, 2026
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
5 changes: 5 additions & 0 deletions client-java/controller/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@
<artifactId>libthrift</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.cassandra</groupId>
<artifactId>java-driver-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>bson</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package org.evomaster.client.java.controller.cassandra.calculator;

import org.evomaster.client.java.controller.cassandra.model.CassandraRow;
import org.evomaster.client.java.controller.cassandra.operations.CqlQueryOperation;
import org.evomaster.client.java.controller.cassandra.parser.CqlParserUtils;
import org.evomaster.client.java.distance.heuristics.DistanceHelper;
import org.evomaster.client.java.distance.heuristics.Truthness;
import org.evomaster.client.java.distance.heuristics.TruthnessUtils;

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

/**
* Calculator designed to compute a branch-distance-based heuristic for a CQL (Cassandra Query Language) query,
* given the rows returned by executing that query against the database.
* <p>
* The distance reflects how far the query's WHERE condition is from being satisfied by
* the available data and is used to guide the search towards inserting data in the database
* that makes the executed queries return non-empty results during the execution of generated tests.
*/
public class CassandraHeuristicsCalculator {
Comment thread
jgaleotti marked this conversation as resolved.

public static final double C = DistanceHelper.H_NOT_NULL;
public static final double C_BETTER = 0.15;

public static final Truthness TRUE_TRUTHNESS = new Truthness(1.0, C);
public static final Truthness FALSE_TRUTHNESS = new Truthness(C, 1.0);
public static final Truthness FALSE_TRUTHNESS_BETTER = new Truthness(C_BETTER, 1.0);

private final CassandraOperationEvaluator evaluator = new CassandraOperationEvaluator();

/**
* Computes the heuristic distance of the given CQL query with respect to the provided rows.
* A distance of {@code 0.0} means the query is satisfied, while values closer
* to {@code 1.0} indicate the query is further from being satisfied.
*
* @param cqlQuery the CQL query to evaluate
* @param returnedRows all rows in the table the query targets, used to evaluate how close
* the query's condition is to matching at least one row
* @return a distance value in {@code [0.0, 1.0]}, where {@code 0.0} represents the best case
*/
public double computeDistance(String cqlQuery, Iterable<CassandraRow> returnedRows) {
return 1.0 - computeHQuery(cqlQuery, returnedRows).getOfTrue();
}

private Truthness computeHQuery(String cqlQuery, Iterable<CassandraRow> returnedRows) {
if (!CqlParserUtils.canParseCqlCommand(cqlQuery)) {
return FALSE_TRUTHNESS;
}

List<CassandraRow> rows = toList(returnedRows);

org.evomaster.client.java.controller.cassandra.parser.CqlParser.RootContext root =
CqlParserUtils.parseCqlCommand(cqlQuery);
CqlQueryOperation whereOp = CqlParserUtils.getWhereOperation(root);

Truthness hRowSet = computeHRowSet(rows);

if (whereOp == null) {
return hRowSet;
}

Truthness hCondition = computeHCondition(whereOp, rows);
return TruthnessUtils.buildAndAggregationTruthness(hRowSet, hCondition);
}

private Truthness computeHRowSet(List<CassandraRow> rows) {
return TruthnessUtils.getTruthnessToEmpty(rows.size()).invert();
}

private Truthness computeHCondition(CqlQueryOperation condition,
List<CassandraRow> rows) {
if (rows.isEmpty()) {
return FALSE_TRUTHNESS;
}

double maxOfTrue = 0.0;
for (CassandraRow row : rows) {
double ofTrue = evaluator.evaluate(condition, row).getOfTrue();
if (ofTrue >= 1.0) {
return TRUE_TRUTHNESS;
} else if (ofTrue > maxOfTrue) {
maxOfTrue = ofTrue;
}
}

return TruthnessUtils.buildScaledTruthness(C, maxOfTrue);
}

private static List<CassandraRow> toList(Iterable<CassandraRow> iterable) {
if (iterable instanceof List) {
return (List<CassandraRow>) iterable;
}

List<CassandraRow> list = new ArrayList<>();
for (CassandraRow row : iterable) {
list.add(row);
}
return list;
}
}
Loading
Loading