Commit 650b2dc6 authored by Bartosz Podrygajlo's avatar Bartosz Podrygajlo

A script to run CI tests locally.

Added ./run_locally.sh script. The script takes one argument being the testcase
that one wants to run. The testcase is run locally. This means that some testcases that
utilize hardware resources will not run. However most if not all rfsimulator testcases
should run as in CI.

To this end, the CI python scripting framework was updated, adding --local flag which changes
the script behavior as follows:
 - overrides <node> and <srv_node> XML elements to 'localhost' so all commands are executed locally
 - Avoid running image pull, image cleanup and workspace creation steps of the scripts:
   user is responsible for that
parent 5bd2eb86
...@@ -47,6 +47,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,CONTAINERS,HELP,SCA,PHYSIM,CLUSTER): ...@@ -47,6 +47,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,CONTAINERS,HELP,SCA,PHYSIM,CLUSTER):
py_param_file_present = False py_param_file_present = False
py_params={} py_params={}
force_local = False
while len(argvs) > 1: while len(argvs) > 1:
myArgv = argvs.pop(1) # 0th is this file's name myArgv = argvs.pop(1) # 0th is this file's name
...@@ -54,6 +55,9 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,CONTAINERS,HELP,SCA,PHYSIM,CLUSTER): ...@@ -54,6 +55,9 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,CONTAINERS,HELP,SCA,PHYSIM,CLUSTER):
if re.match('^\-\-help$', myArgv, re.IGNORECASE): if re.match('^\-\-help$', myArgv, re.IGNORECASE):
HELP.GenericHelp(CONST.Version) HELP.GenericHelp(CONST.Version)
sys.exit(0) sys.exit(0)
if re.match('^\-\-local$', myArgv, re.IGNORECASE):
force_local = True
#--apply=<filename> as parameters file, to replace inline parameters #--apply=<filename> as parameters file, to replace inline parameters
elif re.match('^\-\-Apply=(.+)$', myArgv, re.IGNORECASE): elif re.match('^\-\-Apply=(.+)$', myArgv, re.IGNORECASE):
...@@ -271,4 +275,4 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,CONTAINERS,HELP,SCA,PHYSIM,CLUSTER): ...@@ -271,4 +275,4 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,CONTAINERS,HELP,SCA,PHYSIM,CLUSTER):
HELP.GenericHelp(CONST.Version) HELP.GenericHelp(CONST.Version)
sys.exit('Invalid Parameter: ' + myArgv) sys.exit('Invalid Parameter: ' + myArgv)
return py_param_file_present, py_params, mode return py_param_file_present, py_params, mode, force_local
...@@ -217,6 +217,8 @@ class RemoteCmd(Cmd): ...@@ -217,6 +217,8 @@ class RemoteCmd(Cmd):
return client return client
def _lookup_ssh_config(hostname): def _lookup_ssh_config(hostname):
if is_local(hostname):
raise ValueError("Using localhost as SSH target is not allowed: use LocalCmd instead.")
ssh_config = paramiko.SSHConfig() ssh_config = paramiko.SSHConfig()
user_config_file = os.path.expanduser("~/.ssh/config") user_config_file = os.path.expanduser("~/.ssh/config")
if os.path.exists(user_config_file): if os.path.exists(user_config_file):
......
...@@ -43,6 +43,8 @@ def GenericHelp(vers): ...@@ -43,6 +43,8 @@ def GenericHelp(vers):
print(' InitiateHtml, FinalizeHtml') print(' InitiateHtml, FinalizeHtml')
print(' TerminateeNB, TerminateHSS, TerminateMME, TerminateSPGW') print(' TerminateeNB, TerminateHSS, TerminateMME, TerminateSPGW')
print(' LogCollectBuild, LogCollecteNB, LogCollectHSS, LogCollectMME, LogCollectSPGW, LogCollectPing, LogCollectIperf') print(' LogCollectBuild, LogCollecteNB, LogCollectHSS, LogCollectMME, LogCollectSPGW, LogCollectPing, LogCollectIperf')
print(' --local Force local execution: rewrites the test xml script before running to always execute on localhost. Assumes')
print(' images are available locally, will not remove any images and will run inside the current repo directory')
def GitSrvHelp(repository,branch,commit,mergeallow,targetbranch): def GitSrvHelp(repository,branch,commit,mergeallow,targetbranch):
print(' --ranRepository=[OAI RAN Repository URL] -- ' + repository) print(' --ranRepository=[OAI RAN Repository URL] -- ' + repository)
......
...@@ -212,13 +212,17 @@ def ExecuteActionWithParam(action): ...@@ -212,13 +212,17 @@ def ExecuteActionWithParam(action):
elif action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Terminate_UE' or action == 'CheckStatusUE' or action == 'DataEnable_UE' or action == 'DataDisable_UE': elif action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Terminate_UE' or action == 'CheckStatusUE' or action == 'DataEnable_UE' or action == 'DataDisable_UE':
CiTestObj.ue_ids = test.findtext('id').split(' ') CiTestObj.ue_ids = test.findtext('id').split(' ')
if test.findtext('nodes'): if force_local:
CiTestObj.nodes = test.findtext('nodes').split(' ') # Change all execution targets to localhost
if len(CiTestObj.ue_ids) != len(CiTestObj.nodes): CiTestObj.nodes = ['localhost'] * len(CiTestObj.ue_ids)
logging.error('Number of Nodes are not equal to the total number of UEs')
sys.exit("Mismatch in number of Nodes and UIs")
else: else:
CiTestObj.nodes = [None] * len(CiTestObj.ue_ids) if test.findtext('nodes'):
CiTestObj.nodes = test.findtext('nodes').split(' ')
if len(CiTestObj.ue_ids) != len(CiTestObj.nodes):
logging.error('Number of Nodes are not equal to the total number of UEs')
sys.exit("Mismatch in number of Nodes and UIs")
else:
CiTestObj.nodes = [None] * len(CiTestObj.ue_ids)
if action == 'Initialize_UE': if action == 'Initialize_UE':
success = CiTestObj.InitializeUE(HTML) success = CiTestObj.InitializeUE(HTML)
elif action == 'Attach_UE': elif action == 'Attach_UE':
...@@ -238,13 +242,17 @@ def ExecuteActionWithParam(action): ...@@ -238,13 +242,17 @@ def ExecuteActionWithParam(action):
CiTestObj.ping_args = test.findtext('ping_args') CiTestObj.ping_args = test.findtext('ping_args')
CiTestObj.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold') CiTestObj.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold')
CiTestObj.ue_ids = test.findtext('id').split(' ') CiTestObj.ue_ids = test.findtext('id').split(' ')
if test.findtext('nodes'): if force_local:
CiTestObj.nodes = test.findtext('nodes').split(' ') # Change all execution targets to localhost
if len(CiTestObj.ue_ids) != len(CiTestObj.nodes): CiTestObj.nodes = ['localhost'] * len(CiTestObj.ue_ids)
logging.error('Number of Nodes are not equal to the total number of UEs')
sys.exit("Mismatch in number of Nodes and UIs")
else: else:
CiTestObj.nodes = [None] * len(CiTestObj.ue_ids) if test.findtext('nodes'):
CiTestObj.nodes = test.findtext('nodes').split(' ')
if len(CiTestObj.ue_ids) != len(CiTestObj.nodes):
logging.error('Number of Nodes are not equal to the total number of UEs')
sys.exit("Mismatch in number of Nodes and UIs")
else:
CiTestObj.nodes = [None] * len(CiTestObj.ue_ids)
ping_rttavg_threshold = test.findtext('ping_rttavg_threshold') or '' ping_rttavg_threshold = test.findtext('ping_rttavg_threshold') or ''
success = CiTestObj.Ping(HTML,EPC,CONTAINERS) success = CiTestObj.Ping(HTML,EPC,CONTAINERS)
...@@ -252,15 +260,19 @@ def ExecuteActionWithParam(action): ...@@ -252,15 +260,19 @@ def ExecuteActionWithParam(action):
CiTestObj.iperf_args = test.findtext('iperf_args') CiTestObj.iperf_args = test.findtext('iperf_args')
CiTestObj.ue_ids = test.findtext('id').split(' ') CiTestObj.ue_ids = test.findtext('id').split(' ')
CiTestObj.svr_id = test.findtext('svr_id') or None CiTestObj.svr_id = test.findtext('svr_id') or None
if test.findtext('nodes'): if force_local:
CiTestObj.nodes = test.findtext('nodes').split(' ') # Change all execution targets to localhost
if len(CiTestObj.ue_ids) != len(CiTestObj.nodes): CiTestObj.nodes = ['localhost'] * len(CiTestObj.ue_ids)
logging.error('Number of Nodes are not equal to the total number of UEs')
sys.exit("Mismatch in number of Nodes and UIs")
else: else:
CiTestObj.nodes = [None] * len(CiTestObj.ue_ids) if test.findtext('nodes'):
CiTestObj.nodes = test.findtext('nodes').split(' ')
if len(CiTestObj.ue_ids) != len(CiTestObj.nodes):
logging.error('Number of Nodes are not equal to the total number of UEs')
sys.exit("Mismatch in number of Nodes and UIs")
else:
CiTestObj.nodes = [None] * len(CiTestObj.ue_ids)
if test.findtext('svr_node'): if test.findtext('svr_node'):
CiTestObj.svr_node = test.findtext('svr_node') CiTestObj.svr_node = test.findtext('svr_node') if not force_local else 'localhost'
CiTestObj.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold') CiTestObj.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold')
CiTestObj.iperf_bitrate_threshold = test.findtext('iperf_bitrate_threshold') or '90' CiTestObj.iperf_bitrate_threshold = test.findtext('iperf_bitrate_threshold') or '90'
CiTestObj.iperf_profile = test.findtext('iperf_profile') or 'balanced' CiTestObj.iperf_profile = test.findtext('iperf_profile') or 'balanced'
...@@ -356,6 +368,9 @@ def ExecuteActionWithParam(action): ...@@ -356,6 +368,9 @@ def ExecuteActionWithParam(action):
elif action == 'Undeploy_Object': elif action == 'Undeploy_Object':
success = CONTAINERS.UndeployObject(HTML, RAN) success = CONTAINERS.UndeployObject(HTML, RAN)
elif action == 'Create_Workspace': elif action == 'Create_Workspace':
if force_local:
# Do not create a working directory when running locally. Current repo directory will be used
return True
success = CONTAINERS.Create_Workspace(HTML) success = CONTAINERS.Create_Workspace(HTML)
elif action == 'Run_Physim': elif action == 'Run_Physim':
...@@ -375,6 +390,9 @@ def ExecuteActionWithParam(action): ...@@ -375,6 +390,9 @@ def ExecuteActionWithParam(action):
success = CONTAINERS.Push_Image_to_Local_Registry(HTML, svr_id) success = CONTAINERS.Push_Image_to_Local_Registry(HTML, svr_id)
elif action == 'Pull_Local_Registry' or action == 'Clean_Test_Server_Images': elif action == 'Pull_Local_Registry' or action == 'Clean_Test_Server_Images':
if force_local:
# Do not pull or remove images when running locally. User is supposed to handle image creation & cleanup
return True
svr_id = test.findtext('svr_id') svr_id = test.findtext('svr_id')
images = test.findtext('images').split() images = test.findtext('images').split()
# hack: for FlexRIC, we need to overwrite the tag to use # hack: for FlexRIC, we need to overwrite the tag to use
...@@ -463,7 +481,9 @@ CLUSTER = cls_cluster.Cluster() ...@@ -463,7 +481,9 @@ CLUSTER = cls_cluster.Cluster()
#----------------------------------------------------------- #-----------------------------------------------------------
import args_parse import args_parse
py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,EPC,CONTAINERS,HELP,SCA,PHYSIM,CLUSTER) # Force local execution, move all execution targets to localhost
force_local = False
py_param_file_present, py_params, mode, force_local = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,EPC,CONTAINERS,HELP,SCA,PHYSIM,CLUSTER)
......
#!/bin/bash
set -e
SHORT_COMMIT_SHA=$(git rev-parse --short=8 HEAD)
COMMIT_SHA=$(git rev-parse HEAD)
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
REPO_PATH=$(dirname $(realpath $0))/../
TESTCASE=$1
if [ $# -eq 0 ]
then
echo "Provide a testcase as an argument"
exit 1
fi
# The script assumes you've build the following images:
#
# docker build . -f docker/Dockerfile.gNB.ubuntu22 -t oai-gnb
# docker build . -f docker/Dockerfile.nrUE.ubuntu22 -t oai-nr-ue
#
# The images above depend on the following images:
#
# docker build . -f docker/Dockerfile.build.ubuntu22 -t ran-build
# dokcer build . -f docker/Dockerfile.base.ubuntu22 -t ran-base
docker tag oai-nr-ue oai-ci/oai-nr-ue:develop-${SHORT_COMMIT_SHA}
docker tag oai-gnb oai-ci/oai-gnb:develop-${SHORT_COMMIT_SHA}
python3 main.py --mode=TesteNB --ranRepository=NONE --ranBranch=${CURRENT_BRANCH} \
--ranCommitID=${COMMIT_SHA} --ranAllowMerge=false \
--ranTargetBranch=NONE --eNBIPAddress=NONE --eNBUserName=NONE --eNBPassword=NONE \
--eNBSourceCodePath=NONE --EPCIPAddress=NONE --EPCType=OAI --eNBPassword=NONE \
--eNBSourceCodePath=${REPO_PATH} --EPCIPAddress=NONE \
--EPCUserName=NONE --EPCPassword=NONE --EPCSourceCodePath=NONE \
--XMLTestFile=xml_files/${TESTCASE} --local
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment