mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-05 17:40:40 +02:00
updates api version based on version file & converted shell script files to python
This commit is contained in:
parent
0d5d851585
commit
3ad4e01a5d
23
slsDetectorServers/compileAllServers.sh
Normal file → Executable file
23
slsDetectorServers/compileAllServers.sh
Normal file → Executable file
@ -1,17 +1,17 @@
|
|||||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||||
|
|
||||||
# empty branch = developer branch in updateAPIVersion.sh
|
|
||||||
branch=""
|
|
||||||
det_list=("ctbDetectorServer
|
det_list=("ctbDetectorServer
|
||||||
gotthard2DetectorServer
|
gotthard2DetectorServer
|
||||||
jungfrauDetectorServer
|
jungfrauDetectorServer
|
||||||
mythen3DetectorServer
|
mythen3DetectorServer
|
||||||
moenchDetectorServer
|
moenchDetectorServer
|
||||||
xilinx_ctbDetectorServer"
|
xilinx_ctbDetectorServer"
|
||||||
)
|
)
|
||||||
usage="\nUsage: compileAllServers.sh [server|all(opt)] [branch(opt)]. \n\tNo arguments mean all servers with 'developer' branch. \n\tNo 'branch' input means 'developer branch'"
|
usage="\nUsage: compileAllServers.sh [server|all(opt)] [update_api(opt)]. \n\tNo arguments mean all servers with 'developer' branch. \n\tupdate_api if true updates the api to version in VERSION file"
|
||||||
|
|
||||||
|
update_api=false
|
||||||
|
target=clean
|
||||||
# arguments
|
# arguments
|
||||||
if [ $# -eq 0 ]; then
|
if [ $# -eq 0 ]; then
|
||||||
# no argument, all servers
|
# no argument, all servers
|
||||||
@ -34,15 +34,13 @@ elif [ $# -eq 1 ] || [ $# -eq 2 ]; then
|
|||||||
declare -a det=("${1}")
|
declare -a det=("${1}")
|
||||||
#echo "Compiling only $1"
|
#echo "Compiling only $1"
|
||||||
fi
|
fi
|
||||||
# branch
|
|
||||||
if [ $# -eq 2 ]; then
|
if [ $# -eq 2 ]; then
|
||||||
# arg in list
|
update_api=$2
|
||||||
if [[ $det_list == *$2* ]]; then
|
if $update_api ; then
|
||||||
echo -e "Invalid argument 2: $2. $usage"
|
target=version
|
||||||
return 1
|
echo "updating api to $(cat ../VERSION)"
|
||||||
fi
|
fi
|
||||||
branch+=$2
|
|
||||||
#echo "with branch $branch"
|
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo -e "Too many arguments.$usage"
|
echo -e "Too many arguments.$usage"
|
||||||
@ -61,8 +59,7 @@ do
|
|||||||
file="${i}_developer"
|
file="${i}_developer"
|
||||||
echo -e "Compiling $dir [$file]"
|
echo -e "Compiling $dir [$file]"
|
||||||
cd $dir
|
cd $dir
|
||||||
make clean
|
if make $target; then
|
||||||
if make version API_BRANCH=$branch; then
|
|
||||||
deterror[$idet]="OK"
|
deterror[$idet]="OK"
|
||||||
else
|
else
|
||||||
deterror[$idet]="FAIL"
|
deterror[$idet]="FAIL"
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||||
|
|
||||||
# empty branch = developer branch in updateAPIVersion.sh
|
|
||||||
branch=""
|
|
||||||
det_list=("ctbDetectorServer"
|
det_list=("ctbDetectorServer"
|
||||||
"gotthard2DetectorServer"
|
"gotthard2DetectorServer"
|
||||||
"jungfrauDetectorServer"
|
"jungfrauDetectorServer"
|
||||||
@ -10,14 +8,14 @@ det_list=("ctbDetectorServer"
|
|||||||
"moenchDetectorServer"
|
"moenchDetectorServer"
|
||||||
"xilinx_ctbDetectorServer"
|
"xilinx_ctbDetectorServer"
|
||||||
)
|
)
|
||||||
usage="\nUsage: compileAllServers.sh [server|all(opt)] [branch(opt)]. \n\tNo arguments mean all servers with 'developer' branch. \n\tNo 'branch' input means 'developer branch'"
|
usage="\nUsage: compileAllServers.sh [server|all(opt)]. \n\tNo arguments mean all servers with 'developer' branch."
|
||||||
|
|
||||||
# arguments
|
# arguments
|
||||||
if [ $# -eq 0 ]; then
|
if [ $# -eq 0 ]; then
|
||||||
# no argument, all servers
|
# no argument, all servers
|
||||||
declare -a det=${det_list[@]}
|
declare -a det=${det_list[@]}
|
||||||
echo "Compiling all servers"
|
echo "Compiling all servers"
|
||||||
elif [ $# -eq 1 ] || [ $# -eq 2 ]; then
|
elif [ $# -eq 1 ]; then
|
||||||
# 'all' servers
|
# 'all' servers
|
||||||
if [[ $1 == "all" ]]; then
|
if [[ $1 == "all" ]]; then
|
||||||
declare -a det=${det_list[@]}
|
declare -a det=${det_list[@]}
|
||||||
@ -32,16 +30,6 @@ elif [ $# -eq 1 ] || [ $# -eq 2 ]; then
|
|||||||
declare -a det=("${1}")
|
declare -a det=("${1}")
|
||||||
#echo "Compiling only $1"
|
#echo "Compiling only $1"
|
||||||
fi
|
fi
|
||||||
# branch
|
|
||||||
if [ $# -eq 2 ]; then
|
|
||||||
# arg in list
|
|
||||||
if [[ $det_list == *$2* ]]; then
|
|
||||||
echo -e "Invalid argument 2: $2. $usage"
|
|
||||||
return -1
|
|
||||||
fi
|
|
||||||
branch+=$2
|
|
||||||
#echo "with branch $branch"
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
echo -e "Too many arguments.$usage"
|
echo -e "Too many arguments.$usage"
|
||||||
return -1
|
return -1
|
||||||
@ -59,8 +47,7 @@ do
|
|||||||
file="${i}_developer"
|
file="${i}_developer"
|
||||||
echo -e "Compiling $dir [$file]"
|
echo -e "Compiling $dir [$file]"
|
||||||
cd $dir
|
cd $dir
|
||||||
make clean
|
if make clean; then
|
||||||
if make API_BRANCH=$branch; then
|
|
||||||
deterror[$idet]="OK"
|
deterror[$idet]="OK"
|
||||||
else
|
else
|
||||||
deterror[$idet]="FAIL"
|
deterror[$idet]="FAIL"
|
||||||
|
@ -25,15 +25,15 @@ version: clean versioning $(PROGS)
|
|||||||
|
|
||||||
boot: $(OBJS)
|
boot: $(OBJS)
|
||||||
|
|
||||||
version_branch=$(API_BRANCH)
|
|
||||||
version_name=APICTB
|
version_name=APICTB
|
||||||
version_path=slsDetectorServers/ctbDetectorServer
|
version_path=slsDetectorServers/ctbDetectorServer
|
||||||
versioning:
|
versioning:
|
||||||
cd ../../ && echo $(PWD) && echo `tput setaf 6; ./updateAPIVersion.sh $(version_name) $(version_path) $(version_branch); tput sgr0;`
|
cd ../../ && echo $(PWD) && echo `tput setaf 6; python updateAPIVersion.py $(version_name) $(version_path); tput sgr0;`
|
||||||
|
|
||||||
|
|
||||||
$(PROGS): $(OBJS)
|
$(PROGS): $(OBJS)
|
||||||
# echo $(OBJS)
|
# echo $(OBJS)
|
||||||
|
cd $(current_dir)
|
||||||
mkdir -p $(DESTDIR)
|
mkdir -p $(DESTDIR)
|
||||||
$(CC) -o $@ $^ $(CFLAGS) $(LDLIBS)
|
$(CC) -o $@ $^ $(CFLAGS) $(LDLIBS)
|
||||||
mv $(PROGS) $(DESTDIR)
|
mv $(PROGS) $(DESTDIR)
|
||||||
@ -41,7 +41,7 @@ $(PROGS): $(OBJS)
|
|||||||
rm $(main_src)*.o $(md5_dir)*.o
|
rm $(main_src)*.o $(md5_dir)*.o
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o
|
cd $(current_dir) && rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ class Version {
|
|||||||
private:
|
private:
|
||||||
std::string version_;
|
std::string version_;
|
||||||
std::string date_;
|
std::string date_;
|
||||||
const std::string defaultBranch_ = "developer";
|
inline static const std::string defaultBranch_[] = {"developer", "0.0.0"};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Version(const std::string &s);
|
explicit Version(const std::string &s);
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||||
/** API versions */
|
/** API versions */
|
||||||
#define APILIB "developer 0x241122"
|
#define APILIB "0.0.0 0x250514"
|
||||||
#define APIRECEIVER "developer 0x241122"
|
#define APIRECEIVER "0.0.0 0x250515"
|
||||||
#define APICTB "developer 0x250310"
|
#define APICTB "0.0.0 0x250515"
|
||||||
#define APIGOTTHARD2 "developer 0x250310"
|
#define APIGOTTHARD2 "developer 0x250310"
|
||||||
#define APIMOENCH "developer 0x250310"
|
#define APIMOENCH "developer 0x250310"
|
||||||
#define APIEIGER "developer 0x250310"
|
#define APIEIGER "developer 0x250310"
|
||||||
|
@ -21,7 +21,8 @@ Version::Version(const std::string &s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Version::hasSemanticVersioning() const {
|
bool Version::hasSemanticVersioning() const {
|
||||||
return version_ != defaultBranch_;
|
|
||||||
|
return (version_ != defaultBranch_[0]) && (version_ != defaultBranch_[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Version::getVersion() const { return version_; }
|
std::string Version::getVersion() const { return version_; }
|
||||||
|
@ -14,6 +14,7 @@ target_sources(tests PRIVATE
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-TypeTraits.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/test-TypeTraits.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-UdpRxSocket.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/test-UdpRxSocket.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-logger.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/test-logger.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/test-Version.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/test-ZmqSocket.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/test-ZmqSocket.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
19
slsSupportLib/tests/test-Version.cpp
Normal file
19
slsSupportLib/tests/test-Version.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||||
|
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||||
|
#include "catch.hpp"
|
||||||
|
#include "sls/Version.h"
|
||||||
|
|
||||||
|
namespace sls {
|
||||||
|
|
||||||
|
TEST_CASE("check if version is semantic", "[.version]") {
|
||||||
|
|
||||||
|
auto [version_string, has_semantic_version] =
|
||||||
|
GENERATE(std::make_tuple("developer 0x250512", false),
|
||||||
|
std::make_tuple("0.0.0 0x250512", false));
|
||||||
|
|
||||||
|
Version version(version_string);
|
||||||
|
|
||||||
|
CHECK(version.hasSemanticVersioning() == has_semantic_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace sls
|
140
tests/scripts/test_frame_synchronizer.py
Normal file
140
tests/scripts/test_frame_synchronizer.py
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
# 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, frame synchronizer, pull sockets, acquire, test and kill them finally.
|
||||||
|
'''
|
||||||
|
|
||||||
|
import sys, time
|
||||||
|
import traceback, json
|
||||||
|
|
||||||
|
from slsdet import Detector
|
||||||
|
from slsdet.defines import DEFAULT_TCP_RX_PORTNO
|
||||||
|
|
||||||
|
from utils_for_test import (
|
||||||
|
Log,
|
||||||
|
LogLevel,
|
||||||
|
RuntimeException,
|
||||||
|
checkIfProcessRunning,
|
||||||
|
killProcess,
|
||||||
|
cleanup,
|
||||||
|
cleanSharedmemory,
|
||||||
|
startProcessInBackground,
|
||||||
|
startProcessInBackgroundWithLogFile,
|
||||||
|
startDetectorVirtualServer,
|
||||||
|
loadConfig,
|
||||||
|
ParseArguments
|
||||||
|
)
|
||||||
|
|
||||||
|
LOG_PREFIX_FNAME = '/tmp/slsFrameSynchronizer_test'
|
||||||
|
MAIN_LOG_FNAME = LOG_PREFIX_FNAME + '_log.txt'
|
||||||
|
PULL_SOCKET_PREFIX_FNAME = LOG_PREFIX_FNAME + '_pull_socket_'
|
||||||
|
|
||||||
|
|
||||||
|
def startFrameSynchronizerPullSocket(name, fp):
|
||||||
|
fname = PULL_SOCKET_PREFIX_FNAME + name + '.txt'
|
||||||
|
cmd = ['python', '-u', 'frameSynchronizerPullSocket.py']
|
||||||
|
startProcessInBackgroundWithLogFile(cmd, fp, fname)
|
||||||
|
|
||||||
|
|
||||||
|
def startFrameSynchronizer(num_mods, fp):
|
||||||
|
cmd = ['slsFrameSynchronizer', str(DEFAULT_TCP_RX_PORTNO), str(num_mods)]
|
||||||
|
# in 10.0.0
|
||||||
|
#cmd = ['slsFrameSynchronizer', '-p', str(DEFAULT_TCP_RX_PORTNO), '-n', str(num_mods)]
|
||||||
|
startProcessInBackground(cmd, fp)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
def acquire(fp, det):
|
||||||
|
Log(LogLevel.INFO, 'Acquiring')
|
||||||
|
Log(LogLevel.INFO, 'Acquiring', fp)
|
||||||
|
det.acquire()
|
||||||
|
|
||||||
|
|
||||||
|
def testFramesCaught(name, det, num_frames):
|
||||||
|
fnum = det.rx_framescaught[0]
|
||||||
|
if fnum != num_frames:
|
||||||
|
raise RuntimeException(f"{name} caught only {fnum}. Expected {num_frames}")
|
||||||
|
|
||||||
|
Log(LogLevel.INFOGREEN, f'Frames caught test passed for {name}')
|
||||||
|
Log(LogLevel.INFOGREEN, f'Frames caught test passed for {name}', fp)
|
||||||
|
|
||||||
|
|
||||||
|
def testZmqHeadetTypeCount(name, det, num_mods, num_frames, fp):
|
||||||
|
|
||||||
|
Log(LogLevel.INFO, f"Testing Zmq Header type count for {name}")
|
||||||
|
Log(LogLevel.INFO, f"Testing Zmq Header type count for {name}", fp)
|
||||||
|
htype_counts = {
|
||||||
|
"header": 0,
|
||||||
|
"series_end": 0,
|
||||||
|
"module": 0
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
# get a count of each htype from file
|
||||||
|
pull_socket_fname = PULL_SOCKET_PREFIX_FNAME + name + '.txt'
|
||||||
|
with open(pull_socket_fname, 'r') as log_fp:
|
||||||
|
for line in log_fp:
|
||||||
|
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
|
||||||
|
|
||||||
|
# test if file contents matches expected counts
|
||||||
|
num_ports_per_module = 1 if name == "gotthard2" else det.numinterfaces
|
||||||
|
total_num_frame_parts = num_ports_per_module * num_mods * num_frames
|
||||||
|
for htype, expected_count in [("header", num_mods), ("series_end", num_mods), ("module", total_num_frame_parts)]:
|
||||||
|
if htype_counts[htype] != expected_count:
|
||||||
|
msg = f"Expected {expected_count} '{htype}' entries, found {htype_counts[htype]}"
|
||||||
|
raise RuntimeException(msg)
|
||||||
|
except Exception as e:
|
||||||
|
raise RuntimeException(f'Failed to get zmq header count type. Error:{str(e)}') from e
|
||||||
|
|
||||||
|
Log(LogLevel.INFOGREEN, f"Zmq Header type count test passed for {name}")
|
||||||
|
Log(LogLevel.INFOGREEN, f"Zmq Header type count test passed for {name}", fp)
|
||||||
|
|
||||||
|
|
||||||
|
def startTestsForAll(args, fp):
|
||||||
|
for server in args.servers:
|
||||||
|
try:
|
||||||
|
Log(LogLevel.INFOBLUE, f'Synchronizer Tests for {server}')
|
||||||
|
Log(LogLevel.INFOBLUE, f'Synchronizer Tests for {server}', fp)
|
||||||
|
cleanup(fp)
|
||||||
|
startDetectorVirtualServer(server, args.num_mods, fp)
|
||||||
|
startFrameSynchronizerPullSocket(server, fp)
|
||||||
|
startFrameSynchronizer(args.num_mods, fp)
|
||||||
|
d = loadConfig(name=server, rx_hostname=args.rx_hostname, settingsdir=args.settingspath, fp=fp, num_mods=args.num_mods, num_frames=args.num_frames)
|
||||||
|
print("mac source adress: ", d.udp_srcmac)
|
||||||
|
print("source ip: ", d.udp_srcip)
|
||||||
|
print("detector type: ", d.type)
|
||||||
|
acquire(fp, d)
|
||||||
|
testFramesCaught(server, d, args.num_frames)
|
||||||
|
testZmqHeadetTypeCount(server, d, args.num_mods, args.num_frames, fp)
|
||||||
|
Log(LogLevel.INFO, '\n')
|
||||||
|
except Exception as e:
|
||||||
|
raise RuntimeException(f'Synchronizer Tests failed') from e
|
||||||
|
|
||||||
|
Log(LogLevel.INFOGREEN, 'Passed all synchronizer tests for all detectors \n' + str(args.servers))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
args = ParseArguments(description='Automated tests to test frame synchronizer', default_num_mods=2)
|
||||||
|
|
||||||
|
Log(LogLevel.INFOBLUE, '\nLog File: ' + MAIN_LOG_FNAME + '\n')
|
||||||
|
|
||||||
|
with open(MAIN_LOG_FNAME, 'w') as fp:
|
||||||
|
try:
|
||||||
|
startTestsForAll(args, fp)
|
||||||
|
cleanup(fp)
|
||||||
|
except Exception as e:
|
||||||
|
with open(MAIN_LOG_FNAME, 'a') as fp_error:
|
||||||
|
traceback.print_exc(file=fp_error)
|
||||||
|
cleanup(fp)
|
||||||
|
Log(LogLevel.ERROR, f'Tests Failed.')
|
||||||
|
|
||||||
|
|
245
tests/scripts/utils_for_test.py
Normal file
245
tests/scripts/utils_for_test.py
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||||
|
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||||
|
'''
|
||||||
|
This file is used for common utils used for integration tests between simulators and receivers.
|
||||||
|
'''
|
||||||
|
|
||||||
|
import sys, subprocess, time, argparse
|
||||||
|
from enum import Enum
|
||||||
|
from colorama import Fore, Style, init
|
||||||
|
|
||||||
|
from slsdet import Detector, detectorSettings
|
||||||
|
from slsdet.defines import DEFAULT_TCP_RX_PORTNO, DEFAULT_UDP_DST_PORTNO
|
||||||
|
SERVER_START_PORTNO=1900
|
||||||
|
|
||||||
|
init(autoreset=True)
|
||||||
|
|
||||||
|
|
||||||
|
class LogLevel(Enum):
|
||||||
|
INFO = 0
|
||||||
|
INFORED = 1
|
||||||
|
INFOGREEN = 2
|
||||||
|
INFOBLUE = 3
|
||||||
|
WARNING = 4
|
||||||
|
ERROR = 5
|
||||||
|
DEBUG = 6
|
||||||
|
|
||||||
|
|
||||||
|
LOG_LABELS = {
|
||||||
|
LogLevel.WARNING: "WARNING: ",
|
||||||
|
LogLevel.ERROR: "ERROR: ",
|
||||||
|
LogLevel.DEBUG: "DEBUG: "
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LOG_COLORS = {
|
||||||
|
LogLevel.INFO: Fore.WHITE,
|
||||||
|
LogLevel.INFORED: Fore.RED,
|
||||||
|
LogLevel.INFOGREEN: Fore.GREEN,
|
||||||
|
LogLevel.INFOBLUE: Fore.BLUE,
|
||||||
|
LogLevel.WARNING: Fore.YELLOW,
|
||||||
|
LogLevel.ERROR: Fore.RED,
|
||||||
|
LogLevel.DEBUG: Fore.CYAN
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def Log(level: LogLevel, message: str, stream=sys.stdout):
|
||||||
|
color = LOG_COLORS.get(level, Fore.WHITE)
|
||||||
|
label = LOG_LABELS.get(level, "")
|
||||||
|
print(f"{color}{label}{message}{Style.RESET_ALL}", file=stream, flush=True)
|
||||||
|
|
||||||
|
|
||||||
|
class RuntimeException (Exception):
|
||||||
|
def __init__ (self, message):
|
||||||
|
Log(LogLevel.ERROR, message)
|
||||||
|
super().__init__(message)
|
||||||
|
|
||||||
|
|
||||||
|
def checkIfProcessRunning(processName):
|
||||||
|
cmd = f"pgrep -f {processName}"
|
||||||
|
res = subprocess.getoutput(cmd)
|
||||||
|
return res.strip().splitlines()
|
||||||
|
|
||||||
|
|
||||||
|
def killProcess(name, fp):
|
||||||
|
pids = checkIfProcessRunning(name)
|
||||||
|
if pids:
|
||||||
|
Log(LogLevel.INFO, f"Killing '{name}' processes with PIDs: {', '.join(pids)}", fp)
|
||||||
|
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:
|
||||||
|
raise RuntimeException(f"Failed to kill process {name} pid:{pid}. Error: {str(e)}") from e
|
||||||
|
#else:
|
||||||
|
# Log(LogLevel.INFO, 'process not running : ' + name)
|
||||||
|
|
||||||
|
|
||||||
|
def cleanSharedmemory(fp):
|
||||||
|
Log(LogLevel.INFO, 'Cleaning up shared memory', fp)
|
||||||
|
try:
|
||||||
|
p = subprocess.run(['sls_detector_get', 'free'], stdout=fp, stderr=fp)
|
||||||
|
except:
|
||||||
|
raise RuntimeException('Could not free shared memory')
|
||||||
|
|
||||||
|
|
||||||
|
def cleanup(fp):
|
||||||
|
Log(LogLevel.INFO, 'Cleaning up')
|
||||||
|
Log(LogLevel.INFO, 'Cleaning up', fp)
|
||||||
|
killProcess('DetectorServer_virtual', fp)
|
||||||
|
killProcess('slsReceiver', fp)
|
||||||
|
killProcess('slsMultiReceiver', fp)
|
||||||
|
killProcess('slsFrameSynchronizer', fp)
|
||||||
|
killProcess('frameSynchronizerPullSocket', fp)
|
||||||
|
cleanSharedmemory(fp)
|
||||||
|
|
||||||
|
|
||||||
|
def startProcessInBackground(cmd, fp):
|
||||||
|
Log(LogLevel.INFO, 'Starting up ' + ' '.join(cmd))
|
||||||
|
Log(LogLevel.INFO, 'Starting up ' + ' '.join(cmd), fp)
|
||||||
|
try:
|
||||||
|
p = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, restore_signals=False)
|
||||||
|
except Exception as e:
|
||||||
|
raise RuntimeException(f'Failed to start {cmd}:{str(e)}') from e
|
||||||
|
|
||||||
|
|
||||||
|
def startProcessInBackgroundWithLogFile(cmd, fp, log_file_name):
|
||||||
|
Log(LogLevel.INFOBLUE, 'Starting up ' + ' '.join(cmd) + '. Log: ' + log_file_name)
|
||||||
|
Log(LogLevel.INFOBLUE, 'Starting up ' + ' '.join(cmd) + '. Log: ' + log_file_name, fp)
|
||||||
|
try:
|
||||||
|
with open(log_file_name, 'w') as log_fp:
|
||||||
|
subprocess.Popen(cmd, stdout=log_fp, stderr=log_fp, text=True)
|
||||||
|
except Exception as e:
|
||||||
|
raise RuntimeException(f'Failed to start {cmd}:{str(e)}') from e
|
||||||
|
|
||||||
|
|
||||||
|
def runProcessWithLogFile(name, cmd, fp, log_file_name):
|
||||||
|
Log(LogLevel.INFOBLUE, 'Running ' + name + '. Log: ' + log_file_name)
|
||||||
|
Log(LogLevel.INFOBLUE, 'Running ' + name + '. Log: ' + log_file_name, fp)
|
||||||
|
Log(LogLevel.INFOBLUE, 'Cmd: ' + ' '.join(cmd), fp)
|
||||||
|
try:
|
||||||
|
with open(log_file_name, 'w') as log_fp:
|
||||||
|
subprocess.run(cmd, stdout=log_fp, stderr=log_fp, check=True, text=True)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
Log(LogLevel.ERROR, f'Failed to run {name}:{str(e)}', fp)
|
||||||
|
raise RuntimeException(f'Failed to run {name}:{str(e)}')
|
||||||
|
|
||||||
|
with open (log_file_name, 'r') as f:
|
||||||
|
for line in f:
|
||||||
|
if "FAILED" in line:
|
||||||
|
raise RuntimeException(f'{line}')
|
||||||
|
|
||||||
|
Log(LogLevel.INFOGREEN, name + ' successful!\n')
|
||||||
|
Log(LogLevel.INFOGREEN, name + ' successful!\n', fp)
|
||||||
|
|
||||||
|
|
||||||
|
def startDetectorVirtualServer(name :str, num_mods, fp):
|
||||||
|
for i in range(num_mods):
|
||||||
|
subprocess.run(["which", name + "DetectorServer_virtual"])
|
||||||
|
|
||||||
|
port_no = SERVER_START_PORTNO + (i * 2)
|
||||||
|
cmd = [name + 'DetectorServer_virtual', '-p', str(port_no)]
|
||||||
|
startProcessInBackgroundWithLogFile(cmd, fp, "/tmp/virtual_det_" + name + str(i) + ".txt")
|
||||||
|
match name:
|
||||||
|
case 'jungfrau':
|
||||||
|
time.sleep(7)
|
||||||
|
case 'gotthard2':
|
||||||
|
time.sleep(5)
|
||||||
|
case _:
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
|
||||||
|
def connectToVirtualServers(name, num_mods):
|
||||||
|
try:
|
||||||
|
d = Detector()
|
||||||
|
except Exception as e:
|
||||||
|
raise RuntimeException(f'Could not create Detector object for {name}. Error: {str(e)}') from e
|
||||||
|
|
||||||
|
counts_sec = 100
|
||||||
|
while (counts_sec != 0):
|
||||||
|
try:
|
||||||
|
d.virtual = [num_mods, SERVER_START_PORTNO]
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
# stop server still not up, wait a bit longer
|
||||||
|
if "Cannot connect to" in str(e):
|
||||||
|
Log(LogLevel.WARNING, f'Still waiting for {name} virtual server to be up...{counts_sec}s left')
|
||||||
|
time.sleep(1)
|
||||||
|
counts_sec -= 1
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
def loadConfig(name, rx_hostname, settingsdir, fp, num_mods = 1, num_frames = 1):
|
||||||
|
Log(LogLevel.INFO, 'Loading config')
|
||||||
|
Log(LogLevel.INFO, 'Loading config', fp)
|
||||||
|
try:
|
||||||
|
d = connectToVirtualServers(name, num_mods)
|
||||||
|
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'
|
||||||
|
if name != "eiger":
|
||||||
|
d.udp_srcip = 'auto'
|
||||||
|
|
||||||
|
if name == "jungfrau" or name == "moench" or name == "xilinx_ctb":
|
||||||
|
d.powerchip = 1
|
||||||
|
|
||||||
|
if name == "xilinx_ctb":
|
||||||
|
d.configureTransceiver()
|
||||||
|
|
||||||
|
if name == "eiger":
|
||||||
|
d.trimen = [4500, 5400, 6400]
|
||||||
|
d.settingspath = settingsdir + '/eiger/'
|
||||||
|
d.setThresholdEnergy(4500, detectorSettings.STANDARD)
|
||||||
|
|
||||||
|
d.frames = num_frames
|
||||||
|
except Exception as e:
|
||||||
|
raise RuntimeException(f'Could not load config for {name}. Error: {str(e)}') from e
|
||||||
|
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
def ParseArguments(description, default_num_mods=1):
|
||||||
|
parser = argparse.ArgumentParser(description)
|
||||||
|
|
||||||
|
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 absolute path to the settings directory')
|
||||||
|
parser.add_argument('-n', '--num-mods', nargs='?', default=default_num_mods, 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()
|
||||||
|
|
||||||
|
# Set default server list if not provided
|
||||||
|
if args.servers is None:
|
||||||
|
args.servers = [
|
||||||
|
'eiger',
|
||||||
|
'jungfrau',
|
||||||
|
'mythen3',
|
||||||
|
'gotthard2',
|
||||||
|
'ctb',
|
||||||
|
'moench',
|
||||||
|
'xilinx_ctb'
|
||||||
|
]
|
||||||
|
|
||||||
|
Log(LogLevel.INFO, 'Arguments:\n' +
|
||||||
|
'rx_hostname: ' + args.rx_hostname +
|
||||||
|
'\nsettingspath: \'' + args.settingspath +
|
||||||
|
'\nservers: \'' + ' '.join(args.servers) +
|
||||||
|
'\nnum_mods: \'' + str(args.num_mods) +
|
||||||
|
'\nnum_frames: \'' + str(args.num_frames) + '\'')
|
||||||
|
|
||||||
|
return args
|
81
updateAPIVersion.py
Normal file
81
updateAPIVersion.py
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||||
|
# Copyright (C) 2025 Contributors to the SLS Detector Package
|
||||||
|
"""
|
||||||
|
Script to update API VERSION file based on the version in VERSION file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
API_FILE = SCRIPT_DIR + "/slsSupportLib/include/sls/versionAPI.h"
|
||||||
|
|
||||||
|
VERSION_FILE = SCRIPT_DIR + "/VERSION"
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description = 'updates API version')
|
||||||
|
parser.add_argument('api_module_name', choices=["APILIB", "APIRECEIVER", "APICTB", "APIGOTTHARD2", "APIMOENCH", "APIEIGER", "APIXILINXCTB", "APIJUNGFRAU", "APIMYTHEN3"], help = 'module name to change api version options are: ["APILIB", "APIRECEIVER", "APICTB", "APIGOTTHARD2", "APIMOENCH", "APIEIGER", "APIXILINXCTB", "APIJUNGFRAU", "APIMYTHEN3"]')
|
||||||
|
parser.add_argument('api_dir', help = 'Relative or absolut path to the module code')
|
||||||
|
|
||||||
|
def update_api_file(new_api : str, api_module_name : str, api_file_name : str):
|
||||||
|
|
||||||
|
regex_pattern = re.compile(rf'#define\s+{api_module_name}\s+')
|
||||||
|
with open(api_file_name, "r") as api_file:
|
||||||
|
lines = api_file.readlines()
|
||||||
|
|
||||||
|
with open(api_file_name, "w") as api_file:
|
||||||
|
for line in lines:
|
||||||
|
if regex_pattern.match(line):
|
||||||
|
api_file.write(f'#define {api_module_name} "{new_api}"\n')
|
||||||
|
else:
|
||||||
|
api_file.write(line)
|
||||||
|
|
||||||
|
def get_latest_modification_date(directory : str):
|
||||||
|
latest_time = 0
|
||||||
|
latest_date = None
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk(directory):
|
||||||
|
for file in files:
|
||||||
|
if file.endswith(".o"):
|
||||||
|
continue
|
||||||
|
full_path = os.path.join(root, file)
|
||||||
|
try:
|
||||||
|
mtime = os.path.getmtime(full_path)
|
||||||
|
if mtime > latest_time:
|
||||||
|
latest_time = mtime
|
||||||
|
except FileNotFoundError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
latest_date = datetime.fromtimestamp(latest_time).strftime("%y%m%d")
|
||||||
|
|
||||||
|
return latest_date
|
||||||
|
|
||||||
|
|
||||||
|
def update_api_version(api_module_name : str, api_dir : str):
|
||||||
|
api_date = get_latest_modification_date(api_dir)
|
||||||
|
api_date = "0x"+str(api_date)
|
||||||
|
|
||||||
|
with open(VERSION_FILE, "r") as version_file:
|
||||||
|
api_version = version_file.read().strip()
|
||||||
|
|
||||||
|
api_version = api_version + " " + api_date #not sure if we should give an argument option version_branch
|
||||||
|
|
||||||
|
update_api_file(api_version, api_module_name, API_FILE)
|
||||||
|
|
||||||
|
print(f"updated {api_module_name} api version to: {api_version}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
api_dir = SCRIPT_DIR + "/" + args.api_dir
|
||||||
|
|
||||||
|
|
||||||
|
update_api_version(args.api_module_name, api_dir)
|
||||||
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
|
||||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
|
||||||
usage="\nUsage: updateAPIVersion.sh [API_NAME] [API_DIR] [API_BRANCH(opt)]."
|
|
||||||
|
|
||||||
if [ $# -lt 2 ]; then
|
|
||||||
echo -e "Requires atleast 2 arguments. $usage"
|
|
||||||
return [-1]
|
|
||||||
fi
|
|
||||||
|
|
||||||
API_NAME=$1
|
|
||||||
PACKAGE_DIR=$PWD
|
|
||||||
API_DIR=$PACKAGE_DIR/$2
|
|
||||||
API_FILE=$PACKAGE_DIR/slsSupportLib/include/sls/versionAPI.h
|
|
||||||
CURR_DIR=$PWD
|
|
||||||
|
|
||||||
if [ ! -d "$API_DIR" ]; then
|
|
||||||
echo "[API_DIR] does not exist. $usage"
|
|
||||||
return [-1]
|
|
||||||
fi
|
|
||||||
|
|
||||||
#go to directory
|
|
||||||
cd $API_DIR
|
|
||||||
|
|
||||||
#deleting line from file
|
|
||||||
NUM=$(sed -n '/'$API_NAME' /=' $API_FILE)
|
|
||||||
#echo $NUM
|
|
||||||
|
|
||||||
|
|
||||||
if [ "$NUM" -gt 0 ]; then
|
|
||||||
sed -i ${NUM}d $API_FILE
|
|
||||||
fi
|
|
||||||
|
|
||||||
#find new API date
|
|
||||||
API_DATE="find . -printf \"%T@ %CY-%Cm-%Cd\n\"| sort -nr | cut -d' ' -f2- | egrep -v '(\.)o' | head -n 1"
|
|
||||||
|
|
||||||
API_DATE=`eval $API_DATE`
|
|
||||||
|
|
||||||
API_DATE=$(sed "s/-//g" <<< $API_DATE | awk '{print $1;}' )
|
|
||||||
|
|
||||||
#extracting only date
|
|
||||||
API_DATE=${API_DATE:2:6}
|
|
||||||
|
|
||||||
#prefix of 0x
|
|
||||||
API_DATE=${API_DATE/#/0x}
|
|
||||||
echo "date="$API_DATE
|
|
||||||
|
|
||||||
|
|
||||||
# API_VAL concatenates branch and date
|
|
||||||
API_VAL=""
|
|
||||||
# API branch is defined (3rd argument)
|
|
||||||
if [ $# -eq 3 ]; then
|
|
||||||
API_BRANCH=$3
|
|
||||||
echo "branch="$API_BRANCH
|
|
||||||
API_VAL+="\"$API_BRANCH $API_DATE\""
|
|
||||||
else
|
|
||||||
# API branch not defined (default is developer)
|
|
||||||
echo "branch=developer"
|
|
||||||
API_VAL+="\"developer $API_DATE\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
#copy it to versionAPI.h
|
|
||||||
echo "#define "$API_NAME $API_VAL >> $API_FILE
|
|
||||||
|
|
||||||
#go back to original directory
|
|
||||||
cd $CURR_DIR
|
|
34
updateClientAPIVersion.py
Normal file
34
updateClientAPIVersion.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||||
|
# Copyright (C) 2025 Contributors to the SLS Detector Package
|
||||||
|
"""
|
||||||
|
Script to update API VERSION for slsReceiverSoftware or slsDetectorSoftware
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
|
||||||
|
from updateAPIVersion import update_api_version
|
||||||
|
|
||||||
|
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description = 'updates API version')
|
||||||
|
parser.add_argument('module_name', nargs="?", choices=["slsDetectorSoftware", "slsReceiverSoftware", "all"], default="all", help = 'module name to change api version options are: ["slsDetectorSoftware", "slsReceiverSoftware, "all"]')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.module_name == "all":
|
||||||
|
client_names = ["APILIB", "APIRECEIVER"]
|
||||||
|
client_directories = [SCRIPT_DIR+"/slsDetectorSoftware", SCRIPT_DIR+"/slsReceiverSoftware"]
|
||||||
|
elif args.module_name == "slsDetectorSoftware":
|
||||||
|
client_names = ["APILIB"]
|
||||||
|
client_directories = [SCRIPT_DIR+"/slsDetectorSoftware"]
|
||||||
|
else:
|
||||||
|
client_names = ["APIRECEIVER"]
|
||||||
|
client_directories = [SCRIPT_DIR+"/slsReceiverSoftware"]
|
||||||
|
|
||||||
|
for client_name, client_directory in zip(client_names, client_directories):
|
||||||
|
update_api_version(client_name, client_directory)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
|||||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
|
||||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
|
||||||
branch=""
|
|
||||||
client_list=("slsDetectorSoftware" "slsReceiverSoftware")
|
|
||||||
usage="\nUsage: updateClientAPI.sh [all|slsDetectorSoftware|slsReceiverSoftware] [branch]. \n\tNo arguments means all with 'developer' branch. \n\tNo 'branch' input means 'developer branch'"
|
|
||||||
|
|
||||||
# arguments
|
|
||||||
if [ $# -eq 0 ]; then
|
|
||||||
declare -a client=${client_list[@]}
|
|
||||||
echo "API Versioning all"
|
|
||||||
elif [ $# -eq 1 ] || [ $# -eq 2 ]; then
|
|
||||||
# 'all' client
|
|
||||||
if [[ $1 == "all" ]]; then
|
|
||||||
declare -a client=${client_list[@]}
|
|
||||||
echo "API Versioning all"
|
|
||||||
else
|
|
||||||
# only one server
|
|
||||||
if [[ $client_list != *$1* ]]; then
|
|
||||||
echo -e "Invalid argument 1: $1. $usage"
|
|
||||||
return -1
|
|
||||||
fi
|
|
||||||
declare -a client=("${1}")
|
|
||||||
#echo "Versioning only $1"
|
|
||||||
fi
|
|
||||||
if [ $# -eq 2 ]; then
|
|
||||||
if [[ $client_list == *$2* ]]; then
|
|
||||||
echo -e "Invalid argument 2: $2. $usage"
|
|
||||||
return -1
|
|
||||||
fi
|
|
||||||
branch+=$2
|
|
||||||
#echo "with branch $branch"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo -e "Too many arguments.$usage"
|
|
||||||
return -1
|
|
||||||
fi
|
|
||||||
|
|
||||||
#echo "list is: ${client[@]}"
|
|
||||||
|
|
||||||
# versioning each client
|
|
||||||
for i in ${client[@]}
|
|
||||||
do
|
|
||||||
dir=$i
|
|
||||||
case $dir in
|
|
||||||
slsDetectorSoftware)
|
|
||||||
declare -a name=APILIB
|
|
||||||
;;
|
|
||||||
slsReceiverSoftware)
|
|
||||||
declare -a name=APIRECEIVER
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo -n "unknown client argument $i"
|
|
||||||
return -1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
echo -e "Versioning $dir [$name]"
|
|
||||||
./updateAPIVersion.sh $name $dir $branch
|
|
||||||
done
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user