Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8.9

This commit is contained in:
Florian Nücke 2016-04-16 14:45:33 +02:00
commit 25b6d214a7
4 changed files with 264 additions and 18 deletions

View File

@ -9,11 +9,14 @@ if #args < 2 then
io.write(" -r: copy directories recursively.\n")
io.write(" -u: copy only when the SOURCE file differs from the destination\n")
io.write(" file or when the destination file is missing.\n")
io.write(" -P: preserve attributes, e.g. symbolic links.\n")
io.write(" -v: verbose output.\n")
io.write(" -x: stay on original source file system.\n")
return 1
end
options.P = options.P or options.r
local from = {}
for i = 1, #args - 1 do
table.insert(from, shell.resolve(args[i]))
@ -66,6 +69,10 @@ end
local function recurse(fromPath, toPath, origin)
status(fromPath, toPath)
local isLink, target = fs.isLink(fromPath)
if isLink and options.P then
return fs.link(target, toPath)
end
if fs.isDirectory(fromPath) then
if not options.r then
io.write("omitting directory `" .. fromPath .. "'\n")

View File

@ -240,13 +240,20 @@ function buffer:read(...)
local function readLine(chop)
local start = 1
while true do
local l = self.bufferRead:find("\n", start, true)
if l then
local result = self.bufferRead:sub(1, l + (chop and -1 or 0))
self.bufferRead = self.bufferRead:sub(l + 1)
local buf = self.bufferRead
local i = buf:find("[\r\n]", start)
local c = i and buf:sub(i,i)
local is_cr = c == "\r"
if i and (not is_cr or i < #buf) then
local n = buf:sub(i+1,i+1)
if is_cr and n == "\n" then
c = c .. n
end
local result = buf:sub(1, i - 1) .. (chop and "" or c)
self.bufferRead = buf:sub(i + #c)
return result
else
start = #self.bufferRead
start = #self.bufferRead - (is_cr and 1 or 0)
local result, reason = readChunk()
if not result then
if reason then

View File

@ -267,12 +267,8 @@ private class Network private(private val data: mutable.Map[String, Network.Vert
node.address = java.util.UUID.randomUUID().toString
} while (data.contains(node.address) || otherNetwork.data.contains(node.address))
if (neighbors.isEmpty) {
assert(otherNetwork.data.size == 1)
Network.joinNewNetwork(node)
} else {
neighbors.foreach(_.connect(node))
}
Network.joinNewNetwork(node)
neighbors.filter(_.network != null).foreach(_.connect(node))
})
duplicates.head.data.network.asInstanceOf[Network.Wrapper].network
@ -568,6 +564,8 @@ object Network extends api.detail.NetworkAPI {
new Packet(source, destination, port, data, ttl)
}
var isServer = SideTracker.isServer _
class NodeBuilder(val _host: Environment, val _reachability: Visibility) extends api.detail.Builder.NodeBuilder {
def withComponent(name: String, visibility: Visibility) = new Network.ComponentBuilder(_host, _reachability, name, visibility)
@ -577,7 +575,7 @@ object Network extends api.detail.NetworkAPI {
def withConnector() = withConnector(0)
def create() = if (SideTracker.isServer) new MutableNode with NodeVarargPart {
def create() = if (isServer()) new MutableNode with NodeVarargPart {
val host = _host
val reachability = _reachability
}
@ -589,7 +587,7 @@ object Network extends api.detail.NetworkAPI {
def withConnector() = withConnector(0)
def create() = if (SideTracker.isServer) new Component with NodeVarargPart {
def create() = if (isServer()) new Component with NodeVarargPart {
val host = _host
val reachability = _reachability
val name = _name
@ -603,7 +601,7 @@ object Network extends api.detail.NetworkAPI {
def withComponent(name: String) = withComponent(name, _reachability)
def create() = if (SideTracker.isServer) new Connector with NodeVarargPart {
def create() = if (isServer()) new Connector with NodeVarargPart {
val host = _host
val reachability = _reachability
localBufferSize = _bufferSize
@ -612,7 +610,7 @@ object Network extends api.detail.NetworkAPI {
}
class ComponentConnectorBuilder(val _host: Environment, val _reachability: Visibility, val _name: String, val _visibility: Visibility, val _bufferSize: Double) extends api.detail.Builder.ComponentConnectorBuilder {
def create() = if (SideTracker.isServer) new ComponentConnector with NodeVarargPart {
def create() = if (isServer()) new ComponentConnector with NodeVarargPart {
val host = _host
val reachability = _reachability
val name = _name
@ -708,9 +706,8 @@ object Network extends api.detail.NetworkAPI {
}
nbt.setInteger("port", port)
nbt.setInteger("ttl", ttl)
val dataArray = data.toArray
nbt.setInteger("dataLength", dataArray.length)
for (i <- dataArray.indices) dataArray(i) match {
nbt.setInteger("dataLength", data.length)
for (i <- data.indices) data(i) match {
case null | Unit | None =>
case value: java.lang.Boolean => nbt.setBoolean("data" + i, value)
case value: java.lang.Integer => nbt.setInteger("data" + i, value)

View File

@ -0,0 +1,235 @@
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))
}
}