1 /* 2 * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5 package kotlinx.coroutines.validator 6 7 import org.junit.Test 8 import org.objectweb.asm.* 9 import org.objectweb.asm.ClassReader.* 10 import org.objectweb.asm.ClassWriter.* 11 import org.objectweb.asm.Opcodes.* 12 import java.util.jar.* 13 import kotlin.test.* 14 15 class MavenPublicationMetaInfValidator { 16 17 @Test testMetaInfCoreStructurenull18 fun testMetaInfCoreStructure() { 19 val clazz = Class.forName("kotlinx.coroutines.Job") 20 JarFile(clazz.protectionDomain.codeSource.location.file).checkMetaInfStructure( 21 setOf( 22 "MANIFEST.MF", 23 "kotlinx-coroutines-core.kotlin_module", 24 "com.android.tools/proguard/coroutines.pro", 25 "com.android.tools/r8/coroutines.pro", 26 "proguard/coroutines.pro", 27 "versions/9/module-info.class", 28 "kotlinx_coroutines_core.version" 29 ) 30 ) 31 } 32 33 @Test testMetaInfAndroidStructurenull34 fun testMetaInfAndroidStructure() { 35 val clazz = Class.forName("kotlinx.coroutines.android.HandlerDispatcher") 36 JarFile(clazz.protectionDomain.codeSource.location.file).checkMetaInfStructure( 37 setOf( 38 "MANIFEST.MF", 39 "kotlinx-coroutines-android.kotlin_module", 40 "services/kotlinx.coroutines.CoroutineExceptionHandler", 41 "services/kotlinx.coroutines.internal.MainDispatcherFactory", 42 "com.android.tools/r8-from-1.6.0/coroutines.pro", 43 "com.android.tools/r8-upto-3.0.0/coroutines.pro", 44 "com.android.tools/proguard/coroutines.pro", 45 "proguard/coroutines.pro", 46 "versions/9/module-info.class", 47 "kotlinx_coroutines_android.version" 48 ) 49 ) 50 } 51 checkMetaInfStructurenull52 private fun JarFile.checkMetaInfStructure(expected: Set<String>) { 53 val actual = HashSet<String>() 54 for (e in entries()) { 55 if (e.isDirectory() || !e.realName.contains("META-INF")) { 56 continue 57 } 58 val partialName = e.realName.substringAfter("META-INF/") 59 actual.add(partialName) 60 } 61 62 if (actual != expected) { 63 val intersection = actual.intersect(expected) 64 val mismatch = actual.subtract(intersection) + expected.subtract(intersection) 65 fail("Mismatched files: " + mismatch) 66 } 67 68 close() 69 } 70 } 71