Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8dc2cb6
test(core): define explicit database test lanes
nevzheng Sep 27, 2026
00d8f0d
fix(ci): address #13517 review nits from jerryshao
claude Sep 28, 2026
57e3f4f
improvement(test): replace per-backend exclude-tags with @DatabaseTes…
claude Sep 28, 2026
123ac1f
Revert "improvement(test): replace per-backend exclude-tags with @Dat…
claude Sep 28, 2026
e2c5af8
fix(test): update TestBackendTestSelector for getDisplayName() format…
claude Sep 28, 2026
409c0b7
improvement(ci): remove the unwired compare-legacy subcommand
claude Sep 28, 2026
737c831
fix(ci): use a JUnit tag expression for core database lane exclusion
claude Sep 28, 2026
59cb4e5
fix(ci): revert accidental test_core_test_identity.py inclusion
claude Sep 28, 2026
8a53aac
improvement(test): flatten core database lane tags, drop the gatekeep…
claude Sep 28, 2026
4650c02
improvement(test): namespace core database lane annotations under Cor…
claude Sep 28, 2026
adabf54
improvement(test): deprecate :core:test in place, add SPIP design doc
claude Sep 28, 2026
28afdd1
fix(test): fix unit-lane manifest break, tighten CoreBackend docs
claude Sep 28, 2026
9a027ef
improvement(test): fail when a core test class runs in no lane
nevzheng Sep 30, 2026
81ae97d
docs(build): note that includeDockerTaggedTests is read in doFirst
nevzheng Sep 30, 2026
64c0c48
docs(build): correct when CI realizes :core:test
nevzheng Sep 30, 2026
78b5cf7
improvement(test): report member classes in coreTestLaneOf
nevzheng Sep 30, 2026
05511e4
docs(design): note the orphan-lane guard in the core DB split doc
nevzheng Sep 30, 2026
f728749
ci: run core database test lanes in their own build.yml jobs
claude Oct 12, 2026
7cc881a
improvement(test): keep only the core database lane changes
nevzheng Oct 13, 2026
27ec2cb
docs(test): note that the core lane, not the class, decides Docker
nevzheng Oct 13, 2026
95ecb6c
docs(test): tighten core lane comments
nevzheng Oct 13, 2026
15b30e0
improvement(test): trim core lane test scaffolding
nevzheng Oct 13, 2026
85a0c7f
improvement(test): drop core lane code that restates defaults or pins…
nevzheng Oct 13, 2026
7df1dae
docs(test): describe the core test lanes in how-to-test
nevzheng Oct 13, 2026
5481579
improvement(test): give coreUnitTest main's policies.md setup
nevzheng Oct 13, 2026
4ef3fd5
test(core): reuse database fixtures by class
nevzheng Sep 27, 2026
56290e6
fix(test): log container close failures at the end of the test plan a…
nevzheng Oct 14, 2026
ca32141
test(core): add bounded adaptive database forks
nevzheng Sep 27, 2026
1eae08e
fix(test): keep the fork count out of the core lanes' cache key
nevzheng Oct 14, 2026
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
190 changes: 173 additions & 17 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ jobs:
-x :catalogs-contrib:catalog-jdbc-clickhouse:test
-x :catalogs-contrib:catalog-jdbc-hologres:test
-x :catalogs-contrib:catalog-jdbc-oceanbase:test
# Core's tests run in the core-test job, one lane per job; :core:test is deprecated.
-x :core:test
)

if [ "${{ needs.changes.outputs.mcp_server_changes }}" != "true" ]; then
Expand All @@ -223,13 +225,179 @@ jobs:

./gradlew "${gradle_args[@]}"

- name: Fetch base branch for coverage diff
- name: Upload coverage data
if: github.event_name == 'pull_request'
uses: actions/upload-artifact@v7
with:
name: jacoco-build
# build.gradle.kts anchors the artifact at the repository root, so the report paths keep
# their module prefix, which jacoco_report.py uses to name modules.
path: |
build.gradle.kts
**/build/reports/jacoco/test/jacocoTestReport.xml
if-no-files-found: ignore
retention-days: 1

- name: Upload unit tests report
uses: actions/upload-artifact@v7
if: failure()
with:
name: unit test report
path: |
build/reports
catalogs-contrib/**/*.log
catalogs-contrib/**/*.tar
catalogs/**/*.log
catalogs/**/*.tar

core-test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
java-version: [ 17 ]
# One job per core test lane, so each lane's results and coverage inputs are inspectable on
# their own. Lanes are defined in core/build.gradle.kts.
lane: [ unit, h2, mysql, postgresql ]
include:
- lane: unit
task: coreUnitTest
skip-docker-tests: true
- lane: h2
task: coreH2Test
skip-docker-tests: true
- lane: mysql
task: coreMySQLTest
skip-docker-tests: false
- lane: postgresql
task: corePostgreSQLTest
skip-docker-tests: false
timeout-minutes: 120
needs: changes
if: >-
needs.changes.outputs.source_changes == 'true' &&
needs.changes.outputs.maintenance_module_only_changes != 'true'
steps:
- uses: actions/checkout@v4

