Files
openairinterface5g/common/utils/time_manager/tests/test_auto.c
T
Robert Schmidt 8107939f08 Change OAI license to CSSL v1.0 (and others)
- all RAN code, CI code, configuration files, dockerfiles, in CSSL v1.0
- all deployment code (openshift, charts, ancillary files like shell
  scripts), in MIT
- documentation in CC-BY-4.0
- exceptions might apply and are listed in NOTICE
- there is a new LICENSES folder with all licenses
- CONTRIBUTIONS.md has been updated accordingly

For automated changes based on OAI PL v1.1:

    perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.{c,h,cpp}
    perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.ts
    perl -i~ -0pe 's/<!--.*Licensed to the OpenAirInterface.*openairinterface.org\n.*-->/<!-- SPDX-License-Identifier: LicenseRef-CSSL-1.0 -->/s' **/*.xml

The rest (cmake, files with missing license, cmake) manually.
2026-03-27 16:36:37 +01:00

281 lines
7.1 KiB
C

/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include "common/utils/time_manager/time_manager.h"
#include "common/utils/LOG/log.h"
#include "common/config/config_userapi.h"
configmodule_interface_t *uniqCfg = NULL;
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
{
if (s != NULL) {
printf("%s:%d %s() Exiting OAI softmodem: %s\n", file, line, function, s);
}
if (assert)
abort();
else
exit(1);
}
static int rlc_tick_count = 0;
static int pdcp_tick_count = 0;
static int x2ap_tick_count = 0;
void nr_rlc_ms_tick(void)
{
rlc_tick_count++;
}
void nr_pdcp_ms_tick(void)
{
pdcp_tick_count++;
}
void x2ap_ms_tick(void)
{
x2ap_tick_count++;
}
/* return 1 if ok, 0 if error */
static int standalone_realtime(void)
{
time_manager_tick_function_t tick_functions[] = {
nr_pdcp_ms_tick,
nr_rlc_ms_tick,
x2ap_ms_tick
};
int tick_functions_count = sizeofArray(tick_functions);
time_manager_start(tick_functions, tick_functions_count, TIME_SOURCE_REALTIME);
sleep(1);
time_manager_finish();
LOG_I(UTIL,
"standalone realtime: rlc ticks: %d pdcp ticks: %d x2ap ticks: %d\n",
rlc_tick_count,
pdcp_tick_count,
x2ap_tick_count);
/* let's accept 1% deviation from the 1000 counts we expect */
return abs(rlc_tick_count-1000) < 10
&& abs(pdcp_tick_count - 1000) < 10
&& abs(x2ap_tick_count - 1000) < 10;
}
/* return 1 if ok, 0 if error */
static int standalone_iq_samples(void)
{
time_manager_tick_function_t tick_functions[] = {
nr_pdcp_ms_tick,
nr_rlc_ms_tick,
x2ap_ms_tick
};
int tick_functions_count = sizeofArray(tick_functions);
time_manager_start(tick_functions, tick_functions_count, TIME_SOURCE_IQ_SAMPLES);
/* let's pretend we have 2000 samples per second */
for (int i = 0; i < 1000; i++) {
time_manager_iq_samples(1, 2000);
usleep(10);
time_manager_iq_samples(1, 2000);
usleep(10);
}
time_manager_finish();
LOG_I(UTIL,
"standalone iq-samples: rlc ticks: %d pdcp ticks: %d x2ap ticks: %d\n",
rlc_tick_count,
pdcp_tick_count,
x2ap_tick_count);
/* exact count is required */
return rlc_tick_count == 1000
&& pdcp_tick_count == 1000
&& x2ap_tick_count == 1000;
}
/* return 1 if ok, 0 if error */
static int client_server(char *program_name, bool iq_samples_time_source)
{
LOG_I(UTIL, "client/server %s: launch sub-processes\n", iq_samples_time_source ? "iq-samples" : "realtime");
pid_t server;
pid_t client;
/* start server */
server = fork();
DevAssert(server >= 0);
if (server == 0) {
/* run as server */
if (iq_samples_time_source)
execl(program_name, program_name, "--time_management.mode", "server", "--time_management.time_source", "iq_samples", NULL);
else
execl(program_name, program_name, "--time_management.mode", "server", NULL);
exit(1);
}
/* wait a little bit so that server is ready to accept clients
* (this is hackish)
*/
usleep(1000);
/* start client */
client = fork();
DevAssert(client >= 0);
if (client == 0) {
/* run as client */
execl(program_name, program_name, "--time_management.mode", "client", NULL);
exit(1);
}
/* wait for completion */
int ret = 1;
int status;
pid_t r = waitpid(server, &status, 0);
DevAssert(r == server);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
ret = 0;
r = waitpid(client, &status, 0);
DevAssert(r == client);
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
ret = 0;
return ret;
}
/* return 1 if ok, 0 if error */
static int run_sub_client_server(bool iq_samples_time_source)
{
time_manager_tick_function_t tick_functions[] = {
nr_pdcp_ms_tick,
nr_rlc_ms_tick,
x2ap_ms_tick
};
int tick_functions_count = sizeofArray(tick_functions);
/* last argument doesn't matter, overwritten by args of execl in client_server() */
time_manager_start(tick_functions, tick_functions_count, TIME_SOURCE_REALTIME);
if (iq_samples_time_source) {
/* 'iq_samples_time_source' is true only for server
* wait a bit for client to be there otherwise server
* may finish too early
*/
usleep(100*1000);
/* let's pretend we have 2000 samples per second */
for (int i = 0; i < 1000; i++) {
time_manager_iq_samples(1, 2000);
usleep(10);
time_manager_iq_samples(1, 2000);
usleep(10);
}
} else {
sleep(1);
}
time_manager_finish();
LOG_I(UTIL, "client/server: rlc ticks: %d pdcp ticks: %d x2ap ticks: %d\n", rlc_tick_count, pdcp_tick_count, x2ap_tick_count);
if (iq_samples_time_source)
return rlc_tick_count == 1000
&& pdcp_tick_count == 1000
&& x2ap_tick_count == 1000;
else
/* let's accept 1% deviation from the 1000 counts we expect */
return abs(rlc_tick_count-1000) < 10
&& abs(pdcp_tick_count - 1000) < 10
&& abs(x2ap_tick_count - 1000) < 10;
}
int main(int argc, char **argv)
{
if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == NULL) {
exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
}
logInit();
/* for client/server tests, we use sub-processes with command line parameters */
if (argc > 1) {
/* if there are command line parameters then it's a sub-process */
rlc_tick_count = 0;
pdcp_tick_count = 0;
x2ap_tick_count = 0;
/* return value to the main test program
* let's do as for the shell: 0 means success and 1 means error
*/
/* we know we are in iq-samples time source mode if the last argument is "iq_samples" */
int success = run_sub_client_server(!strcmp(argv[argc - 1], "iq_samples")) == 1;
return 1 - success;
}
int err = 0;
/* test standalone realtime */
rlc_tick_count = 0;
pdcp_tick_count = 0;
x2ap_tick_count = 0;
int ret = standalone_realtime();
if (ret == 1)
LOG_I(UTIL, "standalone realtime: OK\n");
else {
LOG_E(UTIL, "standalone realtime: ERROR\n");
err = 1;
}
/* test standalone iq-samples */
rlc_tick_count = 0;
pdcp_tick_count = 0;
x2ap_tick_count = 0;
ret = standalone_iq_samples();
if (ret == 1)
LOG_I(UTIL, "standalone iq-samples: OK\n");
else {
LOG_E(UTIL, "standalone iq-samples: ERROR\n");
err = 1;
}
/* client/server tests are not written in a robust way
* they may fail depending on realtime on the machine
* de-activate if needed (if CI fails)
*/
/* test client/server realtime */
rlc_tick_count = 0;
pdcp_tick_count = 0;
x2ap_tick_count = 0;
ret = client_server(argv[0], false);
if (ret == 1)
LOG_I(UTIL, "client-server realtime: OK\n");
else {
LOG_E(UTIL, "client-server realtime: ERROR\n");
err = 1;
}
/* test client/server iq-samples */
rlc_tick_count = 0;
pdcp_tick_count = 0;
x2ap_tick_count = 0;
ret = client_server(argv[0], true);
if (ret == 1)
LOG_I(UTIL, "client-server iq-samples: OK\n");
else {
LOG_E(UTIL, "client-server iq-samples: ERROR\n");
err = 1;
}
logTerm();
return err;
}