Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/sql-test-and-build-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ jobs:
- name: Build and Test
run: |
if [ "${{ matrix.test-type }}" = "unit" ]; then
./gradlew --continue build -x spotlessCheck -x integTest -x tracingIntegTest -x yamlRestTest -x doctest
./gradlew --continue build jacocoAggregatedReport -x spotlessCheck -x integTest -x tracingIntegTest -x yamlRestTest -x doctest
elif [ "${{ matrix.test-type }}" = "integration" ]; then
./gradlew --continue integTest tracingIntegTest yamlRestTest
else
Expand All @@ -124,7 +124,7 @@ jobs:
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: jacoco-coverage-reports
path: '**/build/reports/jacoco/test/jacocoTestReport.xml'
path: build/reports/jacoco/jacocoAggregatedReport/jacocoAggregatedReport.xml
retention-days: 1
if-no-files-found: error

Expand Down
4 changes: 3 additions & 1 deletion DEVELOPER_GUIDE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ For faster local iterations, skip integration tests. ``./gradlew build -x integT
- Compile all Java source files.
* - ./gradlew test
- Run all unit tests.
* - ./gradlew test jacocoAggregatedReport
- Run all unit tests and generate a code coverage report across all modules in build/reports/jacoco/jacocoAggregatedReport.
* - ./gradlew :integ-test:integTest
- Run all integration test (this takes time).
* - ./gradlew :integ-test:yamlRestTest
Expand Down Expand Up @@ -357,7 +359,7 @@ Here is a sample for integration test for your reference:
}
}

Finally thanks to JaCoCo library, you can check out the test coverage in ``<module_name>/build/reports/jacoco`` for your changes easily.
Finally thanks to JaCoCo library, you can check out the test coverage in ``<module_name>/build/reports/jacoco`` for your changes easily. A module's report only counts the tests of that module. To also count tests in other modules (for example ``ppl`` tests of ``core`` classes), which is the coverage that Codecov reports, run ``./gradlew test jacocoAggregatedReport`` and open ``build/reports/jacoco/jacocoAggregatedReport/html/index.html``.

Deploying Locally
-----------------
Expand Down
50 changes: 50 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,56 @@ jacocoTestCoverageVerification {
}
check.dependsOn jacocoTestCoverageVerification

// Each module's jacocoTestReport credits a class only with the tests of its own module, but many
// classes are mostly tested from other modules (for example core's CalciteRelNodeVisitor is tested
// by ppl's CalcitePPL*Test). This report merges the unit test execution data of every module that
// applies jacoco and reports it against the classes of the modules below, with the same excludes as
// their own jacocoTestReport. CI uploads it to Codecov. The per-module
// jacocoTestCoverageVerification rules still measure each module's own tests only.
def aggregatedCoverageModules = [
':api',
':async-query',
':async-query-core',
':core',
':datasources',
':direct-query',
':direct-query-core',
':opensearch',
':ppl',
':prometheus',
':protocol',
':sql',
]
def jacocoAggregatedReport = tasks.register('jacocoAggregatedReport', JacocoReport) {
group = 'verification'
description = 'Generates a code coverage report of all modules from the unit tests of all modules. ' +
'Does not run the tests; use ./gradlew test jacocoAggregatedReport.'
reports {
html.required = true
xml.required = true
csv.required = false
}
}
// The module reports set their excludes in afterEvaluate, so read them once every project is evaluated.
gradle.projectsEvaluated {
jacocoAggregatedReport.configure {
subprojects.findAll { it.plugins.hasPlugin('jacoco') }.each { p ->
// 'junit4' is the JUnit 4 test task of async-query, direct-query and direct-query-core.
p.tasks.withType(Test).matching { it.name in ['test', 'junit4'] }.each { testTask ->
// Like each module's jacocoTestReport, only run after the tests rather than depend on
// them, so that a failing test still leaves a report for CI to upload.
mustRunAfter testTask
executionData testTask
}
}
aggregatedCoverageModules.each { path ->
def moduleReport = project(path).tasks.named('jacocoTestReport', JacocoReport).get()
classDirectories.from(moduleReport.classDirectories)
sourceDirectories.from(moduleReport.sourceDirectories)
}
}
}


configurations.all {
resolutionStrategy.force 'junit:junit:4.13.2'
Expand Down
Loading