Skip to content

Fixes and adds tests for Kotlin Serialization version compatibility issue #163

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

Merged
merged 13 commits into from
May 2, 2025
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
13 changes: 8 additions & 5 deletions .github/workflows/kotlin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ on:
pull_request:
paths:
- '.github/workflows/kotlin*'
- 'gradle/**'
- '**/gradle/**'
- 'kotlin/**'

push:
branches:
- main
paths:
- '.github/workflows/kotlin*'
- 'gradle/**'
- '**/gradle/**'
- 'kotlin/**'

release:
Expand Down Expand Up @@ -44,7 +44,7 @@ jobs:
java-version: 17

- name: Setup Gradle
uses: gradle/gradle-build-action@v3
uses: gradle/actions/setup-gradle@v4

- name: Cache Kotlin packages
uses: actions/cache@v4
Expand All @@ -62,12 +62,15 @@ jobs:

- name: Test
env:
ORG_GRADLE_PROJECT_version: ${{ steps.tag_name.outputs.VERSION || '0.0.1' }}
ORG_GRADLE_PROJECT_version: ${{ steps.tag_name.outputs.VERSION || 'development' }}
run: ./gradlew test publishToMavenLocal

- name: Test integration w/ minimum required versions
run: ./gradlew test -p integration-tests

- name: Configure AWS Credentials
if: github.repository == 'adsbynimbus/nimbus-openrtb' && github.event_name == 'release'
uses: aws-actions/configure-aws-credentials@v1-node16
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ vars.AWS_ROLE }}
aws-region: us-east-1
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ Pods/
Podfile.lock

# Swift Package Manager
.swiftpm/
Packages/
Package.resolved
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Project-wide Gradle settings.
org.gradle.jvmargs=-Xmx6g -XX:+UseParallelGC -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx6g -Xms6g -XX:+UseG1GC -XX:SoftRefLRUPolicyMSPerMB=1 -XX:ReservedCodeCacheSize=320m -XX:+HeapDumpOnOutOfMemoryError
org.gradle.caching=true
org.gradle.configureondemand=true
org.gradle.parallel=true
Expand All @@ -11,7 +11,7 @@ org.gradle.configuration-cache-problems=warn
org.gradle.configuration-cache.max-problems=5

group=com.adsbynimbus.openrtb
version=0.17.0
version=development

## Android Build Settings
android.defaults.buildfeatures.resvalues=false
Expand All @@ -21,7 +21,7 @@ android.useAndroidX=true

## Kotlin Build Settings
kotlin.code.style=official
kotlin.daemon.jvmargs=-Xmx2g -XX:+UseParallelGC -Dfile.encoding=UTF-8
kotlin.daemon.jvmargs=-Dfile.encoding=UTF-8 -Xmx6g -Xms6g -XX:+UseG1GC -XX:SoftRefLRUPolicyMSPerMB=1 -XX:ReservedCodeCacheSize=320m -XX:+HeapDumpOnOutOfMemoryError
kotlin.incremental.multiplatform=true
kotlin.incremental.native=true
kotlin.native.ignoreDisabledTargets=true
Expand Down
5 changes: 2 additions & 3 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
android = "8.9.2"
dokka = "1.9.20"
kotest = "6.0.0.M3"
kotlin = "2.1.0"
serialization = { require = "[1.4, 2.0[", prefer = "1.8.1" }
kotlin = "2.1.20"
serialization = { require = "[1.5.1, )", prefer = "1.7.3" }

[plugins]
android = { id = "com.android.library", version.ref = "android" }
Expand All @@ -20,5 +20,4 @@ serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-jso

[bundles]
test-android = [ "kotest-runner" ]

test-common = [ "kotest-assertions", "kotest-engine" ]
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
9 changes: 4 additions & 5 deletions gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
Expand Down Expand Up @@ -115,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
CLASSPATH="\\\"\\\""


# Determine the Java command to use to start the JVM.
Expand Down Expand Up @@ -206,15 +205,15 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.

set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"

# Stop when "xargs" is not available.
Expand Down
4 changes: 2 additions & 2 deletions gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ goto fail
:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set CLASSPATH=


@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*

:end
@rem End local scope for the variables with windows NT shell
Expand Down
38 changes: 38 additions & 0 deletions integration-tests/android/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
plugins {
alias(libs.plugins.android)
alias(libs.plugins.kotlin)
}

android {
//noinspection GradleDependency
compileSdk = 34
defaultConfig {
minSdk = 21
}
namespace = "com.adsbynimbus.openrtb.android"

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

kotlinOptions {
jvmTarget = "1.8"
}

sourceSets.configureEach {
if (name.contains("test", ignoreCase = true)) {
java.srcDirs("../../kotlin/src/commonTest/kotlin")
}
}
}

tasks.withType<Test> {
useJUnitPlatform()
}

dependencies {
implementation(libs.openrtb)
implementation(libs.serialization.json)
implementation(libs.bundles.test)
}
27 changes: 27 additions & 0 deletions integration-tests/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[versions]
#noinspection AndroidGradlePluginVersion
android = "8.2.2"
#noinspection NewerVersionAvailable
kotest = "5.8.0"
#noinspection NewerVersionAvailable
kotlin = "1.9.22"
#noinspection NewerVersionAvailable
serialization = "1.5.1"

[plugins]
android = { id = "com.android.library", version.ref = "android" }
kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

[libraries]
kotest-assertions = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest" }
kotest-engine = { module = "io.kotest:kotest-framework-engine", version.ref = "kotest" }
kotest-runner = { module = "io.kotest:kotest-runner-junit5", version.ref = "kotest" }
openrtb = { module = "com.adsbynimbus.openrtb:kotlin-android", version = "development" }
serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" }

