diff --git a/.gitignore b/.gitignore index 2adc5d457c..06a51f1b64 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,9 @@ +# vim swp +*.swp + +# log and exec file cmake_targets/log/ cmake_targets/*/build/ -targets/bin/ - +log/ +lte_build_oai/ +targets/bin/ \ No newline at end of file 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 64c5cc0f58..9a3b759915 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 b5c34d5b81..2a27673686 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -31,16 +31,20 @@ 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 gNb-usrp", "Build nr-UE-usrp", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test-FDD-Band7", "Test-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40"]) + gitlabBuilds(builds: ["Build basic-sim", "Build gNb-usrp", "Build nr-UE-usrp", "Build eNb-USRP", "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') } @@ -69,6 +73,12 @@ pipeline { } else { doRedHatBuild = false } + if (params.FlexRanRtcGitLabRepository_Credentials != null) { + doFlexranCtrlTest = true + } + if (fileExists("flexran")) { + sh "rm -Rf flexran > /dev/null 2>&1" + } } } } @@ -78,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}" @@ -97,12 +110,29 @@ 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 // For the moment, there is no fail criteria. Just a notification of number of files that do not follow sh "./ci-scripts/checkCodingFormattingRules.sh" } + if (doFlexranCtrlTest) { + sh "mkdir flexran" + dir ('flexran') { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.FlexRanRtcGitLabRepository_Credentials}", usernameVariable: 'git_username', passwordVariable: 'git_password'] + ]) { + sh "git clone https://${git_username}:${git_password}@gitlab.eurecom.fr/flexran/flexran-rtc.git . > ../git_clone.log 2>&1" + } + sh "sed -i -e 's#add-apt-repository.*cleishm.*neo4j#add-apt-repository ppa:cleishm/neo4j -y#' -e 's#libneo4j-client-dev#libneo4j-client-dev -y#' tools/install_dependencies" + sh "zip -r -qq flexran.zip ." + } + } } } post { @@ -110,6 +140,7 @@ pipeline { script { def message = "OAI " + JOB_NAME + " build (" + BUILD_ID + "): Merge Conflicts -- Cannot perform CI" addGitLabMRComment comment: message + currentBuild.result = 'FAILURE' } } } @@ -147,6 +178,14 @@ pipeline { } } + stage ("Start VM -- phy-sim") { + steps { + timeout (time: 5, unit: 'MINUTES') { + sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" + } + } + } + stage ("Start VM -- enb-ethernet") { steps { timeout (time: 5, unit: 'MINUTES') { @@ -162,15 +201,7 @@ pipeline { } } } - - stage ("Start VM -- phy-sim") { - steps { - timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" - } - } - } - + stage ("Start VM -- cppcheck") { steps { timeout (time: 5, unit: 'MINUTES') { @@ -190,15 +221,6 @@ pipeline { } } } - stage ("Build eNb-USRP") { - steps { - gitlabCommitStatus(name: "Build eNb-USRP") { - timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } - } - } - } stage ("Build basic simulator") { steps { gitlabCommitStatus(name: "Build basic-sim") { @@ -208,29 +230,11 @@ pipeline { } } } - stage ("Build eNb-ethernet") { - steps { - gitlabCommitStatus(name: "Build eNb-ethernet") { - timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } - } - } - } - stage ("Build UE-ethernet") { - steps { - gitlabCommitStatus(name: "Build UE-ethernet") { - timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } - } - } - } stage ("Build 5G gNB-USRP") { steps { gitlabCommitStatus(name: "Build gNb-usrp") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } @@ -239,7 +243,16 @@ pipeline { steps { gitlabCommitStatus(name: "Build nr-UE-usrp") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } + } + } + } + stage ("Build eNb-USRP") { + steps { + gitlabCommitStatus(name: "Build eNb-USRP") { + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } @@ -253,12 +266,30 @@ pipeline { } } } + stage ("Build eNb-ethernet") { + steps { + gitlabCommitStatus(name: "Build eNb-ethernet") { + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } + } + } + } + stage ("Build UE-ethernet") { + steps { + gitlabCommitStatus(name: "Build UE-ethernet") { + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } + } + } + } stage ("Build eNb-USRP on Red Hat") { when { expression {doRedHatBuild} } steps { - gitlabCommitStatus(name: "Build eNb-USRP-CentOS") { + gitlabCommitStatus(name: "Build eNb-USRP-RHE") { script { try { withCredentials([ @@ -269,7 +300,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" } } } @@ -277,6 +308,11 @@ pipeline { } } post { + failure { + script { + currentBuild.result = 'FAILURE' + } + } always { script { dir ('archives') { @@ -287,6 +323,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)) { @@ -310,158 +357,159 @@ pipeline { stage ("Variant Tests") { parallel { - stage ("Test physical simulators") { - steps { - gitlabCommitStatus(name: "Test phy-sim") { - timeout (time: 45, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } - } - } - } - stage ("Test basic simulator") { - steps { - gitlabCommitStatus(name: "Test basic-sim") { - timeout (time: 20, 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 FDD - Band 7 - B210") { - steps { - script { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-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), - string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) - ] - } - } else { - gitlabCommitStatus(name: "Test-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(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-FDD-Band7-B210.html')) { - copyArtifacts(projectName: 'eNB-CI-FDD-Band7-B210', - filter: 'test_results*.html', - selector: lastCompleted()) - if (fileExists('test_results-eNB-CI-FDD-Band7-B210.html')) { - sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-FDD-Band7-B210.html" - archiveArtifacts artifacts: 'test_results-eNB-CI-FDD-Band7-B210.html' + 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 ("Test TDD - Band 40 - B210") { - steps { - script { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-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), - string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) - ] - } - } else { - gitlabCommitStatus(name: "Test-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(GIT_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), - booleanParam(name: 'eNB_mergeRequest', value: false) - ] + 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' + } + } } } } - } - 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-TDD-Band40-B210.html')) { - copyArtifacts(projectName: 'eNB-CI-TDD-Band40-B210', - filter: 'test_results*.html', - selector: lastCompleted()) - if (fileExists('test_results-eNB-CI-TDD-Band40-B210.html')) { - sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-TDD-Band40-B210.html" - archiveArtifacts artifacts: 'test_results-eNB-CI-TDD-Band40-B210.html' + 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 L1 simulator") { + steps { + script { + timeout (time: 30, unit: 'MINUTES') { + try { + gitlabCommitStatus(name: "Test L1-sim") { + sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l1-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } + } catch (Exception e) { + currentBuild.result = 'FAILURE' + } + } + } + } + } + stage ("Test RF simulator") { + steps { + script { + timeout (time: 30, unit: 'MINUTES') { + try { + gitlabCommitStatus(name: "Test RF-sim") { + sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant rf-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } + } 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 ("Destroy all Virtual Machines") { + steps { + sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + } + } + } + } + stage ("Test MONOLITHIC - FDD - Band 7 - B210") { + steps { + script { + triggerSlaveJob ('eNB-CI-FDD-Band7-B210', 'Test-Mono-FDD-Band7') + } + } + post { + always { + script { + finalizeSlaveJob('eNB-CI-FDD-Band7-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } + stage ("Test MONOLITHIC - TDD - Band 40 - B210") { + steps { + script { + triggerSlaveJob ('eNB-CI-TDD-Band40-B210', 'Test-Mono-TDD-Band40') + } + } + post { + always { + script { + finalizeSlaveJob('eNB-CI-TDD-Band40-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } } } stage ("Test IF4p5 - FDD - Band 7 - B210") { steps { script { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-IF4p5-FDD-Band7") { - build job: 'eNB-CI-IF4p5-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), - string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) - ] - } - } else { - gitlabCommitStatus(name: "Test-IF4p5-FDD-Band7") { - build job: 'eNB-CI-IF4p5-FDD-Band7-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) - ] - } - } + triggerSlaveJob ('eNB-CI-IF4p5-FDD-Band7-B210', 'Test-IF4p5-FDD-Band7') } } 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-IF4p5-FDD-Band7-B210.html')) { - copyArtifacts(projectName: 'eNB-CI-IF4p5-FDD-Band7-B210', - filter: 'test_results*.html', - selector: lastCompleted()) - if (fileExists('test_results-eNB-CI-IF4p5-FDD-Band7-B210.html')) { - sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-IF4p5-FDD-Band7-B210.html" - archiveArtifacts artifacts: 'test_results-eNB-CI-IF4p5-FDD-Band7-B210.html' - } - } + finalizeSlaveJob('eNB-CI-IF4p5-FDD-Band7-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' } } } @@ -469,45 +517,77 @@ pipeline { stage ("Test IF4p5 - TDD - Band 40 - B210") { steps { script { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-IF4p5-TDD-Band40") { - build job: 'eNB-CI-IF4p5-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), - string(name: 'eNB_TargetBranch', value: String.valueOf(env.gitlabTargetBranch)) - ] - } - } else { - gitlabCommitStatus(name: "Test-IF4p5-TDD-Band40") { - build job: 'eNB-CI-IF4p5-TDD-Band40-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) - ] - } - } + triggerSlaveJob ('eNB-CI-IF4p5-TDD-Band40-B210', 'Test-IF4p5-TDD-Band40') } } 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-IF4p5-TDD-Band40-B210.html')) { - copyArtifacts(projectName: 'eNB-CI-IF4p5-TDD-Band40-B210', - filter: 'test_results*.html', - selector: lastCompleted()) - if (fileExists('test_results-eNB-CI-IF4p5-TDD-Band40-B210.html')) { - sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-IF4p5-TDD-Band40-B210.html" - archiveArtifacts artifacts: 'test_results-eNB-CI-IF4p5-TDD-Band40-B210.html' - } - } + finalizeSlaveJob('eNB-CI-IF4p5-TDD-Band40-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } + stage ("Test MONOLITHIC - FDD - Band 13 - B210") { + steps { + script { + triggerSlaveJob ('eNB-CI-MONO-FDD-Band13-B210', 'Test-Mono-FDD-Band13') + } + } + post { + always { + script { + finalizeSlaveJob('eNB-CI-MONO-FDD-Band13-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } + stage ("Test OAI UE - FDD - Band 20 - B200") { + steps { + script { + triggerSlaveJobNoGitLab ('UE-CI-FDD-Band20-B200') + } + } + post { + always { + script { + finalizeSlaveJob('UE-CI-FDD-Band20-B200') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } + stage ("Test OAI UE - OAI eNB - FDD - Band 7 - B200") { + steps { + script { + // Delayed trigger on slave job, so it is always the last one to run + sh "sleep 240" + triggerSlaveJob ('eNB-UE-CI-MONO-FDD-Band7-B200', 'Test-eNB-OAI-UE-FDD-Band7') + } + } + post { + always { + script { + finalizeSlaveJob('eNB-UE-CI-MONO-FDD-Band7-B200') + } + } + failure { + script { + currentBuild.result = 'FAILURE' } } } @@ -517,7 +597,7 @@ pipeline { always { script { dir ('archives') { - sh "if [ -d basic_sim/test ] || [ -d phy_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi" + sh "if [ -d basic_sim/test ] || [ -d phy_sim/test ] || [ -d l2_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi" } if(fileExists('archives/vm_tests_logs.zip')) { archiveArtifacts artifacts: 'archives/vm_tests_logs.zip' @@ -535,11 +615,6 @@ pipeline { } } } - stage ("Destroy all Virtual Machines") { - steps { - sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } - } } post { always { @@ -548,13 +623,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 { @@ -585,3 +665,66 @@ OAI CI Team''', } } } + +// ---- Slave Job functions + +def triggerSlaveJob (jobName, gitlabStatusName) { + if ("MERGE".equals(env.gitlabActionType)) { + gitlabCommitStatus(name: gitlabStatusName) { + build job: jobName, + 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: gitlabStatusName) { + build job: jobName, + 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) + ] + } + } +} + +def triggerSlaveJobNoGitLab (jobName) { + if ("MERGE".equals(env.gitlabActionType)) { + build job: jobName, + 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 { + build job: jobName, + 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) + ] + } +} + +def finalizeSlaveJob(jobName) { + // 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 + fileName = "test_results-${jobName}.html" + if (!fileExists(fileName)) { + copyArtifacts(projectName: jobName, + filter: 'test_results*.html', + selector: lastCompleted()) + if (fileExists(fileName)) { + sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' ${fileName}" + archiveArtifacts artifacts: fileName + } + } +} \ No newline at end of file diff --git a/ci-scripts/Jenkinsfile-tmp-full-ran b/ci-scripts/Jenkinsfile-tmp-full-ran new file mode 100644 index 0000000000..4ade6086e8 --- /dev/null +++ b/ci-scripts/Jenkinsfile-tmp-full-ran @@ -0,0 +1,430 @@ +#!/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 + +// Name of the phone resource +def oaiUEResource = params.oaiUEResource + +// Terminate Status +def termENB = 0 +def termOAIUE = 1 +def termStatusArray = new Boolean[termOAIUE + 1] +termStatusArray[termENB] = false +termStatusArray[termOAIUE] = 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(extra: [[resource: ciSmartPhoneResource]], resource: ciSmartPhoneResource) + } + + 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.oaiUEResource == null) { + allParametersPresent = false + } + if (params.eNB_IPAddress == null) { + allParametersPresent = false + } + if (params.eNB_SourceCodePath == null) { + allParametersPresent = false + } + if (params.eNB_Credentials == null) { + allParametersPresent = false + } + if (params.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.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_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=TesteNB --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password} --UESourceCodePath=${params.UE_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) { + currentBuild.result = 'FAILURE' + buildStageStatus = false + } + } + } + sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password}" + } + } + } + } + } + stage ("Terminate") { + parallel { + stage('Terminate eNB') { + steps { + echo '\u2705 \u001B[32mTerminate eNB\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateeNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}" + } + } + post { + success { + script { + termStatusArray[termENB] = true + } + } + } + } + stage('Terminate OAI-UE') { + steps { + echo '\u2705 \u001B[32mTerminate OAI-UE\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateOAIUE --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_Password}" + } + } + post { + success { + script { + termStatusArray[termOAIUE] = true + } + } + } + } + } + } + stage('Log Collection') { + parallel { + stage('Log Collection (eNB - Run)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}" + + echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m' + sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("enb.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "enb.log.${env.BUILD_ID}.zip" + } + if(fileExists("ci-scripts/test_results.html")) { + sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html" + sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html" + archiveArtifacts "test_results-${JOB_NAME}.html" + } + } + } + } + stage('Log Collection (OAI UE - Run)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (OAI UE - Run)\u001B[0m' + 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 (OAI 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" + } + } + } + } + stage('Log Collection (Ping)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (Ping)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectPing --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (Ping)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/ping.log.zip ./ping.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("ping.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "ping.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (Iperf)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (Iperf)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectIperf --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (Iperf)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/iperf.log.zip ./iperf.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("iperf.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "iperf.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (SPGW)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (SPGW)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectSPGW --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (SPGW)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/spgw.log.zip ./spgw.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("spgw.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "spgw.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (MME)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (MME)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectMME --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (MME)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/mme.log.zip ./mme.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("mme.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "mme.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (HSS)') { + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (HSS)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectHSS --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (HSS)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/hss.log.zip ./hss.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("hss.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "hss.log.${env.BUILD_ID}.zip" + } + } + } + } + } + } + } + + 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" + } + } + } + } + } + // Making sure that we really shutdown every thing before leaving + failure { + script { + if (!termStatusArray[termENB]) { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateeNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}" + } + } + if (!termStatusArray[termOAIUE]) { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.UE_Credentials}", usernameVariable: 'UE_Username', passwordVariable: 'UE_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateOAIUE --UEIPAddress=${params.UE_IPAddress} --UEUserName=${UE_Username} --UEPassword=${UE_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/add_user_to_conf_file.awk b/ci-scripts/add_user_to_conf_file.awk new file mode 100644 index 0000000000..b338d5e7ac --- /dev/null +++ b/ci-scripts/add_user_to_conf_file.awk @@ -0,0 +1,33 @@ +BEGIN{lineIdx=0;captureUEDesc=0} +{ + if ($0 ~/UE0/) { + captureUEDesc = 1 + } + if (captureUEDesc == 1) { + captureLine[lineIdx] = $0 + lineIdx = lineIdx + 1 + } + print $0 +} +END { + for (ueIdx = 1; ueIdx < num_ues; ueIdx++) { + print "" + for (k = 0; k < lineIdx; k++) { + if (captureLine[k] ~/UE0/) { + mLine = captureLine[k] + gsub("UE0", "UE"ueIdx, mLine) + print mLine + } else { + if (captureLine[k] ~/MSIN=/) { + mLine = captureLine[k] + MSIN=sprintf("%08d", 1111+int(ueIdx)) + gsub("00001111", MSIN, mLine) + print mLine + } else { + print captureLine[k] + } + } + + } + } +} diff --git a/ci-scripts/add_user_to_subscriber_list.awk b/ci-scripts/add_user_to_subscriber_list.awk new file mode 100644 index 0000000000..1e25990f59 --- /dev/null +++ b/ci-scripts/add_user_to_subscriber_list.awk @@ -0,0 +1,27 @@ +BEGIN{lineIdx=0} +{ + captureLine[lineIdx] = $0 + lineIdx = lineIdx + 1 + print $0 +} +END{ + for (ueIdx = 1; ueIdx < num_ues; ueIdx++) { + for (k = 0; k < lineIdx; k++) { + if (captureLine[k] ~/UserName=/) { + mLine = captureLine[k] + MSIN=sprintf("%08d", 1111+int(ueIdx)) + gsub("00001111", MSIN, mLine) + print mLine + } else { + if (captureLine[k] ~/SubscriptionIndex/) { + mLine = captureLine[k] + MSIN=sprintf("%d", 111+int(ueIdx)) + gsub("111", MSIN, mLine) + print mLine + } else { + print captureLine[k] + } + } + } + } +} diff --git a/ci-scripts/buildOnRH.sh b/ci-scripts/buildOnRH.sh index 207110fb54..076f34f8d2 100755 --- a/ci-scripts/buildOnRH.sh +++ b/ci-scripts/buildOnRH.sh @@ -179,8 +179,8 @@ echo "############################################################" echo "Checking build status" echo "############################################################" -LOG_PATTERN=.Rel15.txt -NB_PATTERN_FILES=4 +LOG_PATTERN=.Rel14.txt +NB_PATTERN_FILES=7 LOG_FILES=`ls $ARCHIVES_LOC/*.txt` STATUS=0 @@ -198,12 +198,19 @@ do fi done -if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]; then STATUS=-1; fi +if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ] +then + echo "Expecting $NB_PATTERN_FILES log files and found $NB_FOUND_FILES" + 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 "STATUS seems OK" else + 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 ec774a00ea..ee5fc56c5f 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -111,9 +111,14 @@ function build_on_vm { fi echo "############################################################" - echo "Copying GIT repo into VM ($VM_NAME)" + echo "Copying GIT repo into VM ($VM_NAME)" echo "############################################################" - scp -o StrictHostKeyChecking=no $JENKINS_WKSP/localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu + if [[ "$VM_NAME" == *"-flexran-rtc"* ]] + then + scp -o StrictHostKeyChecking=no $JENKINS_WKSP/flexran/flexran.zip ubuntu@$VM_IP_ADDR:/home/ubuntu/localZip.zip + else + scp -o StrictHostKeyChecking=no $JENKINS_WKSP/localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu + fi scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu echo "############################################################" @@ -133,7 +138,22 @@ function build_on_vm { echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS echo "sudo apt-get --yes install zip daemon cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS fi - else + fi + if [[ "$VM_NAME" == *"-flexran-rtc"* ]] + then + if [ $DAEMON -eq 0 ] + then + echo "echo \"sudo apt-get --yes --quiet install zip curl jq \"" >> $VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS + echo "sudo apt-get --yes install zip curl jq >> zip-install.txt 2>&1" >> $VM_CMDS + else + echo "echo \"sudo apt-get --yes --quiet install zip daemon curl jq \"" >> $VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS + echo "sudo apt-get --yes install zip daemon curl jq >> zip-install.txt 2>&1" >> $VM_CMDS + fi + fi + if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]] + then if [ $DAEMON -eq 0 ] then echo "echo \"sudo apt-get --yes --quiet install zip subversion libboost-dev \"" >> $VM_CMDS @@ -163,7 +183,19 @@ function build_on_vm { echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp -O /home/ubuntu/tmp/cmake_targets/log/cppcheck_build.txt -E /home/ubuntu/tmp/cmake_targets/log/cppcheck.xml ./my-vm-build.sh" >> $VM_CMDS fi - else + fi + if [[ "$VM_NAME" == *"-flexran-rtc"* ]] + then + echo "mkdir -p cmake_targets/log" >> $VM_CMDS + echo "chmod 777 cmake_targets/log" >> $VM_CMDS + echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS + echo "echo \"./tools/install_dependencies \"" >> $VM_CMDS + echo "./tools/install_dependencies > cmake_targets/log/install-build.txt 2>&1" >> $VM_CMDS + echo "echo \"$BUILD_OPTIONS \"" >> $VM_CMDS + echo "$BUILD_OPTIONS > cmake_targets/log/rt_controller.Rel14.txt 2>&1" >> $VM_CMDS + fi + if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]] + then echo "echo \"source oaienv\"" >> $VM_CMDS echo "source oaienv" >> $VM_CMDS echo "cd cmake_targets/" >> $VM_CMDS @@ -181,6 +213,6 @@ function build_on_vm { echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh" >> $VM_CMDS fi fi - ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS + ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS rm -f $VM_CMDS } diff --git a/ci-scripts/checkAddedWarnings.sh b/ci-scripts/checkAddedWarnings.sh index 1e0f700ec2..d366059a85 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/cu.band7.tm1.100PRB.conf b/ci-scripts/conf_files/cu.band7.tm1.100PRB.conf new file mode 100644 index 0000000000..becd484c56 --- /dev/null +++ b/ci-scripts/conf_files/cu.band7.tm1.100PRB.conf @@ -0,0 +1,221 @@ +Active_eNBs = ( "eNB-CU-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-CU-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ) + + nr_cellid = 12345678L + + tr_s_preference = "f1" + + local_s_if_name = "lo"; + remote_s_address = "127.0.0.3"; + local_s_address = "127.0.0.4"; + local_s_portc = 501; + remote_s_portc = 500; + local_s_portd = 601; + remote_s_portd = 600; + + ////////// 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 = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 100; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnable = "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 = 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 = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff= 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + /* + rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; + */ + + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + } + ); + + + 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"; + } + ); + + 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"; + pdcp_log_level = "info"; + pdcp_log_verbosity = "high"; + rrc_log_level = "info"; + rrc_log_verbosity = "medium"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; + gtp_log_level = "info"; + gtp_log_verbosity = "medium"; +}; + +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"; +}; diff --git a/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf b/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf new file mode 100644 index 0000000000..7e4dfc6de6 --- /dev/null +++ b/ci-scripts/conf_files/cu.band7.tm1.25PRB.conf @@ -0,0 +1,221 @@ +Active_eNBs = ( "eNB-CU-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-CU-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ) + + nr_cellid = 12345678L + + tr_s_preference = "f1" + + local_s_if_name = "lo"; + remote_s_address = "127.0.0.3"; + local_s_address = "127.0.0.4"; + local_s_portc = 501; + remote_s_portc = 500; + local_s_portd = 601; + remote_s_portd = 600; + + ////////// 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 = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -25; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnable = "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 = 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 = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff= 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + /* + rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; + */ + + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + } + ); + + + 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"; + } + ); + + 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"; + pdcp_log_level = "info"; + pdcp_log_verbosity = "high"; + rrc_log_level = "info"; + rrc_log_verbosity = "medium"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; + gtp_log_level = "info"; + gtp_log_verbosity = "medium"; +}; + +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"; +}; diff --git a/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf b/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf new file mode 100644 index 0000000000..b1c4774aba --- /dev/null +++ b/ci-scripts/conf_files/cu.band7.tm1.50PRB.conf @@ -0,0 +1,221 @@ +Active_eNBs = ( "eNB-CU-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-CU-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ) + + nr_cellid = 12345678L + + tr_s_preference = "f1" + + local_s_if_name = "lo"; + remote_s_address = "127.0.0.3"; + local_s_address = "127.0.0.4"; + local_s_portc = 501; + remote_s_portc = 500; + local_s_portd = 601; + remote_s_portd = 600; + + ////////// 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 = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnable = "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 = 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 = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff= 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + /* + rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; + */ + + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + } + ); + + + 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"; + } + ); + + 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"; + pdcp_log_level = "info"; + pdcp_log_verbosity = "high"; + rrc_log_level = "info"; + rrc_log_verbosity = "medium"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; + gtp_log_level = "info"; + gtp_log_verbosity = "medium"; +}; + +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"; +}; diff --git a/ci-scripts/conf_files/du.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/du.band7.tm1.100PRB.usrpb210.conf new file mode 100644 index 0000000000..fe994ef889 --- /dev/null +++ b/ci-scripts/conf_files/du.band7.tm1.100PRB.usrpb210.conf @@ -0,0 +1,119 @@ +Active_eNBs = ( "eNB-Eurecom-DU"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_CU_ID = 0xe00; + + eNB_name = "eNB-Eurecom-DU"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ) + + nr_cellid = 12345678L + + ////////// 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 = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 100; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 115; + + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + } + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "f1"; + local_n_if_name = "lo"; + remote_n_address = "127.0.0.4"; + local_n_address = "127.0.0.3"; + local_n_portc = 500; + remote_n_portc = 501; + local_n_portd = 600; + remote_n_portd = 601; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes"; + nb_tx = 1; + nb_rx = 1; + att_tx = 10; + att_rx = 10; + bands = [7]; + max_pdschReferenceSignalPower = -29; + max_rxgain = 115; + eNB_instances = [0]; + } +); + +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"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; +}; + +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"; +}; diff --git a/ci-scripts/conf_files/du.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/du.band7.tm1.25PRB.usrpb210.conf new file mode 100644 index 0000000000..85407e3f35 --- /dev/null +++ b/ci-scripts/conf_files/du.band7.tm1.25PRB.usrpb210.conf @@ -0,0 +1,119 @@ +Active_eNBs = ( "eNB-Eurecom-DU"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_CU_ID = 0xe00; + + eNB_name = "eNB-Eurecom-DU"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ) + + nr_cellid = 12345678L + + ////////// 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 = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + } + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "f1"; + local_n_if_name = "lo"; + remote_n_address = "127.0.0.4"; + local_n_address = "127.0.0.3"; + local_n_portc = 500; + remote_n_portc = 501; + local_n_portd = 600; + remote_n_portd = 601; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes"; + nb_tx = 1; + nb_rx = 1; + att_tx = 10; + att_rx = 10; + bands = [7]; + max_pdschReferenceSignalPower = -25; + max_rxgain = 125; + eNB_instances = [0]; + } +); + +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"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; +}; + +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"; +}; diff --git a/ci-scripts/conf_files/du.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/du.band7.tm1.50PRB.usrpb210.conf new file mode 100644 index 0000000000..3e97f58068 --- /dev/null +++ b/ci-scripts/conf_files/du.band7.tm1.50PRB.usrpb210.conf @@ -0,0 +1,119 @@ +Active_eNBs = ( "eNB-Eurecom-DU"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_CU_ID = 0xe00; + + eNB_name = "eNB-Eurecom-DU"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ) + + nr_cellid = 12345678L + + ////////// 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 = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + 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 = 120; + + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + } + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "f1"; + local_n_if_name = "lo"; + remote_n_address = "127.0.0.4"; + local_n_address = "127.0.0.3"; + local_n_portc = 500; + remote_n_portc = 501; + local_n_portd = 600; + remote_n_portd = 601; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes"; + nb_tx = 1; + nb_rx = 1; + att_tx = 10; + att_rx = 10; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 120; + eNB_instances = [0]; + } +); + +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"; + flexran_agent_log_level = "info"; + flexran_agent_log_verbosity = "medium"; +}; + +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"; +}; 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..370697660e 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 @@ -37,7 +37,7 @@ eNBs = nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; - rx_gain = 125; + rx_gain = 115; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -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"; @@ -178,8 +183,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; scheduler_mode = "fairRR"; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 150; + puCch10xSnr = 150; } ); 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..fbbc2f1154 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"; @@ -178,8 +183,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; scheduler_mode = "fairRR"; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 150; + puCch10xSnr = 150; } ); @@ -199,7 +204,7 @@ RUs = ( att_rx = 0; bands = [38]; max_pdschReferenceSignalPower = -27; - max_rxgain = 115; + max_rxgain = 125; eNB_instances = [0]; } 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..f49d860a51 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 @@ -37,7 +37,7 @@ eNBs = nb_antennas_tx = 1; nb_antennas_rx = 1; tx_gain = 90; - rx_gain = 125; + rx_gain = 120; prach_root = 0; prach_config_index = 0; prach_high_speed = "DISABLE"; @@ -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"; @@ -178,8 +183,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; scheduler_mode = "fairRR"; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 150; + puCch10xSnr = 150; } ); @@ -199,7 +204,7 @@ RUs = ( att_rx = 0; bands = [38]; max_pdschReferenceSignalPower = -27; - max_rxgain = 115; + max_rxgain = 120; eNB_instances = [0]; } 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..92a6e6f0bc 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf @@ -94,6 +94,14 @@ eNBs = pcch_default_PagingCycle = 128; pcch_nB = "oneT"; + drx_Config_present = "prSetup"; //"prSetup" "prRelease" + drx_onDurationTimer = "psf1"; // "psfX": X=1,2,3,4,5,6,8,10,20,30,40,50,60,80,100 + drx_InactivityTimer = "psf1"; // "psfX": X=1,2,3,4,5,6,8,10,20,30,40,50,60,80,100,200,300,500,750,1280,1920,2560 + drx_RetransmissionTimer = "psf1"; // "psfX": X=1,2,4,6,8,16,24,33 + drx_longDrx_CycleStartOffset_present = "prSf128"; // "psfX": X=10,20,32,40,64,80,128,160,256,320,512,640,1024,1280,2048,2560 + drx_longDrx_CycleStartOffset = 0; // X >= 0 && X < drx_longDrx_CycleStartOffset_present + drx_shortDrx_Cycle = "sf16"; // "sfX": X=2,5,8,10,16,20,32,40,64,80,128,160,256,320,512,640 + drx_shortDrx_ShortCycleTimer = 3; // 1..16 integer. Total duration in short cycle = drx_shortDrx_Cycle*drx_shortDrx_ShortCycleTimer [subframe] bcch_modificationPeriodCoeff = 2; ue_TimersAndConstants_t300 = 1000; ue_TimersAndConstants_t301 = 1000; @@ -178,6 +186,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 new file mode 100644 index 0000000000..b006e04e91 --- /dev/null +++ b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf @@ -0,0 +1,269 @@ +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 = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 2; + nb_antennas_tx = 2; + nb_antennas_rx = 2; + tx_gain = 90; + rx_gain = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -25; + 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 = 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 = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 2; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* + rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + + 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 + }; + } +); + +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"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 2 + nb_rx = 2 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 115; + 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_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + +log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; diff --git a/ci-scripts/conf_files/lte-fdd-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-basic-sim.conf index 1d1395cf6d..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 = ( { @@ -237,8 +242,8 @@ THREAD_STRUCT = ( NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; - FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_INTERFACE_NAME = "ens3"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; @@ -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 32a84fd206..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"; @@ -217,8 +222,8 @@ THREAD_STRUCT = ( NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; - FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_INTERFACE_NAME = "ens3"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; 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 new file mode 100644 index 0000000000..52c0593d1b --- /dev/null +++ b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf @@ -0,0 +1,241 @@ +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 = 93; 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 = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + 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 = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -27; + 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 = 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 = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + + 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 = "ens3"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + ENB_INTERFACE_NAME_FOR_S1U = "ens3"; + 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 + + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + local_s_if_name = "ens3"; + remote_s_address = "CI_UE_IP_ADDR"; + local_s_address = "CI_ENB_IP_ADDR"; + local_s_portc = 50001; + remote_s_portc = 50000; + local_s_portd = 50011; + remote_s_portd = 50010; + tr_s_preference = "nfapi"; + tr_n_preference = "local_RRC"; + } +); + +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"; + } +); + +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/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 new file mode 100644 index 0000000000..2b602cbcf2 --- /dev/null +++ b/ci-scripts/conf_files/ue.nfapi.conf @@ -0,0 +1,44 @@ +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 ="medium"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="full"; +}; + + +L1s = ( + { + num_cc = 1; + tr_n_preference = "nfapi"; + local_n_if_name = "ens3"; + remote_n_address = "CI_ENB_IP_ADDR"; + local_n_address = "CI_UE_IP_ADDR"; + 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 + att_tx = 90 + att_rx = 0; + 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/doc/ci_dev_home.md b/ci-scripts/doc/ci_dev_home.md new file mode 100644 index 0000000000..3bfc36d3f4 --- /dev/null +++ b/ci-scripts/doc/ci_dev_home.md @@ -0,0 +1,31 @@ + + + + + +
+ + + + + + OAI CI Dev documentation +
+ +VM-based RF-Less Environment: + +* [How to setup your test env](./vm_based_simulator_env.md) +* [How to deal with OAI source files](./vm_based_simulator_sources.md) +* [The main script](./vm_based_simulator_main_scripts.md) +* [How to create one or several VM instances](./vm_based_simulator_create.md) +* [How to build an OAI variant](./vm_based_simulator_build.md) +* [How the build is checked](./vm_based_simulator_check_build.md) +* [How to test an OAI variant](./vm_based_simulator_test.md) +* [How to destroy all VM instances](./vm_based_simulator_destroy.md) + +Currently missing documentation: +* How to generate a build report +* How to generate a test report + +--- + diff --git a/ci-scripts/doc/vm_based_simulator_build.md b/ci-scripts/doc/vm_based_simulator_build.md new file mode 100644 index 0000000000..ca3ab356ea --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_build.md @@ -0,0 +1,262 @@ + + + + + +
+ + + + + + OAI CI Virtual-Machine-based Test Environment: build an OAI variant +
+ +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Detailed Description](#2-detailed-description) +3. [Typical Usage](#3-typical-usage) + +# 1. Introduction # + +```bash +$ cd /tmp/CI-raphael +$ ls *.zip +localZip.zip +$ ./ci-scripts/oai-ci-vm-tool build --help +OAI CI VM script + Original Author: Raphael Defosseux + Requirements: + -- uvtool uvtool-libvirt apt-cacher + -- xenial image already synced + Default: + -- eNB with USRP + +Usage: +------ + oai-ci-vm-tool build [OPTIONS] + +Mandatory Options: +-------- + --job-name #### OR -jn #### + Specify the name of the Jenkins job. + + --build-id #### OR -id #### + Specify the build ID of the Jenkins job. + + --workspace #### OR -ws #### + Specify the workspace. + +Options: +-------- + # OpenAirInterface Build Variants + --variant enb-usrp OR -v1 + --variant basic-sim OR -v2 + --variant phy-sim OR -v3 + --variant cppcheck OR -v4 + --variant enb-ethernet OR -v7 + --variant ue-ethernet OR -v8 + # non-OSA Build Variants + --variant flexran-rtc OR -v10 + # OpenAirInterface Test Variants + --variant l1-sim OR -v20 + --variant rf-sim OR -v21 + --variant l2-sim OR -v22 + Specify the variant to build. + + --keep-vm-alive OR -k + Keep the VM alive after the build. + + --daemon OR -D + Run as daemon + + --help OR -h + Print this help message. +``` + +# 2. Detailed Description # + +Source file concerned: `ci-scripts/buildOnVM.sh` + +## 2.1. build_on_vm function ## + +* First check if the ZIP file is available and if the apt-cacher proxy configuration file is present. If not, it will stop. +* Check if the VM instance is alive. If not, create it. +* Once the VM is alive, retrieve the IP address with VM_IP_ADDR=`uvt-kvm ip $VM_NAME` +* We copy the ZIP file to the VM : `scp localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu` +* apt-cacher proxy file: `scp etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu` + +Then we open a SSH session on the VM : `ssh ubuntu@$VM_IP_ADDR` + +* We copy the apt-cacher proxy file to its destination space: `sudo cp 01proxy /etc/apt/apt.conf.d/` +* We create an hush login file to eliminate the ssh opening session messages. +* We unzip the ZIP file into `/home/ubuntu/tmp/` folder +* and we work from there. + +# 3. Typical Usage # + +## 3.1. Build in the foreground, check the results and destroy the VM at the end ## + +```bash +$ cd /tmp/CI-raphael +$ ls *.zip +localZip.zip +$ ./ci-scripts/oai-ci-vm-tool build --workspace /tmp/CI-raphael --job-name RAN-CI-develop --build-id 47 --variant enb-usrp +############################################################ +OAI CI VM script +############################################################ +VM_NAME = RAN-CI-develop-b47-enb-usrp +VM_CMD_FILE = RAN-CI-develop-b47-enb-usrp_cmds.txt +JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop +ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/enb_usrp +BUILD_OPTIONS = --eNB -w USRP --mu +VM_MEMORY = 2048 MBytes +VM_CPU = 4 +############################################################ +Creating VM (RAN-CI-develop-b47-enb-usrp) on Ubuntu Cloud Image base +############################################################ +Waiting for VM to be started +Warning: Permanently added '192.168.122.2' (ECDSA) to the list of known hosts. +RAN-CI-develop-b47-enb-usrp has for IP addr = 192.168.122.2 +############################################################ +Copying GIT repo into VM (RAN-CI-develop-b47-enb-usrp) +############################################################ +Warning: Permanently added '192.168.122.2' (ECDSA) to the list of known hosts. +############################################################ +Running install and build script on VM (RAN-CI-develop-b47-enb-usrp) +############################################################ +Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-145-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/advantage + + Get cloud support with Ubuntu Advantage Cloud Guest: + http://www.ubuntu.com/business/services/cloud + +0 packages can be updated. +0 updates are security updates. + +New release '18.04.2 LTS' available. +Run 'do-release-upgrade' to upgrade to it. + + +sudo apt-get --yes --quiet install zip subversion libboost-dev +unzip -qq -DD ../localZip.zip +cd /home/ubuntu/tmp +source oaienv +cd cmake_targets +./build_oai -I --eNB -w USRP --mu + +# Here wait for a few minutes 8 to 12 minutes # + +############################################################ +Creating a tmp folder to store results and artifacts +############################################################ +############################################################ +Destroying VM +############################################################ +# Host 192.168.122.2 found: line 19 +/home/eurecom/.ssh/known_hosts updated. +Original contents retained as /home/eurecom/.ssh/known_hosts.old +############################################################ +Checking build status +############################################################ +STATUS seems OK +``` + +If you are adding the `-k` or `--keep-vm-alive` option, the VM instance will not be destroyed and you explore what happenned. + +## 3.2. Build in the background ## + +This is how it is done in the CI master job pipeline. + +```bash +$ cd /tmp/CI-raphael +$ ls *.zip +localZip.zip +$ ./ci-scripts/oai-ci-vm-tool build --workspace /tmp/CI-raphael --job-name RAN-CI-develop --build-id 47 --variant phy-sim --daemon +12:44:24 ############################################################ +12:44:24 OAI CI VM script +12:44:24 ############################################################ +12:44:24 VM_NAME = RAN-CI-develop-b47-phy-sim +12:44:24 VM_CMD_FILE = RAN-CI-develop-b47-phy-sim_cmds.txt +12:44:24 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop +12:44:24 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim +12:44:24 BUILD_OPTIONS = --phy_simulators +12:44:24 VM_MEMORY = 2048 MBytes +12:44:24 VM_CPU = 4 +12:44:24 ############################################################ +12:44:24 Creating VM (RAN-CI-develop-b47-phy-sim) on Ubuntu Cloud Image base +12:44:24 ############################################################ +12:44:27 Waiting for VM to be started +12:46:34 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts. +12:46:34 RAN-CI-develop-b47-phy-sim has for IP addr = 192.168.122.220 +12:46:34 ############################################################ +12:46:34 Copying GIT repo into VM (RAN-CI-develop-b47-phy-sim) +12:46:34 ############################################################ +12:46:34 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts. +12:46:34 ############################################################ +12:46:34 Running install and build script on VM (RAN-CI-develop-b47-phy-sim) +12:46:34 ############################################################ +12:46:34 Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-145-generic x86_64) +12:46:34 +12:46:34 * Documentation: https://help.ubuntu.com +12:46:34 * Management: https://landscape.canonical.com +12:46:34 * Support: https://ubuntu.com/advantage +12:46:34 +12:46:34 Get cloud support with Ubuntu Advantage Cloud Guest: +12:46:34 http://www.ubuntu.com/business/services/cloud +12:46:34 +12:46:34 0 packages can be updated. +12:46:34 0 updates are security updates. +12:46:34 +12:46:34 New release '18.04.2 LTS' available. +12:46:34 Run 'do-release-upgrade' to upgrade to it. +12:46:34 +12:46:34 +12:46:34 sudo apt-get --yes --quiet install zip daemon subversion libboost-dev +12:46:46 unzip -qq -DD ../localZip.zip +12:46:48 source oaienv +12:46:48 sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh +12:46:48 STATUS seems OK +``` + +So here is 2.5 minutes, a VM was created, source files copied and the build process is started in the background. + +```bash +$ cd /tmp/raphael +$ ./ci-scripts/oai-ci-vm-tool wait --workspace /var/jenkins/workspace/RAN-CI-develop --variant phy-sim --job-name RAN-CI-develop --build-id 47 --keep-vm-alive +12:49:14 ############################################################ +12:49:14 OAI CI VM script +12:49:14 ############################################################ +12:49:14 VM_NAME = RAN-CI-develop-b47-phy-sim +12:49:14 VM_CMD_FILE = RAN-CI-develop-b47-phy-sim_cmds.txt +12:49:14 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop +12:49:14 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim +12:49:14 BUILD_OPTIONS = --phy_simulators +12:49:15 Waiting for VM to be started +12:49:15 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts. +12:49:16 RAN-CI-develop-b47-phy-sim has for IP addr = 192.168.122.220 +12:49:16 ############################################################ +12:49:16 Waiting build process to end on VM (RAN-CI-develop-b47-phy-sim) +12:49:16 ############################################################ +12:49:16 ps -aux | grep build +12:54:23 ############################################################ +12:54:23 Creating a tmp folder to store results and artifacts +12:54:23 ############################################################ +12:54:23 ############################################################ +12:54:23 Checking build status +12:54:23 ############################################################ +12:54:23 STATUS seems OK +``` + +Here the `--keep-vm-alive` option is used to keep the VM alive and performs some testing. + +--- + +Next step: [how the build is checked](./vm_based_simulator_check_build.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_check_build.md b/ci-scripts/doc/vm_based_simulator_check_build.md new file mode 100644 index 0000000000..d66b8ff2a0 --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_check_build.md @@ -0,0 +1,44 @@ + + + + + +
+ + + + + + OAI CI Virtual-Machine-based Test Environment: checking the build result +
+ +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Detailed Description](#2-detailed-description) + +# 1. Introduction # + +Function is called: + +- when building in foreground +- when waiting for the background build process is finished + +# 2. Detailed Description # + +Source file concerned: `ci-scripts/waitBuildOnVM.sh` + +## 2.1. check_on_vm_build function ## + +* Retrieve the build log files from the VM instance `ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.txt` +* and copy them locally in the workspace at $ARCHIVES_LOC +* List all log files that match the pattern. Each should have + * the `Built target` pattern (the library/executable SHALL link) +* The number of patterned log files SHALL match $NB_PATTERN_FILES defined in `ci-scripts/oai-ci-vm-tool` script for the variant + +--- + +Next step: [how to test a function](./vm_based_simulator_test.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_create.md b/ci-scripts/doc/vm_based_simulator_create.md new file mode 100644 index 0000000000..c54d69ca14 --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_create.md @@ -0,0 +1,111 @@ + + + + + +
+ + + + + + OAI CI Virtual-Machine-based Test Environment: create a VM instance +
+ +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Detailed Description](#2-detailed-description) +3. [Typical Usage](#3-typical-usage) + +# 1. Introduction # + +```bash +$ cd /tmp/CI-raphael +$ ./ci-scripts/oai-ci-vm-tool create --help +OAI CI VM script + Original Author: Raphael Defosseux + Requirements: + -- uvtool uvtool-libvirt apt-cacher + -- xenial image already synced + Default: + -- eNB with USRP + +Usage: +------ + oai-ci-vm-tool create [OPTIONS] + +Mandatory Options: +-------- + --job-name #### OR -jn #### + Specify the name of the Jenkins job. + + --build-id #### OR -id #### + Specify the build ID of the Jenkins job. + + # OpenAirInterface Build Variants + --variant enb-usrp OR -v1 + --variant basic-sim OR -v2 + --variant phy-sim OR -v3 + --variant cppcheck OR -v4 + --variant enb-ethernet OR -v7 + --variant ue-ethernet OR -v8 + # non-OSA Build Variants + --variant flexran-rtc OR -v10 + # OpenAirInterface Test Variants + --variant l1-sim OR -v20 + --variant rf-sim OR -v21 + --variant l2-sim OR -v22 + Specify the variant to build. + + --help OR -h + Print this help message. +``` + +# 2. Detailed Description # + +Source file concerned: `ci-scripts/createVM.sh` + +## 2.1. create_vm function ## + +This is the function that is being called from the main oai-vm-tool script. + +The main purpose is to start a VM instance: + +```bash +uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml +``` + +Variables are set in the main script based on the options. + +`--unsafe-caching` option is used because our VM instances are throw-away's. + +`--template ci-scripts/template-host.xml` is used to duplicate the CPU properties to the VM instance. **VERY IMPORTANT to build OAI** + +## 2.2. Lock / Unlock functions ## + +There are `acquire_vm_create_lock` and `release_vm_create_lock` functions. + +Creating Virtual Machines instances in parallel **creates a lot of stress** on the host server HW. If you launch creations in parallel (Jenkins pipeline could do it) or you are several people working on the same host server, this mechanism atomizes the creation process and wait until the previous VM creation is finished. + +# 3. Typical Usage # + +```bash +$ cd /tmp/CI-raphael +$ ./ci-scripts/oai-ci-vm-tool create --job-name raphael --build-id 1 --variant phy-sim +# or a more **unique approach** +$ ./ci-scripts/oai-ci-vm-tool create -jn toto -id 1 -v2 +``` + +The Jenkins pipeline uses the master job name as `job-name` option and the job-build ID. + +Try to be unique if you are several developers working on the same host server. + +Finally, typically I never use the `create` command. I use directly the build command that checks if VM is created and if not, will create it. See next step. + +--- + +Next step: [how to build an OAI variant](./vm_based_simulator_build.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_destroy.md b/ci-scripts/doc/vm_based_simulator_destroy.md new file mode 100644 index 0000000000..d69e82a005 --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_destroy.md @@ -0,0 +1,71 @@ + + + + + +
+ + + + + + OAI CI Virtual-Machine-based Test Environment: Properly Destroy all VM instances +
+ +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Detailed Description](#2-detailed-description) +3. [Typical Usage](#3-typical-usage) + +# 1. Introduction # + +```bash +$ cd /tmp/CI-raphael +$ ./ci-scripts/oai-ci-vm-tool destroy --help +OAI CI VM script + Original Author: Raphael Defosseux + Requirements: + -- uvtool uvtool-libvirt apt-cacher + +Usage: +------ + oai-ci-vm-tool destroy [OPTIONS] + +Mandatory Options: +-------- + --job-name #### OR -jn #### + Specify the name of the Jenkins job. + + --build-id #### OR -id #### + Specify the build ID of the Jenkins job. + +Options: +-------- + --help OR -h + Print this help message. +``` + +# 2. Detailed Description # + +Source file concerned: `ci-scripts/destroyAllRunningVM.sh` + +## 2.1. destroy_vm function ## + +This is the function that is being called from the main oai-vm-tool script. + +The main purpose is to destroy all VM instances whose name matches a pattern. + +It also cleans up the `.ssh/known_hosts` file. + +# 3. Typical Usage # + +```bash +$ cd /tmp/CI-raphael +$ ./ci-scripts/oai-ci-vm-tool destroy --job-name raphael --build-id 1 +``` + +--- + +You can go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_env.md b/ci-scripts/doc/vm_based_simulator_env.md new file mode 100644 index 0000000000..5dbcfbd931 --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_env.md @@ -0,0 +1,123 @@ + + + + + +
+ + + + + + OAI CI Virtual-Machine-based Simulator Test Environment +
+ +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Prerequisites](#2-prerequisites) + 1. [uvtool installation](#21-uvtool-installation) + 2. [apt-cacher-server installation](#22-apt-cacher-server-installation) + +# 1. Introduction # + +This document explains how the master pipeline works and how any developer could contribute to add testing. + +It is an extension to the wiki [page](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/ci/enb-master-job). + +The purpose of this master pipeline is to: + +* Validate that a Merge Request is mergeable +* Validate that a Merge Request is following coding guidelines +* Validate that a Merge Request is not breaking any typical build variant +* Validate that a Merge Request is not breaking any legacy simulator-based test + +We will mainly focused on the 2 last items. + +Last point, this documentation is valid for all CI-supported branches: + +* `master` +* `develop` +* `develop-nr` + +But the feature set may not be aligned. **The principles still apply.** + +# 2. Prerequisites # + +Some details are available on this wiki [section](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/ci/enb-ci-architecture#22-pipeline-executor). + +Currently we have a host server (`bellatrix`) with the current parameters: + +* 40 x Intel(R) Xeon(R) CPU E5-2640 v4 @ 2.40GHz +* 64 Gbytes RAM +* Ubuntu 16.04.3 LTS (xenial) + +For you to replicate this environment, you need a strong server: + +* At least 16 cores +* Ubuntu 16 (xenial) or higher (such as bionic, not tested) + +Also we are using a Virtual Machine (VM for the rest of document) based strategy for the moment. + +So you need to install 2 tools: + +* uvt-kvm +* apt-cacher + +We are planning to also add: + +* A Red Hat Linux Entreprise 7.6 host environment +* A Container-based strategy (such as Docket and Kubernetes) + +## 2.1. uvtool installation ## + +```bash +$ sudo apt-get install uvtool +# if you don't have already, create an ssh key +$ ssh-keygen -b 2048 +# retrieve an image +$ sudo uvt-simplestreams-libvirt sync arch=amd64 release=xenial +# we might soon switch to an Ubuntu 18.04 version +$ sudo uvt-simplestreams-libvirt sync arch=amd64 release=bionic +$ uvt-simplestreams-libvirt query +release=bionic arch=amd64 label=release (20190402) +release=xenial arch=amd64 label=release (20190406) +``` + +On our server, I don't update (sync) that often (every 2-4 months). + +For more details: + +* uvtool syntax is [here](http://manpages.ubuntu.com/manpages/trusty/man1/uvt-kvm.1.html) +* more readable tutorial is [here](https://help.ubuntu.com/lts/serverguide/cloud-images-and-uvtool.html) + +## 2.2. apt-cacher-server installation ## + +I recommend to follow to the letter this [tutorial](https://help.ubuntu.com/community/Apt-Cacher-Server). + +The reason: we are creating/using/destroying a lot of VM instances and we are always installing the same packages. +This service allows to cache on the host and, doing so, **decreases the pressure on your internet bandwith usage**. +It also optimizes time at build stage. + +```bash +$ sudo apt-get install apt-cacher apache2 +$ sudo vi /etc/default/apt-cache +$ sudo service apache2 restart + +# Server configuration +$ sudo vi /etc/apt-cacher/apt-cacher.conf + --> allowed_hosts = * + --> fix the installer_files_regexp +$ sudo vi /etc/apt/apt.conf.d/01proxy +--> add `Acquire::http::Proxy "http://:3142";` +$ sudo service apt-cacher restart +``` + +This last file (/etc/apt/apt.conf.d/01proxy) is very important since it is tested in any CI script. + +--- + +We can now switch to the next step: [how to deal with oai sources](./vm_based_simulator_sources.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_main_scripts.md b/ci-scripts/doc/vm_based_simulator_main_scripts.md new file mode 100644 index 0000000000..91aa88b7ec --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_main_scripts.md @@ -0,0 +1,87 @@ + + + + + +
+ + + + + + OAI CI Virtual-Machine-based Test Environment: the Main Script +
+ +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Sub BASH scripts](#2-sub-bash-scripts) +3. [Main script features](#3-main-script-features) + +# 1. Introduction # + +The file name is `./ci-scripts/oai-ci-vm-tool` from the workspace root. + +```bash +$ cd /tmp/CI-raphael +$ ./ci-scripts/oai-ci-vm-tool --help +OAI CI VM script + Original Author: Raphael Defosseux + Requirements: + -- uvtool uvtool-libvirt apt-cacher + -- xenial image already synced + +Usage: +------ + oai-ci-vm-tool (-h|--help) {create,destroy,build,wait,test,report-build,report-test} ... + +``` + +This is a **BASH** script. + + +# 2. Sub BASH scripts # + +The main script is including a bunch of sub BASH scripts. + +* ci-scripts/createVM.sh +* ci-scripts/buildOnVM.sh +* ci-scripts/waitBuildOnVM.sh +* ci-scripts/destroyAllRunningVM.sh +* ci-scripts/runTestOnVM.sh +* ci-scripts/reportBuildLocally.sh +* ci-scripts/reportTestLocally.sh + +**NOTE: ci-scripts/runTestOnVM.sh is getting big and will certainly be split to facilate maintenance. Start functions will be also factorized.** + +# 3. Main script features # + +The main purpose of the main script is decipher the options and launch the requested function. + +It is also **testing if uvtool and apt-cacher are installed.** + +It finally provides parameters to the requested functions. Parameter definition is centralized there. + +For example: + +for VM instance creation: + +* the instance name: VM_NAME +* the RAM and number of CPUs: VM_MEMORY, VM_CPU + +for OAI variant build: + +* build options: BUILD_OPTIONS +* build log file to parse: LOG_PATTERN +* the number of log files to parse: NB_PATTERN_FILES + +These last 2 variables are very important if you change the build options or if you modify the build system and add more targets to build (especially true for physical simulator). + +There are many more variables. + +--- + +Next step: [how to create one or several VM instances](./vm_based_simulator_create.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_sources.md b/ci-scripts/doc/vm_based_simulator_sources.md new file mode 100644 index 0000000000..4bba6a8a09 --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_sources.md @@ -0,0 +1,85 @@ + + + + + +
+ + + + + + OAI CI Virtual-Machine-based Simulator OAI source management +
+ +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Centralized Workspace](#2-centralized-workspace) +3. [Create the ZIP file](#3-create-the-zip-file) + +# 1. Introduction # + +The idea of this section is to optimize/uniform source management for several VM instances. + +If we were cloning the same repository in each VM we are creating, we would put so much pressure on the central GitLab repository. + +The solution: + +* clone/fetch on a given clean workspace and tar/zip only the source files without any artifacts. +* we then copy the tar/zip file to each VM instance +* and within each VM instance, unzip + +# 2. Centralized Workspace # + +You can create a brand new workspace by cloning: + +```bash +$ mkdir /tmp/CI-raphael +$ cd /tmp/CI-raphael +$ git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git . +$ git checkout develop +``` + +You can also use your current cloned workspace and any `develop`-based branch. + +```bash +$ cd /home/raphael/openairinterface5g +$ git fetch +$ git checkout develop-improved-documentation +# CAUTION: the following command will remove any file that has not already been added to GIT +$ sudo git clean -x -d -ff +$ git status +On branch develop-improved-documentation +Your branch is up-to-date with 'origin/develop-improved-documentation'. +nothing to commit, working directory clean +``` + +You can also have modified files. + +**The main point is to have NO ARTIFACTS from a previous build in your workspace.** + +Last point, the workspace folder name is not necesseraly `openairinterface5g`. But all the following commands will be run for the root of the workspace. + +For clarity, I will always use `/tmp/CI-raphael` as $WORKSPACE. + +# 3. Create the ZIP file # + +```bash +# go to root of workspace +$ cd /tmp/CI-raphael +$ zip -r -qq localZip.zip . +``` + +The **Jenkins Pipeline** performs automatically these operations. + +In addition, in case of a merge request, it tries to merge with the target branch and might create a dummy local commit. + +See [section](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/ci/enb-master-job#32-verify-guidelines-stage) + +--- + +Next step: [the main scripts](./vm_based_simulator_main_scripts.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/doc/vm_based_simulator_test.md b/ci-scripts/doc/vm_based_simulator_test.md new file mode 100644 index 0000000000..0be7ae5d3a --- /dev/null +++ b/ci-scripts/doc/vm_based_simulator_test.md @@ -0,0 +1,260 @@ + + + + + +
+ + + + + + OAI CI Virtual-Machine-based Test Environment: Testing an OAI variant +
+ +## Table of Contents ## + +1. [Introduction](#1-introduction) +2. [Detailed Description](#2-detailed-description) +3. [Typical Usage](#3-typical-usage) + 1. [Testing the physical simulators](#31-testing-the-physicals-simulators) + 2. [Testing the basic simulator](#32-testing-the-basic-simulator) + 3. [Testing the RF simulator](#33-testing-the-rf-simulator) + 4. [Testing the L2-nFAPI simulator](#33-testing-the-l2-nfapi-simulator) + +# 1. Introduction # + +Currently 2 build variants can be directly tested: + +* Physical Simulators +* Basic Simulator + +In addition, 2 build variants are used: + +* OAI eNB with ETHERNET transport +* OAI UE with ETHERNET transport + +for the following scenarios: + +* L1 simulator w/ a channel simulator (NOT IMPLEMENTED) +* RF simulator : (IMPLEMENTED but not working as of 2019.w15) +* L2 nFAPI simulator + +Tests are run sequentially in the Jenkins pipeline because: + +* We want to mutualize the VM creation for an EPC +* We have seen performance issues when running in parallel. + + +```bash +./ci-scripts/oai-ci-vm-tool test --help +OAI CI VM script + Original Author: Raphael Defosseux + Requirements: + -- uvtool uvtool-libvirt apt-cacher + -- xenial image already synced + Default: + -- eNB with USRP + +Usage: +------ + oai-ci-vm-tool test [OPTIONS] + +Options: +-------- + --job-name #### OR -jn #### + Specify the name of the Jenkins job. + + --build-id #### OR -id #### + Specify the build ID of the Jenkins job. + + --workspace #### OR -ws #### + Specify the workspace. + + # OpenAirInterface Build Variants + --variant enb-usrp OR -v1 + --variant basic-sim OR -v2 + --variant phy-sim OR -v3 + --variant cppcheck OR -v4 + --variant enb-ethernet OR -v7 + --variant ue-ethernet OR -v8 + # non-OSA Build Variants + --variant flexran-rtc OR -v10 + # OpenAirInterface Test Variants + --variant l1-sim OR -v20 + --variant rf-sim OR -v21 + --variant l2-sim OR -v22 + Specify the variant to build. + + --keep-vm-alive OR -k + Keep the VM alive after the build. + + --help OR -h + Print this help message. +``` + +# 2. Detailed Description # + +Source file concerned: `ci-scripts/run_test_on_vm.sh` + +**TBD when file is re-structured.** + +# 3. Typical Usage # + +## 3.1. Testing the physical simulators ## + +```bash +$ ./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant phy-sim --job-name RAN-CI-develop --build-id 47 +12:54:29 ############################################################ +12:54:29 OAI CI VM script +12:54:29 ############################################################ +12:54:29 VM_NAME = RAN-CI-develop-b47-phy-sim +12:54:29 VM_CMD_FILE = RAN-CI-develop-b47-phy-sim_cmds.txt +12:54:29 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop +12:54:29 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim/test +12:54:29 ############################################################ +12:54:29 Waiting for VM to be started +12:54:29 ############################################################ +12:54:29 Warning: Permanently added '192.168.122.220' (ECDSA) to the list of known hosts. +12:54:30 RAN-CI-develop-b47-phy-sim has for IP addr = 192.168.122.220 +... +13:04:48 Test Results are written to /home/ubuntu/tmp/cmake_targets/autotests/log/results_autotests.xml +13:05:00 ############################################################ +13:05:00 Creating a tmp folder to store results and artifacts +13:05:00 ############################################################ +13:05:00 /var/jenkins/workspace/RAN-CI-develop/archives/phy_sim/test /var/jenkins/workspace/RAN-CI-develop +13:05:04 /var/jenkins/workspace/RAN-CI-develop +13:05:04 ############################################################ +13:05:04 Destroying VM +13:05:04 ############################################################ +13:05:06 # Host 192.168.122.220 found: line 21 +13:05:06 /home/eurecom/.ssh/known_hosts updated. +13:05:06 Original contents retained as /home/eurecom/.ssh/known_hosts.old +13:05:06 ############################################################ +13:05:06 Checking run status +13:05:06 ############################################################ +13:05:06 NB_FOUND_FILES = 1 +13:05:06 NB_RUNS = 20 +13:05:06 NB_FAILURES = 0 +13:05:06 STATUS seems OK +``` + +Note that the VM instance is destroyed. You do that when you are sure your test is passing. + +## 3.2. Testing the basic simulator ## + +```bash +$ ./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant basic-sim --job-name RAN-CI-develop --build-id 48 +15:11:13 ############################################################ +15:11:13 OAI CI VM script +15:11:13 ############################################################ +15:11:13 VM_NAME = RAN-CI-develop-b48-basic-sim +15:11:13 VM_CMD_FILE = RAN-CI-develop-b48-basic-sim_cmds.txt +15:11:13 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop +15:11:13 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/basic_sim/test +15:11:13 ############################################################ +15:11:13 Waiting for VM to be started +15:11:13 ############################################################ +15:11:14 Warning: Permanently added '192.168.122.29' (ECDSA) to the list of known hosts. +15:11:15 RAN-CI-develop-b48-basic-sim has for IP addr = 192.168.122.29 +15:11:15 ############################################################ +15:11:15 Test EPC on VM (RAN-CI-develop-b48-epc) will be using ltebox +15:11:15 ############################################################ +15:11:15 EPC_VM_CMD_FILE = RAN-CI-develop-b48-epc_cmds.txt +15:11:15 ############################################################ +15:11:15 Creating test EPC VM (RAN-CI-develop-b48-epc) on Ubuntu Cloud Image base +15:11:15 ############################################################ +15:11:18 Waiting for VM to be started +15:13:25 Warning: Permanently added '192.168.122.156' (ECDSA) to the list of known hosts. +15:13:25 RAN-CI-develop-b48-epc has for IP addr = 192.168.122.156 +15:13:25 Warning: Permanently added '192.168.122.156' (ECDSA) to the list of known hosts. +15:13:25 ls: cannot access '/opt/ltebox/tools/start_ltebox': No such file or directory +15:13:25 ############################################################ +15:13:25 Copying ltebox archives into EPC VM (RAN-CI-develop-b48-epc) +15:13:25 ############################################################ +15:13:25 ############################################################ +15:13:25 Install EPC on EPC VM (RAN-CI-develop-b48-epc) +15:13:25 ############################################################ +.... +15:24:39 ############################################################ +15:24:39 Terminate EPC +15:24:39 ############################################################ +15:24:39 cd /opt/ltebox/tools +15:24:39 sudo ./stop_ltebox +15:24:40 sudo daemon --name=simulated_hss --stop +15:24:40 sudo killall --signal SIGKILL hss_sim +15:24:40 ############################################################ +15:24:40 Destroying VMs +15:24:40 ############################################################ +15:24:41 # Host 192.168.122.29 found: line 18 +15:24:41 /home/eurecom/.ssh/known_hosts updated. +15:24:41 Original contents retained as /home/eurecom/.ssh/known_hosts.old +15:24:43 # Host 192.168.122.60 found: line 20 +15:24:43 /home/eurecom/.ssh/known_hosts updated. +15:24:43 Original contents retained as /home/eurecom/.ssh/known_hosts.old +15:24:43 ############################################################ +15:24:43 Checking run status +15:24:43 ############################################################ +15:24:43 STATUS seems OK +``` + +## 3.3. Test the RF simulator ## + +```bash +./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant rf-sim --job-name RAN-CI-develop --build-id 48 --keep-vm-alive +15:24:45 Currently RF-Simulator Testing is not implemented / enabled +15:24:45 Comment out these lines in ./ci-scripts/oai-ci-vm-tool if you want to run it +15:24:45 STATUS seems OK +``` + +## 3.4. Testing the L2-nFAPI simulator + +```bash +./ci-scripts/oai-ci-vm-tool test --workspace /var/jenkins/workspace/RAN-CI-develop --variant l2-sim --job-name RAN-CI-develop --build-id 48 +15:24:47 ############################################################ +15:24:47 OAI CI VM script +15:24:47 ############################################################ +15:24:47 ENB_VM_NAME = RAN-CI-develop-b48-enb-ethernet +15:24:47 ENB_VM_CMD_FILE = RAN-CI-develop-b48-enb-ethernet_cmds.txt +15:24:47 UE_VM_NAME = RAN-CI-develop-b48-ue-ethernet +15:24:47 UE_VM_CMD_FILE = RAN-CI-develop-b48-ue-ethernet_cmds.txt +15:24:47 JENKINS_WKSP = /var/jenkins/workspace/RAN-CI-develop +15:24:47 ARCHIVES_LOC = /var/jenkins/workspace/RAN-CI-develop/archives/l2_sim/test +15:24:47 ############################################################ +15:24:47 Waiting for ENB VM to be started +15:24:47 ############################################################ +15:24:47 Warning: Permanently added '192.168.122.110' (ECDSA) to the list of known hosts. +15:24:48 RAN-CI-develop-b48-enb-ethernet has for IP addr = 192.168.122.110 +15:24:48 ############################################################ +15:24:48 Waiting for UE VM to be started +15:24:48 ############################################################ +15:24:49 Warning: Permanently added '192.168.122.90' (ECDSA) to the list of known hosts. +15:24:50 RAN-CI-develop-b48-ue-ethernet has for IP addr = 192.168.122.90 +15:24:50 ############################################################ +15:24:50 Test EPC on VM (RAN-CI-develop-b48-epc) will be using ltebox +15:24:50 ############################################################ +15:24:50 EPC_VM_CMD_FILE = RAN-CI-develop-b48-epc_cmds.txt +15:24:50 Waiting for VM to be started +15:24:50 Warning: Permanently added '192.168.122.156' (ECDSA) to the list of known hosts. +15:24:51 RAN-CI-develop-b48-epc has for IP addr = 192.168.122.156 +... +15:42:44 ############################################################ +15:42:44 Destroying VMs +15:42:44 ############################################################ +15:42:46 # Host 192.168.122.110 found: line 18 +15:42:46 /home/eurecom/.ssh/known_hosts updated. +15:42:46 Original contents retained as /home/eurecom/.ssh/known_hosts.old +15:42:47 # Host 192.168.122.90 found: line 18 +15:42:47 /home/eurecom/.ssh/known_hosts updated. +15:42:47 Original contents retained as /home/eurecom/.ssh/known_hosts.old +15:42:47 ############################################################ +15:42:47 Checking run status +15:42:47 ############################################################ +15:42:47 STATUS failed? +``` +--- + +Final step: [how to properly destroy all VM instances](./vm_based_simulator_destroy.md) + +You can also go back to the [CI dev main page](./ci_dev_home.md) + diff --git a/ci-scripts/main.py b/ci-scripts/main.py index dc101fe7ea..fbd6fb471f 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. @@ -50,6 +49,11 @@ MME_PROCESS_OK = +3 SPGW_PROCESS_FAILED = -4 SPGW_PROCESS_OK = +4 UE_IP_ADDRESS_ISSUE = -5 +OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE = -20 +OAI_UE_PROCESS_COULD_NOT_SYNC = -21 +OAI_UE_PROCESS_ASSERTION = -22 +OAI_UE_PROCESS_FAILED = -6 +OAI_UE_PROCESS_OK = +6 #----------------------------------------------------------- # Import @@ -89,6 +93,7 @@ class SSHConnection(): self.EPCPassword = '' self.EPCSourceCodePath = '' self.EPCType = '' + self.EPC_PcapFileName = '' self.ADBIPAddress = '' self.ADBUserName = '' self.ADBPassword = '' @@ -100,6 +105,9 @@ class SSHConnection(): self.Initialize_eNB_args = '' self.eNBLogFile = '' self.eNB_instance = '' + self.eNBOptions = '' + self.rruOptions = '' + self.rruLogFile = '' self.ping_args = '' self.ping_packetloss_threshold = '' self.iperf_args = '' @@ -114,18 +122,28 @@ class SSHConnection(): self.htmlFooterCreated = False self.htmlUEConnected = -1 self.htmleNBFailureMsg = '' + self.htmlUEFailureMsg = '' self.picocom_closure = False self.idle_sleep_time = 0 self.htmlTabRefs = [] self.htmlTabNames = [] self.htmlTabIcons = [] self.finalStatus = False - self.eNBOsVersion = '' - self.eNBKernelVersion = '' - self.eNBUhdVersion = '' - self.eNBCpuNb = '' - self.eNBCpuModel = '' - self.eNBCpuMHz = '' + 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.UELogFile = '' + self.Build_OAI_UE_args = '' + self.Initialize_OAI_UE_args = '' def open(self, ipaddress, username, password): count = 0 @@ -326,6 +344,43 @@ class SSHConnection(): 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 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() @@ -389,8 +444,9 @@ class SSHConnection(): if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.eNBSourceCodePath == '': Usage() sys.exit('Insufficient Parameter') - initialize_eNB_flag = True - pStatus = self.CheckProcessExist(initialize_eNB_flag) + check_eNB = False + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow(self.Initialize_eNB_args, 'KO', pStatus) self.CreateHtmlTabFooter(False) @@ -404,13 +460,15 @@ class SSHConnection(): if result is not None: eth_interface = result.group('eth_interface') logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + '\u001B[0m') - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f /tmp/enb_' + self.testCase_id + '_s1log.pcap', '\$', 5) - self.command('echo $USER; nohup sudo tshark -f "host ' + self.eNBIPAddress +'" -i ' + eth_interface + ' -w /tmp/enb_' + self.testCase_id + '_s1log.pcap > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) + self.EPC_PcapFileName = 'enb_' + self.testCase_id + '_s1log.pcap' + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f /tmp/' + self.EPC_PcapFileName, '\$', 5) + self.command('echo $USER; nohup sudo tshark -f "host ' + self.eNBIPAddress +'" -i ' + eth_interface + ' -w /tmp/' + self.EPC_PcapFileName + ' > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) self.close() self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) 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:] @@ -428,9 +486,19 @@ class SSHConnection(): sys.exit('Insufficient Parameter') ci_full_config_file = config_path + '/ci-' + config_file rruCheck = False - result = re.search('rru', str(config_file)) + result = re.search('rru|du', str(config_file)) if result is not None: rruCheck = True + # do not reset board twice in IF4.5 case + result = re.search('rru|enb|du', str(config_file)) + if result is not None: + self.command('echo ' + self.eNBPassword + ' | sudo -S uhd_find_devices', '\$', 10) + 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 b2xx_fx3_utils --reset-device', '\$', 10) + # Reloading FGPA bin firmware + self.command('echo ' + self.eNBPassword + ' | sudo -S uhd_find_devices', '\$', 15) # 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); @@ -438,12 +506,17 @@ 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 + result = re.search('rru|du', str(config_file)) + if result is not None: + self.rruLogFile = 'enb_' + self.testCase_id + '.log' time.sleep(6) doLoop = True loopCounter = 10 @@ -465,25 +538,31 @@ class SSHConnection(): 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) + if self.EPC_PcapFileName != '': + time.sleep(0.5) + self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + self.EPC_PcapFileName, '\$', 5) self.close() time.sleep(1) - pcap_log_file = 'enb_' + self.testCase_id + '_s1log.pcap' - copyin_res = self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + pcap_log_file, '.') - if (copyin_res == 0): - self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, pcap_log_file, self.eNBSourceCodePath + '/cmake_targets/.') + if self.EPC_PcapFileName != '': + copyin_res = self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + self.EPC_PcapFileName, '.') + if (copyin_res == 0): + self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.EPC_PcapFileName, self.eNBSourceCodePath + '/cmake_targets/.') sys.exit(1) else: - self.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) + self.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Starting"', '\$', 4) if rruCheck: result = re.search('wait RUs', str(self.ssh.before)) else: - result = re.search('got sync', str(self.ssh.before)) + result = re.search('got sync|Starting F1AP at CU', str(self.ssh.before)) if result is None: 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') + time.sleep(10) self.close() @@ -517,6 +596,125 @@ 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') + result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) + if result is None: + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) + 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', '\$', 10) + 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 b2xx_fx3_utils --reset-device', '\$', 10) + # Reloading FGPA bin firmware + self.command('echo ' + self.UEPassword + ' | sudo -S uhd_find_devices', '\$', 15) + else: + logging.debug('Did not find any B2xx device') + self.command('cd ' + self.UESourceCodePath, '\$', 5) + self.command('source oaienv', '\$', 5) + self.command('cd cmake_targets/lte_build_oai/build', '\$', 5) + result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) + # We may have to regenerate the .u* files + if result is None: + self.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) + self.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5) + self.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5) + # Launch UE with the modified config file + 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.UELogFile = 'ue_' + self.testCase_id + '.log' + + # We are now looping several times to hope we really sync w/ an eNB + doOutterLoop = True + outterLoopCounter = 5 + gotSyncStatus = True + fullSyncStatus = True + while (doOutterLoop): + self.command('cd ' + self.UESourceCodePath + '/cmake_targets/lte_build_oai/build', '\$', 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) + time.sleep(6) + self.command('cd ../..', '\$', 5) + doLoop = True + loopCounter = 10 + gotSyncStatus = True + # the 'got sync' message is for the UE threads synchronization + while (doLoop): + loopCounter = loopCounter - 1 + if (loopCounter == 0): + # Here should never occur + logging.error('"got sync" message never showed!') + gotSyncStatus = False + doLoop = False + continue + 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 + logging.debug('Found "got sync" message!') + if gotSyncStatus == False: + # we certainly need to stop the lte-uesoftmodem process if it is still running! + self.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) + result = re.search('lte-uesoftmodem', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT lte-uesoftmodem', '\$', 4) + time.sleep(3) + # We are now checking if sync w/ eNB DOES NOT OCCUR + # Usually during the cell synchronization stage, the UE returns with No cell synchronization message + doLoop = True + loopCounter = 10 + while (doLoop): + loopCounter = loopCounter - 1 + if (loopCounter == 0): + # Here we do have a great chance that the UE did cell-sync w/ eNB + doLoop = False + doOutterLoop = False + fullSyncStatus = True + continue + self.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) + result = re.search('No cell synchronization found', str(self.ssh.before)) + if result is None: + time.sleep(6) + else: + doLoop = False + fullSyncStatus = False + logging.debug('Found: "No cell synchronization" message! --> try again') + time.sleep(6) + self.command('ps -aux | grep --text --color=never softmodem | grep -v grep', '\$', 4) + result = re.search('lte-uesoftmodem', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal=SIGINT lte-uesoftmodem', '\$', 4) + outterLoopCounter = outterLoopCounter - 1 + if (outterLoopCounter == 0): + doOutterLoop = False + + if fullSyncStatus and gotSyncStatus: + result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) + if result is None: + self.command('ifconfig oaitun_ue1', '\$', 4) + result = re.search('inet addr', str(self.ssh.before)) + if result is not None: + logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m') + else: + logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m') + + self.close() + # For the moment we are always OK!!! + self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', ALL_PROCESSES_OK, 'OAI UE') + logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m') + def checkDevTTYisUnlocked(self): self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) count = 0 @@ -604,21 +802,155 @@ 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') + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) + 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 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.close() + 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.close() + 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.close() + 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.close() + 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: @@ -671,8 +1003,9 @@ class SSHConnection(): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': Usage() sys.exit('Insufficient Parameter') - initialize_eNB_flag = False - pStatus = self.CheckProcessExist(initialize_eNB_flag) + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', pStatus) self.AutoTerminateUEandeNB() @@ -736,8 +1069,9 @@ class SSHConnection(): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': Usage() sys.exit('Insufficient Parameter') - initialize_eNB_flag = False - pStatus = self.CheckProcessExist(initialize_eNB_flag) + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', pStatus) self.AutoTerminateUEandeNB() @@ -800,8 +1134,9 @@ class SSHConnection(): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': Usage() sys.exit('Insufficient Parameter') - initialize_eNB_flag = False - pStatus = self.CheckProcessExist(initialize_eNB_flag) + check_eNB = True + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', pStatus) self.CreateHtmlTabFooter(False) @@ -848,6 +1183,18 @@ class SSHConnection(): sys.exit('Insufficient Parameter') ue_ip_status = 0 self.UEIPAddresses = [] + if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): + if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': + Usage() + sys.exit('Insufficient Parameter') + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('ifconfig oaitun_ue1', '\$', 4) + result = re.search('inet addr:(?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)', str(self.ssh.before)) + UE_IPAddress = result.group('ueipaddress') + logging.debug('\u001B[1mUE (' + self.UEDevices[0] + ') IP Address is ' + UE_IPAddress + '\u001B[0m') + self.UEIPAddresses.append(UE_IPAddress) + self.close() + return ue_ip_status self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) for device_id in self.UEDevices: count = 0 @@ -867,7 +1214,7 @@ class SSHConnection(): logging.debug('\u001B[1mUE (' + device_id + ') IP Address is ' + UE_IPAddress + '\u001B[0m') for ueipaddress in self.UEIPAddresses: if ueipaddress == UE_IPAddress: - logging.debug('\u001B[1mUE (' + device_id + ') IP Address ' + UE_IPAddress + 'has been existed!' + '\u001B[0m') + logging.debug('\u001B[1mUE (' + device_id + ') IP Address ' + UE_IPAddress + ': has already been allocated to another device !' + '\u001B[0m') ue_ip_status -= 1 continue self.UEIPAddresses.append(UE_IPAddress) @@ -893,24 +1240,28 @@ class SSHConnection(): if ping_status < 0: message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!' logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.close() self.ping_iperf_wrong_exit(lock, UE_IPAddress, 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.close() self.ping_iperf_wrong_exit(lock, UE_IPAddress, 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.close() self.ping_iperf_wrong_exit(lock, UE_IPAddress, 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.close() self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) return rtt_min = result.group('rtt_min') @@ -948,19 +1299,119 @@ class SSHConnection(): except: os.kill(os.getppid(),signal.SIGUSR1) + def PingNoS1(self): + check_eNB = True + check_OAI_UE = True + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) + if (pStatus < 0): + self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + self.AutoTerminateUEandeNB() + self.CreateHtmlTabFooter(False) + sys.exit(1) + ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args)) + if ping_from_eNB is not None: + if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '': + Usage() + sys.exit('Insufficient Parameter') + else: + if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': + Usage() + sys.exit('Insufficient Parameter') + try: + if ping_from_eNB is not None: + self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) + self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets/', '\$', 5) + else: + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('cd ' + self.UESourceCodePath + '/cmake_targets/', '\$', 5) + self.command('cd cmake_targets', '\$', 5) + ping_time = re.findall("-c (\d+)",str(self.ping_args)) + ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '.log', '\$', int(ping_time[0])*1.5) + # TIMEOUT CASE + if ping_status < 0: + message = 'Ping with OAI UE crashed due to TIMEOUT!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + 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') + return + packetloss = result.group('packetloss') + if float(packetloss) == 100: + message = 'Packet Loss is 100%' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + 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') + 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' + logging.debug('\u001B[1;37;44m OAI UE ping result \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') + self.close() + html_queue = SimpleQueue() + ip_addr = 'TBD' + html_cell = '
OAI UE ping result\n' + qMsg + '
' + html_queue.put(html_cell) + if packetLossOK: + self.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) + else: + self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) + + # copying on the EPC server for logCollection + if ping_from_eNB is not None: + copyin_res = self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') + else: + copyin_res = self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') + if (copyin_res == 0): + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'ping_' + self.testCase_id + '.log', self.EPCSourceCodePath + '/scripts') + except: + os.kill(os.getppid(),signal.SIGUSR1) + def Ping(self): + result = re.search('noS1', str(self.Initialize_eNB_args)) + if result is not None: + self.PingNoS1() + return 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) + check_eNB = True + if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): + check_OAI_UE = True + else: + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) + self.AutoTerminateUEandeNB() self.CreateHtmlTabFooter(False) sys.exit(1) ueIpStatus = self.GetAllUEIPAddresses() if (ueIpStatus < 0): self.CreateHtmlTestRow(self.ping_args, 'KO', UE_IP_ADDRESS_ISSUE) + self.AutoTerminateUEandeNB() self.CreateHtmlTabFooter(False) sys.exit(1) multi_jobs = [] @@ -1301,8 +1752,12 @@ class SSHConnection(): self.close() # Launch iperf client on UE - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) + if (device_id == 'OAI-UE'): + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) + else: + self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) iperf_time = self.Iperf_ComputeTime() time.sleep(0.5) @@ -1314,12 +1769,16 @@ class SSHConnection(): time.sleep(0.5) self.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) - iperf_status = self.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee -a iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + if (device_id == 'OAI-UE'): + iperf_status = self.command('iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + ' -B ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee -a iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + else: + iperf_status = self.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee -a iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) # TIMEOUT Case if iperf_status < 0: self.close() message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.close() self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) return clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) @@ -1336,6 +1795,10 @@ class SSHConnection(): os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) + # in case of OAI-UE + if (device_id == 'OAI-UE'): + self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.') + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): try: @@ -1344,43 +1807,60 @@ class SSHConnection(): return useIperf3 = False udpIperf = True - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - # if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it - self.command('if [ ! -d ' + self.EPCSourceCodePath + '/scripts ]; then mkdir -p ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5) - self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - # Checking if iperf / iperf3 are installed - self.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5) - result = re.search('iperf3', str(self.ssh.before)) - if result is None: - result = re.search('iperf', str(self.ssh.before)) + if (device_id != 'OAI-UE'): + self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + # if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it + self.command('if [ ! -d ' + self.EPCSourceCodePath + '/scripts ]; then mkdir -p ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5) + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) + # Checking if iperf / iperf3 are installed + self.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5) + result = re.search('iperf3', str(self.ssh.before)) if result is None: - message = 'Neither iperf nor iperf3 installed on UE!' - logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') - self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) - return - else: - useIperf3 = True + result = re.search('iperf', str(self.ssh.before)) + if result is None: + message = 'Neither iperf nor iperf3 installed on UE!' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + self.close() + self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, message) + return + else: + useIperf3 = True + self.close() # in case of iperf, UL has its own function if (not useIperf3): result = re.search('-R', str(self.iperf_args)) if result is not None: - self.close() self.Iperf_UL_common(lock, UE_IPAddress, device_id, idx, ue_num, statusQueue) return - if (useIperf3): - self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) - else: + # Launch the IPERF server on the UE side for DL + if (device_id == 'OAI-UE'): + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) result = re.search('-u', str(self.iperf_args)) if result is None: - self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + self.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) udpIperf = False else: - self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + self.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -u -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) + else: + self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) + if (useIperf3): + self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) + else: + self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + result = re.search('-u', str(self.iperf_args)) + if result is None: + self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + udpIperf = False + else: + self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) time.sleep(0.5) self.close() + # Launch the IPERF client on the EPC side for DL self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) iperf_time = self.Iperf_ComputeTime() @@ -1400,6 +1880,7 @@ class SSHConnection(): self.Iperf_analyzeV3Output(lock, UE_IPAddress, device_id, statusQueue) else: iperf_status = self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee -a iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + if iperf_status < 0: self.close() message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' @@ -1409,28 +1890,154 @@ class SSHConnection(): clientStatus = self.Iperf_analyzeV2Output(lock, UE_IPAddress, device_id, statusQueue, modified_options) self.close() - self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - self.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5) - result = re.search('shell +(?P\d+)', str(self.ssh.before)) - if result is not None: - pid_iperf = result.group('pid') - self.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5) + # Kill the IPERF server that runs in background + if (device_id == 'OAI-UE'): + self.open(self.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('killall iperf', '\$', 5) + else: + self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + self.command('stdbuf -o0 adb -s ' + device_id + ' shell ps | grep --color=never iperf | grep -v grep', '\$', 5) + result = re.search('shell +(?P\d+)', str(self.ssh.before)) + if result is not None: + pid_iperf = result.group('pid') + self.command('stdbuf -o0 adb -s ' + device_id + ' shell kill -KILL ' + pid_iperf, '\$', 5) self.close() + # if the client report is absent, try to analyze the server log file if (clientStatus == -1): time.sleep(1) if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') - self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + if (device_id == 'OAI-UE'): + self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + else: + self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) + + # in case of OAI UE: + if (device_id == 'OAI-UE'): + if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): + pass + else: + self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', self.EPCSourceCodePath + '/scripts') except: os.kill(os.getppid(),signal.SIGUSR1) + def IperfNoS1(self): + check_eNB = True + check_OAI_UE = True + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) + if (pStatus < 0): + self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) + self.AutoTerminateUEandeNB() + self.CreateHtmlTabFooter(False) + sys.exit(1) + if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': + Usage() + sys.exit('Insufficient Parameter') + server_on_enb = re.search('-R', str(self.iperf_args)) + if server_on_enb is not None: + iServerIPAddr = self.eNBIPAddress + iServerUser = self.eNBUserName + iServerPasswd = self.eNBPassword + iClientIPAddr = self.UEIPAddress + iClientUser = self.UEUserName + iClientPasswd = self.UEPassword + else: + iServerIPAddr = self.UEIPAddress + iServerUser = self.UEUserName + iServerPasswd = self.UEPassword + iClientIPAddr = self.eNBIPAddress + iClientUser = self.eNBUserName + iClientPasswd = self.eNBPassword + # Starting the iperf server + self.open(iServerIPAddr, iServerUser, iServerPasswd) + # args SHALL be "-c client -u any" + # -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1 + # -B 10.0.1.1 -u -s -i 1 -fm + server_options = re.sub('-u.*$', '-u -s -i 1 -fm', str(self.iperf_args)) + server_options = server_options.replace('-c','-B') + self.command('rm -f /tmp/tmp_iperf_server_' + self.testCase_id + '.log', '\$', 5) + self.command('echo $USER; nohup iperf ' + server_options + ' > /tmp/tmp_iperf_server_' + self.testCase_id + '.log 2>&1 &', iServerUser, 5) + time.sleep(0.5) + self.close() + + # Starting the iperf client + modified_options = self.Iperf_ComputeModifiedBW(0, 1) + modified_options = modified_options.replace('-R','') + iperf_time = self.Iperf_ComputeTime() + self.open(iClientIPAddr, iClientUser, iClientPasswd) + self.command('rm -f /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', 5) + iperf_status = self.command('stdbuf -o0 iperf ' + modified_options + ' 2>&1 | stdbuf -o0 tee /tmp/tmp_iperf_' + self.testCase_id + '.log', '\$', int(iperf_time)*5.0) + status_queue = SimpleQueue() + lock = Lock() + if iperf_status < 0: + message = 'iperf on OAI UE crashed due to TIMEOUT !' + logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m') + clientStatus = -2 + else: + clientStatus = self.Iperf_analyzeV2Output(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) + self.close() + + # Stopping the iperf server + self.open(iServerIPAddr, iServerUser, iServerPasswd) + self.command('killall --signal SIGKILL iperf', '\$', 5) + time.sleep(0.5) + self.close() + if (clientStatus == -1): + if (os.path.isfile('iperf_server_' + self.testCase_id + '.log')): + os.remove('iperf_server_' + self.testCase_id + '.log') + self.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') + self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options) + + # copying on the EPC server for logCollection + copyin_res = self.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') + if (copyin_res == 0): + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts') + copyin_res = self.copyin(iClientIPAddr, iClientUser, iClientPasswd, '/tmp/tmp_iperf_' + self.testCase_id + '.log', 'iperf_' + self.testCase_id + '_OAI-UE.log') + if (copyin_res == 0): + self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts') + iperf_noperf = False + if status_queue.empty(): + iperf_status = False + else: + iperf_status = True + html_queue = SimpleQueue() + while (not status_queue.empty()): + count = status_queue.get() + if (count < 0): + iperf_status = False + if (count > 0): + iperf_noperf = True + device_id = status_queue.get() + ip_addr = status_queue.get() + message = status_queue.get() + html_cell = '
UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '
' + html_queue.put(html_cell) + if (iperf_noperf and iperf_status): + self.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) + elif (iperf_status): + self.CreateHtmlTestRowQueue(self.iperf_args, 'OK', len(self.UEDevices), html_queue) + else: + self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) + self.AutoTerminateUEandeNB() + self.CreateHtmlTabFooter(False) + sys.exit(1) + def Iperf(self): + result = re.search('noS1', str(self.Initialize_eNB_args)) + if result is not None: + self.IperfNoS1() + return if self.EPCIPAddress == '' or self.EPCUserName == '' or self.EPCPassword == '' or self.EPCSourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': Usage() sys.exit('Insufficient Parameter') - initialize_eNB_flag = False - pStatus = self.CheckProcessExist(initialize_eNB_flag) + check_eNB = True + if (len(self.UEDevices) == 1) and (self.UEDevices[0] == 'OAI-UE'): + check_OAI_UE = True + else: + check_OAI_UE = False + pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) self.AutoTerminateUEandeNB() @@ -1487,26 +2094,37 @@ class SSHConnection(): self.CreateHtmlTabFooter(False) sys.exit(1) - def CheckProcessExist(self, initialize_eNB_flag): + def CheckProcessExist(self, check_eNB, check_OAI_UE): multi_jobs = [] status_queue = SimpleQueue() - p = Process(target = SSH.CheckHSSProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - p = Process(target = SSH.CheckMMEProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - p = Process(target = SSH.CheckSPGWProcess, args = (status_queue,)) - p.daemon = True - p.start() - multi_jobs.append(p) - if initialize_eNB_flag == False: + # in noS1 config, no need to check status from EPC + result = re.search('noS1', str(self.Initialize_eNB_args)) + if result is None: + p = Process(target = SSH.CheckHSSProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) + p = Process(target = SSH.CheckMMEProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) + p = Process(target = SSH.CheckSPGWProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) + else: + if (check_eNB == False) and (check_OAI_UE == False): + return 0 + if check_eNB: p = Process(target = SSH.CheckeNBProcess, args = (status_queue,)) p.daemon = True p.start() multi_jobs.append(p) + if check_OAI_UE: + p = Process(target = SSH.CheckOAIUEProcess, args = (status_queue,)) + p.daemon = True + p.start() + multi_jobs.append(p) for job in multi_jobs: job.join() @@ -1525,12 +2143,55 @@ class SSHConnection(): logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFile) if logStatus < 0: result = logStatus + self.eNBLogFile = '' 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('ue_', 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.UEIPAddress, self.UEUserName, self.UEPassword) + self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 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) - self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never lte-softmodem', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) result = re.search('lte-softmodem', str(self.ssh.before)) if result is None: logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m') @@ -1544,7 +2205,7 @@ class SSHConnection(): def CheckHSSProcess(self, status_queue): try: self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never hss', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep --color=never hss | grep -v grep', '\$', 5) if re.match('OAI', self.EPCType, re.IGNORECASE): result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) else: @@ -1561,7 +2222,7 @@ class SSHConnection(): def CheckMMEProcess(self, status_queue): try: self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) - self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never mme', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep --color=never mme | grep -v grep', '\$', 5) if re.match('OAI', self.EPCType, re.IGNORECASE): result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) else: @@ -1579,10 +2240,10 @@ class SSHConnection(): try: self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) if re.match('OAI', self.EPCType, re.IGNORECASE): - self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never spgw', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep --color=never spgw | grep -v grep', '\$', 5) result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) else: - self.command('stdbuf -o0 ps -aux | grep -v grep | grep --color=never xGw', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep --color=never xGw | grep -v grep', '\$', 5) result = re.search('xGw', str(self.ssh.before)) if result is None: logging.debug('\u001B[1;37;41m SPGW Process Not Found! \u001B[0m') @@ -1597,12 +2258,12 @@ class SSHConnection(): if (not os.path.isfile('./' + eNBlogFile)): return -1 enb_log_file = open('./' + eNBlogFile, 'r') + exitSignalReceived = False foundAssertion = False msgAssertion = '' msgLine = 0 foundSegFault = False foundRealTimeIssue = False - rrcSetupRequest = 0 rrcSetupComplete = 0 rrcReleaseRequest = 0 rrcReconfigRequest = 0 @@ -1615,18 +2276,33 @@ class SSHConnection(): uciStatMsgCount = 0 pdcpFailure = 0 ulschFailure = 0 + cdrxActivationMessageCount = 0 + self.htmleNBFailureMsg = '' for line in enb_log_file.readlines(): - result = re.search('[Ss]egmentation [Ff]ault', str(line)) + 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('Exiting OAI softmodem', str(line)) if result is not None: + exitSignalReceived = True + result = re.search('[Ss]egmentation [Ff]ault', str(line)) + if result is not None and not exitSignalReceived: foundSegFault = True result = re.search('[Cc]ore [dD]ump', str(line)) - if result is not None: + if result is not None and not exitSignalReceived: foundSegFault = True result = re.search('[Aa]ssertion', str(line)) - if result is not None: + if result is not None and not exitSignalReceived: foundAssertion = True result = re.search('LLL', str(line)) - if result is not None: + if result is not None and not exitSignalReceived: foundRealTimeIssue = True if foundAssertion and (msgLine < 3): msgLine += 1 @@ -1655,6 +2331,9 @@ class SSHConnection(): result = re.search('LTE_RRCConnectionReestablishmentReject|RRCConnectionReestablishmentReject', str(line)) if result is not None: rrcReestablishReject += 1 + result = re.search('CDRX configuration activated after RRC Connection', str(line)) + if result is not None: + cdrxActivationMessageCount += 1 result = re.search('uci->stat', str(line)) if result is not None: uciStatMsgCount += 1 @@ -1671,7 +2350,7 @@ class SSHConnection(): if result is not None: rachCanceledProcedure += 1 enb_log_file.close() - self.htmleNBFailureMsg = '' + logging.debug(' File analysis completed') if uciStatMsgCount > 0: statMsg = 'eNB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') @@ -1684,11 +2363,8 @@ class SSHConnection(): statMsg = 'eNB showed ' + str(ulschFailure) + ' "ULSCH in error in round" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') self.htmleNBFailureMsg += statMsg + '\n' - if rrcSetupRequest > 0 or rrcSetupComplete > 0: - rrcMsg = 'eNB requested ' + str(rrcSetupRequest) + ' RRC Connection Setup(s)' - logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') - self.htmleNBFailureMsg += rrcMsg + '\n' - rrcMsg = ' -- ' + str(rrcSetupComplete) + ' were completed' + if rrcSetupComplete > 0: + rrcMsg = 'eNB completed ' + str(rrcSetupComplete) + ' RRC Connection Setup(s)' logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') self.htmleNBFailureMsg += rrcMsg + '\n' if rrcReleaseRequest > 0: @@ -1712,6 +2388,10 @@ class SSHConnection(): rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected' logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') self.htmleNBFailureMsg += rrcMsg + '\n' + if cdrxActivationMessageCount > 0: + rrcMsg = 'eNB activated the CDRX Configuration for ' + str(cdrxActivationMessageCount) + ' time(s)' + logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rrcMsg + '\n' if rachCanceledProcedure > 0: rachMsg = 'eNB cancelled ' + str(rachCanceledProcedure) + ' RA procedure(s)' logging.debug('\u001B[1;30;43m ' + rachMsg + ' \u001B[0m') @@ -1734,9 +2414,175 @@ 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') + exitSignalReceived = False + foundAssertion = False + msgAssertion = '' + msgLine = 0 + foundSegFault = False + foundRealTimeIssue = False + uciStatMsgCount = 0 + pdcpDataReqFailedCount = 0 + badDciCount = 0 + rrcConnectionRecfgComplete = 0 + no_cell_sync_found = False + mib_found = False + frequency_found = False + plmn_found = False + self.htmlUEFailureMsg = '' + for line in ue_log_file.readlines(): + result = re.search('Exiting OAI softmodem', str(line)) + if result is not None: + exitSignalReceived = True + result = re.search('System error|[Ss]egmentation [Ff]ault|======= Backtrace: =========|======= Memory map: ========', str(line)) + if result is not None and not exitSignalReceived: + foundSegFault = True + result = re.search('[Cc]ore [dD]ump', str(line)) + if result is not None and not exitSignalReceived: + foundSegFault = True + result = re.search('[Aa]ssertion', str(line)) + if result is not None and not exitSignalReceived: + foundAssertion = True + result = re.search('LLL', str(line)) + if result is not None and not exitSignalReceived: + foundRealTimeIssue = True + if foundAssertion and (msgLine < 3): + msgLine += 1 + msgAssertion += str(line) + result = re.search('uci->stat', str(line)) + if result is not None and not exitSignalReceived: + uciStatMsgCount += 1 + result = re.search('PDCP data request failed', str(line)) + if result is not None and not exitSignalReceived: + pdcpDataReqFailedCount += 1 + result = re.search('bad DCI 1A', str(line)) + if result is not None and not exitSignalReceived: + badDciCount += 1 + result = re.search('Generating RRCConnectionReconfigurationComplete', str(line)) + if result is not None: + rrcConnectionRecfgComplete += 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("PLMN MCC (?P\d{1,3}), MNC (?P\d{1,3}), TAC", str(line)) + if result is not None and (not plmn_found): + try: + mibMsg = 'PLMN MCC = ' + result.group('mcc') + ' MNC = ' + result.group('mnc') + self.htmlUEFailureMsg += mibMsg + '\n' + logging.debug('\033[94m' + mibMsg + '\033[0m') + plmn_found = True + except Exception as e: + logging.error('\033[91m' + "PLMN 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 rrcConnectionRecfgComplete > 0: + statMsg = 'UE connected to eNB (' + str(rrcConnectionRecfgComplete) + ' RRCConnectionReconfigurationComplete message(s) generated)' + logging.debug('\033[94m' + statMsg + '\033[0m') + self.htmlUEFailureMsg += statMsg + '\n' + 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 pdcpDataReqFailedCount > 0: + statMsg = 'UE showed ' + str(pdcpDataReqFailedCount) + ' "PDCP data request failed" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmlUEFailureMsg += statMsg + '\n' + if badDciCount > 0: + statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1A" message(s)' + logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') + self.htmlUEFailureMsg += statMsg + '\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;30;43m UE showed an assertion! \u001B[0m') + self.htmlUEFailureMsg += 'UE showed an assertion!\n' + if not mib_found or not frequency_found: + return OAI_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 OAI_UE_PROCESS_COULD_NOT_SYNC + return 0 + def TerminateeNB(self): self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5) +<<<<<<< HEAD self.command('echo ' + self.eNBPassword + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5) self.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGINT lte-softmodem || true', '\$', 5) @@ -1746,6 +2592,20 @@ class SSHConnection(): if result is not None: self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5) time.sleep(5) +======= + self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) + result = re.search('lte-softmodem', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.eNBPassword + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5) + self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGINT lte-softmodem || true', '\$', 5) + time.sleep(5) + self.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) + result = re.search('lte-softmodem', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5) + time.sleep(2) + self.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) +>>>>>>> develop self.close() # If tracer options is on, stopping tshark on EPC side result = re.search('T_stdout', str(self.Initialize_eNB_args)) @@ -1754,10 +2614,17 @@ class SSHConnection(): logging.debug('\u001B[1m Stopping tshark \u001B[0m') self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) time.sleep(1) +<<<<<<< HEAD pcap_log_file = self.eNBLogFile.replace('.log', '_s1log.pcap') self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + pcap_log_file, '\$', 5) self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + pcap_log_file, '.') self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, pcap_log_file, self.eNBSourceCodePath + '/cmake_targets/.') +======= + if self.EPC_PcapFileName != '': + self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + self.EPC_PcapFileName, '\$', 5) + self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + self.EPC_PcapFileName, '.') + self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.EPC_PcapFileName, self.eNBSourceCodePath + '/cmake_targets/.') +>>>>>>> develop self.close() logging.debug('\u001B[1m Replaying RAW record file\u001B[0m') self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) @@ -1777,23 +2644,48 @@ class SSHConnection(): self.eNBLogFile = '' else: result = re.search('enb_', str(self.eNBLogFile)) +<<<<<<< HEAD if result is not None: copyin_res = self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFile, '.') +======= + analyzeFile = False + if result is not None: + analyzeFile = True + fileToAnalyze = str(self.eNBLogFile) + self.eNBLogFile = '' + else: + result = re.search('enb_', str(self.rruLogFile)) + if result is not None: + analyzeFile = True + fileToAnalyze = str(self.rruLogFile) + self.rruLogFile = '' + if analyzeFile: + copyin_res = self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + fileToAnalyze, '.') +>>>>>>> develop if (copyin_res == -1): logging.debug('\u001B[1;37;41m Could not copy eNB logfile to analyze it! \u001B[0m') self.htmleNBFailureMsg = 'Could not copy eNB logfile to analyze it!' self.CreateHtmlTestRow('N/A', 'KO', ENB_PROCESS_NOLOGFILE_TO_ANALYZE) +<<<<<<< HEAD self.eNBLogFile = '' return logging.debug('\u001B[1m Analyzing eNB logfile \u001B[0m') logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFile) +======= + return + logging.debug('\u001B[1m Analyzing eNB logfile \u001B[0m') + logStatus = self.AnalyzeLogFile_eNB(fileToAnalyze) +>>>>>>> develop if (logStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', logStatus) self.CreateHtmlTabFooter(False) sys.exit(1) else: self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) +<<<<<<< HEAD self.eNBLogFile = '' +======= +>>>>>>> develop else: self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) @@ -1802,7 +2694,7 @@ class SSHConnection(): if re.match('OAI', self.EPCType, re.IGNORECASE): self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_hss oai_hss || true', '\$', 5) time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep -v grep | grep hss', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep hss | grep -v grep', '\$', 5) result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) if result is not None: self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_hss oai_hss || true', '\$', 5) @@ -1821,7 +2713,7 @@ class SSHConnection(): if re.match('OAI', self.EPCType, re.IGNORECASE): self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_mme mme || true', '\$', 5) time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep -v grep | grep mme', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep mme | grep -v grep', '\$', 5) result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) if result is not None: self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_mme mme || true', '\$', 5) @@ -1836,7 +2728,7 @@ class SSHConnection(): if re.match('OAI', self.EPCType, re.IGNORECASE): self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGINT run_spgw spgw || true', '\$', 5) time.sleep(2) - self.command('stdbuf -o0 ps -aux | grep -v grep | grep spgw', '\$', 5) + self.command('stdbuf -o0 ps -aux | grep spgw | grep -v grep', '\$', 5) result = re.search('\/bin\/bash .\/run_', str(self.ssh.before)) if result is not None: self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL run_spgw spgw || true', '\$', 5) @@ -1874,28 +2766,103 @@ 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('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) + result = re.search('lte-uesoftmodem', str(self.ssh.before)) + if result is not None: + self.command('echo ' + self.UEPassword + ' | sudo -S daemon --name=ue' + str(self.UE_instance) + '_daemon --stop', '\$', 5) + self.command('echo ' + self.UEPassword + ' | sudo -S killall --signal SIGINT lte-uesoftmodem || true', '\$', 5) + time.sleep(5) + self.command('ps -aux | grep --color=never softmodem | grep -v grep', '\$', 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(2) + self.command('rm -f my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) + self.close() + result = re.search('ue_', str(self.UELogFile)) + if result is not None: + copyin_res = self.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') + if (copyin_res == -1): + logging.debug('\u001B[1;37;41m Could not copy UE logfile to analyze it! \u001B[0m') + self.htmlUEFailureMsg = 'Could not copy UE logfile to analyze it!' + self.CreateHtmlTestRow('N/A', 'KO', OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE') + self.UELogFile = '' + return + logging.debug('\u001B[1m Analyzing UE logfile \u001B[0m') + logStatus = self.AnalyzeLogFile_UE(self.UELogFile) + result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) + if result is not None: + ueAction = 'Sniffing' + else: + ueAction = 'Connection' + if (logStatus < 0): + logging.debug('\u001B[1m' + ueAction + ' Failed \u001B[0m') + self.htmlUEFailureMsg = '' + ueAction + ' Failed\n' + self.htmlUEFailureMsg + self.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE') + # In case of sniffing on commercial eNBs we have random results + # Not an error then + if (logStatus != OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'): + self.Initialize_OAI_UE_args = '' + self.AutoTerminateUEandeNB() + self.CreateHtmlTabFooter(False) + sys.exit(1) + else: + logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m') + self.htmlUEFailureMsg = '' + ueAction + ' Completed\n' + self.htmlUEFailureMsg + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + self.UELogFile = '' + else: + self.htmlUEFailureMsg = 'No Log File to analyze!' + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + def AutoTerminateUEandeNB(self): - self.testCase_id = 'AUTO-KILL-UE' - self.desc = 'Automatic Termination of UE' - self.ShowTestID() - self.TerminateUE() - self.testCase_id = 'AUTO-KILL-eNB' - self.desc = 'Automatic Termination of eNB' - self.ShowTestID() - self.eNB_instance = '0' - self.TerminateeNB() + if (self.ADBIPAddress != 'none'): + self.testCase_id = 'AUTO-KILL-UE' + self.desc = 'Automatic Termination of UE' + self.ShowTestID() + self.TerminateUE() + if (self.Initialize_OAI_UE_args != ''): + self.testCase_id = 'AUTO-KILL-UE' + self.desc = 'Automatic Termination of UE' + self.ShowTestID() + self.TerminateOAIUE() + if (self.Initialize_eNB_args != ''): + self.testCase_id = 'AUTO-KILL-eNB' + self.desc = 'Automatic Termination of eNB' + self.ShowTestID() + self.eNB_instance = '0' + self.TerminateeNB() + + def IdleSleep(self): + time.sleep(self.idle_sleep_time) + self.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', ALL_PROCESSES_OK) def IdleSleep(self): time.sleep(self.idle_sleep_time) 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): @@ -1964,6 +2931,7 @@ class SSHConnection(): self.command('zip spgw.log.zip xGwLog.0', '\$', 60) self.close() +<<<<<<< HEAD def RetrieveSystemVersion(self): if self.eNBIPAddress == 'none': self.eNBOsVersion = 'Ubuntu 16.04.5 LTS' @@ -2001,6 +2969,72 @@ class SSHConnection(): logging.debug('model: ' + self.eNBCpuModel) self.eNBCpuMHz = result.group('cpu_mhz') + ' MHz' logging.debug('cpu_mhz: ' + self.eNBCpuMHz) +======= + 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, machine): + if self.eNBIPAddress == 'none' or self.UEIPAddress == '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 0 + if machine == 'eNB': + if self.eNBIPAddress != '' and self.eNBUserName != '' and self.eNBPassword != '': + IPAddress = self.eNBIPAddress + UserName = self.eNBUserName + Password = self.eNBPassword + else: + return -1 + if machine == 'UE': + if self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != '': + IPAddress = self.UEIPAddress + UserName = self.UEUserName + Password = self.UEPassword + else: + return -1 + + 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.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.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.UhdVersion = result.group('uhd_version') + logging.debug('UHD Version is: ' + self.UhdVersion) + self.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 15) + 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.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) +>>>>>>> develop self.close() #----------------------------------------------------------- @@ -2008,6 +3042,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') @@ -2085,6 +3122,7 @@ class SSHConnection(): self.htmlFile.write(' \n') self.htmlFile.write(' \n') +<<<<<<< HEAD terminate_ue_flag = True if (self.ADBIPAddress != 'none'): self.GetAllUEDevices(terminate_ue_flag) @@ -2097,6 +3135,19 @@ class SSHConnection(): 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') +======= + if (self.ADBIPAddress != 'none'): + terminate_ue_flag = True + self.GetAllUEDevices(terminate_ue_flag) + self.GetAllCatMDevices(terminate_ue_flag) + 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') + else: + self.UEDevices.append('OAI-UE') + self.htmlUEConnected = len(self.UEDevices) + self.htmlFile.write('

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

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