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

[FLINK-5092] Add maven profile with code coverage report generation #2836

Closed
wants to merge 4 commits into from

Conversation

BorisOsipov
Copy link

@BorisOsipov BorisOsipov commented Nov 21, 2016

Thanks for contributing to Apache Flink. Before you open your pull request, please take the following check list into consideration.
If your changes take all of the items into account, feel free to open your pull request. For more information and/or questions please refer to the How To Contribute guide.
In addition to going through the list, please provide a meaningful description of your changes.

  • General

    • The pull request references the related JIRA issue ("[FLINK-XXX] Jira title text")
    • The pull request addresses only one issue
    • Each commit in the PR has a meaningful commit message (including the JIRA id)
  • Documentation

    • Documentation has been added for new functionality
    • Old documentation affected by the pull request has been updated
    • JavaDoc for public methods has been added
  • Tests & Build

    • Functionality added by the pull request is covered by tests
    • mvn clean verify has been executed successfully locally or a Travis build has passed

I hope it's nice to have ability to collect test coverage.

Copy link
Contributor

@mxm mxm left a comment

Choose a reason for hiding this comment

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

Thanks for your contribution @BorisOsipov! Looks good. I would prefer is we changed the argLine definitions as little as possible. That's why I would like to just use the late property evaluation once in the parent POM and let that be inherited by all Surefire configurations.

pom.xml Outdated
<log4j.configuration>${log4j.configuration}</log4j.configuration>
</systemPropertyVariables>
<argLine>-Xms256m -Xmx800m -Dmvn.forkNumber=${surefire.forkNumber} -XX:-UseGCOverheadLimit</argLine>
<!-- Do not define argLine here. See http://www.eclemma.org/jacoco/trunk/doc/prepare-agent-mojo.html -->
Copy link
Contributor

Choose a reason for hiding this comment

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

That's bound to cause problems because a lot of code assumes these arguments here. We shouldn't touch them and instead do as the documentation you linked suggested:

One of the ways to do this in case of maven-surefire-plugin - is to use syntax for late property evaluation:

<argLine>@{argLine} -Xms256m -Xmx800m -Dmvn.forkNumber=${surefire.forkNumber} -XX:-UseGCOverheadLimit</argLine>

pom.xml Outdated
@@ -93,6 +93,7 @@ under the License.
<flink.forkCount>1C</flink.forkCount>
<flink.reuseForks>true</flink.reuseForks>
<log4j.configuration>log4j-test.properties</log4j.configuration>
<argLine>-Xms256m -Xmx800m -XX:-UseGCOverheadLimit</argLine>
Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer if the argline configuration stayed as is. It is missing the fork number here. This requires us to manually insert it for all modules which rely on it.

<argLine>-Xms256m -Xmx2800m -Dmvn.forkNumber=${surefire.forkNumber} -XX:-UseGCOverheadLimit</argLine>
<systemPropertyVariables>
<mvn.forkNumber>0${surefire.forkNumber}</mvn.forkNumber>
</systemPropertyVariables>
Copy link
Contributor

Choose a reason for hiding this comment

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

We can just remove all argLine definition here along with the forkNumber definition. They are already defined in the parent pom.

<argLine>-Xms256m -Xmx1000m -Dlog4j.configuration=${log4j.configuration} -Dmvn.forkNumber=${surefire.forkNumber} -XX:-UseGCOverheadLimit</argLine>
<systemPropertyVariables>
<mvn.forkNumber>0${surefire.forkNumber}</mvn.forkNumber>
</systemPropertyVariables>
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here.

<argLine>-Xms256m -Xmx1000m -Dlog4j.configuration=${log4j.configuration} -Dmvn.forkNumber=${surefire.forkNumber} -XX:-UseGCOverheadLimit</argLine>
<systemPropertyVariables>
<mvn.forkNumber>0${surefire.forkNumber}</mvn.forkNumber>
</systemPropertyVariables>
Copy link
Contributor

Choose a reason for hiding this comment

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

And here (see above).

Copy link
Contributor

@mxm mxm left a comment

Choose a reason for hiding this comment

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

A few minor comments. Then we should be ready to merge.

pom.xml Outdated
@@ -93,7 +93,7 @@ under the License.
<flink.forkCount>1C</flink.forkCount>
<flink.reuseForks>true</flink.reuseForks>
<log4j.configuration>log4j-test.properties</log4j.configuration>
<argLine>-Xms256m -Xmx800m -XX:-UseGCOverheadLimit</argLine>
<argLine> </argLine>
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not needed anymore.