- uses: ./.github/actions/setup-java-toolchains
with:
java-version: ${{ matrix.java-version }}

- name: Free up disk space
run: |
dev/ci/util_free_space.sh

- name: Test database concurrency build logic
id: buildsrc-tests
if: matrix.lane == 'unit'
run: ./gradlew -p buildSrc test

- name: Upload database concurrency build logic test report
if: ${{ failure() && steps.buildsrc-tests.outcome == 'failure' }}
uses: actions/upload-artifact@v7
with:
name: core-database-buildsrc-test-report
path: |
buildSrc/build/reports/tests/test
buildSrc/build/test-results/test
if-no-files-found: warn
retention-days: 1

- name: Run core ${{ matrix.lane }} lane
run: |
./gradlew :core:${{ matrix.task }} \
-PskipWeb=true \
-PskipITs \
-PskipDockerTests=${{ matrix.skip-docker-tests }}

- name: Validate core test evidence
run: |
junit_xml="$(find "core/build/test-results/${{ matrix.task }}" \
-type f -name 'TEST-*.xml' -print -quit)"
test -n "${junit_xml}"
test -s "${junit_xml}"
test -s "build/reports/tests/core/${{ matrix.task }}/index.html"
test -s "core/build/jacoco/${{ matrix.task }}.exec"
if [ "${{ matrix.lane }}" != "unit" ]; then
shard_record="$(find \
"core/build/test-results/${{ matrix.task }}/shard-telemetry" \
-type f -name 'worker-*.log' -size +0c -print -quit)"
test -n "${shard_record}"
test -s "${shard_record}"
fi

- name: Upload core test evidence
uses: actions/upload-artifact@v7
with:
name: core-${{ matrix.lane }}-test-evidence
path: |
core/build/test-results/${{ matrix.task }}
build/reports/tests/core/${{ matrix.task }}
core/build/jacoco/${{ matrix.task }}.exec
if-no-files-found: error
retention-days: 1

- name: Upload core test report
uses: actions/upload-artifact@v7
if: failure()
with:
name: core test report ${{ matrix.lane }}
path: |
build/reports/tests/core
core/build/test-results

coverage:
runs-on: ubuntu-latest
timeout-minutes: 30
needs: [ changes, build, core-test ]
if: >-
always() &&
github.event_name == 'pull_request' &&
needs.build.result == 'success' &&
(needs.changes.outputs.maintenance_module_only_changes == 'true' ||
needs['core-test'].result == 'success')
steps:
- uses: actions/checkout@v4

- uses: ./.github/actions/setup-java-toolchains
if: needs.changes.outputs.maintenance_module_only_changes != 'true'
with:
java-version: 17

- name: Fetch base branch for coverage diff
run: git fetch origin ${{ github.base_ref }} --depth=1

- name: Download coverage data
uses: actions/download-artifact@v4
with:
pattern: jacoco-*
merge-multiple: true

- name: Download core test evidence
if: needs.changes.outputs.maintenance_module_only_changes != 'true'
uses: actions/download-artifact@v4
with:
pattern: core-*-test-evidence
path: core-test-evidence

- name: Generate combined core coverage
if: needs.changes.outputs.maintenance_module_only_changes != 'true'
run: |
mkdir -p core/build/jacoco
for task in coreUnitTest coreH2Test coreMySQLTest corePostgreSQLTest; do
exec_file="$(find core-test-evidence -path "*/core/build/jacoco/${task}.exec" -print -quit)"
test -n "${exec_file}"
install -m 0644 "${exec_file}" "core/build/jacoco/${task}.exec"
done
./gradlew \
:core:jacocoTestReport \
-PcoreSuiteCoverage=true \
-PskipWeb=true
test -s core/build/reports/jacoco/test/jacocoTestReport.xml

- name: Generate Coverage Report
id: coverage
if: github.event_name == 'pull_request'
run: |
python3 dev/ci/jacoco_report.py \
--base-ref "${{ github.base_ref }}" \
Expand All @@ -240,11 +408,11 @@ jobs:
--output coverage-report.md

- name: Save PR number
if: github.event_name == 'pull_request' && steps.coverage.outputs.has_reports == 'true'
if: steps.coverage.outputs.has_reports == 'true'
run: echo "${{ github.event.pull_request.number }}" > pr-number.txt

- name: Upload Coverage Report
if: github.event_name == 'pull_request' && steps.coverage.outputs.has_reports == 'true'
if: steps.coverage.outputs.has_reports == 'true'
uses: actions/upload-artifact@v7
with:
name: coverage-report
Expand All @@ -253,19 +421,7 @@ jobs:
pr-number.txt

