blob: 73d6839e19b3779df8d3d83680b41301edfc8827 [file] [log] [blame] [raw]
import li.cil.oc.api
import li.cil.oc.api.network.Environment
import li.cil.oc.api.network.Message
import li.cil.oc.api.network.Node
import li.cil.oc.api.network.Visibility
import li.cil.oc.server.network.Network
import li.cil.oc.server.network.{Node => MutableNode}
import org.scalatest._
import org.scalatest.mock.MockitoSugar
import scala.collection.convert.WrapAsScala._
class NetworkTest extends FlatSpec with MockitoSugar {
Network.isServer = () => true
api.API.network = Network
val host = mock[Environment]
"A Node" should "not belong to a network after creation" in {
val node = api.Network.newNode(host, Visibility.Network).create()
assert(node.network == null)
}
it should "belong to a network after joining a new network" in {
val node = api.Network.newNode(host, Visibility.Network).create()
api.Network.joinNewNetwork(node)
assert(node.network != null)
}
it should "not belong to a network after being removed from its new network" in {
val node = api.Network.newNode(host, Visibility.Network).create()
api.Network.joinNewNetwork(node)
node.remove()
assert(node.network == null)
}
it should "have a neighbor after being connected to another node" in {
val node1 = api.Network.newNode(host, Visibility.Network).create()
api.Network.joinNewNetwork(node1)
val node2 = api.Network.newNode(host, Visibility.Network).create()
node1.connect(node2)
assert(node1.neighbors.nonEmpty)
assert(node2.neighbors.nonEmpty)
assert(node1.isNeighborOf(node2))
assert(node2.isNeighborOf(node1))
}
it should "be reachable by neighbors when visibility is set to Neighbors" in {
val node1 = api.Network.newNode(host, Visibility.Neighbors).create()
api.Network.joinNewNetwork(node1)
val node2 = api.Network.newNode(host, Visibility.Network).create()
node1.connect(node2)
assert(node1.canBeReachedFrom(node2))
}
it should "be in the same network as nodes it is connected to" in {
val node1 = api.Network.newNode(host, Visibility.Network).create()
api.Network.joinNewNetwork(node1)
val node2 = api.Network.newNode(host, Visibility.Network).create()
node1.connect(node2)
val node3 = api.Network.newNode(host, Visibility.Network).create()
node2.connect(node3)
assert(node1.network == node2.network)
assert(node2.network == node3.network)
assert(node1.network == node3.network)
}
it should "have a different address than nodes it is connected to" in {
val node1 = api.Network.newNode(host, Visibility.Network).create()
api.Network.joinNewNetwork(node1)
val node2 = api.Network.newNode(host, Visibility.Network).create()
node1.connect(node2)
val node3 = api.Network.newNode(host, Visibility.Network).create()
node2.connect(node3)
assert(node1.address != node2.address)
assert(node2.address != node3.address)
assert(node1.address != node3.address)
}
it should "not be reachable by non neighbors when visibility is set to Neighbors" in {
val node1 = api.Network.newNode(host, Visibility.Neighbors).create()
api.Network.joinNewNetwork(node1)
val node2 = api.Network.newNode(host, Visibility.Network).create()
node1.connect(node2)
val node3 = api.Network.newNode(host, Visibility.Network).create()
node2.connect(node3)
assert(!node1.canBeReachedFrom(node3))
}
it should "be reachable by all nodes when visibility is set to Network" in {
val node1 = api.Network.newNode(host, Visibility.Network).create()
api.Network.joinNewNetwork(node1)
val node2 = api.Network.newNode(host, Visibility.Network).create()
node1.connect(node2)
val node3 = api.Network.newNode(host, Visibility.Network).create()
node2.connect(node3)
assert(node1.canBeReachedFrom(node2))
assert(node1.canBeReachedFrom(node3))
}
it should "not be reachable by any node when visibility is set to None" in {
val node1 = api.Network.newNode(host, Visibility.None).create()
api.Network.joinNewNetwork(node1)
val node2 = api.Network.newNode(host, Visibility.Network).create()
node1.connect(node2)
val node3 = api.Network.newNode(host, Visibility.Network).create()
node2.connect(node3)
assert(!node1.canBeReachedFrom(node2))
assert(!node1.canBeReachedFrom(node3))
}
it should "be in a separate network after a netsplit" in {
val node1 = api.Network.newNode(host, Visibility.Network).create()
api.Network.joinNewNetwork(node1)
val node2 = api.Network.newNode(host, Visibility.Network).create()
node1.connect(node2)
val node3 = api.Network.newNode(host, Visibility.Network).create()
node2.connect(node3)
node2.remove()
assert(node1.network != null)
assert(node2.network == null)
assert(node3.network != null)
assert(node1.network != node3.network)
}
it should "change its address when joining a network containing a node with its address" in {
val node1 = api.Network.newNode(host, Visibility.Network).create()
api.Network.joinNewNetwork(node1)
val node2 = api.Network.newNode(host, Visibility.Network).create()
node2.asInstanceOf[MutableNode].address = node1.address
node1.connect(node2)
assert(node1.address != node2.address)
}
"A Network" should "keep its local layout after being merged with another network" in {
val node1 = api.Network.newNode(host, Visibility.Network).create()
api.Network.joinNewNetwork(node1)
val node2 = api.Network.newNode(host, Visibility.Network).create()
node1.connect(node2)
val node3 = api.Network.newNode(host, Visibility.Network).create()
node2.connect(node3)
val node4 = api.Network.newNode(host, Visibility.Network).create()
api.Network.joinNewNetwork(node4)
val node5 = api.Network.newNode(host, Visibility.Network).create()
node4.connect(node5)
val node6 = api.Network.newNode(host, Visibility.Network).create()
node5.connect(node6)
node2.connect(node5)
assert(node1.neighbors.size == 1 && node1.isNeighborOf(node2))
assert(node3.neighbors.size == 1 && node3.isNeighborOf(node2))
assert(node4.neighbors.size == 1 && node4.isNeighborOf(node5))
assert(node6.neighbors.size == 1 && node6.isNeighborOf(node5))
assert(node2.isNeighborOf(node5))
}
it should "keep its local layout after being merged with another network containing nodes with duplicate addresses at bridge points" in {
val node1 = api.Network.newNode(host, Visibility.Network).create()
api.Network.joinNewNetwork(node1)
val node2 = api.Network.newNode(host, Visibility.Network).create()
node1.connect(node2)
val node3 = api.Network.newNode(host, Visibility.Network).create()
node1.connect(node3)
val node4 = api.Network.newNode(host, Visibility.Network).create()
node3.connect(node4)
val node5 = api.Network.newNode(host, Visibility.Network).create()
node5.asInstanceOf[MutableNode].address = node1.address
api.Network.joinNewNetwork(node5)
val node6 = api.Network.newNode(host, Visibility.Network).create()
node6.asInstanceOf[MutableNode].address = node2.address
node5.connect(node6)
val node7 = api.Network.newNode(host, Visibility.Network).create()
node7.asInstanceOf[MutableNode].address = node3.address
node5.connect(node7)
val node8 = api.Network.newNode(host, Visibility.Network).create()
node8.asInstanceOf[MutableNode].address = node4.address
node7.connect(node8)
node3.connect(node7)
assert(node1.neighbors.size == 2 && node1.isNeighborOf(node2) && node1.isNeighborOf(node3))
assert(node2.neighbors.size == 1 && node2.isNeighborOf(node1))
assert(node3.neighbors.size == 3 && node3.isNeighborOf(node1) && node3.isNeighborOf(node4) && node3.isNeighborOf(node7))
assert(node4.neighbors.size == 1 && node4.isNeighborOf(node3))
assert(node5.neighbors.size == 2 && node5.isNeighborOf(node6) && node5.isNeighborOf(node7))
assert(node6.neighbors.size == 1 && node6.isNeighborOf(node5))
assert(node7.neighbors.size == 3 && node7.isNeighborOf(node5) && node7.isNeighborOf(node8) && node7.isNeighborOf(node3))
assert(node8.neighbors.size == 1 && node8.isNeighborOf(node7))
}
it should "not error when nodes disconnect themselves in a remapping operation" in {
val host = new Environment {
val node1 = api.Network.newNode(this, Visibility.Network).create()
val node2 = api.Network.newNode(this, Visibility.Network).create()
api.Network.joinNewNetwork(node1)
override def node: Node = node1
override def onMessage(message: Message): Unit = {}
override def onConnect(node: Node): Unit = {
if (node == node1) {
node.connect(node2)
}
}
override def onDisconnect(node: Node): Unit = {
if (node == node1) {
node2.remove()
}
}
}
val node3 = api.Network.newNode(host, Visibility.Network).create()
node3.asInstanceOf[MutableNode].address = host.node.address
api.Network.joinNewNetwork(node3)
node3.connect(host.node)
assert(host.node1.neighbors.size == 2 && host.node1.isNeighborOf(host.node2) && host.node1.isNeighborOf(node3))
assert(host.node2.neighbors.size == 1 && host.node2.isNeighborOf(host.node1))
assert(node3.neighbors.size == 1 && node3.isNeighborOf(host.node1))
}
}