dspot icon indicating copy to clipboard operation
dspot copied to clipboard

Add support for assertNotNull

Open assadOW2 opened this issue 6 years ago • 6 comments

Characteristics

Description

This is not a bug but an improvement suggestion made by Daniel Le Berre after reviewing the generated code.

https://github.com/STAMP-project/dspot-usecases-output/blob/master/OW2/Sat4j/20181030-1515/dspot-out/org/sat4j/AmplBugSAT107.java

After line 50 ( IConstr o_testNoSolutionExists__5 = solver.addClause(clause);), we can add an assertNotNull test on o_testNoSolutionExists__5 before testing the next Assert.

For instance, thanks to Descartes, we detected that in the BugSAT34 original test, there was not a test on null, and that leaded to correct the test: https://gitlab.ow2.org/sat4j/sat4j/commit/309b935d53606fcba2f4e009da82590c993a857d

What we did manually could be done automatically and kill extreme mutants generated by Descartes.

Steps to reproduce

Properties file
project=.
src=src/main/java/
testSrc=src/test/java/
Command Line / Options
java -jar target/dspot-USED-VERSION-jar-with-dependencies.jar \
-p myPropertiesFile.properties

Other files and URLs

Relationships

Help on issue template

Preview to follow the link or open file .github/ISSUE_DOC.md

assadOW2 avatar Nov 08 '18 14:11 assadOW2

Hello @assadOW2

I agree that It would be great to add this kind of assertion.

However, in DSpot, the assertions' generation is based on a java convention:

We consider that observations points are getters on existing objects inside the test. In DSpot, we defined a getter as follow:

  1. It is a public method
  2. It does not take any parameter
  3. It has a return type (non-void)
  4. It has a name that complies with a java name convention for getter, i.e. starts with get, is, should, has.

Why we do that ? Because from our point of view, getters are pures, and thus, we can rely on them to create stable assertions. During the assertions' generation, DSpot can execute multiple times the same method to collect the values, and thus if this method is not pure, DSpot is wasting its time (and we all know that DSpot is taking already to much time) because It won't be able to generate an assertion (considering the value as not deterministic).

I see two way to improve this:

  1. Instead of generating a observations point on objects, one can imagine that we observe method. In our explain we would end up with
Observation.log(this.system.addClause(new VecInt(new int[] { 1, 2, -3 }));)

instead of

Observation.log(this.system)
  1. We compute, a priori, the purity of methods and we expand the scope to all of them instead of relying on the convetion explained above.

This is a crucial point for DSpot, thank you very much !

danglotb avatar Nov 08 '18 15:11 danglotb

Hi @danglotb

My point was really the following.

The current code generated by DSpot is:

IConstr o_testNoSolutionExists__5 = solver.addClause(clause);
Assert.assertFalse(((OriginalBinaryClause) (o_testNoSolutionExists__5)).isSatisfied());
Assert.assertEquals(0.0, ((double) (((OriginalBinaryClause) (o_testNoSolutionExists__5)).getActivity())), 0.1);

Adding a simple, induced assertion to the current assertions could produce some improvements in terms of mutation score.

IConstr o_testNoSolutionExists__5 = solver.addClause(clause);
Assert.assertNonNull(o_testNoSolutionExists__5); // NEW
Assert.assertFalse(((OriginalBinaryClause) (o_testNoSolutionExists__5)).isSatisfied());
Assert.assertEquals(0.0, ((double) (((OriginalBinaryClause) (o_testNoSolutionExists__5)).getActivity())), 0.1);

That way, you get a failed assertion instead of getting an NPE in the following assertion.

danielleberre avatar Nov 08 '18 19:11 danielleberre

We can add the assertion before any block of instructions using a reference like in the example proposed by @danielleberre.

In the case we find patterns such as:

obj.getAReference().doSomething();

First transform the code:

<Type> obj_reference = obj.getAReference();
obj_reference.doSomething();

and finally:

<Type> obj_reference = obj.getAReference();
assertNonNull(obj_reference);
obj_reference.doSomething();

oscarlvp avatar Nov 15 '18 08:11 oscarlvp

Hi @danielleberre, @oscarlvp

Okay I get it now.

As described by @oscarlvp, this task can be done easily. Just need to play a little bit with the Spoon's API.

I guess your changes will appear in the eu.stamp_project.dspot.assertgenerator package and in particular in eu.stamp_project.dspot.assertgenerator.AssertBuilder#buildAssert method.

danglotb avatar Nov 15 '18 09:11 danglotb

Yep, looks good to me.

danielleberre avatar Nov 15 '18 09:11 danielleberre

For the record from the plenary meeting: Oscar works on it

monperrus avatar Jan 31 '19 08:01 monperrus