From 4fe1656cf89c10b2f69aedc104a19f61a138f826 Mon Sep 17 00:00:00 2001 From: Aris Adamantiadis Date: Tue, 28 Dec 2010 13:17:27 +0100 Subject: Moved benchmarks to the tests/ directory --- CMakeLists.txt | 3 - DefineOptions.cmake | 3 + benchmarks/CMakeLists.txt | 21 ---- benchmarks/bench1.sh | 13 --- benchmarks/bench2.sh | 13 --- benchmarks/bench_scp.c | 25 ----- benchmarks/benchmarks.c | 228 ---------------------------------------- benchmarks/benchmarks.h | 31 ------ benchmarks/latency.c | 136 ------------------------ tests/CMakeLists.txt | 5 + tests/benchmarks/CMakeLists.txt | 21 ++++ tests/benchmarks/bench1.sh | 13 +++ tests/benchmarks/bench2.sh | 13 +++ tests/benchmarks/bench_scp.c | 25 +++++ tests/benchmarks/benchmarks.c | 228 ++++++++++++++++++++++++++++++++++++++++ tests/benchmarks/benchmarks.h | 31 ++++++ tests/benchmarks/latency.c | 136 ++++++++++++++++++++++++ 17 files changed, 475 insertions(+), 470 deletions(-) delete mode 100644 benchmarks/CMakeLists.txt delete mode 100644 benchmarks/bench1.sh delete mode 100755 benchmarks/bench2.sh delete mode 100644 benchmarks/bench_scp.c delete mode 100644 benchmarks/benchmarks.c delete mode 100644 benchmarks/benchmarks.h delete mode 100644 benchmarks/latency.c create mode 100644 tests/benchmarks/CMakeLists.txt create mode 100644 tests/benchmarks/bench1.sh create mode 100755 tests/benchmarks/bench2.sh create mode 100644 tests/benchmarks/bench_scp.c create mode 100644 tests/benchmarks/benchmarks.c create mode 100644 tests/benchmarks/benchmarks.h create mode 100644 tests/benchmarks/latency.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d57317f5..86e80ee0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,9 +97,6 @@ if (WITH_TESTING) add_subdirectory(tests) endif (WITH_TESTING) -if (WITH_BENCHMARKS) - add_subdirectory(benchmarks) -endif (WITH_BENCHMARKS) message(STATUS "********************************************") message(STATUS "********** ${PROJECT_NAME} build options : **********") diff --git a/DefineOptions.cmake b/DefineOptions.cmake index 17abbd15..d82588cb 100644 --- a/DefineOptions.cmake +++ b/DefineOptions.cmake @@ -14,3 +14,6 @@ option(WITH_BENCHMARKS "Build benchmarks tools" OFF) if (WITH_TESTING) set(WITH_STATIC_LIB ON) endif (WITH_TESTING) +if(WITH_BENCHMARKS) + set(WITH_TESTING ON) +endif(WITH_BENCHMARKS) \ No newline at end of file diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt deleted file mode 100644 index 5b2b808d..00000000 --- a/benchmarks/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -project(libssh-benchmarks C) - -set(benchmarks_SRCS - bench_scp.c benchmarks.c latency.c -) - -include_directories( - ${LIBSSH_PUBLIC_INCLUDE_DIRS} -) - -add_executable(benchmarks ${benchmarks_SRCS}) - -target_link_libraries(benchmarks ${LIBSSH_SHARED_LIBRARY}) - -include_directories( - ${LIBSSH_PUBLIC_INCLUDE_DIRS} - ${CMAKE_BINARY_DIR} -) - -if (WITH_SFTP) -endif (WITH_SFTP) diff --git a/benchmarks/bench1.sh b/benchmarks/bench1.sh deleted file mode 100644 index 4458e9a7..00000000 --- a/benchmarks/bench1.sh +++ /dev/null @@ -1,13 +0,0 @@ -export CIPHER=aes128-cbc -export DEST=localhost - -echo "Upload raw SSH statistics" -echo "local machine: `uname -a`" -echo "Cipher : $CIPHER ; Destination : $DEST (`ssh $DEST uname -a`)" -echo "Local ssh version: `ssh -V 2>&1`" -echo "Ping latency to $DEST": -ping -q -c 1 -n $DEST -echo "Destination $DEST SSHD vesion : `echo | nc $DEST 22 | head -n1`" -echo "ssh login latency :`(time -f user:%U ssh $DEST 'id > /dev/null') 2>&1`" -./generate.py | dd bs=4096 count=100000 | time ssh -c $CIPHER $DEST "dd bs=4096 of=/dev/null" 2>&1 - diff --git a/benchmarks/bench2.sh b/benchmarks/bench2.sh deleted file mode 100755 index 01d67777..00000000 --- a/benchmarks/bench2.sh +++ /dev/null @@ -1,13 +0,0 @@ -export CIPHER=aes128-cbc -export DEST=localhost - -echo "Upload raw SSH statistics" -echo "local machine: `uname -a`" -echo "Cipher : $CIPHER ; Destination : $DEST (`ssh $DEST uname -a`)" -echo "Local ssh version: `samplessh -V 2>&1`" -echo "Ping latency to $DEST": -ping -q -c 1 -n $DEST -echo "Destination $DEST SSHD vesion : `echo | nc $DEST 22 | head -n1`" -echo "ssh login latency :`(time -f user:%U samplessh $DEST 'id > /dev/null') 2>&1`" -./generate.py | dd bs=4096 count=100000 | strace samplessh -c $CIPHER $DEST "dd bs=4096 of=/dev/null" 2>&1 - diff --git a/benchmarks/bench_scp.c b/benchmarks/bench_scp.c deleted file mode 100644 index 3ef3bbfc..00000000 --- a/benchmarks/bench_scp.c +++ /dev/null @@ -1,25 +0,0 @@ -/* bench_scp.c - * - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH Library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * The SSH Library 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 Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "benchmarks.h" -#include - diff --git a/benchmarks/benchmarks.c b/benchmarks/benchmarks.c deleted file mode 100644 index 44ddb5d8..00000000 --- a/benchmarks/benchmarks.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH Library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * The SSH Library 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 Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "config.h" -#include "benchmarks.h" -#include - -#include -#include -#include - -#ifdef HAVE_ARGP_H -#include - -const char *argp_program_version = "libssh benchmarks 2010-12-28"; -const char *argp_program_bug_address = "Aris Adamantiadis "; - -static char **cmdline; - -#define MAX_HOSTS_CONNECT 20 - -/* Program documentation. */ -static char doc[] = "libssh benchmarks"; -enum libssh_benchmarks { - BENCHMARK_RAW_UPLOAD=1, - BENCHMARK_NUMBER -}; - -const char *libssh_benchmarks_names[]={ - "null", - "benchmark_raw_upload" -}; - -struct argument_s { - const char *hosts[MAX_HOSTS_CONNECT]; - char benchmarks[BENCHMARK_NUMBER -1]; - int verbose; - int nhosts; - int ntests; -}; - -/* The options we understand. */ -static struct argp_option options[] = { - { - .name = "verbose", - .key = 'v', - .arg = NULL, - .flags = 0, - .doc = "Make libssh benchmark more verbose", - .group = 0 - }, - { - .name = "raw-upload", - .key = '1', - .arg = NULL, - .flags = 0, - .doc = "Upload raw data using channel", - .group = 0 - }, - { - .name = "host", - .key = 'h', - .arg = "HOST", - .flags = 0, - .doc = "Add a host to connect for benchmark (format user@hostname)", - .group = 0 - }, - {NULL, 0, NULL, 0, NULL, 0} -}; - -/* Parse a single option. */ -static error_t parse_opt (int key, char *arg, struct argp_state *state) { - /* Get the input argument from argp_parse, which we - * know is a pointer to our arguments structure. - */ - struct argument_s *arguments = state->input; - - /* arg is currently not used */ - (void) arg; - - switch (key) { - case '1': - arguments->benchmarks[key - '1' + 1] = 1; - arguments->ntests ++; - break; - case 'v': - arguments->verbose++; - break; - case 'h': - if(arguments->nhosts >= MAX_HOSTS_CONNECT){ - fprintf(stderr, "Too much hosts\n"); - return ARGP_ERR_UNKNOWN; - } - arguments->hosts[arguments->nhosts]=arg; - arguments->nhosts++; - break; - case ARGP_KEY_ARG: - /* End processing here. */ - cmdline = &state->argv [state->next - 1]; - state->next = state->argc; - break; - default: - return ARGP_ERR_UNKNOWN; - } - - return 0; -} - -/* Our argp parser. */ -static struct argp argp = {options, parse_opt, NULL, doc, NULL, NULL, NULL}; - -#endif /* HAVE_ARGP_H */ - -static void cmdline_parse(int argc, char **argv, struct argument_s *arguments) { - /* - * Parse our arguments; every option seen by parse_opt will - * be reflected in arguments. - */ -#ifdef HAVE_ARGP_H - argp_parse(&argp, argc, argv, 0, 0, arguments); -#endif /* HAVE_ARGP_H */ -} - -static void arguments_init(struct argument_s *arguments){ - memset(arguments,0,sizeof(*arguments)); -} - -static ssh_session connect_host(const char *host, int verbose){ - ssh_session session=ssh_new(); - if(session==NULL) - goto error; - if(ssh_options_set(session,SSH_OPTIONS_HOST, host)<0) - goto error; - ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbose); - if(ssh_connect(session)==SSH_ERROR) - goto error; - if(ssh_userauth_autopubkey(session,NULL) != SSH_AUTH_SUCCESS) - goto error; - return session; -error: - fprintf(stderr,"Error connecting to \"%s\": %s\n",host,ssh_get_error(session)); - ssh_free(session); - return NULL; -} - -static void do_benchmarks(ssh_session session, struct argument_s *arguments, - const char *hostname){ - float ping_rtt=0.0; - float ssh_rtt=0.0; - int err; - - if(arguments->verbose>0) - fprintf(stdout,"Testing ICMP RTT\n"); - err=benchmarks_ping_latency(hostname, &ping_rtt); - if(err == 0){ - fprintf(stdout,"ping RTT : %f ms\n",ping_rtt); - } - err=benchmarks_ssh_latency(session, &ssh_rtt); - if(err==0){ - fprintf(stdout, "SSH RTT : %f ms\n",ssh_rtt); - } -} - -int main(int argc, char **argv){ - struct argument_s arguments; - ssh_session session; - int i; - - arguments_init(&arguments); - cmdline_parse(argc, argv, &arguments); - if (arguments.nhosts==0){ - fprintf(stderr,"At least one host must be specified"); - return EXIT_FAILURE; - } - if (arguments.ntests==0){ - for(i=1; i < BENCHMARK_NUMBER ; ++i){ - arguments.benchmarks[i-1]=1; - } - arguments.ntests=BENCHMARK_NUMBER-1; - } - if (arguments.verbose > 0){ - fprintf(stdout, "Will try hosts "); - for(i=0;i 0) - fprintf(stdout,"Connecting to \"%s\"...\n",arguments.hosts[i]); - session=connect_host(arguments.hosts[i], arguments.verbose); - if(session != NULL && arguments.verbose > 0) - fprintf(stdout,"Success\n"); - if(session == NULL){ - fprintf(stderr,"Errors occured, stopping\n"); - return EXIT_FAILURE; - } - do_benchmarks(session, &arguments, arguments.hosts[i]); - ssh_disconnect(session); - ssh_free(session); - } - return EXIT_SUCCESS; -} - diff --git a/benchmarks/benchmarks.h b/benchmarks/benchmarks.h deleted file mode 100644 index fa32c9c9..00000000 --- a/benchmarks/benchmarks.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH Library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * The SSH Library 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 Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#ifndef BENCHMARKS_H_ -#define BENCHMARKS_H_ - -#include - -/* latency.c */ -int benchmarks_ping_latency (const char *host, float *average); -int benchmarks_ssh_latency (ssh_session session, float *average); - -#endif /* BENCHMARKS_H_ */ diff --git a/benchmarks/latency.c b/benchmarks/latency.c deleted file mode 100644 index 17379453..00000000 --- a/benchmarks/latency.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This file is part of the SSH Library - * - * Copyright (c) 2010 by Aris Adamantiadis - * - * The SSH Library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2.1 of the License, or (at your - * option) any later version. - * - * The SSH Library 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 Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the SSH Library; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -#include "benchmarks.h" -#include - -#include -#include -#include -#include -#include - -#define PING_PROGRAM "/bin/ping" - -/** @internal - * @brief Calculates the RTT of the host with ICMP ping, and returns the - * average of the calculated RTT. - * @param[in] host hostname to ping. - * @param[out] average average RTT in ms. - * @returns 0 on success, -1 if there is an error. - * @warning relies on an external ping program which may not exist on - * certain OS. - */ -int benchmarks_ping_latency (const char *host, float *average){ - const char *ptr; - char cmd[256]; - char line[1024]; - FILE *fd; - int found=0; - - /* strip out the hostname */ - ptr=strchr(host,'@'); - if(ptr) - ptr++; - else - ptr=host; - - snprintf(cmd,sizeof(cmd),"%s -n -q -c3 %s",PING_PROGRAM, ptr); - fd=popen(cmd,"r"); - if(fd==NULL){ - fprintf(stderr,"Error executing command : %s\n", strerror(errno)); - return -1; - } - - while(!found && fgets(line,sizeof(line),fd)!=NULL){ - if(strstr(line,"rtt")){ - ptr=strchr(line,'='); - if(ptr==NULL) - goto parseerror; - ptr=strchr(ptr,'/'); - if(ptr==NULL) - goto parseerror; - *average=strtof(ptr+1,NULL); - found=1; - break; - } - } - if(!found) - goto parseerror; - fclose(fd); - return 0; - -parseerror: - fprintf(stderr,"Parse error : couldn't locate average in %s",line); - fclose(fd); - return -1; -} - -struct timestamp_struct { - struct timeval timestamp; -}; - -static void timestamp_init(struct timestamp_struct *ts){ - gettimeofday(&ts->timestamp,NULL); -} - -static float elapsed_time(struct timestamp_struct *ts){ - struct timeval now; - time_t secdiff; - long usecdiff; /* may be negative */ - - gettimeofday(&now,NULL); - secdiff=now.tv_sec - ts->timestamp.tv_sec; - usecdiff=now.tv_usec - ts->timestamp.tv_usec; - //printf("%d sec diff, %d usec diff\n",secdiff, usecdiff); - return (float) (secdiff*1000) + ((float)usecdiff)/1000; -} - -int benchmarks_ssh_latency(ssh_session session, float *average){ - float times[3]; - struct timestamp_struct ts; - int i; - ssh_channel channel; - channel=ssh_channel_new(session); - if(channel==NULL) - goto error; - if(ssh_channel_open_session(channel)==SSH_ERROR) - goto error; - - for(i=0;i<3;++i){ - timestamp_init(&ts); - if(ssh_channel_request_env(channel,"TEST","test")==SSH_ERROR && - ssh_get_error_code(session)==SSH_FATAL) - goto error; - times[i]=elapsed_time(&ts); - } - ssh_channel_close(channel); - ssh_channel_free(channel); - channel=NULL; - printf("Times : %f ms ; %f ms ; %f ms\n", times[0], times[1], times[2]); - *average=(times[0]+times[1]+times[2])/3; - return 0; -error: - fprintf(stderr,"Error calculating SSH latency : %s\n",ssh_get_error(session)); - if(channel) - ssh_channel_free(channel); - return -1; -} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 56980abe..da1fb412 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -32,3 +32,8 @@ add_subdirectory(unittests) if (WITH_CLIENT_TESTING) add_subdirectory(client) endif (WITH_CLIENT_TESTING) + +if (WITH_BENCHMARKS) + add_subdirectory(benchmarks) +endif (WITH_BENCHMARKS) + diff --git a/tests/benchmarks/CMakeLists.txt b/tests/benchmarks/CMakeLists.txt new file mode 100644 index 00000000..5b2b808d --- /dev/null +++ b/tests/benchmarks/CMakeLists.txt @@ -0,0 +1,21 @@ +project(libssh-benchmarks C) + +set(benchmarks_SRCS + bench_scp.c benchmarks.c latency.c +) + +include_directories( + ${LIBSSH_PUBLIC_INCLUDE_DIRS} +) + +add_executable(benchmarks ${benchmarks_SRCS}) + +target_link_libraries(benchmarks ${LIBSSH_SHARED_LIBRARY}) + +include_directories( + ${LIBSSH_PUBLIC_INCLUDE_DIRS} + ${CMAKE_BINARY_DIR} +) + +if (WITH_SFTP) +endif (WITH_SFTP) diff --git a/tests/benchmarks/bench1.sh b/tests/benchmarks/bench1.sh new file mode 100644 index 00000000..4458e9a7 --- /dev/null +++ b/tests/benchmarks/bench1.sh @@ -0,0 +1,13 @@ +export CIPHER=aes128-cbc +export DEST=localhost + +echo "Upload raw SSH statistics" +echo "local machine: `uname -a`" +echo "Cipher : $CIPHER ; Destination : $DEST (`ssh $DEST uname -a`)" +echo "Local ssh version: `ssh -V 2>&1`" +echo "Ping latency to $DEST": +ping -q -c 1 -n $DEST +echo "Destination $DEST SSHD vesion : `echo | nc $DEST 22 | head -n1`" +echo "ssh login latency :`(time -f user:%U ssh $DEST 'id > /dev/null') 2>&1`" +./generate.py | dd bs=4096 count=100000 | time ssh -c $CIPHER $DEST "dd bs=4096 of=/dev/null" 2>&1 + diff --git a/tests/benchmarks/bench2.sh b/tests/benchmarks/bench2.sh new file mode 100755 index 00000000..01d67777 --- /dev/null +++ b/tests/benchmarks/bench2.sh @@ -0,0 +1,13 @@ +export CIPHER=aes128-cbc +export DEST=localhost + +echo "Upload raw SSH statistics" +echo "local machine: `uname -a`" +echo "Cipher : $CIPHER ; Destination : $DEST (`ssh $DEST uname -a`)" +echo "Local ssh version: `samplessh -V 2>&1`" +echo "Ping latency to $DEST": +ping -q -c 1 -n $DEST +echo "Destination $DEST SSHD vesion : `echo | nc $DEST 22 | head -n1`" +echo "ssh login latency :`(time -f user:%U samplessh $DEST 'id > /dev/null') 2>&1`" +./generate.py | dd bs=4096 count=100000 | strace samplessh -c $CIPHER $DEST "dd bs=4096 of=/dev/null" 2>&1 + diff --git a/tests/benchmarks/bench_scp.c b/tests/benchmarks/bench_scp.c new file mode 100644 index 00000000..3ef3bbfc --- /dev/null +++ b/tests/benchmarks/bench_scp.c @@ -0,0 +1,25 @@ +/* bench_scp.c + * + * This file is part of the SSH Library + * + * Copyright (c) 2010 by Aris Adamantiadis + * + * The SSH Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The SSH Library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the SSH Library; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include "benchmarks.h" +#include + diff --git a/tests/benchmarks/benchmarks.c b/tests/benchmarks/benchmarks.c new file mode 100644 index 00000000..44ddb5d8 --- /dev/null +++ b/tests/benchmarks/benchmarks.c @@ -0,0 +1,228 @@ +/* + * This file is part of the SSH Library + * + * Copyright (c) 2010 by Aris Adamantiadis + * + * The SSH Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The SSH Library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the SSH Library; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include "config.h" +#include "benchmarks.h" +#include + +#include +#include +#include + +#ifdef HAVE_ARGP_H +#include + +const char *argp_program_version = "libssh benchmarks 2010-12-28"; +const char *argp_program_bug_address = "Aris Adamantiadis "; + +static char **cmdline; + +#define MAX_HOSTS_CONNECT 20 + +/* Program documentation. */ +static char doc[] = "libssh benchmarks"; +enum libssh_benchmarks { + BENCHMARK_RAW_UPLOAD=1, + BENCHMARK_NUMBER +}; + +const char *libssh_benchmarks_names[]={ + "null", + "benchmark_raw_upload" +}; + +struct argument_s { + const char *hosts[MAX_HOSTS_CONNECT]; + char benchmarks[BENCHMARK_NUMBER -1]; + int verbose; + int nhosts; + int ntests; +}; + +/* The options we understand. */ +static struct argp_option options[] = { + { + .name = "verbose", + .key = 'v', + .arg = NULL, + .flags = 0, + .doc = "Make libssh benchmark more verbose", + .group = 0 + }, + { + .name = "raw-upload", + .key = '1', + .arg = NULL, + .flags = 0, + .doc = "Upload raw data using channel", + .group = 0 + }, + { + .name = "host", + .key = 'h', + .arg = "HOST", + .flags = 0, + .doc = "Add a host to connect for benchmark (format user@hostname)", + .group = 0 + }, + {NULL, 0, NULL, 0, NULL, 0} +}; + +/* Parse a single option. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state) { + /* Get the input argument from argp_parse, which we + * know is a pointer to our arguments structure. + */ + struct argument_s *arguments = state->input; + + /* arg is currently not used */ + (void) arg; + + switch (key) { + case '1': + arguments->benchmarks[key - '1' + 1] = 1; + arguments->ntests ++; + break; + case 'v': + arguments->verbose++; + break; + case 'h': + if(arguments->nhosts >= MAX_HOSTS_CONNECT){ + fprintf(stderr, "Too much hosts\n"); + return ARGP_ERR_UNKNOWN; + } + arguments->hosts[arguments->nhosts]=arg; + arguments->nhosts++; + break; + case ARGP_KEY_ARG: + /* End processing here. */ + cmdline = &state->argv [state->next - 1]; + state->next = state->argc; + break; + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +} + +/* Our argp parser. */ +static struct argp argp = {options, parse_opt, NULL, doc, NULL, NULL, NULL}; + +#endif /* HAVE_ARGP_H */ + +static void cmdline_parse(int argc, char **argv, struct argument_s *arguments) { + /* + * Parse our arguments; every option seen by parse_opt will + * be reflected in arguments. + */ +#ifdef HAVE_ARGP_H + argp_parse(&argp, argc, argv, 0, 0, arguments); +#endif /* HAVE_ARGP_H */ +} + +static void arguments_init(struct argument_s *arguments){ + memset(arguments,0,sizeof(*arguments)); +} + +static ssh_session connect_host(const char *host, int verbose){ + ssh_session session=ssh_new(); + if(session==NULL) + goto error; + if(ssh_options_set(session,SSH_OPTIONS_HOST, host)<0) + goto error; + ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbose); + if(ssh_connect(session)==SSH_ERROR) + goto error; + if(ssh_userauth_autopubkey(session,NULL) != SSH_AUTH_SUCCESS) + goto error; + return session; +error: + fprintf(stderr,"Error connecting to \"%s\": %s\n",host,ssh_get_error(session)); + ssh_free(session); + return NULL; +} + +static void do_benchmarks(ssh_session session, struct argument_s *arguments, + const char *hostname){ + float ping_rtt=0.0; + float ssh_rtt=0.0; + int err; + + if(arguments->verbose>0) + fprintf(stdout,"Testing ICMP RTT\n"); + err=benchmarks_ping_latency(hostname, &ping_rtt); + if(err == 0){ + fprintf(stdout,"ping RTT : %f ms\n",ping_rtt); + } + err=benchmarks_ssh_latency(session, &ssh_rtt); + if(err==0){ + fprintf(stdout, "SSH RTT : %f ms\n",ssh_rtt); + } +} + +int main(int argc, char **argv){ + struct argument_s arguments; + ssh_session session; + int i; + + arguments_init(&arguments); + cmdline_parse(argc, argv, &arguments); + if (arguments.nhosts==0){ + fprintf(stderr,"At least one host must be specified"); + return EXIT_FAILURE; + } + if (arguments.ntests==0){ + for(i=1; i < BENCHMARK_NUMBER ; ++i){ + arguments.benchmarks[i-1]=1; + } + arguments.ntests=BENCHMARK_NUMBER-1; + } + if (arguments.verbose > 0){ + fprintf(stdout, "Will try hosts "); + for(i=0;i 0) + fprintf(stdout,"Connecting to \"%s\"...\n",arguments.hosts[i]); + session=connect_host(arguments.hosts[i], arguments.verbose); + if(session != NULL && arguments.verbose > 0) + fprintf(stdout,"Success\n"); + if(session == NULL){ + fprintf(stderr,"Errors occured, stopping\n"); + return EXIT_FAILURE; + } + do_benchmarks(session, &arguments, arguments.hosts[i]); + ssh_disconnect(session); + ssh_free(session); + } + return EXIT_SUCCESS; +} + diff --git a/tests/benchmarks/benchmarks.h b/tests/benchmarks/benchmarks.h new file mode 100644 index 00000000..fa32c9c9 --- /dev/null +++ b/tests/benchmarks/benchmarks.h @@ -0,0 +1,31 @@ +/* + * This file is part of the SSH Library + * + * Copyright (c) 2010 by Aris Adamantiadis + * + * The SSH Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The SSH Library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the SSH Library; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#ifndef BENCHMARKS_H_ +#define BENCHMARKS_H_ + +#include + +/* latency.c */ +int benchmarks_ping_latency (const char *host, float *average); +int benchmarks_ssh_latency (ssh_session session, float *average); + +#endif /* BENCHMARKS_H_ */ diff --git a/tests/benchmarks/latency.c b/tests/benchmarks/latency.c new file mode 100644 index 00000000..17379453 --- /dev/null +++ b/tests/benchmarks/latency.c @@ -0,0 +1,136 @@ +/* + * This file is part of the SSH Library + * + * Copyright (c) 2010 by Aris Adamantiadis + * + * The SSH Library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The SSH Library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the SSH Library; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#include "benchmarks.h" +#include + +#include +#include +#include +#include +#include + +#define PING_PROGRAM "/bin/ping" + +/** @internal + * @brief Calculates the RTT of the host with ICMP ping, and returns the + * average of the calculated RTT. + * @param[in] host hostname to ping. + * @param[out] average average RTT in ms. + * @returns 0 on success, -1 if there is an error. + * @warning relies on an external ping program which may not exist on + * certain OS. + */ +int benchmarks_ping_latency (const char *host, float *average){ + const char *ptr; + char cmd[256]; + char line[1024]; + FILE *fd; + int found=0; + + /* strip out the hostname */ + ptr=strchr(host,'@'); + if(ptr) + ptr++; + else + ptr=host; + + snprintf(cmd,sizeof(cmd),"%s -n -q -c3 %s",PING_PROGRAM, ptr); + fd=popen(cmd,"r"); + if(fd==NULL){ + fprintf(stderr,"Error executing command : %s\n", strerror(errno)); + return -1; + } + + while(!found && fgets(line,sizeof(line),fd)!=NULL){ + if(strstr(line,"rtt")){ + ptr=strchr(line,'='); + if(ptr==NULL) + goto parseerror; + ptr=strchr(ptr,'/'); + if(ptr==NULL) + goto parseerror; + *average=strtof(ptr+1,NULL); + found=1; + break; + } + } + if(!found) + goto parseerror; + fclose(fd); + return 0; + +parseerror: + fprintf(stderr,"Parse error : couldn't locate average in %s",line); + fclose(fd); + return -1; +} + +struct timestamp_struct { + struct timeval timestamp; +}; + +static void timestamp_init(struct timestamp_struct *ts){ + gettimeofday(&ts->timestamp,NULL); +} + +static float elapsed_time(struct timestamp_struct *ts){ + struct timeval now; + time_t secdiff; + long usecdiff; /* may be negative */ + + gettimeofday(&now,NULL); + secdiff=now.tv_sec - ts->timestamp.tv_sec; + usecdiff=now.tv_usec - ts->timestamp.tv_usec; + //printf("%d sec diff, %d usec diff\n",secdiff, usecdiff); + return (float) (secdiff*1000) + ((float)usecdiff)/1000; +} + +int benchmarks_ssh_latency(ssh_session session, float *average){ + float times[3]; + struct timestamp_struct ts; + int i; + ssh_channel channel; + channel=ssh_channel_new(session); + if(channel==NULL) + goto error; + if(ssh_channel_open_session(channel)==SSH_ERROR) + goto error; + + for(i=0;i<3;++i){ + timestamp_init(&ts); + if(ssh_channel_request_env(channel,"TEST","test")==SSH_ERROR && + ssh_get_error_code(session)==SSH_FATAL) + goto error; + times[i]=elapsed_time(&ts); + } + ssh_channel_close(channel); + ssh_channel_free(channel); + channel=NULL; + printf("Times : %f ms ; %f ms ; %f ms\n", times[0], times[1], times[2]); + *average=(times[0]+times[1]+times[2])/3; + return 0; +error: + fprintf(stderr,"Error calculating SSH latency : %s\n",ssh_get_error(session)); + if(channel) + ssh_channel_free(channel); + return -1; +} -- cgit v1.2.3