[bundles]
test = [
"kotest-assertions",
"kotest-engine",
"kotest-runner",
]
33 changes: 33 additions & 0 deletions integration-tests/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@file:Suppress("UnstableApiUsage")

pluginManagement {
repositories {
google {
mavenContent {
includeGroupAndSubgroups("androidx")
includeGroupAndSubgroups("com.android")
includeGroupAndSubgroups("com.google")
}
}
mavenCentral()
gradlePluginPortal()
}
}

dependencyResolutionManagement {
repositories {
mavenLocal()
google {
mavenContent {
includeGroupAndSubgroups("androidx")
includeGroupAndSubgroups("com.android")
includeGroupAndSubgroups("com.google")
}
}
mavenCentral()
}
}

rootProject.name = "nimbus-openrtb-integration-tests"

include("android")
6 changes: 3 additions & 3 deletions kotlin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ plugins {
}

android {
compileSdk = 35
compileSdk = 36
defaultConfig {
minSdk = 21
consumerProguardFile("src/androidMain/consumer-proguard-rules.pro")
Expand All @@ -37,8 +37,8 @@ kotlin {
sourceSets {
configureEach {
languageSettings {
apiVersion = KotlinVersion.KOTLIN_1_7.version
languageVersion = KotlinVersion.KOTLIN_1_7.version
apiVersion = KotlinVersion.KOTLIN_1_9.version
languageVersion = KotlinVersion.KOTLIN_1_9.version
optIn("kotlinx.serialization.ExperimentalSerializationApi")
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.adsbynimbus.openrtb.request
package com.adsbynimbus.openrtb

import com.adsbynimbus.openrtb.request.BidRequest
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.collections.shouldHaveSize
import io.kotest.matchers.maps.shouldContain
Expand Down Expand Up @@ -184,19 +185,23 @@ const val testJson = """
}
"""

class DeserializationTest : StringSpec({
class BidRequestTest : StringSpec({

val request = BidRequest.fromJson(testJson)
lateinit var request: BidRequest

"BidResponse fromJson deserializes the impression array" {
beforeTest {
request = BidRequest.fromJson(testJson)
}

"BidRequest fromJson deserializes the impression array" {
request.imp shouldHaveSize 1
}

"BidResponse fromJson deserializes the app object" {
"BidRequest fromJson deserializes the app object" {
request.app.shouldNotBeNull()
}

"BidResponse fromJson deserializes the device object" {
"BidRequest fromJson deserializes the device object" {
request.device.shouldNotBeNull()
request.device?.run {
ua shouldBe "test-ua-string"
Expand All @@ -206,38 +211,38 @@ class DeserializationTest : StringSpec({
}
}

"BidResponse fromJson deserializes the format object" {
"BidRequest fromJson deserializes the format object" {
request.format.w shouldBe 320
request.format.h shouldBe 480
}

"BidResponse fromJson deserializes the user object" {
"BidRequest fromJson deserializes the user object" {
request.user.shouldNotBeNull()
}

"BidResponse fromJson deserializes the source object" {
"BidRequest fromJson deserializes the source object" {
request.source.shouldNotBeNull()
}

"BidResponse fromJson deserializes the regs object" {
"BidRequest fromJson deserializes the regs object" {
request.regs.shouldNotBeNull()
}

"BidResponse fromJson deserializes the regs ext object" {
"BidRequest fromJson deserializes the regs ext object" {
request.regs?.ext.shouldNotBeNull()
request.regs?.ext?.gdpr shouldBe 0
request.regs?.ext?.us_privacy shouldBe "1YNN"
request.regs?.ext?.gpp shouldBe "DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA"
request.regs?.ext?.gpp_sids shouldBe "2"
}

"BidResponse fromJson deserializes the ext object" {
"BidRequest fromJson deserializes the ext object" {
request.ext.shouldNotBeEmpty()
request.ext.shouldContain("api_key", "12345678-4321-1234-0000-6c5b91b1eac6")
request.session_id shouldBe "session1"
}

"BidResponse fromJson deserialized EIDS" {
"BidRequest fromJson deserialized EIDS" {
request.user?.ext?.eids.shouldNotBeNull()
request.user?.ext?.eids?.run {
size shouldBe 2
Expand All @@ -252,7 +257,7 @@ class DeserializationTest : StringSpec({
}
}

"BidResponse fromJson deserialized native extension" {
"BidRequest fromJson deserialized native extension" {
request.imp[0].native?.ext?.nimbusNative?.run {
assets shouldHaveSize 3
context shouldBe 1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.adsbynimbus.openrtb.response
package com.adsbynimbus.openrtb

import com.adsbynimbus.openrtb.response.BidResponse
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.collections.shouldContain
import io.kotest.matchers.shouldBe
Expand Down Expand Up @@ -37,9 +38,13 @@ private fun testJson(ext: String = "") = """
}
"""

class DeserializationTest : StringSpec({
class BidResponseTest : StringSpec({

val response = BidResponse.fromJson(testJson())
lateinit var response: BidResponse

beforeTest {
response = BidResponse.fromJson(testJson())
}

"BidResponse fromJson deserializes the type field" {
response.type shouldBe "native"
Expand Down Expand Up @@ -113,7 +118,8 @@ class DeserializationTest : StringSpec({
"use_new_renderer": true
}
""".trimIndent())).ext.use_new_renderer shouldBe true
BidResponse.fromJson(testJson("""
BidResponse.fromJson(
testJson("""
,"ext": {
"use_new_renderer": false
}
Expand Down