Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
openairinterface-6g
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
openairinterface-6g
Commits
dad8814b
Commit
dad8814b
authored
May 16, 2025
by
Jaroslava Fiedlerova
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
CI: Add functions for OC Physim deployment and analysis
parent
986db77b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
148 additions
and
11 deletions
+148
-11
ci-scripts/cls_analysis.py
ci-scripts/cls_analysis.py
+66
-1
ci-scripts/cls_cluster.py
ci-scripts/cls_cluster.py
+37
-0
ci-scripts/cls_oai_html.py
ci-scripts/cls_oai_html.py
+12
-10
ci-scripts/scripts/oc-deploy-physims.sh
ci-scripts/scripts/oc-deploy-physims.sh
+33
-0
No files found.
ci-scripts/cls_analysis.py
View file @
dad8814b
...
@@ -20,8 +20,11 @@
...
@@ -20,8 +20,11 @@
# */
# */
#---------------------------------------------------------------------
#---------------------------------------------------------------------
import
logging
import
re
import
re
import
os
import
xml.etree.ElementTree
as
ET
import
json
# Define the mapping of physim_test values to search patterns
# Define the mapping of physim_test values to search patterns
PHYSIM_PATTERN_MAPPING
=
{
PHYSIM_PATTERN_MAPPING
=
{
...
@@ -80,3 +83,65 @@ class Analysis():
...
@@ -80,3 +83,65 @@ class Analysis():
msg
=
f'
{
time1_match
.
group
(
1
)
}
:
{
time1_match
.
group
(
2
)
}
us
\n
{
time2_match
.
group
(
1
)
}
:
{
time2_match
.
group
(
2
)
}
us exceeds a limit of
{
threshold
}
us'
msg
=
f'
{
time1_match
.
group
(
1
)
}
:
{
time1_match
.
group
(
2
)
}
us
\n
{
time2_match
.
group
(
1
)
}
:
{
time2_match
.
group
(
2
)
}
us exceeds a limit of
{
threshold
}
us'
return
success
,
msg
return
success
,
msg
def
analyze_oc_physim
(
result_junit
,
details_json
):
try
:
tree
=
ET
.
parse
(
result_junit
)
root
=
tree
.
getroot
()
nb_tests
=
int
(
root
.
attrib
[
"tests"
])
nb_failed
=
int
(
root
.
attrib
[
"failures"
])
except
ET
.
ParseError
as
e
:
return
False
,
False
,
f'Could not parse XML log file
{
result_junit
}
:
{
e
}
'
except
FileNotFoundError
as
e
:
return
False
,
False
,
f'JUnit XML log file
{
result_junit
}
not found:
{
e
}
'
except
Exception
as
e
:
return
False
,
False
,
f'While parsing JUnit XML log file: exception:
{
e
}
'
try
:
with
open
(
details_json
)
as
f
:
j
=
json
.
load
(
f
)
# prepare JSON for easier access of strings
json_test_desc
=
{}
for
e
in
j
[
"tests"
]:
json_test_desc
[
e
[
"name"
]]
=
e
except
json
.
JSONDecodeError
as
e
:
return
False
,
False
,
f'Could not decode JSON log file
{
details_json
}
:
{
e
}
'
except
FileNotFoundError
as
e
:
return
False
,
False
,
f'Physim JSON log file
{
details_json
}
not found:
{
e
}
'
except
Exception
as
e
:
return
False
,
False
,
f'While parsing physim JSON log file: exception:
{
e
}
'
test_result
=
{}
for
test
in
root
:
# for each test
test_name
=
test
.
attrib
[
"name"
]
test_exec
=
json_test_desc
[
test_name
][
"properties"
][
1
][
"value"
][
0
]
desc
=
json_test_desc
[
test_name
][
"properties"
][
1
][
"value"
][
1
]
# get runtime and checks
test_check
=
test
.
attrib
[
"status"
]
==
"run"
time
=
round
(
float
(
test
.
attrib
[
"time"
]),
1
)
time_check
=
time
<
150
output
=
test
.
findtext
(
"system-out"
)
output_check
=
"exceeds the threshold"
not
in
output
# collect logs
log_dir
=
f'../cmake_targets/log/
{
test_exec
}
'
os
.
makedirs
(
log_dir
,
exist_ok
=
True
)
with
open
(
f'
{
log_dir
}
/
{
test_name
}
.log'
,
'w'
)
as
f
:
f
.
write
(
output
)
# prepare result and info
info
=
f"Runtime:
{
f'
{
time
:.
3
f
}
'[:5]
}
s"
resultstr
=
'PASS'
if
(
test_check
and
time_check
and
output_check
)
else
'FAIL'
if
test_check
:
if
not
output_check
:
info
+=
" Test log exceeds maximal allowed length 100 kB"
if
not
time_check
:
info
+=
" Test exceeds 150s"
if
not
(
time_check
and
output_check
):
nb_failed
+=
1
# time threshold/output length error, not counted for by ctest as of now
test_result
[
test_name
]
=
[
desc
,
info
,
resultstr
]
test_summary
=
{}
test_summary
[
'Nbtests'
]
=
nb_tests
test_summary
[
'Nbpass'
]
=
nb_tests
-
nb_failed
test_summary
[
'Nbfail'
]
=
nb_failed
return
nb_failed
==
0
,
test_summary
,
test_result
ci-scripts/cls_cluster.py
View file @
dad8814b
...
@@ -31,8 +31,10 @@
...
@@ -31,8 +31,10 @@
import
logging
import
logging
import
re
import
re
import
time
import
time
import
os
import
cls_oai_html
import
cls_oai_html
import
cls_analysis
import
constants
as
CONST
import
constants
as
CONST
import
helpreadme
as
HELP
import
helpreadme
as
HELP
import
cls_containerize
import
cls_containerize
...
@@ -457,3 +459,38 @@ class Cluster:
...
@@ -457,3 +459,38 @@ class Cluster:
HTML
.
CreateHtmlNextTabHeaderTestRow
(
collectInfo
,
imageSize
)
HTML
.
CreateHtmlNextTabHeaderTestRow
(
collectInfo
,
imageSize
)
return
status
return
status
def
deploy_oc_physim
(
self
,
HTML
,
oc_release
,
svr_id
):
if
self
.
ranRepository
==
''
or
self
.
ranBranch
==
''
or
self
.
ranCommitID
==
''
:
HELP
.
GenericHelp
(
CONST
.
Version
)
raise
ValueError
(
f'Insufficient Parameter: ranRepository
{
self
.
ranRepository
}
ranBranch
{
self
.
ranBranch
}
ranCommitID
{
self
.
ranCommitID
}
'
)
image_tag
=
cls_containerize
.
CreateTag
(
self
.
ranCommitID
,
self
.
ranBranch
,
self
.
ranAllowMerge
)
logging
.
debug
(
f'Running physims from server:
{
svr_id
}
'
)
script
=
"scripts/oc-deploy-physims.sh"
options
=
f"oaicicd-core-for-ci-ran
{
oc_release
}
{
image_tag
}
{
self
.
eNBSourceCodePath
}
"
ret
=
cls_cmd
.
runScript
(
svr_id
,
script
,
600
,
options
)
logging
.
debug
(
f'"
{
script
}
" finished with code
{
ret
.
returncode
}
, output:
\n
{
ret
.
stdout
}
'
)
log_dir
=
f'
{
os
.
getcwd
()
}
/../cmake_targets/log'
os
.
makedirs
(
log_dir
,
exist_ok
=
True
)
result_junit
=
f'
{
oc_release
}
-run.xml'
details_json
=
f'
{
oc_release
}
-tests.json'
with
cls_cmd
.
getConnection
(
svr_id
)
as
ssh
:
ssh
.
copyin
(
src
=
f'
{
self
.
eNBSourceCodePath
}
/ci-scripts/
{
details_json
}
'
,
tgt
=
f'
{
log_dir
}
/
{
details_json
}
'
)
ssh
.
copyin
(
src
=
f'
{
self
.
eNBSourceCodePath
}
/ci-scripts/
{
result_junit
}
'
,
tgt
=
f'
{
log_dir
}
/
{
result_junit
}
'
)
ssh
.
copyin
(
src
=
f'
{
self
.
eNBSourceCodePath
}
/ci-scripts/physim_log.txt'
,
tgt
=
f'
{
log_dir
}
/physim_log.txt'
)
ssh
.
copyin
(
src
=
f'
{
self
.
eNBSourceCodePath
}
/ci-scripts/physim_pods_summary.txt'
,
tgt
=
f'
{
log_dir
}
/physim_pods_summary.txt'
)
ssh
.
copyin
(
src
=
f'
{
self
.
eNBSourceCodePath
}
/ci-scripts/LastTestsFailed.log'
,
tgt
=
f'
{
log_dir
}
/LastTestsFailed.log'
)
test_status
,
test_summary
,
test_result
=
cls_analysis
.
Analysis
.
analyze_oc_physim
(
f'
{
log_dir
}
/
{
result_junit
}
'
,
f'
{
log_dir
}
/
{
details_json
}
'
)
if
test_summary
:
if
test_status
:
HTML
.
CreateHtmlTestRow
(
'N/A'
,
'OK'
,
CONST
.
ALL_PROCESSES_OK
)
HTML
.
CreateHtmlTestRowPhySimTestResult
(
test_summary
,
test_result
)
logging
.
info
(
'
\u001B
[1m Physical Simulator Pass
\u001B
[0m'
)
else
:
HTML
.
CreateHtmlTestRow
(
'Some test(s) failed!'
,
'KO'
,
CONST
.
OC_PHYSIM_DEPLOY_FAIL
)
HTML
.
CreateHtmlTestRowPhySimTestResult
(
test_summary
,
test_result
)
logging
.
error
(
'
\u001B
[1m Physical Simulator Fail
\u001B
[0m'
)
else
:
HTML
.
CreateHtmlTestRowQueue
(
'Physical simulator failed'
,
'KO'
,
[
test_result
])
logging
.
error
(
'
\u001B
[1m Physical Simulator Fail
\u001B
[0m'
)
return
test_status
ci-scripts/cls_oai_html.py
View file @
dad8814b
...
@@ -564,13 +564,13 @@ class HTMLManagement():
...
@@ -564,13 +564,13 @@ class HTMLManagement():
self
.
htmlFile
.
write
(
' <th>Nb Pass</th>
\n
'
)
self
.
htmlFile
.
write
(
' <th>Nb Pass</th>
\n
'
)
self
.
htmlFile
.
write
(
' </tr>
\n
'
)
self
.
htmlFile
.
write
(
' </tr>
\n
'
)
self
.
htmlFile
.
write
(
' <tr>
\n
'
)
self
.
htmlFile
.
write
(
' <tr>
\n
'
)
self
.
htmlFile
.
write
(
' <td colspan="2" bgcolor = "lightcyan" > physim_
test
.txt </td>
\n
'
)
self
.
htmlFile
.
write
(
' <td colspan="2" bgcolor = "lightcyan" > physim_
log
.txt </td>
\n
'
)
self
.
htmlFile
.
write
(
' <td colspan="2" bgcolor = "lightcyan" >'
+
str
(
testSummary
[
'Nbtests'
])
+
' </td>
\n
'
)
self
.
htmlFile
.
write
(
' <td colspan="2" bgcolor = "lightcyan" >'
+
str
(
testSummary
[
'Nbtests'
])
+
' </td>
\n
'
)
if
testSummary
[
'Nbfail'
]
==
0
:
if
testSummary
[
'Nbfail'
]
==
0
:
self
.
htmlFile
.
write
(
' <td bgcolor = "lightcyan" >'
+
str
(
testSummary
[
'Nbfail'
])
+
'
</td>
\n
'
)
self
.
htmlFile
.
write
(
' <td bgcolor = "lightcyan" >'
+
str
(
testSummary
[
'Nbfail'
])
+
'</td>
\n
'
)
else
:
else
:
self
.
htmlFile
.
write
(
' <td bgcolor = "red" >
'
+
str
(
testSummary
[
'Nbfail'
])
+
'
</td>
\n
'
)
self
.
htmlFile
.
write
(
' <td bgcolor = "red" >
<font color="white">'
+
str
(
testSummary
[
'Nbfail'
])
+
'</font>
</td>
\n
'
)
self
.
htmlFile
.
write
(
' <td gcolor = "lightcyan" >'
+
str
(
testSummary
[
'Nbpass'
])
+
' </td>
\n
'
)
self
.
htmlFile
.
write
(
' <td
b
gcolor = "lightcyan" >'
+
str
(
testSummary
[
'Nbpass'
])
+
' </td>
\n
'
)
self
.
htmlFile
.
write
(
' </tr>
\n
'
)
self
.
htmlFile
.
write
(
' </tr>
\n
'
)
self
.
htmlFile
.
write
(
' <tr bgcolor = "#F0F0F0" >
\n
'
)
self
.
htmlFile
.
write
(
' <tr bgcolor = "#F0F0F0" >
\n
'
)
self
.
htmlFile
.
write
(
' <td colspan="6"><b> ---- PHYSIM TEST DETAIL INFO---- </b></td>
\n
'
)
self
.
htmlFile
.
write
(
' <td colspan="6"><b> ---- PHYSIM TEST DETAIL INFO---- </b></td>
\n
'
)
...
@@ -578,22 +578,24 @@ class HTMLManagement():
...
@@ -578,22 +578,24 @@ class HTMLManagement():
self
.
htmlFile
.
write
(
' <tr bgcolor = "#33CCFF" >
\n
'
)
self
.
htmlFile
.
write
(
' <tr bgcolor = "#33CCFF" >
\n
'
)
self
.
htmlFile
.
write
(
' <th colspan="2">Test Name</th>
\n
'
)
self
.
htmlFile
.
write
(
' <th colspan="2">Test Name</th>
\n
'
)
self
.
htmlFile
.
write
(
' <th colspan="2">Test Description</th>
\n
'
)
self
.
htmlFile
.
write
(
' <th colspan="2">Test Description</th>
\n
'
)
self
.
htmlFile
.
write
(
' <th colspan="2">Result</th>
\n
'
)
self
.
htmlFile
.
write
(
' <th>Test Status</th>
\n
'
)
self
.
htmlFile
.
write
(
' <th>Info</th>
\n
'
)
self
.
htmlFile
.
write
(
' </tr>
\n
'
)
self
.
htmlFile
.
write
(
' </tr>
\n
'
)
y
=
''
y
=
''
for
key
,
value
in
testResult
.
items
():
for
key
,
value
in
testResult
.
items
():
x
=
key
.
split
(
"."
)
x
=
key
.
split
(
"."
)
if
x
[
0
]
!=
y
:
if
x
[
2
]
!=
y
:
self
.
htmlFile
.
write
(
' <tr bgcolor = "lightgreen" >
\n
'
)
self
.
htmlFile
.
write
(
' <tr bgcolor = "lightgreen" >
\n
'
)
self
.
htmlFile
.
write
(
' <td style="text-align: center;" colspan="6"><b>"'
+
x
[
0
]
+
'" series </b></td>
\n
'
)
self
.
htmlFile
.
write
(
' <td style="text-align: center;" colspan="6"><b>"'
+
x
[
2
]
+
'" series </b></td>
\n
'
)
self
.
htmlFile
.
write
(
' </tr>
\n
'
)
self
.
htmlFile
.
write
(
' </tr>
\n
'
)
y
=
x
[
0
]
y
=
x
[
2
]
self
.
htmlFile
.
write
(
' <tr>
\n
'
)
self
.
htmlFile
.
write
(
' <tr>
\n
'
)
self
.
htmlFile
.
write
(
' <td colspan="2" bgcolor = "lightcyan" >'
+
key
+
' </td>
\n
'
)
self
.
htmlFile
.
write
(
' <td colspan="2" bgcolor = "lightcyan" >'
+
key
+
' </td>
\n
'
)
self
.
htmlFile
.
write
(
' <td colspan="2" bgcolor = "lightcyan" >'
+
value
[
0
]
+
'</td>
\n
'
)
self
.
htmlFile
.
write
(
' <td colspan="2" bgcolor = "lightcyan" >'
+
value
[
0
]
+
'</td>
\n
'
)
if
'PASS'
in
value
:
if
'PASS'
in
value
:
self
.
htmlFile
.
write
(
' <td
colspan="2" bgcolor = "green" >'
+
value
[
1
]
+
'
</td>
\n
'
)
self
.
htmlFile
.
write
(
' <td
bgcolor = "green" ><font color="white"><b>'
+
value
[
2
]
+
'</b></font>
</td>
\n
'
)
else
:
else
:
self
.
htmlFile
.
write
(
' <td colspan="2" bgcolor = "red" >'
+
value
[
1
]
+
'</td>
\n
'
)
self
.
htmlFile
.
write
(
' <td bgcolor = "red" ><font color="white"><b>'
+
value
[
2
]
+
'</b></font></td>
\n
'
)
self
.
htmlFile
.
write
(
' <td bgcolor = "lightcyan">'
+
value
[
1
]
+
'</td>
\n
'
)
self
.
htmlFile
.
close
()
self
.
htmlFile
.
close
()
ci-scripts/scripts/oc-deploy-physims.sh
0 → 100755
View file @
dad8814b
#!/bin/bash
set
-e
function
die
()
{
echo
$@
;
exit
1
;
}
[
$#
-eq
4
]
||
die
"usage:
$0
<namespace> <release> <image tag> <oai directory>"
OC_NS
=
${
1
}
OC_RELEASE
=
${
2
}
IMG_TAG
=
${
3
}
OAI_DIR
=
${
4
}
cat
/opt/oc-password | oc login
-u
oaicicd
--server
https://api.oai.cs.eurecom.fr:6443
>
/dev/null
oc project
${
OC_NS
}
>
/dev/null
oc tag oaicicd-ran/oai-physim:
${
IMG_TAG
}
${
OC_NS
}
/oai-physim:
${
IMG_TAG
}
helm
install
${
OC_RELEASE
}
${
OAI_DIR
}
/charts/
${
OC_RELEASE
}
--set
global.image.version
=
${
IMG_TAG
}
--wait
POD_ID
=
$(
oc get pods |
grep
oai-
${
OC_RELEASE
}
|
awk
'{print $1}'
)
sleep
10
echo
"Monitoring logs for 'FINISHED' in pod '
$POD_ID
'"
oc logs
-f
-n
${
OC_NS
}
"
$POD_ID
"
|
while
read
-r
line
;
do
if
[[
"
$line
"
==
*
"FINISHED"
*
]]
;
then
echo
"'FINISHED' detected in logs. Copying logs..."
oc logs
-n
${
OC_NS
}
"
$POD_ID
"
>>
${
OAI_DIR
}
/ci-scripts/physim_log.txt
oc describe pod
$POD_ID
>>
${
OAI_DIR
}
/ci-scripts/physim_pods_summary.txt
oc
cp
"
$POD_ID
"
:/opt/oai-physim/Testing/Temporary/LastTestsFailed.log
${
OAI_DIR
}
/ci-scripts/LastTestsFailed.log
oc
cp
"
$POD_ID
"
:/opt/oai-physim/
${
OC_RELEASE
}
-tests
.json
${
OAI_DIR
}
/ci-scripts/
${
OC_RELEASE
}
-tests
.json
oc
cp
"
$POD_ID
"
:/opt/oai-physim/
${
OC_RELEASE
}
-run
.xml
${
OAI_DIR
}
/ci-scripts/
${
OC_RELEASE
}
-run
.xml
break
fi
done
helm uninstall
${
OC_RELEASE
}
--wait
oc delete istag oai-physim:
${
IMG_TAG
}
-n
${
OC_NS
}
oc
logout
>
/dev/null
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment