Files
fs25-adsmartpickup/tests/test_adWaitPool.lua
T

161 lines
7.5 KiB
Lua

-- Kør: luajit tests/test_adWaitPool.lua (fra repo-roden)
-- Wait-puljen: kandidater pr. mappe, reservationer, nærmeste ledige, rutetjek, redirect.
dofile("FS25_ADSmartPickup/adSupplyPlanner.lua")
dofile("FS25_ADSmartPickup/adWaitPool.lua")
local failures = 0
local function check(name, actual, expected)
if actual == expected then
print("OK " .. name)
else
failures = failures + 1
print(string.format("FAIL %s: forventede %s, fik %s", name, tostring(expected), tostring(actual)))
end
end
local markers, wayPoints = {}, {}
local function addMarker(id, name, group, x, z)
wayPoints[id] = {id = id, x = x, z = z, incoming = {}}
local marker = {id = id, markerIndex = #markers + 1, name = name, group = group}
table.insert(markers, marker)
return marker
end
local unreachable = {}
local adEnv = {
ADGraphManager = {
getMapMarkers = function() return markers end,
getMapMarkerByWayPointId = function(_, id) for _, m in ipairs(markers) do if m.id == id then return m end end end,
getWayPointById = function(_, id) return wayPoints[id] end,
getPathTo = function(_, vehicle, id) if unreachable[id] then return {} end return {{id = id}} end,
pathFromTo = function(_, from, to) if unreachable[to] then return {} end return {{id = to}} end,
},
}
getWorldTranslation = function(node) return node.x, 0, node.z end
addMarker(10, "cow wait 1", "cow wait", 0, 0)
addMarker(11, "cow wait 2", "cow wait", 50, 0)
addMarker(20, "Wait 3", "General Wait", 10, 0)
addMarker(30, "silo 1", "silo", 5, 0)
-- W1: kandidater
check("W1 kun mappen", #ADWaitPool.getCandidates(adEnv, "cow wait"), 2)
check("W1 tom pulje = alle Wait-mapper", #ADWaitPool.getCandidates(adEnv, ""), 3)
check("W1 nil = alle", #ADWaitPool.getCandidates(adEnv, nil), 3)
-- W2: nærmeste ledige fra vognens position; reserverede springes over; egen reservation OK
local v1, v2 = {name = "v1", rootNode = {x = 45, z = 0}}, {name = "v2", rootNode = {x = 45, z = 0}}
check("W2 nærmeste", ADWaitPool.pickFree(adEnv, v1, "cow wait").marker.id, 11)
ADWaitPool.claim(11, v1)
check("W2 reserveret springes over", ADWaitPool.pickFree(adEnv, v2, "cow wait").marker.id, 10)
check("W2 egen reservation genbruges", ADWaitPool.pickFree(adEnv, v1, "cow wait").marker.id, 11)
-- W3: claim / owner / release
check("W3 ejer", ADWaitPool.getOwner(11), v1)
ADWaitPool.releaseVehicle(v1)
check("W3 frigivet", ADWaitPool.getOwner(11), nil)
check("W3 nu ledig for v2", ADWaitPool.pickFree(adEnv, v2, "cow wait").marker.id, 11)
-- W4: nåelighed
unreachable[11] = true
check("W4 uopnåelig nærmeste -> næste", ADWaitPool.pickFree(adEnv, v2, "cow wait", function(c) return ADWaitPool.hasRouteTo(adEnv, v2, c.marker.id) end).marker.id, 10)
check("W4 hasRouteTo false", ADWaitPool.hasRouteTo(adEnv, v2, 11), false)
check("W4 hasRouteBothWays true", ADWaitPool.hasRouteBothWays(adEnv, v2, 10, 30), true)
check("W4 hasRouteBothWays hjem uopnåelig", ADWaitPool.hasRouteBothWays(adEnv, v2, 10, 11), false)
unreachable[11] = nil
check("W4 intet punkt -> nil", ADWaitPool.pickFree(adEnv, v2, "cow wait", function() return false end), nil)
-- W5: getClaims sorteret på mappe, dernæst id
ADWaitPool.claim(20, v2)
ADWaitPool.claim(10, v1)
local claims = ADWaitPool.getClaims(adEnv)
check("W5 to reservationer", #claims, 2)
check("W5 første = General Wait", claims[1].marker.group, "General Wait")
check("W5 anden = cow wait 1", claims[2].marker.id, 10)
ADWaitPool.releaseVehicle(v1)
ADWaitPool.releaseVehicle(v2)
check("W5 alt frigivet", #ADWaitPool.getClaims(adEnv), 0)
-- W6: redirect stopper trigger-aktivitet og sætter sti
local stopped = {}
local task = {
destinationID = 99, state = 1,
vehicle = {ad = {
trailerModule = {isActiveAtTrigger = function() return true end, stopUnloading = function() stopped.unload = true end, stopLoading = function() stopped.load = true end},
drivePathModule = {setPathTo = function(_, id) stopped.pathTo = id end},
}},
}
ADWaitPool.STATE_DRIVING = 2
ADWaitPool.redirect(task, 10)
check("W6 destination", task.destinationID, 10)
check("W6 state driving", task.state, 2)
check("W6 setPathTo", stopped.pathTo, 10)
check("W6 stopUnloading", stopped.unload, true)
-- WR: AD's rutesøgning siger nej, men vejnettet har en vej fra traktorens nærmeste waypoint -> godtages
-- (in-game 24/9: 'Æg storage' ved Chicken Wait 1, "ingen vej til 'Chicken Storage Unload'" trods vej)
do
wayPoints[901] = {id = 901, x = 0, z = 0, out = {902}}
wayPoints[902] = {id = 902, x = 5, z = 0, out = {903}}
wayPoints[903] = {id = 903, x = 10, z = 0, out = {}}
wayPoints[904] = {id = 904, x = 20, z = 0, out = {}} -- ingen indgang
unreachable[903], unreachable[904] = true, true
local vehicle = {getClosestWayPoint = function() return 901, 1 end}
check("WR AD nej, vejnettet ja -> nåelig", ADWaitPool.hasRouteTo(adEnv, vehicle, 903), true)
check("WR hverken AD eller vejnet -> ikke nåelig", ADWaitPool.hasRouteTo(adEnv, vehicle, 904), false)
check("WR uden nærmeste waypoint -> AD's svar", ADWaitPool.hasRouteTo(adEnv, {}, 903), false)
unreachable[903], unreachable[904] = nil, nil
end
-- RC: rutesvar gemmes 30 s pr. mål og 10 m-område (holdende vogne spurgte hvert 5. s -> hak hvert 5. s)
do
local pathCalls = 0
local realGetPathTo = adEnv.ADGraphManager.getPathTo
adEnv.ADGraphManager.getPathTo = function(self, vehicle, id) pathCalls = pathCalls + 1; return realGetPathTo(self, vehicle, id) end
local clock = 0
netGetTime = function() return clock end
local positions = {[500] = {100, 100}}
getWorldTranslation = function(node) local p = positions[node]; return p[1], 0, p[2] end
local parked = {rootNode = 500, getClosestWayPoint = function() return 901, 1 end}
ADWaitPool.hasRouteTo(adEnv, parked, 10)
ADWaitPool.hasRouteTo(adEnv, parked, 10)
check("RC samme svar genbruges", pathCalls, 1)
positions[500] = {104, 103}
ADWaitPool.hasRouteTo(adEnv, parked, 10)
check("RC samme 10 m-område genbruges", pathCalls, 1)
positions[500] = {160, 100}
ADWaitPool.hasRouteTo(adEnv, parked, 10)
check("RC nyt sted -> nyt svar", pathCalls, 2)
clock = 31000
ADWaitPool.hasRouteTo(adEnv, parked, 10)
check("RC efter 30 s -> nyt svar", pathCalls, 3)
local first = ADWaitPool.hasRouteTo(adEnv, parked, 11)
check("RC andet mål -> nyt svar", pathCalls, 4)
check("RC samme svar igen", ADWaitPool.hasRouteTo(adEnv, parked, 11), first)
check("RC uden nyt kald", pathCalls, 4)
adEnv.ADGraphManager.getPathTo = realGetPathTo
netGetTime = nil
end
-- MR: rute markør->markør gemmes (uafhængig af hvor vognen er) — hak 26/9: 30-39 ms pr. rutetjek
do
local calls = 0
local realFromTo = adEnv.ADGraphManager.pathFromTo
adEnv.ADGraphManager.pathFromTo = function(self, from, to) calls = calls + 1; return realFromTo(self, from, to) end
local savedClock = netGetTime
local t = 1000
netGetTime = function() return t end
ADWaitPool.resetMarkerRoutes()
local far = {name = "far", rootNode = {x = 5000, z = 5000}}
check("MR første: rute", ADWaitPool.hasRouteBothWays(adEnv, v2, 10, 30), true)
local afterFirst = calls
t = t + 60000
check("MR anden fra en helt anden position: samme svar", ADWaitPool.hasRouteBothWays(adEnv, far, 10, 30), true)
check("MR anden gang ingen ny ruteberegning", calls, afterFirst)
adEnv.ADGraphManager.pathFromTo = realFromTo
netGetTime = savedClock
end
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1)