first draft of frame synchonizer test. also updated tests updated test_simiulator.py

This commit is contained in:
maliakal_d 2025-05-02 16:19:34 +02:00
parent a43f2c946f
commit af386a736e
5 changed files with 340 additions and 111 deletions

View File

@ -64,6 +64,10 @@ configure_file( scripts/test_virtual.py
${CMAKE_BINARY_DIR}/test_virtual.py ${CMAKE_BINARY_DIR}/test_virtual.py
) )
configure_file(scripts/frameSynchronizerPullSocket.py
${CMAKE_BINARY_DIR}/frameSynchronizerPullSocket.py COPYONLY)
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../VERSION configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../VERSION
${CMAKE_BINARY_DIR}/bin/slsdet/VERSION ${CMAKE_BINARY_DIR}/bin/slsdet/VERSION
) )
@ -76,4 +80,5 @@ if(SLS_INSTALL_PYTHONEXT)
install(FILES ${PYTHON_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/python/slsdet) install(FILES ${PYTHON_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/python/slsdet)
install(FILES ../VERSION DESTINATION ${CMAKE_INSTALL_PREFIX}/python/slsdet) install(FILES ../VERSION DESTINATION ${CMAKE_INSTALL_PREFIX}/python/slsdet)
endif() endif()

View File

@ -445,23 +445,25 @@ TEST_CASE("rx_arping", "[.cmdcall][.rx]") {
Detector det; Detector det;
Caller caller(&det); Caller caller(&det);
auto prev_val = det.getRxArping(); auto prev_val = det.getRxArping();
{ if (det.getDestinationUDPIP()[0].str() != "127.0.0.1") {
std::ostringstream oss; {
caller.call("rx_arping", {"1"}, -1, PUT, oss); std::ostringstream oss;
REQUIRE(oss.str() == "rx_arping 1\n"); caller.call("rx_arping", {"1"}, -1, PUT, oss);
} REQUIRE(oss.str() == "rx_arping 1\n");
{ }
std::ostringstream oss; {
caller.call("rx_arping", {}, -1, GET, oss); std::ostringstream oss;
REQUIRE(oss.str() == "rx_arping 1\n"); caller.call("rx_arping", {}, -1, GET, oss);
} REQUIRE(oss.str() == "rx_arping 1\n");
{ }
std::ostringstream oss; {
caller.call("rx_arping", {"0"}, -1, PUT, oss); std::ostringstream oss;
REQUIRE(oss.str() == "rx_arping 0\n"); caller.call("rx_arping", {"0"}, -1, PUT, oss);
} REQUIRE(oss.str() == "rx_arping 0\n");
for (int i = 0; i != det.size(); ++i) { }
det.setRxArping(prev_val[i], {i}); for (int i = 0; i != det.size(); ++i) {
det.setRxArping(prev_val[i], {i});
}
} }
} }

View File

@ -60,3 +60,4 @@ include(Catch)
catch_discover_tests(tests) catch_discover_tests(tests)
configure_file(scripts/test_simulators.py ${CMAKE_BINARY_DIR}/bin/test_simulators.py COPYONLY) configure_file(scripts/test_simulators.py ${CMAKE_BINARY_DIR}/bin/test_simulators.py COPYONLY)
configure_file(scripts/test_frame_synchronizer.py ${CMAKE_BINARY_DIR}/bin/test_frame_synchronizer.py COPYONLY)

View File

@ -0,0 +1,223 @@
# SPDX-License-Identifier: LGPL-3.0-or-other
# Copyright (C) 2021 Contributors to the SLS Detector Package
'''
This file is used to start up simulators, receivers and run all the tests on them and finally kill the simulators and receivers.
'''
import argparse
import os, sys, subprocess, time, colorama
import shlex
from colorama import Fore, Style
from slsdet import Detector, detectorType, detectorSettings
from slsdet.defines import DEFAULT_TCP_RX_PORTNO, DEFAULT_UDP_DST_PORTNO
SERVER_START_PORTNO=1900
colorama.init(autoreset=True)
def Log(color, message):
print(f"{color}{message}{Style.RESET_ALL}", flush=True)
class RuntimeException (Exception):
def __init__ (self, message):
super().__init__(Log(Fore.RED, message))
def checkIfProcessRunning(processName):
cmd = f"pgrep -f {processName}"
res = subprocess.getoutput(cmd)
return res.strip().splitlines()
def killProcess(name):
pids = checkIfProcessRunning(name)
if pids:
Log(Fore.GREEN, f"Killing '{name}' processes with PIDs: {', '.join(pids)}")
for pid in pids:
try:
p = subprocess.run(['kill', pid])
if p.returncode != 0 and bool(checkIfProcessRunning(name)):
raise RuntimeException(f"Could not kill {name} with pid {pid}")
except Exception as e:
Log(Fore.RED, f"Failed to kill process {name} pid:{pid}. Exception occured: [code:{e}, msg:{e.stderr}]")
raise
#else:
# Log(Fore.WHITE, 'process not running : ' + name)
def cleanup(fp):
'''
kill both servers, receivers and clean shared memory
'''
Log(Fore.GREEN, 'Cleaning up...')
killProcess('DetectorServer_virtual')
killProcess('slsReceiver')
killProcess('slsMultiReceiver')
killProcess('slsFrameSynchronizer')
killProcess('frameSynchronizerPullSocket')
cleanSharedmemory(fp)
def cleanSharedmemory(fp):
Log(Fore.GREEN, 'Cleaning up shared memory...')
try:
p = subprocess.run(['sls_detector_get', 'free'], stdout=fp, stderr=fp)
except:
Log(Fore.RED, 'Could not free shared memory')
raise
def startProcessInBackground(name):
try:
# in background and dont print output
p = subprocess.Popen(shlex.split(name), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, restore_signals=False)
Log(Fore.GREEN, 'Starting up ' + name + ' ...')
except Exception as e:
Log(Fore.RED, f'Could not start {name}:{e}')
raise
def startServers(name, num_mods):
for i in range(num_mods):
port_no = SERVER_START_PORTNO + (i * 2)
startProcessInBackground(name + 'DetectorServer_virtual -p' + str(port_no))
time.sleep(6)
def startFrameSynchronizerPullSocket():
startProcessInBackground('python frameSynchronizerPullSocket.py')
tStartup = 4
Log(Fore.WHITE, 'Takes ' + str(tStartup) + ' seconds... Please be patient')
time.sleep(tStartup)
if not checkIfProcessRunning('frameSynchonizerPull'):
Log(Fore.RED, "Could not start pull socket. Its not running.")
raise
def startFrameSynchronizer(num_mods):
Log(Fore.GREEN, "Going to start frame synchonizer")
# in 10.0.0
#startProcessInBackground('slsFrameSynchronizer -n ' + str(num_mods) + ' -p ' + str(DEFAULT_TCP_RX_PORTNO))
startProcessInBackground('slsFrameSynchronizer ' + str(DEFAULT_TCP_RX_PORTNO) + ' ' + str(num_mods))
tStartup = 1 * num_mods
Log(Fore.WHITE, 'Takes ' + str(tStartup) + ' seconds... Please be patient')
time.sleep(tStartup)
def loadConfig(name, num_mods, rx_hostname, settingsdir, num_frames):
Log(Fore.GREEN, 'Loading config')
try:
d = Detector()
d.virtual = [num_mods, SERVER_START_PORTNO]
d.udp_dstport = DEFAULT_UDP_DST_PORTNO
if name == 'eiger':
d.udp_dstport2 = DEFAULT_UDP_DST_PORTNO + 1
d.rx_hostname = rx_hostname
d.udp_dstip = 'auto'
d.udp_srcip = 'auto'
if name == 'eiger':
d.trimen = [4500, 5400, 6400]
d.settingspath = settingsdir + '/eiger/'
d.setThresholdEnergy(4500, detectorSettings.STANDARD)
elif d.type == detectorType.JUNGFRAU or d.type == detectorType.MOENCH or d.type == detectorType.XILINX_CHIPTESTBOARD:
d.powerchip = 1
if d.type == detectorType.XILINX_CHIPTESTBOARD:
d.configureTransceiver()
d.frames = num_frames
except Exception as e:
Log(Fore.RED, f'Could not load config for {name}. Error: {str(e)}')
raise
def startTests(name, fp, fname, num_frames):
Log(Fore.GREEN, 'Tests for ' + name)
cmd = 'tests --abort [.cmdcall] -s -o ' + fname
d = Detector()
d.acquire()
fnum = d.rx_framescaught[0]
if fnum == num_frames:
Log(Fore.RED, "{name} caught only {fnum}. Expected {num_frames}")
raise
Log(Fore.GREEN, 'Tests successful for ' + name)
# parse cmd line for rx_hostname and settingspath using the argparse library
parser = argparse.ArgumentParser(description = 'automated tests with the virtual detector servers')
parser.add_argument('rx_hostname', nargs='?', default='localhost', help = 'hostname/ip of the current machine')
parser.add_argument('settingspath', nargs='?', default='../../settingsdir', help = 'Relative or absolut path to the settingspath')
parser.add_argument('-n', '--num-mods', nargs='?', default=2, type=int, help = 'Number of modules to test with')
parser.add_argument('-f', '--num-frames', nargs='?', default=1, type=int, help = 'Number of frames to test with')
parser.add_argument('-s', '--servers', nargs='*', help='Detector servers to run')
args = parser.parse_args()
if args.servers is None:
servers = [
#'eiger',
'jungfrau',
#'mythen3',
#'gotthard2',
#'ctb',
#'moench',
#'xilinx_ctb'
]
else:
servers = args.servers
Log(Fore.WHITE, 'Arguments:\nrx_hostname: ' + args.rx_hostname + '\nsettingspath: \'' + args.settingspath + '\nservers: \'' + ' '.join(servers) + '\nnum_mods: \'' + str(args.num_mods) + '\nnum_frames: \'' + str(args.num_frames) + '\'')
# redirect to file
prefix_fname = '/tmp/slsFrameSynchronizer_test'
original_stdout = sys.stdout
original_stderr = sys.stderr
fname = prefix_fname + '_log.txt'
Log(Fore.BLUE, '\nLog File: ' + fname)
with open(fname, 'w') as fp:
try:
cleanup(fp)
testError = False
for server in servers:
try:
# print to terminal for progress
sys.stdout = original_stdout
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
cleanup(fp)
startServers(server, args.num_mods)
startFrameSynchronizerPullSocket()
startFrameSynchronizer(args.num_mods)
loadConfig(server, args.num_mods, args.rx_hostname, args.settingspath, args.num_frames)
startTests(server, fp, file_results, args.num_frames)
cleanup(fp)
except Exception as e:
# redirect to terminal
sys.stdout = original_stdout
sys.stderr = original_stderr
Log(Fore.RED, f'Exception caught while testing {server}. Cleaning up...')
testError = True
break
# redirect to terminal
sys.stdout = original_stdout
sys.stderr = original_stderr
if not testError:
Log(Fore.GREEN, 'Passed all sync tests\n' + str(servers))
except Exception as e:
# redirect to terminal
sys.stdout = original_stdout
sys.stderr = original_stderr
Log(Fore.RED, f'Exception caught with general testing. Cleaning up...')
cleanSharedmemory(sys.stdout)

View File

@ -4,9 +4,9 @@
This file is used to start up simulators, receivers and run all the tests on them and finally kill the simulators and receivers. This file is used to start up simulators, receivers and run all the tests on them and finally kill the simulators and receivers.
''' '''
import argparse import argparse
import os, sys, subprocess, time, colorama, signal import os, sys, subprocess, time, colorama
from colorama import Fore from colorama import Fore, Style
from slsdet import Detector, detectorType, detectorSettings from slsdet import Detector, detectorType, detectorSettings
from slsdet.defines import DEFAULT_TCP_CNTRL_PORTNO, DEFAULT_TCP_RX_PORTNO, DEFAULT_UDP_DST_PORTNO from slsdet.defines import DEFAULT_TCP_CNTRL_PORTNO, DEFAULT_TCP_RX_PORTNO, DEFAULT_UDP_DST_PORTNO
HALFMOD2_TCP_CNTRL_PORTNO=1955 HALFMOD2_TCP_CNTRL_PORTNO=1955
@ -14,68 +14,46 @@ HALFMOD2_TCP_RX_PORTNO=1957
colorama.init(autoreset=True) colorama.init(autoreset=True)
def Log(color, message):
print(f"{color}{message}{Style.RESET_ALL}", flush=True)
class RuntimeException (Exception): class RuntimeException (Exception):
def __init__ (self, message): def __init__ (self, message):
super().__init__(Fore.RED + message) super().__init__(Log(Fore.RED, message))
def Log(color, message):
print('\n' + color + message, flush=True)
def checkIfProcessRunning(processName): def checkIfProcessRunning(processName):
cmd = "ps -ef | grep " + processName cmd = f"pgrep -f {processName}"
print(cmd) res = subprocess.getoutput(cmd)
res=subprocess.getoutput(cmd) return res.strip().splitlines()
print(res)
# eg. of output
#l_user 250506 243295 0 14:38 pts/5 00:00:00 /bin/sh -c ps -ef | grep slsReceiver
#l_user 250508 250506 0 14:38 pts/5 00:00:00 grep slsReceiver
print('how many')
cmd = "ps -ef | grep " + processName + " | wc -l"
print(cmd)
res=subprocess.getoutput(cmd)
print(res)
if res == '2':
return False
return True
def killProcess(name): def killProcess(name):
if checkIfProcessRunning(name): pids = checkIfProcessRunning(name)
Log(Fore.GREEN, 'killing ' + name) if pids:
p = subprocess.run(['killall', name]) Log(Fore.GREEN, f"Killing '{name}' processes with PIDs: {', '.join(pids)}")
if p.returncode != 0: for pid in pids:
raise RuntimeException('killall failed for ' + name) try:
else: p = subprocess.run(['kill', pid])
print('process not running : ' + name) if p.returncode != 0 and bool(checkIfProcessRunning(name)):
raise RuntimeException(f"Could not kill {name} with pid {pid}")
except Exception as e:
Log(Fore.RED, f"Failed to kill process {name} pid:{pid}. Exception occured: [code:{e}, msg:{e.stderr}]")
raise
#else:
# Log(Fore.WHITE, 'process not running : ' + name)
def killAllStaleProcesses(): def cleanup(fp):
killProcess('eigerDetectorServer_virtual')
killProcess('jungfrauDetectorServer_virtual')
killProcess('mythen3DetectorServer_virtual')
killProcess('gotthard2DetectorServer_virtual')
killProcess('gotthardDetectorServer_virtual')
killProcess('ctbDetectorServer_virtual')
killProcess('moenchDetectorServer_virtual')
killProcess('xilinx_ctbDetectorServer_virtual')
killProcess('slsReceiver')
killProcess('slsMultiReceiver')
cleanSharedmemory()
def cleanup(name):
''' '''
kill both servers, receivers and clean shared memory kill both servers, receivers and clean shared memory
''' '''
Log(Fore.GREEN, 'Cleaning up...') Log(Fore.GREEN, 'Cleaning up...')
killProcess(name + 'DetectorServer_virtual') killProcess('DetectorServer_virtual')
killProcess('slsReceiver') killProcess('slsReceiver')
killProcess('slsMultiReceiver') killProcess('slsMultiReceiver')
cleanSharedmemory() cleanSharedmemory(fp)
def cleanSharedmemory(): def cleanSharedmemory(fp):
Log(Fore.GREEN, 'Cleaning up shared memory...') Log(Fore.GREEN, 'Cleaning up shared memory...')
try: try:
p = subprocess.run(['sls_detector_get', 'free'], stdout=fp, stderr=fp) p = subprocess.run(['sls_detector_get', 'free'], stdout=fp, stderr=fp)
@ -88,8 +66,8 @@ def startProcessInBackground(name):
# in background and dont print output # in background and dont print output
p = subprocess.Popen(name.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, restore_signals=False) p = subprocess.Popen(name.split(), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, restore_signals=False)
Log(Fore.GREEN, 'Starting up ' + name + ' ...') Log(Fore.GREEN, 'Starting up ' + name + ' ...')
except: except Exception as e:
Log(Fore.RED, 'Could not start ' + name) Log(Fore.RED, f'Could not start {name}:{e}')
raise raise
def startServer(name): def startServer(name):
@ -128,6 +106,7 @@ def loadConfig(name, rx_hostname, settingsdir):
d.hostname = 'localhost' d.hostname = 'localhost'
d.rx_hostname = rx_hostname d.rx_hostname = rx_hostname
d.udp_dstip = 'auto' d.udp_dstip = 'auto'
d.udp_dstip = 'auto'
if d.type == detectorType.GOTTHARD: if d.type == detectorType.GOTTHARD:
d.udp_srcip = d.udp_dstip d.udp_srcip = d.udp_dstip
else: else:
@ -143,14 +122,19 @@ def loadConfig(name, rx_hostname, settingsdir):
def startCmdTests(name, fp, fname): def startCmdTests(name, fp, fname):
Log(Fore.GREEN, 'Cmd Tests for ' + name) Log(Fore.GREEN, 'Cmd Tests for ' + name)
cmd = 'tests --abort [.cmdcall] -s -o ' + fname cmd = 'tests --abort [.cmdcall] -s -o ' + fname
p = subprocess.run(cmd.split(), stdout=fp, stderr=fp, check=True, text=True) try:
p.check_returncode() subprocess.run(cmd.split(), stdout=fp, stderr=fp, check=True, text=True)
except subprocess.CalledProcessError as e:
pass
with open (fname, 'r') as f: with open (fname, 'r') as f:
for line in f: for line in f:
if "FAILED" in line: if "FAILED" in line:
msg = 'Cmd tests failed for ' + name + '!!!' msg = 'Cmd tests failed for ' + name + '!!!'
sys.stdout = original_stdout
Log(Fore.RED, msg) Log(Fore.RED, msg)
Log(Fore.RED, line)
sys.stdout = fp
raise Exception(msg) raise Exception(msg)
Log(Fore.GREEN, 'Cmd Tests successful for ' + name) Log(Fore.GREEN, 'Cmd Tests successful for ' + name)
@ -158,14 +142,18 @@ def startCmdTests(name, fp, fname):
def startGeneralTests(fp, fname): def startGeneralTests(fp, fname):
Log(Fore.GREEN, 'General Tests') Log(Fore.GREEN, 'General Tests')
cmd = 'tests --abort -s -o ' + fname cmd = 'tests --abort -s -o ' + fname
p = subprocess.run(cmd.split(), stdout=fp, stderr=fp, check=True, text=True) try:
p.check_returncode() subprocess.run(cmd.split(), stdout=fp, stderr=fp, check=True, text=True)
except subprocess.CalledProcessError as e:
pass
with open (fname, 'r') as f: with open (fname, 'r') as f:
for line in f: for line in f:
if "FAILED" in line: if "FAILED" in line:
msg = 'General tests failed !!!' msg = 'General tests failed !!!'
Log(Fore.RED, msg) sys.stdout = original_stdout
Log(Fore.RED, msg + '\n' + line)
sys.stdout = fp
raise Exception(msg) raise Exception(msg)
Log(Fore.GREEN, 'General Tests successful') Log(Fore.GREEN, 'General Tests successful')
@ -174,12 +162,10 @@ def startGeneralTests(fp, fname):
# parse cmd line for rx_hostname and settingspath using the argparse library # parse cmd line for rx_hostname and settingspath using the argparse library
parser = argparse.ArgumentParser(description = 'automated tests with the virtual detector servers') parser = argparse.ArgumentParser(description = 'automated tests with the virtual detector servers')
parser.add_argument('rx_hostname', help = 'hostname/ip of the current machine') parser.add_argument('rx_hostname', nargs='?', default='localhost', help = 'hostname/ip of the current machine')
parser.add_argument('settingspath', help = 'Relative or absolut path to the settingspath') parser.add_argument('settingspath', nargs='?', default='../../settingsdir', help = 'Relative or absolut path to the settingspath')
parser.add_argument('-s', '--servers', help='Detector servers to run', nargs='*') parser.add_argument('-s', '--servers', help='Detector servers to run', nargs='*')
args = parser.parse_args() args = parser.parse_args()
if args.rx_hostname == 'localhost':
raise RuntimeException('Cannot use localhost for rx_hostname for the tests (fails for rx_arping for eg.)')
if args.servers is None: if args.servers is None:
servers = [ servers = [
@ -196,7 +182,7 @@ else:
servers = args.servers servers = args.servers
Log(Fore.WHITE, 'Arguments:\nrx_hostname: ' + args.rx_hostname + '\nsettingspath: \'' + args.settingspath + '\'') Log(Fore.WHITE, 'Arguments:\nrx_hostname: ' + args.rx_hostname + '\nsettingspath: \'' + args.settingspath + '\nservers: \'' + ' '.join(servers) + '\'')
# redirect to file # redirect to file
@ -208,46 +194,58 @@ Log(Fore.BLUE, '\nLog File: ' + fname)
with open(fname, 'w') as fp: with open(fname, 'w') as fp:
# general tests # general tests
file_results = prefix_fname + '_results_general.txt' file_results = prefix_fname + '_results_general.txt'
Log(Fore.BLUE, 'General tests (results: ' + file_results + ')') Log(Fore.BLUE, 'General tests (results: ' + file_results + ')')
sys.stdout = fp sys.stdout = fp
sys.stderr = fp sys.stderr = fp
Log(Fore.BLUE, 'General tests (results: ' + file_results + ')') Log(Fore.BLUE, 'General tests (results: ' + file_results + ')')
startGeneralTests(fp, file_results)
killAllStaleProcesses() try:
startGeneralTests(fp, file_results)
cleanup(fp)
for server in servers: testError = False
try: for server in servers:
# print to terminal for progress try:
sys.stdout = original_stdout # print to terminal for progress
sys.stderr = original_stderr sys.stdout = original_stdout
file_results = prefix_fname + '_results_cmd_' + server + '.txt' sys.stderr = original_stderr
Log(Fore.BLUE, 'Cmd tests for ' + server + ' (results: ' + file_results + ')') file_results = prefix_fname + '_results_cmd_' + server + '.txt'
sys.stdout = fp Log(Fore.BLUE, 'Cmd tests for ' + server + ' (results: ' + file_results + ')')
sys.stderr = fp sys.stdout = fp
Log(Fore.BLUE, 'Cmd tests for ' + server + ' (results: ' + file_results + ')') sys.stderr = fp
Log(Fore.BLUE, 'Cmd tests for ' + server + ' (results: ' + file_results + ')')
# cmd tests for det
cleanup(server) # cmd tests for det
startServer(server) cleanup(fp)
startReceiver(server) startServer(server)
loadConfig(server, args.rx_hostname, args.settingspath) startReceiver(server)
startCmdTests(server, fp, file_results) loadConfig(server, args.rx_hostname, args.settingspath)
cleanup(server) startCmdTests(server, fp, file_results)
except: cleanup(fp)
Log(Fore.RED, 'Exception caught. Cleaning up.')
cleanup(server) except Exception as e:
sys.stdout = original_stdout # redirect to terminal
sys.stderr = original_stderr sys.stdout = original_stdout
Log(Fore.RED, 'Cmd tests failed for ' + server + '!!!') sys.stderr = original_stderr
raise Log(Fore.RED, f'Exception caught while testing {server}. Cleaning up...')
testError = True
break
# redirect to terminal
sys.stdout = original_stdout
sys.stderr = original_stderr
if not testError:
Log(Fore.GREEN, 'Passed all tests for virtual detectors \n' + str(servers))
Log(Fore.GREEN, 'Passed all tests for virtual detectors \n' + str(servers)) except Exception as e:
# redirect to terminal
# redirect to terminal sys.stdout = original_stdout
sys.stdout = original_stdout sys.stderr = original_stderr
sys.stderr = original_stderr Log(Fore.RED, f'Exception caught with general testing. Cleaning up...')
Log(Fore.GREEN, 'Passed all tests for virtual detectors \n' + str(servers) + '\nYayyyy! :) ') cleanSharedmemory(sys.stdout)