pom.xml Outdated
@@ -996,10 +996,9 @@ under the License.
<reuseForks>${flink.reuseForks}</reuseForks>
<systemPropertyVariables>
<forkNumber>0${surefire.forkNumber}</forkNumber>
<mvn.forkNumber>0${surefire.forkNumber}</mvn.forkNumber>
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, this is probably fine. Could you re-add this line and remove the parameter from the the argLine?

<systemPropertyVariables>
<mvn.forkNumber>0${surefire.forkNumber}</mvn.forkNumber>
</systemPropertyVariables>
<argLine>-Xms256m -Xmx1000m -Dlog4j.configuration=${log4j.configuration} -XX:-UseGCOverheadLimit</argLine>
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this can be reduced to

<argLine>@{argLine} -Xmx1000m</argLine>

<systemPropertyVariables>
<mvn.forkNumber>0${surefire.forkNumber}</mvn.forkNumber>
</systemPropertyVariables>
<argLine>-Xms256m -Xmx1000m -Dlog4j.configuration=${log4j.configuration} -XX:-UseGCOverheadLimit</argLine>
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this can be reduced to

<argLine>@{argLine} -Xmx1000m</argLine>

<systemPropertyVariables>
<mvn.forkNumber>0${surefire.forkNumber}</mvn.forkNumber>
</systemPropertyVariables>
<argLine>-Xms256m -Xmx2800m -Dmvn.forkNumber=${surefire.forkNumber} -XX:-UseGCOverheadLimit</argLine>
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this can be reduced to

<argLine>@{argLine} -Xmx2800m</argLine>

@BorisOsipov
Copy link
Author

@mxm Thank you for review. I ran into some issues with collecting coverage data.
I am going to do additional tests and come back to you.

@BorisOsipov
Copy link
Author

@mxm
I tried to use late property evaluation approach in argLine.
Unfortunately, it doesn't work well with different profiles. In some cases it breaks test run by maven without a coverage profile. In other case it breaks run tests from IDE.
Finally, I came back to the first version with argLine as property. I tested it with\without coverage profile. I didn't find any problems or changes in tests run.
There is no problem with inheritance of Surefire configuration.
I didn't change JVM memory options in argLine to keep the current behavior as is.
I introduced mvn.forkNumber as a system property instead of the parameter in argLine.(this property is used to correct logging)

@zentol
Copy link
Contributor

zentol commented Nov 25, 2016

Has anyone actually looked in detail into the report that is generated?

@BorisOsipov
Copy link
Author

@zentol I aggregated results by SonarQube.
I can share some overall report.
flink.pdf

@zentol
Copy link
Contributor

zentol commented Nov 25, 2016

If i ran this myself, could i see which lines are not covered?

@BorisOsipov
Copy link
Author

BorisOsipov commented Nov 25, 2016

You can find report in ${project.basedir}/target/jacoco-report folder.

Copy link
Contributor

@mxm mxm left a comment

Choose a reason for hiding this comment

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

If late property binding does not work, let's use the property. Could you add a comment for the property? It seems to be an undocumented feature of Surefire. It is hard to guess that setting a property influences the configuration of a Maven plugin?

By the way, the forkNumber is used for logging but also other purposes (using it as an offset for port bindings to prevent collisions).

@zentol
Copy link
Contributor

zentol commented Nov 25, 2016

The plugin cannot detect cross-module coverage, correct? as in, all the tests in flink-tests will not contribute in any way to the coverage of other modules?

@mxm
Copy link
Contributor

mxm commented Nov 25, 2016 via email

@BorisOsipov
Copy link
Author

@zentol Yes plugin cannot detect out of box cross-module coverage, but there are some tricks how it could be done.

I've implemented and tested one of them.
I squash older commits and split my works to two commits.
The first one adds coverage plugin and change surefire configuration.
The second one adds:

  • new maven submodule for coverage report aggregation.
  • change shade maven plugin configuration. When tests run with coverage profile shaded jar doesn't replace original jar(shadedArtifactAttached=true). It needs because maven-shade-plugin changes class files and it makes impossible coverage reports aggregations, because jacoco requires the same classes on data collecting and report phases.

Changes in shade configuration made some test broken:

  • ClassLoaderITCase
  • ZooKeeperLeaderElectionITCase
  • JobManagerHACheckpointRecoveryITCase

I investigate that they cannot run correctly without shading and there is no way to fix it.
I think it is not a big problem.

So you can get full coverage report by running command mvn clean install -Pcoverage -Dmaven.test.failure.ignore=true and open flink/flink-test-utils-parent/flink-test-utils-coverage/target/site/jacoco-aggregate/index.html

