Run integration tests in CI

This commit is contained in:
elsid 2022-06-06 01:10:33 +02:00
parent 8a13cde778
commit 7989d1645f
No known key found for this signature in database
GPG key ID: 4DE04C198CBA7625
9 changed files with 150 additions and 29 deletions

View file

@ -12,23 +12,25 @@ input.setControlSwitch(input.CONTROL_SWITCH.Magic, false)
input.setControlSwitch(input.CONTROL_SWITCH.VanityMode, false)
input.setControlSwitch(input.CONTROL_SWITCH.ViewMode, false)
testing.registerLocalTest('playerMovement',
testing.registerLocalTest('playerRotation',
function()
local startTime = core.getSimulationTime()
local pos = self.position
while core.getSimulationTime() < startTime + 0.5 do
local endTime = core.getSimulationTime() + 1
while core.getSimulationTime() < endTime do
self.controls.jump = false
self.controls.run = true
self.controls.movement = 0
self.controls.sideMovement = 0
local progress = (core.getSimulationTime() - startTime) / 0.5
self.controls.yawChange = util.normalizeAngle(math.rad(90) * progress - self.rotation.z)
self.controls.yawChange = util.normalizeAngle(math.rad(90) - self.rotation.z) * 0.5
coroutine.yield()
end
testing.expectEqualWithDelta(self.rotation.z, math.rad(90), 0.05, 'Incorrect rotation')
end)
while core.getSimulationTime() < startTime + 1.5 do
testing.registerLocalTest('playerForwardRunning',
function()
local startPos = self.position
local endTime = core.getSimulationTime() + 1
while core.getSimulationTime() < endTime do
self.controls.jump = false
self.controls.run = true
self.controls.movement = 1
@ -36,12 +38,18 @@ testing.registerLocalTest('playerMovement',
self.controls.yawChange = 0
coroutine.yield()
end
direction = (self.position - pos) / types.Actor.runSpeed(self)
testing.expectEqualWithDelta(direction.x, 1, 0.1, 'Run forward, X coord')
testing.expectEqualWithDelta(direction.y, 0, 0.1, 'Run forward, Y coord')
local direction, distance = (self.position - startPos):normalize()
local normalizedDistance = distance / types.Actor.runSpeed(self)
testing.expectEqualWithDelta(normalizedDistance, 1, 0.2, 'Normalized forward runned distance')
testing.expectEqualWithDelta(direction.x, 0, 0.1, 'Run forward, X coord')
testing.expectEqualWithDelta(direction.y, 1, 0.1, 'Run forward, Y coord')
end)
pos = self.position
while core.getSimulationTime() < startTime + 2.5 do
testing.registerLocalTest('playerDiagonalWalking',
function()
local startPos = self.position
local endTime = core.getSimulationTime() + 1
while core.getSimulationTime() < endTime do
self.controls.jump = false
self.controls.run = false
self.controls.movement = -1
@ -49,9 +57,11 @@ testing.registerLocalTest('playerMovement',
self.controls.yawChange = 0
coroutine.yield()
end
direction = (self.position - pos) / types.Actor.walkSpeed(self)
local direction, distance = (self.position - startPos):normalize()
local normalizedDistance = distance / types.Actor.walkSpeed(self)
testing.expectEqualWithDelta(normalizedDistance, 1, 0.2, 'Normalized diagonally walked distance')
testing.expectEqualWithDelta(direction.x, -0.707, 0.1, 'Walk diagonally, X coord')
testing.expectEqualWithDelta(direction.y, 0.707, 0.1, 'Walk diagonally, Y coord')
testing.expectEqualWithDelta(direction.y, -0.707, 0.1, 'Walk diagonally, Y coord')
end)
return {
@ -60,4 +70,3 @@ return {
},
eventHandlers = testing.eventHandlers
}

View file

@ -29,10 +29,10 @@ local function testTimers()
while not (ts1 and ts2 and th1 and th2) do coroutine.yield() end
testing.expectAlmostEqual(th1, 36, 'async:newGameTimer failed')
testing.expectAlmostEqual(ts1, 0.5, 'async:newSimulationTimer failed')
testing.expectAlmostEqual(th2, 72, 'async:newUnsavableGameTimer failed')
testing.expectAlmostEqual(ts2, 1, 'async:newUnsavableSimulationTimer failed')
testing.expectGreaterOrEqual(th1, 36, 'async:newGameTimer failed')
testing.expectGreaterOrEqual(ts1, 0.5, 'async:newSimulationTimer failed')
testing.expectGreaterOrEqual(th2, 72, 'async:newUnsavableGameTimer failed')
testing.expectGreaterOrEqual(ts2, 1, 'async:newUnsavableSimulationTimer failed')
end
local function testTeleport()
@ -51,9 +51,25 @@ local function testTeleport()
testing.expectEqualWithDelta(player.rotation.z, math.rad(-90), 0.05, 'teleporting changes rotation')
end
local function initPlayer()
player:teleport('', util.vector3(4096, 4096, 867.237), util.vector3(0, 0, 0))
coroutine.yield()
end
tests = {
{'timers', testTimers},
{'playerMovement', function() testing.runLocalTest(player, 'playerMovement') end},
{'playerRotation', function()
initPlayer()
testing.runLocalTest(player, 'playerRotation')
end},
{'playerForwardRunning', function()
initPlayer()
testing.runLocalTest(player, 'playerForwardRunning')
end},
{'playerDiagonalWalking', function()
initPlayer()
testing.runLocalTest(player, 'playerDiagonalWalking')
end},
{'teleport', testTeleport},
}

View file

@ -52,6 +52,12 @@ function M.expectAlmostEqual(v1, v2, msg)
end
end
function M.expectGreaterOrEqual(v1, v2, msg)
if not (v1 >= v2) then
error(string.format('%s: %f >= %f', msg or '', v1, v2), 2)
end
end
local localTests = {}
local localTestRunner = nil

View file

@ -51,14 +51,30 @@ def runTest(name):
)
if (test_dir / "test.omwscripts").exists():
omw_cfg.write("content=test.omwscripts\n")
with open(config_dir / "settings.cfg", "a", encoding="utf-8") as settings_cfg:
settings_cfg.write(
"[Video]\n"
"resolution x = 640\n"
"resolution y = 480\n"
"framerate limit = 60\n"
)
stdout_lines = list()
exit_ok = True
test_success = True
with subprocess.Popen(
[f"{openmw_binary}", "--replace=config", f"--config={config_dir}", "--skip-menu", "--no-grab"],
[openmw_binary, "--replace=config", "--config", config_dir, "--skip-menu", "--no-grab", "--no-sound"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding="utf-8",
env={
"OPENMW_OSG_STATS_FILE": work_dir / f"{name}.{time_str}.osg_stats.log",
"OPENMW_OSG_STATS_LIST": "times",
**os.environ,
},
) as process:
quit_requested = False
for line in process.stdout:
stdout_lines.append(line)
words = line.split(" ")
if len(words) > 1 and words[1] == "E]":
print(line, end="")
@ -72,16 +88,30 @@ def runTest(name):
elif "TEST_FAILED" in line:
w = line.split("TEST_FAILED")[1].split("\t")
print(f"FAILED {w[3]}\t\t")
test_success = False
process.wait(5)
if not quit_requested:
print("ERROR: Unexpected termination")
shutil.copyfile(config_dir / "openmw.log", work_dir / f"{name}.{time_str}.log")
print(f"{name} finished")
exit_ok = False
if process.returncode != 0:
print(f"ERROR: openmw exited with code {process.returncode}")
exit_ok = False
if os.path.exists(config_dir / "openmw.log"):
shutil.copyfile(config_dir / "openmw.log", work_dir / f"{name}.{time_str}.log")
if not exit_ok:
sys.stdout.writelines(stdout_lines)
if test_success and exit_ok:
print(f"{name} succeeded")
else:
print(f"{name} failed")
return test_success and exit_ok
status = 0
for entry in tests_dir.glob("test_*"):
if entry.is_dir():
runTest(entry.name)
if not runTest(entry.name):
status = -1
shutil.rmtree(config_dir, ignore_errors=True)
shutil.rmtree(userdata_dir, ignore_errors=True)
exit(status)

View file

@ -76,7 +76,7 @@ def main(print_keys, regexp_match, timeseries, hist, hist_ratio, stdev_hist, plo
def matching_keys(patterns):
if regexp_match:
return [key for pattern in patterns for key in keys if re.search(pattern, key)]
return keys
return patterns
if timeseries:
draw_timeseries(sources=frames, keys=matching_keys(timeseries), add_sum=timeseries_sum,
begin_frame=begin_frame, end_frame=end_frame)