Skip to content

Fuzzer uses erased generic types when creating user defined types #2432

Open
@IlyaMuravjov

Description

@IlyaMuravjov

Description

Fuzzer uses erased generic types when creating user defined types, for example, in the class below T is always replaced with Object, even when we test acceptStringValueHolder() method which only accepts GenericValueHolder<String>.

public class GenericValueHolder<T> {
    private final T value;
    
    public GenericValueHolder(T value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }
    
    public static void acceptStringValueHolder(GenericValueHolder<String> genericValueHolder) {}
}

To Reproduce

Run the following unit test.

@Test
fun `fuzzer correctly creates user defined parametrized types`() {
    val seenGenericValueHolders = mutableListOf<GenericValueHolder<*>>()
    var remainingRuns = 100
    runBlockingWithContext {
        runJavaFuzzing(
            TestIdentityPreservingIdGenerator,
            methodUnderTest = GenericValueHolder::class.java.declaredMethods.first { it.name == "acceptStringValueHolder" }.executableId,
            constants = emptyList(),
            names = emptyList(),
        ) { _, _, (genericValueHolder) ->
            seenGenericValueHolders.add(
                ValueConstructor().construct(listOf(genericValueHolder.model)).single().value as GenericValueHolder<*>
            )
            remainingRuns--
            BaseFeedback(Trie.emptyNode(), if (remainingRuns > 0) Control.CONTINUE else Control.STOP)
        }
    }
    val seenStrings = seenGenericValueHolders.mapNotNull { it.value }
    assertNotEquals(emptyList<String>(), seenStrings)
    seenStrings.forEach { assertInstanceOf(String::class.java, it) }
}

Expected behavior

Java Fuzzer is expected to detect Generic type (when it is defined) and generate correct instances of this type.

Actual behavior

Now Java Fuzzer doesn't take generic type into account. It generates only Object instances.

Visual proofs (screenshots, logs, images)

Unexpected type ==> expected: <java.lang.String> but was: <java.lang.Object>
Expected :java.lang.String
Actual   :java.lang.Object
<Click to see difference>

org.opentest4j.AssertionFailedError: Unexpected type ==> expected: <java.lang.String> but was: <java.lang.Object>
	at app//org.junit.jupiter.api.AssertInstanceOf.assertInstanceOf(AssertInstanceOf.java:51)
	at app//org.junit.jupiter.api.AssertInstanceOf.assertInstanceOf(AssertInstanceOf.java:35)
	at app//org.junit.jupiter.api.Assertions.assertInstanceOf(Assertions.java:3539)
	at app//org.utbot.fuzzing.JavaFuzzingTest.fuzzer correctly creates user defined parametrized types(JavaFuzzingTest.kt:325)

Metadata

Metadata

Assignees

No one assigned

    Labels

    comp-fuzzingIssue is related to the fuzzingctg-bugIssue is a buglang-javaIssue is related to Java support

    Type

    No type

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions