blob: b7f97f033ea95b1a3bf577cfde48f4d0205849fa [file] [log] [blame]
/*
* Copyright 2016-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package kotlinx.coroutines.validator
import org.junit.*
import org.junit.Assert.*
import java.io.*
import java.util.jar.*
class MavenPublicationValidator {
private val ATOMIC_FU_REF = "Lkotlinx/atomicfu/".toByteArray()
@Test
fun testNoAtomicfuInClasspath() {
val result = runCatching { Class.forName("kotlinx.atomicfu.AtomicInt") }
assertTrue(result.exceptionOrNull() is ClassNotFoundException)
}
@Test
fun testNoAtomicfuInMppJar() {
val clazz = Class.forName("kotlinx.coroutines.Job")
JarFile(clazz.protectionDomain.codeSource.location.file).checkForAtomicFu()
}
@Test
fun testNoAtomicfuInAndroidJar() {
val clazz = Class.forName("kotlinx.coroutines.android.HandlerDispatcher")
JarFile(clazz.protectionDomain.codeSource.location.file).checkForAtomicFu()
}
private fun JarFile.checkForAtomicFu() {
val foundClasses = mutableListOf<String>()
for (e in entries()) {
if (!e.name.endsWith(".class")) continue
val bytes = getInputStream(e).use { it.readBytes() }
loop@for (i in 0 until bytes.size - ATOMIC_FU_REF.size) {
for (j in 0 until ATOMIC_FU_REF.size) {
if (bytes[i + j] != ATOMIC_FU_REF[j]) continue@loop
}
foundClasses += e.name // report error at the end with all class names
break@loop
}
}
if (foundClasses.isNotEmpty()) {
error("Found references to atomicfu in jar file $name in the following class files: ${
foundClasses.joinToString("") { "\n\t\t" + it }
}")
}
close()
}
}