Skip to content

Fuzzer should generate tests for simple collection with generic types #875 #988

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

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