davidliu
Committed by GitHub

Jacoco reporting (#228)

* Jacoco test coverage reporting

* jacoco github action

* fix github action

* publish only summary

* fix github action

* only run unit tests for now

* asdf

* fix file path

* remove github actions for now
@@ -48,6 +48,33 @@ jobs: @@ -48,6 +48,33 @@ jobs:
48 - name: Build with Gradle 48 - name: Build with Gradle
49 run: ./gradlew clean assembleRelease livekit-android-sdk:testRelease 49 run: ./gradlew clean assembleRelease livekit-android-sdk:testRelease
50 50
  51 +# TODO: Figure out appropriate place to run this. Takes ~3 mins, so pretty slow.
  52 +# # generates coverage-report.md and publishes as checkrun
  53 +# - name: JaCoCo Code Coverage Report
  54 +# id: jacoco_reporter
  55 +# uses: PavanMudigonda/jacoco-reporter@v4.8
  56 +# with:
  57 +# coverage_results_path: "client-sdk-android/livekit-android-sdk/build/jacoco/jacoco.xml"
  58 +# coverage_report_name: Coverage
  59 +# coverage_report_title: JaCoCo
  60 +# github_token: ${{ secrets.GITHUB_TOKEN }}
  61 +# skip_check_run: false
  62 +# minimum_coverage: 60
  63 +# fail_below_threshold: false
  64 +# publish_only_summary: false
  65 +#
  66 +# # Publish Coverage Job Summary
  67 +# - name: Add Coverage Job Summary
  68 +# run: echo "${{ steps.jacoco_reporter.outputs.coverageSummary }}" >> $GITHUB_STEP_SUMMARY
  69 +#
  70 +# # uploads the coverage-report.md artifact
  71 +# - name: Upload Code Coverage Artifacts
  72 +# uses: actions/upload-artifact@v2
  73 +# with:
  74 +# name: code-coverage-report-markdown
  75 +# path: "*/coverage-results.md"
  76 +# retention-days: 7
  77 +
51 - name: Import video test keys into gradle properties 78 - name: Import video test keys into gradle properties
52 if: github.event_name == 'push' 79 if: github.event_name == 'push'
53 run: | 80 run: |
@@ -58,11 +85,11 @@ jobs: @@ -58,11 +85,11 @@ jobs:
58 LIVEKIT_URL: ${{ secrets.LIVEKIT_URL }} 85 LIVEKIT_URL: ${{ secrets.LIVEKIT_URL }}
59 LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_API_KEY }} 86 LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_API_KEY }}
60 LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }} 87 LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }}
61 - 88 +
62 - name: Build video test app 89 - name: Build video test app
63 if: github.event_name == 'push' 90 if: github.event_name == 'push'
64 run: ./gradlew video-encode-decode-test:assembleDebug video-encode-decode-test:assembleDebugAndroidTest 91 run: ./gradlew video-encode-decode-test:assembleDebug video-encode-decode-test:assembleDebugAndroidTest
65 - 92 +
66 - name: Video Encode Decode App upload and Set app id in environment variable. 93 - name: Video Encode Decode App upload and Set app id in environment variable.
67 if: github.event_name == 'push' 94 if: github.event_name == 'push'
68 run: | 95 run: |
@@ -100,7 +127,7 @@ jobs: @@ -100,7 +127,7 @@ jobs:
100 env: 127 env:
101 BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} 128 BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
102 BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} 129 BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
103 - 130 +
104 - name: Trigger BrowserStack tests 131 - name: Trigger BrowserStack tests
105 if: github.event_name == 'push' 132 if: github.event_name == 'push'
106 run: | 133 run: |
@@ -109,7 +136,7 @@ jobs: @@ -109,7 +136,7 @@ jobs:
109 env: 136 env:
110 BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} 137 BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
111 BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} 138 BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
112 - 139 +
113 - name: get version name 140 - name: get version name
114 if: github.event_name == 'push' 141 if: github.event_name == 'push'
115 run: echo "::set-output name=version_name::$(cat gradle.properties | grep VERSION_NAME | cut -d "=" -f2)" 142 run: echo "::set-output name=version_name::$(cat gradle.properties | grep VERSION_NAME | cut -d "=" -f2)"
@@ -4,15 +4,17 @@ buildscript { @@ -4,15 +4,17 @@ buildscript {
4 apply from: 'deps.gradle' 4 apply from: 'deps.gradle'
5 repositories { 5 repositories {
6 google() 6 google()
  7 + gradlePluginPortal()
7 mavenCentral() 8 mavenCentral()
8 } 9 }
9 dependencies { 10 dependencies {
10 - classpath 'com.android.tools.build:gradle:7.1.3' 11 + classpath 'com.android.tools.build:gradle:7.2.2'
11 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10" 12 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10"
12 classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version" 13 classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
13 classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version" 14 classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version"
14 classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.19' 15 classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.19'
15 classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.30.0" 16 classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.30.0"
  17 + classpath 'com.dicedmelon.gradle:jacoco-android:0.1.5'
16 // NOTE: Do not place your application dependencies here; they belong 18 // NOTE: Do not place your application dependencies here; they belong
17 // in the individual module build.gradle files 19 // in the individual module build.gradle files
18 } 20 }
1 -#Thu Apr 29 14:50:17 JST 2021 1 +#Mon May 22 01:18:06 JST 2023
2 distributionBase=GRADLE_USER_HOME 2 distributionBase=GRADLE_USER_HOME
3 -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip  
4 distributionPath=wrapper/dists 3 distributionPath=wrapper/dists
5 -zipStorePath=wrapper/dists 4 +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
6 zipStoreBase=GRADLE_USER_HOME 5 zipStoreBase=GRADLE_USER_HOME
  6 +zipStorePath=wrapper/dists
@@ -5,6 +5,8 @@ plugins { @@ -5,6 +5,8 @@ plugins {
5 id 'kotlin-kapt' 5 id 'kotlin-kapt'
6 id 'kotlinx-serialization' 6 id 'kotlinx-serialization'
7 id 'com.google.protobuf' 7 id 'com.google.protobuf'
  8 + id 'jacoco'
  9 + id 'com.dicedmelon.gradle.jacoco-android'
8 } 10 }
9 11
10 android { 12 android {
@@ -88,6 +90,19 @@ protobuf { @@ -88,6 +90,19 @@ protobuf {
88 } 90 }
89 } 91 }
90 92
  93 +jacoco {
  94 + toolVersion = "0.8.10"
  95 +}
  96 +
  97 +tasks.withType(Test) {
  98 + jacoco.includeNoLocationClasses = true
  99 + jacoco.excludes = ['jdk.internal.*']
  100 +}
  101 +
  102 +jacocoAndroidUnitTestReport {
  103 + excludes += ['livekit/**',]
  104 +}
  105 +
91 dokkaHtml { 106 dokkaHtml {
92 moduleName.set("livekit-android-sdk") 107 moduleName.set("livekit-android-sdk")
93 dokkaSourceSets { 108 dokkaSourceSets {
@@ -17,6 +17,9 @@ class RTCConfigurationTest : BaseTest() { @@ -17,6 +17,9 @@ class RTCConfigurationTest : BaseTest() {
17 newConfig::class.java 17 newConfig::class.java
18 .declaredFields 18 .declaredFields
19 .forEach { field -> 19 .forEach { field ->
  20 + if (field.isSynthetic) {
  21 + return@forEach
  22 + }
20 assertEquals("Failed on ${field.name}", field.get(originalConfig), field.get(newConfig)) 23 assertEquals("Failed on ${field.name}", field.get(originalConfig), field.get(newConfig))
21 } 24 }
22 } 25 }
@@ -53,7 +56,10 @@ class RTCConfigurationTest : BaseTest() { @@ -53,7 +56,10 @@ class RTCConfigurationTest : BaseTest() {
53 if (field.name == "iceServers") { 56 if (field.name == "iceServers") {
54 return@forEach 57 return@forEach
55 } 58 }
56 - 59 + // Ignore synthetic fields. Jacoco will create some that aren't relevant to this test.
  60 + if (field.isSynthetic) {
  61 + return@forEach
  62 + }
57 val value = field.get(config) 63 val value = field.get(config)
58 val newValue = if (value == null) { 64 val newValue = if (value == null) {
59 when (field.type) { 65 when (field.type) {