Commit 7ca58890 authored by Raphael Defosseux's avatar Raphael Defosseux
Browse files

Merge remote-tracking branch 'origin/master' into helm-charts

parents c7b6c4fa ec517f7b
------------------------------------------------------------------------------
OPENAIR-CN-5G
An implementation of the 5G Core network by the OpenAirInterface community.
------------------------------------------------------------------------------
OPENAIR-CN-5G is an implementation of the 3GPP specifications for the 5G Core Network.
<h1 align="center">
<a href="https://openairinterface.org/"><img src="https://openairinterface.org/wp-content/uploads/2015/06/cropped-oai_final_logo.png" alt="OAI" width="550"></a>
</h1>
<p align="center">
<a href="https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed/-/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-OAI--Public--V1.1-blue" alt="License"></a>
<a href="https://jenkins-oai.eurecom.fr/job/OAI-CN5G-AMF/"><img src="https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins-oai.eurecom.fr%2Fjob%2FOAI-CN5G-AMF%2F&label=build%20AMF"></a>
<a href="https://jenkins-oai.eurecom.fr/job/OAI-CN5G-NRF/"><img src="https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins-oai.eurecom.fr%2Fjob%2FOAI-CN5G-NRF%2F&label=build%20NRF"></a>
<a href="https://jenkins-oai.eurecom.fr/job/OAI-CN5G-SMF/"><img src="https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins-oai.eurecom.fr%2Fjob%2FOAI-CN5G-SMF%2F&label=build%20SMF"></a>
</p>
<h2 align="center">
OPENAIR-CN-5G: An implementation of the 5G Core network by the OpenAirInterface community.
</h2>
`OPENAIR-CN-5G` is an implementation of the 3GPP specifications for the 5G Core Network.
At the moment, it contains the following network elements:
* Access and Mobility Management Function (**AMF**)
* Session Management Function (**SMF**)
* User Plane Function (**UPF**)
Each has its own repository.
* Access and Mobility Management Function (**[AMF](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-amf)**)
* Authentication Server Management Function (**AUSF**)
* Network Repository Function (**[NRF](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-nrf)**)
* Session Management Function (**[SMF](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-smf)**)
* Unified Data Management (**UDM**)
* Unified Data Repository (**UDR**)
* User Plane Function (**UPF**) with 2 variants:
* Simple Implementation based on our 4G CUPS component (**[SPGWU-TINY](https://github.com/OPENAIRINTERFACE/openair-spgwu-tiny)**)
* VPP-Based Implementation (**UPF-VPP**)
Each has its own repository. Some of these repositories are still private, soon to be released.
This repository is a **Federation of the OpenAir CN 5G repositories**.
......
......@@ -38,9 +38,6 @@ def cn_ci_host = params.Host_CN_CI_Server
def cn_ci_resource = params.DockerContainers
def ds_tester_ci_resource = params.DsTester
// Location of the DsTester workspace
def dsTestFrameworkLocation = params.dsTestFrameworkLocation
// When triggered by upstream, specify which tag to use
def upstreamTagToUse = params.upstreamTagToUse
......@@ -58,6 +55,7 @@ def dsT_host_ip_addr = ""
// Flags
def scmEvent = false
def upstreamEvent = false
def deployed = true
// Default tags / branches --> could be passed on by upstream job or by PR content
def nrfTag = params.nrfTag
......@@ -165,6 +163,14 @@ pipeline {
smfBranch = params.SMF_BRANCH
echo "Upstream Job passed SMF_BRANCH to use: ${smfBranch}"
}
if (params.SPGWU_TAG != null) {
spgwuTag = params.SPGWU_TAG
echo "Upstream Job passed SPGWU_TAG to use: ${spgwuTag}"
}
if (params.SPGWU_BRANCH != null) {
spgwuBranch = params.SPGWU_BRANCH
echo "Upstream Job passed SPGWU_BRANCH to use: ${spgwuBranch}"
}
sh "git clean -x -d -f > /dev/null 2>&1"
sh "git fetch --prune > /dev/null 2>&1"
sh 'git checkout -f ' + upstreamTagToUse
......@@ -238,16 +244,10 @@ pipeline {
stage ('Deploy Whole 5G Core Network') {
steps {
script {
echo '\u2705 \u001B[32mDeploy CN5G in idle mode\u001B[0m'
echo '\u2705 \u001B[32mDeploy CN5G using Docker-Compose\u001B[0m'
// Prepare all needed files for docker-compose
// First put all correct tags to test
sh 'sed -e "s#NRF_IMAGE_TAG#' + nrfTag + '#" -e "s#AMF_IMAGE_TAG#' + amfTag + '#" -e "s#SMF_IMAGE_TAG#' + smfTag + '#" -e "s#SPGWU_IMAGE_TAG#' + spgwuTag + '#" ci-scripts/dsTesterDockerCompose/docker-compose.tplt > ci-scripts/dsTesterDockerCompose/docker-compose.yml'
// Entrypoints are modified to be inactive for dsTester framework
sh 'sed -e "s@exec.*@sleep infinity@" component/oai-nrf/scripts/entrypoint.sh > ci-scripts/dsTesterDockerCompose/nrf-entrypoint-sleep.sh'
sh 'sed -e "s@exec.*@sleep infinity@" component/oai-amf/scripts/entrypoint.sh > ci-scripts/dsTesterDockerCompose/amf-entrypoint-sleep.sh'
sh 'sed -e "s@exec.*@sleep infinity@" component/oai-smf/scripts/entrypoint.sh > ci-scripts/dsTesterDockerCompose/smf-entrypoint-sleep.sh'
sh 'sed -e "s@exec.*@sleep infinity@" component/oai-upf-equivalent/scripts/entrypoint.sh > ci-scripts/dsTesterDockerCompose/upf-entrypoint-sleep.sh'
sh 'chmod 775 ci-scripts/dsTesterDockerCompose/*entrypoint-sleep.sh'
dir('ci-scripts/dsTesterDockerCompose') {
sh 'docker-compose up -d > ../../archives/compose_5gcn_up.log 2>&1'
sh 'sleep 100'
......@@ -273,25 +273,25 @@ pipeline {
}
// Do docker logs to recover the configuration results
try {
sh 'docker logs cicd-oai-nrf > archives/nrf_config.log 2>&1'
//sh 'docker logs cicd-oai-nrf > archives/nrf_config.log 2>&1'
sh 'docker inspect --format=\'STATUS: {{.State.Health.Status}}\' cicd-oai-nrf >> archives/nrf_config.log'
} catch (Exception e) {
sh 'echo "STATUS: KO" >> archives/nrf_config.log'
}
try {
sh 'docker logs cicd-oai-amf > archives/amf_config.log 2>&1'
//sh 'docker logs cicd-oai-amf > archives/amf_config.log 2>&1'
sh 'docker inspect --format=\'STATUS: {{.State.Health.Status}}\' cicd-oai-amf >> archives/amf_config.log'
} catch (Exception e) {
sh 'echo "STATUS: KO" >> archives/amf_config.log'
}
try {
sh 'docker logs cicd-oai-smf > archives/smf_config.log 2>&1'
//sh 'docker logs cicd-oai-smf > archives/smf_config.log 2>&1'
sh 'docker inspect --format=\'STATUS: {{.State.Health.Status}}\' cicd-oai-smf >> archives/smf_config.log'
} catch (Exception e) {
sh 'echo "STATUS: OK" >> archives/smf_config.log'
}
try {
sh 'docker logs cicd-oai-upf > archives/spgwu_config.log 2>&1'
//sh 'docker logs cicd-oai-upf > archives/spgwu_config.log 2>&1'
sh 'docker inspect --format=\'STATUS: {{.State.Health.Status}}\' cicd-oai-upf >> archives/spgwu_config.log'
} catch (Exception e) {
sh 'echo "STATUS: KO" >> archives/spgwu_config.log'
......@@ -301,11 +301,13 @@ pipeline {
success {
script {
sh 'echo "DEPLOYMENT: OK" > archives/deployment_status.log'
sh 'python3 ./ci-scripts/routeCheck.py --mode=Add --userName=' + dsT_host_user + ' --hostName=' + dsT_host
}
}
unsuccessful {
script {
sh 'echo "DEPLOYMENT: KO" > archives/deployment_status.log'
deployed = false
}
}
}
......@@ -315,11 +317,46 @@ pipeline {
steps {
lock (ds_tester_ci_resource) {
script {
sh 'cd ' + dsTestFrameworkLocation + ' && git clean -x -d -f > /dev/null'
sh 'cd ' + dsTestFrameworkLocation + '/scripts && export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:.:/usr/local/devsol/bin && CI_ENV=True SRC_BASE_DIR=' + WORKSPACE + ' ./run-5gc.bash -pt --shark --detach --get-results --5g --pcap-test > ' + WORKSPACE + '/archives/run-5g-dstester.log 2>&1'
sh 'cd ' + dsTestFrameworkLocation + ' && git stash > /dev/null'
sh 'cd ' + dsTestFrameworkLocation + ' && git stash clear > /dev/null'
sh 'cd ' + WORKSPACE + ' && python3 ./ci-scripts/toCheckDSTesterResult.py'
echo '\u2705 \u001B[32mTesting with DS Tester\u001B[0m'
if (fileExists("dstester")) {
sh "rm -Rf dstester > /dev/null 2>&1"
}
sh "mkdir -p dstester"
dir ('dstester') {
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.dsTesterGitLabRepository_Credentials}", usernameVariable: 'git_username', passwordVariable: 'git_token']
]) {
sh "git clone https://${git_username}:${git_token}@github.com/OPENAIRINTERFACE/chasseur.git . > ../git_clone.log 2>&1"
sh "git checkout develop >> ../git_clone.log 2>&1"
try {
sh "python3 jenkins/dogmatix-agent.py -f jenkins/suit-docker-compose.yaml | tee ../DS-TEST-RESULTS/dsTester_Summary.txt"
} catch (Exception e) {
currentBuild.result = 'FAILURE'
echo "dsTester Running FAILED"
}
}
}
sh "python3 ./ci-scripts/toCheckDSTesterResult1.py"
}
}
}
post {
always {
script {
// Copy the pcaps and logs from the containers
sh "mkdir -p archives/pcaps archives/logs"
try {
sh 'docker cp cicd-oai-nrf:/tmp/nrf.pcap archives/pcaps/oai_nrf.pcap'
sh 'docker cp cicd-oai-nrf:/tmp/nrf.log archives/logs/oai_nrf.log'
sh 'docker cp cicd-oai-amf:/tmp/amf.pcap archives/pcaps/oai_amf.pcap'
sh 'docker cp cicd-oai-amf:/tmp/amf.log archives/logs/oai_amf.log'
sh 'docker cp cicd-oai-smf:/tmp/smf.pcap archives/pcaps/oai_smf.pcap'
sh 'docker cp cicd-oai-smf:/tmp/smf.log archives/logs/oai_smf.log'
sh 'docker cp cicd-oai-upf:/tmp/spgwu.pcap archives/pcaps/oai_spgwu.pcap'
sh 'docker cp cicd-oai-upf:/tmp/spgwu.log archives/logs/oai_spgwu.log'
} catch (Exception e) {
sh 'echo "Error in copying pcaps & logs from the containers"'
}
}
}
}
......@@ -328,6 +365,7 @@ pipeline {
steps {
script {
echo '\u2705 \u001B[32mUn-Deploy CN5G\u001B[0m'
sh 'python3 ./ci-scripts/routeCheck.py --mode=Delete --userName=' + dsT_host_user + ' --hostName=' + dsT_host
dir('ci-scripts/dsTesterDockerCompose') {
sh 'docker-compose down > ../../archives/compose_normal_down.log 2>&1'
}
......@@ -337,16 +375,25 @@ pipeline {
}
post {
always {
script {
script {
// Get logs if deployment fail
if (deployed != true) {
sh "mkdir -p archives/logs"
sh 'docker logs cicd-oai-nrf > archives/logs/oai_nrf.log'
sh 'docker logs cicd-oai-amf > archives/logs/oai_amf.log'
sh 'docker logs cicd-oai-smf > archives/logs/oai_smf.log'
sh 'docker logs cicd-oai-upf > archives/logs/oai_spgwu.log'
}
// Remove any leftover containers/networks
sh 'python3 ./ci-scripts/routeCheck.py --mode=Delete --userName=' + dsT_host_user + ' --hostName=' + dsT_host
dir('ci-scripts/dsTesterDockerCompose') {
sh 'docker-compose down > ../../archives/compose_l_down.log 2>&1'
}
// Generating the HTML report
sh 'python3 ./ci-scripts/dsTestGenerateHTMLReport.py --job_name=' + JOB_NAME + ' --job_id=' + BUILD_ID + ' --job_url=' + BUILD_URL
sh 'python3 ./ci-scripts/dsTestGenerateHTMLReport2.py --job_name=' + JOB_NAME + ' --job_id=' + BUILD_ID + ' --job_url=' + BUILD_URL
// Zipping all archived log files
sh "zip -r -qq cn5g_fed_docker_logs.zip archives DS-TEST-RESULTS/*.tar DS-TEST-RESULTS/status.txt"
sh "zip -r -qq cn5g_fed_docker_logs.zip archives DS-TEST-RESULTS"
if (fileExists('cn5g_fed_docker_logs.zip')) {
archiveArtifacts artifacts: 'cn5g_fed_docker_logs.zip'
}
......
#/*
# * 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
# */
#---------------------------------------------------------------------
import os
import re
import sys
import subprocess
import yaml
class HtmlReport():
def __init__(self):
self.job_name = ''
self.job_id = ''
self.job_url = ''
self.job_start_time = 'TEMPLATE_TIME'
def generate(self):
cwd = os.getcwd()
self.file = open(cwd + '/test_results_oai_cn5g.html', 'w')
self.generateHeader()
self.deploymentSummaryHeader()
finalStatus = self.testSummaryHeader()
self.testSummaryDetails()
self.testSummaryFooter()
self.generateFooter()
self.file.close()
if finalStatus:
sys.exit(0)
else:
print("DS-TESTER testing FAILED")
def generateHeader(self):
# HTML Header
self.file.write('<!DOCTYPE html>\n')
self.file.write('<html class="no-js" lang="en-US">\n')
self.file.write('<head>\n')
self.file.write(' <meta name="viewport" content="width=device-width, initial-scale=1">\n')
self.file.write(' <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">\n')
self.file.write(' <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>\n')
self.file.write(' <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>\n')
self.file.write(' <title>OAI 5G Core Network Test Results for ' + self.job_name + ' job build #' + self.job_id + '</title>\n')
self.file.write('</head>\n')
self.file.write('<body><div class="container">\n')
self.file.write(' <table width = "100%" style="border-collapse: collapse; border: none;">\n')
self.file.write(' <tr style="border-collapse: collapse; border: none;">\n')
self.file.write(' <td style="border-collapse: collapse; border: none;">\n')
self.file.write(' <a href="http://www.openairinterface.org/">\n')
self.file.write(' <img src="http://www.openairinterface.org/wp-content/uploads/2016/03/cropped-oai_final_logo2.png" alt="" border="none" height=50 width=150>\n')
self.file.write(' </img>\n')
self.file.write(' </a>\n')
self.file.write(' </td>\n')
self.file.write(' <td style="border-collapse: collapse; border: none; vertical-align: center;">\n')
self.file.write(' <b><font size = "6">Job Summary -- Job: ' + self.job_name + ' -- Build-ID: <a href="' + self.job_url + '">' + self.job_id + '</a></font></b>\n')
self.file.write(' </td>\n')
self.file.write(' </tr>\n')
self.file.write(' </table>\n')
self.file.write(' <br>\n')
def generateFooter(self):
self.file.write(' <div class="well well-lg">End of Test Report -- Copyright <span class="glyphicon glyphicon-copyright-mark"></span> 2020 <a href="http://www.openairinterface.org/">OpenAirInterface</a>. All Rights Reserved.</div>\n')
self.file.write('</div></body>\n')
self.file.write('</html>\n')
def deploymentSummaryHeader(self):
self.file.write(' <h2>Deployment Summary</h2>\n')
cwd = os.getcwd()
if os.path.isfile(cwd + '/archives/deployment_status.log'):
cmd = 'egrep -c "DEPLOYMENT: OK" archives/deployment_status.log || true'
status = False
ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8')
if ret.stdout is not None:
if ret.stdout.strip() == '1':
status = True
if status:
self.file.write(' <div class="alert alert-success">\n')
self.file.write(' <strong>Successful Deployment! <span class="glyphicon glyphicon-warning-sign"></span></strong>\n')
self.file.write(' </div>\n')
else:
self.file.write(' <div class="alert alert-danger">\n')
self.file.write(' <strong>Failed Deployment! <span class="glyphicon glyphicon-warning-sign"></span></strong>\n')
self.file.write(' </div>\n')
else:
self.file.write(' <div class="alert alert-warning">\n')
self.file.write(' <strong>LogFile not available! <span class="glyphicon glyphicon-warning-sign"></span></strong>\n')
self.file.write(' </div>\n')
self.file.write(' <br>\n')
self.file.write(' <button data-toggle="collapse" data-target="#deployment-details">More details on Deployment</button>\n')
self.file.write(' <br>\n')
self.file.write(' <div id="deployment-details" class="collapse">\n')
self.file.write(' <br>\n')
self.file.write(' <table class="table-bordered" width = "80%" align = "center" border = 1>\n')
self.file.write(' <tr bgcolor = "#33CCFF" >\n')
self.file.write(' <th>Container Name</th>\n')
self.file.write(' <th>Used Image Tag</th>\n')
self.file.write(' <th>Image Creation Date</th>\n')
self.file.write(' <th>Used Image Size</th>\n')
self.file.write(' <th>Configuration Status</th>\n')
self.file.write(' </tr>\n')
self.addImageRow('mysql')
self.addImageRow('oai_nrf')
self.addImageRow('oai_amf')
self.addImageRow('oai_smf')
self.addImageRow('oai_spgwu')
self.file.write(' </table>\n')
self.file.write(' </div>\n')
def addImageRow(self, imageInfoPrefix):
cwd = os.getcwd()
if imageInfoPrefix == 'oai_amf':
containerName = 'oai-amf'
tagPattern = 'OAI_AMF_TAG'
statusPrefix = 'amf'
if imageInfoPrefix == 'oai_smf':
containerName = 'oai-smf'
tagPattern = 'OAI_SMF_TAG'
statusPrefix = 'smf'
if imageInfoPrefix == 'oai_nrf':
containerName = 'oai-nrf'
tagPattern = 'OAI_NRF_TAG'
statusPrefix = 'nrf'
if imageInfoPrefix == 'oai_spgwu':
containerName = 'oai-spgwu-tiny'
tagPattern = 'OAI_SPGWU_TAG'
statusPrefix = 'spgwu'
if imageInfoPrefix == 'mysql':
containerName = imageInfoPrefix
tagPattern = 'N/A'
if os.path.isfile(cwd + '/archives/' + imageInfoPrefix + '_image_info.log'):
usedTag = ''
createDate = ''
size = ''
with open(cwd + '/archives/' + imageInfoPrefix + '_image_info.log') as imageLog:
for line in imageLog:
line = line.strip()
result = re.search(tagPattern + ': (?P<tag>[a-zA-Z0-9\-\_:]+)', line)
if result is not None:
usedTag = result.group('tag')
result = re.search('Date = (?P<date>[a-zA-Z0-9\-\_:]+)', line)
if result is not None:
createDate = result.group('date')
result = re.search('Size = (?P<size>[0-9]+) bytes', line)
if result is not None:
sizeInt = int(result.group('size'))
if sizeInt < 1000000:
sizeInt = int(sizeInt / 1000)
size = str(sizeInt) + ' kB'
else:
sizeInt = int(sizeInt / 1000000)
size = str(sizeInt) + ' MB'
imageLog.close()
configState = 'KO'
cmd = 'egrep -c "STATUS: healthy" archives/' + statusPrefix + '_config.log || true'
ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8')
if ret.stdout is not None:
if ret.stdout.strip() == '1':
configState = 'OK'
self.file.write(' <tr>\n')
self.file.write(' <td>' + containerName + '</td>\n')
self.file.write(' <td>' + usedTag + '</td>\n')
self.file.write(' <td>' + createDate + '</td>\n')
self.file.write(' <td>' + size + '</td>\n')
if configState == 'OK':
self.file.write(' <td bgcolor = "DarkGreen"><b><font color="white">' + configState + '</font></b></td>\n')
else:
self.file.write(' <td bgcolor = "Red"><b><font color="white">' + configState + '</font></b></td>\n')
self.file.write(' </tr>\n')
else:
if imageInfoPrefix == 'mysql':
self.file.write(' <tr>\n')
self.file.write(' <td>' + containerName + '</td>\n')
self.file.write(' <td>mysql:5.7</td>\n')
self.file.write(' <td>N/A</td>\n')
self.file.write(' <td>449MB</td>\n')
configState = 'KO'
cmd = 'egrep -c "STATUS: healthy" archives/mysql_status.log || true'
ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8')
if ret.stdout is not None:
if ret.stdout.strip() == '1':
configState = 'OK'
if configState == 'OK':
self.file.write(' <td bgcolor = "DarkGreen"><b><font color="white">OK</font></b></td>\n')
else:
self.file.write(' <td bgcolor = "Red"><b><font color="white">KO</font></b></td>\n')
self.file.write(' </tr>\n')
else:
self.file.write(' <tr>\n')
self.file.write(' <td>' + containerName + '</td>\n')
self.file.write(' <td>UNKNOWN</td>\n')
self.file.write(' <td>N/A</td>\n')
self.file.write(' <td>N/A</td>\n')
self.file.write(' <td bgcolor = "DarkOrange"><b><font color="white">UNKNOW</font></b></td>\n')
self.file.write(' </tr>\n')
def testSummaryHeader(self):
self.file.write(' <h2>DS Tester Summary</h2>\n')
cwd = os.getcwd()
finalStatusOK = False
if os.path.isfile(cwd + '/DS-TEST-RESULTS/5gcn.yaml'):
cmd = f'egrep -c "final-result: pass" DS-TEST-RESULTS/5gcn.yaml || true'
ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8')
if ret.stdout is not None:
if ret.stdout.strip() == '1':
finalStatusOK = True
if finalStatusOK:
self.file.write(' <div class="alert alert-success">\n')
self.file.write(' <strong>Successful DsTester suite! <span class="glyphicon glyphicon-warning-sign"></span></strong>\n')
self.file.write(' </div>\n')
else:
self.file.write(' <div class="alert alert-danger">\n')
self.file.write(' <strong>Failed DsTester suite! <span class="glyphicon glyphicon-warning-sign"></span></strong>\n')
self.file.write(' </div>\n')
else:
self.file.write(' <div class="alert alert-warning">\n')
self.file.write(' <strong>LogFile not available! <span class="glyphicon glyphicon-warning-sign"></span></strong>\n')
self.file.write(' </div>\n')
return finalStatusOK
def testSummaryFooter(self):
self.file.write(' <br>\n')
def testSummaryDetails(self):
self.file.write(' <br>\n')
self.file.write(' <button data-toggle="collapse" data-target="#ds-tester-details">More details on DsTester results</button>\n')
self.file.write(' <div id="ds-tester-details" class="collapse">\n')
self.file.write(' <table class="table-bordered" width = "60%" align = "center" border = 1>\n')
self.file.write(' <tr bgcolor = "#33CCFF" >\n')
self.file.write(' <th>Test Name</th>\n')
self.file.write(' <th>Test Status</th>\n')
self.file.write(' <th>Test Details</th>\n')
self.file.write(' </tr>\n')
cwd = os.getcwd()
if os.path.isfile(cwd + '/DS-TEST-RESULTS/5gcn.yaml'):
with open(cwd + '/DS-TEST-RESULTS/5gcn.yaml') as f:
data = yaml.load(f)
nScenarios = len(data['scenarios'])
for scenario in range(nScenarios):
self.file.write(' <tr>\n')
self.file.write(' <td>' + data['scenarios'][scenario]['name'] + '</td>\n')
if data['scenarios'][scenario]['result'] == 'fail':
self.file.write(' <td bgcolor = "Red"><b><font color="white">KO</font></b></td>\n')
elif data['scenarios'][scenario]['result'] == 'pass':
self.file.write(' <td bgcolor = "DarkGreen"><b><font color="white">OK</font></b></td>\n')
else:
self.file.write(' <td bgcolor = "DarkOrange"><b><font color="white">UNKNOW</font></b></td>\n')
testDetails = ''
for x,y in data['scenarios'][scenario]['conditions'].items():
testDetails += str(x) + ': ' + str(y) + '\n'
#details += '\n'
self.file.write(' <td><pre>' + testDetails + '</pre></td>\n')
self.file.write(' </tr>\n')
else:
print ('no details???')
self.file.write(' </table>\n')
self.file.write(' </div>\n')
def Usage():
print('----------------------------------------------------------------------------------------------------------------------')
print('dsTestGenerateHTMLReport.py')
print(' Generate an HTML report for the Jenkins pipeline on oai-cn5g-fed.')
print('----------------------------------------------------------------------------------------------------------------------')
print('Usage: python3 generateHtmlReport.py [options]')
print(' --help Show this help.')
print('---------------------------------------------------------------------------------------------- Mandatory Options -----')
print(' --job_name=[Jenkins Job name]')
print(' --job_id=[Jenkins Job Build ID]')
print(' --job_url=[Jenkins Job Build URL]')
#--------------------------------------------------------------------------------------------------------
#
# Start of main
#
#--------------------------------------------------------------------------------------------------------
argvs = sys.argv
argc = len(argvs)
HTML = HtmlReport()
while len(argvs) > 1:
myArgv = argvs.pop(1)
if re.match('^\-\-help$', myArgv, re.IGNORECASE):
Usage()
sys.exit(0)
elif re.match('^\-\-job_name=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-job_name=(.+)$', myArgv, re.IGNORECASE)
HTML.job_name = matchReg.group(1)
elif re.match('^\-\-job_id=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-job_id=(.+)$', myArgv, re.IGNORECASE)
HTML.job_id = matchReg.group(1)
elif re.match('^\-\-job_url=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match('^\-\-job_url=(.+)$', myArgv, re.IGNORECASE)
HTML.job_url = matchReg.group(1)
else:
sys.exit('Invalid Parameter: ' + myArgv)
if HTML.job_name == '' or HTML.job_id == '' or HTML.job_url == '':
sys.exit('Missing Parameter in job description')
HTML.generate()
#!/bin/bash
STATUS=0
NB_UNREPLACED_AT=`cat /openair-amf/etc/*.conf | grep -v contact@openairinterface.org | grep -c @ || true`
NOT_FOUND=`ldd /openair-amf/bin/oai_amf | grep -c "not found" || true`
if [[ $NB_UNREPLACED_AT -ne 0 || $NOT_FOUND -ne 0 ]]
then
STATUS=-1
RESULT=$(ps aux | grep -v nohup || true)
SUB='/openair-amf/bin/oai_amf -c /openair-amf/etc/amf.conf -o'
if [[ $RESULT =~ $SUB ]]; then
STATUS=0
else
STATUS=-1
fi
exit $STATUS
......@@ -29,6 +29,12 @@ services:
ports:
- 80
- 9090
command: >
bash -c "nohup tshark -i eth0 -w /tmp/nrf.pcap 2>&1 > /dev/null &
/openair-nrf/bin/oai_nrf -c /openair-nrf/etc/nrf.conf -o | tee /tmp/nrf.log 2>&1
"
cap_add:
- NET_ADMIN
environment:
- TZ=Europe/Paris
- NRF_INTERFACE_NAME_FOR_SBI=eth0
......@@ -41,9 +47,7 @@ services:
cicd_public_net:
ipv4_address: 192.168.61.195
volumes:
- ./nrf-entrypoint-sleep.sh:/openair-nrf/bin/nrf-entrypoint-sleep.sh
- ./nrf-healthy-check.sh:/openair-nrf/bin/nrf-healthy-check.sh
entrypoint: /bin/bash -c "/openair-nrf/bin/nrf-entrypoint-sleep.sh"
healthcheck:
test: /bin/bash -c "/openair-nrf/bin/nrf-healthy-check.sh"
interval: 10s
......@@ -56,6 +60,12 @@ services:
ports:
- 38412
- 80