diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 00000000..e711a04d --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,12 @@ +codecov: + require_ci_to_pass: yes + +coverage: + precision: 2 + round: down + range: "75...100" + status: + project: + default: + target: 75% # the required coverage value + threshold: 1% # the leniency in hitting the target \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e017740..0bcc5e2c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,6 +38,5 @@ jobs: - name: Upload Coverage Report uses: codecov/codecov-action@v1 with: - file: ./build/reports/jacoco/test/jacocoTestReport.xml - flags: plugin + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/README.md b/README.md index fc95f76e..b900ee32 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ +[![codecov](https://codecov.io/gh/opensearch-project/common-utils/branch/main/graph/badge.svg?token=CQ01D9MNQL)](https://codecov.io/gh/opensearch-project/common-utils) - [OpenSearch Common Utils](#opensearch-common-utils) - [Contributing](#contributing) diff --git a/build-tools/opensearchplugin-coverage.gradle b/build-tools/opensearchplugin-coverage.gradle new file mode 100644 index 00000000..2b4d21c0 --- /dev/null +++ b/build-tools/opensearchplugin-coverage.gradle @@ -0,0 +1,49 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * OpenSearch Plugin build tools don't work with the Gradle Jacoco Plugin to report coverage out of the box. + * https://github.com/elastic/elasticsearch/issues/28867. + * + * This code sets up coverage reporting manually for OpenSearch plugin tests. This is complicated because: + * 1. The OpenSearch integTest Task doesn't implement Gradle's JavaForkOptions so we have to manually start the jacoco agent with the test JVM + * 2. The cluster nodes are stopped using 'kill -9' which means jacoco can't dump it's execution output to a file on VM shutdown + * 3. The Java Security Manager prevents JMX from writing execution output to the file. + * + * To workaround these we start the cluster with jmx enabled and then use Jacoco's JMX MBean to get the execution data before the + * cluster is stopped and dump it to a file. Luckily our current security policy seems to allow this. This will also probably + * break if there are multiple nodes in the integTestCluster. But for now... it sorta works. + */ +apply plugin: 'jacoco' + +// Get gradle to generate the required jvm agent arg for us using a dummy tasks of type Test. Unfortunately Elastic's +// testing tasks don't derive from Test so the jacoco plugin can't do this automatically. +def jacocoDir = "${buildDir}/jacoco" +task dummyTest(type: Test) { + enabled = false + workingDir = file("/") // Force absolute path to jacoco agent jar + jacoco { + destinationFile = file("${jacocoDir}/test.exec") + destinationFile.parentFile.mkdirs() + jmx = true + } +} + +jacocoTestReport { + dependsOn test + executionData dummyTest.jacoco.destinationFile + getSourceDirectories().from(sourceSets.main.allSource) + getClassDirectories().from(sourceSets.main.output) + reports { + html.enabled = true // human readable + xml.enabled = true // for coverlay + } +} + +project.gradle.projectsEvaluated { + jacocoTestReport.dependsOn test +} + +check.dependsOn jacocoTestReport diff --git a/build.gradle b/build.gradle index eb2e8bc9..67e4bef1 100644 --- a/build.gradle +++ b/build.gradle @@ -63,6 +63,7 @@ apply plugin: 'io.gitlab.arturbosch.detekt' apply plugin: 'org.jetbrains.kotlin.jvm' apply plugin: 'org.jetbrains.kotlin.plugin.allopen' apply plugin: 'opensearch.repositories' +apply from: 'build-tools/opensearchplugin-coverage.gradle' configurations { ktlint