JenkinsPipelineUnit icon indicating copy to clipboard operation
JenkinsPipelineUnit copied to clipboard

Modify Loader to enable Cobertura code coverage

Open idij opened this issue 6 years ago • 4 comments

I'd like to use Cobertura code coverage along with JenkinsPipelineUnit, but that doesn't work out of the box, though I was able to get it to work with some changes:

I'm using maven, and to get cobertura to report correctly, I need to enable addSources and compile goals (otherwise the coverage percentages all show zero):

        <plugin>
            <groupId>org.codehaus.gmavenplus</groupId>
            <artifactId>gmavenplus-plugin</artifactId>
            <version>1.5</version>
            <executions>
                <execution>
                    <goals>
                        <goal>addSources</goal>
                        <goal>addTestSources</goal>
                        <goal>compile</goal>
                        <goal>testCompile</goal>

However, as soon as I do that, the parseClass function that adds the method interceptors stops being called, and most of my unit tests start to fail. After some experimentation I overrode this too:

@Override
java.lang.Class	loadClass(java.lang.String name, boolean lookupScriptFiles, boolean preferClassOverScript, boolean resolve) {
	Class clazz = super.loadClass (name, lookupScriptFiles, preferClassOverScript, resolve)
	if (!preferClassOverScript) {
		clazz.metaClass.invokeMethod = helper.getMethodInterceptor()
		clazz.metaClass.static.invokeMethod = helper.getMethodInterceptor()
		clazz.metaClass.methodMissing = helper.getMethodMissingInterceptor()
	}
	return clazz
}

The interceptors are only changed conditionally, because every class is loaded through here, not just the pipeline ones. I triggered that by a somewhat hacky change here in LibraryLoader.groovy to pass false as the second parameter (it's always true otherwise):

def clazz = groovyClassLoader.loadClass(it, true, false, false)

It'd probably be better to lookup a list of classes to modify rather than overloading the meaning of the preferClassOverScript param, but I had that changed to false anyway to experiment would it solve the problem by itself (it doesn't).

So, that all works, and Cobertura code coverage for Jenkins shared library works now in my project. Is this something you are interested in changing?

idij avatar Sep 18 '18 10:09 idij

@idij Did you override the loadClass method in InterceptingGCL?

Also, I think you changed this line to call this new method, correct? https://github.com/jenkinsci/JenkinsPipelineUnit/blob/eb34a1f304491938b8d7eeac35fab080ccc81a86/src/main/groovy/com/lesfurets/jenkins/unit/global/lib/LibraryLoader.groovy#L104

haridsv avatar Dec 06 '19 09:12 haridsv

@idij @stchar How do you test with local changes in this project? Should we install the jar to the local maven repo and then add it as a dependency from my pipeline gradle project?

haridsv avatar Dec 06 '19 16:12 haridsv

@haridsv, Yep you right. Starting from v1.2 it uses maven-publish So you can build the jar localy and then install it to ~/.m2 using task publishToMavenLocal

stchar avatar Dec 07 '19 18:12 stchar

Hi, I was wondering if there was any update on this? It seems Jacoco coverage support has stalled (#103 and https://github.com/mkobit/jenkins-pipeline-shared-libraries-gradle-plugin/issues/32). It would be good to have some support for code coverage and Cobertura seems like the closest thanks to @idij's work above.

timbrown5 avatar Aug 03 '20 09:08 timbrown5