What do you think about these changes?
I glad to answer you questions if you have

@zentol
Copy link
Contributor

zentol commented Dec 16, 2016

I will try this out on the weekend and report back :)

@BorisOsipov
Copy link
Author

Pay attention that Jacoco does not support parallel test execution. Your experiment will be longer than usual full tests execution

@BorisOsipov
Copy link
Author

@zentol Hi. Any news?

@zentol
Copy link
Contributor

zentol commented Jan 17, 2017

@BorisOsipov i haven't found time yet to try this out :(

The long running time makes it tricky since you devote the machine completely to tests for hours. I could let it run over night though ... frankly, i haven't considered that option yet for some reason.

Will try that tonight.

@zentol
Copy link
Contributor

zentol commented Jan 18, 2017

I let it run overnight but a test failure caused the build to lockup :(
Will disable the test and try again this evening.

@kenmy
Copy link

kenmy commented Jan 18, 2017

I have tryed to collect coverage by this approach.
During my attempt I rebased this PR into e187b5e (master in apach/flink at the yesterday evening). And share result via gdrive.
My branch is here. I am not sure that did anything right because haven't checked added projects since this PR. I hope is will help to resolve conflicts faster.

@zentol
Copy link
Contributor

zentol commented Jan 18, 2017

@kenmy Thank you, this helped me a lot :)

@BorisOsipov From a quick glance the aggregation appears to be working.

This is really cool stuff. We'll have to go through the pom changes again, maybe @rmetzger can help here. But i wanna get this in. :)

Some thoughts:

  • Is there a way to exclude certain files? We have some generated code (Tuple classes), and it's a bit funky for scala code (specifically case classes).
  • Is there a way to see how often a given line was tested? (Could maybe be useful for test deduplication)

@BorisOsipov
Copy link
Author

@zentol

Is there a way to exclude certain files?

Sure. It setups like in other plugins by include\exclude section in plugin configuration.

Is there a way to see how often a given line was tested?

Unfortunately no. All available coverage counters described here http://www.eclemma.org/jacoco/trunk/doc/counters.html

@zentol
Copy link
Contributor

zentol commented Jan 18, 2017

Ok, cool. We should certainly exclude classes under "org.apache.flink.runtime.messages".

I'll have to dig through the report some more to find others, but i guess we can add them later on too.

@@ -364,6 +363,18 @@ under the License.
</transformers>
</configuration>
</execution>
<execution>
<id>shade-flink</id>
Copy link
Contributor

Choose a reason for hiding this comment

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

With this we execute the shade-plugin also for other build-profiles, correct? (same for flink-examples/flink-examples-streaming) It would be cool if this would only be done when creating the coverage report, so that the normal build-time is unaffected.

Copy link
Author

Choose a reason for hiding this comment

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

The maven's philosophy is 'one artifact per project'. These projects don't follow this way and produce several jar's artifacts :)
Shade plugin should produce flink-storm-streaming_2.10-1.2-SNAPSHOT-shaded.jar but it doesn't do it. It is a problem for maven install plugin that wants to have such jar by default. And it leads to failure on install phase without such configuration changes. For this reason I added such changes.

So I propose don't collect test coverage for these projects (flink-storm and streaming examples) at all. What do you think?

Boris Osipov added 3 commits February 3, 2017 11:52
- add maven profile 'coverage' with maven jacoco plugin
- extract argLine from surefire configuration to project properties
- add module for tests coverage report aggregating
- add option for disabling replacing original jar with shaded one
@BorisOsipov
Copy link
Author

@zentol I've rebased pr and excluded mentioned above flink-examples-streaming and flink-storm-examples modules.

@BorisOsipov BorisOsipov closed this Feb 4, 2017
@BorisOsipov BorisOsipov reopened this Feb 4, 2017
@@ -65,6 +68,7 @@ under the License.
<goal>shade</goal>
</goals>
<configuration combine.self="override">
<shadedArtifactAttached>${shade.shadedArtifactAttached}</shadedArtifactAttached>
Copy link
Contributor

Choose a reason for hiding this comment

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

Why can't we define this in the parent pom globally for all shade plugin instances?

<profile>
<id>coverage</id>
<modules>
<module>flink-examples-batch</module>
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are the streaming examples not in the module list?

There is a separate "flink-test-utils-coverage" package that expects the all flink packages
have built before.
We need to depend on all modules if we want to get full coverage report
including coverage from tests in flink-tests module.
Copy link
Contributor

Choose a reason for hiding this comment

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

tabs vs spaces for indentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants