Compare commits

..

251 Commits

Author SHA1 Message Date
Nika Ghaderi
f9b23226ed added test_scm_stability 2025-08-26 12:36:41 +00:00
Robert Schmidt
207aac94d1 Merge branch 'integration_2025_w34' into 'develop'
Integration: `2025.w34`

* !3555 Remove dead code and variables, simplify code
* !3591 separate computation of size and value for DCI precoding information
* !3550 some work for better interoperability with srsRAN DU
* !3562 cleaning syntax of nr-ru.c
* !3598 Align add_boolean_option as per CMake documentation use only ON/OFF for uniformity
* !3407 Taps client for vrtsim
* !3035 NR L1 common channel level functions
* !3589 RF emulator and improvements of the timers
* !3577 Fix for UECAP file handling in dora/phytest mode
* !3600 Fix for UE TCI state ID configuration
* !3599 DLSCH scheduler: fix bugs in UE sorting

See merge request oai/openairinterface5g!3597
2025-08-22 08:07:59 +00:00
Robert Schmidt
6758d14a93 Merge remote-tracking branch 'origin/fixes-dlsch-sched' into integration_2025_w34 (!3599)
DLSCH scheduler: fix bugs in UE sorting

Fix two issues/bugs when sorting UEs in the DLSCH scheduler following
the PF metric, which should improve fairness.
2025-08-21 18:10:23 +02:00
Robert Schmidt
406e36919f Merge remote-tracking branch 'origin/config_UE_TCI_fix' into integration_2025_w34 (!3600)
Fix for UE TCI state ID configuration
2025-08-21 17:30:49 +02:00
Robert Schmidt
8695a8dbba Merge remote-tracking branch 'origin/dora_phytest_uecap_fix' into integration_2025_w34 (!3577)
Fix for UECAP file handling in dora/phytest mode
2025-08-21 17:30:15 +02:00
Robert Schmidt
8ccd944db2 Merge remote-tracking branch 'origin/rf_emulator_and_timers_fix' into integration_2025_w34 (!3589)
RF emulator and improvements of the timers

RF emulator:
Add an RF library emulating a real device without the need of a real
device.  This is thought to enable using phy-test without requiring a
radio device or channel simulation.  The library synchronizes on the
real time clock, drops TX and generate noise on RX.  Noise generation
can be disabled and the noise level configured.

Timers improvements:
- Fix standard deviation for merged timers
- Add display of ULSCH decoding timers
- Add decoding timer in AAL
2025-08-21 15:22:44 +02:00
Romain Beurdouche
42ad189bf3 feat(rf_emulator): documentation 2025-08-21 10:53:03 +02:00
Robert Schmidt
946939e8cc CI: integrate RFemulator phytest in timing-phytest pipeline 2025-08-21 10:53:03 +02:00
Robert Schmidt
89e6e53f8c Remove --emulate-rf option and corresponding code
With the RFemulator, there is no need for a dedicated --emulate-rf
option anymore. For all uses of --emulate-rf, RFemulator should be used
instead.
2025-08-21 10:53:03 +02:00
Romain Beurdouche
1cebf02b1e feat(rf_emulator): Add parameters
Add two parameters:
* `enable_noise` to enable noise injection at TX
* `noise_level_dBFS` to set noise level
2025-08-21 10:53:03 +02:00
Robert Schmidt
a30bee2fab DLSCH sched: Fix coefficients for UE list ordering
Update the comparator() to properly sort UEs based on their coefficient
by appliey a consistent logic of -1/0/1 (see man qsort) for
smaller/equal/larger.  The previous logic was only sorting based on 0/1
(equal/larger), which would result in some UEs with a high coefficient
not necessarily advancing to the start of the list, which could reduce
the likelihood of them being scheduled when they actually should (in
other words, this should improve fairness).

