com.asarkar.grpc.test.Resources.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of grpc-test Show documentation
Show all versions of grpc-test Show documentation
JUnit5 Extension that can automatically release gRPC resources at the end of the test
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)
}
}