FEX/Scripts/Threaded_Lockstep_Runner.py
Ryan Houdek 7d5442357a Scripts: Disable using catchsegv if it doesn't exist
Fixes #2724

If catchsegv doesn't exist then just remove it from the execution
environment.

While nice to have, this shouldn't be mandatory especially with Debian
no longer shipping it.
2023-06-16 13:31:00 -07:00

104 lines
3.4 KiB
Python
Executable File

#!/usr/bin/python3
from enum import Flag
import json
import os
import struct
import sys
import glob
from threading import Thread
import subprocess
import time
import multiprocessing
from shutil import which
if sys.version_info[0] < 3:
raise Exception("Python 3 or a more recent version is required.")
if (len(sys.argv) < 3):
sys.exit("We need two arguments. Location of LockStepRunner and folder containing the tests")
# Remove our SHM regions if they still exist
SHM_Files = glob.glob("/dev/shm/*_Lockstep")
for file in SHM_Files:
os.remove(file)
UnitTests = sorted(glob.glob(sys.argv[2] + "*"))
UnitTestsSize = len(UnitTests)
Threads = [None] * UnitTestsSize
Results = [None] * UnitTestsSize
ThreadResults = [[None] * 2] * UnitTestsSize
MaxFileNameStringLen = 0
def Threaded_Runner(Args, ID, Client):
Log = open("Log_" + str(ID) + "_" + str(Client), "w")
Log.write("Args: %s\n" % " ".join(Args))
Log.flush()
Process = subprocess.Popen(Args, stdout=Log, stderr=Log)
Process.wait()
Log.flush()
ThreadResults[ID][Client] = Process.returncode
def Threaded_Manager(Runner, ID, File):
ServerArgs = ["catchsegv", Runner, "-c", "vm", "-n", "1", "-I", "R" + str(ID), File]
ClientArgs = ["catchsegv", Runner, "-c", "vm", "-n", "1", "-I", "R" + str(ID), "-C"]
if which("catchsegv") is None:
ServerArgs.pop(0)
ClientArgs.pop(0)
ServerThread = Thread(target = Threaded_Runner, args = (ServerArgs, ID, 0))
ClientThread = Thread(target = Threaded_Runner, args = (ClientArgs, ID, 1))
ServerThread.start()
ClientThread.start()
ClientThread.join()
ServerThread.join()
# The server is the one we should listen to for results
if (ThreadResults[ID][1] != 0 and ThreadResults[ID][0] == 0):
# If the client died for some reason but server thought we were fine then take client data
Results[ID] = ThreadResults[ID][1]
else:
# Else just take the server data
Results[ID] = ThreadResults[ID][0]
DupLen = MaxFileNameStringLen - len(UnitTests[ID])
if (Results[ID] == 0):
print("\t'%s'%s - PASSED ID: %d - 0" % (UnitTests[ID], " "*DupLen, ID))
else:
print("\t'%s'%s - FAILED ID: %d - %s" % (UnitTests[ID], " "*DupLen, ID, hex(Results[ID])))
RunnerSlot = 0
MaxRunnerSlots = min(32, multiprocessing.cpu_count() / 2)
RunnerSlots = [None] * MaxRunnerSlots
for RunnerID in range(UnitTestsSize):
File = UnitTests[RunnerID]
print("'%s' Running Test" % File)
MaxFileNameStringLen = max(MaxFileNameStringLen, len(File))
Threads[RunnerID] = Thread(target = Threaded_Manager, args = (sys.argv[1], RunnerID, File))
Threads[RunnerID].start()
if (MaxRunnerSlots != 0):
RunnerSlots[RunnerSlot] = Threads[RunnerID]
RunnerSlot += 1
if (RunnerSlot == MaxRunnerSlots):
for i in range(MaxRunnerSlots):
RunnerSlots[i].join()
RunnerSlot = 0
for i in range(UnitTestsSize):
Threads[i].join()
print("====== PASSED RESULTS ======")
for i in range(UnitTestsSize):
DupLen = MaxFileNameStringLen - len(UnitTests[i])
if (Results[i] == 0):
print("\t'%s'%s - PASSED ID: %d - 0" % (UnitTests[i], " "*DupLen, i))
print("====== FAILED RESULTS ======")
for i in range(UnitTestsSize):
DupLen = MaxFileNameStringLen - len(UnitTests[i])
if (Results[i] != 0):
print("\t'%s'%s - FAILED ID: %d - %s" % (UnitTests[i], " "*DupLen, i, hex(Results[i])))