Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ fun signPublicationIfKeyPresent(project: Project, publication: MavenPublication)
project.extensions.configure<SigningExtension>("signing") {
useInMemoryPgpKeys(keyId, signingKey, signingKeyPassphrase)
sign(publication)

// Temporary workaround, see https://github.com/gradle/gradle/issues/26091#issuecomment-1722947958
tasks.withType<AbstractPublishToMaven>().configureEach {
val signingTasks = tasks.withType<Sign>()
mustRunAfter(signingTasks)
}
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ allprojects {

@OptIn(ExperimentalBCVApi::class)
apiValidation {
ignoredProjects.add("kotlinx-io-benchmarks")
ignoredProjects.addAll(listOf(
"kotlinx-io-benchmarks",
"kotlinx-io-smoke-tests"
))
klib.enabled = true
}

Expand Down
3 changes: 3 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ rootProject.name = "kotlinx-io"
include(":kotlinx-io-core")
include(":kotlinx-io-benchmarks")
include(":kotlinx-io-bytestring")
include(":kotlinx-io-smoke-tests")

project(":kotlinx-io-core").projectDir = file("./core")
project(":kotlinx-io-benchmarks").projectDir = file("./benchmarks")
project(":kotlinx-io-bytestring").projectDir = file("./bytestring")
project(":kotlinx-io-smoke-tests").projectDir = file("./smoke-tests")
20 changes: 20 additions & 0 deletions smoke-tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Tests aimed to verify that all artifacts are published correctly
and there are no dependency related issues.

There are two sets of tests: one targeting Gradle projects and another targeting Maven projects.
Each set could be invoked independently via `verifyGradleProjects` and `verifyMavenProjects` tasks
correspondingly. Both tasks are aggregated by the `smokeTest` task.

Note that `check` and `test` tasks are no-op.

Tests could be executed against arbitrary `kotlinx-io` version. The version could be set using
`smokeTest.kotlinxIoVersion` property. If the property is unset or has a blank value, current project
version will be used instead. In that case, local maven repo will be used and publication tasks
will be executed before any tests.

For projects published to a staging Sonatype repository it's possible to specify repository ID
using `smokeTest.stagingRepository` property.

### How to run

`./gradlew :kotlinx-io-smoke-tests:smokeTest -PsmokeTest.kotlinxIoVersion=0.5.3-test -PsmokeTest.stagingRepository=orgjetbrainskotlinx-3482`
100 changes: 100 additions & 0 deletions smoke-tests/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import org.apache.tools.ant.taskdefs.condition.Os

plugins {
kotlin("jvm")
}

val stagingRepositoryIdRawValue = project.findProperty("smokeTest.stagingRepository")?.toString()

val stagingRepositoryId: String = if (stagingRepositoryIdRawValue != null) {
stagingRepositoryIdRawValue
} else {
logger.warn("smokeTest.stagingRepository was not set.")
""
}

val stagingRepository: String = "https://oss.sonatype.org/content/repositories/$stagingRepositoryId"

val kotlinxIoVersionRawValue = project.findProperty("smokeTest.kotlinxIoVersion")?.toString()
var useLocalBuild = false

val kotlinxIoVersion: String = if (kotlinxIoVersionRawValue.isNullOrBlank()) {
useLocalBuild = true
val v = version.toString()
logger.warn("smokeTest.kotlinxIoVersion was not specified, using $v instead.")
v
} else {
kotlinxIoVersionRawValue
}

repositories {
mavenCentral()
}

tasks {
val kotlinVersion: String = libs.versions.kotlin.get()

val verifyMavenProjects by registering(Exec::class) {
workingDir = projectDir.resolve("src").resolve("test").resolve("resources").resolve("maven-projects")
executable = workingDir.resolve(getMavenWrapperName()).absolutePath
args = buildList {
add("-DKOTLIN_VERSION=$kotlinVersion")
add("-DKOTLINX_IO_VERSION=$kotlinxIoVersion")
if (stagingRepository.isNotBlank()) {
add("-DSTAGING_REPOSITORY_URL=$stagingRepository")
add("-Pstaging")
}
add("verify")
}
if (useLocalBuild) {
dependsOn(project(":kotlinx-io-core").tasks.named("publishToMavenLocal"))
dependsOn(project(":kotlinx-io-bytestring").tasks.named("publishToMavenLocal"))
}
}
val cleanMavenProjects by registering(Exec::class) {
workingDir = projectDir.resolve("src").resolve("test").resolve("resources").resolve("maven-projects")
executable = workingDir.resolve(getMavenWrapperName()).absolutePath
args = listOf("-DKOTLIN_VERSION=$kotlinVersion", "-DKOTLINX_IO_VERSION=$kotlinxIoVersion", "clean")
}

val verifyGradleProjects = create("verifyGradleProjects", Test::class) {
useJUnit()
if (useLocalBuild) {
dependsOn(project(":kotlinx-io-core").tasks.named("publishToMavenLocal"))
dependsOn(project(":kotlinx-io-bytestring").tasks.named("publishToMavenLocal"))
}

systemProperty("kotlinxIoVersion", kotlinxIoVersion)
systemProperty("stagingRepository", stagingRepository)
systemProperty("useLocalBuild", useLocalBuild)
systemProperty("kotlinVersion", kotlinVersion)
}

create("smokeTest") {
dependsOn(verifyMavenProjects)
dependsOn(verifyGradleProjects)
}

named("clean").configure {
dependsOn(cleanMavenProjects)
}

check.configure {
enabled = false
}
test.configure {
enabled = false
}
}

dependencies {
testImplementation(kotlin("test"))
testImplementation(gradleTestKit())
}

fun getMavenWrapperName(): String =
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
"mvnw.cmd"
} else {
"mvnw"
}
114 changes: 114 additions & 0 deletions smoke-tests/src/test/kotlin/GradleProjectsTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright 2017-2024 JetBrains s.r.o. and respective authors and developers.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENCE file.
*/

package kotlinx.io

import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import kotlin.io.path.outputStream
import kotlin.test.Test
import kotlin.test.assertEquals

private const val buildScriptFilename = "build.gradle.kts"
private const val settingsFilename = "settings.gradle.kts"

public class GradleProjectsTest {
@JvmField
@Rule
public val projectDir = TemporaryFolder()

private val kotlinxIoVersion: String = System.getProperty("kotlinxIoVersion")!!
private val kotlinVersion: String = System.getProperty("kotlinVersion")!!
private val useLocalBuild: String = System.getProperty("useLocalBuild")!!
private val stagingRepository: String = System.getProperty("stagingRepository")!!
private val bytestringDependency: String = "org.jetbrains.kotlinx:kotlinx-io-bytestring:$kotlinxIoVersion"
private val coreDependency: String = "org.jetbrains.kotlinx:kotlinx-io-core:$kotlinxIoVersion"

private fun generateBuildScript(multiplatform: Boolean, dependencyName: String) {
val templateFile = (if (multiplatform) "kmp" else "jvm") + "." + buildScriptFilename
var template = GradleProjectsTest::class.java.getResourceAsStream(
"/templates/$templateFile")!!.reader().readText()

template = template.replace("%DEPENDENCY%", dependencyName)
.replace("%KOTLIN_VERSION%", kotlinVersion)
.replace("%USE_LOCAL_REPO%", useLocalBuild)
.replace("%STAGING_REPOSITORY%", stagingRepository)

val outFile = projectDir.newFile(buildScriptFilename)
outFile.writeText(template)
}

private fun setupTest(testCase: String, multiplatform: Boolean, dependencyName: String) {
copySrcFile(testCase, multiplatform)

projectDir.newFile(settingsFilename).outputStream().use {
GradleProjectsTest::class.java.getResourceAsStream("/templates/$settingsFilename")!!.copyTo(it)
}

generateBuildScript(multiplatform, dependencyName)
}

private fun copySrcFile(testCase: String, multiplatform: Boolean) {
val testSubdir = if (multiplatform) "commonTest" else "test"
val srcDir = projectDir.newFolder("src", testSubdir, "kotlin")
val resource = GradleProjectsTest::class.java.getResourceAsStream("/gradle-projects/$testCase/SmokeTest.kt")!!
val outFile = srcDir.toPath().resolve("SmokeTest.kt")
outFile.outputStream().use {
resource.copyTo(it)
}
}

private fun assertTestPassed(buildResult: BuildResult, taskName: String = ":test") {
assertEquals(TaskOutcome.SUCCESS, buildResult.task(taskName)?.outcome,
"Task \"$taskName\" should pass.\n" + buildResult.output)
}

@Test
fun bytestringJvm() {
setupTest("bytestring-jvm", false, bytestringDependency)
val results = GradleRunner.create()
.withProjectDir(projectDir.root)
.withArguments(":test")
.run()

assertTestPassed(results)
}

@Test
fun coreJvm() {
setupTest("core-jvm", false, coreDependency)
val results = GradleRunner.create()
.withProjectDir(projectDir.root)
.withArguments(":test")
.run()

assertTestPassed(results)
}

@Test
fun bytestringMultiplatform() {
setupTest("bytestring-multiplatform", true, bytestringDependency)
val results = GradleRunner.create()
.withProjectDir(projectDir.root)
.withArguments(":allTests")
.run()

assertTestPassed(results, ":allTests")
}

@Test
fun coreMultiplatform() {
setupTest("core-multiplatform", true, coreDependency)
val results = GradleRunner.create()
.withProjectDir(projectDir.root)
.withArguments(":allTests")
.run()

assertTestPassed(results, ":allTests")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2017-2024 JetBrains s.r.o. and respective authors and developers.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENCE file.
*/

package org.example

import kotlinx.io.bytestring.ByteString
import kotlin.test.Test
import kotlin.test.assertEquals

class SmokeTest {
@Test
fun test() {
assertEquals("ByteString(size=1 hex=42)", ByteString(0x42).toString())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright 2017-2024 JetBrains s.r.o. and respective authors and developers.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENCE file.
*/

import kotlinx.io.bytestring.ByteString
import kotlin.test.Test
import kotlin.test.assertEquals

class SmokeTest {
@Test
fun test() {
assertEquals("ByteString(size=1 hex=42)", ByteString(0x42).toString())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2017-2024 JetBrains s.r.o. and respective authors and developers.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENCE file.
*/

package org.example

import kotlinx.io.Buffer
import kotlinx.io.bytestring.ByteString
import kotlinx.io.readByteArray
import kotlinx.io.readByteString
import kotlinx.io.write
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals

class SmokeTest {
@Test
fun testCore() {
val buffer = Buffer()
buffer.writeLong(0)
assertContentEquals(ByteArray(8), buffer.readByteArray())
}

@Test
fun testByteString() {
val byteString = ByteString(0x42)
val buffer = Buffer()
buffer.write(byteString)

assertEquals(ByteString(0x42), buffer.readByteString())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2017-2024 JetBrains s.r.o. and respective authors and developers.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENCE file.
*/

import kotlinx.io.Buffer
import kotlinx.io.bytestring.ByteString
import kotlinx.io.files.Path
import kotlinx.io.files.SystemFileSystem
import kotlinx.io.readByteArray
import kotlinx.io.readByteString
import kotlinx.io.write
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals

class SmokeTest {
@Test
fun testCore() {
val buffer = Buffer()
buffer.writeLong(0)
assertContentEquals(ByteArray(8), buffer.readByteArray())
}

@Test
fun testByteString() {
val byteString = ByteString(0x42)
val buffer = Buffer()
buffer.write(byteString)

assertEquals(ByteString(0x42), buffer.readByteString())
}

@Test
fun testUseFiles() {
try {
SystemFileSystem.exists(Path("."))
} catch (t: Throwable) {
// that's fine
}
}
}
Binary file not shown.
Loading