Skip to content

Conversation

Markoutte
Copy link
Collaborator

Description

Introduces provider to generate collections with generic types. Now, fuzzer creates tests with values for such types as Collection<Integer>, Map<MyClass, String>, and recursive types like: Collection<List<Double>>, Map<String, Set<Integer>>.

Fixes #875

Type of Change

  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

How Has This Been Tested?

Automated Testing

Run:

org.utbot.framework.plugin.api.ModelProviderTest
org.utbot.framework.plugin.api.CollectionModelProviderTest

Manual Scenario

Here several examples which can be tested:

public class CollectionExample {

    /**
     * Should create unsorted list that will be sorted as a result.
     */
    public static <T extends Number> Collection<T> sorted(Collection<T> source) {
        return source.stream().sorted().collect(Collectors.toList());
    }

    /**
     * Should create at least both answers: one that finds the key, and another returns null.
     */
    public static String getKeyForValue(Map<String, Number> map, Number value) {
        for (Map.Entry<String, Number> entry : map.entrySet()) {
            if (Objects.equals(entry.getValue(), value)) {
                return entry.getKey();
            }
        }
        return null;
    }

    /**
     * Should find a branch that returns true and size of array is greater than 1 (non-trivial).
     */
    public static boolean isDiagonal(Collection<Collection<Double>> matrix) {
        int cols = matrix.size();
        if (cols <= 1) {
            return false;
        }
        int i = 0;
        for (Collection<Double> col : matrix) {
            if (col.size() != cols) {
                return false;
            }
            int j = 0;
            for (Double value : col) {
                if (i == j && value == 0.0) return false;
                if (i != j && value != 0.0) return false;
                j++;
            }
            i++;
        }
        return true;
    }

    /**
     * Checks that different collections can be created. Part 1
     */
    public boolean allCollectionAreSameSize1(
            Collection<Integer> c,
            List<Integer> l,
            Set<Integer> s,
            SortedSet<Integer> ss,
            Deque<Integer> d,
            Iterable<Integer> i
    ) {
        if (c.size() != l.size()) {
            return false;
        }
        if (l.size() != s.size()) {
            return false;
        }
        if (s.size() != ss.size()) {
            return false;
        }
        if (ss.size() != d.size()) {
            return false;
        }
        if (d.size() != StreamSupport.stream(i.spliterator(), false).count()) {
            return false;
        }
        return true;
    }

    /**
     * Checks that different collections can be created. Part 2
     */
    public boolean allCollectionAreSameSize2(
            Iterable<Integer> i,
            Stack<Integer> st,
            NavigableSet<Integer> ns,
            Map<Integer, Integer> m,
            SortedMap<Integer, Integer> sm,
            NavigableMap<Integer, Integer> nm
    ) {
        if (StreamSupport.stream(i.spliterator(), false).count() != st.size()) {
            return false;
        }
        if (st.size() != ns.size()) {
            return false;
        }
        if (ns.size() != m.size()) {
            return false;
        }
        if (m.size() != sm.size()) {
            return false;
        }
        if (sm.size() != nm.size()) {
            return false;
        }
        return true;
    }

    /**
     * Should create TreeSet without any modifications as T extends Number is not Comparable
     */
    public <T extends Number> boolean testTreeSetWithoutComparable(NavigableSet<T> set) {
        if (set.size() > 5) {
            return true;
        }
        return false;
    }

    /**
     * Should create TreeSet with modifications as Integer is Comparable
     */
    public boolean testTreeSetWithComparable(NavigableSet<Integer> set) {
        if (set.size() > 5) {
            return true;
        }
        return false;
    }

    static class ConcreteList<T> extends LinkedList<T> {}

    /**
     * Should create concrete class
     */
    public boolean testConcreteCollectionIsCreated(ConcreteList<?> list) {
        if (list.size() > 5) {
            return true;
        }
        return false;
    }

    static class ConcreteMap<K, V> extends HashMap<K, V> { }

    /**
     * Should create concrete class
     */
    public boolean testConcreteMapIsCreated(ConcreteMap<?, ?> map) {
        if (map.size() > 5) {
            return true;
        }
        return false;
    }
}

Checklist:

  • The change followed the style guidelines of the UTBot project
  • Self-review of the code is passed
  • The change contains enough commentaries, particularly in hard-to-understand areas
  • New documentation is provided or existed one is altered
  • No new warnings
  • New tests have been added
  • All tests pass locally with my changes

@Markoutte Markoutte added the comp-fuzzing Issue is related to the fuzzing label Sep 21, 2022
Copy link
Collaborator

@volivan239 volivan239 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a powerful change, but I believe there still may be some room for improving variety of created models, needs discussion.

* Added GenericArrayType
* Fixed the logic around number of generated values in recursive calls
@Markoutte Markoutte force-pushed the pelevin/875_Fuzzer_should_generate_tests_for_simple_collection_with_generic_types branch from 3ba5682 to b618d6b Compare September 23, 2022 08:26
@Markoutte Markoutte merged commit 28d1eb8 into main Sep 26, 2022
@Markoutte Markoutte deleted the pelevin/875_Fuzzer_should_generate_tests_for_simple_collection_with_generic_types branch September 26, 2022 08:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp-fuzzing Issue is related to the fuzzing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fuzzer should generate tests for simple collection with generic types

3 participants