numam-dpdk/app/test/process.h
Reshma Pattan 207b1c813f test: fix build without ring PMD
Some unit tests has dependency on RING PMD,
so this patch is trying to fix those and other
closely related issues.

1)pdump, latency, bitrate, ring PMD and test_event_eth_tx_adapter
unit tests are dependent on ring PMD, so compile those
tests only when ring PMD is enabled else ignore.

2)get rid of make file error which was added by bond unit test
for ring PMD disabled case which is not necessary.

3)Tx adapter UT is dependent on RING PMD, but it was
observed that it was missing from the run in meson
build, so added it. TX adapter UT uses 'sw event and
'null' pmd drivers, so for shared builds the drivers .so
path has to be passed to the test args of meson UT run.

Fixes: 086eb64db3 ("test/pdump: add unit test for pdump library")
Fixes: fdeb30fa71 ("test/bitrate: add unit tests for bitrate library")
Fixes: 1e3676a06e ("test/latency: add unit tests for latencystats library")
Fixes: 46cf97e4bb ("eventdev: add test for eth Tx adapter")
Fixes: d23e09e0ef ("app/test: link with ring pmd when needed")
Cc: stable@dpdk.org

Reported-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Reshma Pattan <reshma.pattan@intel.com>
Tested-by: Nikhil Rao <nikhil.rao@intel.com>
Tested-by: Bruce Richardson <bruce.richardson@intel.com>
2020-02-16 19:08:53 +01:00

172 lines
3.9 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2010-2014 Intel Corporation
*/
#ifndef _PROCESS_H_
#define _PROCESS_H_
#include <errno.h> /* errno */
#include <limits.h> /* PATH_MAX */
#include <libgen.h> /* basename et al */
#include <stdlib.h> /* NULL */
#include <string.h> /* strerror */
#include <unistd.h> /* readlink */
#include <dirent.h>
#include <sys/wait.h>
#include <rte_string_fns.h> /* strlcpy */
#ifdef RTE_EXEC_ENV_FREEBSD
#define self "curproc"
#define exe "file"
#else
#define self "self"
#define exe "exe"
#endif
#ifdef RTE_LIBRTE_PDUMP
#ifdef RTE_LIBRTE_RING_PMD
#include <pthread.h>
extern void *send_pkts(void *empty);
extern uint16_t flag_for_send_pkts;
#endif
#endif
/*
* launches a second copy of the test process using the given argv parameters,
* which should include argv[0] as the process name. To identify in the
* subprocess the source of the call, the env_value parameter is set in the
* environment as $RTE_TEST
*/
static inline int
process_dup(const char *const argv[], int numargs, const char *env_value)
{
int num;
char *argv_cpy[numargs + 1];
int i, status;
char path[32];
#ifdef RTE_LIBRTE_PDUMP
#ifdef RTE_LIBRTE_RING_PMD
pthread_t thread;
#endif
#endif
pid_t pid = fork();
if (pid < 0)
return -1;
else if (pid == 0) {
/* make a copy of the arguments to be passed to exec */
for (i = 0; i < numargs; i++)
argv_cpy[i] = strdup(argv[i]);
argv_cpy[i] = NULL;
num = numargs;
#ifdef RTE_EXEC_ENV_LINUX
{
const char *procdir = "/proc/" self "/fd/";
struct dirent *dirent;
char *endptr;
int fd, fdir;
DIR *dir;
/* close all open file descriptors, check /proc/self/fd
* to only call close on open fds. Exclude fds 0, 1 and
* 2
*/
dir = opendir(procdir);
if (dir == NULL) {
rte_panic("Error opening %s: %s\n", procdir,
strerror(errno));
}
fdir = dirfd(dir);
if (fdir < 0) {
status = errno;
closedir(dir);
rte_panic("Error %d obtaining fd for dir %s: %s\n",
fdir, procdir,
strerror(status));
}
while ((dirent = readdir(dir)) != NULL) {
errno = 0;
fd = strtol(dirent->d_name, &endptr, 10);
if (errno != 0 || endptr[0] != '\0') {
printf("Error converting name fd %d %s:\n",
fd, dirent->d_name);
continue;
}
if (fd == fdir || fd <= 2)
continue;
close(fd);
}
closedir(dir);
}
#endif
printf("Running binary with argv[]:");
for (i = 0; i < num; i++)
printf("'%s' ", argv_cpy[i]);
printf("\n");
/* set the environment variable */
if (setenv(RECURSIVE_ENV_VAR, env_value, 1) != 0)
rte_panic("Cannot export environment variable\n");
strlcpy(path, "/proc/" self "/" exe, sizeof(path));
if (execv(path, argv_cpy) < 0) {
if (errno == ENOENT) {
printf("Could not find '%s', is procfs mounted?\n",
path);
}
rte_panic("Cannot exec: %s\n", strerror(errno));
}
}
/* parent process does a wait */
#ifdef RTE_LIBRTE_PDUMP
#ifdef RTE_LIBRTE_RING_PMD
if ((strcmp(env_value, "run_pdump_server_tests") == 0))
pthread_create(&thread, NULL, &send_pkts, NULL);
#endif
#endif
while (wait(&status) != pid)
;
#ifdef RTE_LIBRTE_PDUMP
#ifdef RTE_LIBRTE_RING_PMD
if ((strcmp(env_value, "run_pdump_server_tests") == 0)) {
flag_for_send_pkts = 0;
pthread_join(thread, NULL);
}
#endif
#endif
return status;
}
/* FreeBSD doesn't support file prefixes, so force compile failures for any
* tests attempting to use this function on FreeBSD.
*/
#ifdef RTE_EXEC_ENV_LINUX
static char *
get_current_prefix(char *prefix, int size)
{
char path[PATH_MAX] = {0};
char buf[PATH_MAX] = {0};
/* get file for config (fd is always 3) */
snprintf(path, sizeof(path), "/proc/self/fd/%d", 3);
/* return NULL on error */
if (readlink(path, buf, sizeof(buf)) == -1)
return NULL;
/* get the prefix */
snprintf(prefix, size, "%s", basename(dirname(buf)));
return prefix;
}
#endif
#endif /* _PROCESS_H_ */