mirror of
https://git.proxmox.com/git/mirror_kronosnet
synced 2026-01-13 06:39:57 +00:00
Logic is to try to configure a link with port X and if it fails, try the next port. This avoids port collisions between services and knet test suite. Please note that the implementation in test-common.c is NOT super clean. There is still some redundant code in there that is left on purpose. There is another branch, not yet merged, that implements functional testing framework that does heavy use of those functions. We will clean test-common.c as we port the functional testing branch and make it ready for merging. For now, this is good enough to have a more stable test suite. Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
398 lines
10 KiB
C
398 lines
10 KiB
C
/*
|
|
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
|
|
*
|
|
* Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
|
|
*
|
|
* This software licensed under GPL-2.0+
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "libknet.h"
|
|
|
|
#include "internals.h"
|
|
#include "netutils.h"
|
|
#include "test-common.h"
|
|
|
|
static int private_data;
|
|
|
|
static void sock_notify(void *pvt_data,
|
|
int datafd,
|
|
int8_t channel,
|
|
uint8_t tx_rx,
|
|
int error,
|
|
int errorno)
|
|
{
|
|
return;
|
|
}
|
|
|
|
static int dhost_filter_ret = 0;
|
|
|
|
static int dhost_filter(void *pvt_data,
|
|
const unsigned char *outdata,
|
|
ssize_t outdata_len,
|
|
uint8_t tx_rx,
|
|
knet_node_id_t this_host_id,
|
|
knet_node_id_t src_host_id,
|
|
int8_t *dst_channel,
|
|
knet_node_id_t *dst_host_ids,
|
|
size_t *dst_host_ids_entries)
|
|
{
|
|
dst_host_ids[0] = 0;
|
|
|
|
/*
|
|
* fatal fault
|
|
*/
|
|
if (dhost_filter_ret < 0) {
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* trigger EINVAL
|
|
* no ids found
|
|
*/
|
|
if (dhost_filter_ret == 0) {
|
|
*dst_host_ids_entries = 0;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* send correct info back
|
|
*/
|
|
|
|
if (dhost_filter_ret == 1) {
|
|
dst_host_ids[0] = 1;
|
|
*dst_host_ids_entries = 1;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* trigger E2BIG
|
|
* mcast destinations
|
|
*/
|
|
if (dhost_filter_ret == 2) {
|
|
dst_host_ids[0] = 1;
|
|
*dst_host_ids_entries = 2;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* return mcast
|
|
*/
|
|
if (dhost_filter_ret == 3) {
|
|
return 1;
|
|
}
|
|
|
|
return dhost_filter_ret;
|
|
}
|
|
|
|
static void test(void)
|
|
{
|
|
knet_handle_t knet_h;
|
|
int logfds[2];
|
|
int datafd = 0;
|
|
int8_t channel = 0;
|
|
char send_buff[KNET_MAX_PACKET_SIZE];
|
|
struct sockaddr_storage lo;
|
|
|
|
memset(send_buff, 0, sizeof(send_buff));
|
|
|
|
printf("Test knet_send_sync incorrect knet_h\n");
|
|
|
|
if ((!knet_send_sync(NULL, send_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
|
|
printf("knet_send_sync accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno));
|
|
exit(FAIL);
|
|
}
|
|
|
|
setup_logpipes(logfds);
|
|
|
|
knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
|
|
|
|
printf("Test knet_send_sync with no send_buff\n");
|
|
|
|
if ((!knet_send_sync(knet_h, NULL, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
|
|
printf("knet_send_sync accepted invalid send_buff or returned incorrect error: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
flush_logs(logfds[0], stdout);
|
|
|
|
printf("Test knet_send_sync with invalid send_buff len (0)\n");
|
|
|
|
if ((!knet_send_sync(knet_h, send_buff, 0, channel)) || (errno != EINVAL)) {
|
|
printf("knet_send_sync accepted invalid send_buff len (0) or returned incorrect error: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
flush_logs(logfds[0], stdout);
|
|
|
|
printf("Test knet_send_sync with invalid send_buff len (> KNET_MAX_PACKET_SIZE)\n");
|
|
|
|
if ((!knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE + 1, channel)) || (errno != EINVAL)) {
|
|
printf("knet_send_sync accepted invalid send_buff len (> KNET_MAX_PACKET_SIZE) or returned incorrect error: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
flush_logs(logfds[0], stdout);
|
|
|
|
printf("Test knet_send_sync with invalid channel (-1)\n");
|
|
|
|
channel = -1;
|
|
|
|
if ((!knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
|
|
printf("knet_send_sync accepted invalid channel (-1) or returned incorrect error: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
flush_logs(logfds[0], stdout);
|
|
|
|
printf("Test knet_send_sync with invalid channel (KNET_DATAFD_MAX)\n");
|
|
|
|
channel = KNET_DATAFD_MAX;
|
|
|
|
if ((!knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
|
|
printf("knet_send_sync accepted invalid channel (KNET_DATAFD_MAX) or returned incorrect error: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
flush_logs(logfds[0], stdout);
|
|
|
|
printf("Test knet_send_sync with unconfigured channel\n");
|
|
|
|
channel = 0;
|
|
|
|
if ((!knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
|
|
printf("knet_send_sync accepted invalid unconfigured channel or returned incorrect error: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
flush_logs(logfds[0], stdout);
|
|
|
|
printf("Test knet_send_sync with data forwarding disabled\n");
|
|
|
|
if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
|
|
printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
datafd = 0;
|
|
channel = -1;
|
|
|
|
if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
|
|
printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
if ((knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != ECANCELED)) {
|
|
printf("knet_send_sync didn't detect datafwd disabled or returned incorrect error: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
flush_logs(logfds[0], stdout);
|
|
|
|
printf("Test knet_send_sync with broken dst_host_filter\n");
|
|
|
|
if (knet_handle_setfwd(knet_h, 1) < 0) {
|
|
printf("knet_handle_setfwd failed: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
if (knet_handle_enable_filter(knet_h, NULL, dhost_filter) < 0) {
|
|
printf("knet_handle_enable_filter failed: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
dhost_filter_ret = -1;
|
|
|
|
if ((knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != EFAULT)) {
|
|
printf("knet_send_sync didn't detect fatal error from dst_host_filter or returned incorrect error: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
flush_logs(logfds[0], stdout);
|
|
|
|
printf("Test knet_send_sync with dst_host_filter returning no host_ids_entries\n");
|
|
|
|
dhost_filter_ret = 0;
|
|
|
|
if ((knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != EINVAL)) {
|
|
printf("knet_send_sync didn't detect 0 host_ids from dst_host_filter or returned incorrect error: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
flush_logs(logfds[0], stdout);
|
|
|
|
printf("Test knet_send_sync with host down\n");
|
|
|
|
dhost_filter_ret = 1;
|
|
|
|
if ((knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != EHOSTDOWN)) {
|
|
printf("knet_send_sync didn't detect hostdown or returned incorrect error: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
flush_logs(logfds[0], stdout);
|
|
|
|
printf("Test knet_send_sync with dst_host_filter returning too many host_ids_entries\n");
|
|
|
|
if (knet_host_add(knet_h, 1) < 0) {
|
|
printf("knet_host_add failed: %s\n", strerror(errno));
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
|
|
printf("Unable to configure link: %s\n", strerror(errno));
|
|
knet_host_remove(knet_h, 1);
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
|
|
printf("knet_link_set_enable failed: %s\n", strerror(errno));
|
|
knet_link_clear_config(knet_h, 1, 0);
|
|
knet_host_remove(knet_h, 1);
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
if (wait_for_host(knet_h, 1, 10, logfds[0], stdout) < 0) {
|
|
printf("timeout waiting for host to be reachable");
|
|
knet_link_set_enable(knet_h, 1, 0, 0);
|
|
knet_link_clear_config(knet_h, 1, 0);
|
|
knet_host_remove(knet_h, 1);
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
dhost_filter_ret = 2;
|
|
|
|
if ((knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != E2BIG)) {
|
|
printf("knet_send_sync didn't detect 2+ host_ids from dst_host_filter or returned incorrect error: %s\n", strerror(errno));
|
|
knet_link_set_enable(knet_h, 1, 0, 0);
|
|
knet_link_clear_config(knet_h, 1, 0);
|
|
knet_host_remove(knet_h, 1);
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
flush_logs(logfds[0], stdout);
|
|
|
|
printf("Test knet_send_sync with dst_host_filter returning mcast packets\n");
|
|
|
|
dhost_filter_ret = 3;
|
|
|
|
if ((knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != E2BIG)) {
|
|
printf("knet_send_sync didn't detect mcast packet from dst_host_filter or returned incorrect error: %s\n", strerror(errno));
|
|
knet_link_set_enable(knet_h, 1, 0, 0);
|
|
knet_link_clear_config(knet_h, 1, 0);
|
|
knet_host_remove(knet_h, 1);
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
flush_logs(logfds[0], stdout);
|
|
|
|
printf("Test knet_send_sync with valid data\n");
|
|
|
|
dhost_filter_ret = 1;
|
|
|
|
if (knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) < 0) {
|
|
printf("knet_send_sync failed: %d %s\n", errno, strerror(errno));
|
|
knet_link_set_enable(knet_h, 1, 0, 0);
|
|
knet_link_clear_config(knet_h, 1, 0);
|
|
knet_host_remove(knet_h, 1);
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
flush_logs(logfds[0], stdout);
|
|
|
|
if (knet_handle_setfwd(knet_h, 0) < 0) {
|
|
printf("knet_handle_setfwd failed: %s\n", strerror(errno));
|
|
knet_link_set_enable(knet_h, 1, 0, 0);
|
|
knet_link_clear_config(knet_h, 1, 0);
|
|
knet_host_remove(knet_h, 1);
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
exit(FAIL);
|
|
}
|
|
|
|
knet_link_set_enable(knet_h, 1, 0, 0);
|
|
knet_link_clear_config(knet_h, 1, 0);
|
|
knet_host_remove(knet_h, 1);
|
|
knet_handle_free(knet_h);
|
|
flush_logs(logfds[0], stdout);
|
|
close_logpipes(logfds);
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
test();
|
|
|
|
return PASS;
|
|
}
|