Commit 7b170344 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/ci-nrue-test' into integration_2023_w27

parents 4ae73af4 a0d9beb0
...@@ -464,6 +464,26 @@ pipeline { ...@@ -464,6 +464,26 @@ pipeline {
} }
} }
} }
stage ("SA-OAIUE-CN5G") {
when { expression {do5Gtest} }
steps {
script {
triggerCN5GSlaveJob ('RAN-SA-OAIUE-CN5G', 'RAN-SA-OAIUE-CN5G')
}
}
post {
always {
script {
finalizeSlaveJob('RAN-SA-OAIUE-CN5G')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
}
}
}
}
} }
} }
stage ("DockerHub-Push") { stage ("DockerHub-Push") {
......
#!/bin/groovy
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
// Location of the executor node
def pythonExecutor = params.pythonExecutor
// Location of the test XML file to be run
def testXMLFile = params.pythonTestXmlFile
def mainPythonAllXmlFiles = ""
def buildStageStatus = true
// Name of the test stage
def testStageName = params.pipelineTestStageName
// Name of the resource
def lockResources = []
if (params.LockResources != null && params.LockResources.trim().length() > 0)
params.LockResources.trim().split(",").each{lockResources += [resource: it.trim()]}
// Global Parameters. Normally they should be populated when the master job
// triggers the slave job with parameters
def eNB_Repository
def eNB_Branch
def eNB_CommitID
def eNB_AllowMergeRequestProcess = false
def eNB_TargetBranch
// Flags
def scmEvent = false
def upstreamEvent = false
//-------------------------------------------------------------------------------
// Pipeline start
pipeline {
agent {
label pythonExecutor
}
options {
timestamps()
ansiColor('xterm')
lock(extra: lockResources)
}
stages {
stage ('Verify Parameters') {
steps {
script {
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"'
JOB_TIMESTAMP = JOB_TIMESTAMP.trim()
def allParametersPresent = true
// It is already to late to check it
if (params.pythonExecutor != null) {
echo "eNB CI executor node : ${pythonExecutor}"
}
// If not present picking a default Stage Name
if (params.pipelineTestStageName == null) {
// picking default
testStageName = 'Template Test Stage'
}
if (params.LockResources == null) {
echo "no LockResources given"
allParametersPresent = false
}
if (params.eNB_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB_Credentials == null) {
allParametersPresent = false
}
if (params.eNB1_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB1_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB1_Credentials == null) {
allParametersPresent = false
}
// the following 4 parameters should be pushed by the master trigger
// if not present, take the job GIT variables (used for developing)
if (params.eNB_Repository == null) {
eNB_Repository = env.GIT_URL
} else {
eNB_Repository = params.eNB_Repository
}
echo "eNB_Repository : ${eNB_Repository}"
if (params.eNB_Branch == null) {
eNB_Branch = env.GIT_BRANCH
} else {
eNB_Branch = params.eNB_Branch
}
echo "eNB_Branch : ${eNB_Branch}"
if (params.eNB_CommitID == null) {
eNB_CommitID = env.GIT_COMMIT
} else {
eNB_CommitID = params.eNB_CommitID
}
echo "eNB_CommitID : ${eNB_CommitID}"
if (params.eNB_mergeRequest != null) {
eNB_AllowMergeRequestProcess = params.eNB_mergeRequest
if (eNB_AllowMergeRequestProcess) {
if (params.eNB_TargetBranch != null) {
eNB_TargetBranch = params.eNB_TargetBranch
} else {
eNB_TargetBranch = 'develop'
}
echo "eNB_TargetBranch : ${eNB_TargetBranch}"
}
}
if (params.EPC_IPAddress == null) {
allParametersPresent = false
}
if (params.EPC_Type == null) {
allParametersPresent = false
}
if (params.EPC_SourceCodePath == null) {
allParametersPresent = false
}
if (params.EPC_Credentials == null) {
allParametersPresent = false
}
if (params.OC_Credentials == null) {
allParametersPresent = false
}
if (params.OC_ProjectName == null) {
allParametersPresent = false
}
if (allParametersPresent) {
echo "All parameters are present"
if (eNB_AllowMergeRequestProcess) {
sh "git fetch"
sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest"
} else {
sh "git fetch"
sh "git checkout -f ${eNB_CommitID}"
}
} else {
echo "Some parameters are missing"
sh "./ci-scripts/fail.sh"
}
}
}
}
stage ("Deploy and Test") {
steps {
script {
dir ('ci-scripts') {
echo "\u2705 \u001B[32m${testStageName}\u001B[0m"
// If not present picking a default XML file
if (params.pythonTestXmlFile == null) {
// picking default
testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml'
echo "Test XML file(default): ${testXMLFile}"
mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " "
} else {
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists(xmlFile)) {
mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " "
echo "Test XML file : ${xmlFile}"
}
}
}
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB1_Credentials}", usernameVariable: 'eNB1_Username', passwordVariable: 'eNB1_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password']
]) {
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists(xmlFile)) {
try {
sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath}"
} catch (Exception e) {
currentBuild.result = 'FAILURE'
buildStageStatus = false
}
}
}
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
}
}
}
}
}
stage ("Log Collection") {
steps {
script {
dir ('ci-scripts') {
// Zipping all archived log files
sh "mkdir test_logs"
sh "mv *.log* test_logs || true"
sh "zip -r -qq test_logs_${env.BUILD_ID}.zip *test_log*/"
sh "rm -rf *test_log*/"
if (fileExists("test_logs_${env.BUILD_ID}.zip")) {
archiveArtifacts artifacts: "test_logs_${env.BUILD_ID}.zip"
}
if (fileExists("test_logs_CN.zip")){
sh "mv test_logs_CN.zip test_logs_CN_${env.BUILD_ID}.zip"
archiveArtifacts artifacts: "test_logs_CN_${env.BUILD_ID}.zip"
}
if (fileExists("test_results.html")) {
sh "mv test_results.html test_results-${env.JOB_NAME}.html"
sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: <a href=\"${BUILD_URL}\">${BUILD_ID}</a>#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html"
archiveArtifacts artifacts: "test_results-${env.JOB_NAME}.html"
}
}
}
}
}
}
}
...@@ -122,10 +122,13 @@ amarisoft_ue_10: ...@@ -122,10 +122,13 @@ amarisoft_ue_10:
CmdPrefix: ip netns exec ue10 CmdPrefix: ip netns exec ue10
MTU: 1500 MTU: 1500
oai_ue_obelix: oai_ue_caracal:
Host: obelix Host: caracal
AttachScript: 'docker start oai-nr-ue'
DetachScript: 'docker stop oai-nr-ue'
NetworkScript: ip a show dev oaitun_ue1 NetworkScript: ip a show dev oaitun_ue1
IF: oaitun_ue1 IF: oaitun_ue1
MTU: 1500
rfsim5g_gnb_nos1: rfsim5g_gnb_nos1:
Host: localhost Host: localhost
......
...@@ -82,6 +82,7 @@ class Cluster: ...@@ -82,6 +82,7 @@ class Cluster:
self.ranTargetBranch = "" self.ranTargetBranch = ""
self.cmd = None self.cmd = None
self.imageToPull = '' self.imageToPull = ''
self.testSvrId = None
def _recreate_entitlements(self): def _recreate_entitlements(self):
# recreating entitlements, don't care if deletion fails # recreating entitlements, don't care if deletion fails
...@@ -195,12 +196,13 @@ class Cluster: ...@@ -195,12 +196,13 @@ class Cluster:
self.cmd.run(f'oc delete -f {filename}') self.cmd.run(f'oc delete -f {filename}')
def PullClusterImage(self, HTML, RAN): def PullClusterImage(self, HTML, RAN):
if self.testSvrId == None: self.testSvrId = self.eNBIPAddress
if self.imageToPull == '': if self.imageToPull == '':
HELP.GenericHelp(CONST.Version) HELP.GenericHelp(CONST.Version)
HELP.EPCSrvHelp(self.imageToPull) sys.exit('Insufficient Parameter')
sys.exit('Insufficient eNB Parameters') logging.debug(f'Pull OC image {self.imageToPull} to server {self.testSvrId}')
self.testCase_id = HTML.testCase_id self.testCase_id = HTML.testCase_id
cmd = cls_cmd.getConnection(self.eNBIPAddress) cmd = cls_cmd.getConnection(self.testSvrId)
succeeded = OC_login(cmd, self.OCUserName, self.OCPassword, CI_OC_RAN_NAMESPACE) succeeded = OC_login(cmd, self.OCUserName, self.OCPassword, CI_OC_RAN_NAMESPACE)
if not succeeded: if not succeeded:
logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m') logging.error('\u001B[1m OC Cluster Login Failed\u001B[0m')
......
...@@ -52,7 +52,7 @@ import cls_cmd ...@@ -52,7 +52,7 @@ import cls_cmd
import sshconnection as SSH import sshconnection as SSH
import helpreadme as HELP import helpreadme as HELP
import constants as CONST import constants as CONST
import cls_oaicitest
#----------------------------------------------------------- #-----------------------------------------------------------
# Helper functions used here and in other classes # Helper functions used here and in other classes
# (e.g., cls_cluster.py) # (e.g., cls_cluster.py)
...@@ -838,7 +838,7 @@ class Containerize(): ...@@ -838,7 +838,7 @@ class Containerize():
mySSH.command('cd ' + lSourcePath + '/' + self.yamlPath[self.eNB_instance], '\$', 5) mySSH.command('cd ' + lSourcePath + '/' + self.yamlPath[self.eNB_instance], '\$', 5)
mySSH.command('cp docker-compose.y*ml ci-docker-compose.yml', '\$', 5) mySSH.command('cp docker-compose.y*ml ci-docker-compose.yml', '\$', 5)
imagesList = ['oai-enb', 'oai-gnb', 'oai-nr-cuup', 'oai-gnb-aw2s'] imagesList = ['oai-enb', 'oai-gnb', 'oai-nr-cuup', 'oai-gnb-aw2s', 'oai-nr-ue']
for image in imagesList: for image in imagesList:
imageTag = ImageTagToUse(image, self.ranCommitID, self.ranBranch, self.ranAllowMerge) imageTag = ImageTagToUse(image, self.ranCommitID, self.ranBranch, self.ranAllowMerge)
mySSH.command(f'sed -i -e "s#image: {image}:latest#image: oai-ci/{imageTag}#" ci-docker-compose.yml', '\$', 2) mySSH.command(f'sed -i -e "s#image: {image}:latest#image: oai-ci/{imageTag}#" ci-docker-compose.yml', '\$', 2)
...@@ -877,6 +877,7 @@ class Containerize(): ...@@ -877,6 +877,7 @@ class Containerize():
else: else:
time.sleep(10) time.sleep(10)
cnt += 1 cnt += 1
mySSH.command('docker inspect --format="ImageUsed: {{.Config.Image}}" ' + containerName, '\$', 5) mySSH.command('docker inspect --format="ImageUsed: {{.Config.Image}}" ' + containerName, '\$', 5)
for stdoutLine in mySSH.getBefore().split('\n'): for stdoutLine in mySSH.getBefore().split('\n'):
if stdoutLine.count('ImageUsed: oai-ci'): if stdoutLine.count('ImageUsed: oai-ci'):
...@@ -903,7 +904,7 @@ class Containerize(): ...@@ -903,7 +904,7 @@ class Containerize():
cnt = 0 cnt = 0
while (cnt < 20): while (cnt < 20):
mySSH.command('docker logs ' + containerName + ' | egrep --text --color=never -i "wait|sync|Starting"', '\$', 30) mySSH.command('docker logs ' + containerName + ' | egrep --text --color=never -i "wait|sync|Starting"', '\$', 30)
result = re.search('got sync|Starting F1AP at CU', mySSH.getBefore()) result = re.search('got sync|Starting F1AP at CU|Got sync', mySSH.getBefore())
if result is None: if result is None:
time.sleep(6) time.sleep(6)
cnt += 1 cnt += 1
...@@ -993,7 +994,6 @@ class Containerize(): ...@@ -993,7 +994,6 @@ class Containerize():
mySSH.command('docker volume prune --force', '\$', 20) mySSH.command('docker volume prune --force', '\$', 20)
mySSH.close() mySSH.close()
# Analyzing log file! # Analyzing log file!
files = ','.join([f'{s}-{HTML.testCase_id}' for s in services]) files = ','.join([f'{s}-{HTML.testCase_id}' for s in services])
if len(services) > 1: if len(services) > 1:
...@@ -1005,6 +1005,16 @@ class Containerize(): ...@@ -1005,6 +1005,16 @@ class Containerize():
HTML.htmleNBFailureMsg='Could not copy logfile to analyze it!' HTML.htmleNBFailureMsg='Could not copy logfile to analyze it!'
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE) HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE)
self.exitStatus = 1 self.exitStatus = 1
# use function for UE log analysis, when oai-nr-ue container is used
elif 'oai-nr-ue' in services:
self.exitStatus == 0
logging.debug('\u001B[1m Analyzing UE logfile ' + filename + ' \u001B[0m')
logStatus = cls_oaicitest.OaiCiTest().AnalyzeLogFile_UE(f'{filename}', HTML, RAN)
if (logStatus < 0):
fullStatus = False
HTML.CreateHtmlTestRow('UE log Analysis', 'KO', logStatus)
else:
HTML.CreateHtmlTestRow('UE log Analysis', 'OK', CONST.ALL_PROCESSES_OK)
else: else:
for svcName in services: for svcName in services:
filename = f'{svcName}-{HTML.testCase_id}.log' filename = f'{svcName}-{HTML.testCase_id}.log'
......
...@@ -1059,7 +1059,7 @@ class OaiCiTest(): ...@@ -1059,7 +1059,7 @@ class OaiCiTest():
cmd = cls_cmd.getConnection(ue.getHost()) cmd = cls_cmd.getConnection(ue.getHost())
cmd.run(f'rm /tmp/{server_filename}', reportNonZero=False) cmd.run(f'rm /tmp/{server_filename}', reportNonZero=False)
port = f'{5002+idx}' port = f'{5002+idx}'
cmd.run(f'{ue.getCmdPrefix()} iperf3 -c {cn_target_ip} -p {port} {iperf_opt} --get-server-output &> /tmp/{server_filename}', timeout=iperf_time*1.5) cmd.run(f'{ue.getCmdPrefix()} iperf3 -B {ue.getIP()} -c {cn_target_ip} -p {port} {iperf_opt} --get-server-output &> /tmp/{server_filename}', timeout=iperf_time*1.5)
cmd.copyin(f'/tmp/{server_filename}', server_filename) cmd.copyin(f'/tmp/{server_filename}', server_filename)
cmd.close() cmd.close()
if udpIperf: if udpIperf:
......
Active_gNBs = ( "gNB-OAI");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_CU_ID = 0xe00;
gNB_name = "gNB-OAI";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 208; mnc = 97; mnc_length = 2; snssaiList = ({sst = 1;}); });
nr_cellid = 12345678L
////////// Physical parameters:
min_rxtxtime = 5;
do_SRS = 0;
force_256qam_off = 1;
pdsch_AntennaPorts_N1 = 1;
pdsch_AntennaPorts_XP = 1;
pusch_AntennaPorts = 1;
pdcch_ConfigSIB1 = (
{
controlResourceSetZero = 12;
searchSpaceZero = 0;
}
);
servingCellConfigCommon = (
{
#spCellConfigCommon
physCellId = 0;
# downlinkConfigCommon
#frequencyInfoDL
dl_frequencyBand = 78;
absoluteFrequencySSB = 634080;
dl_absoluteFrequencyPointA = 632808;
#scs-SpecificCarrierList
dl_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
dl_subcarrierSpacing = 1;
dl_carrierBandwidth = 106;
#initialDownlinkBWP
#genericParameters
# this is RBstart=0,L=106 (275*(L-1))+RBstart
initialDLBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialDLBWPsubcarrierSpacing = 1;
#pdcch-ConfigCommon
initialDLBWPcontrolResourceSetZero = 12;
initialDLBWPsearchSpaceZero = 0;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
#scs-SpecificCarrierList
ul_offstToCarrier = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
ul_subcarrierSpacing = 1;
ul_carrierBandwidth = 106;
pMax = 20;
#initialUplinkBWP
#genericParameters
initialULBWPlocationAndBandwidth = 28875;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
initialULBWPsubcarrierSpacing = 1;
#rach-ConfigCommon
#rach-ConfigGeneric
prach_ConfigurationIndex = 98;
#prach_msg1_FDM
#0 = one, 1=two, 2=four, 3=eight
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 0;
zeroCorrelationZoneConfig = 12;
preambleReceivedTargetPower = -96;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;
#oneHalf (0..15) 4,8,12,16,...60,64
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15;
#ra_ContentionResolutionTimer
#(0..7) 8,16,24,32,40,48,56,64
ra_ContentionResolutionTimer = 7;
rsrp_ThresholdSSB = 19;
#prach-RootSequenceIndex_PR
#1 = 839, 2 = 139
prach_RootSequenceIndex_PR = 2;
prach_RootSequenceIndex = 1;
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
#
msg1_SubcarrierSpacing = 1,
# restrictedSetConfig
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
msg3_DeltaPreamble = 1;
p0_NominalWithGrant = -90;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
p0_nominal = -70;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
ssb_PositionsInBurst_Bitmap = 1;
# ssb_periodicityServingCell
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spar e1
ssb_periodicityServingCell = 2;
# dmrs_TypeA_position
# 0 = pos2, 1 = pos3
dmrs_TypeA_Position = 0;
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
subcarrierSpacing = 1;
#tdd-UL-DL-ConfigurationCommon
# subcarrierSpacing
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
referenceSubcarrierSpacing = 1;
# pattern1
# dl_UL_TransmissionPeriodicity
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
dl_UL_TransmissionPeriodicity = 6;
nrofDownlinkSlots = 7;
nrofDownlinkSymbols = 6;
nrofUplinkSlots = 2;
nrofUplinkSymbols = 4;
ssPBCH_BlockPower = -25;
}
);
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// AMF parameters:
amf_ip_address = ( { ipv4 = "172.21.6.100";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_NG_AMF = "eno33np0";
GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.124/22";
GNB_INTERFACE_NAME_FOR_NGU = "eno33np0";
GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.124/22";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
pusch_TargetSNRx10 = 180;
pucch_TargetSNRx10 = 200;
ulsch_max_frame_inactivity = 1;
ul_max_mcs = 16;
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
prach_dtx_threshold = 120;
#pucch0_dtx_threshold = 150;
}
);
RUs = (
{
local_rf = "yes";
nb_tx = 1;
nb_rx = 1;
att_tx = 0;
att_rx = 0;
bands = [78];
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
eNB_instances = [0];
##beamforming 1x2 matrix: 1 layer x 2 antennas
bf_weights = [0x00007fff, 0x0000];
sf_extension = 0
sdr_addrs = "addr=192.168.80.52,clock_source=internal,time_source=internal"
}
);
security = {
# preferred ciphering algorithms
# the first one of the list that an UE supports in chosen
# valid values: nea0, nea1, nea2, nea3
ciphering_algorithms = ( "nea0" );
# preferred integrity algorithms
# the first one of the list that an UE supports in chosen
# valid values: nia0, nia1, nia2, nia3
integrity_algorithms = ( "nia2", "nia0" );
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
drb_ciphering = "yes";
drb_integrity = "no";
};
log_config :
{
global_log_level ="info";
hw_log_level ="info";
phy_log_level ="info";
mac_log_level ="info";
rlc_log_level ="info";
pdcp_log_level ="info";
rrc_log_level ="info";
f1ap_log_level ="debug";
gtpu_log_level ="info";
};
...@@ -420,10 +420,12 @@ def GetParametersFromXML(action): ...@@ -420,10 +420,12 @@ def GetParametersFromXML(action):
RAN.command = test.findtext('command') RAN.command = test.findtext('command')
RAN.command_fail = test.findtext('command_fail') in ['True', 'true', 'Yes', 'yes'] RAN.command_fail = test.findtext('command_fail') in ['True', 'true', 'Yes', 'yes']
elif action == 'Pull_Cluster_Image': elif action == 'Pull_Cluster_Image':
# CLUSTER.imageToPull.clear()
string_field = test.findtext('images_to_pull') string_field = test.findtext('images_to_pull')
if (string_field is not None): if (string_field is not None):
CLUSTER.imageToPull = string_field.split() CLUSTER.imageToPull = string_field.split()
string_field = test.findtext('test_svr_id')
if (string_field is not None):
CLUSTER.testSvrId = string_field
else: else:
logging.warning(f"unknown action {action} from option-parsing point-of-view") logging.warning(f"unknown action {action} from option-parsing point-of-view")
......
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>TEST-5G-NRUE</htmlTabRef>
<htmlTabName>40 MHz TDD SA</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>1</repeatCount>
<TestCaseRequestedList>
010000 010001
020000 020001
000001
001000
002000
000100
000200
040001 040000
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010000">
<class>Pull_Cluster_Image</class>
<desc>Pull Images from Cluster</desc>
<images_to_pull>oai-gnb</images_to_pull>
<test_svr_id>avra</test_svr_id>
</testCase>
<testCase id="010001">
<class>Pull_Cluster_Image</class>
<desc>Pull Images from Cluster</desc>
<images_to_pull>oai-nr-ue</images_to_pull>
<test_svr_id>caracal</test_svr_id>
</testCase>
<testCase id = "030000">
<class>Custom_Command</class>
<desc>Reboot USRP N310</desc>
<node>avra</node>
<command>ssh root@192.168.80.52 reboot ; sleep 45</command>
</testCase>
<testCase id = "030001">
<class>Custom_Command</class>
<desc>Reboot USRP N310</desc>
<node>caracal</node>
<command>ssh root@192.168.20.2 reboot ; sleep 45</command>
</testCase>
<testCase id="020000">
<class>Deploy_Object</class>
<desc>Deploy gNB (TDD/Band78/40MHz/N310) in a container</desc>
<yaml_path>ci-scripts/yaml_files/5g_sa_n310_gnb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="020001">
<class>Deploy_Object</class>
<desc>Deploy nrUE (TDD/Band78/40MHz/N310) in a container</desc>
<yaml_path>ci-scripts/yaml_files/5g_sa_n310_nrue</yaml_path>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
</testCase>
<testCase id="000001">
<class>Attach_UE</class>
<desc>Attach OAIUE</desc>
<id>oai_ue_caracal</id>
</testCase>
<testCase id="000100">
<class>Iperf</class>
<desc>iperf (DL/20Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 20M -t 30 -i 1 -R</iperf_args>
<direction>IPERF3</direction>
<id>oai_ue_caracal</id>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
</testCase>
<testCase id="000200">
<class>Iperf</class>
<desc>iperf (UL/5Mbps/UDP)(30 sec)(single-ue profile)</desc>
<iperf_args>-u -b 5M -t 30 -i 1 </iperf_args>
<direction>IPERF3</direction>
<id>oai_ue_caracal</id>
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
</testCase>
<testCase id="001000">
<class>Ping</class>
<desc>Ping: 20pings in 20sec</desc>
<id>oai_ue_caracal</id>
<ping_args>-c 20</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>25</ping_rttavg_threshold>
</testCase>
<testCase id="002000">
<class>Ping</class>
<desc>Ping: 100pings in 20sec</desc>
<id>oai_ue_caracal</id>
<ping_args>-c 100 -i 0.2</ping_args>
<ping_packetloss_threshold>1</ping_packetloss_threshold>
<ping_rttavg_threshold>30</ping_rttavg_threshold>
</testCase>
<testCase id="040000">
<class>Undeploy_Object</class>
<desc>Undeploy gNB</desc>
<yaml_path>ci-scripts/yaml_files/5g_sa_n310_gnb</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<d_retx_th>20,100,100,100</d_retx_th>
<u_retx_th>20,100,100,100</u_retx_th>
</testCase>
<testCase id="040001">
<class>Undeploy_Object</class>
<desc>Undeploy nr UE</desc>
<yaml_path>ci-scripts/yaml_files/5g_sa_n310_nrue</yaml_path>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
</testCase>
</testCaseList>
<!--
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The OpenAirInterface Software Alliance licenses this file to You under
the OAI Public License, Version 1.1 (the "License"); you may not use this file
except in compliance with the License.
You may obtain a copy of the License at
http://www.openairinterface.org/?page_id=698
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
For more information about the OpenAirInterface (OAI) Software Alliance:
contact@openairinterface.org
-->
<testCaseList>
<htmlTabRef>test-aw2s-cleanup</htmlTabRef>
<htmlTabName>CleanUp of test servers</htmlTabName>
<htmlTabIcon>trash</htmlTabIcon>
<TestCaseRequestedList>
111111
222222
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="111111">
<class>Clean_Test_Server_Images</class>
<desc>Clean Test Images on Test Server</desc>
<test_svr_id>0</test_svr_id>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<desc>Clean Test Images on Test Server</desc>
<test_svr_id>1</test_svr_id>
</testCase>
</testCaseList>
version: '3.8'
services:
oai-gnb:
image: oai-gnb:latest
privileged: true
network_mode: "host"
container_name: oai-gnb
environment:
TZ: Europe/Paris
USE_ADDITIONAL_OPTIONS: --sa --tune-offset 20000000 --log_config.global_log_options level,nocolor,time
volumes:
- ../../conf_files/gnb.sa.band78.106prb.n310.7ds2u.conf:/opt/oai-gnb/etc/gnb.conf
healthcheck:
test: /bin/bash -c "pgrep nr-softmodem"
interval: 10s
timeout: 5s
retries: 5
version: '3.8'
services:
oai-nr-ue:
image: oai-nr-ue:latest
privileged: true
network_mode: host
container_name: oai-nr-ue
#entrypoint: /bin/bash -c "sleep infinity"
environment:
TZ: Europe/Paris
USE_ADDITIONAL_OPTIONS: --usrp-args type=n3xx,name=ni-n3xx-31641B9,addr=192.168.20.2 -r 106 --numerology 1 --band 78 -C 3511200000 --sa --ue-fo-compensation --ue-rxgain 65 --tune-offset 20000000 --log_config.global_log_options level,nocolor,time --uicc0.imsi 208970000000111 --uicc0.nssai_sd 16777215
volumes:
- ../../conf_files/ue.sa.conf:/opt/oai-nr-ue/etc/nr-ue.conf
healthcheck:
test: /bin/bash -c "pgrep nr-uesoftmodem"
interval: 10s
timeout: 5s
retries: 5
...@@ -61,6 +61,14 @@ Note: The available resources, and their current usage, is indicated here: ...@@ -61,6 +61,14 @@ Note: The available resources, and their current usage, is indicated here:
[PDF version](testbenches_doc_resources/5g-aw2s-bench.pdf) | [LaTeX/TikZ version](testbenches_doc_resources/5g-aw2s-bench.tex) if you want to modify to reflect your setup [PDF version](testbenches_doc_resources/5g-aw2s-bench.pdf) | [LaTeX/TikZ version](testbenches_doc_resources/5g-aw2s-bench.tex) if you want to modify to reflect your setup
### 5G UE OTA Testbench
**Purpose**: Over-the-air 5G tests with OAI UE
![OAI UE Testbench](testbenches_doc_resources/5g-nrue-bench.png)
[PDF version](testbenches_doc_resources/5g-nrue-bench.pdf) | [LaTeX/TikZ version](testbenches_doc_resources/5g-nrue-bench.tex) if you want to modify to reflect your setup
### 4G Testbench(es) ### 4G Testbench(es)
**Purpose**: 4G/LTE testbenches **Purpose**: 4G/LTE testbenches
...@@ -121,6 +129,9 @@ Webhook ...@@ -121,6 +129,9 @@ Webhook
- [RAN-SA-B200-Module-SABOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-SA-B200-Module-SABOX-Container/) - [RAN-SA-B200-Module-SABOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-SA-B200-Module-SABOX-Container/)
- ofqot + B200, idefix + Quectel, nepes w/ sabox - ofqot + B200, idefix + Quectel, nepes w/ sabox
- basic SA test (20 MHz TDD), F1, reestablishment, ... - basic SA test (20 MHz TDD), F1, reestablishment, ...
- [RAN-SA-OAIUE-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-OAIUE-CN5G/)
- 5G-NR SA test setup: gNB on avra(RHEL9.2) + N310, OAIUE on caracal(RHEL9.1) + N310, OAI CN5G
- OpenShift cluster for CN deployment and container images for gNB and UE deployment
- [RAN-Ubuntu18-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu18-Image-Builder/) - [RAN-Ubuntu18-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu18-Image-Builder/)
- obelix: Ubuntu 20 image build using docker (Note: builds U20 images while pipeline is named U18!) - obelix: Ubuntu 20 image build using docker (Note: builds U20 images while pipeline is named U18!)
...@@ -134,9 +145,6 @@ Webhook ...@@ -134,9 +145,6 @@ Webhook
- [RAN-SA-Module-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-Module-CN5G/) - [RAN-SA-Module-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-Module-CN5G/)
- asterix + N310 (gNB), nrmodule2 + Quectel, porcepix w/ OAI 5GC - asterix + N310 (gNB), nrmodule2 + Quectel, porcepix w/ OAI 5GC
- NR 2x2 (standalone) - NR 2x2 (standalone)
- [RAN-SA-OAIUE-N310-X300-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-OAIUE-N310-X300-CN5G/)
- asterix + N310 (gNB), obelix + N310 or X300 (5G UE), porcepix w/ OAI 5GC
- OTA test with OAIUE using both N310 and X300
- [RAN-SA-AmariS-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-AmariS-CN5G/) - [RAN-SA-AmariS-CN5G](https://jenkins-oai.eurecom.fr/view/RAN/job/RAN-SA-AmariS-CN5G/)
- asterix + N310, amariue (1x UE), porcepix w/ OAI 5GC - asterix + N310, amariue (1x UE), porcepix w/ OAI 5GC
- Amarisoft UE simulator: expected to be increased to more UEs - Amarisoft UE simulator: expected to be increased to more UEs
......
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds, positioning, shapes.symbols}
\usepackage{helvet}
\renewcommand*{\rmdefault}{\sfdefault}
\begin{document}
\begin{tikzpicture}
[
font=\footnotesize,
faraday/.style={minimum size=3cm, draw, dashed},
duplexer/.style={draw,fill=white},
]
\node[label=above:avra] (avra)
{\includegraphics[width=1.2cm]{server}};
\node[right=0.5cm of avra, label=above:USRP N310] (n310gnb)
{\includegraphics[width=1.2cm]{n310}} edge (avra);
\node[right=.2cm of n310gnb, duplexer] (b78o) {n78} edge (n310gnb);
\node[right=0.5cm of b78o] (ant1)
{\includegraphics[width=0.3cm]{antenna}} edge (b78o);
\node[left=0.5cm of avra] (oc)
{\includegraphics[width=1.2cm]{openshift}} edge (avra);
\node[right=7cm of n310gnb, label=above:caracal] (caracal)
{\includegraphics[width=1.2cm]{server}};
\node[left=0.5cm of caracal, label=above:USRP N310] (n310ue)
{\includegraphics[width=1.2cm]{n310}} edge (caracal);
\node[left=.2cm of n310ue, duplexer] (b78a) {n78} edge (n310ue);
\node[left=0.5cm of b78a] (ant2)
{\includegraphics[width=0.3cm]{antenna}} edge (b78a);
\end{tikzpicture}
\end{document}
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