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

Mcpods 6503 junit coverage alignment #82

Merged
merged 6 commits into from
Nov 21, 2023
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
76 changes: 60 additions & 16 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -1,24 +1,68 @@
name: Run XYZ Hub tests
name: Run Naksha tests

on: [push, pull_request, workflow_dispatch]
on:
pull_request:
types:
- opened # run whenever PR is opened
- synchronize # run whenever PR is updated
- reopened # run whenever PR is reopoened
workflow_dispatch: # manual run


permissions:
checks: write # for junit reporting
pull-requests: write # for jacoco PR comments

env:
MIN_COVERAGE_OVERALL: 25
MIN_COVERAGE_CHANGED_FILES: 65

jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgis/postgis # Postgres with PostGIS extension
env:
POSTGRES_PASSWORD: password
POSTGRES_USER: postgres
POSTGRES_DB: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v2
- name: Cache local Maven repository
uses: actions/cache@v2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v1
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
with:
gradle-version: 8.2
- name: Execute tests & verify overall coverage
run: gradle test jacocoTestReport jacocoTestCoverageVerification
- name: Publish Test Report
uses: mikepenz/action-junit-report@v4
if: success() || failure() # always run even if the previous step fails
with:
report_paths: '**/build/test-results/test/TEST-*.xml'
- name: Publish code coverage report as PR comment
id: jacoco
uses: madrapps/jacoco-report@v1.6.1
with:
java-version: '8'
- name: Start the XYZ Hub stack
run: mvn clean install -Pdocker -DskipTests=true -DdockerComposeFile=docker-compose-dynamodb.yml
- name: Run tests
run: mvn verify -DskipTests=false
paths: '**/build/reports/jacoco/test/jacocoTestReport.xml'
token: ${{ secrets.GITHUB_TOKEN }}
min-coverage-overall: $MIN_COVERAGE_OVERALL
min-coverage-changed-files: $MIN_COVERAGE_CHANGED_FILES
title: Code Coverage
- name: Fail when coverage of changed files is too low
run: |
CHANGED_FILES_FAILED=$(echo '${{ steps.jacoco.outputs.coverage-changed-files }} < ${{ env.MIN_COVERAGE_CHANGED_FILES }}' | bc)
[[ $CHANGED_FILES_FAILED -ne 0 ]] && echo 'Changed files coverage ${{ steps.jacoco.outputs.coverage-changed-files }}% is smaller than required ${{ env.MIN_COVERAGE_CHANGED_FILES }}%'
[[ $CHANGED_FILES_FAILED -ne 0 ]] && exit 1 || exit 0
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,25 @@ The OpenAPI specification files are accessible under the following URIs:

