Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incomplete expected is created for classes from Java standard library #2573

Open
IlyaMuravjov opened this issue Aug 31, 2023 · 4 comments
Open
Assignees
Labels
comp-codegen Issue is related to code generator comp-instrumented-process Issue is related to Instrumented process ctg-bug Issue is a bug

Comments

@IlyaMuravjov
Copy link
Collaborator

Description

No fields of expected are set, leading to equals overridden equals returning false or crashing and assertEquals(expected, actual) failing.

To Reproduce

Generate tests for the following class

public class JavaUtils {
    public static Date getEpochStart() {
        return Date.from(Instant.EPOCH);
    }

    public static File getSomeFile() {
        return new File("file.txt");
    }

    public static BigInteger getSomeBigInteger() {
        return BigInteger.ZERO;
    }
}

Expected behavior

One passing test per method.

Actual behavior

One failing (at runtime) test per method.

public final class JavaUtilsTest {
    ///region Test suites for executable org.example.JavaUtils.getEpochStart

    ///region SYMBOLIC EXECUTION: SUCCESSFUL EXECUTIONS for method getEpochStart()

    /**
     * @utbot.classUnderTest {@link JavaUtils}
     * @utbot.methodUnderTest {@link JavaUtils#getEpochStart()}
     * @utbot.invokes {@link Date#from(java.time.Instant)}
     */
    @Test
    @DisplayName("getEpochStart: -> DateFrom")
    public void testGetEpochStart_DateFrom() {
        Date actual = JavaUtils.getEpochStart();

        Date expected = new Date();

        // java.util.Date has overridden equals method
        assertEquals(expected, actual);
    }
    ///endregion

    ///endregion

    ///region Test suites for executable org.example.JavaUtils.getSomeBigInteger

    ///region SYMBOLIC EXECUTION: SUCCESSFUL EXECUTIONS for method getSomeBigInteger()

    /**
     * @utbot.classUnderTest {@link JavaUtils}
     * @utbot.methodUnderTest {@link JavaUtils#getSomeBigInteger()}
     * @utbot.returnsFrom {@code return BigInteger.ZERO;}
     */
    @Test
    @DisplayName("getSomeBigInteger: -> return BigInteger.ZERO")
    public void testGetSomeBigInteger_ReturnBigIntegerZERO() throws Exception {
        BigInteger actual = JavaUtils.getSomeBigInteger();

        BigInteger expected = ((BigInteger) createInstance("java.math.BigInteger"));

        // java.math.BigInteger has overridden equals method
        assertEquals(expected, actual);
    }
    ///endregion

    ///endregion

    ///region Test suites for executable org.example.JavaUtils.getSomeFile

    ///region OTHER: SUCCESSFUL EXECUTIONS for method getSomeFile()

    @Test
    public void testGetSomeFile1() throws Exception {
        File actual = JavaUtils.getSomeFile();

        File expected = ((File) createInstance("java.io.File"));

        // java.io.File has overridden equals method
        assertEquals(expected, actual);
    }
    ///endregion

    ///endregion
}

Errors:

org.opentest4j.AssertionFailedError: expected: <Thu Aug 31 15:45:57 MSK 2023> but was: <Thu Jan 01 03:00:00 MSK 1970>
	at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:151)
	at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:132)
	at org.junit.jupiter.api.AssertEquals.failNotEqual(AssertEquals.java:197)
	at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
	at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:177)
	at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1142)
	at org.example.JavaUtilsTest.testGetEpochStart_DateFrom(JavaUtilsTest.java:31)

java.lang.NullPointerException
	at java.base/java.io.WinNTFileSystem.compare(WinNTFileSystem.java:698)
	at java.base/java.io.File.compareTo(File.java:2198)
	at java.base/java.io.File.equals(File.java:2217)
	at org.junit.jupiter.api.AssertionUtils.objectsAreEqual(AssertionUtils.java:110)
	at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:181)
	at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:177)
	at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1142)
	at org.example.JavaUtilsTest.testGetSomeFile1(JavaUtilsTest.java:71)

java.lang.NullPointerException
	at java.base/java.math.BigInteger.equals(BigInteger.java:3865)
	at org.junit.jupiter.api.AssertionUtils.objectsAreEqual(AssertionUtils.java:110)
	at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:181)
	at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:177)
	at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1142)
	at org.example.JavaUtilsTest.testGetSomeBigInteger_ReturnBigIntegerZERO(JavaUtilsTest.java:54)
@IlyaMuravjov IlyaMuravjov added ctg-bug Issue is a bug comp-codegen Issue is related to code generator comp-instrumented-process Issue is related to Instrumented process labels Aug 31, 2023
@alisevych alisevych added this to the September Release milestone Sep 11, 2023
@IlyaMuravjov
Copy link
Collaborator Author

It's unclear what exactly we want to achieve here. If we set all fields, that may over inflate models and generated tests.

Quick fix:

  • mark models that have missing fields (including missing fields of fields, etc.)
  • don’t use overwritten equals() for such models (only compare fields that are present in the model)

Optional step:

  • instead of not constructing models for Java standard library classes, limit max model construction depth for these classes to like 1-3 layers

@alisevych
Copy link
Member

Additional context

The issue is reproducing in spring-petclinic project in a test on VisitController$loadPetWithVisit method.
Actual date LocalDate.now()
Expected is ((LocalDate) createInstance("java.time.LocalDate"));

So assert fails with error

expected: <0000-00-00> but was: <2023-09-18>

@tyuldashev
Copy link
Collaborator

Is it different from #94 (The engine can not handle some JDK APIs,e.g., Date) problem?

@alisevych
Copy link
Member

alisevych commented Sep 19, 2023

Is it different from #94 (The engine can not handle some JDK APIs,e.g., Date) problem?

Yes, it's a different issue.
This issue is regarding how instrumented process is creating classes. And then the model is applied in tests as the expected result of concrete execution.
While #94 is regarding symbolic engine limitations.

@alisevych alisevych removed this from the October Release milestone Sep 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comp-codegen Issue is related to code generator comp-instrumented-process Issue is related to Instrumented process ctg-bug Issue is a bug
Projects
Status: Todo
Development

No branches or pull requests

4 participants