From 1a3e8fe2d1fefcf0cc845252b1d041ae62e5e38f Mon Sep 17 00:00:00 2001 From: Andre Weber Date: Thu, 29 Feb 2024 14:38:18 +0100 Subject: [PATCH 1/4] feature: Add Code Coverage Report --- .../connection/DataBrokerConnectorFactory.kt | 11 +-- build.gradle.kts | 80 +++++++++++++++++++ .../eclipse/kuksa/DataBrokerConnectionTest.kt | 2 +- vss-processor/build.gradle.kts | 1 + 4 files changed, 88 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/connection/DataBrokerConnectorFactory.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/connection/DataBrokerConnectorFactory.kt index 067b9162..90aef843 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/connection/DataBrokerConnectorFactory.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/connection/DataBrokerConnectorFactory.kt @@ -45,7 +45,10 @@ class DataBrokerConnectorFactory { createInsecureManagedChannel(connectionInfo) } - val jsonWebToken = loadJsonWebToken(context, connectionInfo) + var jsonWebToken: JsonWebToken? = null + if (connectionInfo.isAuthenticationEnabled) { + jsonWebToken = loadJsonWebToken(context, connectionInfo.jwtUriPath) + } return DataBrokerConnector(managedChannel, jsonWebToken).apply { timeoutConfig = this@DataBrokerConnectorFactory.timeoutConfig @@ -86,10 +89,8 @@ class DataBrokerConnectorFactory { } @Throws(IOException::class) - private fun loadJsonWebToken(context: Context, connectionInfo: ConnectionInfo): JsonWebToken? { - val isAuthenticationDisabled = !connectionInfo.isAuthenticationEnabled - val jwtUriPath = connectionInfo.jwtUriPath - if (isAuthenticationDisabled || jwtUriPath.isNullOrEmpty()) { + private fun loadJsonWebToken(context: Context, jwtUriPath: String?): JsonWebToken? { + if (jwtUriPath.isNullOrEmpty()) { return null } diff --git a/build.gradle.kts b/build.gradle.kts index afce8049..3ef8da42 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,6 +17,8 @@ * */ +import com.android.build.api.dsl.LibraryExtension +import com.android.build.gradle.internal.dsl.BaseAppModuleExtension import org.eclipse.kuksa.version.VERSION_FILE_DEFAULT_NAME import org.eclipse.kuksa.version.VERSION_FILE_DEFAULT_PATH_KEY import java.nio.file.FileVisitResult @@ -38,6 +40,7 @@ plugins { detekt version kotlin("jvm") + jacoco } subprojects { @@ -102,3 +105,80 @@ tasks.register("mergeDashFiles") { } } } + +// region jacoco coverage report + +subprojects { + apply { + plugin("jacoco") + } + + if (plugins.hasPlugin("com.android.library")) { + configure { + @Suppress("UnstableApiUsage") + testOptions { + buildTypes { + named("debug") { + enableUnitTestCoverage = true + enableAndroidTestCoverage = true + } + } + } + } + } + + if (plugins.hasPlugin("com.android.application")) { + configure { + @Suppress("UnstableApiUsage") + testOptions { + buildTypes { + named("debug") { + enableUnitTestCoverage = true + enableAndroidTestCoverage = true + } + } + } + } + } +} + +tasks.create("jacocoRootReport", JacocoReport::class.java) { + group = "report" + + reports { + html.required.set(true) + xml.required.set(true) + csv.required.set(false) + } + + val excludes = listOf( + "**/buildSrc/**", + "**/app/**", + "**/samples/**", + "**/build/**/org/eclipse/kuksa/vss/**", // generated + "**/test*/**/*.*", + ) + + val sourcesKotlin = subprojects.map { it.layout.projectDirectory.dir("src/main/kotlin") } + val sourcesJava = subprojects.map { it.layout.projectDirectory.dir("src/main/java") } + + val classes = fileTree(rootDir) { + include( + "**/build/classes/kotlin/**/*.class", // kotlin-jvm modules + "**/build/tmp/kotlin-classes/debug/**/*.class", // android modules (application, libraries) + ) + exclude(excludes) + }.toSet() + + val executionPaths = fileTree(rootDir) { + include("**/*.exec", "**/*.ec") + exclude(excludes) + }.toSet() + + additionalSourceDirs.setFrom(sourcesKotlin, sourcesJava) + sourceDirectories.setFrom(sourcesKotlin, sourcesJava) + classDirectories.setFrom(classes) + executionData.setFrom(executionPaths) +} + +// endregion jacoco diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectionTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectionTest.kt index e26af91c..8ce05047 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectionTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectionTest.kt @@ -263,7 +263,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ // this test closes the connection, the connection can't be used afterward anymore `when`("A DisconnectListener is registered successfully") { - val disconnectListener = mockk() + val disconnectListener = mockk(relaxed = true) val disconnectListeners = dataBrokerConnection.disconnectListeners disconnectListeners.register(disconnectListener) diff --git a/vss-processor/build.gradle.kts b/vss-processor/build.gradle.kts index d3099dd4..9707f9a4 100644 --- a/vss-processor/build.gradle.kts +++ b/vss-processor/build.gradle.kts @@ -25,6 +25,7 @@ plugins { kotlin("jvm") publish alias(libs.plugins.dokka) + jacoco } val versionPath = rootProject.ext[VERSION_FILE_DEFAULT_PATH_KEY] as String From 39cca9dee986bf764dd3b5a63c17ee610ae7f602 Mon Sep 17 00:00:00 2001 From: Andre Weber Date: Thu, 29 Feb 2024 14:39:10 +0100 Subject: [PATCH 2/4] chore: Move from "java" to "kotlin" Folder --- .../org/eclipse/kuksa/vsscore/annotation/VssDefinition.kt | 0 .../org/eclipse/kuksa/vsscore/extension/StringExtension.kt | 0 .../org/eclipse/kuksa/vsscore/model/VssSpecification.kt | 0 .../org/eclipse/kuksa/vsscore/extension/StringExtensionTest.kt | 0 .../org/eclipse/kuksa/vsscore/model/VssSpecificationTest.kt | 0 .../org/eclipse/kuksa/vsscore/model/VssVehicle.kt | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename vss-core/src/main/{java => kotlin}/org/eclipse/kuksa/vsscore/annotation/VssDefinition.kt (100%) rename vss-core/src/main/{java => kotlin}/org/eclipse/kuksa/vsscore/extension/StringExtension.kt (100%) rename vss-core/src/main/{java => kotlin}/org/eclipse/kuksa/vsscore/model/VssSpecification.kt (100%) rename vss-core/src/test/{java => kotlin}/org/eclipse/kuksa/vsscore/extension/StringExtensionTest.kt (100%) rename vss-core/src/test/{java => kotlin}/org/eclipse/kuksa/vsscore/model/VssSpecificationTest.kt (100%) rename vss-core/src/test/{java => kotlin}/org/eclipse/kuksa/vsscore/model/VssVehicle.kt (100%) diff --git a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssDefinition.kt b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/annotation/VssDefinition.kt similarity index 100% rename from vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssDefinition.kt rename to vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/annotation/VssDefinition.kt diff --git a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/extension/StringExtension.kt b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/extension/StringExtension.kt similarity index 100% rename from vss-core/src/main/java/org/eclipse/kuksa/vsscore/extension/StringExtension.kt rename to vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/extension/StringExtension.kt diff --git a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssSpecification.kt b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssSpecification.kt similarity index 100% rename from vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssSpecification.kt rename to vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssSpecification.kt diff --git a/vss-core/src/test/java/org/eclipse/kuksa/vsscore/extension/StringExtensionTest.kt b/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/extension/StringExtensionTest.kt similarity index 100% rename from vss-core/src/test/java/org/eclipse/kuksa/vsscore/extension/StringExtensionTest.kt rename to vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/extension/StringExtensionTest.kt diff --git a/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssSpecificationTest.kt b/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssSpecificationTest.kt similarity index 100% rename from vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssSpecificationTest.kt rename to vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssSpecificationTest.kt diff --git a/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssVehicle.kt b/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssVehicle.kt similarity index 100% rename from vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssVehicle.kt rename to vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssVehicle.kt From 7c1da7a5f43239bd58b6e4024fb307a2681a29b2 Mon Sep 17 00:00:00 2001 From: Andre Weber Date: Thu, 29 Feb 2024 14:40:36 +0100 Subject: [PATCH 3/4] chore: Add GitHub Action Composite Task for Test Execution --- .github/actions/run-tests/action.yml | 58 +++++++++++++++++++++++ .github/workflows/build-main.yaml | 6 +++ .github/workflows/build-pull-request.yaml | 21 ++------ 3 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 .github/actions/run-tests/action.yml diff --git a/.github/actions/run-tests/action.yml b/.github/actions/run-tests/action.yml new file mode 100644 index 00000000..1e357cf2 --- /dev/null +++ b/.github/actions/run-tests/action.yml @@ -0,0 +1,58 @@ +name: Run Tests +description: Runs Unit and Integration Test. Tests will be executed on a Databroker instance. + +inputs: + upload-test-reports: + description: "Uploads the resulting test reports if enabled" + required: false + default: 'false' + upload-code-coverage-reports: + description: "Executes Code Coverage Generation and uploads the resulting reports if enabled" + required: false + default: 'false' + databroker-version: + description: "Databroker Version" + required: false + default: 'master' + +runs: + using: "composite" + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: "Run Docker Container of Databroker in detached mode" + run: docker run --pull=always --rm --publish 55556:55556/tcp --detach --name databroker ghcr.io/eclipse/kuksa.val/databroker:${{ inputs.databroker-version }} --port 55556 --insecure + shell: bash + + - name: Run 'test' with Gradle Wrapper + run: ./gradlew test -Dkotest.tags="!CustomDatabroker" + shell: bash + + - name: Upload Test Reports + if: ${{ inputs.upload-test-reports == 'true' }} + uses: actions/upload-artifact@v3 + with: + name: test-reports + path: ${{ github.workspace }}/**/reports/tests/*/ + if-no-files-found: error + retention-days: 14 + + - name: Create Code Coverage Reports + if: ${{ inputs.upload-code-coverage-reports == 'true' }} + run: ./gradlew jacocoRootReport + shell: bash + + - name: Upload Code Coverage Report + if: ${{ inputs.upload-code-coverage-reports == 'true' }} + uses: actions/upload-artifact@v3 + with: + name: code-coverage + path: ${{ github.workspace }}/build/reports/jacoco/jacocoRootReport/html/* + if-no-files-found: error + retention-days: 14 + + - name: "Stop Docker Container of Databroker" + if: always() + run: docker stop databroker + shell: bash diff --git a/.github/workflows/build-main.yaml b/.github/workflows/build-main.yaml index 1747dea4..d8ffabc4 100755 --- a/.github/workflows/build-main.yaml +++ b/.github/workflows/build-main.yaml @@ -38,6 +38,12 @@ jobs: if-no-files-found: error retention-days: 14 + - name: Execute Tests + uses: ./.github/actions/run-tests + with: + upload-test-reports: true + upload-code-coverage-reports: true + - name: Archive changelog uses: actions/upload-artifact@v3 with: diff --git a/.github/workflows/build-pull-request.yaml b/.github/workflows/build-pull-request.yaml index 8e3cf0a3..25e03247 100755 --- a/.github/workflows/build-pull-request.yaml +++ b/.github/workflows/build-pull-request.yaml @@ -10,9 +10,6 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: "Run Docker Container of Databroker in detached mode" - run: docker run --pull=always --rm --publish 55556:55556/tcp --detach --name databroker ghcr.io/eclipse/kuksa.val/databroker:master --port 55556 --insecure - - name: Setup Project uses: ./.github/actions/setup-project @@ -23,6 +20,7 @@ jobs: run: ./gradlew ktlintCheck detekt - name: Upload Detekt Reports + if: always() uses: actions/upload-artifact@v3 with: name: detekt-reports @@ -30,17 +28,8 @@ jobs: if-no-files-found: error retention-days: 14 - - name: Run 'test' with Gradle Wrapper - run: ./gradlew test -Dkotest.tags="!CustomDatabroker" - - - name: Upload Test Reports - uses: actions/upload-artifact@v3 + - name: Execute Tests + uses: ./.github/actions/run-tests with: - name: test-reports - path: ${{ github.workspace }}/**/reports/tests/*/ - if-no-files-found: error - retention-days: 14 - - - name: "Stop Docker Container of Databroker" - if: always() - run: docker stop databroker + upload-test-reports: true + upload-code-coverage-reports: true From e6cbf9f4b529183fbe9d8e52db26ef1048b8aa78 Mon Sep 17 00:00:00 2001 From: Andre Weber Date: Fri, 1 Mar 2024 12:06:51 +0100 Subject: [PATCH 4/4] chore: Exclude VSS Processor Plugin from Code Coverage Report --- build.gradle.kts | 5 +++-- vss-processor/build.gradle.kts | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3ef8da42..ecaf5eed 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -147,7 +147,7 @@ tasks.create("jacocoRootReport", JacocoReport::class.java) { reports { html.required.set(true) - xml.required.set(true) + xml.required.set(false) csv.required.set(false) } @@ -155,7 +155,8 @@ tasks.create("jacocoRootReport", JacocoReport::class.java) { "**/buildSrc/**", "**/app/**", "**/samples/**", - "**/build/**/org/eclipse/kuksa/vss/**", // generated + "**/vssprocessor/plugin/**", // code coverage not supported for Gradle Plugins / Gradle TestKit tests + "**/build/**/org/eclipse/kuksa/vss/**", // generated code "**/test*/**/*.*", ) diff --git a/vss-processor/build.gradle.kts b/vss-processor/build.gradle.kts index 9707f9a4..d3099dd4 100644 --- a/vss-processor/build.gradle.kts +++ b/vss-processor/build.gradle.kts @@ -25,7 +25,6 @@ plugins { kotlin("jvm") publish alias(libs.plugins.dokka) - jacoco } val versionPath = rootProject.ext[VERSION_FILE_DEFAULT_PATH_KEY] as String