1 /* 2 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5 package kotlinx.coroutines 6 7 import org.junit.Test 8 import java.lang.reflect.* 9 import java.util.concurrent.* 10 import kotlin.test.* 11 12 @Suppress("DEPRECATION") 13 class CommonPoolTest { Trynull14 private inline fun <T> Try(block: () -> T) = try { block() } catch (e: Throwable) { null } 15 16 @Test testIsGoodCommonPoolnull17 fun testIsGoodCommonPool() { 18 // Test only on JDKs that has all we need 19 val fjpClass = Try { Class.forName("java.util.concurrent.ForkJoinPool") } ?: return 20 val wtfClass = Try { Class.forName("java.util.concurrent.ForkJoinPool${'$'}ForkJoinWorkerThreadFactory") } ?: return 21 val dwtfClass = Try { Class.forName("java.util.concurrent.ForkJoinPool${'$'}DefaultForkJoinWorkerThreadFactory") } ?: return 22 // We need private constructor to create "broken" FJP instance 23 val fjpCtor = Try { fjpClass.getDeclaredConstructor( 24 Int::class.java, 25 wtfClass, 26 Thread.UncaughtExceptionHandler::class.java, 27 Int::class.java, 28 String::class.java 29 ) } ?: return 30 fjpCtor.isAccessible = true 31 val dwtfCtor = Try { dwtfClass.getDeclaredConstructor() } ?: return 32 dwtfCtor.isAccessible = true 33 // Create bad pool 34 val fjp0: ExecutorService = createFJP(0, fjpCtor, dwtfCtor) ?: return 35 assertFalse(CommonPool.isGoodCommonPool(fjpClass, fjp0)) 36 fjp0.shutdown() 37 // Create good pool 38 val fjp1: ExecutorService = createFJP(1, fjpCtor, dwtfCtor) ?: return 39 assertTrue(CommonPool.isGoodCommonPool(fjpClass, fjp1)) 40 fjp1.shutdown() 41 } 42 createFJPnull43 private fun createFJP( 44 parallelism: Int, 45 fjpCtor: Constructor<out Any>, 46 dwtfCtor: Constructor<out Any> 47 ): ExecutorService? = Try { 48 fjpCtor.newInstance( 49 parallelism, 50 dwtfCtor.newInstance(), 51 Thread.getDefaultUncaughtExceptionHandler(), 52 0, 53 "Worker" 54 ) 55 } as? ExecutorService 56 }