- name: Output Coverage Info
if: github.event_name == 'pull_request' && steps.coverage.outputs.has_reports == 'true'
if: steps.coverage.outputs.has_reports == 'true'
run: |
echo "Total coverage ${{ steps.coverage.outputs.coverage-overall }}"
echo "Changed Files coverage ${{ steps.coverage.outputs.coverage-changed-files }}"

- name: Upload unit tests report
uses: actions/upload-artifact@v7
if: failure()
with:
name: unit test report
path: |
build/reports
catalogs-contrib/**/*.log
catalogs-contrib/**/*.tar
catalogs/**/*.log
catalogs/**/*.tar
41 changes: 32 additions & 9 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import com.github.jk1.license.render.InventoryHtmlReportRenderer
import com.github.jk1.license.render.ReportRenderer
import com.github.vlsi.gradle.dsl.configureEach
import net.ltgt.gradle.errorprone.errorprone
import org.apache.gravitino.testing.CoreDatabaseConcurrency
import org.apache.tools.zip.ZipEntry
import org.apache.tools.zip.ZipOutputStream
import org.gradle.api.attributes.java.TargetJvmVersion
Expand Down Expand Up @@ -458,12 +459,11 @@ allprojects {
// Ryuk need privileged mode, if we want to rootless or run non-privileged mode, we need to disable it.
param.environment("TESTCONTAINERS_RYUK_DISABLED", "true")

val dockerRunning = project.rootProject.extra["dockerRunning"] as? Boolean ?: false
val macDockerConnector = project.rootProject.extra["macDockerConnector"] as? Boolean ?: false
if (OperatingSystem.current().isMacOsX() &&
dockerRunning &&
macDockerConnector
) {
val macDockerConnectorFixedNetwork =
project.rootProject.extra[
CoreDatabaseConcurrency.MAC_DOCKER_CONNECTOR_FIXED_NETWORK_EXTRA
] as? Boolean ?: false
if (macDockerConnectorFixedNetwork) {
param.environment("NEED_CREATE_DOCKER_NETWORK", "true")
}

Expand Down Expand Up @@ -514,9 +514,14 @@ allprojects {

val dockerTest = project.rootProject.extra["dockerTest"] as? Boolean ?: false
param.environment("dockerTest", dockerTest.toString())
// Must stay inside doFirst: tasks such as :core's database lanes set this flag in their own
// configuration action, which may run after this configureEach action registers.
val includeDockerTaggedTests =
param.extensions.extraProperties.properties["includeDockerTaggedTests"] as? Boolean
?: dockerTest
val dorisMultiVersion = project.hasProperty("dorisMultiVersionTest")
param.useJUnitPlatform {
if (!dockerTest) {
if (!includeDockerTaggedTests) {
excludeTags("gravitino-docker-test")
}
if (!dorisMultiVersion) {
Expand Down Expand Up @@ -1017,9 +1022,19 @@ subprojects {
val skipTests = project.hasProperty("skipTests")
if (!skipTests) {
val extraArgs = project.property("extraJvmArgs") as List<String>
jvmArgs = listOf("-Xmx4G") + extraArgs
jvmArgs = listOf(CoreDatabaseConcurrency.TEST_WORKER_MAX_HEAP_ARGUMENT) + extraArgs
useJUnitPlatform()
finalizedBy(tasks.getByName("jacocoTestReport"))
val isCoreSuiteTask =
project.path == ":core" &&
name in setOf(
"coreUnitTest",
"coreH2Test",
"coreMySQLTest",
"corePostgreSQLTest"
)
if (!isCoreSuiteTask) {
finalizedBy(tasks.getByName("jacocoTestReport"))
}
}
}

Expand Down Expand Up @@ -1630,13 +1645,21 @@ project.extra["dockerTest"] = false
project.extra["dockerRunning"] = false
project.extra["macDockerConnector"] = false
project.extra["isOrbStack"] = false
project.extra[CoreDatabaseConcurrency.MAC_DOCKER_CONNECTOR_FIXED_NETWORK_EXTRA] = false

// The following is to check the docker status and print the tip message
fun printDockerCheckInfo() {
checkMacDockerConnector()
checkDockerStatus()
checkOrbStackStatus()

val macDockerConnectorFixedNetwork =
OperatingSystem.current().isMacOsX() &&
(project.extra["dockerRunning"] as? Boolean ?: false) &&
(project.extra["macDockerConnector"] as? Boolean ?: false)
project.extra[CoreDatabaseConcurrency.MAC_DOCKER_CONNECTOR_FIXED_NETWORK_EXTRA] =
macDockerConnectorFixedNetwork

val testMode = project.properties["testMode"] as? String ?: "embedded"
if (testMode != "deploy" && testMode != "embedded") {
return
Expand Down
37 changes: 37 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

plugins {
`java`
}

repositories {
mavenCentral()
}

dependencies {
compileOnly("com.google.code.findbugs:jsr305:3.0.2")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
testImplementation("org.junit.jupiter:junit-jupiter-params:5.8.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
}

tasks.test {
useJUnitPlatform()
}
Loading
Loading