Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
oai
cn5g
oai-cn5g-fed
Commits
7ca58890
Commit
7ca58890
authored
Jul 16, 2021
by
Raphael Defosseux
Browse files
Merge remote-tracking branch 'origin/master' into helm-charts
parents
c7b6c4fa
ec517f7b
Changes
50
Expand all
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
7ca58890
------------------------------------------------------------------------------
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**
.
...
...
ci-scripts/Jenkinsfile-GitLab-Docker
View file @
7ca58890
...
...
@@ -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 mod
e\u001B[0m'
echo
'\u2705 \u001B[32mDeploy CN5G
using Docker-Compos
e\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/dsTestGenerateHTMLReport
2
.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'
}
...
...
ci-scripts/dsTestGenerateHTMLReport2.py
0 → 100644
View file @
7ca58890
#/*
# * 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
()
ci-scripts/dsTesterDockerCompose/amf-healthy-check.sh
View file @
7ca58890
#!/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
ci-scripts/dsTesterDockerCompose/docker-compose.tplt
View file @
7ca58890
...
...
@@ -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