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

Field assertions fixes #920

Merged
merged 6 commits into from
Oct 12, 2022
Merged

Field assertions fixes #920

merged 6 commits into from
Oct 12, 2022

Conversation

Damtev
Copy link
Member

@Damtev Damtev commented Sep 13, 2022

Description

Fixes for several consecutive bugs with field assertions:

  1. Unnecessary Object type case for variables created with reflection
  2. Missed initial field states for arrays
  3. Unnecessary field state assertions for failed tests

Also, added line separator after single-line block comment.

See corresponding tests behavior in Manual Testing section.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

Automated Testing

org.utbot.examples.codegen.modifiers.ClassWithPrivateMutableFieldOfPrivateTypeTest

Manual Scenario

Consider the following code:

public class StringRegex {
    Pattern pattern = Pattern.compile("\\d{1,10}\\w");

    public String stringRegex(String str) {
        if (pattern.matcher(str).find()) {
            return str.substring(0, 2);
        } else {
            return str;
        }
    }
}

and generate tests for the method stringRegex with the following settings: [Java, JUnit4, No mocks, 60s timeout, useConcreteExecution = true].

  1. One of the generated test methods contains the following code:
stringRegex.stringRegex(null);

Pattern pattern1 = stringRegex.pattern;
Object finalStringRegexPatternCompiled = getFieldValue(pattern1, "java.util.regex.Pattern", "compiled");

Class assertClazz = Class.forName("org.junit.Assert");
Class finalStringRegexPatternCompiledType = boolean.class;
Method assertTrueMethod = assertClazz.getDeclaredMethod("assertTrue", finalStringRegexPatternCompiledType);
assertTrueMethod.setAccessible(true);
Object[] assertTrueMethodArguments = new Object[1];
assertTrueMethodArguments[0] = finalStringRegexPatternCompiled;
assertTrueMethod.invoke(null, assertTrueMethodArguments);

Here the JUnit4 method assertTrue is invoked using reflection because of variable finalStringRegexPatternCompiled with type Object.
But in this example this variable may be safely casted to its type boolean, and reflection usage for the assertTrue usage would be redundant.

So, expected code:

stringRegex.stringRegex(null);

Pattern pattern1 = stringRegex.pattern;
boolean finalStringRegexPatternCompiled = ((Boolean) getFieldValue(pattern1, "java.util.regex.Pattern", "compiled"));

assertTrue(finalStringRegexPatternCompiled);
  1. One of the generated test methods contains the following code:
stringRegex.stringRegex(null);

Pattern pattern1 = stringRegex.pattern;
int[] finalStringRegexPatternBuffer = ((int[]) getFieldValue(pattern1, "java.util.regex.Pattern", "buffer"));
Pattern pattern2 = stringRegex.pattern;
Map finalStringRegexPatternNamedGroups = ((Map) getFieldValue(pattern2, "java.util.regex.Pattern", "namedGroups"));
Pattern pattern3 = stringRegex.pattern;
Object finalStringRegexPatternGroupNodes = getFieldValue(pattern3, "java.util.regex.Pattern", "groupNodes");
Pattern pattern4 = stringRegex.pattern;
int[] finalStringRegexPatternTemp = ((int[]) getFieldValue(pattern4, "java.util.regex.Pattern", "temp"));
Pattern pattern5 = stringRegex.pattern;
int finalStringRegexPatternPatternLength = ((Integer) getFieldValue(pattern5, "java.util.regex.Pattern", "patternLength"));

assertNull(finalStringRegexPatternNamedGroups);

assertEquals(0, finalStringRegexPatternPatternLength);

There are no assertions for finalStringRegexPatternNamedGroups and finalStringRegexPatternGroupNodes because they have array types and are filtered out from initial states by mistake.

So, expected code is:

stringRegex.stringRegex(null);

Pattern pattern1 = stringRegex.pattern;
boolean finalStringRegexPatternCompiled = ((Boolean) getFieldValue(pattern1, "java.util.regex.Pattern", "compiled"));
Pattern pattern2 = stringRegex.pattern;
int[] finalStringRegexPatternBuffer = ((int[]) getFieldValue(pattern2, "java.util.regex.Pattern", "buffer"));
Pattern pattern3 = stringRegex.pattern;
Map finalStringRegexPatternNamedGroups = ((Map) getFieldValue(pattern3, "java.util.regex.Pattern", "namedGroups"));
Pattern pattern4 = stringRegex.pattern;
List finalStringRegexPatternTopClosureNodes = ((List) getFieldValue(pattern4, "java.util.regex.Pattern", "topClosureNodes"));
Pattern pattern5 = stringRegex.pattern;
int[] finalStringRegexPatternTemp = ((int[]) getFieldValue(pattern5, "java.util.regex.Pattern", "temp"));
Pattern pattern6 = stringRegex.pattern;
boolean finalStringRegexPatternHasSupplementary = ((Boolean) getFieldValue(pattern6, "java.util.regex.Pattern", "hasSupplementary"));

assertTrue(finalStringRegexPatternCompiled);

assertNull(finalStringRegexPatternBuffer);

assertNull(finalStringRegexPatternNamedGroups);

assertNull(finalStringRegexPatternTopClosureNodes);

assertNull(finalStringRegexPatternTemp);

assertTrue(finalStringRegexPatternHasSupplementary);

that contains assertions for these fields.

  1. Actually, the execution above is exception-throwing and breaks after invocation of method under test stringRegex.stringRegex(string);.
    So, all these field assertions are redundant because they will never be invoked, and the last statement of this test method has to be MUT invocation.

Checklist (remove irrelevant options):

  • 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

@Damtev Damtev added ctg-bug Issue is a bug comp-codegen Issue is related to code generator labels Sep 13, 2022
@Damtev Damtev force-pushed the damtev/field_assertions_fixes branch from ab2fd98 to 4713374 Compare September 16, 2022 09:34
@Damtev Damtev force-pushed the damtev/field_assertions_fixes branch 2 times, most recently from b05acbb to a177d4c Compare October 7, 2022 10:17
@Damtev Damtev force-pushed the damtev/field_assertions_fixes branch from a177d4c to 130f598 Compare October 7, 2022 13:23
Copy link
Collaborator

@EgorkaKulikov EgorkaKulikov left a comment

Choose a reason for hiding this comment

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

Thank you very much for fixing these problems.

@Damtev Damtev merged commit a0738ed into main Oct 12, 2022
@Damtev Damtev deleted the damtev/field_assertions_fixes branch October 12, 2022 13:53
AbdullinAM pushed a commit to AbdullinAM/UTBotJava that referenced this pull request Oct 17, 2022
* Used real variable type after field access with reflection if possible

* Added missing line separator after single-line block comment

* Added missed initial field states for arrays

* Removed field state assertions for failing tests
AbdullinAM pushed a commit to AbdullinAM/UTBotJava that referenced this pull request Oct 17, 2022
* Used real variable type after field access with reflection if possible

* Added missing line separator after single-line block comment

* Added missed initial field states for arrays

* Removed field state assertions for failing tests
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 ctg-bug Issue is a bug
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

2 participants