See also: 62e4025bc8 ("Integrate inactivity scheduling into main
    allocation loop")
2025-08-21 10:33:59 +02:00
Robert Schmidt
8a091a0b84 DLSCH sched: only sort relevant part of list
This reduces the amount of elements to compare.

See also: 7ee8e8eaba ("Fix bug: only sort relevant part of list")
2025-08-21 10:32:23 +02:00
francescomani
dd0188dfdc fix for config UE TCI state ID 2025-08-21 09:41:14 +02:00
Robert Schmidt
5ad35f6bfe Merge remote-tracking branch 'origin/vrtsim-taps-client' into integration_2025_w34 (!3407)
Taps client for vrtsim

The MR allows vrtsim to connect to the Raytracing Channel Emulator (CE later).
https://gitlab.eurecom.fr/oai/raytracing-channel-emulator

Additional Ubuntu packages required:

- libnanomsg-dev
- flatbuffers-compiler
- libflatbuffers-dev

Everything was tested on the same host. Follow the steps below to
successfully replicate:

1. Build nr-softmodem dependencies
2. Build nr-softmodem for (gNB, nrUE) with OAI_VRTSIM_TAPS_CLIENTset to ON.
3. Start the core network (Optional) follow this tutorial
4. Start the gNB

       sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf --gNBs.[0].min_rxtxtime 6 --device.name vrtsim --vrtsim.role server --vrtsim.timescale 0.5 --vrtsim.taps-socket ipc:///tmp/ru_socket_0

5. Start the nrUE

       sudo ./nr-uesoftmodem -C 3619200000 -r 106 --numerology 1 --ssb 516  --band 78 --device.name vrtsim --vrtsim.taps-socket ipc:///tmp/ue_socket_0

6. Start the CE Server, once the UE and gNB are running properly, so the
   server can connect to IPC sockets
7. Start CE client; the binaries can be downloaded from a pipeline run
   or from this link
8. Move the UE in the CE client to generate a new taps array and
   populate the taps in softmodems
2025-08-21 09:35:41 +02:00
Robert Schmidt
0a65bd27c1 Merge remote-tracking branch 'origin/NR_common_L1' into integration_2025_w34 (!3035)
NR L1 common channel level functions

Common L1 functions shared between gNB and UE for DLSCH/ULSCH/PDCCH/PBCH
channel level
2025-08-21 09:34:31 +02:00
Robert Schmidt
c61ef34a38 Merge remote-tracking branch 'origin/cmake-boolean-correction' into integration_2025_w34 (!3598)
Align add_boolean_option as per CMake documentation use only ON/OFF for uniformity

The add_boolean_option of CMake is not uniform everywhere. We were using
either True/False or ON/OFF. It is better to be uniform to avoid
confusion.

As an example, see here CMake documentation for an example:
https://cmake.org/cmake/help/latest/module/CMakeDependentOption.html#example-basic-usage

There are also some minor spelling corrections.
2025-08-21 09:33:03 +02:00
Robert Schmidt
2eb9a36e21 Merge remote-tracking branch 'origin/cleaning-syntax-nr-ru.c' into integration_2025_w34 (!3562)
cleaning syntax of nr-ru.c
2025-08-21 09:32:31 +02:00
Robert Schmidt
d0f6c63314 Merge remote-tracking branch 'origin/interop-srsran-du' into integration_2025_w34 (!3550)
some work for better interoperability with srsRAN DU

Just add the minimum to get some user plane traffic going on.

When doing user plane traffic, in the CU logs we have a lot of:

    [GTPU]   NR-RAN container type: 1 not supported

That will be fixed in another MR, not here.
2025-08-21 09:31:32 +02:00
Cedric Roux
653ad775ea hack: ignore empty Cell Group Config returned by DU
Interoperability testing with srsRAN DU shows than when receiving
RRCReconfigurationCompleteIndicator in a UEContextModificationRequest
the DU replies in the UEContextModificationResponse with an empty
CellGroupConfig.

This CellGroupConfig is encoded as 2 zero bytes. Let's ignore this
message when we receive it, don't forward it to the UE in a
RRC Reconfiguration, as it should per standard (38.473 8.3.4.2):

    If the CellGroupConfig IE is included in the DU to CU RRC Information
    IE contained in the UE CONTEXT MODIFICATION RESPONSE message, the
    gNB-CU shall perform RRC Reconfiguration as described in TS 38.331 [8].
    The CellGroupConfig IE shall transparently be signaled to the UE as
    specified in TS 38.331 [8].

To be removed/reworked in the future if the interoperability
situation improves.
2025-08-21 09:30:41 +02:00
Cedric Roux
807b38ddae GTPU: CU has to send NR-U Sequence Number
This is in 3GPP TS 38.425.

Because it was not done, there was a problem of interoperability
between openair CU and srsran DU. No DL traffic was reaching the UE.

A new GTPU API function is introduced: gtpv1uSendDirectWithNRUSeqNum().
It is only used in the gNB CU, in PDCP. So it was decided to not add a
new parameter to gtpv1uSendDirect() but instead add a new API function.
2025-08-21 09:30:41 +02:00
Cedric Roux
84ce708f96 GTPU: basic support of DL USER DATA
See 3GPP TS 38.425 5.5.2.1.

Only sending part, only dealing with NR-U Sequence Number.
2025-08-21 09:30:41 +02:00
Cedric Roux
c35f07b0b9 GTPU: add an API to better deal with extension headers
And adapt existing code to use it.

Only for transmission for the moment.
2025-08-21 09:30:41 +02:00
Bartosz Podrygajlo
513173ae0d Rename VRTSIM cmake option to OAI_VRTSIM 2025-08-20 15:57:34 +02:00
Bartosz Podrygajlo
171b3f206f VRTsim: Add a timeout in taps client
Add a timeout in nanomsg receive code to allow the client
thread to exit cleanly.
2025-08-20 15:57:34 +02:00
Bartosz Podrygajlo
74fc56813f Update vrtsim documentation 2025-08-20 15:57:34 +02:00
Bartosz Podrygajlo
ea3a4b991c VRTSIM: allow client reconnection via a connection descriptor file
Replace the unwieldy unix socket implementation of peer information
exchange with an authorative connection descriptor file that
informs the client of the connection method an number of antennas
on the server.

This allows the server to run without the client and allows the
client to reconnect as long as the server is running, as many times
as needed.
2025-08-20 15:57:34 +02:00
Bartosz Podrygajlo
54fdd3547b Clean exit of vrtsim client if server is stopped first
Force exit in case current sample is not modified by the server with 2s.
2025-08-20 15:57:34 +02:00
Bartosz Podrygajlo
fc28e2d3fc Make vrtsim output to stdout more readable. 2025-08-20 15:57:34 +02:00
Bartosz Podrygajlo
acba82b874 Simplify shm td iq channel implementation
Move the channel state management outside the channel implementation.
This simplifies the channel implementation but forces users of the
channel to manage it's state manually.
2025-08-20 15:57:34 +02:00
Bartosz Podrygajlo
fcea07ca71 Detect disconnecton & handle error states in vrtsim
Add handling for error states in vrtsim which allows to close the
softmodems with CTRL+C without hanging, improving user experience
 - Client detection of stale timer.
 - Abort state for client and server
2025-08-20 15:57:34 +02:00
Bartosz Podrygajlo
16f5299203 Taps client client for vrtsim
Added a libary that can connect to a channel emulator and provide taps
as they are generated.

 - Enable connection from vrtsim to channel emulation server
 - Depends on flatbuffers definition file from raytracing-channel-emulator
 - Depends on libanomsg-dev and flatbuffers-compiler (Ubuntu) or equivalent
 - Added a compile time option ENABLE_TAPS_CLIENT to prevent other users
   from being affected by additional dependencies
2025-08-20 15:57:30 +02:00
Sagar Arora
fc1c8a9be0 Align add_boolean_option as per cmake documentation use only ON/OFF for uniformity
Signed-off-by: Sagar Arora <sagar.arora@openairinterface.org>
2025-08-20 13:17:45 +02:00
Robert Schmidt
8a05dcdfee Merge remote-tracking branch 'origin/NR_fix_tpmi_ctnd' into integration_2025_w34 (!3591)
separate computation of size and value for DCI precoding information

This removes stuff that is only relevant for the gNB from the common
functions and moves it to the gNB scheduler functions (related to UL
precoding). In principle no functional change.
2025-08-20 13:11:47 +02:00
Robert Schmidt
60bb39570b Merge remote-tracking branch 'origin/compile-improvements' into integration_2025_w34 (!3555)
Remove dead code and variables, simplify code
2025-08-20 13:11:28 +02:00
Laurent THOMAS
13f5c258ca remove unused global 2025-08-20 09:36:48 +02:00
Laurent THOMAS
2bda52b054 rename a global "ru" in root_unit and include correctly the .h file, that leads to mistakes fixes 2025-08-20 09:36:48 +02:00
Laurent THOMAS
4b47d26ea2 remove dirty and unused functions with global vars (not working anyway) 2025-08-20 09:36:48 +02:00
Laurent THOMAS
c2d9f17242 remove a dependancy of gNB to LTE that is not used and adds global vars to gNB 2025-08-20 09:36:48 +02:00
Laurent THOMAS
4a3ebb3033 remove dead code and replace unmanaged asn1_xer_print global variable by the appropriate existing debug flag 2025-08-20 09:36:48 +02:00
Laurent THOMAS
2dae7b0db4 Limit visibilty of roundKeys 2025-08-20 09:36:48 +02:00
Laurent THOMAS
7cc35cf7e0 remove dead function 2025-08-20 09:36:48 +02:00
Laurent THOMAS
c4f4f8d919 Remove threequarter_fs, log_level; make functions static
2 functions with same name as static to make it clearer they are separate.

remove unused copy of log_level global var.

remove threequarter sampling variable from the radio board general
configuration. The decision of sampling rate is made above. A better
behavior can be done later, like ask to the radio board what sampling
rate it can do,then use it to decide the appropiate sampling rate from
the gNB configuration. In UE case, it is another issue, as the sampling
rate would change after we decode SIB1, but also it is not developped
yet.
2025-08-20 09:36:23 +02:00
Laurent THOMAS
78f12dbc03 Change tracy version to latest release 2025-08-20 09:32:23 +02:00
francescomani
b4796b4dda remove unused deinterleaving function from dlsch ue 2025-08-19 16:25:47 +02:00
francescomani
6af8f5619a use common channel level for PDSCH 2025-08-19 16:25:44 +02:00
francescomani
8d904dbf23 use common channel level for PUSCH 2025-08-19 16:24:17 +02:00
francescomani
65d0fb152e use common channel level for DCI reception 2025-08-19 16:19:48 +02:00
francescomani
a95a32c2f6 use common channel level for PBCH 2025-08-19 16:18:41 +02:00
francescomani
92dc641e98 common channel level function 2025-08-19 16:11:50 +02:00
Bartosz Podrygajlo
096ea7bd87 Fixes for vrtsim
- Allow client to exit cleanly if server is down
 - Ensure timing_thread is joined only once avoiding exit_function loop
 - Free noise_device
 - Save previously sent samples for channel modelling
2025-08-18 08:07:51 +02:00
Laurent THOMAS
29108a0974 cleaning syntax of nr-ru.c 2025-08-16 21:38:18 +02:00
Romain Beurdouche
dfa77647b1 feat(rf_emulator): Add late writes counter 2025-08-16 08:35:13 +00:00
Romain Beurdouche
5e03748835 feat(rf_emulator): Add noise generation 2025-08-16 08:35:08 +00:00
Cedric Roux
33cbbafddb ds: add a new type "byte array producer"
Introduced to write bytes to a byte array with size checking.
2025-08-14 23:37:11 +02:00
Robert Schmidt
9e37a2cf94 Merge branch 'integration_2025_w33' into 'develop'
Integration: `2025.w33`

* !3563 UE fixes: pucch format 2 and CSI IM
* !3567 Workaround for handling 2 SS0 occasions per slot
* !3578 fix a T trace
* !3395 RFsim variable size H_awgn_mimo
* !3581 NR UE NTN: consider acceleration on orbital path to calculate N_UE_TA_drift_variant
* !3580 NR UE: fix pdcch llr_size calculation in nr_rx_pdcch()
* !3576 Cleanup documentation and interface of the LDPC segment coding libraries
* !3573 Make Amarisoft UE sim a RedCap UE
* !3586 Print UE command line parameters at gNB MAC for split architecture without L1
* !3584 add gtpu error packet parsing and display
* !3556 Introduce support for Cat-B RU using Predefined-Beam BF with Aerial L1
* !3492 Upgrade CI images to Ubuntu 24
* !3521 Refactor ULSCH scheduler towards more TDD pattern flexibility
* !3590 Improve MAC docs for MCS and docker for BuildKit usage
* !3579 CI: speed up and simplify build, remove unnecessary Python code, remove --eNB\* parameter list

Closes #927 and #973

See merge request oai/openairinterface5g!3583
2025-08-14 16:18:58 +00:00
Romain Beurdouche
bf83b78758 feat(rf_emulator): Count late reads
Count late reads and print every second instead of printing each.
2025-08-14 15:33:36 +00:00
Romain Beurdouche
5212bd7a85 feat(rf_emulator): Add a dummy RF library
Add a simple RF emulator library with no real RF.
It only synchronizes the gNB with the real time clock.
It is to be used for stress test or benchmarking in phy-test mode.
2025-08-14 15:33:32 +00:00
Robert Schmidt
2c351c94d0 Merge remote-tracking branch 'origin/doc-updates' into integration_2025_w33 (!3590)
Improve MAC docs for MCS and docker for BuildKit usage

See commits for details. The first one is for fixing an omission in
!3281, the second to clarify docker build usage.

Closes: #973
2025-08-14 16:46:44 +02:00
Robert Schmidt
9f5ea8beba Merge remote-tracking branch 'origin/cleanup-build-oai-speedup-cluster' into integration_2025_w33 (!3579)
CI: speed up and simplify build, remove unnecessary Python code, remove --eNB* parameter list

This cleans up the CI framework for running end-to-end tests, and
improves the integration with OAI code. Specifically

- cleanup build_oai and helpers to output all text, which is captured
  better by the CI
- build some images in the Cluster-Build in parallel to increase speed
- remove all --eNB{,1,2}{IPAddress,UserName,Password} variables. Those
  were indexed through "instance" and "server ID" and are replaced with
  the actual node name. I consider further cleanup to introduce a
  "global" XML file node name so we don't need this in each step and
  instead define this once.
- individual cleanup
2025-08-14 16:45:52 +02:00
Robert Schmidt
5b8d66bbac Write simple CI documentation and add sample script 2025-08-14 14:55:23 +02:00
Robert Schmidt
b075c733f3 CI: correct log analysis filename interpolation
A previous commit changed to use archiveArtifact() to recover CI logs,
and then attempted to "guess" the L1/MAC stats file name through a
regex. However, the format "enb-[0-9]+" is not correct, as
archiveArtifact() puts the task ID ("[0-9]+") BEFORE the file name
(here, "enb"). So, make it more generic and match the final "-enb.log"
("$" means "end of string").

Fixes: 244ea8fc22 ("Use archiveArtifact() for TerminateeNB()")
2025-08-14 14:55:23 +02:00
Robert Schmidt
f82063c252 CI: Sleep: print time to wait 2025-08-14 14:55:23 +02:00
Robert Schmidt
c5624661eb Remove HTML 'no analysis function'
For some network functions, we don't match an analysis function. In the
console logs we print an info message. In the HTML, it's just noise.
2025-08-14 14:55:23 +02:00
Robert Schmidt
852e98d385 Run_Physim(): avoid large console logs, rewrite file
Many of these tests exit with an exit code != 0. Thus, the CI
automatically logs the result. Rather, write everything including stderr
to the file for analysis.

Also, rewrite the file with ">" instead of appending through ">>". While
appending works because the CI removes files after archiving, it seems
"cleaner" to remove files.
2025-08-14 14:55:23 +02:00
Robert Schmidt
3c54daf4e2 Remove "forcedWorkspaceCleanup" option
It is superseded by the CreateWorkspace() function and task step (which
removes and recreates a workspace), and this option was not actually
used in any function except for the build of unit tests, but no XML
step actually specified this option.
2025-08-14 14:55:23 +02:00
Robert Schmidt
35f080e426 Fix: new Iperf test need to get ctx 2025-08-14 14:55:23 +02:00
Robert Schmidt
9e1cbb1035 Ignore eNB{,1,2}{UserName,IPAddress,Password} parameters
After having transitioned to direct node names in the XML, these
parameters are not relevant anymore.

The best way to view this patch is with

    git show <SHA> --ignore-all-space
2025-08-14 14:55:04 +02:00
Robert Schmidt
0e60be785c Remove SSH connection
Remove this class. It is not safe to use (no return codes, can get out
of sync), hardcodes the use of passwords, and it's API is cumbersone.

More explanations can also be found in !1867. It is superseded by
cls_cmd.py
2025-08-14 14:55:04 +02:00
Robert Schmidt
dc27690c86 LogCollecteNB() not used anymore
Since 28ce0dc444 ("Main: pass in ctx"), the CI always collects logs
into cmake_targets/log/. Hence, LogCollecteNB() is never called. We can
remove it.

Further, change the cmake_targets/log/ to ci-log/, which is shorter, and
append a / on the zip path to make sure that only contents is zipped.
2025-08-14 14:55:04 +02:00
Robert Schmidt
45da9face4 Reimplement Initialize_eNB()/Terminate_eNB()
Reimplement these functions by

- using cls_cmd
- retain only the necessary steps from the timing-phytest function
- pass in ctx and node information, instead of server ID
- remove all superfluous variables that don't seem to be used
- make some lists (corresponding indices are "server ID") into normal
  variables.
2025-08-14 14:55:04 +02:00
Robert Schmidt
c4efe9feed cls_containerize: yamlPath/services as normal string
These variables were set as lists, to be indexed by the "server ID".
Since this has been removed from all XMLs, it is not necessary anymore.
2025-08-14 14:55:04 +02:00
Robert Schmidt
3f4df04875 Run_Physim(): pass node 2025-08-14 14:55:04 +02:00
Robert Schmidt
190dc55d9f Pass node to various Build*() functions
Pass node directly from XML to these functions

- BuildClusterImage()
- BuildImage()
- BuildProxy()
- BuildRunTests()

instead of reading the "server ID" and looking up from
eNB_IPAddress/eNB1_IPAddress/eNB2_IPAddress.

Improve the proxy build unit test by properly passing ctx information.
2025-08-14 14:55:04 +02:00
Robert Schmidt
293c7afd0b File not used by CI 2025-08-14 14:55:04 +02:00
Robert Schmidt
074092af17 Remove unused variables 2025-08-14 14:55:04 +02:00
Robert Schmidt
d3837cd3b0 Deploy_Run_PhySim(): pass node name
harmonize with other code that takes a "node" parameter.
2025-08-14 14:55:04 +02:00
Robert Schmidt
af58cf2441 CppCheckAnalysis()/LicenceFormattingCheck(): use node
- ubuntu18 eNB_IPAddress obelix => obelix
- cppcheck eNB_IPAddress 172.21.18.47 => carabe
2025-08-14 14:55:04 +02:00
Robert Schmidt
6233667de9 Push_Local_Registry(): pass node 2025-08-14 14:55:04 +02:00
Robert Schmidt
7839d06601 Create/Deploy/Undeploy(): use node
Pass the node name for a host on which to create a workspace or
deploy/undeploy.

Add a new test for the creation of workspaces.

To help myself and the reviewer, here is a list of
"eNB_IPAddress"/"eNB1_IPAddress" parameters I copied from the various
pipelines:
- rfsim 4G eNB_IPAddress none => localhost
- rfsim 5g eNB_IPAddress none => localhost
- flexric eNB_IPAddress none => localhost
- l2sim 4g eNB_IPAddress none => localhost
- l2sim 4G eNB1_IPAddress 172.21.16.128 => obelix => localhost
- cluster image eNB_IPAddress poseidon
- ubuntu18 eNB_IPAddress obelix => obelix
- ubuntu-arm eNB_IPAddress gracehopper3-oai => gracehopper3-oai
- arm-cross eNB_IPAddress alambix => alambix
- lte-tdd eNB_IPAddress 172.21.18.45 => starsky
- lte-fdd eNB_IPAddress 172.21.18.46 => hutch
- lte-oaiue eNB_IPAddress 172.21.18.46 => hutch
- lte-oaiue eNB1_IPAddress 172.21.18.47 => carabe
- lte-tdd-2x2 eNB_IPAddress 172.21.16.128 => obelix
- nsa eNB_IPAddress 172.21.16.137 => nepes
- nsa eNB1_IPAddress 172.21.16.109 => ofqot
- sa-aerial eNB_IPAddress gracehopper1-oai => gracehopper1-oai
- aw2s eNB_IPAddress 172.21.16.124 => avra
- sabox eNB_IPAddress 172.21.16.109 => ofqot
- sa-oaiue eNB_IPAddress avra => avra
- sa-oaiue eNB1_IPAddress caracal => caracal
- cppcheck eNB_IPAddress 172.21.18.47 => carabe
- timing-phytest eNB_IPAddress caracal => caracal
- physim 4g eNB_IPAddress avra => avra
- physim 5g eNB_IPAddress avra => avra
2025-08-14 14:55:04 +02:00
Robert Schmidt
d95e6bca6b Pull_Image_from_Registry()/Clean_Test_Server_Images(): pass node
Pass the node name for a host onto/from which to pull/clean the images.
For doing this, I used:

- rfsim 4G eNB_IPAddress none => localhost
- rfsim 5g eNB_IPAddress none => localhost
- flexric eNB_IPAddress none => localhost
- l2sim 4g eNB_IPAddress none => localhost
- l2sim 4G eNB1_IPAddress 172.21.16.128 => obelix => localhost
2025-08-14 14:55:04 +02:00
Robert Schmidt
e25075134c Integrate all SA-OAIUE pipeline related files into one 2025-08-14 14:55:04 +02:00
Robert Schmidt
881f753f3f Integrate all NSA-related XML files into one
Is simpler to test manually and view the results.
2025-08-14 14:55:04 +02:00
Robert Schmidt
7defffe97a Remove unused file 2025-08-14 14:55:04 +02:00
Robert Schmidt
ae3799d4ed Remove unused parameters 2025-08-14 14:55:04 +02:00
Robert Schmidt
c8c6aa50f3 Cluster: build FHI7.2 in parallel 2025-08-14 14:55:04 +02:00
Robert Schmidt
2f43b09651 Remove unnecessary HTML printing, simplify code 2025-08-14 14:55:04 +02:00
Robert Schmidt
81a79980dd AnalyzeBuildLogs(): only analyze one file at a time
Will be used in a follow-up commit to simplify analysis of log files and
HTML file printing.
2025-08-14 14:55:04 +02:00
Robert Schmidt
089059e10a Remove unused variables 2025-08-14 14:55:04 +02:00
Bartosz Podrygajlo
3febc50f47 Make run_locally.sh script take the full path to the xml file
Use full path to xml file in run_locally.sh to allow usage of system
command line completion feature.
2025-08-14 14:55:04 +02:00
Robert Schmidt
cf967d3314 Complete run_locally.sh to produce valid HTML 2025-08-14 14:55:04 +02:00
Robert Schmidt
e7ea9ba747 CI: Clarify HTML message if a (ctest-executed) test fails 2025-08-14 14:55:04 +02:00
Robert Schmidt
47b658baf5 Disable various UHD features
build_oai primarily builds UHD for OAI. Thus, a number of targets (B100,
USRP1/2, ...) can be omitted, as OAI does not run on them. Further,
disable documentation and man pages, which is typically not necessary
for the averages user, and does not need to be installed for containers.
2025-08-14 14:55:04 +02:00
Robert Schmidt
599a1a8c74 UHD installation: remove multiple packages at once
Removing packages individually is slow, because apt starts to (re-)read
it's database over and over again. Do it at once to speed up.
2025-08-14 14:55:04 +02:00
Robert Schmidt
2086de2a98 Do not collect log files that don't exist
Since one of the parent commits, build_oai does not redirect files to a
log folder. Hence, there is no need to collect those.
2025-08-14 14:55:04 +02:00
Robert Schmidt
334251c4ff Remove unused build_helper function 2025-08-14 14:55:04 +02:00
Robert Schmidt
6c4e5dccea Don't redirect installation log files to a file
Similarly to the parent, don't redirect log files to a file. It makes
the CI more complicated, and also raises user awareness of what is being
installed.
2025-08-14 14:55:04 +02:00
Robert Schmidt
47a961d876 Merge remote-tracking branch 'origin/refactor-ulsch' into integration_2025_w33 (!3521)
Refactor ULSCH scheduler towards more TDD pattern flexibility

Refactors ULSCH scheduler, notably to support "UL-heavy" TDD patterns,
e.g., DSUUU. Also allows to run TDD pattern2 with UL slots, which was a
limitation in the previous code.
2025-08-14 14:30:58 +02:00
Robert Schmidt
f08710a524 Merge remote-tracking branch 'origin/ubuntu24-docker-images' into integration_2025_w33 (!3492)
Upgrade CI images to Ubuntu 24

The MR upgrade the docker files from Jammy(22.04) to Noble(24.04).
2025-08-14 14:30:21 +02:00
Robert Schmidt
e0c1f8d920 Increase AL candidates count on AW2S pipeline
Increase the number of aggregration level candidates. Since we have many
UEs with concurrent traffic in that pipeline, we should ensure that we
can allocate many DCIs to not waste resources (e.g., not all RBs used
because could not find DCIs for specific UEs).
2025-08-14 13:00:13 +02:00
Robert Schmidt
ba6bad5eb3 Fix AL candidate documentation to right default
The default aggregation level candidate numbers in gnb_config.c (search
"uess_num_agg_level_candidates") is 0,2,0,0,0, so write that instead.
2025-08-14 12:55:53 +02:00
Robert Schmidt
c24673798a Handle TDD pattern 2 in UL TDA allocation
Add the possibility to use UL slots in TDD pattern 2. For simplicity, we
require the mixed slot to be of the same symbols in pattern 1 & 2. For
UL slots, simply use the right amount of UL TDAs, depending on which
number of UL slots among pattern 1 & 2 is bigger.

One complication is the TDA for the mixed slot. The current code assumes
that k2 has to be equal or larger than (number of DL slots +1) (because
the spec says min k2=2, but we might want to schedule DSUUU). Then,
there could be for instance the following cases:

- only pattern 1: DSUUU DSUUU ...: the mixed slot has to be reached an
  entire period in advance
- pattern 1 & 2: DSUUU DDDDD: normal mixed slot k2, e.g., like for 7DS2U
- pattern 1 & 2: DSUUU DDDSU: the mixed slot has to be reached
  N_ul2+N_dl1+1 slots in advance

I can't think of more cases right now. To avoid unscheduled slots, I put
an assertion (which could also trivially be taken out).
2025-08-14 12:50:03 +02:00
Rúben Soares Silva
135525c17a P5 Config: Pack/Unpack TDD table with 10.02 and 10.04 formats
Adds the capability to pack/unpack the TDD table in CONFIG.request
following both SCF222.10.02 (Tag 0x1027) and SCF222.10.04 (Tag 0x1035)
formats In the case of Aerial, the TDD table is packed following the
10.04 format, but with the 10.02 tag Prevent the packing of Digital
Beamforming table and Precoding Matrix table for Aerial
2025-08-14 12:50:03 +02:00
Robert Schmidt
6981783ee1 Select best out of multiple TDAs
A new function get_best_ul_tda() allows to select the "best" TDA out of
a number of TDA. Specifically, get_best_ul_tda() considers in how many
RBs a given TDA might be allocated, and multiplies this number of RBs
with the number of symbols in the TDA to form a "score". The TDA with
the best "score" is selected, considering it maximizes resource usage.

In phytest scheduler, we use this function to verify that the given TDA
can be really allocated in all selected slots.
2025-08-14 12:50:03 +02:00
Robert Schmidt
71e01bbaa9 Correctly interpret SRS numberOfSymbols
A length of 0 is to be interpreted as 1 symbol, a length of 1 is 2, etc.
2025-08-14 12:50:03 +02:00
Robert Schmidt
98cc36430b Schedule SRS longer in advance, cleanup
Schedule SRS longer in advance, so that it would also be enough even
with big k2 for UL TDA.

Remove useless types: we do not use the information on sched_srs
anymore, so remove it.

Check that the VRB map is free before making allocations.
2025-08-14 12:50:03 +02:00
Robert Schmidt
6ef8dadd88 Only add SRS TDA if SRS is activated
Since the parent commit, the TDA for UL scheduling is dynamically
selected, instead of being hardcoded to specific indices. We can thus
also omit the SRS TDA if no SRS is configured.

Also add SRS-specific TDAs if we schedule further into the future.
2025-08-14 12:50:03 +02:00
Robert Schmidt
cf8099fab1 Refactor TDA allocation: scheduler can take advantage of multiple k2
Add multiple TDAs with k2 larger than the min_rxtxtime, to potentially
allow to allocate all available slots. For this, nr_rrc_config_ul_tda()
inspects the TDD pattern, and allocates as many TDAs as necessary. It
also sorts the TDA list, with smaller k2 and larger symbol lengths
first.

This in turn is now used by get_num_ul_tda() to use a k2 and the slot
configuration to find a suitable TDA, assuming a list as sorted in
nr_rrc_config_ul_tda().

Note that since get_num_ul_tda() does only inspect the available UL
slots, there might be overlap (e.g., when scheduling SRS), which will be
fixed in a follow-up commit.

Also, TDD pattern 2 is not handled here yet, and a follow-up commit will
fix it.
2025-08-14 12:50:03 +02:00
Robert Schmidt
3102068e71 Add ULSCH preprocessor slot logic for scheduling multiple slots
Add a loop to advance slots as determined by current ("DL") slot, and
advance further into the future (for "UL" slots) if TDAs allow. Ensure
to schedule all TDAs if it's the last DL slot, to guarantee a previously
scheduled TDA will also reoccur (i.e., for guaranteeing that
retransmissions can be made).

Note that the check for number of UE being zero is removed, as this
allows to keep "ul_next" close to the "min_next" slot. This way, we can
use fs_get_max(); otherwise, if we did not always execute this loop,
they might diverge far from each other, making the logic inside the loop
more complicated.

This commit introduces a new type "fsn_t" (frame-slot number) that
encapsulates a single frame-slot combination in a single struct. The
helper functions (in gNB_scheduler_ulsch.c) should be moved to a new
file under common/, but we don't do this here to limit the amount of
code changes.
2025-08-14 12:50:03 +02:00
Robert Schmidt
4aea866b6a Use k2 to decide which TDA to use
For scheduling multiple ULSCH ahead, we will have to use different k2.
Hence, we will need to check for k2 in the TDA selection as well. The
function get_ul_tda() is renamed to get_num_ul_tda() to reflect that it
might return multiple TDAs (not done in this commit, but in a follow-up
MR). get_num_ul_tda() also returns a pointer to the first suitable TDA.

In the phy-test scheduler, simplify the selection of the TDA to use: do
not hardcode a specific K2, but rather, use the first one (with any k2).
2025-08-14 12:50:03 +02:00
Robert Schmidt
9059c0290e Provide selected TDA to pf_ul() 2025-08-14 12:50:03 +02:00
Robert Schmidt
90406c101e Introduce dedicated ul_tda array 2025-08-14 12:50:03 +02:00
Robert Schmidt
948c0d5d2c Count and print failed CCE allocations for UL/DL 2025-08-14 12:50:03 +02:00
Robert Schmidt
5e734238c1 pf_ul(): report if UEs scheduled
For the multi-UL slot scheduling functionality in a follow-up commit, it
would be important to know if the scheduler allocated any UEs. If
pf_ul() allocated for some UEs, we might run it again on a different
slot. If on the other hand, no UEs were allocated, there is no point in
running it again.
2025-08-14 12:50:03 +02:00
francescomani
c94db4adec separate computation of size and value for DCI precoding information 2025-08-14 10:56:33 +02:00
Robert Schmidt
d90c432f10 Merge remote-tracking branch 'origin/aerial_pbbf' into integration_2025_w33 (!3556)
Introduce support for Cat-B RU using Predefined-Beam BF with Aerial L1

This merge introduces the support for BeamID based Beamforming in OAI L2 using FAPI and leveraging Aerial L1. Support for OAI L1 is not in the scope of this MR.

Main changes:

- Introduced a third state for the analog_beamforming parameter.
  0=disabled,1=analog_bf,2=oran_bf
- Correctly populated the FAPI BF PDUs (prg_size, num_prgs,
  dig_bf_interfaces)
2025-08-14 10:37:57 +02:00
Robert Schmidt
3ee41c3fec Explain steps to build Dockerfiles without BuildKit
The Dockerfiles are reused for building on different architectures
(amd64/arm64). They differ, though, on some steps for downloading or
installing platform-specific utilities.

This is handled automatically when using BuildKit, which is the default
in docker versions v23.0+. Older docker versions require some special
settings. Explain this in the README.

Closes: #973
2025-08-14 09:49:43 +02:00
Robert Schmidt
ff9a6d97ea gNB MAC doc: add dl/ul_min_mcs
Previous commits removed min_grant_mcs and instead introduced
dl/ul_min_mcs as a more generic replacement.

Fixes: 96b0cae63e ("Drop 'min_grant_mcs' configuration parameter ")
Fixes: 699afafc6f ("Add support for 'dl_min_mcs' and 'ul_min_mcs'
    configuration parameters")
2025-08-14 08:43:38 +02:00
francescomani
1719375cea minor refactoring in nfapi_nr_interface_scf 2025-08-13 19:31:49 +02:00
Gabriele Gemmi
61a7b6b80e compute prgsize from number of RA RB 2025-08-13 19:31:49 +02:00
Gabriele Gemmi
8beb382277 Removed TRP-scheme byte from UL BF PDU to Interop with Aerial 25-1 (FAPI 10.02) 2025-08-13 19:31:49 +02:00
Gabriele Gemmi
9e34a8ebed Compute DCI prgsize from Coreset 2025-08-13 19:31:46 +02:00
Gabriele Gemmi
ce06099a99 Configuration of FAPI Beamforming PDU for Aerial PBBF 2025-08-13 19:07:53 +02:00
Robert Schmidt
ebb544601c Merge remote-tracking branch 'origin/improve-gtpu-error-handling' into integration_2025_w33 (!3584)
add gtpu error packet parsing and display
2025-08-13 18:36:19 +02:00
Robert Schmidt
569cbe24fa Merge remote-tracking branch 'origin/print_UE_cmd_MAC' into integration_2025_w33 (!3586)
Print UE command line parameters at gNB MAC for split architecture without L1
2025-08-13 18:31:32 +02:00
Laurent THOMAS
efccad956a add gtpu error packet parsing and display 2025-08-13 18:00:31 +02:00
Robert Schmidt
843b12db7f Merge branch 'ci-update-uhd' into 'develop'
CI: Update UHD version to 4.8

See merge request oai/openairinterface5g!3587
2025-08-13 10:20:38 +00:00
Romain Beurdouche
e2c89f36ea feat(ldpc_aal): add decoding timer 2025-08-13 09:55:42 +00:00
Romain Beurdouche
ad8b76a8ef feat(nr-gnb): Log decoding timers in the gNB
Log the LDPC reversed interleaving, reversed rate matching and decoding
time stats in nrL1_stats.log for the gNB.
2025-08-13 09:55:42 +00:00
Romain Beurdouche
e79221b05b feat(nr_ulsim): detailed ULSCH decoding timers
Add timers to provide ULSCH decoding time split between decoding,
rate recovery and deinterleaving.
2025-08-13 09:55:42 +00:00
Romain Beurdouche
748684df05 feat(time_meas): Standard deviation & merge
`diff_square` was not merged in `merge_meas` so that calculation of the
standard deviation was not working with merged timers.
2025-08-13 09:55:42 +00:00
francescomani
071d28b3c9 print UE command line parameters also at MAC 2025-08-13 11:05:44 +02:00
Robert Schmidt
3a241fe587 Merge remote-tracking branch 'origin/amarisoft-ue-redcap' into integration_2025_w33 (!3573)
Make Amarisoft UE sim a RedCap UE

Change Amarisoft UE configuration and gNB of the AW2S pipeline to
be/handle RedCap UEs.

The UE should only connect if the gNB handles RedCap UEs. In the logs,
we should see

    [MAC]   UE with RNTI 3725 is RedCap

which we check for the first two UEs (one normal UE/absence of this
message, one RedCap UE/presence of this message).
2025-08-13 08:10:32 +02:00
Robert Schmidt
96c2c143f3 Merge remote-tracking branch 'origin/ldpc_clean_outdated_logs_and_interfaces' into integration_2025_w33 (!3576)
Cleanup documentation and interface of the LDPC segment coding libraries

Fix interface: The LDPC segment decoder interface had variables
'harq_pid', 'ulsch_id' and 'C' that are not useful to the segment
decoder. This MR removes these variables from the interface.

Fix documentation: libconfig log do not display anymore by default so we
may better not show them in the documentation to avoid any
misunderstanding.

Remove ldpc_cl library since the library does not work.
2025-08-13 07:41:31 +02:00
Jaroslava Fiedlerova
8f79abed2e CI: Update UHD version to 4.8 2025-08-12 22:27:29 +02:00
francescomani
4b85f35369 add option to directly send the beam index to L1 via FAPI without look-up table (for 7.2 split) 2025-08-12 18:51:16 +02:00
Robert Schmidt
3b57379887 CI AW2S-Amarisoft: verify RedCap'edness of a UE
Since the parent commit, UE 1 is normal (no RedCap), UE 2 is RedCap.
Verify that the gNB agrees with that and detects the second UE as RedCap
by analyzing some logs.

The first check is a bit elaborate, but basically is

    [ $(docker logs | grep XYZ | wc -l) -eq 0 ]
    ^   ^             ^          ^      ^
    1   2             3          4      5

(1) is the if statement, that compares
  (4) the number of occurrences
  (3) of "RedCap" in the
  (2) docker logs
(5) to being equal to

Note for all UEs which number, and whether it is RedCap (so this need to
be kept in sync with the Amarisoft UE sim configuration file in use!).
2025-08-12 17:33:14 +02:00
Robert Schmidt
4a41df2788 Make some Amarisoft UEs RedCap UEs
Change the parameters to be redcap (release: 17, redcap: "redcap") on
some UEs, and modify the path to the updated configuration.
Specifically, make UE 1 normal (no RedCap), UE 2 RedCap, UEs 3&4 normal,
UEs 5&6 RedCap, etc.

RedCap UEs should now only be able to connect if the gNB is handling Redcap
UEs, which is done in the parent commit.
2025-08-12 17:25:44 +02:00
Robert Schmidt
08428381d6 CI AW2S: modify configuration to have RedCap UEs connect 2025-08-12 17:25:44 +02:00
Robert Schmidt
c3e7fe47e6 Remove unused Amarisoft CI XML file 2025-08-12 17:25:44 +02:00
Robert Schmidt
21dd03ee73 Merge remote-tracking branch 'origin/fix_nr_ue_pdcch_llr_size' into integration_2025_w33 (!3580)
NR UE: fix pdcch llr_size calculation in nr_rx_pdcch()
2025-08-12 12:46:46 +02:00
Robert Schmidt
3681ef33a9 Merge remote-tracking branch 'origin/nr_ue_improve_ntn_ta' into integration_2025_w33 (!3581)
NR UE NTN: consider acceleration on orbital path to calculate N_UE_TA_drift_variant

The ntn-Config ephemerisInfo contains the SAT position and velocity
vector but not the acceleration vector.

But the acceleration magnitude on the orbital path can be calculated as:

    t = 2 * pi * r / v
    omega = 2 * pi / t = v / r
    acceleration = omega² * r = v² / r

Where t is the orbital period, r is the orbital radius, v is the orbital
velocity, omega is the angular velocity. The acceleration direction is
from the SAT position towards the earth center. To calculate the
acceleration towards the UE, this is projected on the direction from the
SAT to the UE.

This is used to calculate the variable N_UE_TA_drift_variant and improve
the TA accuracy.
2025-08-12 12:46:14 +02:00
Robert Schmidt
5f674f5b68 Merge remote-tracking branch 'origin/issue_927' into integration_2025_w33 (!3395)
RFsim variable size H_awgn_mimo

Closes #927
2025-08-12 12:45:53 +02:00
Robert Schmidt
98cfbf0203 Merge remote-tracking branch 'origin/hotfix-bad-t-trace' into integration_2025_w33 (!3578)
fix a 4G T trace
2025-08-12 09:42:26 +02:00
Robert Schmidt
345fd992d9 Merge remote-tracking branch 'origin/searchspace0_with_2_occasion_per_slot' into integration_2025_w33 (!3567)
Workaround for handling 2 SS0 occasions per slot

Search Space 0 monitoring might depend on SSB. In !3332 this dependence
was removed by moving the configuration of SS0 earlier in a workaround
to avoid a segfault in handover. Now, a new workaround is needed to
handle 2 search space occasions per slot.
2025-08-12 09:41:50 +02:00
Robert Schmidt
b0ba247a9e Merge remote-tracking branch 'origin/ue_pucch2_bugfix' into integration_2025_w33 (!3563)
UE fixes: pucch format 2 and CSI IM

- DMRS bugfix for PUCCH format 2 with odd start PRB
- CSI IM noise power estimation omits DC subcarrier
2025-08-12 09:41:19 +02:00
Laurent THOMAS
e2c4033b57 When a client connects, we need to start the send/receive loop but the first reception is void data 2025-08-12 09:22:03 +02:00
francescomani
c137020ca2 remove fixed size H_awgn_mimo that may cause segfault in simulator in case of more than 4 antennas 2025-08-12 09:22:03 +02:00
calvin_peyron
12cf015525 "as" should be in capital letters 2025-08-11 17:11:21 +02:00
Calvin Peyron
3a1be4895f Rename ubuntuXX to ubuntu 2025-08-11 17:11:21 +02:00
Calvin Peyron
5210750883 Fix warning tmp may be uninitialized leads to error 2025-08-11 17:11:21 +02:00
calvin_peyron
bc9ae55723 Remove redundancy
As DEBIAN_FRONTEND has been set as environment variable, there is no need to use DEBIAN_FRONTEND=noninteractive inside RUN lines, it is redundant, hence it has been removed.
2025-08-11 17:11:21 +02:00
calvin_peyron
b3675be33a Upgrade CI images to Ubuntu 24
Libboost went from 1.74.0 to 1.83.0 alongside Ubuntu update.
GCC version is set as default to be more practical.
In Ubuntu22, apt sources were in .list files, in Ubuntu24 they are in .sources files.
Add --break-system-packages for pip installation to use same logic as before, see the pip update 23.0.1 (2023-02-17).
With Ubuntu24 liboai_device requires libpython3.12
2025-08-11 17:11:21 +02:00
Robert Schmidt
35361db76b build_oai: don't redirect compilations to a file
Redirecting to a file has the problem that it is difficult in the CI to
recover these files. Furthermore, at least with ninja, when running
build_oai interactively, the build output will only take some lines
(because ninja rewrites lines), so the change should not be that big to
users.

One CI function would print the entire output from build_oai to the
console. Since that output might be long now, do not do this. The file
is archived, anyway.
2025-08-11 16:11:35 +02:00
Romain Beurdouche
b9bed5838e feat(ldpc_cl): Remove ldpc_cl 2025-08-11 08:38:06 +00:00
Thomas Schlichter
eb6c195c9b NR UE NTN: consider acceleration on orbital path to calculate N_UE_TA_drift_variant
The acceleration magnitude on the orbital path can be calculated as:

t = 2 * pi * r / v
omega = 2 * pi / t = v / r
acceleration = omega² * r = v² / r

Where t is the orbital period, r is the orbital radius, v is the orbital velocity, omega is the angular velocity.
The acceleration direction is from the SAT position towards the earth center.
To calculate the acceleration towards the UE, this is projected on the direction from the SAT to the UE.
2025-08-09 07:37:35 +02:00
Thomas Schlichter
4de0e54a3a NR UE: further simplify and optimize the usage of the PDCCH LLR array
The initial version of this patch was provided by "Laurent THOMAS <laurent.thomas@open-cells.com>"
2025-08-08 17:41:15 +02:00
Romain Beurdouche
a2c03f26e9 fix(nrLDPC_decoder_CL): Apply clang-format 2025-08-08 14:48:41 +00:00
Romain Beurdouche
37bf1deb7d fix(nrLDPC_decoder_LYC): apply clang-format 2025-08-08 14:48:41 +00:00
Romain Beurdouche
8d2df31d7b feat(LDPCImplementation.md): Add short introduction and TOC 2025-08-08 14:48:41 +00:00
Romain Beurdouche
d702bcd657 fix(LDPCdecoder): Cleanup segment decoder interface
Variables 'harq_pid', 'ulsch_id' and 'C' of the segment decoder
interface were not used any more by the implementations and set to zero
by all the callers.
Then it is more relevant and compliant to remove them.
2025-08-08 14:48:41 +00:00
Romain Beurdouche
eb3bd33fd4 feat(LDPCImplementation.md): Remove ldpc_cl logs
Recommended: Remove logs of a library that is not working as far as we
know.

Pop this commit if this seems not necessary.
2025-08-08 14:48:41 +00:00
Romain Beurdouche
cb5de9afbb fix(LDPCImplementation.md): Remove libconfig logs
libconfig log do not display anymore by default so we may better not
show them in the documentation to avoid any misunderstanding.
2025-08-08 14:48:40 +00:00
Thomas Schlichter
a6ccdd1340 NR UE: fix pdcch llr_size calculation in nr_rx_pdcch() 2025-08-08 14:58:14 +02:00
Cedric Roux
a42d8183ca fix a T trace 2025-08-08 12:32:36 +02:00
Robert Schmidt
f3dab10de6 Remove UE_AUTOTEST_TRACE CMake option
This only triggers the build of some dedicated logs that contain
information that is logged already, anyways.
2025-08-08 12:07:48 +02:00
Robert Schmidt
20f938d5ae Remove useless Doxygen variable 2025-08-08 12:07:48 +02:00
Robert Schmidt
f23b654132 Remove auto-test options in build_oai 2025-08-08 12:07:48 +02:00
Jaroslava Fiedlerova
05f9c975ee Merge branch 'integration_2025_w32' into 'develop'
Integration: `2025.w32`

* !3548 NR UE: fix reliable SIB19 reception when ntn-UlSyncValidityDuration-r17 expires
* !3559 numelt in place of config_isparamset
* !3487 T hacks: add new tracer ant0 and a tool to plot ofdm data from usrp or rfsim (output or input)
* !3541 simplify and make more local variables in nr_rx_pdcch() and fix small bugs
* !3547 Add a CU-UP load tester and improve GTP performance
* !3552 CI: refactor iperf3 UDP analysis function
* !3557 Fix PDSCH rate-matching for periodic CSI in UE
* !3571 fix time manager tests in the CI
* !3344 LDPC BBDEV/AAL rework
* !3560 CI: Refactor log collection, collect also (COTS) UE logs

See merge request oai/openairinterface5g!3565
2025-08-08 10:04:17 +00:00
francescomani
4b8359f11c fix for UECAP F1 handling in dora/phytest mode 2025-08-08 09:07:10 +02:00
Jaroslava Fiedlerova
3491a044ff Merge remote-tracking branch 'origin/ci-collect-ue-logs' into integration_2025_w32 (!3560)
CI: Refactor log collection, collect also (COTS) UE logs

Refactor log handling in CI: collect according to currently used XML files. This
makes it homogeneous in the pipelines, and avoids accidental overwriting (as
happens in phytest-timing), as well as harmonizing the log placement
(e.g., no YAML lookup in Ping/Iperf).

Allow to trace and archive UE logs (e.g., Quectel via QLog, Amarisoft UE logs).
By default, no logs will be collected as of this MR, as many files are big.

Various cleanup in Jenkinsfiles, some bugfixes, add unit tests.
2025-08-07 21:40:35 +02:00
Jaroslava Fiedlerova
5ca59d0f48 Merge remote-tracking branch 'origin/ldpc-aal' into integration_2025_w32 (!3344)
LDPC BBDEV/AAL rework

This branch aims to generalize the existing LDPC T2 implementation to support
other DPDK BBDEV accelerators, e.g., Intel ACC100/200.

Differences from the current T2 implementation include:
  1. relax CMakeLists.txt checking for custom dpdk-t2 implementation,
     technically, any DPDK BBDEV should work
  2. BBDEV capability checks during init
  3. llr_scaling to scale the input llr accordingly for better decoding
     performance on the Intel ACC100/200
  4. self-managed harq buffers for the ACC200, as internal harq memory is not
     available

Tested BBDEV devices:
  1. Intel ACC100
  2. Intel ACC200/VRB1
2025-08-07 12:17:11 +02:00
Jaroslava Fiedlerova
5555a465fc Merge remote-tracking branch 'origin/fix-time-manager-ci' into integration_2025_w32 (!3571)
fix time manager tests in the CI

Attempt to have less errors in the CI for the time manager module.
2025-08-06 22:54:07 +02:00
Cedric Roux
eaffaf4058 time manager tests: increase some sleep
The CI fails sometimes, because some processes/threads are created in
unpredictable order and if the client connects before the server is
ready some tests fail, as seen in the following log:

[UTIL]   client/server iq-samples: launch sub-processes
[UTIL]   threadCreate() for time client: creating thread (no affinity, default priority)
[UTIL]   time manager configuration: [time source: server] [mode: client] [server IP: 127.0.0.1} [server port: 7374]
[UTIL]   time client: connection to 127.0.0.1:7374 failed, try again in 1s
[UTIL]   threadCreate() for time source iq samples: creating thread (no affinity, default priority)
[UTIL]   threadCreate() for time server: creating thread (no affinity, default priority)
[UTIL]   time manager configuration: [time source: iq_samples] [mode: server] [server IP: 127.0.0.1} [server port: 7374]
[UTIL]   client/server: rlc ticks: 1000 pdcp ticks: 1000 x2ap ticks: 1000
CMDLINE: "/oai-ran/build/common/utils/time_manager/tests/test_time_manager_auto" "--time_management.mode" "server" "--time_management.time_source" "iq_samples"
[UTIL]   client/server: rlc ticks: 0 pdcp ticks: 0 x2ap ticks: 0
CMDLINE: "/oai-ran/build/common/utils/time_manager/tests/test_time_manager_auto" "--time_management.mode" "client"
[UTIL]   client-server iq-samples: ERROR

The client/server iq-samples test is started.
Then we see this log:
[UTIL]   time manager configuration: [time source: server] [mode: client] [server IP: 127.0.0.1} [server port: 7374]
Which means that the client is running.

It tries to connect to the server (not running yet), but fails, so sleeps
for 1 second before attempting another connection to the server:
[UTIL]   time client: connection to 127.0.0.1:7374 failed, try again in 1s

The sleep is done by the time_client thread, the main thread of the test
program continues and does a sleep(1).

Then the server arrives:
[UTIL]   time manager configuration: [time source: iq_samples] [mode: server] [server IP: 127.0.0.1} [server port: 7374]

It sends all the ticks (to no client, since the client is still sleeping).

Then the test is over, the sleep(1) of the client finishes and the program
exits. The client never connected to the server.
We have this log:
[UTIL]   client/server: rlc ticks: 0 pdcp ticks: 0 x2ap ticks: 0

And the test fails.

It's complicated to write an automatic test involving several uncoordinated
programs. The operating system may create processes in any order. We use
some sleeping to wait, but it may be too short or too long, leading to test
failure.

Let's see with more sleep if the CI fails less.
2025-08-06 11:47:10 +02:00
Jaroslava Fiedlerova
555e609a86 Merge remote-tracking branch 'origin/ue-fix-csi-sched' into integration_2025_w32 (!3557)
Fix PDSCH rate-matching for periodic CSI in UE

Changed the search structure to have periodic resoruce id in the outer
loop and configured resource set as inner loop to prevent configuring
resource that is not needed.

Use const for input pointers.
2025-08-06 11:37:00 +02:00
Jaroslava Fiedlerova
b421bdd276 Merge remote-tracking branch 'origin/ci-iperf3-log-fix' into integration_2025_w32 (!3552)
CI: refactor iperf3 UDP analysis function

- add helper function to covert reported bitrate values to Mbps for calculations
- clean up the UDP analysis function, improve test report formatting
- fix an issue where Gbps values were incorrectly reported
  (example: https://jenkins-oai.eurecom.fr/job/RAN-SA-AERIAL-CN5G/4802/)
- update CI unit test report checks to match the new formatting
2025-08-06 11:36:02 +02:00
Xin Zhe Khooi
f6aeb21d97 ldpc_aal: handle T2 case in runtime 2025-08-05 18:38:17 +02:00
Robert Schmidt
0d4246e354 Rename nrLDPC_coding_t2 options to nrLDPC_coding_aal 2025-08-05 18:38:17 +02:00
Robert Schmidt
c0d797ec0e Rename libldpc_t2 to libldpc_aal
Rename the library to reflect that it's more a generic AAL driver than
specifically for AAL. To this end, rename some documentation.

As of this commit, the options are still called nrLDPC_coding_t2. The
next commit will correct this.

Co-authored-by: Xin Zhe Khooi <khooixz@comp.nus.edu.sg>
2025-08-05 18:38:16 +02:00
Xin Zhe Khooi
61ea0a9e81 ldpc_t2: generalize for broader BBDEV support (ACC100/200)
- Generalized LDPC T2 implementation to support other DPDK BBDEV
  accelerators (e.g., Intel ACC100/200)
- Added BBDEV capability checks during initialization
- Introduced LLR scaling to improve decoding performance on Intel ACC
  cards
- Implemented self-managed HARQ buffers for ACC200 (no internal HARQ
  memory)
- Library usage documentation update, and added developer documentation

Co-authored-by: Romain Beurdouche <romain.beurdouche@eurecom.fr>
2025-08-05 18:37:58 +02:00
Sakthivel Velumani
1becaf0671 Fix periodic CSI scheduling in UE
Changed the search structure to have periodic resoruce id in the outer
loop and configured resource set as inner loop to prevent configuring
resource that is not needed.

Use const for input pointers.
2025-08-05 10:01:05 -04:00
Jaroslava Fiedlerova
d630fb2965 Merge remote-tracking branch 'origin/cuup-load-tester' into integration_2025_w32 (!3547)
Add a CU-UP load tester and improve GTP performance

This adds a simple tester program for the CU-UP. It sets up a number of
UEs/bearers in the CU-UP via the E1 interface, then streams data in
downlink/uplink (as seen by the CU-UP). More information is available in
tests/nr-cuup/README.md.

Includes some fixes to properly verify that SCTP is installed, and use
"the right cmake way" to use it in cmake code (see commit for details).
2025-08-04 23:59:05 +02:00
Jaroslava Fiedlerova
de91ab6eb9 Merge remote-tracking branch 'origin/enhance-ssb-dci-processing' into integration_2025_w32 (!3541)
simplify and make more local variables in nr_rx_pdcch() and fix small bugs...

simplify and make more local variables in nr_rx_pdcch() and fix small bugs
(size 9 RE instaed of 12 RE)
2025-08-04 23:57:40 +02:00
Jaroslava Fiedlerova
da2cbea5e4 Merge remote-tracking branch 'origin/record-iq' into integration_2025_w32 (!3487)
T hacks: add new tracer ant0 and a tool to plot ofdm data from usrp or rfsim
(output or input)

The tool ant0 dumps IQ data to a file (or stdout) as float complex or short.
It is needed for a student's project. (Well, we could use record/extract, but
it's simpler.) The tool ofdm-plot is used to plot output or input signal from
gnb in the frequency domain. May be useful to debug, why not.
2025-08-04 23:55:32 +02:00
Jaroslava Fiedlerova
611971c3c7 Merge remote-tracking branch 'origin/use_numet_not_config_isparamset' into integration_2025_w32 (!3559)
numelt in place of config_isparamset

config_isparamset doesn't seem to work for array types, a temporary solution is
using numelt to verify if the parameter is set in config file
2025-08-04 16:19:35 +02:00
Jaroslava Fiedlerova
c29a56fd17 Merge remote-tracking branch 'origin/fix_sib19_reception' into integration_2025_w32 (!3548)
NR UE: fix reliable SIB19 reception when ntn-UlSyncValidityDuration-r17 expires

Fixes:
- gNB: fix scheduling of Rel-17 SIBs
- gNB: fix case in update_SIB1_NR_SI() when multiple Rel-17 SIBs would be defined
- NR UE: fix calculation of SI window expiry

Updating LEO scenario to test this
- set ntn-UlSyncValidityDuration-r17 to 5 seconds for LEO scenario
- NTN config: setting sib1_tda is not required anymore
2025-08-04 16:18:08 +02:00
Robert Schmidt
6bf88bd3d9 Remove F1 interface names from configuration files
These options are not taken into account, they are not even defined in
the configuration module.
2025-08-04 12:34:23 +02:00
Robert Schmidt
faef56e432 Remove old 4G F1 configuration files
4G F1 has been removed from the code base, so these configs are now
useless.

See also commit 9dc2282249 ("Remove 4G F1")
2025-08-04 12:34:23 +02:00
Robert Schmidt
0a5130cf10 Remove unused control port number from F1
Remove these F1-C port numbers. The configuration is not actually
applied, and the default F1-C port number 38472 (see F1AP_PORT_NUMBER)
is hardcoded in the F1 module.

For the moment, I leave the configuration option, in case we want to
allow to configure the port numbers later).
2025-08-04 12:34:23 +02:00
Robert Schmidt
8d5501edc2 Harmonize GTP log messages
Make a common pattern, which makes it simpler to find them in gNB logs,
and, maybe more importantly, link tunnel creation and update (the update
message was missing the "incoming" TEID, so it is not easy to link to
creation apart from the UE ID, but even then the UE might have multiple
tunnels).
2025-08-04 12:34:23 +02:00
Robert Schmidt
9140b36a2d Refactor gtpv1u_bearer_t and use internally
Reuse the gtpv1u_bearer_t for internal functions. Hopefully this will
also simplify implementation of IPv6, as it encapsulates IP address
handling within gtpv1u_bearer_t.
2025-08-04 12:34:23 +02:00
Robert Schmidt
38ac898672 Refactor GTP: pass addr structure directly
This should simplify future transition to IPv6, as we can pass the right
address directly.
2025-08-04 12:34:23 +02:00
Robert Schmidt
5d9db1688a Refactor port number out of newGtpuCreateTunnel()
The (remote) port number of the GTP module is configured during
initialization. It is therefore not required when calling
newGtpuCreateTunnel(), and could even lead to bugs (if another port
number is used than specified during GTP init).
2025-08-04 12:34:23 +02:00
Robert Schmidt
7c34825dae Receiver thread: independent of ITTI
This also seems to reduce the packet loss on my machine.
Especially in uplink there are no losses anymore.
2025-08-04 12:34:23 +02:00
Robert Schmidt
483d610a9b Reduce receiver mutex scope
This seems to reduce packet loss on my machine.
2025-08-04 12:34:23 +02:00
Robert Schmidt
510814a79a Remove unused struct member 2025-08-04 12:34:23 +02:00
Robert Schmidt
d1a03c993c Reformat gtp_itf.cpp 2025-08-04 12:34:23 +02:00
Robert Schmidt
905fe3fb71 DU Buffer Report/DL Delivery Status: remove unused code 2025-08-04 12:34:23 +02:00
Robert Schmidt
07629e29d6 Add CU-UP load tester and documentation
This is a simple CU-UP load tester. It sets up a configurable number of UEs in the
CU-UP, then sends GTP traffic in downlink/uplink in the N3-F1/F1-N3
direction at the CU-UP. It then compares the sent and received data.

Additional parameters, such as amount of traffic, test length, packet
size, and IP addresses/ports are configurable.

To run:

    mkdir build && cd build && cmake .. -GNinja && ninja nr-cuup nr-cuup-load-test params_libconfig
    ./tests/nr-cuup/nr-cuup-load-test
    ./nr-cuup -O ../tests/nr-cuup/load-test.conf

The tester should be able to detect lost and reordered packets.

Example lost: Receive order 2,3,5,6 (lost packet 4)
=> on packet 2, expected 2, next=expected+1=3
=> on packet 3, expected 3, next=expected+1=4
=> on packet 5, expected 4, diff=5-4=1 (lost 1), next=payload+1=6
=> on packet 6, expected 6
=> 1 lost

Example reordered: Receiver order 2,5,3,6 (lost packet 4)
=> on packet 2, expected 2, next=expected+1=3
=> on packet 5, expected 3, diff=5-3=2 (lost 2), next=payload+1=6
=> on packet 3, expected 6, (reduce lost by 1 to 1), next=expected=6
=> on packet 6, expected 6
=> 1 lost

Example reordered: Receiver order 2,5,3,4,6 (no losses)
2025-08-04 12:31:05 +02:00
Thomas Schlichter
506dc7da52 NR UE: invalidate SI window on successful SI reception to avoid wrongly reusing this old SI window for new SI reception
This fix was suggested by Francesco Mani
2025-08-04 10:52:08 +02:00
Thomas Schlichter
16fd1bb67c gNB: fix case when multiple Rel-17 SIBs would be defined
The boolean value v17_sib was not set to true when allocating si_schedulingInfo_v17 and schedulingInfo2_r17.
So multiple Rel-17 SIBs would lead to multiple allocations and only the last SIB being actually configured.

Fix this by removing the redundant v17_sib variable and directly check if the memory was already allocated.
Also move the definition and allocation of si_schedulingInfo_v17 closer to its actual usage.
2025-08-04 10:52:08 +02:00
Thomas Schlichter
7827a40f19 NTN config: setting sib1_tda is not required anymore 2025-08-04 10:52:08 +02:00
Thomas Schlichter
d4f4cefd6b set ntn-UlSyncValidityDuration-r17 to 5 seconds for LEO scenario
Now that we reliably receive SIB19, we can set the ntn-UlSyncValidityDuration-r17 to a sane value
and thus make sure that the UE always has up-to-date SIB19 information.
2025-08-04 10:52:08 +02:00
Thomas Schlichter
53208bd163 NR UE: fix calculation of SI window expiry 2025-08-04 10:52:08 +02:00
Robert Schmidt
626fce4f44 config_frame_structure(): make const 2025-08-04 09:53:14 +02:00
Robert Schmidt
66023f6a8d Refactor get_feasible_msg3_tda()
Simplify the code. Consider any slot for Msg3, and check that the TDA
fits in a given slot (as before).
2025-08-04 09:53:14 +02:00
Robert Schmidt
961a646dc7 Remove dedicated Msg3 TDA
A dedicated Msg3 TDA is simply not necessary: get_feasible_msg3_tda()
already iterates through all TDAs to find a suitable one for Msg3, and
takes things such as parameter Δ already into account.

The only prerequisite is that the ra_ResponseWindow is long enough. In
some configurations, Msg3 TDA ensured that Msg2 still happened during
ra_ResponseWindow, while Msg3 was outside of it. This is not necessarily
the case anymore, unless ra_ResponseWindow is long enough.

For the normal user, removing ra_ResponseWindow from the config will be
enough.
2025-08-04 09:53:14 +02:00
Robert Schmidt
41d14b571c Remove most ra_ResponseWindow config options
Since the parent commit, the ra_ResponseWindow will be chosen
automatically. Correspondingly, remove most ra_ResponseWindow options
from configuration files in the repository.

One problem in some mu=1 configs is that the ra_ResponseWindow=4 (10
slots), which might be overly restrictive if the L1 slot ahead is
somewhat close to 10 (e.g., 6), in which case we might not be always
able to allocate Msg2 in time.

A notable exception here is gnb-vnf.sa.band66.u0.25prb.nfapi.conf, in
which we still provide it (1) since it uses a non-standard configuration
of a ra_ResponseWindow longer than 10ms (see also issue #916 for more
information) and (2) as an example.
2025-08-04 09:53:14 +02:00
Robert Schmidt
ac3451c6f7 Select ra_ResponseWindow automatically if not configured
If the config file does not specify ra_ResponseWindow, select it to be
10 slots in mu=0, or 20 slots for all others.

This should give us enough flexibility to allocate Msg2 without running
out of the response window. The next commit will remove most
ra_ResponseWindow options in configs.
2025-08-04 09:53:14 +02:00
Robert Schmidt
7cae3c2871 Comments on func 2025-08-04 09:53:14 +02:00
Robert Schmidt
8cded62df0 Refactor TDA allocation
Make it simpler to see, in function nr_rrc_config_ul_tda(), which UL
TDAs we allocate for a UE.
2025-08-04 09:53:14 +02:00
Robert Schmidt
62e4025bc8 Integrate inactivity scheduling into main allocation loop
Scheduling for inactivity only deviates in details from the main
scheduling logic: we simply allocate a fixed number of RBs instead of
making it dependent of data.

In this commit, add an additional flag to sort UEs that are scheduled
for inactivity in front of "normal" UEs (with traffic). Then, schedule
those UEs by limiting/fixing the amount of RBs to schedule to
min_grant_prb.

Update the comparator() to properly sort UEs based on this flag and the
coefficient by applying a consistent logic of -1/0/1 (see man qsort) for
smaller/equal/larger. The inactivity flag, if set, will always have
higher priority over the coefficient to schedule these UEs first, as was
the case prior to this commit.
2025-08-04 09:53:14 +02:00
Robert Schmidt
7ee8e8eaba Fix bug: only sort relevant part of list
This reduces the amount of elements to compare.
2025-08-04 09:53:14 +02:00
Robert Schmidt
dd98030202 Refactor to call post-processor in place
Remove sched_ctrl->sched_ulsch, and call the post-processing function
post_process_ulsch() in the places where sched_ctrl->sched_ulsch has
been assigned. This will have two effects:

- it is not necessary to have the final loop over all UEs, which might
  be costly especially towards many UEs.
- till now, there is only a single sched_ulsch; however, a later commit
  will allow to schedule multiple PUSCH transmissions from a single (DL)
  slot. This would require to make sched_ctrl->sched_ulsch, and
  also iterate through all sched_ulsch. In this new scheme, we can
  simply call post_process_ulsch() multiple times, which is simpler (and
  therefore, implicitly handleded as of this commit).
2025-08-04 09:53:14 +02:00
Robert Schmidt
d71cec7958 Refactor ULSCH phy-test scheduler
Write a single NR_sched_pusch_t structure in a single statement (where
possible). Assign to sched_ctrl->sched_pusch later, where the
post-processing functionality will be called in a follow-up commit.
2025-08-04 09:53:14 +02:00
Robert Schmidt
4772dd889e Refactor ULSCH main allocation procedure
Write a single NR_sched_pusch_t structure in a single statement (where
possible). Assign to sched_ctrl->sched_pusch in one place, where the
post-processing functionality will be called in a follow-up commit.
2025-08-04 09:53:14 +02:00
Robert Schmidt
a469f42085 Refactor retransmission's NR_sched_pusch_t usage
Avoid to overwrite the existing retInfo. Instead, create a new
NR_sched_pusch_t and assign to sched_ctrl->sched_pusch in one place. A
follow-up commit will directly trigger the post processor here.
2025-08-04 09:53:14 +02:00
Robert Schmidt
5b39baacc3 Refactor inactivity-based PUSCH allocation
Write a single NR_sched_pusch_t structure in a single statement (where
possible). Assign to sched_ctrl->sched_pusch in one place, where the
post-processing functionality will be called in a follow-up commit.
2025-08-04 09:53:14 +02:00
Robert Schmidt
81b66fae5e UL harq PID: similar to parent, reduce scope of sched_pusch 2025-08-04 09:53:14 +02:00
Robert Schmidt
f3068caa37 Store selected MCS in UE iterator
PF uses MCS and average throughput to decide which UE to schedule. Thus,
the first loop selects the MCS, and the second does the main UE
allocation after sorting by priority, depending on the MCS.

A follow-up commit will remove sched_pusch from NR_UE_sched_ctrl_t.
Thus, we cannot rely on sched_ctrl to store the MCS in the first loop,
and look it up from there in the second. Instead, store it as part of
the UE iterator data, and take it from there.
2025-08-04 09:53:13 +02:00
Robert Schmidt
243e956ee9 Remove unused parameter from sched_pusch 2025-08-04 09:53:13 +02:00
Robert Schmidt
fcebec09ad Read TX power from HARQ.sched_pusch
A later commit will remove sched_ctrl->sched_pusch. Instead, the TX
power is also stored for each HARQ process (as they contain
sched_pusch). Read it from there, which should have the same effect.
2025-08-04 09:53:13 +02:00
Robert Schmidt
acf6b957b3 Refactor post processor into post_process_ulsch()
Introduce an array with information on FAPI structures to save resource
allocation into. It's in nr_mac_gNB.h because the next commit reuses
this for all preprocessors.
2025-08-04 09:53:13 +02:00
Sakthivel Velumani
39c6cb203c Not include DC for CSI IM measurement
DC subcarrier has a significantly higher energy compared to other CSI IM
resource elements. This causes the average interference + noise
estimation to be higher than CSI-RS signal power making the CQI 0. With
a third-party gnb that schedules PDSCH based on CQI, the UE never
receives DL DCI once it starts sending CSI reports.
2025-08-03 16:53:52 -04:00
Sakthivel Velumani
350cf8d6ef Fix PUCCH 2 DMRS in UE
for start RB not multiple of 4
2025-08-03 16:52:43 -04:00
francescomani
88ec5fb239 highlighting UE LOG with sync SSC printed 2025-08-03 10:41:16 +02:00
francescomani
7f4397a091 workaround to take into account SS0 1st symbol depending on SSB 2025-08-03 10:35:46 +02:00
francescomani
aff31d45b4 formatting 2025-08-03 10:25:00 +02:00
Thomas Schlichter
bbf4cd4a90 gNB: fix scheduling of rel-17 SIBs 2025-08-01 16:00:12 +02:00
Jaroslava Fiedlerova
a9f10bd794 Add CI unit test for highrate iperf test 2025-08-01 12:45:33 +02:00
Jaroslava Fiedlerova
73cfaba2dc CI: refactor iperf3 UDP analysis function
- Add helper function to normalize bitrate values to Mbps for calculations.
- Add helper function to extract data from iperf test report.
- Clean up the UDP analysis function, improve test report formatting.
- Fix an issue where Gbps values were incorrectly reported due to inconsistent
  unit parsing.
- Update CI unit test report checks to match the new formatting.
2025-08-01 12:45:29 +02:00
francescomani
228f642755 config_isparamset doesn't work for array types, using numelt instead 2025-07-31 15:30:09 +02:00
Robert Schmidt
44933f18c6 Code does nothing: gtpv1u_data_g never populated, always HASH_TABLE_KEY_NOT_EXISTS 2025-07-31 08:35:10 +02:00
Robert Schmidt
dbe9e8684b OAI hashtable not used in GTP 2025-07-31 08:35:10 +02:00
Robert Schmidt
1e39f20d87 Make GTP compile on its own, without LTE
Avoid the include gtpv1_u_messages_types.h, as this pulls in e.g., LTE
RRC definitions. The CU-UP load tester integrated in one of the
following commits should be able to build without LTE RRC, if it was for
GTP. Unfortunately, ITTI also pulls in LTE RRC, so it's also somewhat
useless...

Put some forward declarations instead. That also shows that the API is
unnecessarily complex, and would need some cleanup.
2025-07-31 08:35:10 +02:00
Robert Schmidt
aa82d83228 Correctly link sctp into SCTP_CLIENT
Remove sctp from all other targets, since we use sctp::sctp on
SCTP_CLIENT (would fail if it does not exist), and SCTP_CLIENT already
fulfils the SCTP dependency.
2025-07-31 08:35:10 +02:00
Robert Schmidt
83bb8017cf Correct Findsctp.cmake
- Provide some documentation
- Make cmake keywards and sctp lib name lowercase
- Use standard form of find_package_handle_standard_args()
- Make an imported target sctp::sctp that will fail if being used in
  cmake unless defined, which will avoid that "sctp" appears in the
  cmake code but is silently discarded

See also:
https://cmake.org/cmake/help/latest/manual/cmake-developer.7.html#a-sample-find-module
2025-07-31 08:35:10 +02:00
Robert Schmidt
9a7d80ef7d CMake module path to beginning
Move the path to the beginning, so that we can use it early.
Specifically, it was after the SCTP module, and the next commit will use
the Findsctp.cmake module to find SCTP. Use the cmake-proper variable.
2025-07-30 09:39:05 +02:00
Laurent THOMAS
f835705dd1 fix array sizes and aligment issues in 5G UE dci decoder 2025-07-25 15:49:35 +02:00
Laurent THOMAS
343b983aa9 fix SIMD tail length in nr_pdcch_detection_mrc() and replace >> operator by / 2025-07-25 10:04:13 +02:00
Laurent THOMAS
b41c9e2e85 move static some functions that are used only in one file 2025-07-25 10:04:13 +02:00
Laurent THOMAS
19d783f6d9 generalize constant nb re per rn in dci_nr.c 2025-07-25 10:04:04 +02:00
Laurent THOMAS
e8f6d14c47 simplify and make more local variables in nr_rx_pdcch() and fix small bugs (size 9 RE instaed of 12 RE) 2025-07-25 10:02:26 +02:00
Laurent THOMAS
b30da5c0b2 reduce size and make local rxdataF_comp in nr_rx_pdcch() 2025-07-25 10:02:26 +02:00
Laurent THOMAS
2c22f49a45 simplify nr_pdcch_channel_compensation() 2025-07-25 10:02:26 +02:00
Laurent THOMAS
3ca12f78e5 simplify function nr_pdcch_extract_rbs_single() 2025-07-25 10:02:26 +02:00
Laurent THOMAS
fffe9531c3 add assert in a case of wrong gNB configuration file 2025-07-25 10:02:26 +02:00
Cedric Roux
c607413eac rfsim: add a T trace to dump RX IQ data
Only for one antenna.
2025-07-11 10:51:59 +02:00
Cedric Roux
a10420e015 T hacks: add ofdm-plot
Used to... surprise... plot OFDM data as output (or input) by gnb!

Limitation: only one antenna.
2025-07-11 10:51:59 +02:00
Cedric Roux
17b5941367 T: dump logs to stderr, not stdout
This is a problem with the new tool ant0 when we dump IQ to stdout.
The logs will mess up the recording.
2025-07-11 10:51:59 +02:00
Cedric Roux
4a0d8ce637 rfsim: add a T trace to dump IQ data
Only for one antenna.
2025-07-11 10:51:59 +02:00
Cedric Roux
6a2997ec9b T hacks: add ant0 utility to dump IQ data as float complex
Or as int16.
2025-07-11 10:51:59 +02:00
459 changed files with 8670 additions and 8861 deletions

View File

@@ -36,6 +36,8 @@ if(NOT DEFINED ENV{CPM_SOURCE_CACHE})
endif()
include("cmake_targets/CPM.cmake")
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}")
##############################
### CCache: reduce compilation time
##############################
@@ -192,26 +194,26 @@ set(CMAKE_CXX_FLAGS
"${C_FLAGS_PROCESSOR} ${commonOpts} -std=c++11 ${CMAKE_CXX_FLAGS}")
add_boolean_option(SANITIZE_ADDRESS False "enable the address sanitizer (ASan)" ON)
add_boolean_option(SANITIZE_ADDRESS OFF "enable the address sanitizer (ASan)" ON)
if (SANITIZE_ADDRESS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fno-common")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fno-common")
endif ()
add_boolean_option(SANITIZE_THREAD False "enable the address sanitizer (TSan)" ON)
add_boolean_option(SANITIZE_THREAD OFF "enable the address sanitizer (TSan)" ON)
if (SANITIZE_THREAD)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread -fno-omit-frame-pointer -fno-common")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -fno-omit-frame-pointer -fno-common")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
endif()
add_boolean_option(SANITIZE_UNDEFINED False "enable the undefined behavior sanitizer (UBSan)" ON)
add_boolean_option(SANITIZE_UNDEFINED OFF "enable the undefined behavior sanitizer (UBSan)" ON)
if (SANITIZE_UNDEFINED)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
endif ()
add_boolean_option(SANITIZE_MEMORY False "enable the memory sanitizer (MSan, requires clang, incompatible with ASan/UBSan)" ON)
add_boolean_option(SANITIZE_MEMORY OFF "enable the memory sanitizer (MSan, requires clang, incompatible with ASan/UBSan)" ON)
if(SANITIZE_MEMORY)
if (SANITIZE_UNDEFINED OR SANITIZE_ADDRESS)
message(FATAL_ERROR "memory sanitizer cannot coexist with address sanitizer or undefined behavior sanitizer, please disable either MSan or ASan and UBSan")
@@ -276,15 +278,16 @@ endif()
# OAI uses this feature to re-use OAI LOG_I(ASN1, ...)
# see common/utils/config.h
add_boolean_option(TRACE_ASN1C_ENC_DEC OFF "Enable ASN1 encoder/decoder debug traces via OAI logging system" ON)
add_boolean_option(T_TRACER True "Activate the T tracer, a debugging/monitoring framework" ON)
add_boolean_option(ENABLE_LTTNG False "Activate the LTTNG tracer, a debugging/monitoring framework" ON)
add_boolean_option(UE_AUTOTEST_TRACE False "Activate UE autotest specific logs" ON)
add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace" ON)
add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace" ON)
add_boolean_option(T_TRACER ON "Activate the T tracer, a debugging/monitoring framework" ON)
add_boolean_option(ENABLE_LTTNG OFF "Activate the LTTNG tracer, a debugging/monitoring framework" ON)
add_boolean_option(UE_DEBUG_TRACE OFF "Activate UE debug trace" ON)
add_boolean_option(UE_TIMING_TRACE OFF "Activate UE timing trace" ON)
add_boolean_option(TRACY_ENABLE OFF "Enable tracy instrumentation" ON)
if (TRACY_ENABLE)
CPMAddPackage("gh:wolfpld/tracy#v0.11.1")
# the tracy version here should match the tracy server version
# below is latest release as of this commit
CPMAddPackage("gh:wolfpld/tracy#0.12.2")
endif()
set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti)
@@ -336,7 +339,6 @@ target_link_libraries(nr_rrc PUBLIC asn1_nr_rrc asn1_lte_rrc)
set(S1AP_DIR ${OPENAIR3_DIR}/S1AP)
include_directories ("${S1AP_DIR}")
add_library(s1ap
${S1AP_DIR}/s1ap_common.c
${S1AP_DIR}/s1ap_eNB.c
${S1AP_DIR}/s1ap_eNB_context_management_procedures.c
${S1AP_DIR}/s1ap_eNB_decoder.c
@@ -508,34 +510,34 @@ include_directories ("${OPENAIR_DIR}/radio/COMMON")
# ???!!! TO BE DOCUMENTED OPTIONS !!!???
##############################################################
add_boolean_option(UE_EXPANSION False "enable UE_EXPANSION with max 256 UE" ON)
add_boolean_option(PHY_TX_THREAD False "enable UE_EXPANSION with max 256 UE" ON)
add_boolean_option(PRE_SCD_THREAD False "enable UE_EXPANSION with max 256 UE" ON)
add_boolean_option(UE_EXPANSION OFF "enable UE_EXPANSION with max 256 UE" ON)
add_boolean_option(PHY_TX_THREAD OFF "enable UE_EXPANSION with max 256 UE" ON)
add_boolean_option(PRE_SCD_THREAD OFF "enable UE_EXPANSION with max 256 UE" ON)
##########################
# SCHEDULING/REAL-TIME/PERF options
##########################
add_boolean_option(ENABLE_USE_CPU_EXECUTION_TIME False "Add data in vcd traces: disable it if perf issues" ON)
add_boolean_option(ENABLE_VCD False "always true now, time measurements of proc calls and var displays" ON)
add_boolean_option(ENABLE_VCD_FIFO False "time measurements of proc calls and var displays sent to FIFO (one more thread)" ON)
add_boolean_option(ENABLE_USE_CPU_EXECUTION_TIME OFF "Add data in vcd traces: disable it if perf issues" ON)
add_boolean_option(ENABLE_VCD OFF "always true now, time measurements of proc calls and var displays" ON)
add_boolean_option(ENABLE_VCD_FIFO OFF "time measurements of proc calls and var displays sent to FIFO (one more thread)" ON)
##########################
# PHY options
##########################
add_integer_option(MAX_NUM_CCs 1 "Carrier component data arrays size (oai doesn't support carrier aggreagtion for now)" ON)
add_boolean_option(SMBV False "Rohde&Schwarz SMBV100A vector signal generator" ON)
add_boolean_option(DEBUG_PHY False "Enable PHY layer debugging options" ON)
add_boolean_option(DEBUG_PHY_PROC False "Enable debugging of PHY layer procedures" ON)
add_integer_option(MAX_NUM_CCs 1 "Carrier component data arrays size (oai doesn't support carrier aggregation for now)" ON)
add_boolean_option(SMBV OFF "Rohde&Schwarz SMBV100A vector signal generator" ON)
add_boolean_option(DEBUG_PHY OFF "Enable PHY layer debugging options" ON)
add_boolean_option(DEBUG_PHY_PROC OFF "Enable debugging of PHY layer procedures" ON)
##########################
# NAS LAYER OPTIONS
##########################
add_boolean_option(NAS_BUILT_IN_UE True "UE NAS layer present in this executable" ON)
add_boolean_option(NAS_BUILT_IN_UE ON "UE NAS layer present in this executable" ON)
##########################
# RRC LAYER OPTIONS
##########################
add_boolean_option(RRC_DEFAULT_RAB_IS_AM True "set the LTE RLC mode to AM for the default bearer, otherwise it is UM." ON)
add_boolean_option(RRC_DEFAULT_RAB_IS_AM ON "set the LTE RLC mode to AM for the default bearer, otherwise it is UM." ON)
# add the binary tree to the search path for include files
# We will find common/oai_version.h after generation in target directory
@@ -602,7 +604,7 @@ include_directories("${OPENAIR_DIR}")
###############
# include T directory even if the T is off because T macros are in the code
# no matter what. Note: sone files are generated, so we have both source and
# no matter what. Note: some files are generated, so we have both source and
# binary directories
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common/utils/T
${CMAKE_CURRENT_BINARY_DIR}/common/utils/T)
@@ -1394,9 +1396,10 @@ include_directories("${OPENAIR1_DIR}/SCHED_NR_UE")
add_library (GTPV1U
${RRC_DIR}/rrc_eNB_GTPV1U.c
${OPENAIR3_DIR}/ocp-gtpu/gtp_itf.cpp
${OPENAIR3_DIR}/ocp-gtpu/gtpu_extensions.c
)
target_link_libraries(GTPV1U PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(GTPV1U PRIVATE SIMU)
target_link_libraries(GTPV1U PRIVATE SIMU ds)
include_directories(${OPENAIR3_DIR}/ocp-gtp)
set (MME_APP_SRC
@@ -1407,12 +1410,14 @@ add_library(MME_APP ${MME_APP_SRC})
target_link_libraries(MME_APP PRIVATE m2ap m3ap)
target_link_libraries(MME_APP PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
find_package(sctp REQUIRED)
set(SCTP_SRC
${OPENAIR3_DIR}/SCTP/sctp_common.c
${OPENAIR3_DIR}/SCTP/sctp_eNB_task.c
${OPENAIR3_DIR}/SCTP/sctp_eNB_itti_messaging.c
)
add_library(SCTP_CLIENT ${SCTP_SRC})
target_link_libraries(SCTP_CLIENT PRIVATE sctp::sctp)
target_link_libraries(SCTP_CLIENT PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
set(NAS_SRC ${OPENAIR3_DIR}/NAS/)
@@ -1711,7 +1716,6 @@ include_directories("${NFAPI_DIR}/pnf_sim/inc")
add_library(oai_iqplayer MODULE
${OPENAIR_DIR}/radio/iqplayer/iqplayer_lib.c
)
set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}")
#################################
# add executables for operation
@@ -1758,7 +1762,7 @@ target_link_libraries(lte-softmodem PRIVATE
${NAS_UE_LIB} ITTI SIMU shlib_loader
-Wl,--end-group z dl)
target_link_libraries(lte-softmodem PRIVATE pthread m CONFIG_LIB rt sctp)
target_link_libraries(lte-softmodem PRIVATE pthread m CONFIG_LIB rt)
target_link_libraries(lte-softmodem PRIVATE ${T_LIB})
target_link_libraries(lte-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(lte-softmodem PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIES} ${lapacke_LIBRARIES} ${lapack_LIBRARIES})
@@ -1814,7 +1818,7 @@ target_link_libraries(lte-uesoftmodem PRIVATE
${NAS_UE_LIB} ITTI shlib_loader
-Wl,--end-group z dl)
target_link_libraries(lte-uesoftmodem PRIVATE pthread m CONFIG_LIB rt sctp)
target_link_libraries(lte-uesoftmodem PRIVATE pthread m CONFIG_LIB rt)
target_link_libraries(lte-uesoftmodem PRIVATE ${T_LIB})
target_link_libraries(lte-uesoftmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(lte-uesoftmodem PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIES} ${lapacke_LIBRARIES} ${lapack_LIBRARIES})
@@ -1851,7 +1855,7 @@ target_link_libraries(nr-softmodem PRIVATE
time_management
-Wl,--end-group z dl)
target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt sctp)
target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt)
target_link_libraries(nr-softmodem PRIVATE ${T_LIB})
target_link_libraries(nr-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
target_link_libraries(nr-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
@@ -1888,7 +1892,7 @@ target_link_libraries(nr-cuup PRIVATE
CONFIG_LIB ITTI SCTP_CLIENT
GTPV1U e1ap f1ap
time_management
z sctp dl pthread shlib_loader ${T_LIB})
z dl pthread shlib_loader ${T_LIB})
target_link_libraries(nr-cuup PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
if(E2_AGENT)
target_link_libraries(nr-cuup PRIVATE e2_agent e2_agent_arg e2_ran_func_cuup)
@@ -2182,3 +2186,4 @@ add_subdirectory(openair1)
add_subdirectory(openair2)
add_subdirectory(openair3)
add_subdirectory(radio)
add_subdirectory(tests)

View File

@@ -98,18 +98,10 @@ pipeline {
echo "no LockResources given"
allParametersPresent = false
}
if (params.eNB_IPAddress == null) {
echo "no eNB_IPAddress given"
allParametersPresent = false
}
if (params.eNB_SourceCodePath == null) {
echo "no eNB_SourceCodePath given"
allParametersPresent = false
}
if (params.eNB_Credentials == null) {
echo "no eNB_Credentials given"
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) {
@@ -188,7 +180,6 @@ pipeline {
}
}
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password']
]) {
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
@@ -196,7 +187,7 @@ pipeline {
if (fileExists(xmlFile)) {
try {
timeout (time: 60, unit: 'MINUTES') {
sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}"
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}"
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
@@ -204,7 +195,7 @@ pipeline {
}
}
}
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}"
}
}
}

