Test generation for Optional<T> in the plugin (#226) #305
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Added a check for overridden classes in
shouldMock
to avoid access to engine classes that are not available in the plugin.Implemented more accurate speculative marking of final fields as not null to avoid losing paths involving
Optional.empty()
,to enable NPE checks for final fields in user code, and to avoid generating non-informative NPE tests for final fields in system
classes.
UtSettings.checkNpeForFinalFields
is now set default (false
) inAbstractTestCaseGEneratorTest
andSummaryTestCaseGeneratorTest
.Fixes #226
Details
There were two issues with test generation for
Optional<T>
.The
shouldMock
function tried to load overridden classes (in particular,UtOptional
) and failed as the entireorg.utbot.engine.overrides
package is not included in theUtContext
class loader created by the plugin.This commit fixes the problem an explicit check for overridden classes in
shouldMock
.Execution paths involving
Optional.empty()
were lost. This was caused by the assumption that all final fieldscan be considered non-nullable to reduce the number of irrelevant NPE execution paths, especially in system classes,
that can usually be reproduced only by reflection.
The
Optional
class is different from most other system classes as it usesnull
as the marker of the empty value in its final field. The "non-nullable final" optimization leads to discarding execution paths withOptional.empty()
as UNSAT, as the finalvalue
field should be bothnull
(explicit assignment) andnot null
(assumption for final fields).This commit introduces a new memory array to track final fields. For each NPE branch, the "value is null" condition is augmented by the "field is not final" condition. As a result, NPE branches for final fields are discarded with UNSAT, while non-final fields are not affected. The finality check is enabled for system classes only, and may be turned off by setting
UtSettings.checkNpeForFinalFields
totrue
.Type of Change
This commit changes the default behavior of the engine with respect to final fields nullability assumptions.
Previous behavior:
null
values for final fields are not allowed.null
value are discarded even if they are legitimate. No NPE tests are generated.New behavior:
null
values for final fields are allowed.Optional.empty()
bug and any similar bugs if they exist), but can be allowed by settingUtSettings.checkNpeForFinalFields
totrue
.How Has This Been Tested?
Automated Testing
The
UtSettings.checkNpeForFinalFields = true
setting was previously used to allow NPE branch generation for final fields inutbot-framework
unit tests. Setting it tofalse
would break some tests.This commit turns off this special mode, so
utbot-framework
use the same settings w.r.t. final fields nullability as the plugin. No new test failures have been detected in this mode.A new test case was added:
org.utbot.examples.collections.OptionalsTest#testOptionalOfPositive
.Manual Scenario
Generate tests for the following examples using the plugin.
Optional.empty()
For both methods, two tests should be generated, one expecting a non-empty value, and one expecting the
Optional.empty()
result. No NPE tests should be generated.NPE checks for application classes
Two tests should be generated: a test for
shift != null
and a NPE test (shift == null
).Checklist (remove irrelevant options):