Currently to access the Swagger UI from a browser, use this URI [http://{host}:{port}/hub/static/index.html](http://localhost:8080/hub/static/index.html)

# Testing locally

To run tests locally run Gradle `test` task:
```bash
./gradlew test
```

Code coverage report is generated with use of [jacoco](https://www.jacoco.org/)
To generate coverage use Gradle task `jacocoTestReport`:
```bash
./gradlew test jacocoTestReport
```
Outputs for each subproject will be stored in `/[module]/build/reports/jacoco/test/html/index.html`

To validate test coverage, run `jacocoTestCoverageVerification` Gradle task:
```bash
./gradlew test jacocoTestReport jacocoTestCoverageVerification
```

# Acknowledgements

XYZ Hub uses:
Expand Down
84 changes: 74 additions & 10 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
@file:Suppress("PropertyName")

import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import java.net.URI
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import org.gradle.kotlin.dsl.KotlinClosure2

repositories {
maven {
Expand All @@ -21,22 +23,25 @@ plugins {
id("com.github.johnrengelman.shadow") version "8.1.1"
// Don't apply for all projects, we individually only apply where Kotlin is used.
kotlin("jvm") version "1.8.21" apply false
// overall code coverage
jacoco
}

group = "com.here.naksha"
version = rootProject.properties["version"] as String

val jetbrains_annotations = "org.jetbrains:annotations:24.0.1"

val vertx_core = "io.vertx:vertx-core:4.4.4"
val vertx_config = "io.vertx:vertx-config:4.4.4"
val vertx_auth_jwt = "io.vertx:vertx-auth-jwt:4.4.4"
val vertx_redis_client = "io.vertx:vertx-redis-client:4.4.4"
val vertx_jdbc_client = "io.vertx:vertx-jdbc-client:4.4.4"
val vertx_web = "io.vertx:vertx-web:4.4.4"
val vertx_web_openapi = "io.vertx:vertx-web-openapi:4.4.4"
val vertx_web_client = "io.vertx:vertx-web-client:4.4.4"
val vertx_web_templ = "io.vertx:vertx-web-templ-handlebars:4.4.4"
val vertx_version = "4.5.0"
val vertx_core = "io.vertx:vertx-core:$vertx_version"
val vertx_config = "io.vertx:vertx-config:$vertx_version"
val vertx_auth_jwt = "io.vertx:vertx-auth-jwt:$vertx_version"
val vertx_redis_client = "io.vertx:vertx-redis-client:$vertx_version"
val vertx_jdbc_client = "io.vertx:vertx-jdbc-client:$vertx_version"
val vertx_web = "io.vertx:vertx-web:$vertx_version"
val vertx_web_openapi = "io.vertx:vertx-web-openapi:$vertx_version"
val vertx_web_client = "io.vertx:vertx-web-client:$vertx_version"
val vertx_web_templ = "io.vertx:vertx-web-templ-handlebars:$vertx_version"

val netty_transport_native_kqueue = "io.netty:netty-transport-native-kqueue:4.1.90.Final"
val netty_transport_native_epoll = "io.netty:netty-transport-native-epoll:4.1.90.Final"
Expand Down Expand Up @@ -102,11 +107,19 @@ val mockito = "org.mockito:mockito-core:3.12.4"

val flipkart_zjsonpatch = "com.flipkart.zjsonpatch:zjsonpatch:0.4.13"
val json_assert = "org.skyscreamer:jsonassert:1.5.1"
val resillience4j_retry = "io.github.resilience4j:resilience4j-retry:2.0.0"

val mavenUrl = rootProject.properties["mavenUrl"] as String
val mavenUser = rootProject.properties["mavenUser"] as String
val mavenPassword = rootProject.properties["mavenPassword"] as String

/*
Overall coverage of subproject - it might be different for different subprojects
Configurable per project - see `setOverallCoverage`
*/
val minOverallCoverageKey: String = "minOverallCoverage"
val defaultOverallMinCoverage: Double = 0.8 // Don't decrease me!

/*

IMPORTANT: api vs implementation
Expand All @@ -128,6 +141,7 @@ subprojects {
apply(plugin = "java")
apply(plugin = "com.diffplug.spotless")
apply(plugin = "java-library")
apply(plugin = "jacoco")

repositories {
maven(uri("https://repo.osgeo.org/repository/release/"))
Expand Down Expand Up @@ -174,7 +188,17 @@ subprojects {
test {
maxHeapSize = "4g"
useJUnitPlatform()
testLogging.showStandardStreams = true
testLogging {
showStandardStreams = true
exceptionFormat = TestExceptionFormat.FULL
events("standardOut", "started", "passed", "skipped", "failed")
}
afterTest(KotlinClosure2(
{ descriptor: TestDescriptor, result: TestResult ->
val totalTime = result.endTime - result.startTime
println("Total time of $descriptor.name was $totalTime")
}
))
}

compileJava {
Expand All @@ -189,6 +213,24 @@ subprojects {
addStringOption("Xmaxwarns", "1")
}
}

jacocoTestReport {
dependsOn(test)
reports {
xml.required = true
}
}

jacocoTestCoverageVerification {
dependsOn(jacocoTestReport)
violationRules {
rule {
limit {
minimum = getOverallCoverage().toBigDecimal()
}
}
}
}
}

java {
Expand Down Expand Up @@ -257,6 +299,7 @@ project(":here-naksha-lib-core") {
implementation(vividsolutions_jts_core)
implementation(google_flatbuffers)
}
setOverallCoverage(0.3) // only increasing allowed!
}

project(":here-naksha-lib-heapcache") {
Expand All @@ -270,6 +313,7 @@ project(":here-naksha-lib-heapcache") {
testImplementation(mockito)
implementation(vividsolutions_jts_core)
}
setOverallCoverage(0.5) // only increasing allowed!
}

project(":here-naksha-lib-psql") {
Expand All @@ -290,6 +334,7 @@ project(":here-naksha-lib-psql") {
testImplementation(mockito)
testImplementation(spatial4j)
}
setOverallCoverage(0.0) // only increasing allowed!
}

/*
Expand All @@ -298,6 +343,7 @@ project(":here-naksha-lib-extension") {
dependencies {
api(project(":here-naksha-lib-core"))
}
setOverallCoverage(0.4) // only increasing allowed!
}
*/

Expand All @@ -311,6 +357,7 @@ project(":here-naksha-handler-activitylog") {
implementation(flipkart_zjsonpatch)
testImplementation(jayway_jsonpath)
}
setOverallCoverage(0.4) // only increasing allowed!
}
*/

Expand Down Expand Up @@ -392,6 +439,7 @@ project(":here-naksha-lib-handlers") {
testImplementation(json_assert)
testImplementation(mockito)
}
setOverallCoverage(0.3) // only increasing allowed!
}
//} catch (ignore: UnknownProjectException) {
//}
Expand All @@ -416,7 +464,9 @@ project(":here-naksha-lib-handlers") {
implementation(vertx_web_openapi)

testImplementation(json_assert)
testImplementation(resillience4j_retry)
}
setOverallCoverage(0.25) // only increasing allowed!
}
//} catch (ignore: UnknownProjectException) {
//}
Expand Down Expand Up @@ -469,3 +519,17 @@ rootProject.tasks.shadowJar {
attributes["Main-Class"] = "com.here.naksha.app.service.NakshaApp"
}
}


fun Project.setOverallCoverage(minOverallCoverage: Double) {
ext.set(minOverallCoverageKey, minOverallCoverage)
}

fun Project.getOverallCoverage(): Double {
return if (ext.has(minOverallCoverageKey)) {
ext.get(minOverallCoverageKey) as? Double
?: throw IllegalStateException("Property '$minOverallCoverageKey' is expected to be Double")
} else {
defaultOverallMinCoverage
}
}
Loading
Loading