pgpainless/wot-dijkstra/src/testFixtures/kotlin/org/pgpainless/wot/dsl/NetworkDSL.kt

190 lines
7.2 KiB
Kotlin

// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>
//
// SPDX-License-Identifier: Apache-2.0
package org.pgpainless.wot.dsl
import org.pgpainless.wot.network.*
import java.util.*
/**
* Tons of useful DSL for [Network]-related testing.
*/
interface NetworkDSL {
/**
* Create a [Node] from a [String] fingerprint.
*/
fun Node(fingerprint: String): Node =
Node(Fingerprint(fingerprint), null, RevocationState.notRevoked(), mapOf())
/**
* Create a [Node] from a [String] fingerprint and non-revoked [userId].
*/
fun Node(fingerprint: String, userId: String): Node = Node(
Fingerprint(fingerprint), null, RevocationState.notRevoked(), mapOf(userId to RevocationState.notRevoked()))
fun Node(original: Node, userId: String): Node = Node(
original.fingerprint, original.expirationTime, original.revocationState, original.userIds.plus(userId to RevocationState.notRevoked())
)
/**
* Create an [EdgeComponent] from two [Node] nodes.
*/
fun EdgeComponent(issuer: Node, target: Node): EdgeComponent =
EdgeComponent(issuer, target, null, Date())
/**
* Create an [EdgeComponent] from two [Node] nodes and a target [userId].
*/
fun EdgeComponent(issuer: Node, target: Node, userId: String): EdgeComponent =
EdgeComponent(issuer, target, userId, Date())
fun EdgeComponent(issuer: Node, target: Node, amount: Int, depth: Depth): EdgeComponent =
EdgeComponent(issuer, target, null, Date(), null, true, amount, depth, RegexSet.wildcard())
/**
* Add a single [Node] built from a [String] fingerprint to the builder.
*/
fun Network.Builder.addNode(fingerprint: String): Network.Builder {
return addNode(Node(fingerprint))
}
/**
* Add a single [Node] built from a [String] fingerprint and [userId] to the builder.
*/
fun Network.Builder.addNode(fingerprint: String, userId: String): Network.Builder {
return addNode(Node(fingerprint, userId))
}
/**
* Add multiple [Node] nodes built from [String] fingerprints to the builder.
*/
fun Network.Builder.addNodes(vararg fingerprints: String) {
for (fingerprint in fingerprints) {
addNode(fingerprint)
}
}
/**
* Add an edge between the [Node] with fingerprint [issuer] and
* the [Node] with fingerprint [target].
* If either the issuer or target node doesn't exist, throw an [IllegalArgumentException].
*/
fun Network.Builder.addEdge(issuer: String, target: String): Network.Builder {
val issuerNode = nodes[Fingerprint(issuer)]!!
val targetNode = nodes[Fingerprint(target)]!!
return addEdge(EdgeComponent(issuerNode, targetNode))
}
/**
* Add an edge for [userId] between the [Node] with fingerprint [issuer] and
* the [Node] with fingerprint [target].
* If either the issuer or target node doesn't exist, throw an [IllegalArgumentException].
*/
fun Network.Builder.addEdge(issuer: String, target: String, userId: String): Network.Builder {
val issuerNode = nodes[Fingerprint(issuer)]!!
val targetNode = nodes[Fingerprint(target)]!!
return addEdge(EdgeComponent(issuerNode, targetNode, userId))
}
/**
* Add an edge between the issuer and target node. If either of them doesn't exist, add
* a new node for them to the builder.
*/
fun Network.Builder.buildEdge(issuer: String, target: String): Network.Builder {
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { Node(issuer) }
val targetNode = nodes.getOrPut(Fingerprint(target)) { Node(target) }
return addEdge(EdgeComponent(issuerNode, targetNode))
}
/**
* Add an edge for [userId] between the issuer and the target node. If either of them doesn't
* exist, add a new node.
* If the target node exists, but doesn't carry the [userId], replace it with a copy with
* the [userId] inserted.
*/
fun Network.Builder.buildEdge(issuer: String, target: String, userId: String): Network.Builder {
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { Node(issuer)}
val targetNode = Node(nodes.getOrPut(Fingerprint(target)) { Node(target, userId) }, userId)
return addEdge(EdgeComponent(issuerNode, targetNode, userId))
}
fun Network.Builder.buildEdge(issuer: String, target: String, amount: Int, depth: Int): Network.Builder {
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { Node(issuer) }
val targetNode = nodes.getOrPut(Fingerprint(target)) { Node(target) }
return addEdge(EdgeComponent(issuerNode, targetNode, null, Date(), null, true, amount, Depth.auto(depth), RegexSet.wildcard()))
}
fun Network.Builder.buildEdge(issuer: String, target: String, amount: Int, depth: Int, regexSet: RegexSet): Network.Builder {
val issuerNode = nodes.getOrPut(Fingerprint(issuer)) { Node(issuer) }
val targetNode = nodes.getOrPut(Fingerprint(target)) { Node(target) }
return addEdge(EdgeComponent(issuerNode, targetNode, null, Date(), null, true, amount, Depth.auto(depth), regexSet))
}
/**
* Set the reference time of the builder to now.
*/
fun Network.Builder.now(): Network.Builder {
return setReferenceTime(ReferenceTime.now())
}
fun Network.getEdgesFor(issuer: Fingerprint, target: Fingerprint): Edge? {
return edges[issuer]?.find { it.target.fingerprint == target }
}
fun Network.getEdgesFor(issuer: String, target: String): Edge? {
return getEdgesFor(Fingerprint(issuer), Fingerprint(target))
}
fun Network.getEdgeFor(issuer: Fingerprint, target: Fingerprint): List<EdgeComponent>? {
return getEdgeFor(issuer, target, null)
}
fun Network.getEdgeFor(issuer: Fingerprint, target: Fingerprint, userId: String?): List<EdgeComponent>? {
return getEdgesFor(issuer, target)?.components?.get(userId)
}
fun Network.getEdgeFor(issuer: String, target: String): List<EdgeComponent>? {
return getEdgeFor(issuer, target, null)
}
fun Network.getEdgeFor(issuer: String, target: String, userId: String?): List<EdgeComponent>? {
return getEdgeFor(Fingerprint(issuer), Fingerprint(target), userId)
}
fun Date.plusMillis(millis: Long): Date {
return Date(time + millis)
}
fun Date.plusSeconds(seconds: Long): Date {
return plusMillis(1000L * seconds)
}
fun Date.plusMinutes(minutes: Long): Date {
return plusSeconds(60 * minutes)
}
fun Date.plusHours(hours: Long): Date {
return plusMinutes(60 * hours)
}
fun Date.plusDays(days: Long): Date {
return plusHours(24 * days)
}
fun domainRegex(domain: String): RegexSet {
return RegexSet.fromExpression("<[^>]+[@.]" + domain.replace(".", "\\.") + ">$")
}
/**
* Lambda with Receiver.
*
* @see <a href="https://betterprogramming.pub/test-data-creation-using-the-power-of-kotlin-dsl-9526a1fad05b"/>
*/
fun buildNetwork(builderAction: Network.Builder.() -> Unit): Network {
val builder = Network.builder()
builder.builderAction()
return builder.build()
}
}