View File

@@ -91,24 +91,9 @@ pipeline {
echo "no LockResources given"
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.eNB1_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB1_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB1_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) {
@@ -187,8 +172,6 @@ pipeline {
}
}
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB1_Credentials}", usernameVariable: 'eNB1_Username', passwordVariable: 'eNB1_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password']
]) {
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
@@ -197,7 +180,7 @@ pipeline {
if (fileExists(xmlFile)) {
try {
timeout (time: 60, unit: 'MINUTES') {
sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath}"
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}"
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
@@ -205,7 +188,7 @@ pipeline {
}
}
}
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}"
}
}
}

View File

@@ -92,15 +92,9 @@ pipeline {
echo "no LockResources given"
allParametersPresent = false
}
if (params.eNB_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB_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) {
@@ -179,7 +173,6 @@ pipeline {
}
}
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.OC_Credentials}", usernameVariable: 'OC_Username', passwordVariable: 'OC_Password']
]) {
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
@@ -188,7 +181,7 @@ pipeline {
if (fileExists(xmlFile)) {
try {
timeout (time: 60, unit: 'MINUTES') {
sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}"
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile} --OCUserName=${OC_Username} --OCPassword=${OC_Password} --OCProjectName=${OC_ProjectName}"
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
@@ -196,7 +189,7 @@ pipeline {
}
}
}
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}"
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}"
}
}
}

