/**
* Copyright (C) 2010-2017 Gordon Fraser, Andrea Arcuri and EvoSuite
* contributors
*
* This file is part of EvoSuite.
*
* EvoSuite is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* EvoSuite is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>.
*/
package org.evosuite.symbolic.solver.avm;
import static org.evosuite.symbolic.solver.TestSolver.solve;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.evosuite.RandomizedTC;
import org.evosuite.symbolic.expr.Comparator;
import org.evosuite.symbolic.expr.Constraint;
import org.evosuite.symbolic.expr.Expression;
import org.evosuite.symbolic.expr.IntegerConstraint;
import org.evosuite.symbolic.expr.Operator;
import org.evosuite.symbolic.expr.StringConstraint;
import org.evosuite.symbolic.expr.bv.IntegerConstant;
import org.evosuite.symbolic.expr.bv.StringBinaryComparison;
import org.evosuite.symbolic.expr.bv.StringBinaryToIntegerExpression;
import org.evosuite.symbolic.expr.bv.StringMultipleComparison;
import org.evosuite.symbolic.expr.str.StringConstant;
import org.evosuite.symbolic.expr.str.StringUnaryExpression;
import org.evosuite.symbolic.expr.str.StringVariable;
import org.evosuite.symbolic.solver.SolverTimeoutException;
import org.evosuite.symbolic.solver.avm.EvoSuiteSolver;
import org.junit.Test;
public class TestStringSearch extends RandomizedTC {
@Test
public void testEqualsTrueConstant() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "foo";
String const2 = "test";
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
StringBinaryComparison strComp = new StringBinaryComparison(strVar, Operator.EQUALS, strConst, 0L);
constraints.add(new StringConstraint(strComp, Comparator.NE, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertTrue(const2.equals(result.get("test1").toString()));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testEqualsFalseConstant() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "foo";
String const2 = "foo";
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
StringBinaryComparison strComp = new StringBinaryComparison(strVar, Operator.EQUALS, strConst, 0L);
constraints.add(new StringConstraint(strComp, Comparator.EQ, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertTrue(!const2.equals(result.get("test1").toString()));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testEqualsIgnoreCaseTrueConstant() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "foo";
String const2 = "Fest";
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
StringBinaryComparison strComp = new StringBinaryComparison(strVar, Operator.EQUALSIGNORECASE, strConst, 0L);
constraints.add(new StringConstraint(strComp, Comparator.NE, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertTrue(const2.equalsIgnoreCase(result.get("test1").toString()));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testEqualsIgnoreCaseFalseConstant() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "foo";
String const2 = "FOO";
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
StringBinaryComparison strComp = new StringBinaryComparison(strVar, Operator.EQUALSIGNORECASE, strConst, 0L);
constraints.add(new StringConstraint(strComp, Comparator.EQ, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertFalse(const2.equalsIgnoreCase(result.get("test1").toString()));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testStartsWithTrueConstant() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "foo";
String const2 = "test";
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
IntegerConstant offs_expr = new IntegerConstant(2);
ArrayList<Expression<?>> other = new ArrayList<Expression<?>>();
other.add(offs_expr);
StringMultipleComparison strComp = new StringMultipleComparison(strVar, Operator.STARTSWITH, strConst, other,
0L);
constraints.add(new StringConstraint(strComp, Comparator.NE, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertTrue((result.get("test1").toString()).startsWith(const2, 2));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testStartsWithFalseConstant() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "footest";
String const2 = "test";
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
IntegerConstant offs_expr = new IntegerConstant(3);
ArrayList<Expression<?>> other = new ArrayList<Expression<?>>();
other.add(offs_expr);
StringMultipleComparison strComp = new StringMultipleComparison(strVar, Operator.STARTSWITH, strConst, other,
0L);
constraints.add(new StringConstraint(strComp, Comparator.EQ, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertFalse((result.get("test1").toString()).startsWith(const2, 3));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testEndsWithTrueConstant() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "foo";
String const2 = "test";
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
StringBinaryComparison strComp = new StringBinaryComparison(strVar, Operator.ENDSWITH, strConst, 0L);
constraints.add(new StringConstraint(strComp, Comparator.NE, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertTrue((result.get("test1").toString()).endsWith(const2));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testEndsWithFalseConstant() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "footest";
String const2 = "test";
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
StringBinaryComparison strComp = new StringBinaryComparison(strVar, Operator.ENDSWITH, strConst, 0L);
constraints.add(new StringConstraint(strComp, Comparator.EQ, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertFalse((result.get("test1").toString()).endsWith(const2));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testContainsTrueConstant() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "foo";
String const2 = "test";
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
StringBinaryComparison strComp = new StringBinaryComparison(strVar, Operator.CONTAINS, strConst, 0L);
constraints.add(new StringConstraint(strComp, Comparator.NE, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertTrue((result.get("test1").toString()).contains(const2));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testContainsFalseConstant() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "fotesto";
String const2 = "test";
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
StringBinaryComparison strComp = new StringBinaryComparison(strVar, Operator.CONTAINS, strConst, 0L);
constraints.add(new StringConstraint(strComp, Comparator.EQ, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertFalse((result.get("test1").toString()).contains(const2));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testRegionMatchesICTrueConstant() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "teXto";
String const2 = "rtestooo";
boolean ignore_case = true;
int offset1 = 0;
int offset2 = 1;
int len = 4;
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
IntegerConstant len_expr = new IntegerConstant(len);
IntegerConstant offs_one = new IntegerConstant(offset1);
IntegerConstant offs_two = new IntegerConstant(offset2);
IntegerConstant ign_case = new IntegerConstant(ignore_case ? 1 : 0);
ArrayList<Expression<?>> other = new ArrayList<Expression<?>>();
other.add(offs_one);
other.add(offs_two);
other.add(len_expr);
other.add(ign_case);
StringMultipleComparison strComp = new StringMultipleComparison(strVar, Operator.REGIONMATCHES, strConst, other,
0L);
constraints.add(new StringConstraint(strComp, Comparator.NE, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertTrue((result.get("test1").toString()).regionMatches(ignore_case, offset1, const2, offset2, len));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testRegionMatchesICFalseConstant() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "foTESTo";
String const2 = "rtestooo";
boolean ignore_case = true;
int offset1 = 2;
int offset2 = 1;
int len = 4;
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
IntegerConstant len_expr = new IntegerConstant(len);
IntegerConstant offs_two = new IntegerConstant(offset2);
IntegerConstant offs_one = new IntegerConstant(offset1);
IntegerConstant ign_case = new IntegerConstant(ignore_case ? 1 : 0);
ArrayList<Expression<?>> other = new ArrayList<Expression<?>>();
other.add(offs_one);
other.add(offs_two);
other.add(len_expr);
other.add(ign_case);
StringMultipleComparison strComp = new StringMultipleComparison(strVar, Operator.REGIONMATCHES, strConst, other,
0L);
constraints.add(new StringConstraint(strComp, Comparator.EQ, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertFalse((result.get("test1").toString()).regionMatches(ignore_case, offset1, const2, offset2, len));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testInversionOfRegex() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var = "a+";
String regex = "aaa";
// so we need to solve it
assertFalse(var.matches(regex));
String variableName = "test1";
StringVariable strVar = new StringVariable(variableName, var);
StringConstant strConst = new StringConstant(regex);
StringBinaryComparison strComp = new StringBinaryComparison(strConst, Operator.PATTERNMATCHES, strVar, 0L);
// the constraint should evaluate to true
constraints.add(new StringConstraint(strComp, Comparator.NE, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get(variableName));
String solution = result.get(variableName).toString();
assertTrue(solution.matches(regex));
/*
* as the regex defines only one possible matching string, then the
* solution has to be equal to the regex
*/
assertEquals(regex, solution);
} catch (SolverTimeoutException e) {
fail();
}
// now let's invert them
strVar = new StringVariable(variableName, regex);
strConst = new StringConstant(var);
// the inversion should match immediately
assertTrue(regex.matches(var));
// recreate the same type of constraint
strComp = new StringBinaryComparison(strConst, Operator.PATTERNMATCHES, strVar, 0L);
constraints.clear();
constraints.add(new StringConstraint(strComp, Comparator.NE, new IntegerConstant(0)));
try {
result = solve(skr, constraints);
assertNotNull(result);
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testRegexMatchesTrue() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "test";
String const2 = "TEST";
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
StringBinaryComparison strComp = new StringBinaryComparison(strVar, Operator.PATTERNMATCHES, strConst, 0L);
constraints.add(new StringConstraint(strComp, Comparator.NE, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertTrue(result.get("test1").toString().matches(const2));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testChopOffIndexOfC() {
String var1value = "D<E\u001Exqaa:saksajij1§n";
StringVariable var1 = new StringVariable("var1", var1value);
IntegerConstant colon_code = new IntegerConstant(58);
IntegerConstant minus_one = new IntegerConstant(-1);
int colon_int_code = (int) ':';
int concrete_value = var1value.indexOf(colon_int_code);
StringBinaryToIntegerExpression index_of_colon = new StringBinaryToIntegerExpression(var1, Operator.INDEXOFC,
colon_code, (long) concrete_value);
IntegerConstraint constr1 = new IntegerConstraint(index_of_colon, Comparator.EQ, minus_one);
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
constraints.add(constr1);
EvoSuiteSolver solver = new EvoSuiteSolver();
Map<String, Object> solution;
try {
solution = solve(solver, constraints);
assertNotNull(solution);
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testInsertIndexOfC() {
String var1value = "D<E\u001Exqaasaksajij1§n";
StringVariable var1 = new StringVariable("var1", var1value);
IntegerConstant colon_code = new IntegerConstant(58);
IntegerConstant minus_one = new IntegerConstant(-1);
int colon_int_code = (int) ':';
int concrete_value = var1value.indexOf(colon_int_code);
StringBinaryToIntegerExpression index_of_colon = new StringBinaryToIntegerExpression(var1, Operator.INDEXOFC,
colon_code, (long) concrete_value);
IntegerConstraint constr1 = new IntegerConstraint(index_of_colon, Comparator.NE, minus_one);
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
constraints.add(constr1);
EvoSuiteSolver solver = new EvoSuiteSolver();
Map<String, Object> solution;
try {
solution = solve(solver, constraints);
assertNotNull(solution);
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testIndexOfC() {
String var1value = "D<E\u001E";
StringVariable var1 = new StringVariable("var1", var1value);
IntegerConstant colon_code = new IntegerConstant(35);
IntegerConstant numeral_code = new IntegerConstant(58);
IntegerConstant minus_one = new IntegerConstant(-1);
StringBinaryToIntegerExpression index_of_colon = new StringBinaryToIntegerExpression(var1, Operator.INDEXOFC,
colon_code, -1L);
StringBinaryToIntegerExpression index_of_numeral = new StringBinaryToIntegerExpression(var1, Operator.INDEXOFC,
numeral_code, -1L);
IntegerConstraint constr1 = new IntegerConstraint(index_of_colon, Comparator.EQ, minus_one);
IntegerConstraint constr2 = new IntegerConstraint(index_of_numeral, Comparator.NE, minus_one);
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
constraints.add(constr1);
constraints.add(constr2);
EvoSuiteSolver solver = new EvoSuiteSolver();
Map<String, Object> solution;
try {
solution = solve(solver, constraints);
assertNotNull(solution);
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testRegexMatchesFalse() {
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
String var1 = "testsomestring";
String const2 = "testsomestring";
StringVariable strVar = new StringVariable("test1", var1);
StringConstant strConst = new StringConstant(const2);
StringBinaryComparison strComp = new StringBinaryComparison(strVar, Operator.PATTERNMATCHES, strConst, 0L);
constraints.add(new StringConstraint(strComp, Comparator.EQ, new IntegerConstant(0)));
EvoSuiteSolver skr = new EvoSuiteSolver();
Map<String, Object> result;
try {
result = solve(skr, constraints);
assertNotNull(result);
assertNotNull(result.get("test1"));
assertFalse("Result should not match TEST: " + result.get("test1").toString(),
result.get("test1").toString().matches(const2));
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testEqualsToLowerCase() {
// (wed equals var1("f|").toLowerCase()) != 0
StringVariable var1 = new StringVariable("var1", "f|");
StringBinaryComparison cmp3 = new StringBinaryComparison(new StringConstant("wed"), Operator.EQUALS,
new StringUnaryExpression(var1, Operator.TOLOWERCASE, "f|".toLowerCase()), 0L);
StringConstraint constr3 = new StringConstraint(cmp3, Comparator.NE, new IntegerConstant(0));
Collection<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
constraints.add(constr3);
EvoSuiteSolver solver = new EvoSuiteSolver();
Map<String, Object> solution;
try {
solution = solve(solver, constraints);
assertNotNull(solution);
} catch (SolverTimeoutException e) {
fail();
}
}
@Test
public void testIndexOfC2() {
String var1value = ":cc]#0l";
StringVariable var1 = new StringVariable("var0", var1value);
IntegerConstant colon_code = new IntegerConstant(58);
IntegerConstant numeral_code = new IntegerConstant(35);
IntegerConstant minus_one = new IntegerConstant(-1);
StringBinaryToIntegerExpression index_of_colon = new StringBinaryToIntegerExpression(var1, Operator.INDEXOFC,
colon_code, -1L);
StringBinaryToIntegerExpression index_of_numeral = new StringBinaryToIntegerExpression(var1, Operator.INDEXOFC,
numeral_code, -1L);
/*
* Here we are trying to modify the string such that the first '#' comes
* before the first ':', and both are present
*/
IntegerConstraint constr1 = new IntegerConstraint(index_of_colon, Comparator.NE, minus_one);
IntegerConstraint constr2 = new IntegerConstraint(index_of_numeral, Comparator.NE, minus_one);
IntegerConstraint constr3 = new IntegerConstraint(index_of_numeral, Comparator.LT, index_of_colon);
List<Constraint<?>> constraints = new ArrayList<Constraint<?>>();
constraints.add(constr1);
constraints.add(constr2);
constraints.add(constr3);
EvoSuiteSolver solver = new EvoSuiteSolver();
Map<String, Object> solution = null;
try {
/*
* The constraint is not trivial, as there are search plateaus. So
* it is ok if sometimes it fails (tried 10 times, failed 3).
*/
final int TRIES = 20;
for (int i = 0; i < TRIES; i++) {
solution = solve(solver, constraints);
if (solution != null) {
break;
}
}
assertNotNull(solution);
String result = solution.get("var0").toString();
int colonPos = result.indexOf(':');
int numeralPos = result.indexOf('#');
assertTrue("Colon not found in " + result, colonPos >= 0);
assertTrue("Numeral not found in " + result, numeralPos >= 0);
assertTrue(colonPos > numeralPos);
} catch (SolverTimeoutException e) {
fail();
}
}
}