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

com.asarkar.grpc.test.Resources.kt Maven / Gradle / Ivy

Go to download

JUnit5 Extension that can automatically release gRPC resources at the end of the test

There is a newer version: 1.2.2
Show newest version
package com.asarkar.grpc.test

import io.grpc.ManagedChannel
import io.grpc.Server
import java.time.Duration
import java.time.Instant
import java.util.Objects

/**
 * A collection of [Resource]s used by the test that will be released at the end.
 *
 * @author Abhijit Sarkar
 * @since 1.0.0
 */
class Resources {
    private val resources = mutableMapOf()
    private var timeout = Duration.ofSeconds(5)

    /**
     * Registers the given server with the extension. Once registered, the server will be automatically
     * shutdown at the end of the test.
     *
     * @param server server that will be registered.
     * @param timeout a positive time limit for the server to shutdown. If it fails to shutdown
     * in time, the test will fail. Defaults to 5 seconds.
     *
     * @return this
     */
    fun  register(server: T, timeout: Duration = this.timeout): Resources {
        return this.apply { [email protected][ServerResource(server)] = timeout }
    }

    /**
     * Registers the given channel with the extension. Once registered, the channel will be automatically
     * closed at the end of the test.
     *
     * @param channel channel that will be registered.
     * @param timeout a positive time limit for the channel to close. If it fails to close
     * in time, the test will fail. Defaults to 5 seconds.
     *
     * @return this
     */
    fun  register(channel: T, timeout: Duration = this.timeout): Resources {
        return this.apply {
            [email protected][
                ManagedChannelResource(channel)
            ] = timeout
        }
    }

    /**
     * A positive time limit for the registered resources to be released. If the resources fail to
     * release in time, the test will fail. Defaults to 5 seconds. Calling this method does not change
     * the timeout for the resources previously registered.
     *
     * @param timeout
     *
     * @return this
     */
    fun timeout(timeout: Duration): Resources {
        return this.apply { [email protected] = timeout }
    }

    internal fun cleanUp() {
        resources.keys.forEach { it.cleanUp() }
    }

    internal fun forceCleanUp() {
        resources.keys.forEach { it.forceCleanUp() }
    }

    internal fun awaitReleased(): Boolean {
        val start = Instant.now()
        var successful = true
        resources.forEach { (r, t) ->
            try {
                val timeout = t.minus(Duration.between(Instant.now(), start))
                if (timeout.isNegative || !r.awaitReleased(timeout)) {
                    successful = false
                    r.forceCleanUp()
                }
            } catch (e: InterruptedException) {
                successful = false
                Thread.currentThread().interrupt()
                r.forceCleanUp()
            }
        }
        return successful
    }

    override fun toString(): String {
        return if (resources.isEmpty()) "Resources[]" else "Resources${resources.keys.map { it.toString() }}"
    }

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as Resources

        return resources.keys == other.resources.keys
    }

    override fun hashCode(): Int {
        return Objects.hashCode(resources.keys)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy