All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.yag.punner.core.TestingServer.kt Maven / Gradle / Ivy

Go to download

Punner is a parallel JUnit test runner and maven plugin which can speed up your unit test.

There is a newer version: 0.9.17
Show newest version
package com.github.yag.punner.core

import org.junit.After
import org.junit.AfterClass
import org.junit.Before
import org.junit.BeforeClass
import org.junit.ComparisonFailure
import org.junit.runners.model.FrameworkMethod
import org.junit.runners.model.TestClass
import java.io.File
import java.io.ObjectOutputStream
import java.lang.AssertionError

internal object TestingServer {

    private val classInstanceCache = HashMap, Any>()

    @JvmStatic
    fun main(args: Array) {
        val delimiter = args[0]

        System.`in`.bufferedReader().lines().forEach {
            runCommand(it, delimiter)

        }

        shutdown()
    }

    internal fun shutdown() {
        classInstanceCache.forEach { t, _ ->
            val afterClass = TestClass(t).getAnnotatedMethods(AfterClass::class.java)
            afterClass.forEach {
                it.invokeExplosively(null)
            }
        }
    }

    @Suppress("UNCHECKED_CAST")
    internal fun  getInstance(clazz: Class): T {
        var instance = classInstanceCache[clazz]
        return if (instance == null) {
            clazz.newInstance().apply {
                classInstanceCache[clazz] = this as Any
                val beforeClass = TestClass(clazz).getAnnotatedMethods(BeforeClass::class.java)
                beforeClass.forEach {
                    it.invokeExplosively(null)
                }
            }
        } else {
            instance as T
        }
    }

    private fun runCommand(command: String, delimiter: String) : TestResultStore {
        val parameters = command.split(" ")

        // This file only used for test result passing, no log data.
        val (className, methodName, resultPath) = parameters

        val resultOutput = ObjectOutputStream(File(resultPath).outputStream())

        val clazz = Class.forName(className)

        val result = test(clazz, methodName, delimiter)

        result.write(resultOutput)

        resultOutput.flush()
        resultOutput.close()

        println(magicFinish(delimiter))
        System.out.flush()

        return result
    }

    internal fun test(clazz: Class<*>, methodName: String, delimiter: String) : TestResultStore {
        val props = System.getProperties()
        var after: List? = null
        var instance: Any? = null

        try {
            instance = getInstance(clazz)

            val testClass = TestClass(clazz)

            val before = testClass.getAnnotatedMethods(Before::class.java)
            after = testClass.getAnnotatedMethods(After::class.java)

            val method = FrameworkMethod(clazz.getMethod(methodName))

            before.forEach { it.invokeExplosively(instance) }

            println(magicStart(delimiter))
            method.invokeExplosively(instance)
            return TestResultStore(ResultType.SUCCESS, NoError, props)
        } catch (e: Throwable) {
            return TestResultStore(getResultType(e), e, props)
        } finally {
            after?.forEach { method ->
                instance?.let { instance ->
                    method.invokeExplosively(instance)
                }
            }
        }
    }

}

/**
 * Get result type by exception.
 * @param e exception
 */
fun getResultType(e: Throwable): ResultType {
    return when (e) {
        is AssertionError, is ComparisonFailure -> ResultType.FAILURE
        else -> ResultType.ERROR
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy