Commit ee99817d authored by Florian Kaltenberger's avatar Florian Kaltenberger

Merge branch 'ci-dev-nr-add-gnb-nr-ur-uspr-testing' into 'develop-nr'

CI: adding support for the N300 gNB + NR-UE testing

See merge request oai/openairinterface5g!586
parents d54ea501 e5bef5f9
#!/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
*/
// Abstraction function to send social media messages:
// like on Slack or Mattermost
def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) {
if (params.pipelineUsesSlack != null) {
if (params.pipelineUsesSlack) {
slackSend channel: pipeChannel, color: pipeColor, message: pipeMessage
}
}
}
// Location of the test XML file to be run
def testXMLFile = params.pythonTestXmlFile
def mainPythonAllXmlFiles = ""
def buildStageStatus = true
// Name of the phone resource
def ciUSRPsResource = params.USRPsResource
// Terminate Status
def termUE = 0
def termENB = 1
def termStatusArray = new Boolean[2]
termStatusArray[termUE] = false
termStatusArray[termENB] = false
// Global Parameters.
def eNB_Repository
def eNB_Branch
def eNB_CommitID
def eNB_AllowMergeRequestProcess = false
def eNB_TargetBranch
def PROJECT_NAME = "test-boris"
def GIT_COMMIT_AUTHORi
def GIT_COMMIT_EMAIL
def testStageName
// Reversing list because pop() will take the last (right-most) element
//def modeList = ['TesteNB', 'TestUE', 'TesteNB'].reverse()
// Global Parameters not to break the main.py command line and code.
def ADB_IPAddress = "none"
def ADB_Username = "none"
def ADB_Password = "none"
def EPC_IPAddress = "none"
def EPC_Username = "none"
def EPC_Password = "none"
pipeline {
agent {
label pythonExecutor
}
options {
disableConcurrentBuilds()
gitLabConnection('OAI GitLab')
ansiColor('xterm')
lock (ciUSRPsResource)
}
stages {
stage ('Retrieve latest from branch') {
steps {
script {
checkout([$class: 'GitSCM', branches: [[name: "${params.Branch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[url: 'https://gitlab.eurecom.fr/oai/openairinterface5g.git']]])
sh "git clean -x -d -ff"
sh "git log -n1"
}
}
}
stage ("print latest commit info") {
steps {
script {
echo "Building on: "
echo " Repository -- ${GIT_URL}"
echo " Branch -- ${GIT_BRANCH}"
echo " Commit -- ${GIT_COMMIT}"
}
}
}
stage ("Verify Parameters") {
steps {
script {
JOB_TIMESTAMP = sh returnStdout: true, script: 'date --utc --rfc-3339=seconds | sed -e "s#+00:00##"'
JOB_TIMESTAMP = JOB_TIMESTAMP.trim()
echo '\u2705 \u001B[32mVerify Parameters\u001B[0m'
def allParametersPresent = true
// It is already too late to check it
if (params.pythonExecutor != null) {
echo "eNB CI executor node : ${pythonExecutor}"
}
if (params.eNB_Repository == null) {
eNB_Repository = GIT_URL
} else {
eNB_Repository = params.eNB_Repository
}
echo "eNB_Repository = ${eNB_Repository}"
if (params.eNB_Branch== null) {
eNB_Branch = GIT_BRANCH
} else {
eNB_Branch = params.eNB_Branch
}
echo "eNB_Branch = ${eNB_Branch}"
if (params.eNB_CommitID == null) {
eNB_CommitID = GIT_COMMIT
} else {
eNB_CommitID = params.eNB_CommitID
}
echo "eNB_CommitID = ${eNB_CommitID}"
// If not present picking a default Stage Name
if (params.pipelineTestStageName == null) {
// picking default
testStageName = 'Template Test Stage'
} else {
testStageName = params.pipelineTestStageName
}
if (params.USRPsResource == null) {
allParametersPresent = false
}
if (params.eNB_IPAddress == null) {
allParametersPresent = false
}
if (params.UE_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB_Credentials == null) {
allParametersPresent = false
}
if (params.UE_Credentials == null) {
allParametersPresent = false
}
GIT_COMMIT_AUTHOR = sh (
script: 'git show -s --pretty=%an',
returnStdout: true
).trim()
echo "The author of the commit is: ${GIT_COMMIT_AUTHOR}"
GIT_COMMIT_EMAIL = sh (
script: 'git show -s --pretty=%ae',
returnStdout: true
).trim()
echo "The email of the author is: ${GIT_COMMIT_EMAIL}"
if (allParametersPresent) {
echo "All parameters are present"
} else {
echo "Some parameters are missing"
sh "./ci-scripts/fail.sh"
}
}
}
}
stage ("Build and Test") {
steps {
script {
dir ('ci-scripts') {
// If not present picking a default XML file
if (params.pythonTestXmlFile == null) {
// picking default
testXMLFile = 'xml_files/gnb_usrp_build.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.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password']
]) {
sh "python3 main.py --mode=InitiateHtml --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --ADBIPAddress=${ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} ${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} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --UEIPAddress=${params.eNB_IPAddress} --UEUserName=${eNB_Username} --UEPassword=${eNB_Password} --eNBBranch=${eNB_Branch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --UESourceCodePath=${params.eNB_SourceCodePath} --eNBRepository=${eNB_Repository} --eNBCommitID=${eNB_CommitID} --ADBIPAddress=${ADB_IPAddress} --EPCIPAddress=${EPC_IPAddress} --XMLTestFile=${xmlFile}"
} 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 ("Terminate") {
parallel {
stage('Terminate NR UE') {
steps {
echo '\u2705 \u001B[32mTerminate NR UE\u001B[0m'
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password']
]) {
sh "python3 ci-scripts/main.py --mode=TerminateOAIUE --UEIPAddress=${params.eNB_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password}"
}
}
post {
success {
script {
termStatusArray[termUE] = true
}
}
}
}
stage('Terminate NR eNB') {
steps {
echo '\u2705 \u001B[32mTerminate NR eNB\u001B[0m'
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
]) {
sh "python3 ci-scripts/main.py --mode=TerminateeNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
}
}
post {
success {
script {
termStatusArray[termENB] = true
}
}
}
}
}
}
stage('Log Collection') {
parallel {
stage('Log Collection (gNB and NR UE - Build)') {
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (gNB and NR UE - Build)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollectBuild --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
echo '\u2705 \u001B[32mLog Transfer (gNB and NR UE - Build)\u001B[0m'
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/build.log.zip ./build.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("build.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "build.log.${env.BUILD_ID}.zip"
}
}
}
}
stage('Log Collection (gNB - Run)') {
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (gNB - Run)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}"
echo '\u2705 \u001B[32mLog Transfer (gNB - Run)\u001B[0m'
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("enb.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "enb.log.${env.BUILD_ID}.zip"
}
if(fileExists("ci-scripts/test_results.html")) {
sh "mv ci-scripts/test_results.html test_results-${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 "test_results-${JOB_NAME}.html"
}
}
}
}
stage('Log Collection (NR UE - Run)') {
steps {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password']
]) {
echo '\u2705 \u001B[32mLog Collection (gNB - Run)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollectOAIUE --UEIPAddress=${params.eNB_IPAddress} --UEUserName=${eNB_Username} --UEPassword=${eNB_Password} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --UESourceCodePath=${params.eNB_SourceCodePath}"
echo '\u2705 \u001B[32mLog Transfer (gNB - Run)\u001B[0m'
sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/ue.log.zip ./ue.log.${env.BUILD_ID}.zip || true"
}
script {
if(fileExists("ue.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "ue.log.${env.BUILD_ID}.zip"
}
}
}
}
}
}
}
post {
always {
script {
if ("MERGE".equals(env.gitlabActionType)) {
echo "This is a MERGE event"
} else {
gitlabCommitStatus(name: "Test-gNB-nrUE") {
if ((currentBuild.result == null) || (currentBuild.result == 'SUCCESS')) {
echo "Setting the gitlab commit status to pass"
} else {
sh "./ci-scripts/fail.sh"
}
}
}
emailext attachmentsPattern: '*results*.html',
body: '''Hi,
Here are attached HTML report files for $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!
Regards,
OAI CI Team''',
replyTo: 'no-reply@openairinterface.org',
subject: '$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!',
to: GIT_COMMIT_EMAIL
}
}
success {
script {
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ")"
if ("MERGE".equals(env.gitlabActionType)) {
echo "This is a MERGE event"
//addGitLabMRComment comment: message
def message2 = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): passed (" + BUILD_URL + ") -- MergeRequest #" + env.gitlabMergeRequestIid + " (" + env.gitlabMergeRequestTitle + ")"
sendSocialMediaMessage('ci-test', 'good', message2)
} else {
sendSocialMediaMessage('ci-test', 'good', message)
}
}
}
failure {
script {
def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): failed (" + BUILD_URL + ")"
if ("MERGE".equals(env.gitlabActionType)) {
echo "This is a MERGE event"
//addGitLabMRComment comment: message
def message2 = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): failed (" + BUILD_URL + ") -- MergeRequest #" + env.gitlabMergeRequestIid + " (" + env.gitlabMergeRequestTitle + ")"
sendSocialMediaMessage('ci-test', 'danger', message2)
} else {
sendSocialMediaMessage('ci-test', 'danger', message)
}
}
}
}
}
Active_gNBs = ( "gNB-Eurecom-5GNRBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
gNBs =
(
{
////////// Identification parameters:
gNB_ID = 0xe00;
cell_type = "CELL_MACRO_GNB";
gNB_name = "gNB-Eurecom-5GNRBox";
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
tr_s_preference = "local_mac"
////////// Physical parameters:
component_carriers = (
{
node_function = "3GPP_gNODEB";
node_timing = "synch_to_ext_device";
node_synch_ref = 0;
frame_type = "TDD";
DL_prefix_type = "NORMAL";
UL_prefix_type = "NORMAL";
eutra_band = 78;
downlink_frequency = 3510000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 106;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
MIB_subCarrierSpacingCommon = 30;
MIB_ssb_SubcarrierOffset = 0;
MIB_dmrs_TypeA_Position = 2;
pdcch_ConfigSIB1 = 0;
SIB1_frequencyOffsetSSB = "khz5";
SIB1_ssb_PeriodicityServingCell = 5;
SIB1_ss_PBCH_BlockPower = -60;
absoluteFrequencySSB = 0;
DL_FreqBandIndicatorNR = 15;
DL_absoluteFrequencyPointA = 15;
DL_offsetToCarrier = 15;
DL_SCS_SubcarrierSpacing = "kHz30";
DL_SCS_SpecificCarrier_k0 = 0;
DL_carrierBandwidth = 15;
DL_locationAndBandwidth = 15;
DL_BWP_SubcarrierSpacing = "kHz30";
DL_BWP_prefix_type = "NORMAL";
UL_FreqBandIndicatorNR = 15;
UL_absoluteFrequencyPointA = 13;
UL_additionalSpectrumEmission = 3;
UL_p_Max = -1;
UL_frequencyShift7p5khz = "TRUE";
UL_offsetToCarrier = 10;
UL_SCS_SubcarrierSpacing = "kHz30";
UL_SCS_SpecificCarrier_k0 = 0;
UL_carrierBandwidth = 15;
UL_locationAndBandwidth = 15;
UL_BWP_SubcarrierSpacing = "kHz30";
UL_BWP_prefix_type = "NORMAL";
UL_timeAlignmentTimerCommon = "infinity";
ServingCellConfigCommon_n_TimingAdvanceOffset = "n0"
ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01;
ServingCellConfigCommon_ssb_periodicityServingCell = 10;
ServingCellConfigCommon_dmrs_TypeA_Position = 2;
NIA_SubcarrierSpacing = "kHz15";
ServingCellConfigCommon_ss_PBCH_BlockPower = -60;
referenceSubcarrierSpacing = "kHz15";
dl_UL_TransmissionPeriodicity = "ms0p5";
nrofDownlinkSlots = 10;
nrofDownlinkSymbols = 10;
nrofUplinkSlots = 10;
nrofUplinkSymbols = 10;
rach_totalNumberOfRA_Preambles = 63;
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_choice = "oneEighth";
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneEighth = 4;
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneFourth = 8;
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneHalf = 16;
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_one = 24;
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_two = 32;
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_four = 8;
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_eight = 4;
rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_sixteen = 2;
rach_groupBconfigured = "ENABLE";
rach_ra_Msg3SizeGroupA = 56;
rach_messagePowerOffsetGroupB = "dB0";
rach_numberOfRA_PreamblesGroupA = 32;
rach_ra_ContentionResolutionTimer = 8;
rsrp_ThresholdSSB = 64;
rsrp_ThresholdSSB_SUL = 64;
prach_RootSequenceIndex_choice = "l839";
prach_RootSequenceIndex_l839 = 0;
prach_RootSequenceIndex_l139 = 0;
prach_msg1_SubcarrierSpacing = "kHz30";
restrictedSetConfig = "unrestrictedSet";
msg3_transformPrecoding = "ENABLE";
prach_ConfigurationIndex = 10;
prach_msg1_FDM = "one";
prach_msg1_FrequencyStart = 10;
zeroCorrelationZoneConfig = 10;
preambleReceivedTargetPower = -150;
preambleTransMax = 6;
powerRampingStep = "dB0";
ra_ResponseWindow = 8;
groupHoppingEnabledTransformPrecoding = "ENABLE";
msg3_DeltaPreamble = 0;
p0_NominalWithGrant = 0;
PUSCH_TimeDomainResourceAllocation_k2 = 0;
PUSCH_TimeDomainResourceAllocation_mappingType = "typeA";
PUSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0;
pucch_ResourceCommon = 0;
pucch_GroupHopping = "neither";
hoppingId = 0;
p0_nominal = -30;
PDSCH_TimeDomainResourceAllocation_k0 = 2;
PDSCH_TimeDomainResourceAllocation_mappingType = "typeA";
PDSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0;
rateMatchPatternId = 0;
RateMatchPattern_patternType = "bitmaps";
symbolsInResourceBlock = "oneSlot";
periodicityAndPattern = 2;
RateMatchPattern_controlResourceSet = 5;
RateMatchPattern_subcarrierSpacing = "kHz30";
RateMatchPattern_mode = "dynamic";
controlResourceSetZero = 0;
searchSpaceZero = 0;
searchSpaceSIB1 = 10;
searchSpaceOtherSystemInformation = 10;
pagingSearchSpace = 10;
ra_SearchSpace = 10;
PDCCH_common_controlResourceSetId = 5;
PDCCH_common_ControlResourceSet_duration = 2;
PDCCH_cce_REG_MappingType = "nonInterleaved";
PDCCH_reg_BundleSize = 3;
PDCCH_interleaverSize = 3;
PDCCH_shiftIndex = 10;
PDCCH_precoderGranularity = "sameAsREG-bundle";
PDCCH_TCI_StateId = 32;
tci_PresentInDCI = "ENABLE";
PDCCH_DMRS_ScramblingID = 0;
SearchSpaceId = 10;
commonSearchSpaces_controlResourceSetId = 5;
SearchSpace_monitoringSlotPeriodicityAndOffset_choice = "sl1";
SearchSpace_monitoringSlotPeriodicityAndOffset_value = 0;
SearchSpace_duration = 2;
SearchSpace_nrofCandidates_aggregationLevel1 = 0;
SearchSpace_nrofCandidates_aggregationLevel2 = 0;
SearchSpace_nrofCandidates_aggregationLevel4 = 0;
SearchSpace_nrofCandidates_aggregationLevel8 = 0;
SearchSpace_nrofCandidates_aggregationLevel16 = 0;
SearchSpace_searchSpaceType = "common";
Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel1 = 1;
Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel2 = 1;
Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel4 = 1;
Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel8 = 1;
Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel16 = 1;
Common_dci_Format2_3_monitoringPeriodicity = 1;
Common_dci_Format2_3_nrofPDCCH_Candidates = 1;
ue_Specific__dci_Formats = "formats0-0-And-1-0";
RateMatchPatternLTE_CRS_carrierFreqDL = 6;
RateMatchPatternLTE_CRS_carrierBandwidthDL = 6;
RateMatchPatternLTE_CRS_nrofCRS_Ports = 1;
RateMatchPatternLTE_CRS_v_Shift = 0;
RateMatchPatternLTE_CRS_radioframeAllocationPeriod = 1;
RateMatchPatternLTE_CRS_radioframeAllocationOffset = 0;
RateMatchPatternLTE_CRS_subframeAllocation_choice = "oneFrame";
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "192.168.12.26";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
GNB_INTERFACE_NAME_FOR_S1_MME = "eth0";
GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24";
GNB_INTERFACE_NAME_FOR_S1U = "eth0";
GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
att_rx = 0;
bands = [7];
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
sdr_addrs = "addr=192.168.20.2,second_addr=192.168.10.2,mgmt_addr=192.168.20.2,clock_source=external,time_source=external";
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
NETWORK_CONTROLLER :
{
FLEXRAN_ENABLED = "no";
FLEXRAN_INTERFACE_NAME = "lo";
FLEXRAN_IPV4_ADDRESS = "127.0.0.1";
FLEXRAN_PORT = 2210;
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
};
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
# dummy commit
#/* #/*
# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more # * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# * contributor license agreements. See the NOTICE file distributed with # * contributor license agreements. See the NOTICE file distributed with
...@@ -43,6 +44,9 @@ ENB_PROCESS_SEG_FAULT = -11 ...@@ -43,6 +44,9 @@ ENB_PROCESS_SEG_FAULT = -11
ENB_PROCESS_ASSERTION = -12 ENB_PROCESS_ASSERTION = -12
ENB_PROCESS_REALTIME_ISSUE = -13 ENB_PROCESS_REALTIME_ISSUE = -13
ENB_PROCESS_NOLOGFILE_TO_ANALYZE = -14 ENB_PROCESS_NOLOGFILE_TO_ANALYZE = -14
UE_PROCESS_NOLOGFILE_TO_ANALYZE = -20
UE_PROCESS_COULD_NOT_SYNC = -21
UE_PROCESS_ASSERTION = -22
HSS_PROCESS_FAILED = -2 HSS_PROCESS_FAILED = -2
HSS_PROCESS_OK = +2 HSS_PROCESS_OK = +2
MME_PROCESS_FAILED = -3 MME_PROCESS_FAILED = -3
...@@ -64,6 +68,7 @@ import xml.etree.ElementTree as ET ...@@ -64,6 +68,7 @@ import xml.etree.ElementTree as ET
import logging import logging
import datetime import datetime
import signal import signal
#import platform
from multiprocessing import Process, Lock, SimpleQueue from multiprocessing import Process, Lock, SimpleQueue
logging.basicConfig( logging.basicConfig(
level=logging.DEBUG, level=logging.DEBUG,
...@@ -98,8 +103,11 @@ class SSHConnection(): ...@@ -98,8 +103,11 @@ class SSHConnection():
self.desc = '' self.desc = ''
self.Build_eNB_args = '' self.Build_eNB_args = ''
self.Initialize_eNB_args = '' self.Initialize_eNB_args = ''
self.air_interface = 'lte'
self.eNBLogFile = '' self.eNBLogFile = ''
self.eNB_instance = '' self.eNB_instance = ''
self.eNBOptions = ''
self.rruOptions = ''
self.ping_args = '' self.ping_args = ''
self.ping_packetloss_threshold = '' self.ping_packetloss_threshold = ''
self.iperf_args = '' self.iperf_args = ''
...@@ -120,13 +128,25 @@ class SSHConnection(): ...@@ -120,13 +128,25 @@ class SSHConnection():
self.htmlTabNames = [] self.htmlTabNames = []
self.htmlTabIcons = [] self.htmlTabIcons = []
self.finalStatus = False self.finalStatus = False
self.OsVersion = ''
self.KernelVersion = ''
self.UhdVersion = ''
self.UsrpBoard = ''
self.CpuNb = ''
self.CpuModel = ''
self.CpuMHz = ''
self.UEIPAddress = ''
self.UEUserName = ''
self.UEPassword = ''
self.UE_instance = ''
self.UELogFile = ''
self.UESourceCodePath = ''
self.Build_OAI_UE_args = ''
self.Initialize_OAI_UE_args = ''
self.Initialize_OAI_eNB_args = ''
self.clean_repository = True
self.eNBOsVersion = '' self.eNBOsVersion = ''
self.eNBKernelVersion = ''
self.eNBUhdVersion = ''
self.eNBCpuNb = ''
self.eNBCpuModel = ''
self.eNBCpuMHz = ''
def open(self, ipaddress, username, password): def open(self, ipaddress, username, password):
count = 0 count = 0
connect_status = False connect_status = False
...@@ -321,11 +341,48 @@ class SSHConnection(): ...@@ -321,11 +341,48 @@ class SSHConnection():
self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5)
self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5)
self.command('mv compile_oai_enb.log ' + 'build_log_' + self.testCase_id, '\$', 5) self.command('mv compile_oai_enb.log ' + 'build_log_' + self.testCase_id, '\$', 5)
# Workaround to run with develop-nr
self.command('if [ -e ran_build ]; then cp -rf ran_build lte_build_oai; fi', '\$', 30)
self.close() self.close()
self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK)
def BuildOAIUE(self):
if self.UEIPAddress == '' or self.eNBRepository == '' or self.eNBBranch == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '':
Usage()
sys.exit('Insufficient Parameter')
self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
self.command('mkdir -p ' + self.UESourceCodePath, '\$', 5)
self.command('cd ' + self.UESourceCodePath, '\$', 5)
self.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + self.eNBRepository + ' .; else stdbuf -o0 git fetch; fi', '\$', 600)
# here add a check if git clone or git fetch went smoothly
self.command('git config user.email "jenkins@openairinterface.org"', '\$', 5)
self.command('git config user.name "OAI Jenkins"', '\$', 5)
if self.clean_repository:
pass
self.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30)
# if the commit ID is provided use it to point to it
if self.eNBCommitID != '':
self.command('git checkout -f ' + self.eNBCommitID, '\$', 5)
# if the branch is not develop, then it is a merge request and we need to do
# the potential merge. Note that merge conflicts should already been checked earlier
if (self.eNB_AllowMerge):
if self.eNBTargetBranch == '':
if (self.eNBBranch != 'develop') and (self.eNBBranch != 'origin/develop'):
self.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5)
else:
logging.debug('Merging with the target branch: ' + self.eNBTargetBranch)
self.command('git merge --ff origin/' + self.eNBTargetBranch + ' -m "Temporary merge for CI"', '\$', 5)
self.command('source oaienv', '\$', 5)
self.command('cd cmake_targets', '\$', 5)
self.command('mkdir -p log', '\$', 5)
self.command('chmod 777 log', '\$', 5)
# no need to remove in log (git clean did the trick)
self.command('stdbuf -o0 ./build_oai ' + self.Build_OAI_UE_args + ' 2>&1 | stdbuf -o0 tee -a compile_oai_ue.log', 'Bypassing the Tests', 600)
self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5)
self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5)
self.command('mv compile_oai_ue.log ' + 'build_log_' + self.testCase_id, '\$', 5)
self.close()
self.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE')
def InitializeHSS(self): def InitializeHSS(self):
if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '': if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '':
Usage() Usage()
...@@ -411,6 +468,7 @@ class SSHConnection(): ...@@ -411,6 +468,7 @@ class SSHConnection():
self.command('cd ' + self.eNBSourceCodePath, '\$', 5) self.command('cd ' + self.eNBSourceCodePath, '\$', 5)
# Initialize_eNB_args usually start with -O and followed by the location in repository # Initialize_eNB_args usually start with -O and followed by the location in repository
full_config_file = self.Initialize_eNB_args.replace('-O ','') full_config_file = self.Initialize_eNB_args.replace('-O ','')
extra_options = ''
extIdx = full_config_file.find('.conf') extIdx = full_config_file.find('.conf')
if (extIdx > 0): if (extIdx > 0):
extra_options = full_config_file[extIdx + 5:] extra_options = full_config_file[extIdx + 5:]
...@@ -431,6 +489,16 @@ class SSHConnection(): ...@@ -431,6 +489,16 @@ class SSHConnection():
result = re.search('rru', str(config_file)) result = re.search('rru', str(config_file))
if result is not None: if result is not None:
rruCheck = True rruCheck = True
# do not reset board twice in IF4.5 case
result = re.search('rru|enb', str(config_file))
if result is not None:
self.command('echo ' + self.eNBPassword + ' | sudo -S uhd_find_devices', '\$', 30)
result = re.search('type: b200', str(self.ssh.before))
if result is not None:
logging.debug('Found a B2xx device --> resetting it')
self.command('echo ' + self.eNBPassword + ' | sudo -S sudo b2xx_fx3_utils --reset-device', '\$', 5)
# Reloading FGPA bin firmware
self.command('echo ' + self.eNBPassword + ' | sudo -S uhd_find_devices', '\$', 30)
# Make a copy and adapt to EPC / eNB IP addresses # Make a copy and adapt to EPC / eNB IP addresses
self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5)
self.command('sed -i -e \'s/CI_MME_IP_ADDR/' + self.EPCIPAddress + '/\' ' + ci_full_config_file, '\$', 2); self.command('sed -i -e \'s/CI_MME_IP_ADDR/' + self.EPCIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
...@@ -438,12 +506,20 @@ class SSHConnection(): ...@@ -438,12 +506,20 @@ class SSHConnection():
# Launch eNB with the modified config file # Launch eNB with the modified config file
self.command('source oaienv', '\$', 5) self.command('source oaienv', '\$', 5)
self.command('cd cmake_targets', '\$', 5) self.command('cd cmake_targets', '\$', 5)
self.command('echo "ulimit -c unlimited && ./lte_build_oai/build/lte-softmodem -O ' + self.eNBSourceCodePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh ', '\$', 5) self.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface + '-softmodem -O ' + self.eNBSourceCodePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh ', '\$', 5)
self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh ', '\$', 5) self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh ', '\$', 5)
self.command('echo ' + self.eNBPassword + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5)
self.command('echo ' + self.eNBPassword + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + self.eNBSourceCodePath + '/cmake_targets -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) #to use daemon on CentOS we need to source the function
#linux_distro = platform.linux_distribution()[0]
#if re.match('(.*)CentOS(.*)', linux_distro, re.IGNORECASE):
#self.command('source /etc/init.d/functions', '\$', 5)
#use nohup instead of daemon
#self.command('echo ' + self.eNBPassword + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + self.eNBSourceCodePath + '/cmake_targets -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
self.command('echo $USER; nohup sudo ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh' + ' > ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '.log' + ' 2>&1 &', self.eNBUserName, 5)
if not rruCheck: if not rruCheck:
self.eNBLogFile = 'enb_' + self.testCase_id + '.log' self.eNBLogFile = 'enb_' + self.testCase_id + '.log'
if extra_options != '':
self.eNBOptions = extra_options
time.sleep(6) time.sleep(6)
doLoop = True doLoop = True
loopCounter = 10 loopCounter = 10
...@@ -482,6 +558,8 @@ class SSHConnection(): ...@@ -482,6 +558,8 @@ class SSHConnection():
time.sleep(6) time.sleep(6)
else: else:
doLoop = False doLoop = False
if rruCheck and extra_options != '':
self.rruOptions = extra_options
self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK) self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK)
logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m') logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m')
...@@ -517,6 +595,165 @@ class SSHConnection(): ...@@ -517,6 +595,165 @@ class SSHConnection():
job.join() job.join()
self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
def InitializeOAIUE(self):
if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '':
Usage()
sys.exit('Insufficient Parameter')
#initialize_OAI_UE_flag = True
#pStatus = self.CheckOAIUEProcessExist(initialize_OAI_UE_flag)
#if (pStatus < 0):
# self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', pStatus)
# self.CreateHtmlTabFooter(False)
# sys.exit(1)
self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
# b2xx_fx3_utils reset procedure
self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 30)
result = re.search('type: n3xx', str(self.ssh.before))
if result is not None:
pass
logging.debug('Found a B2xx device --> resetting it')
self.command('echo ' + self.UEPassword + ' | sudo -S sudo b2xx_fx3_utils --reset-device', '\$', 5)
# Reloading FGPA bin firmware
self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 30)
else:
logging.debug('Did not find any B2xx device')
self.command('cd ' + self.UESourceCodePath, '\$', 5)
# Initialize_OAI_UE_args usually start with -C and followed by the location in repository
self.command('source oaienv', '\$', 5)
self.command('cd cmake_targets/ran_build/build', '\$', 5)
self.command('echo "ulimit -c unlimited && ./'+ self.air_interface +'-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
self.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5)
#to use daemon on CentOS we need to source the function
#linux_distro = platform.linux_distribution()[0]
#if re.match('(.*)CentOS(.*)', linux_distro, re.IGNORECASE):
#self.command('source /etc/init.d/functions', '\$', 5)
#use nohup instead of daemon
self.command('echo $USER; nohup sudo ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh' + ' > ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ' + ' 2>&1 &', self.UEUserName, 5)
#self.command('echo ' + self.UEPassword + ' | sudo -S -E daemon --inherit --unsafe --name=ue' + str(self.UE_instance) + '_daemon --chdir=' + self.UESourceCodePath + '/cmake_targets/ran_build/build -o ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
self.UELogFile = 'ue_' + self.testCase_id + '.log'
time.sleep(6)
self.command('cd ../..', '\$', 5)
doLoop = True
loopCounter = 10
while (doLoop):
loopCounter = loopCounter - 1
if (loopCounter == 0):
self.close()
doLoop = False
logging.error('\u001B[1;37;41m UE logging system did not show got sync! \u001B[0m')
self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', ALL_PROCESSES_OK, 'OAI UE')
self.CreateHtmlTabFooter(False)
sys.exit(1)
else:
self.command('stdbuf -o0 cat ' + self.UELogFile + ' | egrep --text --color=never -i "wait|sync"', '\$', 4)
if self.air_interface == 'nr':
result = re.search('Starting sync detection', str(self.ssh.before))
else:
result = re.search('got sync', str(self.ssh.before))
if result is None:
time.sleep(10)
else:
doLoop = False
self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE')
logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m')
self.close()
def InitializeOAIeNB(self):
if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.eNBSourceCodePath == '':
Usage()
sys.exit('Insufficient Parameter')
#initialize_OAI_eNB_flag = True
#pStatus = self.CheckOAIeNBProcessExist(initialize_OAI_eNB_flag)
#if (pStatus < 0):
# self.CreateHtmlTestRow(self.Initialize_OAI_eNB_args, 'KO', pStatus)
# self.CreateHtmlTabFooter(False)
# sys.exit(1)
self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
self.command('cd ' + self.eNBSourceCodePath, '\$', 5)
# Initialize_OAI_eNB_args usually start with -C and followed by the location in repository
#full_config_file = self.Initialize_OAI_eNB_args.replace('-O ','')
#extIdx = full_config_file.find('.conf')
#if (extIdx > 0):
# extra_options = full_config_file[extIdx + 5:]
# # if tracer options is on, compiling and running T Tracer
# result = re.search('T_stdout', str(extra_options))
## if result is not None:
# logging.debug('\u001B[1m Compiling and launching T Tracer\u001B[0m')
# self.command('cd common/utils/T/tracer', '\$', 5)
# self.command('make', '\$', 10)
# self.command('echo $USER; nohup ./record -d ../T_messages.txt -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '_record.log 2>&1 &', self.eNBUserName, 5)
# self.command('cd ' + self.eNBSourceCodePath, '\$', 5)
# full_config_file = full_config_file[:extIdx + 5]
# config_path, config_file = os.path.split(full_config_file)
#ci_full_config_file = config_path + '/ci-' + config_file
#rruCheck = False
#result = re.search('rru', str(config_file))
#if result is not None:
# rruCheck = True
## Make a copy and adapt to EPC / eNB IP addresses
#self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5)
#self.command('sed -i -e \'s/CI_eNB_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
# Launch eNB with the modified config file
self.command('source oaienv', '\$', 5)
self.command('cd cmake_targets/ran_build/build', '\$', 5)
#self.command('echo "ulimit -c unlimited && ./' + self.air_interface + '-softmodem ' + self.Initialize_OAI_eNB_args + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
self.eNBLogFile = 'enb_' + self.testCase_id + '.log'
self.command('echo "ulimit -c unlimited && ./' + self.air_interface + '-softmodem ' + self.Initialize_OAI_eNB_args + '|& tee ' + self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFile + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
self.command('echo ' + self.eNBPassword + ' | sudo -S rm -Rf ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '.log', '\$', 5)
#to use daemon on CentOS we need to source the function
#linux_distro = platform.linux_distribution()[0]
#if re.match('(.*)CentOS(.*)', linux_distro, re.IGNORECASE):
#self.command('source /etc/init.d/functions', '\$', 5)
#use nohup instead of daemon
self.command('echo $USER; nohup sudo ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh' + ' > ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '.log' + ' 2>&1 &', self.eNBUserName, 5)
#self.command('echo ' + self.eNBPassword + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + self.eNBSourceCodePath + '/cmake_targets/ran_build/build -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
time.sleep(6)
self.command('cd ../..', '\$', 5)
doLoop = True
loopCounter = 10
print('gNB log file: ' + self.eNBLogFile)
while (doLoop):
loopCounter = loopCounter - 1
if (loopCounter == 0):
# In case of T tracer recording, we may need to kill it
#result = re.search('T_stdout', str(self.Initialize_OAI_eNB_args))
#if result is not None:
# self.command('killall --signal SIGKILL record', '\$', 5)
self.close()
doLoop = False
logging.error('\u001B[1;37;41m eNB logging system did not show got sync! \u001B[0m')
self.CreateHtmlTestRow(self.Initialize_OAI_eNB_args, 'KO', ALL_PROCESSES_OK, 'OAI eNB')
self.CreateHtmlTabFooter(False)
## In case of T tracer recording, we need to kill tshark on EPC side
#result = re.search('T_stdout', str(self.Initialize_OAI_eNB_args))
#if result is not None:
# self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
# logging.debug('\u001B[1m Stopping tshark \u001B[0m')
# self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
# self.close()
# time.sleep(1)
# pcap_log_file = 'enb_' + self.testCase_id + '_s1log.pcap'
# copyin_res = self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + pcap_log_file, '.')
# if (copyin_res == 0):
# self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, pcap_log_file, self.eNBSourceCodePath + '/cmake_targets/.')
sys.exit(1)
else:
#print('current directory: ' + os.getcwd())
#self.command('pwd', '\$', 4)
#print('self.command pwd: ' + str(self.ssh.before))
self.command('stdbuf -o0 cat ' + self.eNBLogFile + ' | egrep --text --color=never -i "wait|sync"', '\$', 30)
#print(self.ssh.before)
result = re.search('got sync', str(self.ssh.before))
if result is None:
time.sleep(11)
else:
doLoop = False
self.CreateHtmlTestRow(self.Initialize_OAI_eNB_args, 'OK', ALL_PROCESSES_OK, 'OAI eNB')
logging.debug('\u001B[1m Initialize OAI eNB Completed\u001B[0m')
self.close()
def checkDevTTYisUnlocked(self): def checkDevTTYisUnlocked(self):
self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
count = 0 count = 0
...@@ -604,21 +841,150 @@ class SSHConnection(): ...@@ -604,21 +841,150 @@ class SSHConnection():
time.sleep(4) time.sleep(4)
# We should check if we register # We should check if we register
count = 0 count = 0
while count < 3: attach_cnt = 0
attach_status = False
while count < 5:
self.command('AT+CEREG?', 'OK', 5) self.command('AT+CEREG?', 'OK', 5)
result = re.search('CEREG: 2,(?P<state>[0-9\-]+)', str(self.ssh.before)) result = re.search('CEREG: 2,(?P<state>[0-9\-]+),', str(self.ssh.before))
if result is not None: if result is not None:
mDataConnectionState = int(result.group('state')) mDataConnectionState = int(result.group('state'))
if mDataConnectionState is not None: if mDataConnectionState is not None:
logging.debug('+CEREG: 2,' + str(mDataConnectionState)) if mDataConnectionState == 1:
count = 10
attach_status = True
result = re.search('CEREG: 2,1,"(?P<networky>[0-9A-Z]+)","(?P<networkz>[0-9A-Z]+)"', str(self.ssh.before))
if result is not None:
networky = result.group('networky')
networkz = result.group('networkz')
logging.debug('\u001B[1m CAT-M module attached to eNB (' + str(networky) + '/' + str(networkz) + ')\u001B[0m')
else:
logging.debug('\u001B[1m CAT-M module attached to eNB\u001B[0m')
else:
logging.debug('+CEREG: 2,' + str(mDataConnectionState))
attach_cnt = attach_cnt + 1
else: else:
logging.debug(str(self.ssh.before)) logging.debug(str(self.ssh.before))
attach_cnt = attach_cnt + 1
count = count + 1 count = count + 1
time.sleep(1) time.sleep(1)
if attach_status:
self.command('AT+CESQ', 'OK', 5)
result = re.search('CESQ: 99,99,255,255,(?P<rsrq>[0-9]+),(?P<rsrp>[0-9]+)', str(self.ssh.before))
if result is not None:
nRSRQ = int(result.group('rsrq'))
nRSRP = int(result.group('rsrp'))
if (nRSRQ is not None) and (nRSRP is not None):
logging.debug(' RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB')
logging.debug(' RSRP = ' + str(-140+nRSRP) + ' dBm')
self.close() self.close()
self.picocom_closure = False self.picocom_closure = False
self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) html_queue = SimpleQueue()
self.checkDevTTYisUnlocked() self.checkDevTTYisUnlocked()
if attach_status:
html_cell = '<pre style="background-color:white">CAT-M module\nAttachment Completed in ' + str(attach_cnt+4) + ' seconds'
if (nRSRQ is not None) and (nRSRP is not None):
html_cell += '\n RSRQ = ' + str(-20+(nRSRQ/2)) + ' dB'
html_cell += '\n RSRP = ' + str(-140+nRSRP) + ' dBm</pre>'
else:
html_cell += '</pre>'
html_queue.put(html_cell)
self.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue)
else:
html_cell = '<pre style="background-color:white">CAT-M module\nAttachment Failed</pre>'
html_queue.put(html_cell)
self.CreateHtmlTestRowQueue('N/A', 'KO', 1, html_queue)
def PingCatM(self):
if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '':
Usage()
sys.exit('Insufficient Parameter')
initialize_eNB_flag = False
pStatus = self.CheckProcessExist(initialize_eNB_flag)
if (pStatus < 0):
self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.CreateHtmlTabFooter(False)
sys.exit(1)
try:
statusQueue = SimpleQueue()
lock = Lock()
self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
self.command('cd ' + self.EPCSourceCodePath, '\$', 5)
self.command('cd scripts', '\$', 5)
if re.match('OAI', self.EPCType, re.IGNORECASE):
logging.debug('Using the OAI EPC HSS: not implemented yet')
self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus)
self.CreateHtmlTabFooter(False)
sys.exit(1)
else:
self.command('egrep --color=never "Allocated ipv4 addr" /opt/ltebox/var/log/xGwLog.0', '\$', 5)
result = re.search('Allocated ipv4 addr: (?P<ipaddr>[0-9\.]+) from Pool', str(self.ssh.before))
if result is not None:
moduleIPAddr = result.group('ipaddr')
else:
return
ping_time = re.findall("-c (\d+)",str(self.ping_args))
device_id = 'catm'
ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + str(moduleIPAddr) + ' 2>&1 | stdbuf -o0 tee -a ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5)
# TIMEOUT CASE
if ping_status < 0:
message = 'Ping with UE (' + str(moduleIPAddr) + ') crashed due to TIMEOUT!'
logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message)
return
result = re.search(', (?P<packetloss>[0-9\.]+)% packet loss, time [0-9\.]+ms', str(self.ssh.before))
if result is None:
message = 'Packet Loss Not Found!'
logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message)
return
packetloss = result.group('packetloss')
if float(packetloss) == 100:
message = 'Packet Loss is 100%'
logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message)
return
result = re.search('rtt min\/avg\/max\/mdev = (?P<rtt_min>[0-9\.]+)\/(?P<rtt_avg>[0-9\.]+)\/(?P<rtt_max>[0-9\.]+)\/[0-9\.]+ ms', str(self.ssh.before))
if result is None:
message = 'Ping RTT_Min RTT_Avg RTT_Max Not Found!'
logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
self.ping_iperf_wrong_exit(lock, moduleIPAddr, device_id, statusQueue, message)
return
rtt_min = result.group('rtt_min')
rtt_avg = result.group('rtt_avg')
rtt_max = result.group('rtt_max')
pal_msg = 'Packet Loss : ' + packetloss + '%'
min_msg = 'RTT(Min) : ' + rtt_min + ' ms'
avg_msg = 'RTT(Avg) : ' + rtt_avg + ' ms'
max_msg = 'RTT(Max) : ' + rtt_max + ' ms'
lock.acquire()
logging.debug('\u001B[1;37;44m ping result (' + moduleIPAddr + ') \u001B[0m')
logging.debug('\u001B[1;34m ' + pal_msg + '\u001B[0m')
logging.debug('\u001B[1;34m ' + min_msg + '\u001B[0m')
logging.debug('\u001B[1;34m ' + avg_msg + '\u001B[0m')
logging.debug('\u001B[1;34m ' + max_msg + '\u001B[0m')
qMsg = pal_msg + '\n' + min_msg + '\n' + avg_msg + '\n' + max_msg
packetLossOK = True
if packetloss is not None:
if float(packetloss) > float(self.ping_packetloss_threshold):
qMsg += '\nPacket Loss too high'
logging.debug('\u001B[1;37;41m Packet Loss too high \u001B[0m')
packetLossOK = False
elif float(packetloss) > 0:
qMsg += '\nPacket Loss is not 0%'
logging.debug('\u001B[1;30;43m Packet Loss is not 0% \u001B[0m')
lock.release()
self.close()
html_cell = '<pre style="background-color:white">CAT-M module\nIP Address : ' + moduleIPAddr + '\n' + qMsg + '</pre>'
statusQueue.put(html_cell)
if (packetLossOK):
self.CreateHtmlTestRowQueue(self.ping_args, 'OK', 1, statusQueue)
else:
self.CreateHtmlTestRowQueue(self.ping_args, 'KO', 1, statusQueue)
self.AutoTerminateUEandeNB()
self.CreateHtmlTabFooter(False)
sys.exit(1)
except:
os.kill(os.getppid(),signal.SIGUSR1)
def AttachUE_common(self, device_id, statusQueue, lock): def AttachUE_common(self, device_id, statusQueue, lock):
try: try:
...@@ -1527,11 +1893,53 @@ class SSHConnection(): ...@@ -1527,11 +1893,53 @@ class SSHConnection():
result = logStatus result = logStatus
return result return result
def CheckOAIUEProcessExist(self, initialize_OAI_UE_flag):
multi_jobs = []
status_queue = SimpleQueue()
if initialize_OAI_UE_flag == False:
p = Process(target = SSH.CheckOAIUEProcess, args = (status_queue,))
p.daemon = True
p.start()
multi_jobs.append(p)
for job in multi_jobs:
job.join()
if (status_queue.empty()):
return -15
else:
result = 0
while (not status_queue.empty()):
status = status_queue.get()
if (status < 0):
result = status
if result == OAI_UE_PROCESS_FAILED:
fileCheck = re.search('enb_', str(self.UELogFile))
if fileCheck is not None:
self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.')
logStatus = self.AnalyzeLogFile_UE(self.UELogFile)
if logStatus < 0:
result = logStatus
return result
def CheckOAIUEProcess(self, status_queue):
try:
self.open(self.OAIUEIPAddress, self.OAIUEUserName, self.OAIUEPassword)
self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never ' + self.air_interface + '-uesoftmodem', '\$', 5)
result = re.search(self.air_interface + '-uesoftmodem', str(self.ssh.before))
if result is None:
logging.debug('\u001B[1;37;41m OAI UE Process Not Found! \u001B[0m')
status_queue.put(OAI_UE_PROCESS_FAILED)
else:
status_queue.put(OAI_UE_PROCESS_OK)
self.close()
except:
os.kill(os.getppid(),signal.SIGUSR1)
def CheckeNBProcess(self, status_queue): def CheckeNBProcess(self, status_queue):
try: try:
self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never lte-softmodem', '\$', 5) self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never ' + self.air_interface + '-softmodem', '\$', 5)
result = re.search('lte-softmodem', str(self.ssh.before)) result = re.search(self.air_interface + '-softmodem', str(self.ssh.before))
if result is None: if result is None:
logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m') logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m')
status_queue.put(ENB_PROCESS_FAILED) status_queue.put(ENB_PROCESS_FAILED)
...@@ -1615,7 +2023,18 @@ class SSHConnection(): ...@@ -1615,7 +2023,18 @@ class SSHConnection():
uciStatMsgCount = 0 uciStatMsgCount = 0
pdcpFailure = 0 pdcpFailure = 0
ulschFailure = 0 ulschFailure = 0
self.htmleNBFailureMsg = ''
for line in enb_log_file.readlines(): for line in enb_log_file.readlines():
if self.rruOptions != '':
res1 = re.search('max_rxgain (?P<requested_option>[0-9]+)', self.rruOptions)
res2 = re.search('max_rxgain (?P<applied_option>[0-9]+)', str(line))
if res1 is not None and res2 is not None:
requested_option = int(res1.group('requested_option'))
applied_option = int(res2.group('applied_option'))
if requested_option == applied_option:
self.htmleNBFailureMsg += '<span class="glyphicon glyphicon-ok-circle"></span> Command line option(s) correctly applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.rruOptions + '\n\n'
else:
self.htmleNBFailureMsg += '<span class="glyphicon glyphicon-ban-circle"></span> Command line option(s) NOT applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.rruOptions + '\n\n'
result = re.search('[Ss]egmentation [Ff]ault', str(line)) result = re.search('[Ss]egmentation [Ff]ault', str(line))
if result is not None: if result is not None:
foundSegFault = True foundSegFault = True
...@@ -1734,17 +2153,172 @@ class SSHConnection(): ...@@ -1734,17 +2153,172 @@ class SSHConnection():
return ENB_PROCESS_REALTIME_ISSUE return ENB_PROCESS_REALTIME_ISSUE
return 0 return 0
def AnalyzeLogFile_UE(self, UElogFile):
if (not os.path.isfile('./' + UElogFile)):
return -1
ue_log_file = open('./' + UElogFile, 'r')
foundAssertion = False
msgAssertion = ''
msgLine = 0
foundSegFault = False
foundRealTimeIssue = False
rlcDiscardBuffer = 0
rachCanceledProcedure = 0
uciStatMsgCount = 0
pdcpFailure = 0
ulschFailure = 0
no_cell_sync_found = False
mib_found = False
frequency_found = False
self.htmlUEFailureMsg = ''
for line in ue_log_file.readlines():
result = re.search('[Ss]egmentation [Ff]ault', str(line))
if result is not None:
foundSegFault = True
result = re.search('[Cc]ore [dD]ump', str(line))
if result is not None:
foundSegFault = True
result = re.search('[Aa]ssertion', str(line))
if result is not None:
foundAssertion = True
result = re.search('LLL', str(line))
if result is not None:
foundRealTimeIssue = True
if foundAssertion and (msgLine < 3):
msgLine += 1
msgAssertion += str(line)
result = re.search('uci->stat', str(line))
if result is not None:
uciStatMsgCount += 1
# No cell synchronization found, abandoning
result = re.search('No cell synchronization found, abandoning', str(line))
if result is not None:
no_cell_sync_found = True
result = re.search("MIB Information => ([a-zA-Z]{1,10}), ([a-zA-Z]{1,10}), NidCell (?P<nidcell>\d{1,3}), N_RB_DL (?P<n_rb_dl>\d{1,3}), PHICH DURATION (?P<phich_duration>\d), PHICH RESOURCE (?P<phich_resource>.{1,4}), TX_ANT (?P<tx_ant>\d)", str(line))
if result is not None and (not mib_found):
try:
mibMsg = "MIB Information: " + result.group(1) + ', ' + result.group(2)
self.htmlUEFailureMsg += mibMsg + '\n'
logging.debug('\033[94m' + mibMsg + '\033[0m')
mibMsg = " nidcell = " + result.group('nidcell')
self.htmlUEFailureMsg += mibMsg
logging.debug('\033[94m' + mibMsg + '\033[0m')
mibMsg = " n_rb_dl = " + result.group('n_rb_dl')
self.htmlUEFailureMsg += mibMsg + '\n'
logging.debug('\033[94m' + mibMsg + '\033[0m')
mibMsg = " phich_duration = " + result.group('phich_duration')
self.htmlUEFailureMsg += mibMsg
logging.debug('\033[94m' + mibMsg + '\033[0m')
mibMsg = " phich_resource = " + result.group('phich_resource')
self.htmlUEFailureMsg += mibMsg + '\n'
logging.debug('\033[94m' + mibMsg + '\033[0m')
mibMsg = " tx_ant = " + result.group('tx_ant')
self.htmlUEFailureMsg += mibMsg + '\n'
logging.debug('\033[94m' + mibMsg + '\033[0m')
mib_found = True
except Exception as e:
logging.error('\033[91m' + "MIB marker was not found" + '\033[0m')
result = re.search("Measured Carrier Frequency (?P<measured_carrier_frequency>\d{1,15}) Hz", str(line))
if result is not None and (not frequency_found):
try:
mibMsg = "Measured Carrier Frequency = " + result.group('measured_carrier_frequency') + ' Hz'
self.htmlUEFailureMsg += mibMsg + '\n'
logging.debug('\033[94m' + mibMsg + '\033[0m')
frequency_found = True
except Exception as e:
logging.error('\033[91m' + "Measured Carrier Frequency not found" + '\033[0m')
result = re.search("Found (?P<operator>[\w,\s]{1,15}) \(name from internal table\)", str(line))
if result is not None:
try:
mibMsg = "The operator is: " + result.group('operator')
self.htmlUEFailureMsg += mibMsg + '\n'
logging.debug('\033[94m' + mibMsg + '\033[0m')
except Exception as e:
logging.error('\033[91m' + "Operator name not found" + '\033[0m')
result = re.search("SIB5 InterFreqCarrierFreq element (.{1,4})/(.{1,4})", str(line))
if result is not None:
try:
mibMsg = "SIB5 InterFreqCarrierFreq element " + result.group(1) + '/' + result.group(2)
self.htmlUEFailureMsg += mibMsg + ' -> '
logging.debug('\033[94m' + mibMsg + '\033[0m')
except Exception as e:
logging.error('\033[91m' + "SIB5 InterFreqCarrierFreq element not found" + '\033[0m')
result = re.search("DL Carrier Frequency/ARFCN : (?P<carrier_frequency>\d{1,15}/\d{1,4})", str(line))
if result is not None:
try:
freq = result.group('carrier_frequency')
new_freq = re.sub('/[0-9]+','',freq)
float_freq = float(new_freq) / 1000000
self.htmlUEFailureMsg += 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz'
logging.debug('\033[94m' + " DL Carrier Frequency is: " + freq + '\033[0m')
except Exception as e:
logging.error('\033[91m' + " DL Carrier Frequency not found" + '\033[0m')
result = re.search("AllowedMeasBandwidth : (?P<allowed_bandwidth>\d{1,7})", str(line))
if result is not None:
try:
prb = result.group('allowed_bandwidth')
self.htmlUEFailureMsg += ' -- PRB: ' + prb + '\n'
logging.debug('\033[94m' + " AllowedMeasBandwidth: " + prb + '\033[0m')
except Exception as e:
logging.error('\033[91m' + " AllowedMeasBandwidth not found" + '\033[0m')
ue_log_file.close()
if uciStatMsgCount > 0:
statMsg = 'UE showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)'
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
self.htmlUEFailureMsg += statMsg + '\n'
if pdcpFailure > 0:
statMsg = 'UE showed ' + str(pdcpFailure) + ' "PDCP Out of Resources" message(s)'
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
self.htmlUEFailureMsg += statMsg + '\n'
if ulschFailure > 0:
statMsg = 'UE showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)'
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
self.htmlUEFailureMsg += statMsg + '\n'
if rachCanceledProcedure > 0:
rachMsg = 'UE cancelled ' + str(rachCanceledProcedure) + ' RA procedure(s)'
logging.debug('\u001B[1;30;43m ' + rachMsg + ' \u001B[0m')
self.htmlUEFailureMsg += rachMsg + '\n'
if foundSegFault:
logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m')
return ENB_PROCESS_SEG_FAULT
if foundAssertion:
logging.debug('\u001B[1;37;43m UE ended with an assertion! \u001B[0m')
# removed for esthetics
#self.htmlUEFailureMsg += msgAssertion
self.htmlUEFailureMsg += 'UE ended with an assertion!\n'
if not mib_found or not frequency_found:
return UE_PROCESS_ASSERTION
if foundRealTimeIssue:
logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m')
self.htmlUEFailureMsg += 'UE faced real time issues!\n'
#return ENB_PROCESS_REALTIME_ISSUE
if no_cell_sync_found and not mib_found:
logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m')
self.htmlUEFailureMsg += 'UE could not synchronize!\n'
return UE_PROCESS_COULD_NOT_SYNC
if rlcDiscardBuffer > 0:
rlcMsg = 'UE RLC discarded ' + str(rlcDiscardBuffer) + ' buffer(s)'
logging.debug('\u001B[1;37;41m ' + rlcMsg + ' \u001B[0m')
self.htmlUEFailureMsg += rlcMsg + '\n'
return ENB_PROCESS_REALTIME_ISSUE
return 0
def TerminateeNB(self): def TerminateeNB(self):
self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5) self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5)
#to use daemon on CentOS we need to source the function
#linux_distro = platform.linux_distribution()[0]
#if re.match('(.*)CentOS(.*)', linux_distro, re.IGNORECASE):
#self.command('source /etc/init.d/functions', '\$', 5)
#use nohup instead of daemon
self.command('echo ' + self.eNBPassword + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5)
self.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) self.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGINT lte-softmodem || true', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGINT -r .*-softmodem || true', '\$', 5)
time.sleep(5) time.sleep(5)
self.command('stdbuf -o0 ps -aux | grep -v grep | grep lte-softmodem', '\$', 5) self.command('stdbuf -o0 ps -aux | grep softmodem | grep -v grep', '\$', 5)
result = re.search('lte-softmodem', str(self.ssh.before)) result = re.search('-softmodem', str(self.ssh.before))
if result is not None: if result is not None:
self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGKILL -r .*-softmodem || true', '\$', 5)
time.sleep(5) time.sleep(5)
self.close() self.close()
# If tracer options is on, stopping tshark on EPC side # If tracer options is on, stopping tshark on EPC side
...@@ -1810,6 +2384,10 @@ class SSHConnection(): ...@@ -1810,6 +2384,10 @@ class SSHConnection():
self.command('cd ' + self.EPCSourceCodePath, '\$', 5) self.command('cd ' + self.EPCSourceCodePath, '\$', 5)
self.command('cd scripts', '\$', 5) self.command('cd scripts', '\$', 5)
self.command('rm -f ./kill_hss.sh', '\$', 5) self.command('rm -f ./kill_hss.sh', '\$', 5)
#to use daemon on CentOS we need to source the function
#linux_distro = platform.linux_distribution()[0]
#if re.match('(.*)CentOS(.*)', linux_distro, re.IGNORECASE):
#self.command('source /etc/init.d/functions', '\$', 5)
self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --name=simulated_hss --stop', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --name=simulated_hss --stop', '\$', 5)
time.sleep(1) time.sleep(1)
self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL hss_sim', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL hss_sim', '\$', 5)
...@@ -1874,6 +2452,50 @@ class SSHConnection(): ...@@ -1874,6 +2452,50 @@ class SSHConnection():
job.join() job.join()
self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
def TerminateOAIUE(self):
self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5)
#to use daemon on CentOS we need to source the function
#linux_distro = platform.linux_distribution()[0]
#if re.match('(.*)CentOS(.*)', linux_distro, re.IGNORECASE):
#self.command('source /etc/init.d/functions', '\$', 5)
#self.command('echo ' + self.UEPassword + ' | sudo -S daemon --name=ue' + str(self.UE_instance) + '_daemon --stop', '\$', 5)
self.command('rm -f my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5)
self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGINT -r .*-uesoftmodem || true', '\$', 5)
time.sleep(5)
self.command('stdbuf -o0 ps -aux | grep uesoftmodem | grep -v grep', '\$', 5)
result = re.search('-uesoftmodem', str(self.ssh.before))
if result is not None:
self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL -r .*-uesoftmodem || true', '\$', 5)
time.sleep(5)
self.close()
result = re.search('ue_', str(self.UELogFile))
if result is not None:
copyin_res = self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.')
if (copyin_res == -1):
logging.debug('\u001B[1;37;41m Could not copy UE logfile to analyze it! \u001B[0m')
optionsMsg = '<pre style="background-color:white">Could not copy UE logfile to analyze it!</pre>'
self.CreateHtmlTestRow(optionsMsg, 'KO', UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE')
self.UELogFile = ''
return
logging.debug('\u001B[1m Analyzing UE logfile \u001B[0m')
logStatus = self.AnalyzeLogFile_UE(self.UELogFile)
if (logStatus < 0):
optionsMsg = '<pre style="background-color:white"><b>Sniffing Unsuccessful</b>\n'
optionsMsg += self.htmlUEFailureMsg
optionsMsg += '</pre>'
self.CreateHtmlTestRow(optionsMsg, 'KO', logStatus, 'UE')
self.CreateHtmlTabFooter(False)
sys.exit(1)
else:
optionsMsg = '<pre style="background-color:white"><b>Sniffing Successful</b>\n'
optionsMsg += self.htmlUEFailureMsg
optionsMsg += '</pre>'
self.CreateHtmlTestRow(optionsMsg, 'OK', ALL_PROCESSES_OK)
self.UELogFile = ''
else:
self.CreateHtmlTestRow('<pre style="background-color:white">No Log File to analyze</pre>', 'OK', ALL_PROCESSES_OK)
def AutoTerminateUEandeNB(self): def AutoTerminateUEandeNB(self):
self.testCase_id = 'AUTO-KILL-UE' self.testCase_id = 'AUTO-KILL-UE'
self.desc = 'Automatic Termination of UE' self.desc = 'Automatic Termination of UE'
...@@ -1890,8 +2512,20 @@ class SSHConnection(): ...@@ -1890,8 +2512,20 @@ class SSHConnection():
self.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', ALL_PROCESSES_OK) self.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', ALL_PROCESSES_OK)
def LogCollectBuild(self): def LogCollectBuild(self):
self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) if (self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != ''):
self.command('cd ' + self.eNBSourceCodePath, '\$', 5) IPAddress = self.eNBIPAddress
UserName = self.eNBUserName
Password = self.eNBPassword
SourceCodePath = self.eNBSourceCodePath
elif (self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != ''):
IPAddress = self.UEIPAddress
UserName = self.UEUserName
Password = self.UEPassword
SourceCodePath = self.UESourceCodePath
else:
sys.exit('Insufficient Parameter')
self.open(IPAddress, UserName, Password)
self.command('cd ' + SourceCodePath, '\$', 5)
self.command('cd cmake_targets', '\$', 5) self.command('cd cmake_targets', '\$', 5)
self.command('rm -f build.log.zip', '\$', 5) self.command('rm -f build.log.zip', '\$', 5)
self.command('zip build.log.zip build_log_*/*', '\$', 60) self.command('zip build.log.zip build_log_*/*', '\$', 60)
...@@ -1907,6 +2541,7 @@ class SSHConnection(): ...@@ -1907,6 +2541,7 @@ class SSHConnection():
self.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 5)
self.close() self.close()
def LogCollectPing(self): def LogCollectPing(self):
self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
self.command('cd ' + self.EPCSourceCodePath, '\$', 5) self.command('cd ' + self.EPCSourceCodePath, '\$', 5)
...@@ -1964,43 +2599,69 @@ class SSHConnection(): ...@@ -1964,43 +2599,69 @@ class SSHConnection():
self.command('zip spgw.log.zip xGwLog.0', '\$', 60) self.command('zip spgw.log.zip xGwLog.0', '\$', 60)
self.close() self.close()
def LogCollectOAIUE(self):
self.open(self.UEIPAddress, self.UEUserName, self.UEPassword)
self.command('cd ' + self.UESourceCodePath, '\$', 5)
self.command('cd cmake_targets', '\$', 5)
self.command('echo ' + self.UEPassword + ' | sudo -S rm -f ue.log.zip', '\$', 5)
self.command('echo ' + self.UEPassword + ' | sudo -S zip ue.log.zip ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 60)
self.command('echo ' + self.UEPassword + ' | sudo -S rm ue*.log core* ue_*record.raw ue_*.pcap ue_*txt', '\$', 5)
self.close()
def RetrieveSystemVersion(self): def RetrieveSystemVersion(self):
if self.eNBIPAddress == 'none': if self.eNBIPAddress == 'none':
self.eNBOsVersion = 'Ubuntu 16.04.5 LTS' self.OsVersion = 'Ubuntu 16.04.5 LTS'
self.eNBKernelVersion = '4.15.0-45-generic' self.KernelVersion = '4.15.0-45-generic'
self.eNBUhdVersion = '3.13.0.1-0' self.UhdVersion = '3.13.0.1-0'
self.eNBCpuNb = '4' self.UsrpBoard = 'B210'
self.eNBCpuModel = 'Intel(R) Core(TM) i5-6200U' self.CpuNb = '4'
self.eNBCpuMHz = '2399.996 MHz' self.CpuModel = 'Intel(R) Core(TM) i5-6200U'
self.CpuMHz = '2399.996 MHz'
return return
if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '': machine = None
if self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != '':
machine = 'eNB'
IPAddress = self.eNBIPAddress
UserName = self.eNBUserName
Password = self.eNBPassword
elif self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != '':
machine = 'UE'
IPAddress = self.UEIPAddress
UserName = self.UEUserName
Password = self.UEPassword
if machine is None:
Usage() Usage()
sys.exit('Insufficient Parameter') sys.exit('Insufficient Parameter')
self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.open(IPAddress, UserName, Password)
self.command('lsb_release -a', '\$', 5) self.command('lsb_release -a', '\$', 5)
result = re.search('Description:\\\\t(?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', str(self.ssh.before)) result = re.search('Description:\\\\t(?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', str(self.ssh.before))
if result is not None: if result is not None:
self.eNBOsVersion = result.group('os_type') self.OsVersion = result.group('os_type')
logging.debug('OS is: ' + self.eNBOsVersion) logging.debug('OS is: ' + self.OsVersion)
self.command('uname -r', '\$', 5) self.command('uname -r', '\$', 5)
result = re.search('uname -r\\\\r\\\\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', str(self.ssh.before)) result = re.search('uname -r\\\\r\\\\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', str(self.ssh.before))
if result is not None: if result is not None:
self.eNBKernelVersion = result.group('kernel_version') self.KernelVersion = result.group('kernel_version')
logging.debug('Kernel Version is: ' + self.eNBKernelVersion) logging.debug('Kernel Version is: ' + self.KernelVersion)
self.command('dpkg --list | egrep --color=never libuhd003', '\$', 5) self.command('dpkg --list | egrep --color=never libuhd003', '\$', 5)
result = re.search('libuhd003:amd64 *(?P<uhd_version>[0-9\.]+)', str(self.ssh.before)) result = re.search('libuhd003:amd64 *(?P<uhd_version>[0-9\.]+)', str(self.ssh.before))
if result is not None: if result is not None:
self.eNBUhdVersion = result.group('uhd_version') self.UhdVersion = result.group('uhd_version')
logging.debug('UHD Version is: ' + self.eNBUhdVersion) logging.debug('UHD Version is: ' + self.UhdVersion)
self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 12)
result = re.search('product: (?P<usrp_board>[0-9A-Za-z]+)\\\\r\\\\n', str(self.ssh.before))
if result is not None:
self.UsrpBoard = result.group('usrp_board')
logging.debug('USRP Board is: ' + self.UsrpBoard)
self.command('lscpu', '\$', 5) self.command('lscpu', '\$', 5)
result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+).*Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', str(self.ssh.before)) result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+).*Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', str(self.ssh.before))
if result is not None: if result is not None:
self.eNBCpuNb = result.group('nb_cpus') self.CpuNb = result.group('nb_cpus')
logging.debug('nb_cpus: ' + self.eNBCpuNb) logging.debug('nb_cpus: ' + self.CpuNb)
self.eNBCpuModel = result.group('model') self.CpuModel = result.group('model')
logging.debug('model: ' + self.eNBCpuModel) logging.debug('model: ' + self.CpuModel)
self.eNBCpuMHz = result.group('cpu_mhz') + ' MHz' self.CpuMHz = result.group('cpu_mhz') + ' MHz'
logging.debug('cpu_mhz: ' + self.eNBCpuMHz) logging.debug('cpu_mhz: ' + self.CpuMHz)
self.close() self.close()
#----------------------------------------------------------- #-----------------------------------------------------------
...@@ -2008,6 +2669,9 @@ class SSHConnection(): ...@@ -2008,6 +2669,9 @@ class SSHConnection():
#----------------------------------------------------------- #-----------------------------------------------------------
def CreateHtmlHeader(self): def CreateHtmlHeader(self):
if (not self.htmlHeaderCreated): if (not self.htmlHeaderCreated):
logging.debug('\u001B[1m----------------------------------------\u001B[0m')
logging.debug('\u001B[1m Creating HTML header \u001B[0m')
logging.debug('\u001B[1m----------------------------------------\u001B[0m')
self.htmlFile = open('test_results.html', 'w') self.htmlFile = open('test_results.html', 'w')
self.htmlFile.write('<!DOCTYPE html>\n') self.htmlFile.write('<!DOCTYPE html>\n')
self.htmlFile.write('<html class="no-js" lang="en-US">\n') self.htmlFile.write('<html class="no-js" lang="en-US">\n')
...@@ -2085,18 +2749,13 @@ class SSHConnection(): ...@@ -2085,18 +2749,13 @@ class SSHConnection():
self.htmlFile.write(' </tr>\n') self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' </table>\n') self.htmlFile.write(' </table>\n')
terminate_ue_flag = True
if (self.ADBIPAddress != 'none'): if (self.ADBIPAddress != 'none'):
terminate_ue_flag = True
self.GetAllUEDevices(terminate_ue_flag) self.GetAllUEDevices(terminate_ue_flag)
self.GetAllCatMDevices(terminate_ue_flag) self.GetAllCatMDevices(terminate_ue_flag)
else: self.htmlUEConnected = len(self.UEDevices)
self.UEDevices.append('doughq9rehg') self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server</h2>\n')
self.UEDevices.append('dnsgiuahgia') self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server</h2>\n')
self.UEDevices.append('uehgieng9')
self.htmlUEConnected = len(self.UEDevices)
self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server</h2>\n')
self.htmlFile.write(' <h2><span class="glyphicon glyphicon-phone"></span> <span class="glyphicon glyphicon-menu-right"></span> ' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server</h2>\n')
self.htmlFile.write(' <br>\n') self.htmlFile.write(' <br>\n')
self.htmlFile.write(' <ul class="nav nav-pills">\n') self.htmlFile.write(' <ul class="nav nav-pills">\n')
count = 0 count = 0
...@@ -2163,6 +2822,9 @@ class SSHConnection(): ...@@ -2163,6 +2822,9 @@ class SSHConnection():
def CreateHtmlFooter(self, passStatus): def CreateHtmlFooter(self, passStatus):
if (os.path.isfile('test_results.html')): if (os.path.isfile('test_results.html')):
logging.debug('\u001B[1m----------------------------------------\u001B[0m')
logging.debug('\u001B[1m Creating HTML footer \u001B[0m')
logging.debug('\u001B[1m----------------------------------------\u001B[0m')
self.RetrieveSystemVersion() self.RetrieveSystemVersion()
self.htmlFile = open('test_results.html', 'a') self.htmlFile = open('test_results.html', 'a')
self.htmlFile.write('</div>\n') self.htmlFile.write('</div>\n')
...@@ -2173,26 +2835,30 @@ class SSHConnection(): ...@@ -2173,26 +2835,30 @@ class SSHConnection():
self.htmlFile.write(' </tr>\n') self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n') self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td>OS Version</td>\n') self.htmlFile.write(' <td>OS Version</td>\n')
self.htmlFile.write(' <td><span class="label label-default">' + self.eNBOsVersion + '</span></td>\n') self.htmlFile.write(' <td><span class="label label-default">' + self.OsVersion + '</span></td>\n')
self.htmlFile.write(' <td>Kernel Version</td>\n') self.htmlFile.write(' <td>Kernel Version</td>\n')
self.htmlFile.write(' <td><span class="label label-default">' + self.eNBKernelVersion + '</span></td>\n') self.htmlFile.write(' <td><span class="label label-default">' + self.KernelVersion + '</span></td>\n')
self.htmlFile.write(' <td>UHD Version</td>\n') self.htmlFile.write(' <td>UHD Version</td>\n')
self.htmlFile.write(' <td><span class="label label-default">' + self.eNBUhdVersion + '</span></td>\n') self.htmlFile.write(' <td><span class="label label-default">' + self.UhdVersion + '</span></td>\n')
self.htmlFile.write(' <td>USRP Board</td>\n')
self.htmlFile.write(' <td><span class="label label-default">' + self.UsrpBoard + '</span></td>\n')
self.htmlFile.write(' </tr>\n') self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n') self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td>Nb CPUs</td>\n') self.htmlFile.write(' <td>Nb CPUs</td>\n')
self.htmlFile.write(' <td><span class="label label-default">' + self.eNBCpuNb + '</span></td>\n') self.htmlFile.write(' <td><span class="label label-default">' + self.CpuNb + '</span></td>\n')
self.htmlFile.write(' <td>CPU Model Name</td>\n') self.htmlFile.write(' <td>CPU Model Name</td>\n')
self.htmlFile.write(' <td><span class="label label-default">' + self.eNBCpuModel + '</span></td>\n') self.htmlFile.write(' <td><span class="label label-default">' + self.CpuModel + '</span></td>\n')
self.htmlFile.write(' <td>CPU Frequency</td>\n') self.htmlFile.write(' <td>CPU Frequency</td>\n')
self.htmlFile.write(' <td><span class="label label-default">' + self.eNBCpuMHz + '</span></td>\n') self.htmlFile.write(' <td><span class="label label-default">' + self.CpuMHz + '</span></td>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' </tr>\n') self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n') self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <th colspan=4 bgcolor = "#33CCFF">Final Status</th>\n') self.htmlFile.write(' <th colspan=5 bgcolor = "#33CCFF">Final Status</th>\n')
if passStatus: if passStatus:
self.htmlFile.write(' <th colspan=2 bgcolor="green"><font color="white">PASS <span class="glyphicon glyphicon-ok"></span></font></th>\n') self.htmlFile.write(' <th colspan=3 bgcolor="green"><font color="white">PASS <span class="glyphicon glyphicon-ok"></span></font></th>\n')
else: else:
self.htmlFile.write(' <th colspan=2 bgcolor="red"><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n') self.htmlFile.write(' <th colspan=3 bgcolor="red"><font color="white">FAIL <span class="glyphicon glyphicon-remove"></span> </font></th>\n')
self.htmlFile.write(' </tr>\n') self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' </table>\n') self.htmlFile.write(' </table>\n')
self.htmlFile.write(' <p></p>\n') self.htmlFile.write(' <p></p>\n')
...@@ -2201,7 +2867,7 @@ class SSHConnection(): ...@@ -2201,7 +2867,7 @@ class SSHConnection():
self.htmlFile.write('</html>\n') self.htmlFile.write('</html>\n')
self.htmlFile.close() self.htmlFile.close()
def CreateHtmlTestRow(self, options, status, processesStatus): def CreateHtmlTestRow(self, options, status, processesStatus, machine='eNB'):
if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)):
self.htmlFile.write(' <tr>\n') self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td bgcolor = "lightcyan" >' + self.testCase_id + '</td>\n') self.htmlFile.write(' <td bgcolor = "lightcyan" >' + self.testCase_id + '</td>\n')
...@@ -2213,15 +2879,17 @@ class SSHConnection(): ...@@ -2213,15 +2879,17 @@ class SSHConnection():
if (processesStatus == 0): if (processesStatus == 0):
self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n') self.htmlFile.write(' <td bgcolor = "lightcoral" >' + str(status) + '</td>\n')
elif (processesStatus == ENB_PROCESS_FAILED): elif (processesStatus == ENB_PROCESS_FAILED):
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process not found</td>\n') self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process not found</td>\n')
elif (processesStatus == ENB_PROCESS_SEG_FAULT): elif (processesStatus == ENB_PROCESS_SEG_FAULT):
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process ended in Segmentation Fault</td>\n') self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Segmentation Fault</td>\n')
elif (processesStatus == ENB_PROCESS_ASSERTION): elif (processesStatus == ENB_PROCESS_ASSERTION) or (processesStatus == UE_PROCESS_ASSERTION):
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process ended in Assertion</td>\n') self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process ended in Assertion</td>\n')
elif (processesStatus == ENB_PROCESS_REALTIME_ISSUE): elif (processesStatus == ENB_PROCESS_REALTIME_ISSUE):
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - eNB process faced Real Time issue(s)</td>\n') self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - ' + machine + ' process faced Real Time issue(s)</td>\n')
elif (processesStatus == ENB_PROCESS_NOLOGFILE_TO_ANALYZE): elif (processesStatus == ENB_PROCESS_NOLOGFILE_TO_ANALYZE) or (processesStatus == UE_PROCESS_NOLOGFILE_TO_ANALYZE):
self.htmlFile.write(' <td bgcolor = "orange" >OK</td>\n') self.htmlFile.write(' <td bgcolor = "orange" >OK?</td>\n')
elif (processesStatus == UE_PROCESS_COULD_NOT_SYNC):
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - UE could not sync</td>\n')
elif (processesStatus == HSS_PROCESS_FAILED): elif (processesStatus == HSS_PROCESS_FAILED):
self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - HSS process not found</td>\n') self.htmlFile.write(' <td bgcolor = "lightcoral" >KO - HSS process not found</td>\n')
elif (processesStatus == MME_PROCESS_FAILED): elif (processesStatus == MME_PROCESS_FAILED):
...@@ -2325,8 +2993,11 @@ def Usage(): ...@@ -2325,8 +2993,11 @@ def Usage():
print(' --XMLTestFile=[XML Test File to be run]') print(' --XMLTestFile=[XML Test File to be run]')
print('------------------------------------------------------------') print('------------------------------------------------------------')
#def GetModeFromXML():
# SSH.mode = test.findtext('mode')
def CheckClassValidity(action,id): def CheckClassValidity(action,id):
if action != 'Build_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'IdleSleep': if action != 'Build_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'Initialize_OAI_eNB' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep':
logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action) logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action)
return False return False
return True return True
...@@ -2340,11 +3011,21 @@ def GetParametersFromXML(action): ...@@ -2340,11 +3011,21 @@ def GetParametersFromXML(action):
SSH.eNB_instance = test.findtext('eNB_instance') SSH.eNB_instance = test.findtext('eNB_instance')
if (SSH.eNB_instance is None): if (SSH.eNB_instance is None):
SSH.eNB_instance = '0' SSH.eNB_instance = '0'
SSH.air_interface = test.findtext('air_interface')
if (SSH.air_interface is None):
SSH.air_interface = 'lte'
else:
SSH.air_interface = SSH.air_interface.lower()
if action == 'Terminate_eNB': if action == 'Terminate_eNB':
SSH.eNB_instance = test.findtext('eNB_instance') SSH.eNB_instance = test.findtext('eNB_instance')
if (SSH.eNB_instance is None): if (SSH.eNB_instance is None):
SSH.eNB_instance = '0' SSH.eNB_instance = '0'
SSH.air_interface = test.findtext('air_interface')
if (SSH.air_interface is None):
SSH.air_interface = 'lte'
else:
SSH.air_interface = SSH.air_interface.lower()
if action == 'Attach_UE': if action == 'Attach_UE':
nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach') nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach')
...@@ -2353,7 +3034,42 @@ def GetParametersFromXML(action): ...@@ -2353,7 +3034,42 @@ def GetParametersFromXML(action):
else: else:
SSH.nbMaxUEtoAttach = int(nbMaxUEtoAttach) SSH.nbMaxUEtoAttach = int(nbMaxUEtoAttach)
if action == 'Ping': if action == 'Build_OAI_UE':
SSH.Build_OAI_UE_args = test.findtext('Build_OAI_UE_args')
SSH.clean_repository = test.findtext('clean_repository')
if (SSH.clean_repository == 'false'):
SSH.clean_repository = False
else:
SSH.clean_repository = True
if action == 'Initialize_OAI_UE':
SSH.Initialize_OAI_UE_args = test.findtext('Initialize_OAI_UE_args')
SSH.UE_instance = test.findtext('UE_instance')
if (SSH.UE_instance is None):
SSH.UE_instance = '0'
SSH.air_interface = test.findtext('air_interface')
if (SSH.air_interface is None):
SSH.air_interface = 'lte'
else:
SSH.air_interface = SSH.air_interface.lower()
if action == 'Initialize_OAI_eNB':
SSH.Initialize_OAI_eNB_args = test.findtext('Initialize_OAI_eNB_args')
SSH.UE_instance = test.findtext('eNB_instance')
if (SSH.eNB_instance is None):
SSH.eNB_instance = '0'
SSH.air_interface = test.findtext('air_interface')
if (SSH.air_interface is None):
SSH.air_interface = 'lte'
else:
SSH.air_interface = SSH.air_interface.lower()
if action == 'Terminate_OAI_UE':
SSH.eNB_instance = test.findtext('UE_instance')
if (SSH.UE_instance is None):
SSH.UE_instance = '0'
if action == 'Ping' or action == 'Ping_CatM_module':
SSH.ping_args = test.findtext('ping_args') SSH.ping_args = test.findtext('ping_args')
SSH.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold') SSH.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold')
...@@ -2395,6 +3111,7 @@ SSH = SSHConnection() ...@@ -2395,6 +3111,7 @@ SSH = SSHConnection()
argvs = sys.argv argvs = sys.argv
argc = len(argvs) argc = len(argvs)
cwd = os.getcwd()
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
...@@ -2403,6 +3120,9 @@ while len(argvs) > 1: ...@@ -2403,6 +3120,9 @@ while len(argvs) > 1:
sys.exit(0) sys.exit(0)
elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE): elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE) matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE)
#if matchReg and mode is not None:
#print('Warning: the mode is defined in both xml file and command line')
#print('ignoring the mode defined in the xml file')
mode = matchReg.group(1) mode = matchReg.group(1)
elif re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE): elif re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE) matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
...@@ -2467,6 +3187,18 @@ while len(argvs) > 1: ...@@ -2467,6 +3187,18 @@ while len(argvs) > 1:
matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE) matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE)
SSH.testXMLfiles.append(matchReg.group(1)) SSH.testXMLfiles.append(matchReg.group(1))
SSH.nbTestXMLfiles += 1 SSH.nbTestXMLfiles += 1
elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE)
SSH.UEIPAddress = matchReg.group(1)
elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE)
SSH.UEUserName = matchReg.group(1)
elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE)
SSH.UEPassword = matchReg.group(1)
elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE)
SSH.UESourceCodePath = matchReg.group(1)
elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE): elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE) matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE)
finalStatus = matchReg.group(1) finalStatus = matchReg.group(1)
...@@ -2482,11 +3214,17 @@ if re.match('^TerminateeNB$', mode, re.IGNORECASE): ...@@ -2482,11 +3214,17 @@ if re.match('^TerminateeNB$', mode, re.IGNORECASE):
sys.exit('Insufficient Parameter') sys.exit('Insufficient Parameter')
SSH.TerminateeNB() SSH.TerminateeNB()
elif re.match('^TerminateUE$', mode, re.IGNORECASE): elif re.match('^TerminateUE$', mode, re.IGNORECASE):
if SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '': if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''):
Usage() Usage()
sys.exit('Insufficient Parameter') sys.exit('Insufficient Parameter')
signal.signal(signal.SIGUSR1, receive_signal) signal.signal(signal.SIGUSR1, receive_signal)
SSH.TerminateUE() SSH.TerminateUE()
elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE):
if SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '':
Usage()
sys.exit('Insufficient Parameter')
signal.signal(signal.SIGUSR1, receive_signal)
SSH.TerminateOAIUE()
elif re.match('^TerminateHSS$', mode, re.IGNORECASE): elif re.match('^TerminateHSS$', mode, re.IGNORECASE):
if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '': if SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '':
Usage() Usage()
...@@ -2503,7 +3241,7 @@ elif re.match('^TerminateSPGW$', mode, re.IGNORECASE): ...@@ -2503,7 +3241,7 @@ elif re.match('^TerminateSPGW$', mode, re.IGNORECASE):
sys.exit('Insufficient Parameter') sys.exit('Insufficient Parameter')
SSH.TerminateSPGW() SSH.TerminateSPGW()
elif re.match('^LogCollectBuild$', mode, re.IGNORECASE): elif re.match('^LogCollectBuild$', mode, re.IGNORECASE):
if SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '': if (SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '') and (SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == ''):
Usage() Usage()
sys.exit('Insufficient Parameter') sys.exit('Insufficient Parameter')
SSH.LogCollectBuild() SSH.LogCollectBuild()
...@@ -2537,16 +3275,24 @@ elif re.match('^LogCollectIperf$', mode, re.IGNORECASE): ...@@ -2537,16 +3275,24 @@ elif re.match('^LogCollectIperf$', mode, re.IGNORECASE):
Usage() Usage()
sys.exit('Insufficient Parameter') sys.exit('Insufficient Parameter')
SSH.LogCollectIperf() SSH.LogCollectIperf()
elif re.match('^LogCollectOAIUE$', mode, re.IGNORECASE):
if SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '':
Usage()
sys.exit('Insufficient Parameter')
SSH.LogCollectOAIUE()
elif re.match('^InitiateHtml$', mode, re.IGNORECASE): elif re.match('^InitiateHtml$', mode, re.IGNORECASE):
if SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '': if (SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == ''):
Usage() Usage()
sys.exit('Insufficient Parameter') sys.exit('Insufficient Parameter')
count = 0 count = 0
foundCount = 0 foundCount = 0
while (count < SSH.nbTestXMLfiles): while (count < SSH.nbTestXMLfiles):
xml_test_file = sys.path[0] + "/" + SSH.testXMLfiles[count] xml_test_file = cwd + "/" + SSH.testXMLfiles[count]
if (os.path.isfile(xml_test_file)): if (os.path.isfile(xml_test_file)):
xmlTree = ET.parse(xml_test_file) try:
xmlTree = ET.parse(xml_test_file)
except:
print("Error while parsing file: " + xml_test_file)
xmlRoot = xmlTree.getroot() xmlRoot = xmlTree.getroot()
SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count)))
SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-' + str(count))) SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-' + str(count)))
...@@ -2558,20 +3304,33 @@ elif re.match('^InitiateHtml$', mode, re.IGNORECASE): ...@@ -2558,20 +3304,33 @@ elif re.match('^InitiateHtml$', mode, re.IGNORECASE):
SSH.CreateHtmlHeader() SSH.CreateHtmlHeader()
elif re.match('^FinalizeHtml$', mode, re.IGNORECASE): elif re.match('^FinalizeHtml$', mode, re.IGNORECASE):
SSH.CreateHtmlFooter(SSH.finalStatus) SSH.CreateHtmlFooter(SSH.finalStatus)
elif re.match('^TesteNB$', mode, re.IGNORECASE): elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE):
if SSH.eNBIPAddress == '' or SSH.eNBRepository == '' or SSH.eNBBranch == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '' or SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '' or SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '': if re.match('^TesteNB$', mode, re.IGNORECASE):
Usage() if (SSH.eNBRepository == '' or SSH.eNBBranch == '' or SSH.eNBSourceCodePath == ''):
sys.exit('Insufficient Parameter') Usage()
sys.exit('Insufficient Parameter')
if (SSH.eNBIPAddress == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '') and (SSH.UEIPAddress == '' or SSH.UEUserName == '' or SSH.UEPassword == ''):
Usage()
sys.exit('Insufficient Parameter')
elif SSH.ADBIPAddress == 'none' and SSH.EPCIPAddress == 'none':
pass
elif SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '' or SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '':
Usage()
sys.exit('Insufficient Parameter')
if (SSH.EPCIPAddress != ''):
SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/tcp_iperf_stats.awk", "/tmp")
SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, cwd + "/active_net_interfaces.awk", "/tmp")
else:
if SSH.UEIPAddress == '' or SSH.eNBRepository == '' or SSH.eNBBranch == '' or SSH.UEUserName == '' or SSH.UEPassword == '' or SSH.UESourceCodePath == '':
Usage()
sys.exit('UE: Insufficient Parameter')
if (SSH.EPCIPAddress != 'none'):
SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, sys.path[0] + "/tcp_iperf_stats.awk", "/tmp")
SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, sys.path[0] + "/active_net_interfaces.awk", "/tmp")
#read test_case_list.xml file #read test_case_list.xml file
# if no parameters for XML file, use default value # if no parameters for XML file, use default value
if (SSH.nbTestXMLfiles != 1): if (SSH.nbTestXMLfiles != 1):
xml_test_file = sys.path[0] + "/test_case_list.xml" xml_test_file = cwd + "/test_case_list.xml"
else: else:
xml_test_file = sys.path[0] + "/" + SSH.testXMLfiles[0] xml_test_file = cwd + "/" + SSH.testXMLfiles[0]
xmlTree = ET.parse(xml_test_file) xmlTree = ET.parse(xml_test_file)
xmlRoot = xmlTree.getroot() xmlRoot = xmlTree.getroot()
...@@ -2627,6 +3386,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE): ...@@ -2627,6 +3386,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE):
SSH.testCase_id = id SSH.testCase_id = id
SSH.desc = test.findtext('desc') SSH.desc = test.findtext('desc')
action = test.findtext('class') action = test.findtext('class')
mode = test.findtext('mode')
if (CheckClassValidity(action, id) == False): if (CheckClassValidity(action, id) == False):
continue continue
SSH.ShowTestID() SSH.ShowTestID()
...@@ -2648,6 +3408,14 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE): ...@@ -2648,6 +3408,14 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE):
SSH.AttachUE() SSH.AttachUE()
elif action == 'Detach_UE': elif action == 'Detach_UE':
SSH.DetachUE() SSH.DetachUE()
elif action == 'Build_OAI_UE':
SSH.BuildOAIUE()
elif action == 'Initialize_OAI_UE':
SSH.InitializeOAIUE()
elif action == 'Terminate_OAI_UE':
SSH.TerminateOAIUE()
elif action == 'Initialize_OAI_eNB':
SSH.InitializeOAIeNB()
elif action == 'Initialize_CatM_module': elif action == 'Initialize_CatM_module':
SSH.InitializeCatM() SSH.InitializeCatM()
elif action == 'Terminate_CatM_module': elif action == 'Terminate_CatM_module':
...@@ -2656,6 +3424,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE): ...@@ -2656,6 +3424,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE):
SSH.AttachCatM() SSH.AttachCatM()
elif action == 'Detach_CatM_module': elif action == 'Detach_CatM_module':
SSH.TerminateCatM() SSH.TerminateCatM()
elif action == 'Ping_CatM_module':
SSH.PingCatM()
elif action == 'Ping': elif action == 'Ping':
SSH.Ping() SSH.Ping()
elif action == 'Iperf': elif action == 'Iperf':
......
<!--
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>run-OAI-gNB-NR-UE-USRP</htmlTabRef>
<htmlTabName>run OAI gNB and OAI NR UE USRP</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<TestCaseRequestedList>
090101 000001 090102 000001 090108 090109
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="090101">
<class>Initialize_OAI_eNB</class>
<desc>Initialize gNB USRP</desc>
<Initialize_OAI_eNB_args>-O ../../../ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf</Initialize_OAI_eNB_args>
<air_interface>NR</air_interface>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>5</idle_sleep_time_in_sec>
</testCase>
<testCase id="090102">
<class>Initialize_OAI_UE</class>
<desc>Initialize NR UE USRP</desc>
<Initialize_OAI_UE_args>-C 3510000000 --numerology 1 -r 106 --phy-test --usrp-args "addr=192.168.30.2,clock_source=external,time_source=external" --threadoffset 16</Initialize_OAI_UE_args>
<air_interface>NR</air_interface>
</testCase>
<testCase id="090108">
<class>Terminate_OAI_UE</class>
<desc>Terminate NR UE</desc>
<air_interface>NR</air_interface>
</testCase>
<testCase id="090109">
<class>Terminate_eNB</class>
<desc>Terminate gNB</desc>
<air_interface>NR</air_interface>
</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>gnb-build-tab</htmlTabRef>
<htmlTabName>Build-gNB</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
010101
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010101">
<mode>TesteNB</mode>
<class>Build_eNB</class>
<desc>Build gNB (USRP)</desc>
<Build_eNB_args>--gNB -w USRP</Build_eNB_args>
</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>nr-ue-build-tab</htmlTabRef>
<htmlTabName>Build-NR-UE</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
010102
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="010102">
<mode>TestUE</mode>
<class>Build_OAI_UE</class>
<desc>Build NR UE (USRP)</desc>
<Build_OAI_UE_args>--nrUE -w USRP</Build_OAI_UE_args>
<clean_repository>false</clean_repository>
</testCase>
</testCaseList>
...@@ -1238,6 +1238,8 @@ int main( int argc, char **argv ) ...@@ -1238,6 +1238,8 @@ int main( int argc, char **argv )
// wait for end of program // wait for end of program
printf("TYPE <CTRL-C> TO TERMINATE\n"); printf("TYPE <CTRL-C> TO TERMINATE\n");
fflush(stdout);
fflush(stderr);
//getchar(); //getchar();
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
......
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