View File

@@ -91,15 +91,9 @@ pipeline {
echo "no LockResources given"
allParametersPresent = false
}
if (params.eNB_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB_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) {
@@ -170,25 +164,21 @@ pipeline {
}
}
}
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
]) {
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists(xmlFile)) {
try {
timeout (time: 60, unit: 'MINUTES') {
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile}"
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --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}"
}
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}"
}
}
}
@@ -198,11 +188,7 @@ pipeline {
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}"
}
sh "python3 ci-scripts/main.py --mode=TerminateeNB"
}
post {
success {
@@ -218,15 +204,9 @@ pipeline {
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} --BuildId=${env.BUILD_ID}"
echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}"
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"
@@ -262,11 +242,7 @@ pipeline {
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}"
}
sh "python3 ci-scripts/main.py --mode=TerminateeNB"
}
}
}

View File

@@ -81,36 +81,9 @@ pipeline {
echo "no LockResources given"
allParametersPresent = false
}
// 1st eNB parameters
if (params.eNB_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB_Credentials == null) {
allParametersPresent = false
}
// 2nd eNB parameters
if (params.eNB1_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB1_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB1_Credentials == null) {
allParametersPresent = false
}
// 3rd eNB parameters
if (params.eNB2_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB2_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB2_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) {
@@ -181,27 +154,21 @@ pipeline {
}
}
}
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB1_Credentials}", usernameVariable: 'eNB1_Username', passwordVariable: 'eNB1_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB2_Credentials}", usernameVariable: 'eNB2_Username', passwordVariable: 'eNB2_Password'],
]) {
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists(xmlFile)) {
try {
timeout (time: 60, unit: 'MINUTES') {
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --XMLTestFile=${xmlFile}"
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
buildStageStatus = false
}
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists(xmlFile)) {
try {
timeout (time: 60, unit: 'MINUTES') {
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --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}"
}
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}"
}
}
}
@@ -211,11 +178,7 @@ pipeline {
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}"
}
sh "python3 ci-scripts/main.py --mode=TerminateeNB"
}
}
}
@@ -224,15 +187,9 @@ pipeline {
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} --BuildId=${env.BUILD_ID}"
echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}"
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"

View File

@@ -83,36 +83,9 @@ pipeline {
echo "no LockResources given"
allParametersPresent = false
}
// 1st eNB parameters
if (params.eNB_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB_Credentials == null) {
allParametersPresent = false
}
// 2nd eNB parameters
if (params.eNB1_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB1_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB1_Credentials == null) {
allParametersPresent = false
}
// 3rd eNB parameters
if (params.eNB2_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB2_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB2_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) {
@@ -183,27 +156,21 @@ pipeline {
}
}
}
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB1_Credentials}", usernameVariable: 'eNB1_Username', passwordVariable: 'eNB1_Password'],
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB2_Credentials}", usernameVariable: 'eNB2_Username', passwordVariable: 'eNB2_Password'],
]) {
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists(xmlFile)) {
try {
timeout (time: 60, unit: 'MINUTES') {
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --eNB1IPAddress=${params.eNB1_IPAddress} --eNB1UserName=${eNB1_Username} --eNB1Password=${eNB1_Password} --eNB1SourceCodePath=${params.eNB1_SourceCodePath} --eNB2IPAddress=${params.eNB2_IPAddress} --eNB2UserName=${eNB2_Username} --eNB2Password=${eNB2_Password} --eNB2SourceCodePath=${params.eNB2_SourceCodePath} --XMLTestFile=${xmlFile}"
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
buildStageStatus = false
}
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${mainPythonAllXmlFiles}"
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists(xmlFile)) {
try {
timeout (time: 60, unit: 'MINUTES') {
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} --eNBSourceCodePath=${params.eNB_SourceCodePath} --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}"
}
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}"
}
}
}
@@ -212,15 +179,8 @@ pipeline {
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} --BuildId=${env.BUILD_ID}"
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"
}
echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}"
script {
if(fileExists("enb.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "enb.log.${env.BUILD_ID}.zip"

View File

@@ -96,15 +96,9 @@ pipeline {
echo "no LockResources given"
allParametersPresent = false
}
if (params.eNB_IPAddress == null) {
allParametersPresent = false
}
if (params.eNB_SourceCodePath == null) {
allParametersPresent = false
}
if (params.eNB_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) {
@@ -181,25 +175,21 @@ pipeline {
}
}
}
withCredentials([
[$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'],
]) {
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${flexricOption} ${mainPythonAllXmlFiles}"
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
sh "python3 main.py --mode=InitiateHtml --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${flexricOption} ${mainPythonAllXmlFiles}"
String[] myXmlTestSuite = testXMLFile.split("\\r?\\n")
for (xmlFile in myXmlTestSuite) {
if (fileExists(xmlFile)) {
try {
timeout (time: 60, unit: 'MINUTES') {
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${flexricOption} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --XMLTestFile=${xmlFile}"
sh "python3 main.py --mode=TesteNB --ranRepository=${eNB_Repository} --ranBranch=${eNB_Branch} --ranCommitID=${eNB_CommitID} --ranAllowMerge=${eNB_AllowMergeRequestProcess} --ranTargetBranch=${eNB_TargetBranch} ${flexricOption} --eNBSourceCodePath=${params.eNB_SourceCodePath} --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}"
}
sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}"
}
}
}
@@ -209,11 +199,7 @@ pipeline {
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}"
}
sh "python3 ci-scripts/main.py --mode=TerminateeNB"
}
post {
success {
@@ -229,15 +215,8 @@ pipeline {
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} --BuildId=${env.BUILD_ID}"
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"
}
echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m'
sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}"
script {
if(fileExists("enb.log.${env.BUILD_ID}.zip")) {
archiveArtifacts "enb.log.${env.BUILD_ID}.zip"
@@ -273,11 +252,7 @@ pipeline {
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}"
}
sh "python3 ci-scripts/main.py --mode=TerminateeNB"
}
}
}

View File

