test frame synchonizer now runs for all modules (only jungfrua enableD) with num modules and num frames as arguments (also servers) and checks the output log of pull socket to ensure there are expected number of headers, moduels and series end htypes

This commit is contained in:
maliakal_d 2025-05-02 22:48:48 +02:00
parent af386a736e
commit 0f4d10912b
2 changed files with 72 additions and 43 deletions

View File

@ -65,7 +65,7 @@ configure_file( scripts/test_virtual.py
) )
configure_file(scripts/frameSynchronizerPullSocket.py configure_file(scripts/frameSynchronizerPullSocket.py
${CMAKE_BINARY_DIR}/frameSynchronizerPullSocket.py COPYONLY) ${CMAKE_BINARY_DIR}/bin/frameSynchronizerPullSocket.py COPYONLY)
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../VERSION configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../VERSION

View File

@ -5,7 +5,7 @@ This file is used to start up simulators, receivers and run all the tests on the
''' '''
import argparse import argparse
import os, sys, subprocess, time, colorama import os, sys, subprocess, time, colorama
import shlex import shlex, traceback, json
from colorama import Fore, Style from colorama import Fore, Style
from slsdet import Detector, detectorType, detectorSettings from slsdet import Detector, detectorType, detectorSettings
@ -15,8 +15,8 @@ SERVER_START_PORTNO=1900
colorama.init(autoreset=True) colorama.init(autoreset=True)
def Log(color, message): def Log(color, message, stream=sys.stdout):
print(f"{color}{message}{Style.RESET_ALL}", flush=True) print(f"{color}{message}{Style.RESET_ALL}", file=stream, flush=True)
class RuntimeException (Exception): class RuntimeException (Exception):
def __init__ (self, message): def __init__ (self, message):
@ -28,10 +28,10 @@ def checkIfProcessRunning(processName):
return res.strip().splitlines() return res.strip().splitlines()
def killProcess(name): def killProcess(name, fp):
pids = checkIfProcessRunning(name) pids = checkIfProcessRunning(name)
if pids: if pids:
Log(Fore.GREEN, f"Killing '{name}' processes with PIDs: {', '.join(pids)}") Log(Fore.WHITE, f"Killing '{name}' processes with PIDs: {', '.join(pids)}", fp)
for pid in pids: for pid in pids:
try: try:
p = subprocess.run(['kill', pid]) p = subprocess.run(['kill', pid])
@ -48,16 +48,17 @@ def cleanup(fp):
''' '''
kill both servers, receivers and clean shared memory kill both servers, receivers and clean shared memory
''' '''
Log(Fore.GREEN, 'Cleaning up...') Log(Fore.WHITE, 'Cleaning up')
killProcess('DetectorServer_virtual') Log(Fore.WHITE, 'Cleaning up', fp)
killProcess('slsReceiver') killProcess('DetectorServer_virtual', fp)
killProcess('slsMultiReceiver') killProcess('slsReceiver', fp)
killProcess('slsFrameSynchronizer') killProcess('slsMultiReceiver', fp)
killProcess('frameSynchronizerPullSocket') killProcess('slsFrameSynchronizer', fp)
killProcess('frameSynchronizerPullSocket', fp)
cleanSharedmemory(fp) cleanSharedmemory(fp)
def cleanSharedmemory(fp): def cleanSharedmemory(fp):
Log(Fore.GREEN, 'Cleaning up shared memory...') Log(Fore.WHITE, 'Cleaning up shared memory...', fp)
try: try:
p = subprocess.run(['sls_detector_get', 'free'], stdout=fp, stderr=fp) p = subprocess.run(['sls_detector_get', 'free'], stdout=fp, stderr=fp)
except: except:
@ -68,37 +69,41 @@ def startProcessInBackground(name):
try: try:
# in background and dont print output # in background and dont print output
p = subprocess.Popen(shlex.split(name), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, restore_signals=False) p = subprocess.Popen(shlex.split(name), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, restore_signals=False)
Log(Fore.GREEN, 'Starting up ' + name + ' ...') Log(Fore.WHITE, 'Starting up ' + name + ' ...', fp)
except Exception as e: except Exception as e:
Log(Fore.RED, f'Could not start {name}:{e}') Log(Fore.RED, f'Could not start {name}:{e}')
raise raise
def startServers(name, num_mods): def startServers(name, num_mods):
Log(Fore.WHITE, 'Starting server')
for i in range(num_mods): for i in range(num_mods):
port_no = SERVER_START_PORTNO + (i * 2) port_no = SERVER_START_PORTNO + (i * 2)
startProcessInBackground(name + 'DetectorServer_virtual -p' + str(port_no)) startProcessInBackground(name + 'DetectorServer_virtual -p' + str(port_no))
time.sleep(6) time.sleep(6)
def startFrameSynchronizerPullSocket(): def startFrameSynchronizerPullSocket(fname, fp):
startProcessInBackground('python frameSynchronizerPullSocket.py') Log(Fore.WHITE, 'Starting sync pull socket')
tStartup = 4 Log(Fore.WHITE, f"Starting up Synchronizer pull socket. Log: {fname}", fp)
Log(Fore.WHITE, 'Takes ' + str(tStartup) + ' seconds... Please be patient') Log(Fore.WHITE, f"Synchronizer pull socket log: {fname}")
time.sleep(tStartup) cmd = ['python', '-u', 'frameSynchronizerPullSocket.py']
if not checkIfProcessRunning('frameSynchonizerPull'): try:
Log(Fore.RED, "Could not start pull socket. Its not running.") with open(fname, 'w') as fp:
subprocess.Popen(cmd, stdout=fp, stderr=fp, text=True)
except Exception as e:
Log(Fore.RED, f"failed to start synchronizer pull socket: {e}")
raise raise
def startFrameSynchronizer(num_mods): def startFrameSynchronizer(num_mods):
Log(Fore.GREEN, "Going to start frame synchonizer") Log(Fore.WHITE, 'Starting frame synchronizer')
# in 10.0.0 # in 10.0.0
#startProcessInBackground('slsFrameSynchronizer -n ' + str(num_mods) + ' -p ' + str(DEFAULT_TCP_RX_PORTNO)) #startProcessInBackground('slsFrameSynchronizer -n ' + str(num_mods) + ' -p ' + str(DEFAULT_TCP_RX_PORTNO))
startProcessInBackground('slsFrameSynchronizer ' + str(DEFAULT_TCP_RX_PORTNO) + ' ' + str(num_mods)) startProcessInBackground('slsFrameSynchronizer ' + str(DEFAULT_TCP_RX_PORTNO) + ' ' + str(num_mods))
tStartup = 1 * num_mods tStartup = 1 * num_mods
Log(Fore.WHITE, 'Takes ' + str(tStartup) + ' seconds... Please be patient')
time.sleep(tStartup) time.sleep(tStartup)
def loadConfig(name, num_mods, rx_hostname, settingsdir, num_frames): def loadConfig(name, num_mods, rx_hostname, settingsdir, num_frames, fp):
Log(Fore.GREEN, 'Loading config') Log(Fore.WHITE, 'Loading config')
Log(Fore.WHITE, 'Loading config', fp)
try: try:
d = Detector() d = Detector()
d.virtual = [num_mods, SERVER_START_PORTNO] d.virtual = [num_mods, SERVER_START_PORTNO]
@ -126,18 +131,46 @@ def loadConfig(name, num_mods, rx_hostname, settingsdir, num_frames):
Log(Fore.RED, f'Could not load config for {name}. Error: {str(e)}') Log(Fore.RED, f'Could not load config for {name}. Error: {str(e)}')
raise raise
def startTests(name, fp, fname, num_frames): def validate_htype_counts(log_path, num_mods, num_frames):
Log(Fore.GREEN, 'Tests for ' + name) htype_counts = {
"header": 0,
"series_end": 0,
"module": 0
}
with open(log_path, 'r') as f:
for line in f:
line = line.strip()
if not line or not line.startswith('{'):
continue
try:
data = json.loads(line)
htype = data.get("htype")
if htype in htype_counts:
htype_counts[htype] += 1
except json.JSONDecodeError:
continue # or log malformed line
for htype, expected_count in [("header", num_mods), ("series_end", num_mods * num_frames), ("module", num_mods)]:
if htype_counts[htype] != expected_count:
msg = f"Expected 2 '{htype}' entries, found {htype_counts[htype]}"
Log(Fore.RED, msg)
raise RuntimeError(msg)
def startTests(name, num_mods, num_frames, fp, file_pull_socket):
Log(Fore.WHITE, 'Tests for ' + name)
Log(Fore.WHITE, 'Tests for ' + name, fp)
cmd = 'tests --abort [.cmdcall] -s -o ' + fname cmd = 'tests --abort [.cmdcall] -s -o ' + fname
d = Detector() d = Detector()
d.acquire() d.acquire()
fnum = d.rx_framescaught[0] fnum = d.rx_framescaught[0]
if fnum == num_frames: if fnum != num_frames:
Log(Fore.RED, "{name} caught only {fnum}. Expected {num_frames}") Log(Fore.RED, f"{name} caught only {fnum}. Expected {num_frames}")
raise raise
Log(Fore.GREEN, 'Tests successful for ' + name) validate_htype_counts(file_pull_socket, num_mods, num_frames)
Log(Fore.GREEN, f"Log file htype checks passed for {name}", fp)
# parse cmd line for rx_hostname and settingspath using the argparse library # parse cmd line for rx_hostname and settingspath using the argparse library
@ -176,27 +209,20 @@ Log(Fore.BLUE, '\nLog File: ' + fname)
with open(fname, 'w') as fp: with open(fname, 'w') as fp:
try: try:
cleanup(fp)
testError = False testError = False
for server in servers: for server in servers:
try: try:
# print to terminal for progress Log(Fore.BLUE, '\nSynchonizer tests for ' + server, fp)
sys.stdout = original_stdout Log(Fore.BLUE, '\nSynchonizer tests for ' + server)
sys.stderr = original_stderr
file_results = prefix_fname + '_results_cmd_' + server + '.txt'
Log(Fore.BLUE, 'Synchonizer tests for ' + server + ' (results: ' + file_results + ')')
sys.stdout = fp
sys.stderr = fp
Log(Fore.BLUE, 'Synchonizer tests for ' + server + ' (results: ' + file_results + ')')
# cmd tests for det # cmd tests for det
cleanup(fp) cleanup(fp)
startServers(server, args.num_mods) startServers(server, args.num_mods)
startFrameSynchronizerPullSocket() file_pull_socket = prefix_fname + '_pull_socket_' + server + '.txt'
startFrameSynchronizerPullSocket(file_pull_socket, fp)
startFrameSynchronizer(args.num_mods) startFrameSynchronizer(args.num_mods)
loadConfig(server, args.num_mods, args.rx_hostname, args.settingspath, args.num_frames) loadConfig(server, args.num_mods, args.rx_hostname, args.settingspath, args.num_frames, fp)
startTests(server, fp, file_results, args.num_frames) startTests(server, args.num_mods, args.num_frames, fp, file_pull_socket)
cleanup(fp) cleanup(fp)
except Exception as e: except Exception as e:
@ -204,6 +230,9 @@ with open(fname, 'w') as fp:
sys.stdout = original_stdout sys.stdout = original_stdout
sys.stderr = original_stderr sys.stderr = original_stderr
Log(Fore.RED, f'Exception caught while testing {server}. Cleaning up...') Log(Fore.RED, f'Exception caught while testing {server}. Cleaning up...')
with open(fname, 'a') as fp_error:
traceback.print_exc(file=fp_error) # This will log the full traceback
testError = True testError = True
break break