2017-05-04 15:53:38 -07:00
|
|
|
/*
|
|
|
|
|
* ZeroTier SDK - Network Virtualization Everywhere
|
|
|
|
|
* Copyright (C) 2011-2017 ZeroTier, Inc. https://www.zerotier.com/
|
|
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*
|
|
|
|
|
* --
|
|
|
|
|
*
|
|
|
|
|
* You can be released from the requirements of the license by purchasing
|
|
|
|
|
* a commercial license. Buying such a license is mandatory as soon as you
|
|
|
|
|
* develop commercial closed-source software that incorporates or links
|
|
|
|
|
* directly against ZeroTier software without disclosing the source code
|
|
|
|
|
* of your own application.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// Comprehensive stress test for socket-like API
|
2017-05-01 17:44:45 -07:00
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
|
#include <netdb.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <fcntl.h>
|
2017-05-30 13:17:39 -07:00
|
|
|
#include <errno.h>
|
2017-05-01 17:44:45 -07:00
|
|
|
|
|
|
|
|
#include <iostream>
|
2017-05-05 16:46:07 -07:00
|
|
|
#include <vector>
|
2017-05-30 13:17:39 -07:00
|
|
|
#include <algorithm>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <map>
|
2017-06-16 16:58:30 -07:00
|
|
|
#include <ctime>
|
|
|
|
|
#include <sys/time.h>
|
2017-05-01 17:44:45 -07:00
|
|
|
|
2017-06-14 16:53:59 -07:00
|
|
|
#include "libzt.h"
|
2017-05-01 17:44:45 -07:00
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
#define EXIT_ON_FAIL false
|
2017-05-01 17:44:45 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
#define PASSED 1
|
|
|
|
|
#define FAILED 0
|
2017-05-01 17:44:45 -07:00
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
#define ECHO_INTERVAL 1000000 // us
|
2017-06-16 16:58:30 -07:00
|
|
|
#define SLAM_INTERVAL 500000
|
|
|
|
|
#define STR_SIZE 32
|
2017-05-01 17:44:45 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
#define TEST_OP_N_BYTES 10
|
|
|
|
|
#define TEST_OP_N_SECONDS 11
|
|
|
|
|
#define TEST_OP_N_TIMES 12
|
2017-05-01 17:44:45 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
#define TEST_MODE_CLIENT 20
|
|
|
|
|
#define TEST_MODE_SERVER 21
|
2017-05-01 17:44:45 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
#define TEST_TYPE_SIMPLE 30
|
|
|
|
|
#define TEST_TYPE_SUSTAINED 31
|
|
|
|
|
#define TEST_TYPE_PERF 32
|
|
|
|
|
#define TEST_TYPE_PERF_TO_ECHO 33
|
|
|
|
|
|
|
|
|
|
#define MIN_PORT 5000
|
|
|
|
|
#define MAX_PORT 50000
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
#define UNIT_TEST_SIG_4 struct sockaddr_in *addr, int operation, int count, int delay, char *details, bool *passed
|
|
|
|
|
#define UNIT_TEST_SIG_6 struct sockaddr_in6 *addr, int operation, int count, int delay, char *details, bool *passed
|
|
|
|
|
|
|
|
|
|
#define ECHOTEST_MODE_RX 333
|
|
|
|
|
#define ECHOTEST_MODE_TX 666
|
|
|
|
|
|
|
|
|
|
#define DATA_BUF_SZ 1024*32
|
|
|
|
|
|
|
|
|
|
#define MAX_RX_BUF_SZ 2048
|
|
|
|
|
#define MAX_TX_BUF_SZ 2048
|
|
|
|
|
|
|
|
|
|
#define ONE_MEGABYTE 1024 * 1024
|
2017-05-05 16:46:07 -07:00
|
|
|
|
2017-05-01 17:44:45 -07:00
|
|
|
char str[STR_SIZE];
|
|
|
|
|
|
2017-05-30 13:17:39 -07:00
|
|
|
std::map<std::string, std::string> testConf;
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
|
|
|
|
|
// TODO: check for correct byte order in sustained and performance tests
|
|
|
|
|
|
2017-05-05 16:46:07 -07:00
|
|
|
/* Tests in this file:
|
|
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
Basic RX/TX connect()/accept() Functionality:
|
2017-05-05 16:46:07 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
[ ?] slam - perform thousands of the same call per second
|
|
|
|
|
[ ] random - act like a monkey, press all the buttons
|
|
|
|
|
[OK] simple client ipv4 - connect, send one message and wait for an echo
|
|
|
|
|
[OK] simple server ipv4 - accept, read one message and echo it back
|
|
|
|
|
[OK] simple client ipv6 - connect, send one message and wait for an echo
|
|
|
|
|
[OK] simple server ipv6 - accept, read one message and echo it back
|
|
|
|
|
[OK] sustained client ipv4 - connect and rx/tx many messages
|
|
|
|
|
[OK] sustained server ipv4 - accept and echo messages
|
|
|
|
|
[ ?] sustained client ipv6 - connect and rx/tx many messages
|
|
|
|
|
[ ?] sustained server ipv6 - accept and echo messages
|
|
|
|
|
[OK] comprehensive client ipv4 - test all ipv4/6 client simple/sustained modes
|
|
|
|
|
[OK] comprehensive server ipv6 - test all ipv4/6 server simple/sustained modes
|
2017-05-05 16:46:07 -07:00
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
Performance:
|
|
|
|
|
(See libzt.h, compile libzt with appropriate ZT_TCP_TX_BUF_SZ, ZT_TCP_RX_BUF_SZ, ZT_UDP_TX_BUF_SZ, and ZT_UDO_RX_BUF_SZ for your test)
|
2017-05-05 16:46:07 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
[OK] Throughput - Test maximum RX/TX speeds
|
|
|
|
|
[ ] Memory Usage - Test memory consumption profile
|
|
|
|
|
[ ] CPU Usage - Test processor usage
|
|
|
|
|
[ ]
|
2017-05-05 16:46:07 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
Correctness:
|
2017-05-05 16:46:07 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
[ ] Block/Non-block - Test that blocking and non-blocking behaviour is consistent
|
|
|
|
|
[ ] Release of resources - Test that all destructor methods/blocks function properly
|
|
|
|
|
[ ] Multi-network handling - Test internal Tap multiplexing works for multiple networks
|
|
|
|
|
[ ] Address handling - Test that addresses are copied/parsed/returned properly
|
2017-05-01 17:44:45 -07:00
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
2017-05-30 13:17:39 -07:00
|
|
|
void displayResults(int *results, int size)
|
|
|
|
|
{
|
|
|
|
|
int success = 0, failure = 0;
|
|
|
|
|
for(int i=0; i<size; i++) {
|
|
|
|
|
if(results[i] == 0)
|
|
|
|
|
success++;
|
|
|
|
|
else
|
|
|
|
|
failure++;
|
|
|
|
|
}
|
|
|
|
|
std::cout << "tials: " << size << std::endl;
|
|
|
|
|
std::cout << " - success = " << (float)success / (float)size << std::endl;
|
|
|
|
|
std::cout << " - failure = " << (float)failure / (float)size << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void loadTestConfigFile(std::string filepath)
|
|
|
|
|
{
|
|
|
|
|
std::string key;
|
|
|
|
|
std::string value;
|
|
|
|
|
std::ifstream testFile;
|
|
|
|
|
testFile.open(filepath.c_str());
|
2017-06-16 16:58:30 -07:00
|
|
|
while (testFile >> key >> value) {
|
|
|
|
|
if(key[0] != '#')
|
|
|
|
|
testConf[key] = value;
|
|
|
|
|
}
|
2017-05-30 13:17:39 -07:00
|
|
|
testFile.close();
|
|
|
|
|
}
|
2017-05-05 16:46:07 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
long int get_now_ts()
|
|
|
|
|
{
|
|
|
|
|
struct timeval tp;
|
|
|
|
|
gettimeofday(&tp, NULL);
|
|
|
|
|
return tp.tv_sec * 1000 + tp.tv_usec / 1000;
|
|
|
|
|
}
|
2017-05-05 16:46:07 -07:00
|
|
|
|
2017-05-01 17:44:45 -07:00
|
|
|
/****************************************************************************/
|
2017-06-16 16:58:30 -07:00
|
|
|
/* SIMPLE */
|
2017-05-01 17:44:45 -07:00
|
|
|
/****************************************************************************/
|
|
|
|
|
|
|
|
|
|
//
|
2017-06-16 16:58:30 -07:00
|
|
|
void tcp_client_4(UNIT_TEST_SIG_4)
|
2017-05-01 17:44:45 -07:00
|
|
|
{
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("\n");
|
2017-05-01 17:44:45 -07:00
|
|
|
int r, w, sockfd, err, len = strlen(str);
|
|
|
|
|
char rbuf[STR_SIZE];
|
2017-06-16 16:58:30 -07:00
|
|
|
memset(rbuf, 0, sizeof rbuf);
|
|
|
|
|
if((sockfd = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error creating ZeroTier socket");
|
2017-06-16 16:58:30 -07:00
|
|
|
if((err = zts_connect(sockfd, (const struct sockaddr *)addr, sizeof(addr))) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error connecting to remote host (%d)", err);
|
2017-05-01 17:44:45 -07:00
|
|
|
w = zts_write(sockfd, str, len);
|
|
|
|
|
r = zts_read(sockfd, rbuf, len);
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("Sent : %s", str);
|
|
|
|
|
DEBUG_TEST("Received : %s", rbuf);
|
2017-05-01 17:44:45 -07:00
|
|
|
err = zts_close(sockfd);
|
2017-06-22 18:22:39 -07:00
|
|
|
sprintf(details, "count=%d, err=%d, r=%d, w=%d", count, err, r, w);
|
2017-06-16 16:58:30 -07:00
|
|
|
*passed = (w == len && r == len && !err) && !strcmp(rbuf, str);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
2017-06-16 16:58:30 -07:00
|
|
|
void tcp_client_6(UNIT_TEST_SIG_6)
|
2017-05-01 17:44:45 -07:00
|
|
|
{
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("\n");
|
2017-05-01 17:44:45 -07:00
|
|
|
int r, w, sockfd, err, len = strlen(str);
|
|
|
|
|
char rbuf[STR_SIZE];
|
2017-06-16 16:58:30 -07:00
|
|
|
memset(rbuf, 0, sizeof rbuf);
|
|
|
|
|
if((sockfd = zts_socket(AF_INET6, SOCK_STREAM, 0)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error creating ZeroTier socket");
|
2017-06-16 16:58:30 -07:00
|
|
|
if((err = zts_connect(sockfd, (const struct sockaddr *)addr, sizeof(addr))) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error connecting to remote host (%d)", err);
|
2017-05-01 17:44:45 -07:00
|
|
|
w = zts_write(sockfd, str, len);
|
|
|
|
|
r = zts_read(sockfd, rbuf, len);
|
|
|
|
|
err = zts_close(sockfd);
|
2017-06-22 18:22:39 -07:00
|
|
|
sprintf(details, "count=%d, err=%d, r=%d, w=%d", count, err, r, w);
|
|
|
|
|
DEBUG_TEST("Sent : %s", str);
|
|
|
|
|
DEBUG_TEST("Received : %s", rbuf);
|
2017-06-16 16:58:30 -07:00
|
|
|
*passed = (w == len && r == len && !err) && !strcmp(rbuf, str);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
2017-06-16 16:58:30 -07:00
|
|
|
void tcp_server_4(UNIT_TEST_SIG_4)
|
2017-05-01 17:44:45 -07:00
|
|
|
{
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("\n");
|
2017-05-01 17:44:45 -07:00
|
|
|
int w=0, r=0, sockfd, accfd, err, len = strlen(str);
|
|
|
|
|
char rbuf[STR_SIZE];
|
2017-06-16 16:58:30 -07:00
|
|
|
memset(rbuf, 0, sizeof rbuf);
|
|
|
|
|
if((sockfd = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error creating ZeroTier socket");
|
2017-06-16 16:58:30 -07:00
|
|
|
if((err = zts_bind(sockfd, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) < 0))
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error binding to interface (%d)", err);
|
2017-06-16 16:58:30 -07:00
|
|
|
if((err = zts_listen(sockfd, 100)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
printf("error placing socket in LISTENING state (%d)", err);
|
2017-06-16 16:58:30 -07:00
|
|
|
if((accfd = zts_accept(sockfd, (struct sockaddr *)&addr, (socklen_t *)sizeof(addr))) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error accepting connection (%d)", err);
|
2017-05-01 17:44:45 -07:00
|
|
|
r = zts_read(accfd, rbuf, sizeof rbuf);
|
|
|
|
|
w = zts_write(accfd, rbuf, len);
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("Received : %s", rbuf);
|
2017-05-01 17:44:45 -07:00
|
|
|
zts_close(sockfd);
|
|
|
|
|
zts_close(accfd);
|
2017-06-22 18:22:39 -07:00
|
|
|
sprintf(details, "count=%d, err=%d, r=%d, w=%d", count, err, r, w);
|
2017-06-16 16:58:30 -07:00
|
|
|
*passed = (w == len && r == len && !err) && !strcmp(rbuf, str);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
2017-06-16 16:58:30 -07:00
|
|
|
void tcp_server_6(UNIT_TEST_SIG_6)
|
2017-05-01 17:44:45 -07:00
|
|
|
{
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("\n");
|
2017-05-01 17:44:45 -07:00
|
|
|
int w=0, r=0, sockfd, accfd, err, len = strlen(str);
|
|
|
|
|
char rbuf[STR_SIZE];
|
2017-06-16 16:58:30 -07:00
|
|
|
memset(rbuf, 0, sizeof rbuf);
|
|
|
|
|
if((sockfd = zts_socket(AF_INET6, SOCK_STREAM, 0)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error creating ZeroTier socket");
|
2017-06-16 16:58:30 -07:00
|
|
|
if((err = zts_bind(sockfd, (struct sockaddr *)addr, sizeof(struct sockaddr_in)) < 0))
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error binding to interface (%d)", err);
|
2017-06-16 16:58:30 -07:00
|
|
|
if((err = zts_listen(sockfd, 100)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error placing socket in LISTENING state (%d)", err);
|
2017-06-16 16:58:30 -07:00
|
|
|
if((accfd = zts_accept(sockfd, (struct sockaddr *)&addr, (socklen_t *)sizeof(addr))) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error accepting connection (%d)", err);
|
2017-05-01 17:44:45 -07:00
|
|
|
r = zts_read(accfd, rbuf, sizeof rbuf);
|
|
|
|
|
w = zts_write(accfd, rbuf, len);
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("Received : %s", rbuf);
|
2017-05-01 17:44:45 -07:00
|
|
|
zts_close(sockfd);
|
|
|
|
|
zts_close(accfd);
|
2017-06-22 18:22:39 -07:00
|
|
|
sprintf(details, "count=%d, err=%d, r=%d, w=%d", count, err, r, w);
|
2017-06-16 16:58:30 -07:00
|
|
|
*passed = (w == len && r == len && !err) && !strcmp(rbuf, str);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************/
|
2017-06-16 16:58:30 -07:00
|
|
|
/* SUSTAINED */
|
2017-05-01 17:44:45 -07:00
|
|
|
/****************************************************************************/
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
// Maintain transfer for count OR count
|
2017-06-16 16:58:30 -07:00
|
|
|
void tcp_client_sustained_4(UNIT_TEST_SIG_4)
|
2017-05-01 17:44:45 -07:00
|
|
|
{
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("\n");
|
2017-06-16 16:58:30 -07:00
|
|
|
int tot=0, n=0, w=0, r=0, sockfd, err, len = strlen(str);
|
2017-06-22 18:22:39 -07:00
|
|
|
|
|
|
|
|
char *rxbuf;
|
|
|
|
|
rxbuf = (char*)malloc(count*sizeof(char));
|
|
|
|
|
memset(rxbuf, 0, count);
|
|
|
|
|
|
|
|
|
|
char *txbuf;
|
|
|
|
|
txbuf = (char*)malloc(count*sizeof(char));
|
|
|
|
|
memset(txbuf, 0, count);
|
|
|
|
|
|
|
|
|
|
long int rx_checksum = 0;
|
|
|
|
|
long int tx_checksum = 0;
|
|
|
|
|
|
|
|
|
|
// generate random data and calculate checksum
|
|
|
|
|
srand((unsigned)time(0));
|
|
|
|
|
int min = 0, max = 9, range = (max - min);
|
|
|
|
|
DEBUG_TEST("preparing random data for buffer...");
|
|
|
|
|
for(int i=0; i<count; i++) {
|
|
|
|
|
txbuf[i] = min + (rand() % static_cast<int>(max - min + 1));
|
|
|
|
|
}
|
|
|
|
|
DEBUG_TEST("calculating checksum before transfer (txbuf)...");
|
|
|
|
|
for(int i=0; i<count; i++) {
|
|
|
|
|
tx_checksum+=txbuf[i];
|
|
|
|
|
fprintf(stderr, "%d ", txbuf[i]);
|
|
|
|
|
}
|
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
if((sockfd = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error creating ZeroTier socket");
|
2017-06-16 16:58:30 -07:00
|
|
|
if((err = zts_connect(sockfd, (const struct sockaddr *)addr, sizeof(addr))) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error connecting to remote host (%d)", err);
|
2017-05-01 17:44:45 -07:00
|
|
|
if(operation == TEST_OP_N_TIMES) {
|
2017-06-22 18:22:39 -07:00
|
|
|
tot = len*count;
|
2017-06-16 16:58:30 -07:00
|
|
|
std::time_t start_time = std::time(nullptr);
|
2017-06-22 18:22:39 -07:00
|
|
|
for(int i=0; i<count; i++) {
|
|
|
|
|
n = zts_write(sockfd, txbuf, len);
|
2017-05-01 17:44:45 -07:00
|
|
|
if (n > 0)
|
|
|
|
|
w += n;
|
2017-06-22 18:22:39 -07:00
|
|
|
n = zts_read(sockfd, rxbuf, len);
|
2017-05-01 17:44:45 -07:00
|
|
|
if (n > 0)
|
|
|
|
|
r += n;
|
|
|
|
|
}
|
2017-06-16 16:58:30 -07:00
|
|
|
std::time_t end_time = std::time(nullptr);
|
|
|
|
|
sleep(2);
|
2017-05-01 17:44:45 -07:00
|
|
|
err = zts_close(sockfd);
|
2017-06-16 16:58:30 -07:00
|
|
|
time_t ts_delta = end_time - start_time;
|
2017-06-22 18:22:39 -07:00
|
|
|
sprintf(details, "count=%d, dt=%d, r=%d, w=%d", count, ts_delta, r, w);
|
|
|
|
|
*passed = (r == tot && w == tot && !err) && !strcmp(rxbuf, txbuf);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
if(operation == TEST_OP_N_BYTES) {
|
2017-06-22 18:22:39 -07:00
|
|
|
|
|
|
|
|
//zts_fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
|
|
|
|
|
|
|
|
|
int wrem = count;
|
|
|
|
|
int rrem = count;
|
|
|
|
|
|
|
|
|
|
std::time_t start_time = std::time(nullptr);
|
|
|
|
|
|
|
|
|
|
while(wrem)
|
|
|
|
|
{
|
|
|
|
|
int next_write = std::min(1024, wrem);
|
|
|
|
|
DEBUG_ERROR("wrem = %d", wrem);
|
|
|
|
|
n = zts_write(sockfd, &txbuf[w], next_write);
|
2017-05-01 17:44:45 -07:00
|
|
|
if (n > 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
{
|
2017-05-01 17:44:45 -07:00
|
|
|
w += n;
|
2017-06-22 18:22:39 -07:00
|
|
|
wrem -= n;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while(rrem)
|
|
|
|
|
{
|
|
|
|
|
int next_read = std::min(1024, rrem);
|
|
|
|
|
DEBUG_ERROR("rrem = %d", rrem);
|
|
|
|
|
n = zts_read(sockfd, &rxbuf[r], next_read);
|
2017-05-01 17:44:45 -07:00
|
|
|
if (n > 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
{
|
2017-05-01 17:44:45 -07:00
|
|
|
r += n;
|
2017-06-22 18:22:39 -07:00
|
|
|
rrem -= n;
|
|
|
|
|
}
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
2017-06-22 18:22:39 -07:00
|
|
|
|
|
|
|
|
std::time_t end_time = std::time(nullptr);
|
|
|
|
|
time_t ts_delta = end_time - start_time;
|
|
|
|
|
|
2017-05-01 17:44:45 -07:00
|
|
|
err = zts_close(sockfd);
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("calculating checksum after transfer (rxbuf)...");
|
|
|
|
|
for(int i=0; i<count; i++) {
|
|
|
|
|
rx_checksum+=rxbuf[i];
|
|
|
|
|
}
|
|
|
|
|
for(int i=0; i<count; i++) {
|
|
|
|
|
tx_checksum+=txbuf[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sprintf(details, "tx_checksum=%x, rx_checksum=%x, count=%d, dt=%d, r=%d, w=%d", tx_checksum, rx_checksum, count, ts_delta, r, w);
|
2017-06-16 16:58:30 -07:00
|
|
|
*passed = (r == tot && w == tot && !err);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
2017-06-22 18:22:39 -07:00
|
|
|
fprintf(stderr, "%s\n", details);
|
|
|
|
|
exit(0);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
// Maintain transfer for count OR count
|
2017-06-16 16:58:30 -07:00
|
|
|
void tcp_client_sustained_6(UNIT_TEST_SIG_6)
|
2017-05-01 17:44:45 -07:00
|
|
|
{
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("\n");
|
2017-06-16 16:58:30 -07:00
|
|
|
int tot=0, n=0, w=0, r=0, sockfd, err, len = strlen(str);
|
2017-05-01 17:44:45 -07:00
|
|
|
char rbuf[STR_SIZE];
|
2017-06-16 16:58:30 -07:00
|
|
|
if((sockfd = zts_socket(AF_INET6, SOCK_STREAM, 0)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error creating ZeroTier socket");
|
2017-06-16 16:58:30 -07:00
|
|
|
if((err = zts_connect(sockfd, (const struct sockaddr *)addr, sizeof(addr))) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error connecting to remote host (%d)", err);
|
2017-05-01 17:44:45 -07:00
|
|
|
//zts_fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
|
|
|
|
if(operation == TEST_OP_N_TIMES) {
|
2017-06-16 16:58:30 -07:00
|
|
|
std::time_t start_time = std::time(nullptr);
|
2017-06-22 18:22:39 -07:00
|
|
|
tot = len*count;
|
|
|
|
|
for(int i=0; i<count; i++) {
|
2017-06-16 16:58:30 -07:00
|
|
|
//usleep(delay * 1000);
|
2017-05-01 17:44:45 -07:00
|
|
|
n = zts_write(sockfd, str, len);
|
|
|
|
|
if (n > 0)
|
|
|
|
|
w += n;
|
|
|
|
|
n = zts_read(sockfd, rbuf, len);
|
|
|
|
|
if (n > 0)
|
|
|
|
|
r += n;
|
|
|
|
|
}
|
2017-06-16 16:58:30 -07:00
|
|
|
std::time_t end_time = std::time(nullptr);
|
2017-05-01 17:44:45 -07:00
|
|
|
err = zts_close(sockfd);
|
2017-06-16 16:58:30 -07:00
|
|
|
time_t ts_delta = end_time - start_time;
|
2017-06-22 18:22:39 -07:00
|
|
|
sprintf(details, "count=%d, ts_delta=%d, r=%d, w=%d", count, ts_delta, r, w);
|
2017-06-16 16:58:30 -07:00
|
|
|
*passed = (r == tot && w == tot && !err) && !strcmp(rbuf, str);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
if(operation == TEST_OP_N_BYTES) {
|
2017-06-22 18:22:39 -07:00
|
|
|
tot = count;
|
2017-05-01 17:44:45 -07:00
|
|
|
while(r < tot || w < tot) {
|
2017-06-16 16:58:30 -07:00
|
|
|
//usleep(delay * 1000);
|
2017-05-01 17:44:45 -07:00
|
|
|
if (w < tot)
|
2017-06-22 18:22:39 -07:00
|
|
|
n = zts_write(sockfd, str, count);
|
2017-05-01 17:44:45 -07:00
|
|
|
if (n > 0)
|
|
|
|
|
w += n;
|
|
|
|
|
if (r < tot)
|
2017-06-22 18:22:39 -07:00
|
|
|
n = zts_read(sockfd, rbuf, count);
|
2017-05-01 17:44:45 -07:00
|
|
|
if (n > 0)
|
|
|
|
|
r += n;
|
|
|
|
|
}
|
|
|
|
|
err = zts_close(sockfd);
|
2017-06-22 18:22:39 -07:00
|
|
|
sprintf(details, "count=%d\n", count);
|
2017-06-16 16:58:30 -07:00
|
|
|
*passed = (r == tot && w == tot && !err);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
// Maintain transfer for count OR count
|
2017-06-16 16:58:30 -07:00
|
|
|
void tcp_server_sustained_4(UNIT_TEST_SIG_4)
|
2017-05-01 17:44:45 -07:00
|
|
|
{
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("\n");
|
2017-06-16 16:58:30 -07:00
|
|
|
int tot=0, n=0, w=0, r=0, sockfd, accfd, err, len = strlen(str);
|
2017-06-22 18:22:39 -07:00
|
|
|
|
|
|
|
|
char *rxbuf;
|
|
|
|
|
rxbuf = (char*)malloc(count*sizeof(char));
|
|
|
|
|
memset(rxbuf, 0, count);
|
|
|
|
|
|
|
|
|
|
char *txbuf;
|
|
|
|
|
txbuf = (char*)malloc(count*sizeof(char));
|
|
|
|
|
memset(txbuf, 0, count);
|
|
|
|
|
|
|
|
|
|
long int rx_checksum = 0;
|
|
|
|
|
long int tx_checksum = 0;
|
|
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
if((sockfd = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error creating ZeroTier socket");
|
2017-06-16 16:58:30 -07:00
|
|
|
if((err = zts_bind(sockfd, (struct sockaddr *)addr, (socklen_t)sizeof(struct sockaddr_in)) < 0))
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error binding to interface (%d)", err);
|
2017-06-16 16:58:30 -07:00
|
|
|
if((err = zts_listen(sockfd, 1)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error placing socket in LISTENING state (%d)", err);
|
2017-06-16 16:58:30 -07:00
|
|
|
if((accfd = zts_accept(sockfd, (struct sockaddr *)&addr, (socklen_t *)sizeof(addr))) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error accepting connection (%d)", err);
|
2017-05-01 17:44:45 -07:00
|
|
|
//zts_fcntl(accfd, F_SETFL, O_NONBLOCK);
|
|
|
|
|
if(operation == TEST_OP_N_TIMES) {
|
2017-06-22 18:22:39 -07:00
|
|
|
tot = len*count;
|
2017-06-16 16:58:30 -07:00
|
|
|
std::time_t start_time = std::time(nullptr);
|
2017-06-22 18:22:39 -07:00
|
|
|
for(int i=0; i<count; i++) {
|
2017-06-16 16:58:30 -07:00
|
|
|
//usleep(delay * 1000);
|
2017-06-22 18:22:39 -07:00
|
|
|
r += zts_read(accfd, rxbuf, len);
|
|
|
|
|
w += zts_write(accfd, txbuf, len);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
2017-06-16 16:58:30 -07:00
|
|
|
std::time_t end_time = std::time(nullptr);
|
2017-05-01 17:44:45 -07:00
|
|
|
zts_close(sockfd);
|
|
|
|
|
zts_close(accfd);
|
2017-06-16 16:58:30 -07:00
|
|
|
time_t ts_delta = end_time - start_time;
|
2017-06-22 18:22:39 -07:00
|
|
|
sprintf(details, "count=%d, ts_delta=%d, r=%d, w=%d", count, ts_delta, r, w);
|
|
|
|
|
*passed = (r == tot && w == tot && !err) && !strcmp(rxbuf, txbuf);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
if(operation == TEST_OP_N_BYTES) {
|
2017-06-22 18:22:39 -07:00
|
|
|
|
|
|
|
|
int wrem = count;
|
|
|
|
|
int rrem = count;
|
|
|
|
|
|
|
|
|
|
std::time_t start_time = std::time(nullptr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//zts_fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while(rrem)
|
|
|
|
|
{
|
|
|
|
|
int next_read = std::min(1024, rrem);
|
|
|
|
|
DEBUG_ERROR("rrem = %d", rrem);
|
|
|
|
|
n = zts_read(accfd, &rxbuf[r], next_read);
|
2017-05-01 17:44:45 -07:00
|
|
|
if (n > 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
{
|
2017-05-01 17:44:45 -07:00
|
|
|
r += n;
|
2017-06-22 18:22:39 -07:00
|
|
|
rrem -= n;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while(wrem)
|
|
|
|
|
{
|
|
|
|
|
int next_write = std::min(1024, wrem);
|
|
|
|
|
DEBUG_ERROR("wrem = %d", wrem);
|
|
|
|
|
n = zts_write(accfd, &txbuf[w], next_write);
|
2017-05-01 17:44:45 -07:00
|
|
|
if (n > 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
{
|
2017-05-01 17:44:45 -07:00
|
|
|
w += n;
|
2017-06-22 18:22:39 -07:00
|
|
|
wrem -= n;
|
|
|
|
|
}
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
2017-06-22 18:22:39 -07:00
|
|
|
|
|
|
|
|
std::time_t end_time = std::time(nullptr);
|
|
|
|
|
time_t ts_delta = end_time - start_time;
|
|
|
|
|
|
|
|
|
|
err = zts_close(sockfd);
|
|
|
|
|
DEBUG_TEST("calculating checksum after transfer (rxbuf)...");
|
|
|
|
|
for(int i=0; i<count; i++) {
|
|
|
|
|
rx_checksum+=rxbuf[i];
|
|
|
|
|
fprintf(stderr, " %d", rxbuf[i]);
|
|
|
|
|
}
|
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
|
|
|
|
|
|
sprintf(details, "tx_checksum=%x, rx_checksum=%x, count=%d, dt=%d, r=%d, w=%d", tx_checksum, rx_checksum, count, ts_delta, r, w);
|
2017-06-16 16:58:30 -07:00
|
|
|
*passed = (r == tot && w == tot && !err);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
2017-06-22 18:22:39 -07:00
|
|
|
fprintf(stderr, "%s\n", details);
|
|
|
|
|
exit(0);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
// Maintain transfer for count OR count
|
2017-06-16 16:58:30 -07:00
|
|
|
void tcp_server_sustained_6(UNIT_TEST_SIG_6)
|
2017-05-01 17:44:45 -07:00
|
|
|
{
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("\n");
|
2017-06-16 16:58:30 -07:00
|
|
|
int tot=0, n=0, w=0, r=0, sockfd, accfd, err, len = strlen(str);
|
2017-05-01 17:44:45 -07:00
|
|
|
char rbuf[STR_SIZE];
|
2017-06-16 16:58:30 -07:00
|
|
|
if((sockfd = zts_socket(AF_INET6, SOCK_STREAM, 0)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error creating ZeroTier socket");
|
2017-06-16 16:58:30 -07:00
|
|
|
if((err = zts_bind(sockfd, (struct sockaddr *)addr, (socklen_t)sizeof(struct sockaddr_in)) < 0))
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error binding to interface (%d)", err);
|
2017-06-16 16:58:30 -07:00
|
|
|
if((err = zts_listen(sockfd, 1)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error placing socket in LISTENING state (%d)", err);
|
2017-06-16 16:58:30 -07:00
|
|
|
if((accfd = zts_accept(sockfd, (struct sockaddr *)&addr, (socklen_t *)sizeof(addr))) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error accepting connection (%d)", err);
|
2017-05-01 17:44:45 -07:00
|
|
|
//zts_fcntl(accfd, F_SETFL, O_NONBLOCK);
|
|
|
|
|
if(operation == TEST_OP_N_TIMES) {
|
2017-06-22 18:22:39 -07:00
|
|
|
tot = len*count;
|
2017-06-16 16:58:30 -07:00
|
|
|
std::time_t start_time = std::time(nullptr);
|
2017-06-22 18:22:39 -07:00
|
|
|
for(int i=0; i<count; i++) {
|
2017-05-01 17:44:45 -07:00
|
|
|
usleep(delay * 1000);
|
|
|
|
|
r += zts_read(accfd, rbuf, len);
|
|
|
|
|
w += zts_write(accfd, rbuf, len);
|
|
|
|
|
}
|
2017-06-16 16:58:30 -07:00
|
|
|
std::time_t end_time = std::time(nullptr);
|
2017-05-01 17:44:45 -07:00
|
|
|
zts_close(sockfd);
|
|
|
|
|
zts_close(accfd);
|
2017-06-16 16:58:30 -07:00
|
|
|
time_t ts_delta = end_time - start_time;
|
2017-06-22 18:22:39 -07:00
|
|
|
sprintf(details, "count=%d, ts_delta=%d, r=%d, w=%d", count, ts_delta, r, w);
|
2017-06-16 16:58:30 -07:00
|
|
|
*passed = (r == tot && w == tot && !err) && !strcmp(rbuf, str);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
if(operation == TEST_OP_N_BYTES) {
|
2017-06-22 18:22:39 -07:00
|
|
|
tot = count;
|
2017-05-01 17:44:45 -07:00
|
|
|
while(r < tot || w < tot) {
|
|
|
|
|
usleep(delay * 1000);
|
|
|
|
|
if (r < tot)
|
2017-06-22 18:22:39 -07:00
|
|
|
n = zts_read(accfd, rbuf, count);
|
2017-05-01 17:44:45 -07:00
|
|
|
if (n > 0)
|
|
|
|
|
r += n;
|
|
|
|
|
if (w < tot)
|
2017-06-22 18:22:39 -07:00
|
|
|
n = zts_write(accfd, str, count);
|
2017-05-01 17:44:45 -07:00
|
|
|
if (n > 0)
|
|
|
|
|
w += n;
|
|
|
|
|
}
|
|
|
|
|
zts_close(sockfd);
|
|
|
|
|
zts_close(accfd);
|
2017-06-22 18:22:39 -07:00
|
|
|
sprintf(details, "count=%d", count);
|
2017-06-16 16:58:30 -07:00
|
|
|
*passed = (r == tot && w == tot && !err);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
2017-06-16 16:58:30 -07:00
|
|
|
}
|
2017-05-01 17:44:45 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
/****************************************************************************/
|
|
|
|
|
/* PERFORMANCE (between library instances) */
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
// Maintain transfer for count OR count
|
2017-06-16 16:58:30 -07:00
|
|
|
void tcp_client_perf_4(UNIT_TEST_SIG_4)
|
|
|
|
|
{
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("\n");
|
2017-06-16 16:58:30 -07:00
|
|
|
int w=0, sockfd, err;
|
2017-06-22 18:22:39 -07:00
|
|
|
int total_test_sz = count;
|
|
|
|
|
int arbitrary_chunk_sz_max = MAX_RX_BUF_SZ;
|
2017-06-16 16:58:30 -07:00
|
|
|
int arbitrary_chunk_sz_min = 512;
|
|
|
|
|
|
|
|
|
|
char rbuf[arbitrary_chunk_sz_max];
|
|
|
|
|
|
|
|
|
|
for (int i=arbitrary_chunk_sz_min; (i*2) < arbitrary_chunk_sz_max; i*=2) {
|
|
|
|
|
|
|
|
|
|
if((sockfd = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
|
|
|
|
DEBUG_ERROR("error creating ZeroTier socket");
|
|
|
|
|
if((err = zts_connect(sockfd, (const struct sockaddr *)addr, sizeof(addr))) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error connecting to remote host (%d)", err);
|
2017-06-16 16:58:30 -07:00
|
|
|
|
|
|
|
|
DEBUG_TEST("[TX] Testing (%d) byte chunks: ", i);
|
|
|
|
|
|
|
|
|
|
int chunk_sz = i;
|
|
|
|
|
long int start_time = get_now_ts();
|
|
|
|
|
w = 0;
|
2017-06-22 18:22:39 -07:00
|
|
|
|
|
|
|
|
// TX
|
2017-06-16 16:58:30 -07:00
|
|
|
while(w < total_test_sz)
|
|
|
|
|
w += zts_write(sockfd, rbuf, chunk_sz);
|
2017-06-22 18:22:39 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
long int end_time = get_now_ts();
|
|
|
|
|
float ts_delta = (end_time - start_time) / (float)1000;
|
|
|
|
|
float rate = (float)total_test_sz / (float)ts_delta;
|
2017-06-22 18:22:39 -07:00
|
|
|
sprintf(details, "tot=%d, dt=%.2f, rate=%.2f MB/s", w, ts_delta, (rate / float(ONE_MEGABYTE) ));
|
2017-06-16 16:58:30 -07:00
|
|
|
zts_close(sockfd);
|
|
|
|
|
}
|
|
|
|
|
*passed = (w == total_test_sz && !err) ? PASSED : FAILED;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
// Maintain transfer for count OR count
|
2017-06-16 16:58:30 -07:00
|
|
|
void tcp_server_perf_4(UNIT_TEST_SIG_4)
|
|
|
|
|
{
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("\n");
|
2017-06-16 16:58:30 -07:00
|
|
|
int r=0, sockfd, accfd, err;
|
2017-06-22 18:22:39 -07:00
|
|
|
int total_test_sz = count;
|
|
|
|
|
int arbitrary_chunk_sz_max = MAX_RX_BUF_SZ;
|
2017-06-16 16:58:30 -07:00
|
|
|
int arbitrary_chunk_sz_min = 512;
|
|
|
|
|
|
|
|
|
|
char rbuf[arbitrary_chunk_sz_max];
|
|
|
|
|
|
|
|
|
|
for (int i=arbitrary_chunk_sz_min; (i*2) < arbitrary_chunk_sz_max; i*=2) {
|
|
|
|
|
if((sockfd = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
|
|
|
|
DEBUG_ERROR("error creating ZeroTier socket");
|
|
|
|
|
if((err = zts_bind(sockfd, (struct sockaddr *)addr, (socklen_t)sizeof(struct sockaddr_in)) < 0))
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error binding to interface (%d)", err);
|
2017-06-16 16:58:30 -07:00
|
|
|
if((err = zts_listen(sockfd, 1)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error placing socket in LISTENING state (%d)", err);
|
2017-06-16 16:58:30 -07:00
|
|
|
if((accfd = zts_accept(sockfd, (struct sockaddr *)&addr, (socklen_t *)sizeof(addr))) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_ERROR("error accepting connection (%d)", err);
|
2017-06-16 16:58:30 -07:00
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("[RX] Testing (%d) byte chunks: ", i);
|
2017-06-16 16:58:30 -07:00
|
|
|
|
|
|
|
|
int chunk_sz = i;
|
|
|
|
|
long int start_time = get_now_ts();
|
|
|
|
|
r = 0;
|
2017-06-22 18:22:39 -07:00
|
|
|
|
|
|
|
|
// RX
|
2017-06-16 16:58:30 -07:00
|
|
|
while(r < total_test_sz)
|
|
|
|
|
r += zts_read(accfd, rbuf, chunk_sz);
|
2017-06-22 18:22:39 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
long int end_time = get_now_ts();
|
|
|
|
|
|
|
|
|
|
float ts_delta = (end_time - start_time) / (float)1000;
|
|
|
|
|
float rate = (float)total_test_sz / (float)ts_delta;
|
2017-06-22 18:22:39 -07:00
|
|
|
|
|
|
|
|
sprintf(details, "tot=%d, dt=%.2f, rate=%.2f MB/s", r, ts_delta, (rate / float(ONE_MEGABYTE) ));
|
2017-06-16 16:58:30 -07:00
|
|
|
|
|
|
|
|
zts_close(sockfd);
|
|
|
|
|
zts_close(accfd);
|
|
|
|
|
}
|
|
|
|
|
*passed = (r == total_test_sz && !err) ? PASSED : FAILED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
/* PERFORMANCE (between library and native) */
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
void tcp_perf_tx_echo_4(UNIT_TEST_SIG_4)
|
2017-06-16 16:58:30 -07:00
|
|
|
{
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("\n");
|
2017-06-16 16:58:30 -07:00
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
int err = 0;
|
|
|
|
|
int tot = 0;
|
|
|
|
|
int w = 0;
|
|
|
|
|
int sockfd, mode;
|
2017-06-16 16:58:30 -07:00
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
char pbuf[64]; // test parameter buffer
|
|
|
|
|
char tbuf[MAX_TX_BUF_SZ];
|
2017-06-16 16:58:30 -07:00
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
mode = ECHOTEST_MODE_TX;
|
2017-06-16 16:58:30 -07:00
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
// connect to remote echotest host
|
|
|
|
|
if((sockfd = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
|
|
|
|
DEBUG_ERROR("error creating ZeroTier socket");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if((err = zts_connect(sockfd, (const struct sockaddr *)addr, sizeof(addr))) < 0) {
|
|
|
|
|
DEBUG_ERROR("error connecting to remote host (%d)", err);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-06-16 16:58:30 -07:00
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("copying test parameters to buffer");
|
|
|
|
|
memset(pbuf, 0, sizeof pbuf);
|
|
|
|
|
memcpy(pbuf, &mode, sizeof mode);
|
|
|
|
|
memcpy(pbuf + sizeof mode, &count, sizeof count);
|
2017-06-16 16:58:30 -07:00
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
DEBUG_TEST("sending test parameters to echotest");
|
|
|
|
|
if((w = zts_write(sockfd, pbuf, sizeof pbuf)) < 0) {
|
|
|
|
|
DEBUG_ERROR("error while sending test parameters to echotest (err=%d)", w);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-06-16 16:58:30 -07:00
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
// begin
|
|
|
|
|
DEBUG_TEST("beginning test, sending test byte stream...");
|
|
|
|
|
while(tot < count) {
|
|
|
|
|
if((w = zts_write(sockfd, tbuf, sizeof tbuf)) < 0) {
|
|
|
|
|
DEBUG_ERROR("error while sending test byte stream to echotest (err=%d)", w);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
tot += w;
|
|
|
|
|
//DEBUG_TEST("tot=%d, sent=%d", tot, w);
|
|
|
|
|
}
|
|
|
|
|
// read results
|
|
|
|
|
memset(pbuf, 0, sizeof pbuf);
|
|
|
|
|
DEBUG_TEST("reading test results from echotest");
|
|
|
|
|
if((w = zts_read(sockfd, pbuf, sizeof tbuf)) < 0) {
|
|
|
|
|
DEBUG_ERROR("error while reading results from echotest (err=%d)", w);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEBUG_TEST("reading test results");
|
|
|
|
|
long int start_time = 0, end_time = 0;
|
|
|
|
|
memcpy(&start_time, pbuf, sizeof start_time);
|
|
|
|
|
memcpy(&end_time, pbuf + sizeof start_time, sizeof end_time);
|
|
|
|
|
|
|
|
|
|
float ts_delta = (end_time - start_time) / (float)1000;
|
|
|
|
|
float rate = (float)tot / (float)ts_delta;
|
|
|
|
|
sprintf(details, "tot=%d, dt=%.2f, rate=%.2f MB/s", tot, ts_delta, (rate / float(ONE_MEGABYTE) ));
|
|
|
|
|
|
|
|
|
|
*passed = (tot == count && !err) ? PASSED : FAILED;
|
2017-06-16 16:58:30 -07:00
|
|
|
}
|
2017-06-22 18:22:39 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
void tcp_perf_rx_echo_4(UNIT_TEST_SIG_4)
|
|
|
|
|
{
|
|
|
|
|
DEBUG_TEST("\n");
|
|
|
|
|
|
|
|
|
|
int err = 0;
|
|
|
|
|
int mode = 0;
|
|
|
|
|
int tot = 0;
|
|
|
|
|
int r = 0;
|
|
|
|
|
|
|
|
|
|
char pbuf[64]; // test parameter buffer
|
|
|
|
|
char tbuf[MAX_TX_BUF_SZ];
|
|
|
|
|
int sockfd;
|
|
|
|
|
|
|
|
|
|
mode = ECHOTEST_MODE_RX;
|
|
|
|
|
|
|
|
|
|
// connect to remote echotest host
|
|
|
|
|
if((sockfd = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
|
|
|
|
DEBUG_ERROR("error creating ZeroTier socket");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if((err = zts_connect(sockfd, (const struct sockaddr *)addr, sizeof(addr))) < 0) {
|
|
|
|
|
DEBUG_ERROR("error connecting to remote host (%d)", err);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEBUG_TEST("copying test parameters to buffer");
|
|
|
|
|
memset(pbuf, 0, sizeof pbuf);
|
|
|
|
|
memcpy(pbuf, &mode, sizeof mode);
|
|
|
|
|
memcpy(pbuf + sizeof mode, &count, sizeof count);
|
|
|
|
|
|
|
|
|
|
DEBUG_TEST("sending test parameters to echotest");
|
|
|
|
|
if((r = zts_write(sockfd, pbuf, sizeof pbuf)) < 0) {
|
|
|
|
|
DEBUG_ERROR("error while sending test parameters to echotest (err=%d)", r);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// begin
|
|
|
|
|
DEBUG_TEST("beginning test, as soon as bytes are read we will start keeping time...");
|
|
|
|
|
if((r = read(sockfd, tbuf, sizeof tbuf)) < 0) {
|
|
|
|
|
DEBUG_ERROR("there was an error reading the test stream. aborting (err=%d, errno=%s)", r, strerror(errno));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tot += r;
|
|
|
|
|
|
|
|
|
|
long int start_time = get_now_ts();
|
|
|
|
|
DEBUG_TEST("Received first set of bytes in test stream. now keeping time");
|
|
|
|
|
|
|
|
|
|
while(tot < count) {
|
|
|
|
|
if((r = read(sockfd, tbuf, sizeof tbuf)) < 0) {
|
|
|
|
|
DEBUG_ERROR("there was an error reading the test stream. aborting (err=%d)", r);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
tot += r;
|
|
|
|
|
//DEBUG_TEST("r=%d, tot=%d", r, tot);
|
|
|
|
|
}
|
|
|
|
|
long int end_time = get_now_ts();
|
|
|
|
|
float ts_delta = (end_time - start_time) / (float)1000;
|
|
|
|
|
float rate = (float)tot / (float)ts_delta;
|
|
|
|
|
sprintf(details, "tot=%d, dt=%.2f, rate=%.2f MB/s", tot, ts_delta, (rate / float(ONE_MEGABYTE) ));
|
|
|
|
|
|
|
|
|
|
*passed = (tot == count && !err) ? PASSED : FAILED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-05-01 17:44:45 -07:00
|
|
|
|
|
|
|
|
|
2017-05-05 16:46:07 -07:00
|
|
|
/****************************************************************************/
|
|
|
|
|
/* SLAM API (multiple of each api call and/or plausible call sequence) */
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#define SLAM_NUMBER 16
|
|
|
|
|
#define SLAM_REPEAT 1
|
|
|
|
|
|
|
|
|
|
int slam_api_test()
|
|
|
|
|
{
|
|
|
|
|
int err = 0;
|
2017-05-30 13:17:39 -07:00
|
|
|
int results[SLAM_NUMBER*SLAM_REPEAT];
|
2017-05-05 16:46:07 -07:00
|
|
|
|
|
|
|
|
struct hostent *server;
|
|
|
|
|
struct sockaddr_in6 addr6;
|
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
// int start_stack_timer_count = pico_ntimers(); // number of picoTCP timers allocated
|
2017-05-30 13:17:39 -07:00
|
|
|
|
2017-05-05 16:46:07 -07:00
|
|
|
// TESTS:
|
|
|
|
|
// socket()
|
|
|
|
|
// close()
|
|
|
|
|
if(false)
|
|
|
|
|
{
|
|
|
|
|
// open and close SLAM_NUMBER*SLAM_REPEAT sockets
|
|
|
|
|
for(int j=0; j<SLAM_REPEAT; j++) {
|
|
|
|
|
std::cout << "slamming " << j << " time(s)" << std::endl;
|
|
|
|
|
usleep(SLAM_INTERVAL);
|
|
|
|
|
// create sockets
|
|
|
|
|
int fds[SLAM_NUMBER];
|
|
|
|
|
for(int i = 0; i<SLAM_NUMBER; i++) {
|
|
|
|
|
if((err = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
2017-06-22 18:22:39 -07:00
|
|
|
std::cout << "error creating socket (errno = " << strerror(errno) << ")" << std::endl;
|
2017-05-05 16:46:07 -07:00
|
|
|
if(errno == EMFILE)
|
|
|
|
|
break;
|
|
|
|
|
else
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
fds[i] = err;
|
|
|
|
|
std::cout << "\tcreating " << i << " socket(s) fd = " << err << std::endl;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
// close sockets
|
|
|
|
|
for(int i = 0; i<SLAM_NUMBER; i++) {
|
|
|
|
|
//std::cout << "\tclosing " << i << " socket(s)" << std::endl;
|
|
|
|
|
if((err = zts_close(fds[i])) < 0) {
|
2017-06-22 18:22:39 -07:00
|
|
|
std::cout << "error closing socket (errno = " << strerror(errno) << ")" << std::endl;
|
2017-05-05 16:46:07 -07:00
|
|
|
//return -1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
fds[i] = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(zts_nsockets() == 0)
|
|
|
|
|
std::cout << "PASSED [slam open and close]" << std::endl;
|
|
|
|
|
else
|
|
|
|
|
std::cout << "FAILED [slam open and close] - sockets left unclosed" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---
|
|
|
|
|
|
|
|
|
|
// TESTS:
|
|
|
|
|
// socket()
|
|
|
|
|
// bind()
|
|
|
|
|
// listen()
|
|
|
|
|
// accept()
|
|
|
|
|
// close()
|
|
|
|
|
if(false)
|
|
|
|
|
{
|
|
|
|
|
int sock = 0;
|
|
|
|
|
std::vector<int> used_ports;
|
|
|
|
|
|
|
|
|
|
for(int j=0; j<SLAM_REPEAT; j++) {
|
|
|
|
|
std::cout << "slamming " << j << " time(s)" << std::endl;
|
|
|
|
|
usleep(SLAM_INTERVAL);
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i<SLAM_NUMBER; i++) {
|
|
|
|
|
if((sock = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
2017-06-22 18:22:39 -07:00
|
|
|
std::cout << "error creating socket (errno = " << strerror(errno) << ")" << std::endl;
|
2017-05-05 16:46:07 -07:00
|
|
|
if(errno == EMFILE)
|
|
|
|
|
break;
|
|
|
|
|
else
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
std::cout << "socket() = " << sock << std::endl;
|
|
|
|
|
usleep(SLAM_INTERVAL);
|
|
|
|
|
|
|
|
|
|
int port;
|
|
|
|
|
while(!(std::find(used_ports.begin(),used_ports.end(),port) == used_ports.end())) {
|
|
|
|
|
port = MIN_PORT + (rand() % (int)(MAX_PORT - MIN_PORT + 1));
|
|
|
|
|
}
|
|
|
|
|
used_ports.push_back(port);
|
|
|
|
|
std::cout << "port = " << port << std::endl;
|
|
|
|
|
|
|
|
|
|
if(false) {
|
|
|
|
|
server = gethostbyname2("::",AF_INET6);
|
|
|
|
|
memset((char *) &addr6, 0, sizeof(addr6));
|
|
|
|
|
addr6.sin6_flowinfo = 0;
|
|
|
|
|
addr6.sin6_family = AF_INET6;
|
|
|
|
|
addr6.sin6_port = htons(port);
|
|
|
|
|
addr6.sin6_addr = in6addr_any;
|
|
|
|
|
err = zts_bind(sock, (struct sockaddr *)&addr6, (socklen_t)(sizeof addr6));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(true) {
|
|
|
|
|
addr.sin_port = htons(port);
|
|
|
|
|
addr.sin_addr.s_addr = inet_addr("10.9.9.50");
|
|
|
|
|
//addr.sin_addr.s_addr = htons(INADDR_ANY);
|
|
|
|
|
addr.sin_family = AF_INET;
|
|
|
|
|
err = zts_bind(sock, (struct sockaddr *)&addr, (socklen_t)(sizeof addr));
|
|
|
|
|
}
|
|
|
|
|
if(err < 0) {
|
2017-06-22 18:22:39 -07:00
|
|
|
std::cout << "error binding socket (errno = " << strerror(errno) << ")" << std::endl;
|
2017-05-05 16:46:07 -07:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(sock > 0) {
|
|
|
|
|
if((err = zts_close(sock)) < 0) {
|
2017-06-22 18:22:39 -07:00
|
|
|
std::cout << "error closing socket (errno = " << strerror(errno) << ")" << std::endl;
|
2017-05-05 16:46:07 -07:00
|
|
|
//return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
used_ports.clear();
|
|
|
|
|
if(zts_nsockets() == 0)
|
|
|
|
|
std::cout << "PASSED [slam open, bind, listen, accept, close]" << std::endl;
|
|
|
|
|
else
|
|
|
|
|
std::cout << "FAILED [slam open, bind, listen, accept, close]" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TESTS:
|
|
|
|
|
// (1) socket()
|
|
|
|
|
// (2) connect()
|
|
|
|
|
// (3) close()
|
2017-05-30 13:17:39 -07:00
|
|
|
int num_times = zts_maxsockets();
|
|
|
|
|
std::cout << "socket/connect/close - " << num_times << " times" << std::endl;
|
|
|
|
|
for(int i=0;i<(SLAM_NUMBER*SLAM_REPEAT); i++) { results[i] = 0; }
|
2017-05-05 16:46:07 -07:00
|
|
|
if(true)
|
|
|
|
|
{
|
2017-05-30 13:17:39 -07:00
|
|
|
int port = 4545;
|
|
|
|
|
|
2017-05-05 16:46:07 -07:00
|
|
|
// open, bind, listen, accept, close
|
2017-05-30 13:17:39 -07:00
|
|
|
for(int j=0; j<num_times; j++) {
|
|
|
|
|
int sock = 0;
|
|
|
|
|
errno = 0;
|
2017-05-05 16:46:07 -07:00
|
|
|
|
2017-05-30 13:17:39 -07:00
|
|
|
usleep(SLAM_INTERVAL);
|
2017-05-05 16:46:07 -07:00
|
|
|
|
2017-05-30 13:17:39 -07:00
|
|
|
// socket()
|
|
|
|
|
printf("creating socket... (%d)\n", j);
|
|
|
|
|
if((sock = zts_socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
std::cout << "error creating socket (errno = " << strerror(errno) << ")" << std::endl;
|
2017-05-30 13:17:39 -07:00
|
|
|
results[j] = std::min(results[j], sock);
|
|
|
|
|
|
|
|
|
|
// set O_NONBLOCK
|
|
|
|
|
if((err = zts_fcntl(sock, F_SETFL, O_NONBLOCK) < 0))
|
2017-06-22 18:22:39 -07:00
|
|
|
std::cout << "error setting O_NONBLOCK (errno=" << strerror(errno) << ")" << std::endl;
|
2017-05-30 13:17:39 -07:00
|
|
|
results[j] = std::min(results[j], err);
|
|
|
|
|
|
|
|
|
|
// connect()
|
|
|
|
|
if(false) {
|
|
|
|
|
server = gethostbyname2("::",AF_INET6);
|
|
|
|
|
memset((char *) &addr6, 0, sizeof(addr6));
|
|
|
|
|
addr6.sin6_flowinfo = 0;
|
|
|
|
|
addr6.sin6_family = AF_INET6;
|
|
|
|
|
addr6.sin6_port = htons(port);
|
|
|
|
|
addr6.sin6_addr = in6addr_any;
|
|
|
|
|
err = zts_connect(sock, (struct sockaddr *)&addr6, (socklen_t)(sizeof addr6));
|
|
|
|
|
}
|
|
|
|
|
if(true) {
|
|
|
|
|
addr.sin_port = htons(port);
|
|
|
|
|
addr.sin_addr.s_addr = inet_addr("10.9.9.51");
|
|
|
|
|
//addr.sin_addr.s_addr = htons(INADDR_ANY);
|
|
|
|
|
addr.sin_family = AF_INET;
|
|
|
|
|
err = zts_connect(sock, (struct sockaddr *)&addr, (socklen_t)(sizeof addr));
|
|
|
|
|
}
|
2017-05-05 16:46:07 -07:00
|
|
|
|
2017-05-30 13:17:39 -07:00
|
|
|
if(errno != EINPROGRESS) { // acceptable error for non-block mode
|
|
|
|
|
if(err < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
std::cout << "error connecting socket (errno = " << strerror(errno) << ")" << std::endl;
|
2017-05-30 13:17:39 -07:00
|
|
|
results[j] = std::min(results[j], err);
|
2017-05-05 16:46:07 -07:00
|
|
|
}
|
2017-05-30 13:17:39 -07:00
|
|
|
|
|
|
|
|
// close()
|
|
|
|
|
if((err = zts_close(sock)) < 0)
|
2017-06-22 18:22:39 -07:00
|
|
|
std::cout << "error closing socket (errno = " << strerror(errno) << ")" << std::endl;
|
2017-05-30 13:17:39 -07:00
|
|
|
results[j] = std::min(results[j], err);
|
2017-05-05 16:46:07 -07:00
|
|
|
}
|
2017-05-30 13:17:39 -07:00
|
|
|
|
|
|
|
|
displayResults(results, num_times);
|
2017-05-05 16:46:07 -07:00
|
|
|
if(zts_nsockets() == 0)
|
|
|
|
|
std::cout << "PASSED [slam open, connect, close]" << std::endl;
|
|
|
|
|
else
|
|
|
|
|
std::cout << "FAILED [slam open, connect, close]" << std::endl;
|
|
|
|
|
}
|
2017-06-05 14:26:06 -07:00
|
|
|
return 0;
|
2017-05-05 16:46:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-05-01 17:44:45 -07:00
|
|
|
/****************************************************************************/
|
|
|
|
|
/* RANDOMIZED API TEST */
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
|
|
|
|
|
int random_api_test()
|
|
|
|
|
{
|
2017-06-16 16:58:30 -07:00
|
|
|
/*
|
2017-05-01 17:44:45 -07:00
|
|
|
// PASSED implies we didn't segfault or hang anywhere
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
int calls_made = 0;
|
|
|
|
|
|
|
|
|
|
// how many calls we'll make
|
|
|
|
|
int num_of_api_calls = 10;
|
|
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
|
|
|
|
|
zts_socket()
|
|
|
|
|
zts_connect()
|
|
|
|
|
zts_listen()
|
|
|
|
|
zts_accept()
|
|
|
|
|
zts_bind()
|
|
|
|
|
zts_getsockopt()
|
|
|
|
|
zts_setsockopt()
|
|
|
|
|
zts_fnctl()
|
|
|
|
|
zts_close()
|
2017-05-01 17:44:45 -07:00
|
|
|
|
|
|
|
|
// variables which will be populated with random values
|
|
|
|
|
int fd, arg_val;
|
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
|
struct sockaddr_in6 addr6;
|
|
|
|
|
|
|
|
|
|
while(calls_made < num_of_api_calls)
|
|
|
|
|
{
|
2017-06-22 18:22:39 -07:00
|
|
|
fprintf(stderr, "calls_made=%d\n", calls_made);
|
2017-05-01 17:44:45 -07:00
|
|
|
int random_call = 0;
|
|
|
|
|
|
|
|
|
|
switch(random_call)
|
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
printf()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
calls_made++;
|
|
|
|
|
}
|
2017-06-16 16:58:30 -07:00
|
|
|
*/
|
2017-05-01 17:44:45 -07:00
|
|
|
return PASSED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
/* test driver, called from main() */
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
/*
|
2017-06-16 16:58:30 -07:00
|
|
|
path = place where ZT keys, and config files will be stored
|
|
|
|
|
nwid = network for app to join
|
|
|
|
|
type = simple, sustained
|
|
|
|
|
ipv = 4, 6
|
|
|
|
|
mode = client, server
|
|
|
|
|
addr = ip address string
|
|
|
|
|
port = integer
|
|
|
|
|
operation = n_times, n_seconds, n_bytes, etc
|
2017-06-22 18:22:39 -07:00
|
|
|
count = number of operations of type
|
2017-06-16 16:58:30 -07:00
|
|
|
delay = delay between each operation
|
2017-05-01 17:44:45 -07:00
|
|
|
*/
|
2017-06-16 16:58:30 -07:00
|
|
|
int test_driver(std::string name, std::string path, std::string nwid,
|
|
|
|
|
int type,
|
|
|
|
|
int ipv,
|
|
|
|
|
int mode,
|
|
|
|
|
std::string ipstr,
|
|
|
|
|
int port,
|
|
|
|
|
int operation,
|
2017-06-22 18:22:39 -07:00
|
|
|
int count,
|
2017-06-16 16:58:30 -07:00
|
|
|
int delay,
|
|
|
|
|
std::vector<std::string> *results)
|
2017-05-01 17:44:45 -07:00
|
|
|
{
|
|
|
|
|
struct hostent *server;
|
|
|
|
|
struct sockaddr_in6 addr6;
|
|
|
|
|
struct sockaddr_in addr;
|
2017-06-16 16:58:30 -07:00
|
|
|
char details[80];
|
|
|
|
|
char result_str[80];
|
|
|
|
|
memset(&details, 0, sizeof details);
|
|
|
|
|
bool passed = 0;
|
2017-06-22 18:22:39 -07:00
|
|
|
char *ok_str = (char*)"[ OK ]";
|
|
|
|
|
char *fail_str = (char*)"[ FAIL ]";
|
2017-06-16 16:58:30 -07:00
|
|
|
|
|
|
|
|
// Create sockadder_in objects for test calls
|
|
|
|
|
if(ipv == 4) {
|
|
|
|
|
addr.sin_port = htons(port);
|
|
|
|
|
addr.sin_addr.s_addr = inet_addr(ipstr.c_str());
|
|
|
|
|
addr.sin_family = AF_INET;
|
|
|
|
|
}
|
|
|
|
|
if(ipv == 6) {
|
|
|
|
|
server = gethostbyname2(ipstr.c_str(),AF_INET6);
|
|
|
|
|
memset((char *) &addr6, 0, sizeof(addr6));
|
|
|
|
|
addr6.sin6_flowinfo = 0;
|
|
|
|
|
addr6.sin6_family = AF_INET6;
|
|
|
|
|
memmove((char *) &addr6.sin6_addr.s6_addr, (char *) server->h_addr, server->h_length);
|
|
|
|
|
addr6.sin6_port = htons(port);
|
|
|
|
|
}
|
2017-05-01 17:44:45 -07:00
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
/* SIMPLE */
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
|
|
|
|
|
// performs a one-off test of a particular subset of the API
|
|
|
|
|
// For instance (ipv4 client, ipv6 server, etc)
|
|
|
|
|
if(type == TEST_TYPE_SIMPLE) {
|
|
|
|
|
if(mode == TEST_MODE_CLIENT) {
|
2017-06-16 16:58:30 -07:00
|
|
|
sprintf(result_str, "tcp_client_%d, %s : %d, ", ipv, ipstr.c_str(), port);
|
|
|
|
|
if(ipv == 4)
|
2017-06-22 18:22:39 -07:00
|
|
|
tcp_client_4(&addr, operation, count, delay, details, &passed);
|
2017-06-16 16:58:30 -07:00
|
|
|
if(ipv == 6)
|
2017-06-22 18:22:39 -07:00
|
|
|
tcp_client_6(&addr6, operation, count, delay, details, &passed);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(mode == TEST_MODE_SERVER) {
|
2017-06-16 16:58:30 -07:00
|
|
|
sprintf(result_str, "tcp_server_%d, %s : %d, ", ipv, ipstr.c_str(), port);
|
|
|
|
|
if(ipv == 4)
|
2017-06-22 18:22:39 -07:00
|
|
|
tcp_server_4(&addr, operation, count, delay, details, &passed);
|
2017-06-16 16:58:30 -07:00
|
|
|
if(ipv == 6)
|
2017-06-22 18:22:39 -07:00
|
|
|
tcp_server_6(&addr6, operation, count, delay, details, &passed);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
/* SUSTAINED */
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
|
|
|
|
|
// Performs a stress test for benchmarking performance
|
|
|
|
|
if(type == TEST_TYPE_SUSTAINED) {
|
|
|
|
|
if(mode == TEST_MODE_CLIENT) {
|
2017-06-16 16:58:30 -07:00
|
|
|
sprintf(result_str, "tcp_client_sustained_%d, %s : %d, ", ipv, ipstr.c_str(), port);
|
|
|
|
|
if(ipv == 4)
|
2017-06-22 18:22:39 -07:00
|
|
|
tcp_client_sustained_4(&addr, operation, count, delay, details, &passed);
|
2017-06-16 16:58:30 -07:00
|
|
|
if(ipv == 6)
|
2017-06-22 18:22:39 -07:00
|
|
|
tcp_client_sustained_6(&addr6, operation, count, delay, details, &passed);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(mode == TEST_MODE_SERVER)
|
|
|
|
|
{
|
2017-06-16 16:58:30 -07:00
|
|
|
sprintf(result_str, "tcp_server_sustained_%d, %s : %d, ", ipv, ipstr.c_str(), port);
|
|
|
|
|
if(ipv == 4)
|
2017-06-22 18:22:39 -07:00
|
|
|
tcp_server_sustained_4(&addr, operation, count, delay, details, &passed);
|
2017-06-16 16:58:30 -07:00
|
|
|
if(ipv == 6)
|
2017-06-22 18:22:39 -07:00
|
|
|
tcp_server_sustained_6(&addr6, operation, count, delay, details, &passed);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
}
|
2017-06-16 16:58:30 -07:00
|
|
|
//
|
|
|
|
|
if(type == TEST_TYPE_PERF) {
|
|
|
|
|
if(mode == TEST_MODE_CLIENT) {
|
|
|
|
|
sprintf(result_str, "tcp_client_perf_%d, %s : %d, ", ipv, ipstr.c_str(), port);
|
|
|
|
|
if(ipv == 4)
|
2017-06-22 18:22:39 -07:00
|
|
|
tcp_client_perf_4(&addr, operation, count, delay, details, &passed);
|
2017-06-16 16:58:30 -07:00
|
|
|
}
|
2017-06-11 20:24:11 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
if(mode == TEST_MODE_SERVER) {
|
|
|
|
|
sprintf(result_str, "tcp_server_perf_%d, %s : %d, ", ipv, ipstr.c_str(), port);
|
|
|
|
|
if(ipv == 4)
|
2017-06-22 18:22:39 -07:00
|
|
|
tcp_server_perf_4(&addr, operation, count, delay, details, &passed);
|
2017-06-16 16:58:30 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
if(type == TEST_TYPE_PERF_TO_ECHO) {
|
|
|
|
|
// Will only operate in client mode
|
|
|
|
|
if(mode == TEST_MODE_CLIENT) {
|
2017-06-22 18:22:39 -07:00
|
|
|
sprintf(result_str, "tcp_perf_tx_echo_%d, %s : %d, ", ipv, ipstr.c_str(), port);
|
2017-06-16 16:58:30 -07:00
|
|
|
if(ipv == 4)
|
2017-06-22 18:22:39 -07:00
|
|
|
tcp_perf_tx_echo_4(&addr, operation, count, delay, details, &passed);
|
|
|
|
|
}
|
|
|
|
|
if(mode == TEST_MODE_SERVER) {
|
|
|
|
|
sprintf(result_str, "tcp_perf_rx_echo_%d, %s : %d, ", ipv, ipstr.c_str(), port);
|
|
|
|
|
if(ipv == 4)
|
|
|
|
|
tcp_perf_rx_echo_4(&addr, operation, count, delay, details, &passed);
|
2017-06-16 16:58:30 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(passed == PASSED) {
|
|
|
|
|
DEBUG_TEST("%s",ok_str);
|
|
|
|
|
results->push_back(std::string(ok_str) + " " + std::string(result_str) + " " + std::string(details));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
DEBUG_ERROR("%s",fail_str);
|
|
|
|
|
results->push_back(std::string(fail_str) + " " + std::string(result_str) + " " + std::string(details));
|
|
|
|
|
}
|
|
|
|
|
if(EXIT_ON_FAIL && !passed) {
|
|
|
|
|
fprintf(stderr, "%s\n", results->at(results->size()-1).c_str());
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
return passed;
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************/
|
2017-06-16 16:58:30 -07:00
|
|
|
/* main(), calls test_driver(...) */
|
2017-05-01 17:44:45 -07:00
|
|
|
/****************************************************************************/
|
|
|
|
|
|
|
|
|
|
int main(int argc , char *argv[])
|
|
|
|
|
{
|
2017-05-30 13:17:39 -07:00
|
|
|
if(argc < 1) {
|
2017-06-16 16:58:30 -07:00
|
|
|
fprintf(stderr, "usage: selftest <alice|bob>.conf\n");
|
|
|
|
|
fprintf(stderr, " - Define your test environment in *.conf files.\n");
|
2017-05-01 17:44:45 -07:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
std::vector<std::string> results;
|
|
|
|
|
|
2017-06-05 17:10:24 -07:00
|
|
|
int err = 0;
|
|
|
|
|
int type = 0;
|
2017-06-16 16:58:30 -07:00
|
|
|
int ipv = 0;
|
2017-06-05 17:10:24 -07:00
|
|
|
int mode = 0;
|
|
|
|
|
int port = 0;
|
|
|
|
|
int operation = 0;
|
2017-06-16 16:58:30 -07:00
|
|
|
int start_port = 0;
|
|
|
|
|
int port_offset = 0;
|
2017-06-22 18:22:39 -07:00
|
|
|
int count = 0;
|
2017-06-05 17:10:24 -07:00
|
|
|
int delay = 0;
|
2017-05-01 17:44:45 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
std::string remote_echo_ipv4;
|
|
|
|
|
|
2017-06-05 14:26:06 -07:00
|
|
|
std::string nwid, stype, path = argv[1];
|
2017-05-30 13:17:39 -07:00
|
|
|
std::string ipstr, ipstr6, local_ipstr, local_ipstr6, remote_ipstr, remote_ipstr6;
|
2017-05-01 17:44:45 -07:00
|
|
|
memcpy(str, "welcome to the machine", 22);
|
|
|
|
|
|
2017-05-30 13:17:39 -07:00
|
|
|
// if a test config file was specified:
|
2017-06-16 16:58:30 -07:00
|
|
|
if(path.find(".conf") != std::string::npos) {
|
|
|
|
|
//printf("\nTest config file contents:\n");
|
2017-05-30 13:17:39 -07:00
|
|
|
loadTestConfigFile(path);
|
|
|
|
|
nwid = testConf["nwid"];
|
|
|
|
|
path = testConf["local_path"];
|
2017-06-09 10:30:57 -07:00
|
|
|
stype = testConf["test"];
|
2017-06-16 16:58:30 -07:00
|
|
|
start_port = atoi(testConf["start_port"].c_str());
|
|
|
|
|
port_offset = atoi(testConf["port_offset"].c_str());
|
2017-05-30 13:17:39 -07:00
|
|
|
local_ipstr = testConf["local_ipv4"];
|
|
|
|
|
local_ipstr6 = testConf["local_ipv6"];
|
|
|
|
|
remote_ipstr = testConf["remote_ipv4"];
|
|
|
|
|
remote_ipstr6 = testConf["remote_ipv6"];
|
2017-06-16 16:58:30 -07:00
|
|
|
|
|
|
|
|
remote_echo_ipv4 = testConf["remote_echo_ipv4"];
|
|
|
|
|
|
2017-05-30 13:17:39 -07:00
|
|
|
std::string smode = testConf["mode"];
|
|
|
|
|
|
|
|
|
|
if(strcmp(smode.c_str(), "server") == 0)
|
|
|
|
|
mode = TEST_MODE_SERVER;
|
|
|
|
|
else
|
|
|
|
|
mode = TEST_MODE_CLIENT;
|
|
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
/*
|
2017-06-22 18:22:39 -07:00
|
|
|
fprintf(stderr, "\tlocal_ipstr =%s\n", local_ipstr.c_str());
|
|
|
|
|
fprintf(stderr, "\tlocal_ipstr6 =%s\n", local_ipstr6.c_str());
|
|
|
|
|
fprintf(stderr, "\tremote_ipstr =%s\n", remote_ipstr.c_str());
|
|
|
|
|
fprintf(stderr, "\tremote_ipstr6=%s\n", remote_ipstr6.c_str());
|
2017-05-30 13:17:39 -07:00
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
fprintf(stderr, "\tstart_port =%d\n", start_port);
|
2017-06-16 16:58:30 -07:00
|
|
|
*/
|
2017-05-30 13:17:39 -07:00
|
|
|
}
|
2017-06-16 16:58:30 -07:00
|
|
|
/*
|
2017-06-22 18:22:39 -07:00
|
|
|
fprintf(stderr, "\tpath =%s\n", path.c_str());
|
|
|
|
|
fprintf(stderr, "\tnwid =%s\n", nwid.c_str());
|
|
|
|
|
fprintf(stderr, "\ttype =%s\n\n", stype.c_str());
|
2017-06-16 16:58:30 -07:00
|
|
|
*/
|
2017-05-30 13:17:39 -07:00
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
DEBUG_TEST("Waiting for libzt to come online...\n");
|
2017-06-05 14:26:06 -07:00
|
|
|
zts_simple_start(path.c_str(), nwid.c_str());
|
2017-06-16 16:58:30 -07:00
|
|
|
if(mode == TEST_MODE_SERVER)
|
|
|
|
|
DEBUG_TEST("Ready. You should start selftest program on second host now...\n\n");
|
|
|
|
|
if(mode == TEST_MODE_CLIENT)
|
|
|
|
|
DEBUG_TEST("Ready. Contacting selftest program on first host.\n\n");
|
|
|
|
|
|
2017-06-05 14:26:06 -07:00
|
|
|
// What follows is a long-form of zts_simple_start():
|
2017-05-30 13:17:39 -07:00
|
|
|
// zts_start(path.c_str());
|
|
|
|
|
// printf("waiting for service to start...\n");
|
|
|
|
|
// while(!zts_running())
|
|
|
|
|
// sleep(1);
|
|
|
|
|
// printf("joining network...\n");
|
|
|
|
|
// zts_join(nwid.c_str());
|
|
|
|
|
// printf("waiting for address assignment...\n");
|
|
|
|
|
// while(!zts_has_address(nwid.c_str()))
|
|
|
|
|
// sleep(1);
|
|
|
|
|
|
|
|
|
|
// SLAM
|
|
|
|
|
// Perform thsouands of repetitions of the same plausible API sequences to detect faults
|
|
|
|
|
if(stype == "slam")
|
|
|
|
|
{
|
|
|
|
|
slam_api_test();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2017-05-05 16:46:07 -07:00
|
|
|
|
2017-05-01 17:44:45 -07:00
|
|
|
// SIMPLE
|
|
|
|
|
// performs a one-off test of a particular subset of the API
|
|
|
|
|
// For instance (ipv4 client, ipv6 server, etc)
|
2017-06-22 18:22:39 -07:00
|
|
|
/*
|
2017-05-01 17:44:45 -07:00
|
|
|
if(stype == "simple")
|
|
|
|
|
{
|
2017-06-16 16:58:30 -07:00
|
|
|
DEBUG_TEST("performing SIMPLE test\n");
|
2017-05-01 17:44:45 -07:00
|
|
|
// Parse args
|
|
|
|
|
type = TEST_TYPE_SIMPLE;
|
2017-06-16 16:58:30 -07:00
|
|
|
ipv = atoi(argv[4]);
|
2017-05-01 17:44:45 -07:00
|
|
|
if(!strcmp(argv[5],"client"))
|
|
|
|
|
mode = TEST_MODE_CLIENT;
|
|
|
|
|
if(!strcmp(argv[5],"server"))
|
|
|
|
|
mode = TEST_MODE_SERVER;
|
|
|
|
|
ipstr = argv[6];
|
|
|
|
|
port = atoi(argv[7]);
|
|
|
|
|
|
|
|
|
|
// Perform test
|
2017-06-22 18:22:39 -07:00
|
|
|
return test_driver(argv[5], path, nwid, type, ipv, mode, ipstr, port, operation, count, delay, &results);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SUSTAINED
|
|
|
|
|
// Performs a stress test for benchmarking performance
|
|
|
|
|
if(stype == "sustained")
|
|
|
|
|
{
|
2017-06-16 16:58:30 -07:00
|
|
|
DEBUG_TEST("performing SUSTAINED test\n");
|
2017-05-01 17:44:45 -07:00
|
|
|
type = TEST_TYPE_SUSTAINED;
|
2017-06-16 16:58:30 -07:00
|
|
|
ipv = atoi(argv[4]);
|
2017-05-01 17:44:45 -07:00
|
|
|
if(!strcmp(argv[5],"client"))
|
|
|
|
|
mode = TEST_MODE_CLIENT;
|
|
|
|
|
if(!strcmp(argv[5],"server"))
|
|
|
|
|
mode = TEST_MODE_SERVER;
|
|
|
|
|
ipstr = argv[6];
|
|
|
|
|
port = atoi(argv[7]);
|
|
|
|
|
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
std::string s_operation = argv[ 8]; // count, count, count
|
|
|
|
|
count = atoi(argv[ 9]); // 10, 100, 1000, ...
|
2017-05-01 17:44:45 -07:00
|
|
|
delay = atoi(argv[10]); // 100 (in ms)
|
|
|
|
|
|
|
|
|
|
if(s_operation == "n_times")
|
|
|
|
|
operation = TEST_OP_N_TIMES;
|
|
|
|
|
if(s_operation == "n_bytes")
|
|
|
|
|
operation = TEST_OP_N_BYTES;
|
|
|
|
|
if(s_operation == "n_seconds")
|
|
|
|
|
operation = TEST_OP_N_SECONDS;
|
|
|
|
|
|
|
|
|
|
// Perform test
|
2017-06-22 18:22:39 -07:00
|
|
|
return test_driver(argv[5], path, nwid, type, ipv, mode, ipstr, port, operation, count, delay, &results);
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
2017-06-22 18:22:39 -07:00
|
|
|
*/
|
2017-05-01 17:44:45 -07:00
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
/* COMPREHENSIVE */
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
|
2017-06-05 14:26:06 -07:00
|
|
|
// Use test/*.conf files to specify test setup
|
|
|
|
|
// More information can be found in TESTING.md
|
2017-05-01 17:44:45 -07:00
|
|
|
|
|
|
|
|
// COMPREHENSIVE
|
|
|
|
|
// Tests ALL API calls
|
|
|
|
|
if(stype == "comprehensive")
|
|
|
|
|
{
|
|
|
|
|
|
2017-06-09 10:30:57 -07:00
|
|
|
// Establish initial IPV4 connection between Alice and Bob
|
|
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
port = start_port;
|
|
|
|
|
delay = 0;
|
2017-06-22 18:22:39 -07:00
|
|
|
count = 128;
|
|
|
|
|
operation = TEST_OP_N_BYTES;
|
2017-06-16 16:58:30 -07:00
|
|
|
|
|
|
|
|
if(mode == TEST_MODE_SERVER)
|
2017-05-30 13:17:39 -07:00
|
|
|
ipstr = local_ipstr;
|
|
|
|
|
else if(mode == TEST_MODE_CLIENT) {
|
2017-06-22 18:22:39 -07:00
|
|
|
sleep(3); // give the server some time to come online before beginning test
|
2017-05-30 13:17:39 -07:00
|
|
|
ipstr = remote_ipstr;
|
|
|
|
|
}
|
2017-06-22 18:22:39 -07:00
|
|
|
err += test_driver("ipv4", path, nwid, TEST_TYPE_SIMPLE, 4, mode, ipstr, port, operation, count, delay, &results);
|
2017-06-09 10:30:57 -07:00
|
|
|
|
|
|
|
|
// Perform sustained transfer
|
|
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
port++;
|
2017-06-22 18:22:39 -07:00
|
|
|
err += test_driver("ipv4_sustained", path, nwid, TEST_TYPE_SUSTAINED, 4, mode, ipstr, port, operation, count, delay, &results);
|
2017-05-30 13:17:39 -07:00
|
|
|
|
|
|
|
|
// swtich modes (client/server)
|
|
|
|
|
if(mode == TEST_MODE_SERVER) {
|
|
|
|
|
ipstr = remote_ipstr;
|
|
|
|
|
mode = TEST_MODE_CLIENT;
|
|
|
|
|
}
|
|
|
|
|
else if(mode == TEST_MODE_CLIENT) {
|
|
|
|
|
ipstr = local_ipstr;
|
|
|
|
|
mode = TEST_MODE_SERVER;
|
|
|
|
|
}
|
2017-06-16 16:58:30 -07:00
|
|
|
|
|
|
|
|
port++;
|
2017-06-22 18:22:39 -07:00
|
|
|
err += test_driver("ipv4", path, nwid, TEST_TYPE_SIMPLE, 4, mode, ipstr, port, operation, count, delay, &results);
|
2017-05-01 17:44:45 -07:00
|
|
|
|
2017-06-05 14:26:06 -07:00
|
|
|
// IPV6
|
|
|
|
|
|
|
|
|
|
if(mode == TEST_MODE_SERVER) {
|
|
|
|
|
ipstr6 = local_ipstr6;
|
|
|
|
|
}
|
|
|
|
|
else if(mode == TEST_MODE_CLIENT) {
|
2017-06-22 18:22:39 -07:00
|
|
|
sleep(3); // give the server some time to come online before beginning test
|
2017-06-05 14:26:06 -07:00
|
|
|
ipstr6 = remote_ipstr6;
|
|
|
|
|
}
|
2017-06-16 16:58:30 -07:00
|
|
|
|
|
|
|
|
port++;
|
2017-06-22 18:22:39 -07:00
|
|
|
err += test_driver("ipv6", path, nwid, TEST_TYPE_SIMPLE, 6, mode, ipstr6, port, operation, count, delay, &results);
|
2017-06-09 10:30:57 -07:00
|
|
|
|
|
|
|
|
// Perform sustained transfer
|
|
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
port++;
|
2017-06-22 18:22:39 -07:00
|
|
|
err += test_driver("ipv6_sustained", path, nwid, TEST_TYPE_SUSTAINED, 6, mode, ipstr6, port, operation, count, delay, &results);
|
2017-06-05 14:26:06 -07:00
|
|
|
|
|
|
|
|
// swtich modes (client/server)
|
|
|
|
|
if(mode == TEST_MODE_SERVER) {
|
|
|
|
|
ipstr6 = remote_ipstr6;
|
|
|
|
|
mode = TEST_MODE_CLIENT;
|
|
|
|
|
}
|
|
|
|
|
else if(mode == TEST_MODE_CLIENT) {
|
|
|
|
|
ipstr6 = local_ipstr6;
|
|
|
|
|
mode = TEST_MODE_SERVER;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
port++;
|
2017-06-22 18:22:39 -07:00
|
|
|
err += test_driver("ipv6", path, nwid, TEST_TYPE_SIMPLE, 6, mode, ipstr6, port, operation, count, delay, &results);
|
2017-06-16 16:58:30 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
// PERFORMANCE (between library instances)
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
count = 1024*16;
|
2017-06-16 16:58:30 -07:00
|
|
|
operation = TEST_OP_N_BYTES;
|
|
|
|
|
|
|
|
|
|
if(mode == TEST_MODE_SERVER) {
|
|
|
|
|
ipstr = remote_ipstr;
|
|
|
|
|
mode = TEST_MODE_CLIENT;
|
|
|
|
|
}
|
|
|
|
|
else if(mode == TEST_MODE_CLIENT) {
|
|
|
|
|
ipstr = local_ipstr;
|
|
|
|
|
mode = TEST_MODE_SERVER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
port++;
|
2017-06-22 18:22:39 -07:00
|
|
|
err += test_driver("ipv4_perf", path, nwid, TEST_TYPE_PERF, 4, mode, ipstr, port, operation, count, delay, &results);
|
2017-06-16 16:58:30 -07:00
|
|
|
|
|
|
|
|
// PERFORMANCE (between this library instance and a native non library instance (echo) )
|
|
|
|
|
// Client/Server mode isn't being tested here, so it isn't important, we'll just set it to client
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
count = 1024*1024*16;
|
2017-06-16 16:58:30 -07:00
|
|
|
operation = TEST_OP_N_BYTES;
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
//mode = TEST_MODE_CLIENT;
|
2017-06-16 16:58:30 -07:00
|
|
|
ipstr = remote_echo_ipv4;
|
|
|
|
|
|
2017-06-22 18:22:39 -07:00
|
|
|
int echo_connect_port = 0;
|
|
|
|
|
|
|
|
|
|
if(strcmp(testConf["name"].c_str(), "alice") == 0)
|
|
|
|
|
echo_connect_port = start_port+port_offset+1;
|
|
|
|
|
else if(strcmp(testConf["name"].c_str(), "bob") == 0)
|
|
|
|
|
{
|
|
|
|
|
echo_connect_port = start_port+port_offset;
|
|
|
|
|
// since we're testing throughput (possibly on the same machine), we want to make
|
|
|
|
|
// sure the other host's test is completed first.
|
|
|
|
|
DEBUG_TEST("waiting for other host's test to conclude");
|
|
|
|
|
sleep(25);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err += test_driver("ipv4_perf_to_echo", path, nwid, TEST_TYPE_PERF_TO_ECHO, 4, mode, ipstr, echo_connect_port, operation, count, delay, &results);
|
|
|
|
|
|
|
|
|
|
if(mode == TEST_MODE_SERVER) {
|
|
|
|
|
mode = TEST_MODE_CLIENT;
|
|
|
|
|
}
|
|
|
|
|
else if(mode == TEST_MODE_CLIENT) {
|
|
|
|
|
mode = TEST_MODE_SERVER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err += test_driver("ipv4_perf_to_echo", path, nwid, TEST_TYPE_PERF_TO_ECHO, 4, mode, ipstr, echo_connect_port, operation, count, delay, &results);
|
2017-06-16 16:58:30 -07:00
|
|
|
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
/* RANDOM */
|
|
|
|
|
/****************************************************************************/
|
|
|
|
|
|
|
|
|
|
// RANDOM
|
|
|
|
|
// performs random API calls with plausible (and random) arguments/data
|
|
|
|
|
if(stype == "random")
|
|
|
|
|
{
|
|
|
|
|
random_api_test();
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-16 16:58:30 -07:00
|
|
|
printf("--------------------------------------------------------------------------------\n");
|
|
|
|
|
for(int i=0;i<results.size(); i++) {
|
|
|
|
|
fprintf(stderr, "%s\n", results[i].c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return err;
|
2017-05-01 17:44:45 -07:00
|
|
|
}
|