@@ -7,20 +7,17 @@ This document outlines how to use the OAI CI framework and gives a quickstart.
There is a script `main.py` that
- reads scenario files from XML
- executes the steps (e.g., deployment of core network, gNB, UE, attach, ping,
...)
- executes the steps (e.g., deployment of CN/gNB/UE, attach, ping, ...)
To simplify, a script `run_locally.sh` can be used to run a single scenario.
First, download images for gNB&UE (we assume you already downloaded the CN):
To simplify, a script `run_locally.sh` can be used to run a single scenario
locally. First, download images for gNB&UE (we assume you already downloaded
the CN) and tag them "latest", which is expected by `run_locally.sh`:
docker pull oaisoftwarealliance/oai-gnb:develop
docker tag oaisoftwarealliance/oai-gnb:develop oai-gnb
docker pull oaisoftwarealliance/oai-nr-ue:develop
docker tag oaisoftwarealliance/oai-nr-ue:develop oai-nr-ue
`run_locally.sh` expects `oai-gnb:latest` and `oai-nr-ue:latest` to be present,
hence the tagging.
Now, run the scenario:
cd ~/openairinterface5g/ci-scripts/
@@ -33,8 +30,7 @@ Output should look like
[2025-08-07 18:07:49,631] INFO: Creating HTML header
[2025-08-07 18:07:49,631] INFO: ----------------------------------------
[2025-08-07 18:07:49,766] INFO: ----------------------------------------
[2025-08-07 18:07:49,767] INFO: Starting Scenario: xml_files/container_5g_rfsim_simple.xm
l
[2025-08-07 18:07:49,767] INFO: Starting Scenario: xml_files/container_5g_rfsim_simple.xml
[2025-08-07 18:07:49,767] INFO: ----------------------------------------
[2025-08-07 18:07:49,767] INFO: placing all artifacts for this run in /home/richie/oai/cmake_targets/log/container_5g_rfsim_simple.xml.d/
@@ -46,7 +42,19 @@ l
[2025-08-07 18:07:49,771] INFO: ----------------------------------------
```
it will run and end-to-end test, connecting one UE to the gNB, and ping, before
it will run an end-to-end test, connecting one UE to the gNB, and ping, before
undeploying. As shown, logs will be under
`/home/richie/oai/cmake_targets/log/container_5g_rfsim_simple.xml.d/`. The
python code also produces an HTML report in `ci-scripts/test_results.html`.
# Running with local changes
In order to run the tests as above, with local changes, please [build images
locally](../docker/README.md).
It is not yet possible to override an existing image with changes made locally
to a source file and run it directly through the CI framework. However, it is
possible to override an existing image with local changes, and run the scenario
manually following the console logs steps provided above. This is described in
the [5G RFsimulator
README](yaml_files/5g_rfsimulator/README.md#6-running-with-local-changes).

View File

@@ -59,17 +59,6 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER):
force_local = True
#--apply=<filename> as parameters file, to replace inline parameters
elif re.match(r'^\-\-Apply=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-Apply=(.+)$', myArgv, re.IGNORECASE)
py_params_file = matchReg.group(1)
with open(py_params_file,'r') as file:
# The FullLoader parameter handles the conversion from YAML
# scalar values to Python dictionary format
py_params = yaml.load(file,Loader=yaml.FullLoader)
py_param_file_present = True #to be removed once validated
#AssignParams(py_params) #to be uncommented once validated
#consider inline parameters
elif re.match(r'^\-\-mode=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-mode=(.+)$', myArgv, re.IGNORECASE)
@@ -132,50 +121,11 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER):
SCA.ranTargetBranch=matchReg.group(1)
CLUSTER.ranTargetBranch=matchReg.group(1)
elif re.match(r'^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE):
if re.match(r'^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE)
RAN.eNBIPAddress=matchReg.group(1)
CONTAINERS.eNBIPAddress=matchReg.group(1)
SCA.eNBIPAddress=matchReg.group(1)
CLUSTER.eNBIPAddress=matchReg.group(1)
elif re.match(r'^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1IPAddress=matchReg.group(1)
CONTAINERS.eNB1IPAddress=matchReg.group(1)
elif re.match(r'^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB2IPAddress=matchReg.group(1)
CONTAINERS.eNB2IPAddress=matchReg.group(1)
print("parameters --eNB*IPAddress ignored")
elif re.match(r'^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE):
if re.match(r'^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE)
RAN.eNBUserName=matchReg.group(1)
CONTAINERS.eNBUserName=matchReg.group(1)
SCA.eNBUserName=matchReg.group(1)
CLUSTER.eNBUserName=matchReg.group(1)
elif re.match(r'^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1UserName=matchReg.group(1)
CONTAINERS.eNB1UserName=matchReg.group(1)
elif re.match(r'^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB2UserName=matchReg.group(1)
CONTAINERS.eNB2UserName=matchReg.group(1)
print("parameters --eNB*UserName ignored")
elif re.match(r'^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE):
if re.match(r'^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE)
RAN.eNBPassword=matchReg.group(1)
CONTAINERS.eNBPassword=matchReg.group(1)
SCA.eNBPassword=matchReg.group(1)
CLUSTER.eNBPassword=matchReg.group(1)
elif re.match(r'^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1Password=matchReg.group(1)
CONTAINERS.eNB1Password=matchReg.group(1)
elif re.match(r'^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB2Password=matchReg.group(1)
CONTAINERS.eNB2Password=matchReg.group(1)
print("parameter --eNB*Password ignored")
elif re.match(r'^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
if re.match(r'^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
@@ -184,26 +134,14 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER):
SCA.eNBSourceCodePath=matchReg.group(1)
CLUSTER.eNBSourceCodePath=matchReg.group(1)
elif re.match(r'^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB1SourceCodePath=matchReg.group(1)
CONTAINERS.eNB1SourceCodePath=matchReg.group(1)
print("parameter --eNB1SourceCodePath ignored")
elif re.match(r'^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE)
RAN.eNB2SourceCodePath=matchReg.group(1)
CONTAINERS.eNB2SourceCodePath=matchReg.group(1)
print("parameter --eNB2SourceCodePath ignored")
elif re.match(r'^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE)
CiTestObj.testXMLfiles.append(matchReg.group(1))
HTML.testXMLfiles.append(matchReg.group(1))
HTML.nbTestXMLfiles=HTML.nbTestXMLfiles+1
elif re.match(r'^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE): # cleanup
print("parameter --UEIPAddress ignored")
elif re.match(r'^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE):
print("parameter --UEUserName ignored")
elif re.match(r'^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE):
print("parameter --UEPassword ignored")
elif re.match(r'^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE):
print("parameter --UESourceCodePath ignored")
elif re.match(r'^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE):
matchReg = re.match(r'^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE)
finalStatus = matchReg.group(1)

View File

@@ -46,7 +46,7 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
@@ -61,8 +61,9 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
redcap: "redcap",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
@@ -76,7 +77,7 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
@@ -91,7 +92,7 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
@@ -106,8 +107,9 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
redcap: "redcap",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
@@ -121,8 +123,9 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
redcap: "redcap",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
@@ -136,7 +139,7 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
@@ -151,7 +154,7 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
@@ -166,7 +169,7 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
@@ -181,8 +184,9 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
redcap: "redcap",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
@@ -196,8 +200,9 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
redcap: "redcap",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
@@ -211,8 +216,9 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
redcap: "redcap",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
@@ -226,7 +232,7 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
@@ -241,7 +247,7 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
apn:"oai",
attach_pdn_type:"ipv4",
@@ -256,8 +262,9 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
redcap: "redcap",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],
@@ -271,8 +278,9 @@ allow dynamic UE creation from remote API */
"sim_algo":"milenage",
"op": "1006020f0a478bf6b699f15c062e42b3",
as_release: 15,
as_release: 17,
ue_category: "nr",
redcap: "redcap",
apn:"oai",
attach_pdn_type:"ipv4",
default_nssai: [ { sst: 1, }, ],

View File

@@ -147,7 +147,7 @@ ltebox-nepes:
amarisoft_ue:
Host: amariue
InitScript: /root/lteue-linux-2025-03-15/lteue /root/oaicicd/ran_sa_aw2s_asue_20MHz/aw2s-multi-00102-20.cfg &
InitScript: /root/lteue-linux-2025-03-15/lteue /root/oaicicd/ran_sa_aw2s_asue_20MHz_redcap/aw2s-multi-00102-20.cfg &
TermScript: /root/lteue-linux-2025-03-15/ws.js -t 10 127.0.0.1:9002 '{"message":"quit"}' || killall -KILL lteue-avx2
NetworkScript: ip netns exec ue1 ip a show dev pdn0
#Tracing:

View File

@@ -69,9 +69,7 @@ def OC_logout(cmd):
class Cluster:
def __init__(self):
self.eNBIPAddress = ""
self.eNBSourceCodePath = ""
self.forcedWorkspaceCleanup = False
self.OCUserName = ""
self.OCPassword = ""
self.OCProjectName = ""
@@ -165,24 +163,6 @@ class Cluster:
return -1
return int(result.group("size"))
def _deploy_pod(self, filename, timeout = 120):
ret = self.cmd.run(f'oc create -f {filename}')
result = re.search(r'pod/(?P<pod>[a-zA-Z0-9_\-]+) created', ret.stdout)
if result is None:
logging.error(f'could not deploy pod: {ret.stdout}')
return None
pod = result.group("pod")
logging.debug(f'checking if pod {pod} is in Running state')
ret = self.cmd.run(f'oc wait --for=condition=ready pod {pod} --timeout={timeout}s', silent=True)
if ret.returncode == 0:
return pod
logging.error(f'pod {pod} did not reach Running state')
self._undeploy_pod(filename)
return None
def _undeploy_pod(self, filename):
self.cmd.run(f'oc delete -f {filename}')
def PullClusterImage(self, HTML, node, images, tag_prefix):
logging.debug(f'Pull OC image {images} to server {node}')
self.testCase_id = HTML.testCase_id
@@ -213,13 +193,12 @@ class Cluster:
self.cmd.run(f'oc logs {job} &> {fn}')
return (image, archiveArtifact(self.cmd, ctx, fn))
def BuildClusterImage(self, ctx, HTML):
def BuildClusterImage(self, ctx, node, HTML):
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
HELP.GenericHelp(CONST.Version)
raise ValueError(f'Insufficient Parameter: ranRepository {self.ranRepository} ranBranch {ranBranch} ranCommitID {self.ranCommitID}')
lIpAddr = self.eNBIPAddress
lSourcePath = self.eNBSourceCodePath
if lIpAddr == '' or lSourcePath == '':
if node == '' or lSourcePath == '':
raise ValueError('Insufficient Parameter: eNBSourceCodePath missing')
ocUserName = self.OCUserName
ocPassword = self.OCPassword
@@ -230,8 +209,8 @@ class Cluster:
if self.OCRegistry.startswith("http") or self.OCRegistry.endswith("/"):
raise ValueError(f'ocRegistry {self.OCRegistry} should not start with http:// or https:// and not end on a slash /')
logging.debug(f'Building on cluster triggered from server: {lIpAddr}')
self.cmd = cls_cmd.RemoteCmd(lIpAddr)
logging.debug(f'Building on cluster triggered from server: {node}')
self.cmd = cls_cmd.RemoteCmd(node)
self.testCase_id = HTML.testCase_id
@@ -296,21 +275,12 @@ class Cluster:
if not status: logging.error('failure during build of ran-base')
log_files.append(self._retrieveOCLog(ctx, ranbase_job, lSourcePath, 'ran-base'))
# recover logs by mounting image
self._retag_image_statement('ran-base', 'ran-base', baseTag, 'openshift/ran-base-log-retrieval.yaml')
pod = self._deploy_pod('openshift/ran-base-log-retrieval.yaml')
if pod is not None:
logdir = f'{lSourcePath}/cmake_targets/log/ran-base'
self.cmd.run(f'mkdir -p {logdir}')
self.cmd.run(f'oc rsync {pod}:/oai-ran/cmake_targets/log/ {logdir}')
self._undeploy_pod('openshift/ran-base-log-retrieval.yaml')
ret = self.cmd.run(f'ls {logdir}')
for f in ret.stdout.splitlines():
archiveArtifact(self.cmd, ctx, f"{logdir}/{f}")
else:
status = False
if status:
self._recreate_is_tag('ran-build-fhi72', imageTag, 'openshift/ran-build-fhi72-is.yaml')
self._recreate_bc('ran-build-fhi72', imageTag, 'openshift/ran-build-fhi72-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.build.fhi72.rhel9')
ranbuildfhi72_job = self._start_build('ran-build-fhi72')
self._recreate_is_tag('oai-physim', imageTag, 'openshift/oai-physim-is.yaml')
self._recreate_bc('oai-physim', imageTag, 'openshift/oai-physim-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.phySim.rhel9')
@@ -326,15 +296,22 @@ class Cluster:
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.clang.rhel9')
clang_job = self._start_build('oai-clang')
wait = ranbuild_job is not None and physim_job is not None and clang_job is not None and self._wait_build_end([ranbuild_job, physim_job, clang_job], 1200)
if not wait: logging.error('error during build of ranbuild_job or physim_job or clang_job')
wait = ranbuildfhi72_job is not None and ranbuild_job is not None and physim_job is not None and clang_job is not None and self._wait_build_end([ranbuildfhi72_job, ranbuild_job, physim_job, clang_job], 1200)
if not wait: logging.error('error during build of ranbuildfhi72_job or ranbuild_job or physim_job or clang_job')
status = status and wait
log_files.append(self._retrieveOCLog(ctx, ranbuildfhi72_job, lSourcePath, 'ran-build-fhi72'))
log_files.append(self._retrieveOCLog(ctx, ranbuild_job, lSourcePath, 'ran-build'))
log_files.append(self._retrieveOCLog(ctx, physim_job, lSourcePath, 'oai-physim'))
log_files.append(self._retrieveOCLog(ctx, clang_job, lSourcePath, 'oai-clang'))
self.cmd.run(f'oc get pods.metrics.k8s.io &>> {build_metrics}')
if status:
self._recreate_is_tag('oai-gnb-fhi72', imageTag, 'openshift/oai-gnb-fhi72-is.yaml')
self._recreate_bc('oai-gnb-fhi72', imageTag, 'openshift/oai-gnb-fhi72-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.fhi72.rhel9')
self._retag_image_statement('ran-build-fhi72', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build-fhi72', imageTag, 'docker/Dockerfile.gNB.fhi72.rhel9')
gnb_fhi72_job = self._start_build('oai-gnb-fhi72')
self._recreate_is_tag('oai-enb', imageTag, 'openshift/oai-enb-is.yaml')
self._recreate_bc('oai-enb', imageTag, 'openshift/oai-enb-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.eNB.rhel9')
@@ -353,10 +330,11 @@ class Cluster:
self._retag_image_statement('ran-build', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build', imageTag, 'docker/Dockerfile.gNB.aw2s.rhel9')
gnb_aw2s_job = self._start_build('oai-gnb-aw2s')
wait = enb_job is not None and gnb_job is not None and gnb_aw2s_job is not None and self._wait_build_end([enb_job, gnb_job, gnb_aw2s_job], 800)
wait = gnb_fhi72_job is not None and enb_job is not None and gnb_job is not None and gnb_aw2s_job is not None and self._wait_build_end([gnb_fhi72_job, enb_job, gnb_job, gnb_aw2s_job], 800)
if not wait: logging.error('error during build of eNB/gNB')
status = status and wait
# recover logs
log_files.append(self._retrieveOCLog(ctx, gnb_fhi72_job, lSourcePath, 'oai-gnb-fhi72'))
log_files.append(self._retrieveOCLog(ctx, enb_job, lSourcePath, 'oai-enb'))
log_files.append(self._retrieveOCLog(ctx, gnb_job, lSourcePath, 'oai-gnb'))
log_files.append(self._retrieveOCLog(ctx, gnb_aw2s_job, lSourcePath, 'oai-gnb-aw2s'))
@@ -389,32 +367,6 @@ class Cluster:
log_files.append(self._retrieveOCLog(ctx, nrue_job, lSourcePath, 'oai-nr-ue'))
self.cmd.run(f'oc get pods.metrics.k8s.io &>> {build_metrics}')
if status:
self._recreate_is_tag('ran-build-fhi72', imageTag, 'openshift/ran-build-fhi72-is.yaml')
self._recreate_bc('ran-build-fhi72', imageTag, 'openshift/ran-build-fhi72-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.build.fhi72.rhel9')
ranbuildfhi72_job = self._start_build('ran-build-fhi72')
wait = ranbuildfhi72_job is not None and self._wait_build_end([ranbuildfhi72_job], 1200)
if not wait: logging.error('error during build of ranbuildfhi72_job')
status = status and wait
log_files.append(self._retrieveOCLog(ctx, ranbuildfhi72_job, lSourcePath, 'ran-build-fhi72'))
self.cmd.run(f'oc get pods.metrics.k8s.io &>> {build_metrics}')
if status:
self._recreate_is_tag('oai-gnb-fhi72', imageTag, 'openshift/oai-gnb-fhi72-is.yaml')
self._recreate_bc('oai-gnb-fhi72', imageTag, 'openshift/oai-gnb-fhi72-bc.yaml')
self._retag_image_statement('ran-base', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-base', baseTag, 'docker/Dockerfile.gNB.fhi72.rhel9')
self._retag_image_statement('ran-build-fhi72', 'image-registry.openshift-image-registry.svc:5000/oaicicd-ran/ran-build-fhi72', imageTag, 'docker/Dockerfile.gNB.fhi72.rhel9')
gnb_fhi72_job = self._start_build('oai-gnb-fhi72')
wait = gnb_fhi72_job is not None and self._wait_build_end([gnb_fhi72_job], 600)
if not wait: logging.error('error during build of gNB-fhi72')
status = status and wait
# recover logs
log_files.append(self._retrieveOCLog(ctx, gnb_fhi72_job, lSourcePath, 'oai-gnb-fhi72'))
self.cmd.run(f'oc get pods.metrics.k8s.io &>> {build_metrics}')
# split and analyze logs
imageSize = {}
for image, _ in log_files:
@@ -444,21 +396,18 @@ class Cluster:
self.cmd.close()
# Analyze the logs
collectInfo = cls_containerize.AnalyzeBuildLogs(log_files, status)
for img in collectInfo:
for f in collectInfo[img]:
status = status and collectInfo[img][f]['status']
if not status:
logging.debug(collectInfo)
collectInfo = {}
for image, lf in log_files:
ret = cls_containerize.AnalyzeBuildLogs(image, lf)
imgStatus = ret['status']
msg = f"size {imageSize[image]}, analysis of {os.path.basename(lf)}: {ret['errors']} errors, {ret['warnings']} warnings"
HTML.CreateHtmlTestRowQueue(image, 'OK' if imgStatus else 'KO', [msg])
status = status and imgStatus
if status:
logging.info('\u001B[1m Building OAI Image(s) Pass\u001B[0m')
HTML.CreateHtmlTestRow('all', 'OK', CONST.ALL_PROCESSES_OK)
else:
logging.error('\u001B[1m Building OAI Images Failed\u001B[0m')
HTML.CreateHtmlTestRow('all', 'KO', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlNextTabHeaderTestRow(collectInfo, imageSize)
# TODO fix groovy script, remove the following.
# the groovy scripts expects all logs in
@@ -469,17 +418,17 @@ class Cluster:
return status
def deploy_oc_physim(self, ctx, HTML, oc_release, svr_id):
def deploy_oc_physim(self, ctx, HTML, oc_release, node):
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}')
logging.debug(f'Running physims from server: {node}')
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)
ret = cls_cmd.runScript(node, script, 600, options)
logging.debug(f'"{script}" finished with code {ret.returncode}, output:\n{ret.stdout}')
with cls_cmd.getConnection(svr_id) as ssh:
with cls_cmd.getConnection(node) as ssh:
details_json = archiveArtifact(ssh, ctx, f'{self.eNBSourceCodePath}/ci-scripts/{oc_release}-tests.json')
result_junit = archiveArtifact(ssh, ctx, f'{self.eNBSourceCodePath}/ci-scripts/{oc_release}-run.xml')
archiveArtifact(ssh, ctx, f'{self.eNBSourceCodePath}/ci-scripts/physim_log.txt')
@@ -492,7 +441,7 @@ class Cluster:
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.CreateHtmlTestRowQueue('At least one physical simulator test failed!', 'KO', ["See below for details"])
HTML.CreateHtmlTestRowPhySimTestResult(test_summary, test_result)
logging.error('\u001B[1m Physical Simulator Fail\u001B[0m')
else:

View File

@@ -82,28 +82,23 @@ def CreateTag(ranCommitID, ranBranch, ranAllowMerge):
tagToUse = f'develop-{shortCommit}'
return tagToUse
def AnalyzeBuildLogs(logfiles, globalStatus):
collectInfo = {}
for image, lf in logfiles:
files = {}
errorandwarnings = {}
committed = False
tagged = False
with open(lf, mode='r') as inputfile:
for line in inputfile:
lineHasTag = re.search(f'Successfully tagged {image}:', str(line)) is not None
lineHasTag2 = re.search(f'naming to docker.io/library/{image}:', str(line)) is not None
tagged = tagged or lineHasTag or lineHasTag2
# the OpenShift Cluster builder prepends image registry URL
lineHasCommit = re.search(r'COMMIT [a-zA-Z0-9\.:/\-]*' + image, str(line)) is not None
committed = committed or lineHasCommit
errorandwarnings['errors'] = 0 if committed or tagged else 1
errorandwarnings['warnings'] = 0
errorandwarnings['status'] = committed or tagged
logging.info(f"Analyzing {image}, file {lf}: {errorandwarnings}")
files['Target Image Creation'] = errorandwarnings
collectInfo[image] = files
return collectInfo
def AnalyzeBuildLogs(image, lf):
errorandwarnings = {}
committed = False
tagged = False
with open(lf, mode='r') as inputfile:
for line in inputfile:
lineHasTag = re.search(f'Successfully tagged {image}:', str(line)) is not None
lineHasTag2 = re.search(f'naming to docker.io/library/{image}:', str(line)) is not None
tagged = tagged or lineHasTag or lineHasTag2
# the OpenShift Cluster builder prepends image registry URL
lineHasCommit = re.search(r'COMMIT [a-zA-Z0-9\.:/\-]*' + image, str(line)) is not None
committed = committed or lineHasCommit
errorandwarnings['errors'] = 0 if committed or tagged else 1
errorandwarnings['warnings'] = 0
errorandwarnings['status'] = committed or tagged
logging.info(f"Analyzing {image}, file {lf}: {errorandwarnings}")
return errorandwarnings
def GetImageName(ssh, svcName, file):
ret = ssh.run(f"docker compose -f {file} config --format json {svcName} | jq -r '.services.\"{svcName}\".image'", silent=True)
@@ -219,7 +214,6 @@ def CheckLogs(self, filename, HTML, RAN):
HTML.htmleNBFailureMsg = ""
else:
logging.info(f"Skipping analysis of log '{filename}': no submatch for xNB/UE")
HTML.CreateHtmlTestRowQueue(f"file {name}", 'OK', ["no analysis function"])
logging.debug(f"log check: file {filename} passed analysis {success}")
return success
@@ -235,25 +229,11 @@ class Containerize():
self.ranAllowMerge = False
self.ranCommitID = ''
self.ranTargetBranch = ''
self.eNBIPAddress = ''
self.eNBUserName = ''
self.eNBPassword = ''
self.eNBSourceCodePath = ''
self.eNB1IPAddress = ''
self.eNB1UserName = ''
self.eNB1Password = ''
self.eNB1SourceCodePath = ''
self.eNB2IPAddress = ''
self.eNB2UserName = ''
self.eNB2Password = ''
self.eNB2SourceCodePath = ''
self.forcedWorkspaceCleanup = False
self.imageKind = ''
self.proxyCommit = None
self.eNB_instance = 0
self.eNB_serverId = ['', '', '']
self.yamlPath = ['', '', '']
self.services = ['', '', '']
self.yamlPath = ''
self.services = ''
self.deploymentTag = ''
self.cli = ''
@@ -271,25 +251,10 @@ class Containerize():
# Container management functions
#-----------------------------------------------------------
def GetCredentials(self, server_id):
if server_id == '0':
ip, path = self.eNBIPAddress, self.eNBSourceCodePath
elif server_id == '1':
ip, path = self.eNB1IPAddress, self.eNB1SourceCodePath
elif server_id == '2':
ip, path = self.eNB2IPAddress, self.eNB2SourceCodePath
else:
raise ValueError(f"unknown server ID '{server_id}'")
if ip == '' or path == '':
HELP.GenericHelp(CONST.Version)
raise ValueError(f'Insufficient Parameter: IP/node {ip}, path {path}')
return (ip, path)
def BuildImage(self, ctx, HTML):
svr = self.eNB_serverId[self.eNB_instance]
lIpAddr, lSourcePath = self.GetCredentials(svr)
logging.debug('Building on server: ' + lIpAddr)
cmd = cls_cmd.getConnection(lIpAddr)
def BuildImage(self, ctx, node, HTML):
lSourcePath = self.eNBSourceCodePath
logging.debug('Building on server: ' + node)
cmd = cls_cmd.getConnection(node)
log_files = []
# Checking the hostname to get adapted on cli and dockerfileprefixes
@@ -298,7 +263,7 @@ class Containerize():
self.host = result.group(0)
if self.host == 'Ubuntu':
self.cli = 'docker'
self.dockerfileprefix = '.ubuntu22'
self.dockerfileprefix = '.ubuntu'
self.cliBuildOptions = ''
elif self.host == 'Red Hat':
self.cli = 'sudo podman'
@@ -337,7 +302,7 @@ class Containerize():
imageNames.append(('oai-gnb', 'gNB.fhi72', 'oai-gnb-fhi72', ''))
result = re.search('build_cross_arm64', self.imageKind)
if result is not None:
self.dockerfileprefix = '.ubuntu22.cross-arm64'
self.dockerfileprefix = '.ubuntu.cross-arm64'
result = re.search('native_arm', self.imageKind)
if result is not None:
imageNames.append(('oai-gnb', 'gNB', 'oai-gnb', ''))
@@ -386,13 +351,6 @@ class Containerize():
t = ("ran-base", archiveArtifact(cmd, ctx, logfile))
log_files.append(t)
# Recover build logs, for the moment only possible when build is successful
cmd.run(f"{self.cli} create --name test {baseImage}:{baseTag}")
cmd.run("mkdir -p cmake_targets/log/ran-base")
logfile = f'{lSourcePath}/cmake_targets/log/ran-base.log'
cmd.run(f"{self.cli} cp test:/oai-ran/cmake_targets/log/all.txt {logfile}")
cmd.run(f"{self.cli} rm -f test")
archiveArtifact(cmd, ctx, logfile)
# First verify if the base image was properly created.
ret = cmd.run(f"{self.cli} image inspect --format=\'Size = {{{{.Size}}}} bytes\' {baseImage}:{baseTag}")
allImagesSize = {}
@@ -438,12 +396,6 @@ class Containerize():
log_files.append(t)
if image == 'oai-gnb-aerial':
cmd.run('rm -f nvipc.src.2025.05.20.tar.gz')
if image == 'ran-build' or image == 'ran-build-asan' or image == 'ran-build-fhi72':
cmd.run(f"docker run --name test-log -d {name}:{imageTag} /bin/true")
logfile = f'{lSourcePath}/{image}.ninja.log'
cmd.run(f"docker cp test-log:/oai-ran/cmake_targets/log/all.txt {logfile}")
cmd.run(f"docker rm -f test-log")
archiveArtifact(cmd, ctx, logfile)
# check the status of the build
ret = cmd.run(f"{self.cli} image inspect --format=\'Size = {{{{.Size}}}} bytes\' {name}:{imageTag}")
if ret.returncode != 0:
@@ -480,25 +432,23 @@ class Containerize():
cmd.close()
# Analyze the logs
collectInfo = AnalyzeBuildLogs(log_files, status)
for name, lf in log_files:
ret = AnalyzeBuildLogs(name, lf)
imgStatus = ret['status']
msg = f"size {allImagesSize[name]}, analysis of {os.path.basename(lf)}: {ret['errors']} errors, {ret['warnings']} warnings"
HTML.CreateHtmlTestRowQueue(name, 'OK' if imgStatus else 'KO', [msg])
status = status and imgStatus
if status:
logging.info('\u001B[1m Building OAI Image(s) Pass\u001B[0m')
HTML.CreateHtmlTestRow(self.imageKind, 'OK', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlNextTabHeaderTestRow(collectInfo, allImagesSize)
return True
else:
logging.error('\u001B[1m Building OAI Images Failed\u001B[0m')
HTML.CreateHtmlTestRow(self.imageKind, 'KO', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlNextTabHeaderTestRow(collectInfo, allImagesSize)
HTML.CreateHtmlTabFooter(False)
return False
return status
def BuildProxy(self, ctx, HTML):
svr = self.eNB_serverId[self.eNB_instance]
lIpAddr, lSourcePath = self.GetCredentials(svr)
logging.debug('Building on server: ' + lIpAddr)
ssh = cls_cmd.getConnection(lIpAddr)
def BuildProxy(self, ctx, node, HTML):
lSourcePath = self.eNBSourceCodePath
logging.debug('Building on server: ' + node)
ssh = cls_cmd.getConnection(node)
oldRanCommidID = self.ranCommitID
oldRanRepository = self.ranRepository
@@ -521,7 +471,7 @@ class Containerize():
buildProxy = ret.returncode != 0 # if no image, build new proxy
if buildProxy:
ssh.run(f'rm -Rf {lSourcePath}')
success = CreateWorkspace(lIpAddr, lSourcePath, self.ranRepository, self.ranCommitID, self.ranTargetBranch, self.ranAllowMerge)
success = CreateWorkspace(node, lSourcePath, self.ranRepository, self.ranCommitID, self.ranTargetBranch, self.ranAllowMerge)
if not success:
raise Exception("could not clone proxy repository")
@@ -557,16 +507,6 @@ class Containerize():
self.ranAllowMerge = oldRanAllowMerge
self.ranTargetBranch = oldRanTargetBranch
# we do not analyze the logs (we assume the proxy builds fine at this stage),
# but need to have the following information to correctly display the HTML
files = {}
errorandwarnings = {}
errorandwarnings['errors'] = 0
errorandwarnings['warnings'] = 0
errorandwarnings['status'] = True
files['Target Image Creation'] = errorandwarnings
collectInfo = {}
collectInfo['proxy'] = files
ret = ssh.run(f'docker image inspect --format=\'Size = {{{{.Size}}}} bytes\' proxy:{tag}')
result = re.search(r'Size *= *(?P<size>[0-9\-]+) *bytes', ret.stdout)
# Cleaning any created tmp volume
@@ -580,21 +520,18 @@ class Containerize():
allImagesSize['proxy'] = str(round(imageSize,1)) + ' Mbytes'
logging.info('\u001B[1m Building L2sim Proxy Image Pass\u001B[0m')
HTML.CreateHtmlTestRow('commit ' + tag, 'OK', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlNextTabHeaderTestRow(collectInfo, allImagesSize)
return True
else:
logging.error('proxy size is unknown')
allImagesSize['proxy'] = 'unknown'
logging.error('\u001B[1m Build of L2sim proxy failed\u001B[0m')
HTML.CreateHtmlTestRow('commit ' + tag, 'KO', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlTabFooter(False)
return False
def BuildRunTests(self, ctx, HTML):
svr = self.eNB_serverId[self.eNB_instance]
lIpAddr, lSourcePath = self.GetCredentials(svr)
logging.debug('Building on server: ' + lIpAddr)
cmd = cls_cmd.RemoteCmd(lIpAddr)
def BuildRunTests(self, ctx, node, HTML):
lSourcePath = self.eNBSourceCodePath
logging.debug('Building on server: ' + node)
cmd = cls_cmd.RemoteCmd(node)
cmd.cd(lSourcePath)
ret = cmd.run('hostnamectl')
@@ -605,9 +542,6 @@ class Containerize():
raise Exception("Can build unit tests only on Ubuntu server")
logging.debug('running on Ubuntu as expected')
if self.forcedWorkspaceCleanup:
cmd.run(f'sudo -S rm -Rf {lSourcePath}')
# check that ran-base image exists as we expect it
baseImage = 'ran-base'
baseTag = 'develop'
@@ -625,7 +559,7 @@ class Containerize():
return False
# build ran-unittests image
dockerfile = "ci-scripts/docker/Dockerfile.unittest.ubuntu22"
dockerfile = "ci-scripts/docker/Dockerfile.unittest.ubuntu"
logfile = f'{lSourcePath}/cmake_targets/log/unittest-build.log'
ret = cmd.run(f'docker build --progress=plain --tag ran-unittests:{baseTag} --file {dockerfile} . &> {logfile}')
archiveArtifact(cmd, ctx, logfile)
@@ -658,10 +592,10 @@ class Containerize():
HTML.CreateHtmlTabFooter(False)
return False
def Push_Image_to_Local_Registry(self, HTML, svr_id, tag_prefix=""):
lIpAddr, lSourcePath = self.GetCredentials(svr_id)
logging.debug('Pushing images to server: ' + lIpAddr)
ssh = cls_cmd.getConnection(lIpAddr)
def Push_Image_to_Local_Registry(self, node, HTML, tag_prefix=""):
lSourcePath = self.eNBSourceCodePath
logging.debug('Pushing images to server: ' + node)
ssh = cls_cmd.getConnection(node)
imagePrefix = 'porcepix.sboai.cs.eurecom.fr'
ret = ssh.run(f'docker login -u oaicicd -p oaicicd {imagePrefix}')
if ret.returncode != 0:
@@ -733,28 +667,26 @@ class Containerize():
msg = "Pulled Images:\n" + '\n'.join(pulled_images)
return True, msg
def Pull_Image_from_Registry(self, HTML, svr_id, images, tag=None, tag_prefix="", registry="porcepix.sboai.cs.eurecom.fr", username="oaicicd", password="oaicicd"):
lIpAddr, lSourcePath = self.GetCredentials(svr_id)
logging.debug('\u001B[1m Pulling image(s) on server: ' + lIpAddr + '\u001B[0m')
def Pull_Image_from_Registry(self, HTML, node, images, tag=None, tag_prefix="", registry="porcepix.sboai.cs.eurecom.fr", username="oaicicd", password="oaicicd"):
logging.debug(f'\u001B[1m Pulling image(s) on server: {node}\u001B[0m')
if not tag:
tag = CreateTag(self.ranCommitID, self.ranBranch, self.ranAllowMerge)
with cls_cmd.getConnection(lIpAddr) as cmd:
with cls_cmd.getConnection(node) as cmd:
success, msg = Containerize.Pull_Image(cmd, images, tag, tag_prefix, registry, username, password)
param = f"on node {lIpAddr}"
param = f"on node {node}"
if success:
HTML.CreateHtmlTestRowQueue(param, 'OK', [msg])
else:
HTML.CreateHtmlTestRowQueue(param, 'KO', [msg])
return success
def Clean_Test_Server_Images(self, HTML, svr_id, images, tag=None):
lIpAddr, lSourcePath = self.GetCredentials(svr_id)
logging.debug(f'\u001B[1m Cleaning image(s) from server: {lIpAddr}\u001B[0m')
def Clean_Test_Server_Images(self, HTML, node, images, tag=None):
logging.debug(f'\u001B[1m Cleaning image(s) from server: {node}\u001B[0m')
if not tag:
tag = CreateTag(self.ranCommitID, self.ranBranch, self.ranAllowMerge)
status = True
with cls_cmd.getConnection(lIpAddr) as myCmd:
with cls_cmd.getConnection(node) as myCmd:
removed_images = []
for image in images:
fullImage = f"oai-ci/{image}:{tag}"
@@ -765,30 +697,28 @@ class Containerize():
msg = "Removed Images:\n" + '\n'.join(removed_images)
s = 'OK' if status else 'KO'
param = f"on node {lIpAddr}"
param = f"on node {node}"
HTML.CreateHtmlTestRowQueue(param, s, [msg])
return status
def Create_Workspace(self,HTML):
svr = self.eNB_serverId[self.eNB_instance]
lIpAddr, lSourcePath = self.GetCredentials(svr)
success = CreateWorkspace(lIpAddr, lSourcePath, self.ranRepository, self.ranCommitID, self.ranTargetBranch, self.ranAllowMerge)
def Create_Workspace(self, node, HTML):
lSourcePath = self.eNBSourceCodePath
success = CreateWorkspace(node, lSourcePath, self.ranRepository, self.ranCommitID, self.ranTargetBranch, self.ranAllowMerge)
if success:
HTML.CreateHtmlTestRowQueue('N/A', 'OK', [f"created workspace {lSourcePath}"])
else:
HTML.CreateHtmlTestRowQueue('N/A', 'KO', ["cannot create workspace"])
return success
def DeployObject(self, ctx, HTML):
svr = self.eNB_serverId[self.eNB_instance]
def DeployObject(self, ctx, node, HTML):
num_attempts = self.num_attempts
lIpAddr, lSourcePath = self.GetCredentials(svr)
logging.debug(f'Deploying OAI Object on server: {lIpAddr}')
yaml = self.yamlPath[self.eNB_instance].strip('/')
lSourcePath = self.eNBSourceCodePath
logging.debug(f'Deploying OAI Object on server: {node}')
yaml = self.yamlPath.strip('/')
wd = f'{lSourcePath}/{yaml}'
wd_yaml = f'{wd}/docker-compose.y*ml'
with cls_cmd.getConnection(lIpAddr) as ssh:
services = GetServices(ssh, self.services[self.eNB_instance], wd_yaml)
with cls_cmd.getConnection(node) as ssh:
services = GetServices(ssh, self.services, wd_yaml)
if services == [] or services == ' ' or services == None:
msg = 'Cannot determine services to start'
logging.error(msg)
@@ -823,13 +753,12 @@ class Containerize():
HTML.CreateHtmlTestRowQueue('N/A', 'KO', ['\n'.join(imagesInfo)])
return deployed
def UndeployObject(self, ctx, HTML, RAN):
svr = self.eNB_serverId[self.eNB_instance]
lIpAddr, lSourcePath = self.GetCredentials(svr)
logging.debug(f'\u001B[1m Undeploying OAI Object from server: {lIpAddr}\u001B[0m')
yaml = self.yamlPath[self.eNB_instance].strip('/')
def UndeployObject(self, ctx, node, HTML, RAN):
lSourcePath = self.eNBSourceCodePath
logging.debug(f'\u001B[1m Undeploying OAI Object from server: {node}\u001B[0m')
yaml = self.yamlPath.strip('/')
wd = f'{lSourcePath}/{yaml}'
with cls_cmd.getConnection(lIpAddr) as ssh:
with cls_cmd.getConnection(node) as ssh:
ExistEnvFilePrint(ssh, wd)
services = GetRunningServices(ssh, f"{wd}/docker-compose.y*ml")
copyin_res = None

View File

@@ -34,16 +34,16 @@ DPDK_PATH = '/opt/dpdk-t2-22.11.0'
class Native():
def Build(ctx, test_case, HTML, host, directory, options):
logging.debug(f'Building on server: {host}')
def Build(ctx, node, test_case, HTML, directory, options):
logging.debug(f'Building on server: {node}')
HTML.testCase_id = test_case
with cls_cmd.getConnection(host) as ssh:
with cls_cmd.getConnection(node) as ssh:
base = f"{directory}/cmake_targets"
ret = ssh.run(f"C_INCLUDE_PATH={DPDK_PATH}/include/ PKG_CONFIG_PATH={DPDK_PATH}/lib64/pkgconfig/ {base}/build_oai {options} > {base}/build_oai.log", timeout=900)
success = ret.returncode == 0
logs = ssh.run(f"cat {base}/build_oai.log", silent=True)
logging.debug(f"build finished with code {ret.returncode}, output:\n{logs.stdout}")
logging.debug(f"build finished with code {ret.returncode}")
archiveArtifact(ssh, ctx, f'{base}/build_oai.log')
@@ -70,7 +70,7 @@ class Native():
workSpacePath = f'{directory}/cmake_targets'
runLogFile=f'{workSpacePath}/physim.log'
with cls_cmd.getConnection(host) as cmd:
cmd.run(f'sudo LD_LIBRARY_PATH=.:{DPDK_PATH}/lib64/ {workSpacePath}/ran_build/build/{physim_test} {options} >> {runLogFile}')
cmd.run(f'sudo LD_LIBRARY_PATH=.:{DPDK_PATH}/lib64/ {workSpacePath}/ran_build/build/{physim_test} {options} > {runLogFile} 2>&1')
physim_file = archiveArtifact(cmd, ctx, runLogFile)
success, msg = cls_analysis.Analysis.analyze_physim(physim_file, physim_test, options, threshold)
if success:

View File

@@ -70,16 +70,6 @@ class HTMLManagement():
self.testCase_id = ''
self.desc = ''
self.OsVersion = ['', '']
self.KernelVersion = ['', '']
self.UhdVersion = ['', '']
self.UsrpBoard = ['', '']
self.CpuNb = ['', '']
self.CpuModel = ['', '']
self.CpuMHz = ['', '']
#-----------------------------------------------------------
# HTML structure creation functions
#-----------------------------------------------------------
@@ -342,58 +332,6 @@ class HTMLManagement():
self.htmlFile.write(' </tr>\n')
self.htmlFile.close()
def CreateHtmlNextTabHeaderTestRow(self, collectInfo, allImagesSize, machine='eNB'):
if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):
return
self.htmlFile = open('test_results.html', 'a')
if bool(collectInfo) == False:
self.htmlFile.write(' <tr bgcolor = "red" >\n')
self.htmlFile.write(' <td colspan="6"><b> ----IMAGES BUILDING FAILED - Unable to recover the image logs ---- </b></td>\n')
self.htmlFile.write(' </tr>\n')
else:
for image in collectInfo:
files = collectInfo[image]
# TabHeader for image logs on built shared and target images
if allImagesSize[image].count('unknown') > 0:
self.htmlFile.write(' <tr bgcolor = "orange" >\n')
elif allImagesSize[image].count('Build Failed') > 0:
self.htmlFile.write(' <tr bgcolor = "red" >\n')
else:
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
self.htmlFile.write(' <td colspan="6"><b> ---- ' + image + ' IMAGE STATUS ----> Size ' + allImagesSize[image] + ' </b></td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n')
self.htmlFile.write(' <th colspan="2">Element</th>\n')
self.htmlFile.write(' <th>Nb Errors</th>\n')
self.htmlFile.write(' <th>Nb Warnings</th>\n')
self.htmlFile.write(' <th colspan="2">Status</th>\n')
self.htmlFile.write(' </tr>\n')
for fil in files:
parameters = files[fil]
# TestRow for image logs on built shared and target images
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" >' + fil + ' </td>\n')
if (parameters['errors'] == 0):
self.htmlFile.write(' <td bgcolor = "green" >' + str(parameters['errors']) + '</td>\n')
else:
self.htmlFile.write(' <td bgcolor = "red" >' + str(parameters['errors']) + '</td>\n')
if (parameters['errors'] > 0):
self.htmlFile.write(' <td bgcolor = "red" >' + str(parameters['warnings']) + '</td>\n')
elif (parameters['warnings'] == 0):
self.htmlFile.write(' <td bgcolor = "green" >' + str(parameters['warnings']) + '</td>\n')
else:
self.htmlFile.write(' <td bgcolor = "orange" >' + str(parameters['warnings']) + '</td>\n')
if (parameters['errors'] == 0) and (parameters['warnings'] == 0):
self.htmlFile.write(' <th colspan="2" bgcolor = "green" ><font color="white">OK </font></th>\n')
elif (parameters['errors'] == 0):
self.htmlFile.write(' <th colspan="2" bgcolor = "orange" ><font color="white">OK </font></th>\n')
else:
self.htmlFile.write(' <th colspan="2" bgcolor = "red" > NOT OK </th>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.close()
#for the moment it is limited to 4 columns, to be made generic later
def CreateHtmlDataLogTable(self, DataLog):
if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):

View File

@@ -84,6 +84,29 @@ def Iperf_ComputeTime(args):
raise Exception('Iperf time not found!')
return int(result.group('iperf_time'))
def convert_to_mbps(value, magnitude):
value = float(value)
if magnitude == 'K' or magnitude == 'k':
return value / 1000
elif magnitude == 'M':
return value
elif magnitude == 'G':
return value * 1000
else:
return value
def extract_iperf_data(res):
if not res:
return None
bitrate_val = res.group('bitrate')
magnitude = res.group('magnitude')
return {
'bitrate_mbps': convert_to_mbps(bitrate_val, magnitude),
'jitter': res.group('jitter'),
'packetloss': res.group('packetloss'),
'bitrate_disp': f'{float(bitrate_val):.2f} {magnitude}bps'
}
def Iperf_analyzeV3TCPJson(filename, iperf_tcp_rate_target):
try:
with open(filename) as f:
@@ -131,54 +154,37 @@ def Iperf_analyzeV3BIDIRJson(filename):
return (True, msg)
def Iperf_analyzeV3UDP(filename, iperf_bitrate_threshold, iperf_packetloss_threshold, target_bitrate):
if (not os.path.isfile(filename)):
if not os.path.isfile(filename):
return (False, 'Iperf3 UDP: Log file not present')
if (os.path.getsize(filename)==0):
if os.path.getsize(filename) == 0:
return (False, 'Iperf3 UDP: Log file is empty')
sender_bitrate = None
receiver_bitrate = None
with open(filename, 'r') as server_file:
for line in server_file.readlines():
res_sender = re.search(r'(?P<bitrate>[0-9\.]+)\s+(?P<unit>[KMG]?bits\/sec)\s+(?P<jitter>[0-9\.]+\s+ms)\s+(?P<lostPack>-?\d+)/(?P<sentPack>-?\d+) \((?P<lost>[0-9\.]+).*?\s+(sender)', line)
res_receiver = re.search(r'(?P<bitrate>[0-9\.]+)\s+(?P<unit>[KMG]?bits\/sec)\s+(?P<jitter>[0-9\.]+\s+ms)\s+(?P<lostPack>-?\d+)/(?P<receivedPack>-?\d+)\s+\((?P<lost>[0-9\.]+)%\).*?(receiver)', line)
if res_sender is not None:
sender_bitrate = res_sender.group('bitrate')
sender_unit = res_sender.group('unit')
sender_jitter = res_sender.group('jitter')
sender_lostPack = res_sender.group('lostPack')
sender_sentPack = res_sender.group('sentPack')
sender_packetloss = res_sender.group('lost')
if res_receiver is not None:
receiver_bitrate = res_receiver.group('bitrate')
receiver_unit = res_receiver.group('unit')
receiver_jitter = res_receiver.group('jitter')
receiver_lostPack = res_receiver.group('lostPack')
receiver_receivedPack = res_receiver.group('receivedPack')
receiver_packetloss = res_receiver.group('lost')
if receiver_bitrate is not None and sender_bitrate is not None:
if sender_unit == 'Kbits/sec':
sender_bitrate = float(sender_bitrate) / 1000
if receiver_unit == 'Kbits/sec':
receiver_bitrate = float(receiver_bitrate) / 1000
br_perf = 100 * float(receiver_bitrate) / float(target_bitrate)
br_perf = '%.2f ' % br_perf
sender_bitrate = '%.2f ' % float(sender_bitrate)
receiver_bitrate = '%.2f ' % float(receiver_bitrate)
req_msg = f'Sender Bitrate : {sender_bitrate} Mbps'
bir_msg = f'Receiver Bitrate: {receiver_bitrate} Mbps'
brl_msg = f'{br_perf}%'
jit_msg = f'Jitter : {receiver_jitter}'
pal_msg = f'Packet Loss : {receiver_packetloss} %'
if float(br_perf) < float(iperf_bitrate_threshold):
brl_msg = f'too low! < {iperf_bitrate_threshold}%'
if float(receiver_packetloss) > float(iperf_packetloss_threshold):
pal_msg += f' (too high! > {iperf_packetloss_threshold}%)'
result = float(br_perf) >= float(iperf_bitrate_threshold) and float(receiver_packetloss) <= float(iperf_packetloss_threshold)
return (result, f'{req_msg}\n{bir_msg} ({brl_msg})\n{jit_msg}\n{pal_msg}')
else:
sender_data = None
receiver_data = None
with open(filename, 'r') as server_file:
for line in server_file:
res_sender = re.search(r'(?P<bitrate>[0-9\.]+)\s+(?P<magnitude>[kKMG]?)bits\/sec\s+(?P<jitter>[0-9\.]+\s+ms)\s+(?P<lostPack>-?\d+)/(?P<sentPack>-?\d+)\s+\((?P<packetloss>[0-9\.eE\-\+]+).*?\s+(sender)', line)
res_receiver = re.search(r'(?P<bitrate>[0-9\.]+)\s+(?P<magnitude>[kKMG]?)bits\/sec\s+(?P<jitter>[0-9\.]+\s+ms)\s+(?P<lostPack>-?\d+)/(?P<receivedPack>-?\d+)\s+\((?P<packetloss>[0-9\.eE\-\+]+)%\).*?(receiver)', line)
if res_sender:
sender_data = extract_iperf_data(res_sender)
if res_receiver:
receiver_data = extract_iperf_data(res_receiver)
if not sender_data or not receiver_data:
return (False, 'Could not analyze iperf report')
br_perf = 100 * receiver_data['bitrate_mbps'] / float(target_bitrate)
br_perf_str = f'{br_perf:.2f}%'
req_msg = f"Sender Bitrate : {sender_data['bitrate_disp']}"
bir_msg = f"Receiver Bitrate: {receiver_data['bitrate_disp']} ({br_perf_str})"
jit_msg = f"Jitter : {receiver_data['jitter']}"
pal_msg = f"Packet Loss : {receiver_data['packetloss']}%"
if br_perf < float(iperf_bitrate_threshold):
bir_msg += f' (too low! < {iperf_bitrate_threshold}%)'
if float(receiver_data['packetloss']) > float(iperf_packetloss_threshold):
pal_msg += f' (too high! > {iperf_packetloss_threshold}%)'
result = br_perf >= float(iperf_bitrate_threshold) and float(receiver_data['packetloss']) <= float(iperf_packetloss_threshold)
return (result, f'{req_msg}\n{bir_msg}\n{jit_msg}\n{pal_msg}')
def Iperf_analyzeV2UDP(server_filename, iperf_bitrate_threshold, iperf_packetloss_threshold, target_bitrate):
result = None
if (not os.path.isfile(server_filename)):
@@ -191,12 +197,9 @@ def Iperf_analyzeV2UDP(server_filename, iperf_bitrate_threshold, iperf_packetlos
result = re.search(statusTemplate, str(line)) or result
if result is None:
return (False, 'Could not parse server report!')
bitrate = float(result.group('bitrate'))
magn = result.group('magnitude')
if magn == "k" or magn == "K":
bitrate /= 1000
elif magn == "G": # we assume bitrate in Mbps, therefore it must be G now
bitrate *= 1000
bitrate_val = float(result.group('bitrate'))
magnitude = result.group('magnitude')
bitrate = convert_to_mbps(bitrate_val, magnitude)
jitter = float(result.group('jitter'))
packetloss = float(result.group('packetloss'))
br_perf = float(bitrate)/float(target_bitrate) * 100
@@ -241,6 +244,7 @@ def Custom_Script(HTML, node, script):
return status == 'OK' or status == 'Warning'
def IdleSleep(HTML, idle_sleep_time):
logging.debug(f"sleep for {idle_sleep_time} seconds")
time.sleep(idle_sleep_time)
HTML.CreateHtmlTestRow(f"{idle_sleep_time} sec", 'OK', CONST.ALL_PROCESSES_OK)
return True

View File

@@ -76,25 +76,18 @@ class StaticCodeAnalysis():
self.ranAllowMerge = False
self.ranCommitID = ''
self.ranTargetBranch = ''
self.eNBIPAddress = ''
self.eNBUserName = ''
self.eNBPassword = ''
self.eNBSourceCodePath = ''
def CppCheckAnalysis(self, ctx, HTML):
def CppCheckAnalysis(self, ctx, node, HTML):
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
lPassWord = self.eNBPassword
lSourcePath = self.eNBSourceCodePath
if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
logging.debug('Building on server: ' + lIpAddr)
cmd = cls_cmd.getConnection(lIpAddr)
if not lSourcePath or not node:
raise ValueError(f"{lSourcePath=} {node=}")
logging.debug('Building on server: ' + node)
cmd = cls_cmd.getConnection(node)
self.testCase_id = HTML.testCase_id
# on RedHat/CentOS .git extension is mandatory
result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
@@ -184,20 +177,16 @@ class StaticCodeAnalysis():
return True
def LicenceAndFormattingCheck(self, ctx, HTML):
def LicenceAndFormattingCheck(self, ctx, node, HTML):
# Workspace is no longer recreated from scratch.
# It implies that this method shall be called last within a build pipeline
# where workspace is already created
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
lPassWord = self.eNBPassword
lSourcePath = self.eNBSourceCodePath
if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
logging.debug('Building on server: ' + lIpAddr)
cmd = cls_cmd.getConnection(lIpAddr)
if not node or not lSourcePath:
raise ValueError(f"{lSourcePath=} {node=}")
logging.debug('Building on server: ' + node)
cmd = cls_cmd.getConnection(node)
self.testCase_id = HTML.testCase_id
check_options = ''
@@ -212,7 +201,7 @@ class StaticCodeAnalysis():
logDir = f'{lSourcePath}/cmake_targets/log/'
cmd.run(f'mkdir -p {logDir}')
cmd.run('docker image rm oai-formatting-check:latest')
cmd.run(f'docker build --target oai-formatting-check --tag oai-formatting-check:latest {check_options} --file {lSourcePath}/ci-scripts/docker/Dockerfile.formatting.bionic {lSourcePath} > {logDir}/oai-formatting-check.txt 2>&1')
cmd.run(f'docker build --target oai-formatting-check --tag oai-formatting-check:latest {check_options} --file {lSourcePath}/ci-scripts/docker/Dockerfile.formatting.ubuntu {lSourcePath} > {logDir}/oai-formatting-check.txt 2>&1')
cmd.run('docker image rm oai-formatting-check:latest')
cmd.run('docker image prune --force')

View File

@@ -23,9 +23,7 @@ gNBs =
local_s_address = "192.168.71.150";
remote_s_address = "192.168.71.171";
local_s_portc = 501;
local_s_portd = 2153;
remote_s_portc = 500;
remote_s_portd = 2153;
# ------- SCTP definitions

View File

@@ -23,9 +23,7 @@ gNBs =
local_s_address = "127.0.0.4";
remote_s_address = "127.0.0.5";
local_s_portc = 501;
local_s_portd = 2153;
remote_s_portc = 500;
remote_s_portd = 2153;
# ------- SCTP definitions

View File

@@ -23,9 +23,7 @@ gNBs =
local_s_address = "192.168.71.150";
remote_s_address = "0.0.0.0"; # multiple DUs
local_s_portc = 501;
local_s_portd = 2152;
remote_s_portc = 500;
remote_s_portd = 2152;
# ------- SCTP definitions

View File

@@ -23,9 +23,7 @@ gNBs =
local_s_address = "127.0.0.4";
remote_s_address = "127.0.0.5";
local_s_portc = 501;
local_s_portd = 2153;
remote_s_portc = 500;
remote_s_portd = 2153;
# ------- SCTP definitions

View File

@@ -22,9 +22,7 @@ gNBs =
local_s_address = "192.168.72.161";
remote_s_address = "192.168.72.171";
local_s_portc = 501;
local_s_portd = 2153;
remote_s_portc = 500;
remote_s_portd = 2153;
# ------- SCTP definitions

View File

@@ -22,9 +22,7 @@ gNBs =
local_s_address = "127.0.0.6";
remote_s_address = "127.0.0.5";
local_s_portc = 501;
local_s_portd = 2153;
remote_s_portc = 500;
remote_s_portd = 2153;
# ------- SCTP definitions

View File

@@ -86,9 +86,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
@@ -163,9 +160,7 @@ MACRLCs = (
tr_n_preference = "f1";
local_n_address = "127.0.0.5";
remote_n_address = "127.0.0.4";
local_n_portc = 500;
local_n_portd = 2153;
remote_n_portc = 501;
remote_n_portd = 2153;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;

View File

@@ -84,9 +84,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
@@ -168,9 +165,7 @@ MACRLCs = (
tr_n_preference = "f1";
local_n_address = "192.168.71.171";
remote_n_address = "192.168.71.150";
local_n_portc = 500;
local_n_portd = 2153;
remote_n_portc = 501;
remote_n_portd = 2153;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;

View File

@@ -83,9 +83,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
@@ -204,9 +201,7 @@ MACRLCs = (
tr_n_preference = "f1";
local_n_address = "127.0.0.5";
remote_n_address = "127.0.0.4";
local_n_portc = 500;
local_n_portd = 2153;
remote_n_portc = 501;
remote_n_portd = 2153;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;

View File

@@ -85,9 +85,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -97,9 +97,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -84,9 +84,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -83,9 +83,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -83,9 +83,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -83,9 +83,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -85,9 +85,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -78,9 +78,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -83,9 +83,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -16,7 +16,6 @@ gNBs =
////////// Physical parameters:
sib1_tda = 5;
min_rxtxtime = 6;
num_dlharq = 32;
num_ulharq = 32;
@@ -85,9 +84,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
@@ -150,6 +146,8 @@ gNBs =
#ext2
#ntn_Config_r17
# This can be of values {s5, s10, s15, s20, s25, s30, s35, s40, s45, s50, s55, s60, s120, s180, s240, s900}
ntn-UlSyncValidityDuration-r17 = 5;
cellSpecificKoffset_r17 = 40;
ta-Common-r17 = 4627000; # 18.84 ms
ta-CommonDrift-r17 = -230000; # -46 µs/s

View File

@@ -16,7 +16,6 @@ gNBs =
////////// Physical parameters:
sib1_tda = 5;
min_rxtxtime = 6;
disable_harq = 1;
cu_sibs = [2];
@@ -84,9 +83,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -82,9 +82,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -81,9 +81,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -86,9 +86,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -84,9 +84,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 2;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -79,9 +79,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -86,9 +86,6 @@ gNBs = (
# powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
# ra_ReponseWindow
# 1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
# ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
# 1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -84,9 +84,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -86,9 +86,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -80,9 +80,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -82,9 +82,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -72,9 +72,6 @@ gNBs:
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep: 1
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow: 5
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR: 4

View File

@@ -85,9 +85,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -78,9 +78,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -98,9 +98,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -99,9 +99,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -80,9 +80,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -87,9 +87,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -83,9 +83,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -87,9 +87,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -25,6 +25,7 @@ gNBs =
pusch_AntennaPorts = 1;
do_CSIRS = 1;
do_SRS = 0;
uess_agg_levels = [2, 2, 2, 0, 0];
servingCellConfigCommon = (
{
@@ -87,9 +88,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
@@ -153,6 +151,11 @@ gNBs =
);
RedCap: {
cellBarredRedCap1Rx_r17 = 1;
cellBarredRedCap2Rx_r17 = 1;
intraFreqReselectionRedCap_r17 = 0;
}
# ------- SCTP definitions
SCTP :

View File

@@ -78,9 +78,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -83,9 +83,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 2;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -83,9 +83,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -82,9 +82,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -83,9 +83,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -98,9 +98,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;

View File

@@ -94,9 +94,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;

View File

@@ -103,9 +103,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3;

View File

@@ -77,9 +77,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -82,9 +82,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 5;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -81,9 +81,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -80,9 +80,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -79,9 +79,6 @@ gNBs =
#powerRampingStep
# 0=dB0,1=dB2,2=dB4,3=dB6
powerRampingStep = 1;
#ra_ReponseWindow
#1,2,4,8,10,20,40,80
ra_ResponseWindow = 4;
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;

View File

@@ -30,8 +30,8 @@ FROM ubuntu:xenial AS oai-cppcheck
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
apt-get upgrade --yes && \
apt-get install --yes \
build-essential \
vim \
cppcheck

View File

@@ -21,11 +21,11 @@
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface BUILD service
# Valid for Ubuntu 22.04
# Valid for Ubuntu 24.04
#
#---------------------------------------------------------------------
FROM ubuntu:bionic AS oai-formatting-check
FROM ubuntu:noble AS oai-formatting-check
ARG MERGE_REQUEST
ARG SRC_BRANCH
@@ -33,8 +33,8 @@ ARG TARGET_BRANCH
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
apt-get upgrade --yes && \
apt-get install --yes \
gawk \
git

View File

@@ -21,7 +21,7 @@
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface BUILD service
# Valid for Ubuntu 22.04
# Valid for Ubuntu 24.04
#
#---------------------------------------------------------------------

View File

@@ -52,10 +52,7 @@ def GitSrvHelp(repository,branch,commit,mergeallow,targetbranch):
print(' --ranAllowMerge=[Allow Merge Request (with target branch) (true or false)] -- ' + mergeallow)
print(' --ranTargetBranch=[Target Branch in case of a Merge Request] -- ' + targetbranch)
def eNBSrvHelp(ipaddr, username, password, sourcepath):
print(' --eNBIPAddress=[eNB\'s IP Address] -- ' + ipaddr)
print(' --eNBUserName=[eNB\'s Login User Name] -- ' + username)
print(' --eNBPassword=[eNB\'s Login Password] -- ' + password)
def eNBSrvHelp(sourcepath):
print(' --eNBSourceCodePath=[eNB\'s Source Code Path] -- ' + sourcepath)
def XmlHelp(filename):

View File

@@ -102,98 +102,46 @@ def ExecuteActionWithParam(action, ctx):
if action == 'Build_eNB' or action == 'Build_Image' or action == 'Build_Proxy' or action == "Build_Cluster_Image" or action == "Build_Run_Tests":
RAN.Build_eNB_args=test.findtext('Build_eNB_args')
CONTAINERS.imageKind=test.findtext('kind')
forced_workspace_cleanup = test.findtext('forced_workspace_cleanup')
RAN.Build_eNB_forced_workspace_cleanup=False
CONTAINERS.forcedWorkspaceCleanup=False
CLUSTER.forcedWorkspaceCleanup = False
if forced_workspace_cleanup is not None and re.match('true', forced_workspace_cleanup, re.IGNORECASE):
RAN.Build_eNB_forced_workspace_cleanup = True
CONTAINERS.forcedWorkspaceCleanup = True
CLUSTER.forcedWorkspaceCleanup = True
eNB_instance=test.findtext('eNB_instance')
if (eNB_instance is None):
RAN.eNB_instance=0
CONTAINERS.eNB_instance=0
else:
RAN.eNB_instance=int(eNB_instance)
CONTAINERS.eNB_instance=int(eNB_instance)
eNB_serverId=test.findtext('eNB_serverId')
if (eNB_serverId is None):
RAN.eNB_serverId[RAN.eNB_instance]='0'
CONTAINERS.eNB_serverId[RAN.eNB_instance]='0'
else:
RAN.eNB_serverId[RAN.eNB_instance]=eNB_serverId
CONTAINERS.eNB_serverId[CONTAINERS.eNB_instance]=eNB_serverId
xmlBgBuildField = test.findtext('backgroundBuild')
if (xmlBgBuildField is None):
RAN.backgroundBuild=False
else:
if re.match('true', xmlBgBuildField, re.IGNORECASE):
RAN.backgroundBuild=True
else:
RAN.backgroundBuild=False
node = test.findtext('node')
proxy_commit = test.findtext('proxy_commit')
if proxy_commit is not None:
CONTAINERS.proxyCommit = proxy_commit
if action == 'Build_eNB':
success = cls_native.Native.Build(ctx, HTML.testCase_id, HTML, RAN.eNBIPAddress, RAN.eNBSourceCodePath, RAN.Build_eNB_args)
success = cls_native.Native.Build(ctx, node, HTML.testCase_id, HTML, RAN.eNBSourceCodePath, RAN.Build_eNB_args)
elif action == 'Build_Image':
success = CONTAINERS.BuildImage(ctx, HTML)
success = CONTAINERS.BuildImage(ctx, node, HTML)
elif action == 'Build_Proxy':
success = CONTAINERS.BuildProxy(ctx, HTML)
success = CONTAINERS.BuildProxy(ctx, node, HTML)
elif action == 'Build_Cluster_Image':
success = CLUSTER.BuildClusterImage(ctx, HTML)
success = CLUSTER.BuildClusterImage(ctx, node, HTML)
elif action == 'Build_Run_Tests':
success = CONTAINERS.BuildRunTests(ctx, HTML)
success = CONTAINERS.BuildRunTests(ctx, node, HTML)
elif action == 'Initialize_eNB':
node = test.findtext('node')
datalog_rt_stats_file=test.findtext('rt_stats_cfg')
if datalog_rt_stats_file is None:
RAN.datalog_rt_stats_file='datalog_rt_stats.default.yaml'
else:
RAN.datalog_rt_stats_file=datalog_rt_stats_file
RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args')
eNB_instance=test.findtext('eNB_instance')
USRPIPAddress=test.findtext('USRP_IPAddress')
if USRPIPAddress is None:
RAN.USRPIPAddress=''
else:
RAN.USRPIPAddress=USRPIPAddress
if (eNB_instance is None):
RAN.eNB_instance=0
else:
RAN.eNB_instance=int(eNB_instance)
eNB_serverId=test.findtext('eNB_serverId')
if (eNB_serverId is None):
RAN.eNB_serverId[RAN.eNB_instance]='0'
else:
RAN.eNB_serverId[RAN.eNB_instance]=eNB_serverId
USRPIPAddress = test.findtext('USRP_IPAddress') or ''
#local variable air_interface
air_interface = test.findtext('air_interface')
if (air_interface is None) or (air_interface.lower() not in ['nr','lte']):
RAN.air_interface[RAN.eNB_instance] = 'lte-softmodem'
RAN.air_interface = 'lte-softmodem'
else:
RAN.air_interface[RAN.eNB_instance] = air_interface.lower() +'-softmodem'
RAN.air_interface = air_interface.lower() +'-softmodem'
cmd_prefix = test.findtext('cmd_prefix')
if cmd_prefix is not None: RAN.cmd_prefix = cmd_prefix
success = RAN.InitializeeNB(HTML)
success = RAN.InitializeeNB(ctx, node, HTML)
elif action == 'Terminate_eNB':
eNB_instance=test.findtext('eNB_instance')
if (eNB_instance is None):
RAN.eNB_instance=0
else:
RAN.eNB_instance=int(eNB_instance)
eNB_serverId=test.findtext('eNB_serverId')
if (eNB_serverId is None):
RAN.eNB_serverId[RAN.eNB_instance]='0'
else:
RAN.eNB_serverId[RAN.eNB_instance]=eNB_serverId
node = test.findtext('node')
#retx checkers
string_field=test.findtext('d_retx_th')
string_field = test.findtext('d_retx_th')
if (string_field is not None):
RAN.ran_checkers['d_retx_th'] = [float(x) for x in string_field.split(',')]
string_field=test.findtext('u_retx_th')
@@ -203,10 +151,10 @@ def ExecuteActionWithParam(action, ctx):
#local variable air_interface
air_interface = test.findtext('air_interface')
if (air_interface is None) or (air_interface.lower() not in ['nr','lte']):
RAN.air_interface[RAN.eNB_instance] = 'lte-softmodem'
RAN.air_interface = 'lte-softmodem'
else:
RAN.air_interface[RAN.eNB_instance] = air_interface.lower() +'-softmodem'
success = RAN.TerminateeNB(ctx, HTML)
RAN.air_interface = air_interface.lower() +'-softmodem'
success = RAN.TerminateeNB(ctx, node, HTML)
elif action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Terminate_UE' or action == 'CheckStatusUE' or action == 'DataEnable_UE' or action == 'DataDisable_UE':
CiTestObj.ue_ids = test.findtext('id').split(' ')
@@ -296,8 +244,8 @@ def ExecuteActionWithParam(action, ctx):
elif action == 'Deploy_Run_PhySim':
oc_release = test.findtext('oc_release')
svr_id = test.findtext('svr_id') or None
success = CLUSTER.deploy_oc_physim(ctx, HTML, oc_release, svr_id)
node = test.findtext('node') or None
success = CLUSTER.deploy_oc_physim(ctx, HTML, oc_release, node)
elif action == 'DeployCoreNetwork' or action == 'UndeployCoreNetwork':
cn_id = test.findtext('cn_id')
@@ -305,62 +253,52 @@ def ExecuteActionWithParam(action, ctx):
success = core_op(cn_id, ctx, HTML)
elif action == 'Deploy_Object' or action == 'Undeploy_Object' or action == "Create_Workspace":
eNB_instance=test.findtext('eNB_instance')
if (eNB_instance is None):
CONTAINERS.eNB_instance=0
else:
CONTAINERS.eNB_instance=int(eNB_instance)
eNB_serverId=test.findtext('eNB_serverId')
if (eNB_serverId is None):
CONTAINERS.eNB_serverId[CONTAINERS.eNB_instance]='0'
else:
CONTAINERS.eNB_serverId[CONTAINERS.eNB_instance]=eNB_serverId
string_field = test.findtext('yaml_path')
if (string_field is not None):
CONTAINERS.yamlPath[CONTAINERS.eNB_instance] = string_field
node = test.findtext('node')
CONTAINERS.yamlPath = test.findtext('yaml_path')
string_field=test.findtext('d_retx_th')
if (string_field is not None):
CONTAINERS.ran_checkers['d_retx_th'] = [float(x) for x in string_field.split(',')]
string_field=test.findtext('u_retx_th')
if (string_field is not None):
CONTAINERS.ran_checkers['u_retx_th'] = [float(x) for x in string_field.split(',')]
string_field = test.findtext('services')
if string_field is not None:
CONTAINERS.services[CONTAINERS.eNB_instance] = string_field
CONTAINERS.services = test.findtext('services')
CONTAINERS.num_attempts = int(test.findtext('num_attempts') or 1)
CONTAINERS.deploymentTag = cls_containerize.CreateTag(CONTAINERS.ranCommitID, CONTAINERS.ranBranch, CONTAINERS.ranAllowMerge)
if action == 'Deploy_Object':
success = CONTAINERS.DeployObject(ctx, HTML)
success = CONTAINERS.DeployObject(ctx, node, HTML)
elif action == 'Undeploy_Object':
success = CONTAINERS.UndeployObject(ctx, HTML, RAN)
success = CONTAINERS.UndeployObject(ctx, node, HTML, RAN)
elif action == 'Create_Workspace':
if force_local:
# Do not create a working directory when running locally. Current repo directory will be used
return True
success = CONTAINERS.Create_Workspace(HTML)
success = CONTAINERS.Create_Workspace(node, HTML)
elif action == 'Run_Physim':
physim_options = test.findtext('physim_run_args')
physim_test = test.findtext('physim_test')
physim_threshold = test.findtext('physim_time_threshold') or 'inf'
success = cls_native.Native.Run_Physim(ctx, HTML, RAN.eNBIPAddress, RAN.eNBSourceCodePath, physim_options, physim_test, physim_threshold)
node = test.findtext('node')
success = cls_native.Native.Run_Physim(ctx, HTML, node, RAN.eNBSourceCodePath, physim_options, physim_test, physim_threshold)
elif action == 'LicenceAndFormattingCheck':
success = SCA.LicenceAndFormattingCheck(ctx, HTML)
node = test.findtext('node')
success = SCA.LicenceAndFormattingCheck(ctx, node, HTML)
elif action == 'Cppcheck_Analysis':
success = SCA.CppCheckAnalysis(ctx, HTML)
node = test.findtext('node')
success = SCA.CppCheckAnalysis(ctx, node, HTML)
elif action == 'Push_Local_Registry':
svr_id = test.findtext('svr_id')
node = test.findtext('node')
tag_prefix = test.findtext('tag_prefix') or ""
success = CONTAINERS.Push_Image_to_Local_Registry(HTML, svr_id, tag_prefix)
success = CONTAINERS.Push_Image_to_Local_Registry(node, HTML, tag_prefix)
elif action == 'Pull_Local_Registry' or action == 'Clean_Test_Server_Images':
if force_local:
# Do not pull or remove images when running locally. User is supposed to handle image creation & cleanup
return True
svr_id = test.findtext('svr_id')
node = test.findtext('node')
tag_prefix = test.findtext('tag_prefix') or ""
images = test.findtext('images').split()
# hack: for FlexRIC, we need to overwrite the tag to use
@@ -368,9 +306,9 @@ def ExecuteActionWithParam(action, ctx):
if len(images) == 1 and images[0] == "oai-flexric":
tag = CONTAINERS.flexricTag
if action == "Pull_Local_Registry":
success = CONTAINERS.Pull_Image_from_Registry(HTML, svr_id, images, tag=tag, tag_prefix=tag_prefix)
success = CONTAINERS.Pull_Image_from_Registry(HTML, node, images, tag=tag, tag_prefix=tag_prefix)
if action == "Clean_Test_Server_Images":
success = CONTAINERS.Clean_Test_Server_Images(HTML, svr_id, images, tag=tag)
success = CONTAINERS.Clean_Test_Server_Images(HTML, node, images, tag=tag)
elif action == 'Custom_Command':
node = test.findtext('node')
@@ -479,7 +417,7 @@ elif re.match('^TerminateSPGW$', mode, re.IGNORECASE):
elif re.match('^LogCollectBuild$', mode, re.IGNORECASE):
logging.warning("Option LogCollectBuild ignored")
elif re.match('^LogCollecteNB$', mode, re.IGNORECASE):
if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '':
if RAN.eNBSourceCodePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
if os.path.isdir('cmake_targets/log'):
@@ -491,7 +429,6 @@ elif re.match('^LogCollecteNB$', mode, re.IGNORECASE):
logging.error("Command '{}' returned non-zero exit status {}.".format(e.cmd, e.returncode))
logging.error("Error output:\n{}".format(e.output))
sys.exit(0)
RAN.LogCollecteNB()
elif re.match('^LogCollectHSS$', mode, re.IGNORECASE):
logging.warning("Option LogCollectHSS ignored")
elif re.match('^LogCollectMME$', mode, re.IGNORECASE):
@@ -536,12 +473,12 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
logging.info('\u001B[1m Starting Scenario: ' + CiTestObj.testXMLfiles[0] + '\u001B[0m')
logging.info('\u001B[1m----------------------------------------\u001B[0m')
if re.match('^TesteNB$', mode, re.IGNORECASE):
if RAN.eNBIPAddress == '' or RAN.ranRepository == '' or RAN.ranBranch == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '':
if RAN.ranRepository == '' or RAN.ranBranch == '' or RAN.eNBSourceCodePath == '':
HELP.GenericHelp(CONST.Version)
if RAN.ranRepository == '':
HELP.GitSrvHelp(RAN.ranRepository, RAN.ranBranch, RAN.ranCommitID, RAN.ranAllowMerge, RAN.ranTargetBranch)
if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '':
HELP.eNBSrvHelp(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath)
if RAN.eNBSourceCodePath == '':
HELP.eNBSrvHelp(RAN.eNBSourceCodePath)
sys.exit('Insufficient Parameter')
else:
if CiTestObj.ranRepository == '' or CiTestObj.ranBranch == '':

View File

@@ -43,7 +43,7 @@ import cls_cmd
#-----------------------------------------------------------
# OAI Testing modules
#-----------------------------------------------------------
import sshconnection as SSH
import cls_cmd
import helpreadme as HELP
import constants as CONST
from cls_ci_helper import archiveArtifact
@@ -60,33 +60,14 @@ class RANManagement():
self.ranAllowMerge = False
self.ranCommitID = ''
self.ranTargetBranch = ''
self.eNBIPAddress = ''
self.eNBUserName = ''
self.eNBPassword = ''
self.eNBSourceCodePath = ''
self.eNB1IPAddress = ''
self.eNB1UserName = ''
self.eNB1Password = ''
self.eNB1SourceCodePath = ''
self.eNB2IPAddress = ''
self.eNB2UserName = ''
self.eNB2Password = ''
self.eNB2SourceCodePath = ''
self.Build_eNB_args = ''
self.backgroundBuild = False
self.backgroundBuildTestId = ['', '', '']
self.Build_eNB_forced_workspace_cleanup = False
self.Initialize_eNB_args = ''
self.imageKind = ''
self.air_interface = ['', '', ''] #changed from 'lte' to '' may lead to side effects in main
self.eNB_instance = 0
self.eNB_serverId = ['', '', '']
self.eNBLogFiles = ['', '', '']
self.air_interface = ''
self.eNBOptions = ['', '', '']
self.eNBmbmsEnables = [False, False, False]
self.eNBstatuses = [-1, -1, -1]
self.testCase_id = ''
self.epcPcapFile = ''
self.runtime_stats= ''
self.datalog_rt_stats={}
self.datalog_rt_stats_file='datalog_rt_stats.default.yaml'
@@ -102,286 +83,98 @@ class RANManagement():
# RAN management functions
#-----------------------------------------------------------
def InitializeeNB(self, HTML):
if self.eNB_serverId[self.eNB_instance] == '0':
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
lPassWord = self.eNBPassword
lSourcePath = self.eNBSourceCodePath
elif self.eNB_serverId[self.eNB_instance] == '1':
lIpAddr = self.eNB1IPAddress
lUserName = self.eNB1UserName
lPassWord = self.eNB1Password
lSourcePath = self.eNB1SourceCodePath
elif self.eNB_serverId[self.eNB_instance] == '2':
lIpAddr = self.eNB2IPAddress
lUserName = self.eNB2UserName
lPassWord = self.eNB2Password
lSourcePath = self.eNB2SourceCodePath
if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
logging.debug('Starting eNB/gNB on server: ' + lIpAddr)
def InitializeeNB(self, ctx, node, HTML):
if not node:
raise ValueError(f"{node=}")
logging.debug('Starting eNB/gNB on server: ' + node)
self.testCase_id = HTML.testCase_id
mySSH = SSH.SSHConnection()
lSourcePath = self.eNBSourceCodePath
cmd = cls_cmd.getConnection(node)
mySSH.open(lIpAddr, lUserName, lPassWord)
mySSH.command('cd ' + lSourcePath, '\$', 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:]
# if tracer options is on, compiling and running T Tracer
result = re.search('T_stdout', str(extra_options))
if result is not None:
logging.debug('\u001B[1m Compiling and launching T Tracer\u001B[0m')
mySSH.command('cd common/utils/T/tracer', '\$', 5)
mySSH.command('make', '\$', 10)
mySSH.command('echo $USER; nohup ./record -d ../T_messages.txt -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '_record.log 2>&1 &', lUserName, 5)
mySSH.command('cd ' + lSourcePath, '\$', 5)
full_config_file = full_config_file[:extIdx + 5]
config_path, config_file = os.path.split(full_config_file)
else:
sys.exit('Insufficient Parameter')
ci_full_config_file = config_path + '/ci-' + config_file
rruCheck = False
result = re.search('^rru|^rcc|^du.band', str(config_file))
if result is not None:
rruCheck = True
mySSH.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5)
mySSH.command('sed -i -e \'s/CI_ENB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2);
mySSH.command('sed -i -e \'s/CI_GNB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2);
mySSH.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
mySSH.command('sed -i -e \'s/CI_RRU1_IP_ADDR/' + self.eNB1IPAddress + '/\' ' + ci_full_config_file, '\$', 2);
mySSH.command('sed -i -e \'s/CI_RRU2_IP_ADDR/' + self.eNB2IPAddress + '/\' ' + ci_full_config_file, '\$', 2);
mySSH.command('sed -i -e \'s/CI_FR1_CTL_ENB_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2);
self.eNBmbmsEnables[int(self.eNB_instance)] = False
mySSH.command('grep --colour=never enable_enb_m2 ' + ci_full_config_file, '\$', 2);
result = re.search('yes', mySSH.getBefore())
if result is not None:
self.eNBmbmsEnables[int(self.eNB_instance)] = True
logging.debug('\u001B[1m MBMS is enabled on this eNB\u001B[0m')
result = re.search('noS1', str(self.Initialize_eNB_args))
eNBinNoS1 = False
if result is not None:
eNBinNoS1 = True
logging.debug('\u001B[1m eNB is in noS1 configuration \u001B[0m')
# Launch eNB with the modified config file
mySSH.command('source oaienv', '\$', 5)
mySSH.command('cd cmake_targets', '\$', 5)
if self.air_interface[self.eNB_instance] == 'nr-softmodem':
mySSH.command('if [ -e rbconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm rbconfig.raw; fi', '\$', 5)
mySSH.command('if [ -e reconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm reconfig.raw; fi', '\$', 5)
# NOTE: WE SHALL do a check if the executable is present (in case build went wrong)
if (extIdx <= 0):
raise ValueError(f"no config file in {self.Initialize_eNB_args}")
extra_options = full_config_file[extIdx + 5:]
full_config_file = full_config_file[:extIdx + 5]
config_path, config_file = os.path.split(full_config_file)
#hack UHD_RFNOC_DIR variable for gNB / N310 on RHEL8 server:
#if the USRP address is in the xml then we are using an eth USRP (N3xx)
if self.air_interface[self.eNB_instance] == 'lte-softmodem':
gNB = False
else:
gNB = True
mySSH.command(f'echo "ulimit -c unlimited && {self.cmd_prefix} ./ran_build/build/{self.air_interface[self.eNB_instance]} -O {lSourcePath}/{ci_full_config_file} {extra_options}" > ./my-lte-softmodem-run{self.eNB_instance}.sh', '\$', 5)
logfile = f'{lSourcePath}/cmake_targets/enb.log'
cmd.cd(f"{lSourcePath}/cmake_targets/") # important: set wd so nrL1_stats.log etc are logged here
cmd.run(f'sudo -E stdbuf -o0 {self.cmd_prefix} {lSourcePath}/cmake_targets/ran_build/build/{self.air_interface} -O {lSourcePath}/{full_config_file} {extra_options} > {logfile} 2>&1 &')
mySSH.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5)
mySSH.command('echo $USER; nohup sudo -E stdbuf -o0 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log 2>&1 &', lUserName, 10)
self.eNBLogFiles[int(self.eNB_instance)] = 'enb_' + self.testCase_id + '.log'
if extra_options != '':
self.eNBOptions[int(self.eNB_instance)] = extra_options
time.sleep(6)
doLoop = True
loopCounter = 20
self.eNBOptions = extra_options
enbDidSync = False
while (doLoop):
loopCounter = loopCounter - 1
if (loopCounter == 0):
# In case of T tracer recording, we may need to kill it
result = re.search('T_stdout', str(self.Initialize_eNB_args))
if result is not None:
mySSH.command('killall --signal SIGKILL record', '\$', 5)
mySSH.close()
doLoop = False
logging.error('\u001B[1;37;41m eNB/gNB logging system did not show got sync! \u001B[0m')
HTML.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'KO', CONST.ALL_PROCESSES_OK)
return False
else:
mySSH.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | grep -E --text --color=never -i "wait|sync|Starting|Started"', '\$', 4)
if rruCheck:
result = re.search('wait RUs', mySSH.getBefore())
else:
result = re.search('got sync|Starting F1AP at CU', mySSH.getBefore())
if result is None:
time.sleep(6)
else:
doLoop = False
enbDidSync = True
time.sleep(10)
rruCheck = False
result = re.search('^rru|^du.band', str(config_file))
if result is not None:
rruCheck = True
if enbDidSync and eNBinNoS1 and not rruCheck:
mySSH.command('ifconfig oaitun_enb1', '\$', 4)
mySSH.command('ifconfig oaitun_enb1', '\$', 4)
result = re.search('inet addr:1|inet 1', mySSH.getBefore())
for _ in range(10):
time.sleep(5)
ret = cmd.run(f'grep --text -E --color=never -i "wait|sync|Starting|Started" {logfile}', reportNonZero=False)
result = re.search('got sync|Starting F1AP at CU', ret.stdout)
if result is not None:
logging.debug('\u001B[1m oaitun_enb1 interface is mounted and configured\u001B[0m')
else:
logging.error('\u001B[1m oaitun_enb1 interface is either NOT mounted or NOT configured\u001B[0m')
if self.eNBmbmsEnables[int(self.eNB_instance)]:
mySSH.command('ifconfig oaitun_enm1', '\$', 4)
result = re.search('inet addr', mySSH.getBefore())
if result is not None:
logging.debug('\u001B[1m oaitun_enm1 interface is mounted and configured\u001B[0m')
else:
logging.error('\u001B[1m oaitun_enm1 interface is either NOT mounted or NOT configured\u001B[0m')
enbDidSync = True
break
if not enbDidSync:
cmd.run(f'sudo killall -9 {self.air_interface}') # in case it did not stop automatically
archiveArtifact(cmd, ctx, logfile)
cmd.close()
msg = f'{self.cmd_prefix} {self.air_interface} -O {config_file} {extra_options}'
if enbDidSync:
self.eNBstatuses[int(self.eNB_instance)] = int(self.eNB_serverId[self.eNB_instance])
logging.debug('\u001B[1m Initialize eNB/gNB Completed\u001B[0m')
HTML.CreateHtmlTestRowQueue(msg, 'OK', [])
else:
logging.error('\u001B[1;37;41m eNB/gNB logging system did not show got sync! \u001B[0m')
HTML.CreateHtmlTestRowQueue(msg, 'KO', [])
mySSH.close()
HTML.CreateHtmlTestRow(f'{self.cmd_prefix} {self.air_interface[self.eNB_instance]} -O {config_file} {extra_options}', 'OK', CONST.ALL_PROCESSES_OK)
logging.debug('\u001B[1m Initialize eNB/gNB Completed\u001B[0m')
return enbDidSync
def TerminateeNB(self, ctx, HTML):
if self.eNB_serverId[self.eNB_instance] == '0':
lIpAddr = self.eNBIPAddress
lUserName = self.eNBUserName
lPassWord = self.eNBPassword
lSourcePath = self.eNBSourceCodePath
elif self.eNB_serverId[self.eNB_instance] == '1':
lIpAddr = self.eNB1IPAddress
lUserName = self.eNB1UserName
lPassWord = self.eNB1Password
lSourcePath = self.eNB1SourceCodePath
elif self.eNB_serverId[self.eNB_instance] == '2':
lIpAddr = self.eNB2IPAddress
lUserName = self.eNB2UserName
lPassWord = self.eNB2Password
lSourcePath = self.eNB2SourceCodePath
if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
logging.debug('Stopping eNB/gNB on server: ' + lIpAddr)
mySSH = SSH.SSHConnection()
mySSH.open(lIpAddr, lUserName, lPassWord)
mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5)
if self.air_interface[self.eNB_instance] == 'lte-softmodem':
nodeB_prefix = 'e'
else:
nodeB_prefix = 'g'
mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem | grep -v grep', '\$', 5)
result = re.search('-softmodem', mySSH.getBefore())
def TerminateeNB(self, ctx, node, HTML):
logging.debug('Stopping eNB/gNB on server: ' + node)
lSourcePath = self.eNBSourceCodePath
cmd = cls_cmd.getConnection(node)
ret = cmd.run('ps -aux | grep --color=never -e softmodem | grep -v grep')
result = re.search('-softmodem', ret.stdout)
if result is not None:
mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem || true', '\$', 5)
time.sleep(10)
mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem | grep -v grep', '\$', 5)
result = re.search('-softmodem', mySSH.getBefore())
if result is not None:
mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem || true', '\$', 5)
time.sleep(5)
mySSH.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5)
#stopping tshark (valid if eNB and enabled in xml, will not harm otherwise)
logging.debug('\u001B[1m Stopping tshark on xNB \u001B[0m')
mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5)
time.sleep(1)
mySSH.close()
# if T tracer was run with option 0 (no logs), analyze logs
# from textlog, otherwise do normal analysis (e.g., option 2)
result = re.search('T_stdout 0', str(self.Initialize_eNB_args))
if (result is not None):
logging.debug('\u001B[1m Replaying RAW record file\u001B[0m')
mySSH.open(lIpAddr, lUserName, lPassWord)
mySSH.command('cd ' + lSourcePath + '/common/utils/T/tracer/', '\$', 5)
enbLogFile = self.eNBLogFiles[int(self.eNB_instance)]
raw_record_file = enbLogFile.replace('.log', '_record.raw')
replay_log_file = enbLogFile.replace('.log', '_replay.log')
extracted_txt_file = enbLogFile.replace('.log', '_extracted_messages.txt')
extracted_log_file = enbLogFile.replace('.log', '_extracted_messages.log')
mySSH.command('./extract_config -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + extracted_txt_file, '\$', 5)
mySSH.command('echo $USER; nohup ./replay -i ' + lSourcePath + '/cmake_targets/' + raw_record_file + ' > ' + lSourcePath + '/cmake_targets/' + replay_log_file + ' 2>&1 &', lUserName, 5)
mySSH.command('./textlog -d ' + lSourcePath + '/cmake_targets/' + extracted_txt_file + ' -no-gui -ON -full > ' + lSourcePath + '/cmake_targets/' + extracted_log_file, '\$', 5)
mySSH.close()
mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/' + extracted_log_file, '.')
logging.debug('\u001B[1m Analyzing eNB replay logfile \u001B[0m')
logStatus = self.AnalyzeLogFile_eNB(extracted_log_file, HTML, self.ran_checkers)
cmd.run('sudo -S killall --signal SIGINT -r .*-softmodem')
time.sleep(6)
ret = cmd.run('ps -aux | grep --color=never -e softmodem | grep -v grep')
result = re.search('-softmodem', ret.stdout)
if result is not None:
cmd.run('sudo -S killall --signal SIGKILL -r .*-softmodem')
time.sleep(5)
# see InitializeeNB()
logfile = f'{lSourcePath}/cmake_targets/enb.log'
logdir = os.path.dirname(logfile)
file = archiveArtifact(cmd, ctx, logfile)
archiveArtifact(cmd, ctx, f"{logdir}/nrL1_stats.log")
archiveArtifact(cmd, ctx, f"{logdir}/nrMAC_stats.log")
cmd.close()
if file is None:
logging.debug('\u001B[1;37;41m Could not copy xNB logfile to analyze it! \u001B[0m')
msg = 'Could not copy xNB logfile to analyze it!'
HTML.CreateHtmlTestRowQueue('N/A', 'KO', [msg])
return False
logging.debug('\u001B[1m Analyzing xNB logfile \u001B[0m ' + file)
logStatus = self.AnalyzeLogFile_eNB(file, HTML, self.ran_checkers)
if logStatus < 0:
HTML.CreateHtmlTestRow('N/A', 'KO', logStatus)
else:
HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
self.eNBLogFiles[int(self.eNB_instance)] = ''
return True
else:
analyzeFile = False
if self.eNBLogFiles[int(self.eNB_instance)] != '':
analyzeFile = True
fileToAnalyze = self.eNBLogFiles[int(self.eNB_instance)]
self.eNBLogFiles[int(self.eNB_instance)] = ''
if analyzeFile:
with cls_cmd.getConnection(lIpAddr) as cmd:
file = archiveArtifact(cmd, ctx, lSourcePath + '/cmake_targets/' + fileToAnalyze)
archiveArtifact(cmd, ctx, lSourcePath + '/cmake_targets/nrL1_stats.log')
archiveArtifact(cmd, ctx, lSourcePath + '/cmake_targets/nrMAC_stats.log')
if file is None:
logging.debug('\u001B[1;37;41m Could not copy ' + nodeB_prefix + 'NB logfile to analyze it! \u001B[0m')
HTML.htmleNBFailureMsg='Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!'
HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE)
self.eNBmbmsEnables[int(self.eNB_instance)] = False
return False
if self.eNB_serverId[self.eNB_instance] != '0':
#*stats.log files + pickle + png
#debug / tentative
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './nrL1_stats.log', self.eNBSourceCodePath + '/cmake_targets/')
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './nrMAC_stats.log', self.eNBSourceCodePath + '/cmake_targets/')
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/')
logging.debug('\u001B[1m Analyzing ' + nodeB_prefix + 'NB logfile \u001B[0m ' + file)
logStatus = self.AnalyzeLogFile_eNB(file, HTML, self.ran_checkers)
if (logStatus < 0):
HTML.CreateHtmlTestRow('N/A', 'KO', logStatus)
#display rt stats for gNB only
if len(self.datalog_rt_stats)!=0 and nodeB_prefix == 'g':
HTML.CreateHtmlDataLogTable(self.datalog_rt_stats)
self.eNBmbmsEnables[int(self.eNB_instance)] = False
return False
else:
HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
else:
HTML.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
#display rt stats for gNB only
if len(self.datalog_rt_stats)!=0 and nodeB_prefix == 'g':
if len(self.datalog_rt_stats) != 0:
HTML.CreateHtmlDataLogTable(self.datalog_rt_stats)
self.eNBmbmsEnables[int(self.eNB_instance)] = False
self.eNBstatuses[int(self.eNB_instance)] = -1
return True
def LogCollecteNB(self):
mySSH = SSH.SSHConnection()
# Copying back to xNB server any log from all the runs.
# Should also contains ping and iperf logs
absPath = os.path.abspath('.')
if absPath.count('ci-scripts') == 0:
os.chdir('./ci-scripts')
for x in os.listdir():
if x.endswith('.log') or x.endswith('.log.png'):
mySSH.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, x, self.eNBSourceCodePath + '/cmake_targets/', silent=True, ignorePermDenied=True)
# Back to normal
mySSH.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword)
mySSH.command('cd ' + self.eNBSourceCodePath, '\$', 5)
mySSH.command('cd cmake_targets', '\$', 5)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/enb_*.pcap .','\$',20)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S mv /tmp/gnb_*.pcap .','\$',20)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5)
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip *.log enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png ping*.log* iperf*.log log/*/*.log log/*/*.pcap', '\$', 60)
result = re.search('core.\d+', mySSH.getBefore())
if result is not None:
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip core* ran_build/build/{lte,nr}-softmodem', '\$', 60) # add core and executable to zip
mySSH.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap gnb_*.pcap enb_*txt physim_*.log *stats.log *monitor.pickle *monitor*.png ping*.log* iperf*.log log/*/*.log log/*/*.pcap', '\$', 15)
mySSH.close()
return logStatus >= 0
def _analyzeUeRetx(self, rounds, checkers, regex):
if len(rounds) == 0 or len(checkers) == 0:
@@ -528,16 +321,16 @@ class RANManagement():
X2HO_state = CONST.X2_HO_REQ_STATE__IDLE
X2HO_outNbProcedures += 1
if self.eNBOptions[int(self.eNB_instance)] != '':
res1 = re.search('max_rxgain (?P<requested_option>[0-9]+)', self.eNBOptions[int(self.eNB_instance)])
if self.eNBOptions[0] != '':
res1 = re.search('max_rxgain (?P<requested_option>[0-9]+)', self.eNBOptions[0])
res2 = re.search('max_rxgain (?P<applied_option>[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:
htmleNBFailureMsg += '<span class="glyphicon glyphicon-ok-circle"></span> Command line option(s) correctly applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n'
htmleNBFailureMsg += '<span class="glyphicon glyphicon-ok-circle"></span> Command line option(s) correctly applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.eNBOptions[0] + '\n\n'
else:
htmleNBFailureMsg += '<span class="glyphicon glyphicon-ban-circle"></span> Command line option(s) NOT applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.eNBOptions[int(self.eNB_instance)] + '\n\n'
htmleNBFailureMsg += '<span class="glyphicon glyphicon-ban-circle"></span> Command line option(s) NOT applied <span class="glyphicon glyphicon-arrow-right"></span> ' + self.eNBOptions[0] + '\n\n'
result = re.search('Exiting OAI softmodem|Caught SIGTERM, shutting down', str(line))
if result is not None:
exitSignalReceived = True
@@ -624,7 +417,7 @@ class RANManagement():
result = re.search('dropping, not enough RBs', str(line))
if result is not None:
dropNotEnoughRBs += 1
if self.eNBmbmsEnables[int(self.eNB_instance)]:
if self.eNBmbmsEnables[0]:
result = re.search('MBMS USER-PLANE.*Requesting.*bytes from RLC', str(line))
if result is not None:
mbmsRequestMsg += 1
@@ -700,8 +493,8 @@ class RANManagement():
# nrL1_stats.log/nrMAC_stats.log should be in the same directory as main log file
# currently the link is only implicit as below based on pattern matching
# I will rework this to give the file explicitly
l1_stats_fn = re.sub(r'enb_[0-9]+', 'nrL1_stats', eNBlogFile)
mac_stats_fn = re.sub(r'enb_[0-9]+', 'nrMAC_stats', eNBlogFile)
l1_stats_fn = re.sub(r'-enb.log$', '-nrL1_stats.log', eNBlogFile)
mac_stats_fn = re.sub(r'-enb.log$', '-nrMAC_stats.log', eNBlogFile)
if os.path.isfile(l1_stats_fn) and os.path.isfile(mac_stats_fn):
# don't use CI-nrL1_stats.log, as this will increase the processing time for
# no reason, we just need the last occurence
@@ -733,7 +526,7 @@ class RANManagement():
#post processing depending on the node type
if not nodeB_prefix_found:
if self.air_interface[self.eNB_instance] == 'lte-softmodem':
if self.air_interface == 'lte-softmodem':
nodeB_prefix = 'e'
else:
nodeB_prefix = 'g'
@@ -937,7 +730,7 @@ class RANManagement():
rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected'
logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
htmleNBFailureMsg += rrcMsg + '\n'
if self.eNBmbmsEnables[int(self.eNB_instance)]:
if self.eNBmbmsEnables[0]:
if mbmsRequestMsg > 0:
rrcMsg = 'eNB requested ' + str(mbmsRequestMsg) + ' times the RLC for MBMS USER-PLANE'
logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
@@ -950,8 +743,8 @@ class RANManagement():
rrcMsg = 'eNB completed ' + str(X2HO_outNbProcedures) + ' X2 Handover Release procedure(s)'
logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
htmleNBFailureMsg += rrcMsg + '\n'
if self.eNBOptions[int(self.eNB_instance)] != '':
res1 = re.search('drx_Config_present prSetup', self.eNBOptions[int(self.eNB_instance)])
if self.eNBOptions[0] != '':
res1 = re.search('drx_Config_present prSetup', self.eNBOptions[0])
if res1 is not None:
if cdrxActivationMessageCount > 0:
rrcMsg = 'eNB activated the CDRX Configuration for ' + str(cdrxActivationMessageCount) + ' time(s)'

View File

@@ -33,13 +33,11 @@ python3 main.py --mode=InitiateHtml --ranRepository=NONE --ranBranch=${CURRENT_B
python3 main.py --mode=TesteNB --ranRepository=NONE --ranBranch=${CURRENT_BRANCH} \
--ranCommitID=${COMMIT_SHA} --ranAllowMerge=false \
--ranTargetBranch=NONE --eNBIPAddress=NONE --eNBUserName=NONE --eNBPassword=NONE \
--ranTargetBranch=NONE \
--eNBSourceCodePath=${REPO_PATH} \
--XMLTestFile=${TESTCASE} --local
RET=$?
python3 main.py --mode=FinalizeHtml \
--local \
--eNBIPAddress=NONE --eNBUserName=NONE --eNBPassword=NONE
python3 main.py --mode=FinalizeHtml --local
exit ${RET}

View File

@@ -1,281 +0,0 @@
#/*
# * 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
# */
#---------------------------------------------------------------------
# Python for CI of OAI-eNB + COTS-UE
#
# Required Python Version
# Python 3.x
#
# Required Python Package
# pexpect
#---------------------------------------------------------------------
#-----------------------------------------------------------
# Import
#-----------------------------------------------------------
import pexpect # pexpect
import logging
import time # sleep
import re
import subprocess
import sys
#-----------------------------------------------------------
# Class Declaration
#-----------------------------------------------------------
class SSHConnection():
def __init__(self):
self.ssh = ''
self.picocom_closure = False
self.ipaddress = ''
self.username = ''
self.cmd2Results = ''
def disablePicocomClosure(self):
self.picocom_closure = False
def enablePicocomClosure(self):
self.picocom_closure = True
def open(self, ipaddress, username, password):
prompt = "\$"
count = 0
connect_status = False
while count < 4:
self.ssh = pexpect.spawn('ssh -o PubkeyAuthentication=yes {}@{}'.format(username,ipaddress))
# Longer timeout at connection due to asterix slowness
self.ssh.timeout = 25
self.sshresponse = self.ssh.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', 'Last login', pexpect.EOF, pexpect.TIMEOUT])
if self.sshresponse == 0:
self.ssh.sendline('yes')
self.sshresponse = self.ssh.expect(['password:', username + '@'])
if self.sshresponse == 0:
self.ssh.sendline(password)
self.sshresponse = self.ssh.expect([prompt, 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if self.sshresponse == 0:
count = 10
connect_status = True
else:
logging.warning('self.sshresponse = ' + str(self.sshresponse))
elif self.sshresponse == 1:
self.ssh.sendline(password)
self.sshresponse = self.ssh.expect([prompt, 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if self.sshresponse == 0:
count = 10
connect_status = True
else:
logging.warning('self.sshresponse = ' + str(self.sshresponse))
elif self.sshresponse == 2:
# We directly ended up on the remote server because of pubkey auth
count = 10
connect_status = True
# this expect() seems to be necessary to advance the read buffer until the prompt, or getBefore() will not return the last command
self.sshresponse = self.ssh.expect([prompt])
else:
# debug output
logging.warning(str(self.ssh.before))
logging.warning('self.sshresponse = ' + str(self.sshresponse))
# adding a tempo when failure
if not connect_status:
time.sleep(1)
count += 1
if connect_status:
self.command('unset HISTFILE', prompt, 5, silent=True)
else:
raise ConnectionError('SSH Connection Failed')
self.ipaddress = ipaddress
self.username = username
def cde_check_value(self, commandline, expected, timeout):
logging.info(commandline)
self.ssh.timeout = timeout
self.ssh.sendline(commandline)
expected.append(pexpect.EOF)
expected.append(pexpect.TIMEOUT)
self.sshresponse = self.ssh.expect(expected)
return self.sshresponse
def command(self, commandline, expectedline, timeout, silent=False, resync=False):
if not silent:
logging.info(commandline)
self.ssh.timeout = timeout
# Nasty patch when pexpect output is out of sync.
# Much pronounced when running back-to-back-back oc commands
if resync:
self.ssh.send(commandline)
self.ssh.expect([commandline, pexpect.TIMEOUT])
self.ssh.send('\r\n')
self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT])
else:
self.ssh.sendline(commandline)
self.sshresponse = self.ssh.expect([expectedline, pexpect.EOF, pexpect.TIMEOUT])
if self.sshresponse == 0:
return 0
elif self.sshresponse == 1:
logging.error('\u001B[1;37;41m Unexpected EOF \u001B[0m')
logging.error('Expected Line : ' + expectedline)
logging.error(str(self.ssh.before))
raise ConnectionError(self.sshresponse)
elif self.sshresponse == 2:
logging.error('\u001B[1;37;41m Unexpected TIMEOUT \u001B[0m')
logging.error('Expected Line : ' + expectedline)
result = re.search('ping |iperf |picocom', str(commandline))
if result is None:
logging.warning(str(self.ssh.before))
raise ConnectionError(self.sshresponse)
else:
return -1
else:
logging.error('\u001B[1;37;41m Unexpected Others \u001B[0m')
logging.error('Expected Line : ' + expectedline)
raise ConnectionError(self.sshresponse)
def command2(self, commandline, timeout, silent=False):
if not silent:
logging.info(commandline)
self.cmd2Results = ''
noHistoryCmd = 'unset HISTFILE; ' + commandline
myHost = self.username + '@' + self.ipaddress
# CAUTION: THIS METHOD IMPLIES THAT THERE ARE VALID SSH KEYS
# BETWEEN THE PYTHON EXECUTOR NODE AND THE REMOTE HOST
# OTHERWISE IT WON'T WORK
lSsh = subprocess.Popen(["ssh", "%s" % myHost, noHistoryCmd],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
self.cmd2Results = str(lSsh.stdout.readlines())
def command3(self, commandline, timeout, silent=False):
if not silent:
logging.info(commandline)
self.cmd2Results = ''
noHistoryCmd = 'unset HISTFILE; ' + commandline
myHost = self.username + '@' + self.ipaddress
# CAUTION: THIS METHOD IMPLIES THAT THERE ARE VALID SSH KEYS
# BETWEEN THE PYTHON EXECUTOR NODE AND THE REMOTE HOST
# OTHERWISE IT WON'T WORK
lSsh = subprocess.Popen(["ssh", "%s" % myHost, noHistoryCmd],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
return lSsh.stdout.readlines()
def close(self):
self.ssh.timeout = 5
self.ssh.sendline('exit')
self.sshresponse = self.ssh.expect([pexpect.EOF, pexpect.TIMEOUT])
self.ipaddress = ''
self.username = ''
if self.sshresponse == 0:
pass
elif self.sshresponse == 1:
if not self.picocom_closure:
logging.warning('\u001B[1;37;41m Unexpected TIMEOUT during closing\u001B[0m')
else:
logging.warning('\u001B[1;37;41m Unexpected Others during closing\u001B[0m')
def copyin(self, ipaddress, username, password, source, destination):
count = 0
copy_status = False
logging.info('scp -r '+ username + '@' + ipaddress + ':' + source + ' ' + destination)
while count < 10:
scp_spawn = pexpect.spawn('scp -r '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 100)
scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0:
scp_spawn.sendline('yes')
scp_spawn.expect('password:')
scp_spawn.sendline(password)
scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0:
count = 10
copy_status = True
else:
logging.warning('1 - scp_response = ' + str(scp_response))
elif scp_response == 1:
scp_spawn.sendline(password)
scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0 or scp_response == 3:
count = 10
copy_status = True
else:
logging.warning('2 - scp_response = ' + str(scp_response))
elif scp_response == 2:
count = 10
copy_status = True
else:
logging.warning('3 - scp_response = ' + str(scp_response))
# adding a tempo when failure
if not copy_status:
time.sleep(1)
count += 1
if copy_status:
return 0
else:
return -1
def copyout(self, ipaddress, username, password, source, destination, silent=False, ignorePermDenied=False):
count = 0
copy_status = False
if not silent:
logging.info('scp -r ' + source + ' ' + username + '@' + ipaddress + ':' + destination)
while count < 4:
scp_spawn = pexpect.spawn('scp -r ' + source + ' ' + username + '@' + ipaddress + ':' + destination, timeout = 100)
scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0:
scp_spawn.sendline('yes')
scp_spawn.expect('password:')
scp_spawn.sendline(password)
scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0:
count = 10
copy_status = True
elif scp_response == 1 and ignorePermDenied:
logging.warning(f'copyout(): permission denied, not copying file ({source})')
count = 10
copy_status = True
else:
logging.warning('1 - scp_response = ' + str(scp_response))
elif scp_response == 1:
scp_spawn.sendline(password)
scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT])
if scp_response == 0 or scp_response == 3:
count = 10
copy_status = True
elif scp_response == 1 and ignorePermDenied:
logging.warning(f'copyout(): permission denied, not copying file ({source})')
count = 10
copy_status = True
else:
logging.warning('2 - scp_response = ' + str(scp_response))
elif scp_response == 2:
count = 10
copy_status = True
else:
logging.warning('3 - scp_response = ' + str(scp_response))
# adding a tempo when failure
if not copy_status:
time.sleep(1)
count += 1
if copy_status:
pass
else:
raise ConnectionError('SCP failed')
def getBefore(self):
return self.ssh.before.decode('utf-8')

View File

@@ -11,6 +11,7 @@ import tempfile
sys.path.append('./') # to find OAI imports below
import cls_oai_html
import cls_containerize
from cls_ci_helper import TestCaseCtx
import cls_cmd
class TestBuild(unittest.TestCase):
@@ -18,22 +19,21 @@ class TestBuild(unittest.TestCase):
self.html = cls_oai_html.HTMLManagement()
self.html.testCase_id = "000000"
self.cont = cls_containerize.Containerize()
self.cont.eNB_serverId[0] = '0'
self.cont.eNBIPAddress = 'localhost'
self.cont.eNBUserName = None
self.cont.eNBPassword = None
self._d = tempfile.mkdtemp()
logging.warning(f"temporary directory: {self._d}")
self.node = 'localhost'
self.cont.eNBSourceCodePath = self._d
self.ctx = TestCaseCtx.Default(tempfile.mkdtemp())
def tearDown(self):
logging.warning(f"removing directory contents")
with cls_cmd.getConnection(None) as cmd:
cmd.run(f"rm -rf {self._d}")
cmd.run(f'rm -rf {self.ctx.logPath}')
def test_build_proxy(self):
self.cont.proxyCommit = "b64d9bce986b38ca59e8582864ade3fcdd05c0dc"
success = self.cont.BuildProxy(self.html)
success = self.cont.BuildProxy(self.ctx, self.node, self.html)
self.assertTrue(success)
if __name__ == '__main__':

View File

@@ -40,76 +40,83 @@ class TestDeploymentMethods(unittest.TestCase):
self.ci = cls_oaicitest.OaiCiTest()
self.cont = cls_containerize.Containerize()
self.ran = ran.RANManagement()
self.cont.yamlPath[0] = ''
self.cont.yamlPath = ''
self.cont.ranAllowMerge = True
self.cont.ranBranch = ''
self.cont.ranCommitID = ''
self.cont.eNB_serverId[0] = '0'
self.cont.eNBIPAddress = 'localhost'
self.cont.eNBUserName = None
self.cont.eNBPassword = None
self.cont.eNBSourceCodePath = os.getcwd()
self.cont.num_attempts = 3
self.node = 'localhost'
self.ctx = TestCaseCtx.Default(tempfile.mkdtemp())
def tearDown(self):
with cls_cmd.LocalCmd() as c:
c.run(f'rm -rf {self.ctx.logPath}')
def test_deploy(self):
self.cont.yamlPath[0] = 'tests/simple-dep/'
self.cont.yamlPath = 'tests/simple-dep/'
self.cont.deploymentTag = "noble"
deploy = self.cont.DeployObject(self.ctx, self.html)
undeploy = self.cont.UndeployObject(self.ctx, self.html, self.ran)
deploy = self.cont.DeployObject(self.ctx, self.node, self.html)
undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran)
self.assertTrue(deploy)
self.assertTrue(undeploy)
def test_deployfails(self):
# fails reliably
old = self.cont.yamlPath
self.cont.yamlPath[0] = 'tests/simple-fail/'
deploy = self.cont.DeployObject(self.ctx, self.html)
self.cont.UndeployObject(self.ctx, self.html, self.ran)
self.cont.yamlPath = 'tests/simple-fail/'
deploy = self.cont.DeployObject(self.ctx, self.node, self.html)
self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran)
self.assertFalse(deploy)
self.cont.yamlPath = old
def test_deployfails_2svc(self):
# fails reliably
old = self.cont.yamlPath
self.cont.yamlPath[0] = 'tests/simple-fail-2svc/'
deploy = self.cont.DeployObject(self.ctx, self.html)
self.cont.UndeployObject(self.ctx, self.html, self.ran)
self.cont.yamlPath = 'tests/simple-fail-2svc/'
deploy = self.cont.DeployObject(self.ctx, self.node, self.html)
self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran)
self.assertFalse(deploy)
self.cont.yamlPath = old
def test_deploy_ran(self):
self.cont.yamlPath[0] = 'yaml_files/5g_rfsimulator_tdd_dora'
self.cont.services[0] = "oai-gnb"
self.cont.yamlPath = 'yaml_files/5g_rfsimulator_tdd_dora'
self.cont.services = "oai-gnb"
self.cont.deploymentTag = 'develop-12345678'
deploy = self.cont.DeployObject(self.ctx, self.html)
undeploy = self.cont.UndeployObject(self.ctx, self.html, self.ran)
deploy = self.cont.DeployObject(self.ctx, self.node, self.html)
undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran)
self.assertTrue(deploy)
self.assertTrue(undeploy)
def test_deploy_multiran(self):
self.cont.yamlPath[0] = 'yaml_files/5g_rfsimulator_tdd_dora'
self.cont.services[0] = "oai-gnb oai-nr-ue"
self.cont.yamlPath = 'yaml_files/5g_rfsimulator_tdd_dora'
self.cont.services = "oai-gnb oai-nr-ue"
self.cont.deploymentTag = 'develop-12345678'
deploy = self.cont.DeployObject(self.ctx, self.html)
undeploy = self.cont.UndeployObject(self.ctx, self.html, self.ran)
deploy = self.cont.DeployObject(self.ctx, self.node, self.html)
undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran)
self.assertTrue(deploy)
self.assertTrue(undeploy)
def test_deploy_staged(self):
self.cont.yamlPath[0] = 'yaml_files/5g_rfsimulator_tdd_dora'
self.cont.services[0] = "oai-gnb"
self.cont.yamlPath = 'yaml_files/5g_rfsimulator_tdd_dora'
self.cont.services = "oai-gnb"
self.cont.deploymentTag = 'develop-12345678'
deploy1 = self.cont.DeployObject(self.ctx, self.html)
self.cont.services[0] = "oai-nr-ue"
deploy2 = self.cont.DeployObject(self.ctx, self.html)
undeploy = self.cont.UndeployObject(self.ctx, self.html, self.ran)
deploy1 = self.cont.DeployObject(self.ctx, self.node, self.html)
self.cont.services = "oai-nr-ue"
deploy2 = self.cont.DeployObject(self.ctx, self.node, self.html)
undeploy = self.cont.UndeployObject(self.ctx, self.node, self.html, self.ran)
self.assertTrue(deploy1)
self.assertTrue(deploy2)
self.assertTrue(undeploy)
def test_create_workspace(self):
self.cont.eNBSourceCodePath = tempfile.mkdtemp()
self.cont.ranRepository = "https://gitlab.eurecom.fr/oai/openairinterface5g.git"
self.cont.ranCommitID = "05f9c975eeecbca1bdff5940affad44465f1301f"
self.cont.ranBranch = "develop"
ws = self.cont.Create_Workspace(self.node, self.html)
with cls_cmd.LocalCmd() as cmd:
cmd.run(f"rm -rf {self.cont.eNBSourceCodePath}")
self.assertTrue(ws)
if __name__ == '__main__':
unittest.main()

View File

@@ -1,4 +1,4 @@
Sender Bitrate : 0.52 Mbps
Receiver Bitrate: 0.52 Mbps (too low! < 99%)
Sender Bitrate : 524.00 Kbps
Receiver Bitrate: 524.00 Kbps (52.40%) (too low! < 99%)
Jitter : 0.026 ms
Packet Loss : 10 % (too high! > 0%)
Packet Loss : 10% (too high! > 0%)

View File

@@ -1,4 +1,4 @@
Sender Bitrate : 0.00 Mbps
Receiver Bitrate: 3.98 Mbps (too low! < 99%)
Sender Bitrate : 0.00 bps
Receiver Bitrate: 3.98 Mbps (4.97%) (too low! < 99%)
Jitter : 3.847 ms
Packet Loss : 0.038 % (too high! > 0%)
Packet Loss : 0.038% (too high! > 0%)

View File

@@ -1,4 +1,4 @@
Sender Bitrate : 1.03 Mbps
Receiver Bitrate: 0.00 Mbps (too low! < 99%)
Sender Bitrate : 1.03 Mbps
Receiver Bitrate: 0.00 bps (0.00%) (too low! < 99%)
Jitter : 0.000 ms
Packet Loss : 0 %
Packet Loss : 0%

View File

@@ -1,4 +1,4 @@
Sender Bitrate : 1.00 Mbps
Receiver Bitrate: 1.00 Mbps (99.60 %)
Sender Bitrate : 996.00 Kbps
Receiver Bitrate: 996.00 Kbps (99.60%)
Jitter : 0.029 ms
Packet Loss : 0 %
Packet Loss : 0%

View File

@@ -1,4 +1,4 @@
Sender Bitrate : 4.67 Mbps
Receiver Bitrate: 4.67 Mbps (100.00 %)
Sender Bitrate : 4.67 Mbps
Receiver Bitrate: 4.67 Mbps (100.00%)
Jitter : 3.413 ms
Packet Loss : 0 %
Packet Loss : 0%

View File

@@ -65,5 +65,20 @@ class TestPingIperf(unittest.TestCase):
success = self.ci.Iperf2_Unidir(self.ctx, self.html, infra_file=infra_file)
self.assertTrue(success)
def test_iperf_highrate(self):
# note: needs to be five seconds because Iperf() adds -O 3, so if it is
# too short, the server is terminated before the client loaded
# everything
self.ci.iperf_args = "-u -t 5 -b 1000M -R -O 0"
self.ci.svr_id = "test"
self.ci.svr_node = "localhost"
self.ci.iperf_packetloss_threshold = "0"
self.ci.iperf_bitrate_threshold = "0"
self.ci.iperf_profile = "balanced"
infra_file = "tests/config/infra_ping_iperf.yaml"
# TODO Should need nothing but options and UE(s) to use
success = self.ci.Iperf(self.ctx, self.html, infra_file=infra_file)
self.assertTrue(success)
if __name__ == '__main__':
unittest.main()

View File

@@ -20,7 +20,6 @@ class TestDeploymentMethods(unittest.TestCase):
self.html = cls_oai_html.HTMLManagement()
self.html.testCaseId = "000000"
self.cont = cls_containerize.Containerize()
self.cont.eNBIPAddress = 'localhost'
self.cont.eNBSourceCodePath = os.getcwd()
def test_pull_clean_local_reg(self):
@@ -32,21 +31,21 @@ class TestDeploymentMethods(unittest.TestCase):
ret = cmd.run(f"ping -c1 -w1 {registry}")
if ret.returncode != 0: # could not ping once -> skip test
self.skipTest(f"test_pull_clean_local_reg: could not reach {registry} (run inside sboai)")
svr_id = '0'
node = 'localhost'
images = ["oai-gnb"]
tag = "develop"
pull = self.cont.Pull_Image_from_Registry(self.html, svr_id, images, tag=tag)
clean = self.cont.Clean_Test_Server_Images(self.html, svr_id, images, tag=tag)
pull = self.cont.Pull_Image_from_Registry(self.html, node, images, tag=tag)
clean = self.cont.Clean_Test_Server_Images(self.html, node, images, tag=tag)
self.assertTrue(pull)
self.assertTrue(clean)
def test_pull_clean_docker_hub(self):
svr_id = '0'
node = 'localhost'
r = "docker.io"
images = ["hello-world"]
tag = "latest"
pull = self.cont.Pull_Image_from_Registry(self.html, svr_id, images, tag=tag, registry=r, username=None, password=None)
clean = self.cont.Clean_Test_Server_Images(self.html, svr_id, images, tag=tag)
pull = self.cont.Pull_Image_from_Registry(self.html, node, images, tag=tag, registry=r, username=None, password=None)
clean = self.cont.Clean_Test_Server_Images(self.html, node, images, tag=tag)
self.assertTrue(pull)
self.assertTrue(clean)

View File

@@ -22,9 +22,6 @@ python3 main.py \
--ranCommitID=${commit} \
--ranAllowMerge=true \
--ranTargetBranch=develop \
--eNBIPAddress=localhost \
--eNBUserName=NONE \
--eNBPassword=NONE \
--eNBSourceCodePath=NONE \
--XMLTestFile=tests/test-runner/test.xml

View File

@@ -32,10 +32,12 @@
<testCase id="000002">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<node>poseidon</node>
</testCase>
<testCase id="000001">
<class>Build_Cluster_Image</class>
<desc>Build Images on OpenShift Cluster</desc>
<node>poseidon</node>
</testCase>
</testCaseList>

View File

@@ -1,47 +0,0 @@
<!--
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
-->
<testCaseList>
<htmlTabRef>l2sim-4glte-proxy-build</htmlTabRef>
<htmlTabName>Build L2sim proxy image</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<TestCaseRequestedList>
100001
000001
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="100001">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
</testCase>
<testCase id="000001">
<class>Build_Proxy</class>
<desc>Build L2sim Proxy Image</desc>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
<proxy_commit>b64d9bce986b38ca59e8582864ade3fcdd05c0dc</proxy_commit>
</testCase>
</testCaseList>

View File

@@ -44,49 +44,44 @@
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<node>obelix</node>
<images>oai-enb oai-lte-ue</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
</testCase>
<testCase id="000000">
<class>Deploy_Object</class>
<desc>Deploy Cassandra Database</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_l2sim_fdd</yaml_path>
<services>cassandra db_init</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000001">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G CoreNetwork</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_l2sim_fdd</yaml_path>
<services>oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000002">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G eNB L2 sim</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_l2sim_fdd</yaml_path>
<services>oai_enb</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000003">
<class>Deploy_Object</class>
<desc>Deploy OAI L2 sim 4G LTE-UE 1 and Proxy</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_l2sim_fdd</yaml_path>
<services>proxy oai_ue1</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000004">
@@ -145,6 +140,7 @@
<testCase id="100001">
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<node>localhost</node>
<desc>Undeploy all OAI 4G stack</desc>
<yaml_path>ci-scripts/yaml_files/4g_l2sim_fdd</yaml_path>
</testCase>
@@ -153,7 +149,7 @@
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<node>obelix</node>
<images>oai-enb oai-lte-ue</images>
</testCase>

View File

@@ -46,23 +46,21 @@
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
</testCase>
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb-asan oai-lte-ue-asan</images>
</testCase>
<testCase id="000011">
<class>Deploy_Object</class>
<desc>Deploy Cassandra Database</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz</yaml_path>
<services>cassandra db_init</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000001">
@@ -80,28 +78,25 @@
<testCase id="000012">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G CoreNetwork</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz</yaml_path>
<services>oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000013">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G eNB RF sim (FDD 05MHz)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz</yaml_path>
<services>oai_enb0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000014">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G LTE-UE RF sim (FDD 05MHz)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz</yaml_path>
<services>oai_ue0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000015">
@@ -161,16 +156,15 @@
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 4G stack</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb-asan oai-lte-ue-asan</images>
</testCase>

View File

@@ -43,14 +43,13 @@
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb-asan oai-lte-ue-asan</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
@@ -67,19 +66,17 @@
<testCase id="000013">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G eNB RF sim (FDD 05MHz)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1</yaml_path>
<services>oai_enb0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000014">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G LTE-UE RF sim (FDD 05MHz)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1</yaml_path>
<services>oai_ue0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="020011">
@@ -132,16 +129,15 @@
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 4G stack</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_05MHz_noS1</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb-asan oai-lte-ue-asan</images>
</testCase>

View File

@@ -47,22 +47,20 @@
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb-asan oai-lte-ue-asan</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
</testCase>
<testCase id="000011">
<class>Deploy_Object</class>
<desc>Deploy Cassandra Database</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz</yaml_path>
<services>cassandra db_init</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000001">
@@ -80,28 +78,25 @@
<testCase id="000012">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G CoreNetwork</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz</yaml_path>
<services>oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000013">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G eNB RF sim (FDD 10MHz)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz</yaml_path>
<services>oai_enb0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000014">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G LTE-UE RF sim (FDD 10MHz)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz</yaml_path>
<services>oai_ue0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000015">
@@ -161,16 +156,15 @@
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 4G stack</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_10MHz</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb-asan oai-lte-ue-asan</images>
</testCase>

View File

@@ -47,22 +47,20 @@
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb-asan oai-lte-ue-asan</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
</testCase>
<testCase id="000011">
<class>Deploy_Object</class>
<desc>Deploy Cassandra Database</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz</yaml_path>
<services>cassandra db_init</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000001">
@@ -80,28 +78,25 @@
<testCase id="000012">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G CoreNetwork</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz</yaml_path>
<services>oai_hss redis magma_mme oai_spgwc oai_spgwu trf_gen</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000013">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G eNB RF sim (FDD 20MHz)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz</yaml_path>
<services>oai_enb0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000014">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G LTE-UE RF sim (FDD 20MHz)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz</yaml_path>
<services>oai_ue0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000015">
@@ -161,16 +156,15 @@
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 4G stack</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fdd_20MHz</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb-asan oai-lte-ue-asan</images>
</testCase>

View File

@@ -40,14 +40,13 @@
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb-asan oai-lte-ue-asan</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
@@ -64,19 +63,17 @@
<testCase id="000013">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G eNB RF sim (FeMBMS)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fembms</yaml_path>
<services>oai_enb0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000014">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G LTE-UE RF sim (FeMBMS)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fembms</yaml_path>
<services>oai_ue0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="030011">
@@ -95,16 +92,15 @@
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 4G stack</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_fembms</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb-asan oai-lte-ue-asan</images>
</testCase>

View File

@@ -40,14 +40,13 @@
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb-asan oai-lte-ue-asan</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
</testCase>
<testCase id="000001">
<class>IdleSleep</class>
@@ -64,19 +63,17 @@
<testCase id="000013">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G eNB RF sim (MBMS)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_mbms</yaml_path>
<services>oai_enb0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000014">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G LTE-UE RF sim (MBMS)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_mbms</yaml_path>
<services>oai_ue0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="030011">
@@ -95,16 +92,15 @@
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 4G stack</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_mbms</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb-asan oai-lte-ue-asan</images>
</testCase>

View File

@@ -47,22 +47,20 @@
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb oai-lte-ue</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
</testCase>
<testCase id="000011">
<class>Deploy_Object</class>
<desc>Deploy Cassandra Database</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz</yaml_path>
<services>cassandra db_init</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000001">
@@ -80,28 +78,25 @@
<testCase id="000012">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G CoreNetwork</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz</yaml_path>
<services>oai_hss oai_mme oai_spgwc oai_spgwu trf_gen</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000013">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G eNB RF sim (TDD 05MHz)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz</yaml_path>
<services>oai_enb0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000014">
<class>Deploy_Object</class>
<desc>Deploy OAI 4G LTE-UE RF sim (TDD 05MHz)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz</yaml_path>
<services>oai_ue0</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="020011">
@@ -154,16 +149,15 @@
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<desc>Undeploy all OAI 4G stack</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/4g_rfsimulator_tdd_05MHz</yaml_path>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-enb oai-lte-ue</images>
</testCase>

View File

@@ -40,40 +40,36 @@
<testCase id="111111">
<class>Pull_Local_Registry</class>
<desc>Pull Images from Local Registry</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-gnb oai-nr-cuup oai-nr-ue</images>
</testCase>
<testCase id="800813">
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<node>localhost</node>
</testCase>
<testCase id="000021">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G CoreNetwork</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_e1</yaml_path>
<services>mysql oai-amf oai-smf oai-upf</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000022">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G RAN RF sim SA (1 CU-CP, 3 CU-UPs, 3 DUs)</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_e1</yaml_path>
<services>oai-cucp oai-cuup oai-cuup2 oai-cuup3 oai-du oai-du2 oai-du3</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000023">
<class>Deploy_Object</class>
<desc>Deploy OAI 5G NR-UE RF sim SA</desc>
<node>localhost</node>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_e1</yaml_path>
<services>oai-nr-ue oai-nr-ue2 oai-nr-ue3</services>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="000024">
@@ -97,19 +93,18 @@
<testCase id="100021">
<class>Undeploy_Object</class>
<always_exec>true</always_exec>
<node>localhost</node>
<desc>Undeploy all OAI 5G stack</desc>
<yaml_path>ci-scripts/yaml_files/5g_rfsimulator_e1</yaml_path>
<d_retx_th>1,0,0,0</d_retx_th>
<u_retx_th>1,0,0,0</u_retx_th>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
</testCase>
<testCase id="222222">
<class>Clean_Test_Server_Images</class>
<always_exec>true</always_exec>
<desc>Clean Test Images on Test Server</desc>
<svr_id>0</svr_id>
<node>localhost</node>
<images>oai-gnb oai-nr-cuup oai-nr-ue</images>
</testCase>

Some files were not shown because too many files have changed in this diff Show More