diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..d7126a6224 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# vim swp +*.swp + +# log and exec file +log/ +lte_build_oai/ +targets/bin/ +cmake_targets/nas_sim_tools/build/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 0dc8d3051b..0000000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,17 +0,0 @@ -job1: - script: - - date - - pwd - - echo $OAI_TEST_CASE_GROUP - - echo $MACHINELIST - - echo $MACHINELISTGENERIC - - echo $RESULT_DIR - - echo $NRUNS_LTE_SOFTMODEM - - source oaienv - - rm -rf cmake_targets/autotests/log - - mkdir cmake_targets/autotests/log - - cd cmake_targets/autotests/v2 - - python main.py - - date - only: - - triggers diff --git a/README.txt b/README.txt index edd233830f..37f6a86571 100644 --- a/README.txt +++ b/README.txt @@ -9,26 +9,36 @@ Please see NOTICE.txt for third party software that is included in the sources. The OpenAirInterface (OAI) software is composed of the following parts: openairinterface5g -├── cmake_targets: build utilities to compile (simulation, emulation and real-time platforms), and generated build files -├── common : some common OAI utilities, other tools can be found at openair2/UTILS +├── ci-scripts: Meta-scripts used by the OSA CI process. Contains also configuration files used day-to-day by CI. +├── cmake_targets: Build utilities to compile (simulation, emulation and real-time platforms), and generated build files +├── common : Some common OAI utilities, other tools can be found at openair2/UTILS +├── doc : Contains an up-to-date feature set list ├── LICENSE -├── maketags : script to generate emacs tags -├── openair1 : 3GPP LTE Rel-10 PHY layer + PHY RF simulation and a subset of Rel 12 Features. -├── openair2 :3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP implementation. +├── maketags : Script to generate emacs tags +├── nfapi : Contains the NFAPI code. A local Readme file provides more details. +├── openair1 : 3GPP LTE Rel-10/12 PHY layer + PHY RF simulation. A local Readme file provides more details. +├── openair2 : 3GPP LTE Rel-10 RLC/MAC/PDCP/RRC/X2AP implementation. + ├── COMMON + ├── DOCS + ├── ENB_APP ├── LAYER2/RLC/ with the following subdirectories: UM_v9.3.0, TM_v9.3.0, and AM_v9.3.0. - ├── LAYER2/PDCP/PDCP_v10.1.0. - ├── RRC/LITE + ├── LAYER2/PDCP/PDCP_v10.1.0. + ├── NETWORK_DRIVER ├── PHY_INTERFACE + ├── RRC/LITE + ├── UTIL ├── X2AP - ├── ENB_APP ├── openair3: 3GPP LTE Rel10 for S1AP, NAS GTPV1-U for both ENB and UE. + ├── COMMON + ├── DOCS ├── GTPV1-U - ├── NAS + ├── NAS ├── S1AP ├── SCTP ├── SECU ├── UDP -└── targets: top level wrapper for unitary simulation for PHY channels, system-level emulation (eNB-UE with and without S1), and realtime eNB and UE and RRH GW. + ├── UTILS +└── targets: Top-level wrappers for unitary simulation for PHY channels, system-level emulation (eNB-UE with and without S1), and realtime eNB and UE and RRH GW. RELEASE NOTES: @@ -44,3 +54,12 @@ v0.6 -> RRH functionality, UE greatly improved, better TDD support, a lot of bugs fixed. WARNING: oaisim in PHY abstraction mode does not work, you need to use v0.5.2 for that. v0.6.1 -> Mostly bugfixes. This is the last version without NFAPI. +v1.0.0 -> January 2019. This version first implements the architectural split described in doc/oai_lte_enb_func_split_arch.png picture. + Only FAPI, nFAPI and IF4.5 interfaces are implemented. + Repository tree structure prepares future integrations of features such as LTE-M, nbIOT or 5G-NR. + Preliminary X2 support has been implemented. + S1-flex has been introduced. + New tools: config library, telnet server, ... + A lot of bugfixes and a proper automated Continuous Integration process validates contributions. +v1.0.1 -> February 2019: Bug fix for the UE L1 simulator. +v1.0.2 -> February 2019: Full OAI support for 3.13.1 UHD diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index fc0290fc44..03f88053b3 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -33,15 +33,18 @@ def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) { def doRedHatBuild = false def doFlexranCtrlTest = false +// Location of the executor node +def nodeExecutor = params.nodeExecutor + pipeline { agent { - label 'bellatrix' + label nodeExecutor } options { disableConcurrentBuilds() timestamps() gitLabConnection('OAI GitLab') - gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-FDD-Band7", "Test-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40"]) + gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-Mono-FDD-Band7", "Test-Mono-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40", "Test-Mono-FDD-Band13"]) ansiColor('xterm') } @@ -85,6 +88,9 @@ pipeline { echo "GitLab Act is ${env.gitlabActionType}" script { if ("MERGE".equals(env.gitlabActionType)) { + // since a bit, in push events, gitlabUserEmail is not populated + gitCommitAuthorEmailAddr = env.gitlabUserEmail + echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}" // GitLab-Jenkins plugin integration is lacking to perform the merge by itself // Doing it manually --> it may have merge conflicts sh "./ci-scripts/doGitLabMerge.sh --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}" @@ -104,6 +110,11 @@ pipeline { } else { echo "Git Branch is ${GIT_BRANCH}" echo "Git Commit is ${GIT_COMMIT}" + // since a bit, in push events, gitlabUserEmail is not populated + gitCommitAuthorEmailAddr = sh returnStdout: true, script: 'git log -n1 --pretty=format:%ae ${GIT_COMMIT}' + gitCommitAuthorEmailAddr = gitCommitAuthorEmailAddr.trim() + echo "GitLab Usermail is ${gitCommitAuthorEmailAddr}" + sh "git log -n1 --pretty=format:\"%s\" > .git/CI_COMMIT_MSG" sh "zip -r -qq localZip.zip ." // Running astyle options on all C/H files in the repository @@ -129,6 +140,7 @@ pipeline { script { def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Merge Conflicts -- Cannot perform CI" addGitLabMRComment comment: message + currentBuild.result = 'FAILURE' } } } @@ -260,7 +272,7 @@ pipeline { expression {doRedHatBuild} } steps { - gitlabCommitStatus(name: "Build eNb-USRP-CentOS") { + gitlabCommitStatus(name: "Build eNb-USRP-RHE") { script { try { withCredentials([ @@ -271,7 +283,7 @@ pipeline { } } } catch (Exception e) { - echo "Red Hat build failed not an error now" + echo "Red Hat build failed but we could keep running pipeline if all ubuntu-based build passed" } } } @@ -279,6 +291,11 @@ pipeline { } } post { + failure { + script { + currentBuild.result = 'FAILURE' + } + } always { script { dir ('archives') { @@ -289,6 +306,17 @@ pipeline { } if ("MERGE".equals(env.gitlabActionType)) { sh "./ci-scripts/oai-ci-vm-tool report-build --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}" + // If the merge request has introduced more CPPCHECK errors or warnings, notifications in GitLab + if (fileExists('oai_cppcheck_added_errors.txt')) { + def ret=readFile('./oai_cppcheck_added_errors.txt').trim(); + if ("0".equals(ret)) { + echo "No added cppcheck warnings/errors in this merge request" + } else { + def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Some modified files in Merge Request MAY have INTRODUCED up to " + ret + " CPPCHECK errors/warnings" + addGitLabMRComment comment: message + } + } + // If the merge request has introduced compilation warnings, notifications in GitLab sh "./ci-scripts/checkAddedWarnings.sh --src-branch ${env.gitlabSourceBranch} --target-branch ${env.gitlabTargetBranch}" def res=readFile('./oai_warning_files.txt').trim(); if ("0".equals(res)) { @@ -312,58 +340,87 @@ pipeline { stage ("Variant Tests") { parallel { - stage ("Test physical simulators") { - steps { - gitlabCommitStatus(name: "Test phy-sim") { - timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + stage ("VM-based tests") { + stages { + stage ("Test physical simulators") { + steps { + script { + timeout (time: 20, unit: 'MINUTES') { + try { + gitlabCommitStatus(name: "Test phy-sim") { + sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + } + } + stage ("Build Flexran Controller") { + when { + expression {doFlexranCtrlTest} + } + steps { + script { + timeout (time: 20, unit: 'MINUTES') { + try { + sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant flexran-rtc --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + } + } + stage ("Test basic simulator") { + steps { + script { + timeout (time: 30, unit: 'MINUTES') { + try { + gitlabCommitStatus(name: "Test basic-sim") { + sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + } + } + stage ("Test L2 simulator") { + steps { + script { + timeout (time: 30, unit: 'MINUTES') { + try { + gitlabCommitStatus(name: "Test L2-sim") { + sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } } } } } - stage ("Test basic simulator") { - steps { - gitlabCommitStatus(name: "Test basic-sim") { - timeout (time: 30, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } - } - } - } - stage ("Test L2 simulator") { - steps { - gitlabCommitStatus(name: "Test L2-sim") { - timeout (time: 30, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } - } - } - } - stage ("Build Flexran Controller") { - when { - expression {doFlexranCtrlTest} - } - steps { - timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant flexran-rtc --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" - } - } - } - stage ("Test FDD - Band 7 - B210") { + stage ("Test MONOLITHIC - FDD - Band 7 - B210") { steps { script { if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-FDD-Band7") { + gitlabCommitStatus(name: "Test-Mono-FDD-Band7") { build job: 'eNB-CI-FDD-Band7-B210', parameters: [ string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true) + booleanParam(name: 'eNB_mergeRequest', value: true), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) ] } } else { - gitlabCommitStatus(name: "Test-FDD-Band7") { + gitlabCommitStatus(name: "Test-Mono-FDD-Band7") { build job: 'eNB-CI-FDD-Band7-B210', parameters: [ string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), @@ -377,8 +434,7 @@ pipeline { } post { // In case of any non-success, we are retrieving the HTML report of the last completed - // slave job. - // The only drop-back is that we may retrieve the HTML report of a previous build + // slave job. The only drop-back is that we may retrieve the HTML report of a previous build always { script { if (!fileExists('test_results-eNB-CI-FDD-Band7-B210.html')) { @@ -392,23 +448,29 @@ pipeline { } } } + failure { + script { + currentBuild.result = 'FAILURE' + } + } } } - stage ("Test TDD - Band 40 - B210") { + stage ("Test MONOLITHIC - TDD - Band 40 - B210") { steps { script { if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-TDD-Band40") { + gitlabCommitStatus(name: "Test-Mono-TDD-Band40") { build job: 'eNB-CI-TDD-Band40-B210', parameters: [ string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true) + booleanParam(name: 'eNB_mergeRequest', value: true), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) ] } } else { - gitlabCommitStatus(name: "Test-TDD-Band40") { + gitlabCommitStatus(name: "Test-Mono-TDD-Band40") { build job: 'eNB-CI-TDD-Band40-B210', parameters: [ string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), @@ -422,8 +484,7 @@ pipeline { } post { // In case of any non-success, we are retrieving the HTML report of the last completed - // slave job. - // The only drop-back is that we may retrieve the HTML report of a previous build + // slave job. The only drop-back is that we may retrieve the HTML report of a previous build always { script { if (!fileExists('test_results-eNB-CI-TDD-Band40-B210.html')) { @@ -437,6 +498,11 @@ pipeline { } } } + failure { + script { + currentBuild.result = 'FAILURE' + } + } } } stage ("Test IF4p5 - FDD - Band 7 - B210") { @@ -449,7 +515,8 @@ pipeline { string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true) + booleanParam(name: 'eNB_mergeRequest', value: true), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) ] } } else { @@ -467,8 +534,7 @@ pipeline { } post { // In case of any non-success, we are retrieving the HTML report of the last completed - // slave job. - // The only drop-back is that we may retrieve the HTML report of a previous build + // slave job. The only drop-back is that we may retrieve the HTML report of a previous build always { script { if (!fileExists('test_results-eNB-CI-IF4p5-FDD-Band7-B210.html')) { @@ -482,6 +548,11 @@ pipeline { } } } + failure { + script { + currentBuild.result = 'FAILURE' + } + } } } stage ("Test IF4p5 - TDD - Band 40 - B210") { @@ -494,7 +565,8 @@ pipeline { string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true) + booleanParam(name: 'eNB_mergeRequest', value: true), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) ] } } else { @@ -512,8 +584,7 @@ pipeline { } post { // In case of any non-success, we are retrieving the HTML report of the last completed - // slave job. - // The only drop-back is that we may retrieve the HTML report of a previous build + // slave job. The only drop-back is that we may retrieve the HTML report of a previous build always { script { if (!fileExists('test_results-eNB-CI-IF4p5-TDD-Band40-B210.html')) { @@ -527,6 +598,111 @@ pipeline { } } } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } + stage ("Test MONOLITHIC - FDD - Band 13 - B210") { + steps { + script { + if ("MERGE".equals(env.gitlabActionType)) { + gitlabCommitStatus(name: "Test-Mono-FDD-Band13") { + build job: 'eNB-CI-MONO-FDD-Band13-B210', + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: true), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) + ] + } + } else { + gitlabCommitStatus(name: "Test-Mono-FDD-Band13") { + build job: 'eNB-CI-MONO-FDD-Band13-B210', + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), + string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), + booleanParam(name: 'eNB_mergeRequest', value: false) + ] + } + } + } + } + post { + // In case of any non-success, we are retrieving the HTML report of the last completed + // slave job. The only drop-back is that we may retrieve the HTML report of a previous build + always { + script { + if (!fileExists('test_results-eNB-CI-MONO-FDD-Band13-B210.html')) { + copyArtifacts(projectName: 'eNB-CI-MONO-FDD-Band13-B210', + filter: 'test_results*.html', + selector: lastCompleted()) + if (fileExists('test_results-eNB-CI-MONO-FDD-Band13-B210.html')) { + sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-MONO-FDD-Band13-B210.html" + archiveArtifacts artifacts: 'test_results-eNB-CI-MONO-FDD-Band13-B210.html' + } + } + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } + stage ("Test OAI UE Sniffing - FDD - Band 20 - B200") { + steps { + script { + if ("MERGE".equals(env.gitlabActionType)) { + //gitlabCommitStatus(name: "Test-OAI-UE-FDD-Band20") { + build job: 'UE-CI-FDD-Band20-B200', + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: true), + string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) + ] + //} + } else { + //gitlabCommitStatus(name: "Test-OAI-UE-FDD-Band20") { + build job: 'UE-CI-FDD-Band20-B200', + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), + string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), + booleanParam(name: 'eNB_mergeRequest', value: false) + ] + //} + } + } + } + post { + // In case of any non-success, we are retrieving the HTML report of the last completed + // slave job. The only drop-back is that we may retrieve the HTML report of a previous build + always { + script { + if (!fileExists('test_results-UE-CI-FDD-Band20-B200.html')) { + copyArtifacts(projectName: 'UE-CI-FDD-Band20-B200', + filter: 'test_results*.html', + selector: lastCompleted()) + if (fileExists('test_results-UE-CI-FDD-Band20-B200.html')) { + sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-UE-CI-FDD-Band20-B200.html" + archiveArtifacts artifacts: 'test_results-UE-CI-FDD-Band20-B200.html' + } + } + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } } } } @@ -565,13 +741,18 @@ pipeline { sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}" 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: env.gitlabUserEmail + to: gitCommitAuthorEmailAddr + + if (fileExists('.git/CI_COMMIT_MSG')) { + sh "rm -f .git/CI_COMMIT_MSG" + } } } success { diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran index 39347b3558..525ceec525 100644 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ b/ci-scripts/Jenkinsfile-tmp-ran @@ -115,8 +115,10 @@ pipeline { } else { String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") for (xmlFile in myXmlTestSuite) { - mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " - echo "Test XML file : ${xmlFile}" + if (fileExists("ci-scripts/" + xmlFile)) { + mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " + echo "Test XML file : ${xmlFile}" + } } } // If not present picking a default Stage Name @@ -191,6 +193,13 @@ pipeline { if (allParametersPresent) { echo "All parameters are present" + if (eNB_AllowMergeRequestProcess) { + sh "git fetch" + sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" + } else { + sh "git fetch" + sh "git checkout -f ${eNB_CommitID}" + } } else { echo "Some parameters are missing" sh "./ci-scripts/fail.sh" @@ -211,6 +220,7 @@ pipeline { sh "python3 main.py --mode=InitiateHtml --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_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} --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" } catch (Exception e) { @@ -218,6 +228,7 @@ pipeline { buildStageStatus = false } } + } sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}" } } diff --git a/ci-scripts/Jenkinsfile-tmp-ue b/ci-scripts/Jenkinsfile-tmp-ue new file mode 100644 index 0000000000..70fe29879f --- /dev/null +++ b/ci-scripts/Jenkinsfile-tmp-ue @@ -0,0 +1,300 @@ +#!/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 + */ + +// Template Jenkins Declarative Pipeline script to run Test w/ RF HW + +// Location of the python executor node shall be in the same subnet as the others servers +def pythonExecutor = params.pythonExecutor + +// Location of the test XML file to be run +def testXMLFile = params.pythonTestXmlFile +def mainPythonAllXmlFiles = "" +def buildStageStatus = true + +// Name of the test stage +def testStageName = params.pipelineTestStageName + +// Name of the phone resource +def ciSmartPhoneResource = params.smartphonesResource + +// Terminate Status +def termUE = 0 +def termENB = 1 +def termSPGW = 2 +def termMME = 3 +def termHSS = 4 +def termStatusArray = new Boolean[termHSS + 1] +termStatusArray[termUE] = false +termStatusArray[termENB] = false +termStatusArray[termSPGW] = false +termStatusArray[termMME] = false +termStatusArray[termHSS] = false + +// Global Parameters. Normally they should be populated when the master job +// triggers the slave job with parameters +def eNB_Repository +def eNB_Branch +def eNB_CommitID +def eNB_AllowMergeRequestProcess = false +def eNB_TargetBranch + +pipeline { + agent { + label pythonExecutor + } + options { + disableConcurrentBuilds() + ansiColor('xterm') + lock (ciSmartPhoneResource) + } + // the following parameter options are commented out so it shows the ones + // that you SHALL have to run the job. + // You can use them as template + /* + parameters { + //node-test parameters + string(name: 'pythonExecutor', defaultValue: 'nodea', description: 'Node where the pipeline - python scripts will be executed') + string(name: 'pythonTestXmlFile', defaultValue: 'enb_usrpB210_band7_50PRB.xml', description: 'Location of the Test XML to be run') + string(name: 'pipelineTestStageName', defaultValue: 'Test COTS-UE - OAI eNB - LTEBOX EPC', description: 'Naming of the Test Stage') + booleanParam(name: 'pipelineZipsConsoleLog', defaultValue: 'True', description: 'If true, the pipeline script retrieves the job console log, zips it and archives it as artifact') + string(name: 'smartphonesResource', defaultValue: 'CI-Bench-1-Phones', description: 'Lockeable Resource to prevent multiple jobs to run simultaneously with the same resource') + + //eNB parameters + string(name: 'eNB_IPAddress', defaultValue: '192.168.XX.XX', description: 'IP Address of eNB') + credentials(name: 'eNB_Credentials', defaultValue: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', credentialType: "Username with password", required: true, description: 'Credentials for eNB') + string(name: 'eNB_SourceCodePath', defaultValue: '/tmp/CI-enb', description: 'Full path of eNB source code') + + //EPC parameters + string(name: 'EPC_IPAddress', defaultValue: '192.168.XX.XX', description: 'IP Address of EPC') + string(name: 'EPC_Type', defaultValue: 'ltebox', description: 'EPC type: OAI or ltebox') + credentials(name: 'EPC_Credentials', defaultValue: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', credentialType: "Username with password", required: true, description: 'Credentials for EPC') + string(name: 'EPC_SourceCodePath', defaultValue: '/tmp/CI-enb', description: 'Full path of EPC source code') + + //ADB server parameters + string(name: 'ADB_IPAddress', defaultValue: '192.168.XX.XX', description: 'IP Address of ADB server') + credentials(name: 'ADB_Credentials', defaultValue: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', credentialType: "Username with password", required: true, description: 'Credentials for ADB') + } + */ + + stages { + stage ("Verify Parameters") { + steps { + script { + echo '\u2705 \u001B[32mVerify Parameters\u001B[0m' + def allParametersPresent = true + + // It is already to late to check it + if (params.pythonExecutor != null) { + echo "eNB CI executor node : ${pythonExecutor}" + } + // If not present picking a default XML file + if (params.pythonTestXmlFile == null) { + // picking default + testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml' + echo "Test XML file(default): ${testXMLFile}" + mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " + } else { + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + if (fileExists("ci-scripts/" + xmlFile)) { + mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " + echo "Test XML file : ${xmlFile}" + } + } + } + // If not present picking a default Stage Name + if (params.pipelineTestStageName == null) { + // picking default + testStageName = 'Template Test Stage' + } + + if (params.smartphonesResource == null) { + allParametersPresent = false + } + if (params.UE_IPAddress == null) { + allParametersPresent = false + } + if (params.UE_SourceCodePath == null) { + allParametersPresent = false + } + if (params.UE_Credentials == null) { + allParametersPresent = false + } + // the following 4 parameters should be pushed by the master trigger + // if not present, take the job GIT variables (used for developing) + if (params.eNB_Repository == null) { + eNB_Repository = env.GIT_URL + } else { + eNB_Repository = params.eNB_Repository + } + echo "eNB_Repository : ${eNB_Repository}" + if (params.eNB_Branch == null) { + eNB_Branch = env.GIT_BRANCH + } else { + eNB_Branch = params.eNB_Branch + } + echo "eNB_Branch : ${eNB_Branch}" + if (params.eNB_CommitID == null) { + eNB_CommitID = env.GIT_COMMIT + } else { + eNB_CommitID = params.eNB_CommitID + } + echo "eNB_CommitID : ${eNB_CommitID}" + if (params.eNB_mergeRequest != null) { + eNB_AllowMergeRequestProcess = params.eNB_mergeRequest + if (eNB_AllowMergeRequestProcess) { + if (params.eNB_TargetBranch != null) { + eNB_TargetBranch = params.eNB_TargetBranch + } else { + eNB_TargetBranch = 'develop' + } + echo "eNB_TargetBranch : ${eNB_TargetBranch}" + } + } +/* + if (params.EPC_IPAddress == null) { + allParametersPresent = false + } + if (params.EPC_Type == null) { + allParametersPresent = false + } + if (params.EPC_SourceCodePath == null) { + allParametersPresent = false + } + if (params.EPC_Credentials == null) { + allParametersPresent = false + } +*/ + if (params.ADB_IPAddress == null) { + allParametersPresent = false + } + if (params.ADB_Credentials == null) { + allParametersPresent = false + } + + if (allParametersPresent) { + echo "All parameters are present" + if (eNB_AllowMergeRequestProcess) { + sh "git fetch" + sh "./ci-scripts/doGitLabMerge.sh --src-branch ${eNB_Branch} --src-commit ${eNB_CommitID} --target-branch ${eNB_TargetBranch} --target-commit latest" + } else { + sh "git fetch" + sh "git checkout -f ${eNB_CommitID}" + } + } else { + echo "Some parameters are missing" + sh "./ci-scripts/fail.sh" + } + } + } + } + stage ("Build and Test") { + steps { + script { + dir ('ci-scripts') { + echo "\u2705 \u001B[32m${testStageName}\u001B[0m" + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] + ]) { + sh "python3 main.py --mode=InitiateHtml --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + if (fileExists(xmlFile)) { + try { + sh "python3 main.py --mode=TestUE --UEIPAddress=${params.UE_IPAddress} --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" + } catch (Exception e) { + currentBuild.result = 'FAILURE' + buildStageStatus = false + } + } + } + sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password}" + } + } + } + } + } + stage('Log Collection') { + parallel { + stage('Log Collection (OAI UE - Build)') { + steps { + echo '\u2705 \u001B[32mLog Collection (OAI UE - Build)\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=LogCollectBuild --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath}" + + echo '\u2705 \u001B[32mLog Transfer (UE - Build)\u001B[0m' + sh "sshpass -p \'${UE_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${UE_Username}@${params.UE_IPAddress}:${UE_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 (OAI UE - Run)') { + steps { + echo '\u2705 \u001B[32mLog Collection (OAI UE - Run)\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=LogCollectOAIUE --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_SourceCodePath}" + + echo '\u2705 \u001B[32mLog Transfer (UE - Run)\u001B[0m' + sh "sshpass -p \'${UE_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${UE_Username}@${params.UE_IPAddress}:${UE_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" + } + 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: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html" + archiveArtifacts "test_results-${JOB_NAME}.html" + } + } + } + } + } + } + } + + post { + always { + script { + if (params.pipelineZipsConsoleLog != null) { + if (params.pipelineZipsConsoleLog) { + echo "Archiving Jenkins console log" + sh "wget --no-check-certificate --no-proxy ${env.JENKINS_URL}/job/${env.JOB_NAME}/${env.BUILD_ID}/consoleText -O consoleText.log || true" + sh "zip -m consoleText.log.${env.BUILD_ID}.zip consoleText.log || true" + if(fileExists("consoleText.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "consoleText.log.${env.BUILD_ID}.zip" + } + } + } + } + } + } +} diff --git a/ci-scripts/buildOnRH.sh b/ci-scripts/buildOnRH.sh index bb57cde165..076f34f8d2 100755 --- a/ci-scripts/buildOnRH.sh +++ b/ci-scripts/buildOnRH.sh @@ -180,7 +180,7 @@ echo "Checking build status" echo "############################################################" LOG_PATTERN=.Rel14.txt -NB_PATTERN_FILES=4 +NB_PATTERN_FILES=7 LOG_FILES=`ls $ARCHIVES_LOC/*.txt` STATUS=0 @@ -204,12 +204,13 @@ then STATUS=-1 fi +echo "COMMAND: build_oai -I -w USRP --eNB" > $ARCHIVES_LOC/build_final_status.log if [ $STATUS -eq 0 ] then - echo "BUILD_OK" > $ARCHIVES_LOC/build_final_status.log + echo "BUILD_OK" >> $ARCHIVES_LOC/build_final_status.log echo "STATUS seems OK" else - echo "BUILD_KO" > $ARCHIVES_LOC/build_final_status.log + echo "BUILD_KO" >> $ARCHIVES_LOC/build_final_status.log echo "STATUS failed?" fi exit $STATUS diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index f9fb3b776f..d4ee84701c 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -94,17 +94,24 @@ function build_on_vm { echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" + acquire_vm_create_lock uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml + echo "Waiting for VM to be started" + uvt-kvm wait $VM_NAME --insecure + + VM_IP_ADDR=`uvt-kvm ip $VM_NAME` + echo "$VM_NAME has for IP addr = $VM_IP_ADDR" + release_vm_create_lock + else + echo "Waiting for VM to be started" + uvt-kvm wait $VM_NAME --insecure + + VM_IP_ADDR=`uvt-kvm ip $VM_NAME` + echo "$VM_NAME has for IP addr = $VM_IP_ADDR" fi - echo "Waiting for VM to be started" - uvt-kvm wait $VM_NAME --insecure - - VM_IP_ADDR=`uvt-kvm ip $VM_NAME` - echo "$VM_NAME has for IP addr = $VM_IP_ADDR" - echo "############################################################" - echo "Copying GIT repo into VM ($VM_NAME)" + echo "Copying GIT repo into VM ($VM_NAME)" echo "############################################################" if [[ "$VM_NAME" == *"-flexran-rtc"* ]] then diff --git a/ci-scripts/checkAddedWarnings.sh b/ci-scripts/checkAddedWarnings.sh index 609261becf..0ffaee9500 100755 --- a/ci-scripts/checkAddedWarnings.sh +++ b/ci-scripts/checkAddedWarnings.sh @@ -95,7 +95,7 @@ fi # Merge request scenario -MERGE_COMMMIT=`git log -n1 | grep commit | sed -e "s@commit @@"` +MERGE_COMMMIT=`git log -n1 --pretty=format:%H` TARGET_INIT_COMMIT=`cat .git/refs/remotes/origin/$TARGET_BRANCH` echo " ---- Checking the modified files by the merge request ----" diff --git a/ci-scripts/checkCodingFormattingRules.sh b/ci-scripts/checkCodingFormattingRules.sh index 61cbf12560..6ac43ca19f 100755 --- a/ci-scripts/checkCodingFormattingRules.sh +++ b/ci-scripts/checkCodingFormattingRules.sh @@ -111,7 +111,7 @@ fi # Merge request scenario -MERGE_COMMMIT=`git log -n1 | grep commit | sed -e "s@commit @@"` +MERGE_COMMMIT=`git log -n1 --pretty=format:%H` TARGET_INIT_COMMIT=`cat .git/refs/remotes/origin/$TARGET_BRANCH` echo " ---- Checking the modified files by the merge request ----" diff --git a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf new file mode 100644 index 0000000000..ea8a56e385 --- /dev/null +++ b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf @@ -0,0 +1,467 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2;} ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNodeB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 13; + downlink_frequency = 751000000L; + uplink_frequency_offset = 31000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 110; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 1; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -24; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = "n64"; #64 + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = "rf128"; #128 + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = "ms1000"; + ue_TimersAndConstants_t301 = "ms1000"; + ue_TimersAndConstants_t310 = "ms1000"; + ue_TimersAndConstants_t311 = "ms10000"; + ue_TimersAndConstants_n310 = "n20"; + ue_TimersAndConstants_n311 = "n1"; + ue_TransmissionMode = "tm1"; + + # eMTC Parameters + emtc_parameters : + { + eMTC_configured = 1; + #hyperSFN_r13 = 0; + #eDRX_Allowed_r13 = 0; + #q_QualMinRSRQ_CE_r13 = ; + + #SIB1 + schedulingInfoSIB1_BR_r13 = 4; + + #system_info_value_tag_SI = + #( + # { + # systemInfoValueTagSi_r13 = 0; + # } + #); + + cellSelectionInfoCE_r13 = "ENABLE"; + q_RxLevMinCE_r13 = -70; + bandwidthReducedAccessRelatedInfo_r13 = "ENABLE" + si_WindowLength_BR_r13 = "ms20"; #0 + si_RepetitionPattern_r13 = "everyRF"; #0 + + scheduling_info_br = + ( + { + si_Narrowband_r13 = 8; + si_TBS_r13 = 5; + } + ); + + fdd_DownlinkOrTddSubframeBitmapBR_r13 = "subframePattern40-r13"; + fdd_DownlinkOrTddSubframeBitmapBR_val_r13 = 0xFFFFFFFFFF; + startSymbolBR_r13 = 2; + si_HoppingConfigCommon_r13 = "off"; #1; # Note: 1==OFF ! + si_ValidityTime_r13 = "true"; #0 + + freqHoppingParametersDL_r13 = "DISABLE" + mpdcch_pdsch_HoppingNB_r13 = "nb2"; #0 + interval_DLHoppingConfigCommonModeA_r13 = "interval-FDD-r13" + interval_DLHoppingConfigCommonModeA_r13_val = 0; + interval_DLHoppingConfigCommonModeB_r13 = "interval-FDD-r13" + interval_DLHoppingConfigCommonModeB_r13_val = 0; + mpdcch_pdsch_HoppingOffset_r13 = 1; + + + # SIB23 + frame_type = "FDD"; + preambleTransMax_CE_r13 = 10; #6 + + rach_numberOfRA_Preambles = 60; #14 + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -110; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 64; + rach_maxHARQ_Msg3Tx = 4; + + # max size for this array is 4 + rach_CE_LevelInfoList_r13 = + ( + { + firstPreamble_r13 = 60; + lastPreamble_r13 = 63; + ra_ResponseWindowSize_r13 = 20; #0 + mac_ContentionResolutionTimer_r13 = 80; #0 + rar_HoppingConfig_r13 = "off"; #1; + } + ); + + # BCCH CONFIG + bcch_modificationPeriodCoeff = 2; + + #PCCH Config + pcch_default_PagingCycle = "rf128"; #128 + pcch_nB = "oneT"; + + #PRACH Config + prach_root = 89; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 1; + + #PDSCH Config Common + pdsch_referenceSignalPower = -24 + pdsch_p_b = 0; + + + # PUSCH Config Common + pusch_n_SB = 1; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_enable64QAM = "DISABLE"; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + + # PUCCH Config Common + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + pucch_deltaF_Format1 = "deltaF0"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + msg3_delta_Preamble = 6; + + + prach_ConfigCommon_v1310 = "ENABLE"; + + mpdcch_startSF_CSS_RA_r13 = "fdd-r13"; + mpdcch_startSF_CSS_RA_r13_val = "v1"; #0 + prach_HoppingOffset_r13 = 0; + + + pdsch_maxNumRepetitionCEmodeA_r13 = "r16"; #0 + #pdsch_maxNumRepetitionCEmodeB_r13 = "r384"; # NULL - 2 + + pusch_maxNumRepetitionCEmodeA_r13 = "r8"; #0 + #pusch_maxNumRepetitionCEmodeB_r13 = "r768"; #4 #NULL + #pusch_HoppingOffset_v1310 = 5; #NULL + + # max size for this array is 3 + rsrp_range_list = + ( + { + rsrp_range_br = 0; + } + ); + + # max size for this array is 4 + prach_parameters_ce_r13 = + ( + { + prach_config_index_br = 3; + prach_freq_offset_br = 2; + prach_StartingSubframe_r13 = 2; + maxNumPreambleAttemptCE_r13 = 10; #6 + numRepetitionPerPreambleAttempt_r13 = 1; #0 + mpdcch_NumRepetition_RA_r13 = 1; #0 + prach_HoppingConfig_r13 = 0; #1 + max_available_narrow_band = [3]; + } + ); + + n1PUCCH_AN_InfoList_r13 = + ( + { + pucch_info_value = 33; + } + ); + + + ue_TimersAndConstants_t300 = "ms1000"; + ue_TimersAndConstants_t301 = "ms400"; + ue_TimersAndConstants_t310 = "ms50"; + ue_TimersAndConstants_t311 = "ms30000"; + ue_TimersAndConstants_n310 = "n1"; + ue_TimersAndConstants_n311 = "n10"; + ue_TransmissionMode = "tm1"; + + pcch_config_v1310 : + { + paging_narrowbands_r13 = 1; + mpdcch_numrepetition_paging_r13 = "r1"; #0 + #nb_v1310 = "one256thT"; #2 + } + + + pucch_NumRepetitionCE_Msg4_Level0_r13 = "n1"; #0 + #pucch_NumRepetitionCE_Msg4_Level1_r13 = "n2"; #1 + #pucch_NumRepetitionCE_Msg4_Level2_r13 = "n16"; #2 + #pucch_NumRepetitionCE_Msg4_Level3_r13 = "n32"; #3 + + sib2_freq_hoppingParameters_r13 : + { + #sib2_mpdcch_pdsch_hoppingNB_r13 = "nb2"; #0 + #sib2_interval_DLHoppingConfigCommonModeA_r13 = "FDD"; # choice -> (0, FDD) (1, TDD) + #sib2_interval_DLHoppingConfigCommonModeA_r13_val = "int1"; + #sib2_interval_DLHoppingConfigCommonModeB_r13 = "FDD"; # choice -> (0, FDD) (1, TDD) + #sib2_interval_DLHoppingConfigCommonModeB_r13_val = "int2"; + + sib2_interval_ULHoppingConfigCommonModeA_r13 = "FDD"; # choice -> (0, FDD) (1, TDD) + sib2_interval_ULHoppingConfigCommonModeA_r13_val = "int4"; #2 +# sib2_interval_ULHoppingConfigCommonModeB_r13 = "FDD"; # choice -> (0, FDD) (1, TDD) +# sib2_interval_ULHoppingConfigCommonModeB_r13_val = "int2"; #0 + +# sib2_mpdcch_pdsch_hoppingOffset_r13 = 1; + } + + rach_preamblesGroupAConfig = "DISABLE"; + + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + + } + + + +} + + + + + ); + + + 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 = "CI_MME_IP_ADDR"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + 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"; + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 200; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [13]; + max_pdschReferenceSignalPower = -24; + max_rxgain = 110; + eNB_instances = [0]; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #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"; + }; diff --git a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf index b6028a8152..1fc3114754 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 10cbd04e9a..2ef30ea4c2 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf index c79dbf1ac0..fbbade22f3 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf index 2c2ca635a6..c119e2f1c0 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf @@ -178,6 +178,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf index 4dd8c1ee22..a0d3ba6d06 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf @@ -178,6 +178,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf index cae47b152c..87beafad6b 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf @@ -178,6 +178,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf index 4e5510b0d4..b006e04e91 100644 --- a/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf @@ -181,6 +181,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; @@ -202,18 +207,18 @@ MACRLCs = ( phy_test_mode = 0; puSch10xSnr = 200; puCch10xSnr = 200; - } + } ); L1s = ( { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_rf = "yes" nb_tx = 2 nb_rx = 2 @@ -224,7 +229,7 @@ RUs = ( max_rxgain = 115; eNB_instances = [0]; } -); +); THREAD_STRUCT = ( { @@ -262,4 +267,3 @@ log_config : rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/lte-fdd-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-basic-sim.conf index 594e3299db..cabbed871a 100644 --- a/ci-scripts/conf_files/lte-fdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-basic-sim.conf @@ -178,6 +178,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { @@ -200,18 +205,18 @@ MACRLCs = ( phy_test_mode = 0; puSch10xSnr = 200; puCch10xSnr = 200; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_rf = "yes" nb_tx = 1 nb_rx = 1 @@ -223,7 +228,7 @@ RUs = ( eNB_instances = [0]; } -); +); THREAD_STRUCT = ( { @@ -261,4 +266,3 @@ NETWORK_CONTROLLER : rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/lte-tdd-basic-sim.conf b/ci-scripts/conf_files/lte-tdd-basic-sim.conf index da330d2379..a376f45453 100644 --- a/ci-scripts/conf_files/lte-tdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-tdd-basic-sim.conf @@ -141,6 +141,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf index 285b7eaf9f..d39f1e0620 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -144,6 +144,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 62e7fb48a4..0ae17356de 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -144,6 +144,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf index f99b701b8e..c58f05c82f 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -144,6 +144,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf index 6c80a4f7cf..6f6aa98788 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf @@ -7,7 +7,7 @@ eNBs = { # real_time choice in {hard, rt-preempt, no} real_time = "no"; - + ////////// Identification parameters: eNB_ID = 0xe00; @@ -181,6 +181,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; @@ -202,18 +207,18 @@ MACRLCs = ( phy_test_mode = 0; puSch10xSnr = 160; puCch10xSnr = 160; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_if_name = "lo"; remote_address = "127.0.0.2"; local_address = "127.0.0.1"; @@ -229,7 +234,7 @@ RUs = ( att_rx = 0; eNB_instances = [0]; } -); +); THREAD_STRUCT = ( { @@ -267,4 +272,3 @@ NETWORK_CONTROLLER : rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf index f4be50810c..ec7fce3dbf 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf @@ -7,7 +7,7 @@ eNBs = { # real_time choice in {hard, rt-preempt, no} real_time = "no"; - + ////////// Identification parameters: eNB_ID = 0xe00; @@ -181,6 +181,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; @@ -202,18 +207,18 @@ MACRLCs = ( phy_test_mode = 0; puSch10xSnr = 160; puCch10xSnr = 160; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_if_name = "lo"; remote_address = "127.0.0.2"; local_address = "127.0.0.1"; @@ -229,7 +234,7 @@ RUs = ( att_rx = 0; eNB_instances = [0]; } -); +); THREAD_STRUCT = ( { @@ -267,4 +272,3 @@ NETWORK_CONTROLLER : rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf index 48c8370b4b..4ebbff4bda 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf @@ -7,7 +7,7 @@ eNBs = { # real_time choice in {hard, rt-preempt, no} real_time = "no"; - + ////////// Identification parameters: eNB_ID = 0xe00; @@ -181,6 +181,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; @@ -202,18 +207,18 @@ MACRLCs = ( phy_test_mode = 0; puSch10xSnr = 160; puCch10xSnr = 160; - } + } ); L1s = ( - { + { num_cc = 1; tr_n_preference = "local_mac"; - } + } ); RUs = ( - { + { local_if_name = "lo"; remote_address = "127.0.0.2"; local_address = "127.0.0.1"; @@ -229,7 +234,7 @@ RUs = ( att_rx = 0; eNB_instances = [0]; } -); +); THREAD_STRUCT = ( { @@ -267,4 +272,3 @@ NETWORK_CONTROLLER : rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf index c2a86f079e..40fba82f9c 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf @@ -179,6 +179,11 @@ eNBs = } ); + ///X2 + enable_x2 = "no"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "ens3"; diff --git a/ci-scripts/conf_files/rru.fdd.band7.conf b/ci-scripts/conf_files/rru.fdd.band7.conf index dab69e1f1e..ea923ae371 100644 --- a/ci-scripts/conf_files/rru.fdd.band7.conf +++ b/ci-scripts/conf_files/rru.fdd.band7.conf @@ -42,4 +42,3 @@ log_config = { rrc_log_level ="error"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/rru.tdd.band40.conf b/ci-scripts/conf_files/rru.tdd.band40.conf index 775a2fbc67..fb2b9399e2 100644 --- a/ci-scripts/conf_files/rru.tdd.band40.conf +++ b/ci-scripts/conf_files/rru.tdd.band40.conf @@ -42,4 +42,3 @@ log_config = { rrc_log_level ="error"; rrc_log_verbosity ="medium"; }; - diff --git a/ci-scripts/conf_files/ue.nfapi.conf b/ci-scripts/conf_files/ue.nfapi.conf index ea0236cab4..355b70326b 100644 --- a/ci-scripts/conf_files/ue.nfapi.conf +++ b/ci-scripts/conf_files/ue.nfapi.conf @@ -17,21 +17,21 @@ log_config = { L1s = ( - { + { num_cc = 1; tr_n_preference = "nfapi"; - local_n_if_name = "lo"; - remote_n_address = "127.0.0.2"; - local_n_address = "127.0.0.1"; - local_n_portc = 50000; - remote_n_portc = 50001; - local_n_portd = 50010; - remote_n_portd = 50011; - } + local_n_if_name = "lo"; + remote_n_address = "127.0.0.2"; + local_n_address = "127.0.0.1"; + local_n_portc = 50000; + remote_n_portc = 50001; + local_n_portd = 50010; + remote_n_portd = 50011; + } ); RUs = ( - { + { local_rf = "yes" nb_tx = 1 nb_rx = 1 @@ -40,5 +40,5 @@ RUs = ( bands = [7,38,42,43]; max_pdschReferenceSignalPower = -27; max_rxgain = 125; - } + } ); diff --git a/ci-scripts/cppcheck_suppressions.list b/ci-scripts/cppcheck_suppressions.list new file mode 100644 index 0000000000..4536f57315 --- /dev/null +++ b/ci-scripts/cppcheck_suppressions.list @@ -0,0 +1,101 @@ +// *INDENT-OFF* cppcheck doesn't like "astyling" this file!!!! +// /* +// * 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 +// */ +//***************************************************************************** +//***************************************************************************** +// section for "valid" memory leaks: the related functions are allocators and +// the caller is responsible of freeing the memory. cppcheck has a mechanism +// to check more accuretaly this, by defining callers responsible of freeing +// but tools like valgring might be more suitable +// +//----------------------------------------------------------------------------- +// suppress error about keysP memory leak, free must be done by calling func +memleak:common/utils/hashtable/obj_hashtable.c +//----------------------------------------------------------------------------- +// suppress error about keys memory leak, free must be done by calling func +memleak:openair2/UTIL/OMG/omg_hashtable.c +//----------------------------------------------------------------------------- +// suppress error about data memory leak. This is the buffer where +// _emm_as_encode function creates the encoded buffer +// +memleak:openair3/NAS/UE/EMM/SAP/emm_as.c +//----------------------------------------------------------------------------- +//***************************************************************************** +// section for files not used in oai exec's included in CI. +// Possibly candidates for removal otherwise should be documented and updated +// for project rules enforcement +// ---------------------------------------------------------------------------- +// likely sources for test programs, maintained? +invalidPrintfArgType_sint:openair1/PHY/CODING/TESTBENCH/ltetest.c +memleak:openair1/PHY/CODING/TESTBENCH/ltetest.c +invalidPrintfArgType_sint:openair1/PHY/CODING/TESTBENCH/pdcch_test.c +// +//----------------------------------------------------------------------------- +// oaisim deprecated, remove? +doubleFree:openair3/TEST/oaisim_mme_list_benchmark.c +// +//----------------------------------------------------------------------------- +// is itti analyzer deprecated +nullPointer:common/utils/itti_analyzer/itti_analyzer.c +nullPointerRedundantCheck:common/utils/itti_analyzer/libbuffers/buffers.c +doubleFree:common/utils/itti_analyzer/libbuffers/socket.c +memleak:common/utils/itti_analyzer/libbuffers/socket.c +memleak:common/utils/itti_analyzer/libparser/array_type.c +memleak:common/utils/itti_analyzer/libui/ui_callbacks.c +//----------------------------------------------------------------------------- +// obviously never even compiled!!! +syntaxError:openair1/SIMULATION/LTE_PHY/dlsim_tm4.c +//----------------------------------------------------------------------------- +// omg, otg commented out in cmakelist to be cleaned up definitely? +arrayIndexOutOfBounds:openair2/UTIL/OMG/omg.c +uninitvar:openair2/UTIL/OTG/otg_rx_socket.c +//----------------------------------------------------------------------------- +// cppcheck is not able to understand that buf is initialized at the first +// iteration of the loop. +nullPointer:common/utils/T/local_tracer.c:243 +//----------------------------------------------------------------------------- +// once again cppcheck does not understand that fds is initialized in the +// first iteration of the loop +nullPointer:common/utils/T/tracer/multi.c:264 +nullPointer:common/utils/T/tracer/multi.c:265 +// +//***************************************************************************** +// +// True problems we don't know how to fix, Suppression is commented out, +// as these kind of problem need either to be fixed or can be suppressed +// when fully uderstood +//----------------------------------------------------------------------------- +// the function [nv]fapi_pnf_p7_config_create should return +// _this. _this points to a structure and a dynamically allocated field is +// returned. cppcheck suspects _this will never be released, so do i +// memleak:nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c +// memleak:nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c +//----------------------------------------------------------------------------- +// may be security_data->kenb.value is released from calling functions. But even +// when, for test, freeing it before returning from emm_proc_security_mode_command +// which does the allocation, cppcheck complains. So something might be wrong... +// memleak:openair3/NAS/UE/EMM/SecurityModeControl.c +//----------------------------------------------------------------------------- +// when used, nobody but the original developer can guess if sn_data_cnf is set or not +// cppcheck found that in some cases it is not, code needs cleanup before fixing that... +// uninitvar:openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +//***************************************************************************** +// *INDENT-ON* diff --git a/ci-scripts/createVM.sh b/ci-scripts/createVM.sh index 192008d867..e693b07b91 100755 --- a/ci-scripts/createVM.sh +++ b/ci-scripts/createVM.sh @@ -49,6 +49,35 @@ function create_usage { echo "" } +function acquire_vm_create_lock { + local FlockFile="/tmp/vmclone.lck" + local unlocked="0" + touch ${FlockFile} 2>/dev/null + if [[ $? -ne 0 ]] + then + echo "Cannot access lock file ${FlockFile}" + exit 2 + fi + while [ $unlocked -eq 0 ] + do + exec 5>${FlockFile} + flock -nx 5 + if [[ $? -ne 0 ]] + then + echo "Another instance of VM creation is running" + sleep 10 + else + unlocked="1" + fi + done + chmod 666 ${FlockFile} 2>/dev/null +} + +function release_vm_create_lock { + local FlockFile="/tmp/vmclone.lck" + rm -Rf ${FlockFile} +} + function create_vm { echo "############################################################" echo "OAI CI VM script" @@ -60,10 +89,12 @@ function create_vm { echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" + acquire_vm_create_lock uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml echo "Waiting for VM to be started" uvt-kvm wait $VM_NAME --insecure VM_IP_ADDR=`uvt-kvm ip $VM_NAME` echo "$VM_NAME has for IP addr = $VM_IP_ADDR" + release_vm_create_lock } diff --git a/ci-scripts/doGitLabMerge.sh b/ci-scripts/doGitLabMerge.sh index 852b6407ea..dd93ff41b7 100755 --- a/ci-scripts/doGitLabMerge.sh +++ b/ci-scripts/doGitLabMerge.sh @@ -103,6 +103,11 @@ esac done +if [[ $TARGET_COMMIT_ID == "latest" ]] +then + TARGET_COMMIT_ID=`git log -n1 --pretty=format:%H origin/$TARGET_BRANCH` +fi + echo "Source Branch is : $SOURCE_BRANCH" echo "Source Commit ID is : $SOURCE_COMMIT_ID" echo "Target Branch is : $TARGET_BRANCH" @@ -121,6 +126,7 @@ git config user.email "jenkins@openairinterface.org" git config user.name "OAI Jenkins" git checkout -f $SOURCE_COMMIT_ID +git log -n1 --pretty=format:\"%s\" > .git/CI_COMMIT_MSG git merge --ff $TARGET_COMMIT_ID -m "Temporary merge for CI" diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 62add8429b..96d7397e46 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -1,4 +1,3 @@ -#/* # * 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. @@ -43,6 +42,9 @@ ENB_PROCESS_SEG_FAULT = -11 ENB_PROCESS_ASSERTION = -12 ENB_PROCESS_REALTIME_ISSUE = -13 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_OK = +2 MME_PROCESS_FAILED = -3 @@ -59,6 +61,7 @@ import re # reg import pexpect # pexpect import time # sleep import os +import subprocess import xml.etree.ElementTree as ET import logging import datetime @@ -99,6 +102,8 @@ class SSHConnection(): self.Initialize_eNB_args = '' self.eNBLogFile = '' self.eNB_instance = '' + self.eNBOptions = '' + self.rruOptions = '' self.ping_args = '' self.ping_packetloss_threshold = '' self.iperf_args = '' @@ -119,12 +124,21 @@ class SSHConnection(): self.htmlTabNames = [] self.htmlTabIcons = [] 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.UESourceCodePath = '' + self.Build_OAI_UE_args = '' + self.Initialize_OAI_UE_args = '' self.eNBOsVersion = '' - self.eNBKernelVersion = '' - self.eNBUhdVersion = '' - self.eNBCpuNb = '' - self.eNBCpuModel = '' - self.eNBCpuMHz = '' def open(self, ipaddress, username, password): count = 0 @@ -320,11 +334,46 @@ class SSHConnection(): 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_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.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) + 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): if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.EPCType == '': Usage() @@ -410,6 +459,7 @@ class SSHConnection(): self.command('cd ' + self.eNBSourceCodePath, '\$', 5) # Initialize_eNB_args usually start with -O and followed by the location in repository full_config_file = self.Initialize_eNB_args.replace('-O ','') + extra_options = '' extIdx = full_config_file.find('.conf') if (extIdx > 0): extra_options = full_config_file[extIdx + 5:] @@ -430,6 +480,16 @@ class SSHConnection(): result = re.search('rru', str(config_file)) if result is not None: 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', '\$', 5) + 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', '\$', 5) # 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_MME_IP_ADDR/' + self.EPCIPAddress + '/\' ' + ci_full_config_file, '\$', 2); @@ -437,12 +497,14 @@ class SSHConnection(): # Launch eNB with the modified config file self.command('source oaienv', '\$', 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('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh ', '\$', 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('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 -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) if not rruCheck: self.eNBLogFile = 'enb_' + self.testCase_id + '.log' + if extra_options != '': + self.eNBOptions = extra_options time.sleep(6) doLoop = True loopCounter = 10 @@ -481,6 +543,8 @@ class SSHConnection(): time.sleep(6) else: doLoop = False + if rruCheck and extra_options != '': + self.rruOptions = extra_options self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK) logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m') @@ -516,6 +580,99 @@ class SSHConnection(): job.join() 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', '\$', 5) + 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.UEPassword + ' | sudo -S sudo b2xx_fx3_utils --reset-device', '\$', 5) + # Reloading FGPA bin firmware + self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 5) + 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 + #full_config_file = self.Initialize_OAI_UE_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.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + self.UESourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '_record.log 2>&1 &', self.UEUserName, 5) + # self.command('cd ' + self.UESourceCodePath, '\$', 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 / UE IP addresses + #self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) + #self.command('sed -i -e \'s/CI_UE_IP_ADDR/' + self.UEIPAddress + '/\' ' + ci_full_config_file, '\$', 2); + # Launch UE with the modified config file + self.command('source oaienv', '\$', 5) + self.command('cd cmake_targets/lte_build_oai/build', '\$', 5) + self.command('echo "ulimit -c unlimited && ./lte-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) + self.command('echo ' + self.UEPassword + ' | sudo -S -E daemon --inherit --unsafe --name=ue' + str(self.UE_instance) + '_daemon --chdir=' + self.UESourceCodePath + '/cmake_targets/lte_build_oai/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): + # In case of T tracer recording, we may need to kill it + #result = re.search('T_stdout', str(self.Initialize_OAI_UE_args)) + #if result is not None: + # self.command('killall --signal SIGKILL record', '\$', 5) + 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) + ## In case of T tracer recording, we need to kill tshark on EPC side + #result = re.search('T_stdout', str(self.Initialize_OAI_UE_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.UEIPAddress, self.UEUserName, self.UEPassword, pcap_log_file, self.UESourceCodePath + '/cmake_targets/.') + sys.exit(1) + else: + self.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) + result = re.search('got sync', str(self.ssh.before)) + if result is None: + time.sleep(6) + 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 checkDevTTYisUnlocked(self): self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) count = 0 @@ -603,21 +760,150 @@ class SSHConnection(): time.sleep(4) # We should check if we register count = 0 - while count < 3: + attach_cnt = 0 + attach_status = False + while count < 5: self.command('AT+CEREG?', 'OK', 5) - result = re.search('CEREG: 2,(?P[0-9\-]+)', str(self.ssh.before)) + result = re.search('CEREG: 2,(?P[0-9\-]+),', str(self.ssh.before)) if result is not None: mDataConnectionState = int(result.group('state')) 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[0-9A-Z]+)","(?P[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: logging.debug(str(self.ssh.before)) + attach_cnt = attach_cnt + 1 count = count + 1 time.sleep(1) + if attach_status: + self.command('AT+CESQ', 'OK', 5) + result = re.search('CESQ: 99,99,255,255,(?P[0-9]+),(?P[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.picocom_closure = False - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + html_queue = SimpleQueue() self.checkDevTTYisUnlocked() + if attach_status: + html_cell = '
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
' + else: + html_cell += '' + html_queue.put(html_cell) + self.CreateHtmlTestRowQueue('N/A', 'OK', 1, html_queue) + else: + html_cell = '
CAT-M module\nAttachment Failed
' + 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[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[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[0-9\.]+)\/(?P[0-9\.]+)\/(?P[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 = '
CAT-M module\nIP Address  : ' + moduleIPAddr + '\n' + qMsg + '
' + 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): try: @@ -1526,6 +1812,48 @@ class SSHConnection(): result = logStatus 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 lte-uesoftmodem', '\$', 5) + result = re.search('lte-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): try: self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) @@ -1614,7 +1942,18 @@ class SSHConnection(): uciStatMsgCount = 0 pdcpFailure = 0 ulschFailure = 0 + self.htmleNBFailureMsg = '' for line in enb_log_file.readlines(): + if self.rruOptions != '': + res1 = re.search('max_rxgain (?P[0-9]+)', self.rruOptions) + res2 = re.search('max_rxgain (?P[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 += ' Command line option(s) correctly applied ' + self.rruOptions + '\n\n' + else: + self.htmleNBFailureMsg += ' Command line option(s) NOT applied ' + self.rruOptions + '\n\n' result = re.search('[Ss]egmentation [Ff]ault', str(line)) if result is not None: foundSegFault = True @@ -1670,7 +2009,6 @@ class SSHConnection(): if result is not None: rachCanceledProcedure += 1 enb_log_file.close() - self.htmleNBFailureMsg = '' if uciStatMsgCount > 0: statMsg = 'eNB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') @@ -1733,6 +2071,156 @@ class SSHConnection(): return ENB_PROCESS_REALTIME_ISSUE 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\d{1,3}), N_RB_DL (?P\d{1,3}), PHICH DURATION (?P\d), PHICH RESOURCE (?P.{1,4}), TX_ANT (?P\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\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[\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\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\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): self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5) @@ -1873,6 +2361,75 @@ class SSHConnection(): job.join() 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) + 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 lte-uesoftmodem || true', '\$', 5) + time.sleep(5) + self.command('stdbuf -o0 ps -aux | grep -v grep | grep lte-uesoftmodem', '\$', 5) + result = re.search('lte-uesoftmodem', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL lte-uesoftmodem || true', '\$', 5) + time.sleep(5) + self.close() + # If tracer options is on, stopping tshark on EPC side + result = re.search('T_stdout', str(self.Initialize_OAI_UE_args)) + if result is not None: + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + logging.debug('\u001B[1m Stopping tshark \u001B[0m') + self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) + time.sleep(1) + pcap_log_file = self.UELogFile.replace('.log', '_s1log.pcap') + self.command('echo ' + self.UEPassword + ' | sudo -S chmod 666 /tmp/' + pcap_log_file, '\$', 5) + self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, '/tmp/' + pcap_log_file, '.') + self.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, pcap_log_file, self.UESourceCodePath + '/cmake_targets/.') + self.close() + logging.debug('\u001B[1m Replaying RAW record file\u001B[0m') + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('cd ' + self.UESourceCodePath + '/common/utils/T/tracer/', '\$', 5) + raw_record_file = self.UELogFile.replace('.log', '_record.raw') + replay_log_file = self.UELogFile.replace('.log', '_replay.log') + extracted_txt_file = self.UELogFile.replace('.log', '_extracted_messages.txt') + extracted_log_file = self.UELogFile.replace('.log', '_extracted_messages.log') + self.command('./extract_config -i ' + self.UESourceCodePath + '/cmake_targets/' + raw_record_file + ' > ' + self.UESourceCodePath + '/cmake_targets/' + extracted_txt_file, '\$', 5) + self.command('echo $USER; nohup ./replay -i ' + self.UESourceCodePath + '/cmake_targets/' + raw_record_file + ' > ' + self.UESourceCodePath + '/cmake_targets/' + replay_log_file + ' 2>&1 &', self.UEUserName, 5) + self.command('./textlog -d ' + self.UESourceCodePath + '/cmake_targets/' + extracted_txt_file + ' -no-gui -ON -full > ' + self.UESourceCodePath + '/cmake_targets/' + extracted_log_file, '\$', 5) + self.close() + self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + extracted_log_file, '.') + logging.debug('\u001B[1m Analyzing UE replay logfile \u001B[0m') + logStatus = self.AnalyzeLogFile_UE(extracted_log_file) + self.CreateHtmlTestRow(html_queue, 'OK', ALL_PROCESSES_OK) + self.UELogFile = '' + else: + 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 = '
Could not copy UE logfile to analyze it!
' + 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 = '
Sniffing Unsuccessful\n'
+					optionsMsg += self.htmlUEFailureMsg
+					optionsMsg += '
' + self.CreateHtmlTestRow(optionsMsg, 'KO', logStatus, 'UE') + self.CreateHtmlTabFooter(False) + sys.exit(1) + else: + optionsMsg = '
Sniffing Successful\n'
+					optionsMsg += self.htmlUEFailureMsg
+					optionsMsg += '
' + self.CreateHtmlTestRow(optionsMsg, 'OK', ALL_PROCESSES_OK) + self.UELogFile = '' + else: + self.CreateHtmlTestRow('
No Log File to analyze
', 'OK', ALL_PROCESSES_OK) + def AutoTerminateUEandeNB(self): self.testCase_id = 'AUTO-KILL-UE' self.desc = 'Automatic Termination of UE' @@ -1889,12 +2446,24 @@ class SSHConnection(): self.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', ALL_PROCESSES_OK) def LogCollectBuild(self): - self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) - self.command('cd ' + self.eNBSourceCodePath, '\$', 5) + if (self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != ''): + 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('rm -f build.log.zip', '\$', 5) self.command('zip build.log.zip build_log_*/*', '\$', 60) - self.command('echo ' + self.eNBPassword + ' | sudo -S rm -rf build_log_*', '\$', 5) + self.command('echo ' + Password + ' | sudo -S rm -rf build_log_*', '\$', 5) self.close() def LogCollecteNB(self): @@ -1962,35 +2531,70 @@ class SSHConnection(): self.command('cp /opt/ltebox/var/log/xGwLog.0 .', '\$', 5) self.command('zip spgw.log.zip xGwLog.0', '\$', 60) 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): - if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '': + if self.eNBIPAddress == 'none': + self.OsVersion = 'Ubuntu 16.04.5 LTS' + self.KernelVersion = '4.15.0-45-generic' + self.UhdVersion = '3.13.0.1-0' + self.UsrpBoard = 'B210' + self.CpuNb = '4' + self.CpuModel = 'Intel(R) Core(TM) i5-6200U' + self.CpuMHz = '2399.996 MHz' + return + 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() sys.exit('Insufficient Parameter') - self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) + self.open(IPAddress, UserName, Password) self.command('lsb_release -a', '\$', 5) result = re.search('Description:\\\\t(?P[a-zA-Z0-9\-\_\.\ ]+)', str(self.ssh.before)) if result is not None: - self.eNBOsVersion = result.group('os_type') - logging.debug('OS is: ' + self.eNBOsVersion) + self.OsVersion = result.group('os_type') + logging.debug('OS is: ' + self.OsVersion) self.command('uname -r', '\$', 5) result = re.search('uname -r\\\\r\\\\n(?P[a-zA-Z0-9\-\_\.]+)', str(self.ssh.before)) if result is not None: - self.eNBKernelVersion = result.group('kernel_version') - logging.debug('Kernel Version is: ' + self.eNBKernelVersion) + self.KernelVersion = result.group('kernel_version') + logging.debug('Kernel Version is: ' + self.KernelVersion) self.command('dpkg --list | egrep --color=never libuhd003', '\$', 5) result = re.search('libuhd003:amd64 *(?P[0-9\.]+)', str(self.ssh.before)) if result is not None: - self.eNBUhdVersion = result.group('uhd_version') - logging.debug('UHD Version is: ' + self.eNBUhdVersion) + self.UhdVersion = result.group('uhd_version') + logging.debug('UHD Version is: ' + self.UhdVersion) + self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 5) + result = re.search('product: (?P[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) result = re.search('CPU\(s\): *(?P[0-9]+).*Model name: *(?P[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P[0-9\.]+)', str(self.ssh.before)) if result is not None: - self.eNBCpuNb = result.group('nb_cpus') - logging.debug('nb_cpus: ' + self.eNBCpuNb) - self.eNBCpuModel = result.group('model') - logging.debug('model: ' + self.eNBCpuModel) - self.eNBCpuMHz = result.group('cpu_mhz') + ' MHz' - logging.debug('cpu_mhz: ' + self.eNBCpuMHz) + self.CpuNb = result.group('nb_cpus') + logging.debug('nb_cpus: ' + self.CpuNb) + self.CpuModel = result.group('model') + logging.debug('model: ' + self.CpuModel) + self.CpuMHz = result.group('cpu_mhz') + ' MHz' + logging.debug('cpu_mhz: ' + self.CpuMHz) self.close() #----------------------------------------------------------- @@ -1998,6 +2602,9 @@ class SSHConnection(): #----------------------------------------------------------- def CreateHtmlHeader(self): 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.write('\n') self.htmlFile.write('\n') @@ -2055,6 +2662,16 @@ class SSHConnection(): self.htmlFile.write(' Commit ID \n') self.htmlFile.write(' ' + self.eNBCommitID + '\n') self.htmlFile.write(' \n') + if self.eNB_AllowMerge != '': + commit_message = subprocess.check_output("git log -n1 --pretty=format:\"%s\" " + self.eNBCommitID, shell=True, universal_newlines=True) + commit_message = commit_message.strip() + self.htmlFile.write(' \n') + if (self.eNB_AllowMerge): + self.htmlFile.write(' Source Commit Message \n') + else: + self.htmlFile.write(' Commit Message \n') + self.htmlFile.write(' ' + commit_message + '\n') + self.htmlFile.write(' \n') if (self.eNB_AllowMerge): self.htmlFile.write(' \n') self.htmlFile.write(' Target Branch \n') @@ -2065,18 +2682,13 @@ class SSHConnection(): self.htmlFile.write(' \n') self.htmlFile.write(' \n') - terminate_ue_flag = True if (self.ADBIPAddress != 'none'): + terminate_ue_flag = True self.GetAllUEDevices(terminate_ue_flag) self.GetAllCatMDevices(terminate_ue_flag) - else: - self.UEDevices.append('doughq9rehg') - self.UEDevices.append('dnsgiuahgia') - self.UEDevices.append('uehgieng9') - self.htmlUEConnected = len(self.UEDevices) - - self.htmlFile.write('

' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server

\n') - self.htmlFile.write('

' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server

\n') + self.htmlUEConnected = len(self.UEDevices) + self.htmlFile.write('

' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server

\n') + self.htmlFile.write('

' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server

\n') self.htmlFile.write('
\n') self.htmlFile.write('