aboutsummaryrefslogtreecommitdiff
path: root/tests/benchmarks
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2011-08-29 20:13:24 +0300
committerAris Adamantiadis <aris@0xbadc0de.be>2011-09-02 11:43:07 +0300
commitb11567ed9bf47688369fec2cf4884082790c43c4 (patch)
tree700006c8f0881b2b649da182f36f3f42b2805dda /tests/benchmarks
parentfaaf334aa38a0a71894f78eb20d6c39e5e34f79e (diff)
downloadlibssh-b11567ed9bf47688369fec2cf4884082790c43c4.tar.gz
libssh-b11567ed9bf47688369fec2cf4884082790c43c4.tar.xz
libssh-b11567ed9bf47688369fec2cf4884082790c43c4.zip
benchmarks: refactoring + sync sftp tests
no surprise, sync sftp is much slower, even for localhost, especially for download.
Diffstat (limited to 'tests/benchmarks')
-rw-r--r--tests/benchmarks/CMakeLists.txt2
-rw-r--r--tests/benchmarks/bench_raw.c11
-rw-r--r--tests/benchmarks/bench_scp.c131
-rw-r--r--tests/benchmarks/bench_sftp.c152
-rw-r--r--tests/benchmarks/benchmarks.c105
-rw-r--r--tests/benchmarks/benchmarks.h27
6 files changed, 401 insertions, 27 deletions
diff --git a/tests/benchmarks/CMakeLists.txt b/tests/benchmarks/CMakeLists.txt
index 02488bd..8dc8552 100644
--- a/tests/benchmarks/CMakeLists.txt
+++ b/tests/benchmarks/CMakeLists.txt
@@ -1,7 +1,7 @@
project(libssh-benchmarks C)
set(benchmarks_SRCS
- bench_scp.c bench_raw.c benchmarks.c latency.c
+ bench_scp.c bench_sftp bench_raw.c benchmarks.c latency.c
)
include_directories(
diff --git a/tests/benchmarks/bench_raw.c b/tests/benchmarks/bench_raw.c
index 62e1055..579ad08 100644
--- a/tests/benchmarks/bench_raw.c
+++ b/tests/benchmarks/bench_raw.c
@@ -189,11 +189,16 @@ const char python_giver[] =
"r=sys.stdin.read(2)\n"
"towrite=XXXXXXXXXX\n"
"wrote=0\n"
+"mtu = 32786\n"
+"buf = 'A'*mtu\n"
"while(wrote < towrite):\n"
" buffersize=towrite-wrote\n"
-" if(buffersize > 4096):\n"
-" buffersize=4096\n"
-" sys.stdout.write('A'*buffersize)\n"
+" if(buffersize > mtu):\n"
+" buffersize=mtu\n"
+" if(buffersize == mtu):\n"
+" sys.stdout.write(buf)\n"
+" else:\n"
+" sys.stdout.write('A'*buffersize)\n"
" wrote+=buffersize\n"
"sys.stdout.flush()\n";
diff --git a/tests/benchmarks/bench_scp.c b/tests/benchmarks/bench_scp.c
index 3ef3bbf..3e0a7c0 100644
--- a/tests/benchmarks/bench_scp.c
+++ b/tests/benchmarks/bench_scp.c
@@ -2,7 +2,7 @@
*
* This file is part of the SSH Library
*
- * Copyright (c) 2010 by Aris Adamantiadis
+ * Copyright (c) 2011 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
@@ -22,4 +22,133 @@
#include "benchmarks.h"
#include <libssh/libssh.h>
+#include <stdio.h>
+#define SCPDIR "/tmp/"
+#define SCPFILE "scpbenchmark"
+
+/** @internal
+ * @brief benchmarks a scp upload using an
+ * existing SSH session.
+ * @param[in] session Open SSH session
+ * @param[in] args Parsed command line arguments
+ * @param[out] bps The calculated bytes per second obtained via benchmark.
+ * @return 0 on success, -1 on error.
+ */
+int benchmarks_scp_up (ssh_session session, struct argument_s *args,
+ float *bps){
+ unsigned long bytes=0x1000000;
+ static char buffer[0x10000];
+ struct timestamp_struct ts;
+ float ms=0.0;
+ unsigned long total=0;
+ ssh_scp scp;
+
+ if(args->data != 0)
+ bytes = args->data * 1024 * 1024;
+ scp = ssh_scp_new(session,SSH_SCP_WRITE,SCPDIR);
+ if(scp == NULL)
+ goto error;
+ if(ssh_scp_init(scp)==SSH_ERROR)
+ goto error;
+ if(ssh_scp_push_file(scp,SCPFILE,bytes,0777) != SSH_OK)
+ goto error;
+ if(args->verbose>0)
+ fprintf(stdout,"Starting upload of %lu bytes now\n",bytes);
+ timestamp_init(&ts);
+ while(total < bytes){
+ unsigned long towrite = bytes - total;
+ int w;
+ if(towrite > 32758)
+ towrite = 32758;
+ w=ssh_scp_write(scp,buffer,towrite);
+ if(w == SSH_ERROR)
+ goto error;
+ total += towrite;
+ }
+ ms=elapsed_time(&ts);
+ *bps=8000 * (float)bytes / ms;
+ if(args->verbose > 0)
+ fprintf(stdout,"Upload took %f ms for %lu bytes, at %f bps\n",ms,
+ bytes,*bps);
+ ssh_scp_close(scp);
+ ssh_scp_free(scp);
+ return 0;
+error:
+ fprintf(stderr,"Error during scp upload : %s\n",ssh_get_error(session));
+ if(scp){
+ ssh_scp_close(scp);
+ ssh_scp_free(scp);
+ }
+ return -1;
+}
+
+/** @internal
+ * @brief benchmarks a scp download using an
+ * existing SSH session.
+ * @param[in] session Open SSH session
+ * @param[in] args Parsed command line arguments
+ * @param[out] bps The calculated bytes per second obtained via benchmark.
+ * @return 0 on success, -1 on error.
+ */
+int benchmarks_scp_down (ssh_session session, struct argument_s *args,
+ float *bps){
+ unsigned long bytes=0x1000000;
+ static char buffer[0x10000];
+ struct timestamp_struct ts;
+ float ms=0.0;
+ unsigned long total=0;
+ ssh_scp scp;
+ int r;
+ size_t size;
+
+ if(args->data != 0)
+ bytes = args->data * 1024 * 1024;
+ scp = ssh_scp_new(session,SSH_SCP_READ,SCPDIR SCPFILE);
+ if(scp == NULL)
+ goto error;
+ if(ssh_scp_init(scp)==SSH_ERROR)
+ goto error;
+ r=ssh_scp_pull_request(scp);
+ if(r == SSH_SCP_REQUEST_NEWFILE){
+ size=ssh_scp_request_get_size(scp);
+ if(bytes > size){
+ printf("Only %d bytes available (on %lu requested).\n",size,bytes);
+ bytes = size;
+ }
+ if(size > bytes){
+ printf("File is %d bytes (on %lu requested). Will cut the end\n",size,bytes);
+ }
+ if(args->verbose>0)
+ fprintf(stdout,"Starting download of %lu bytes now\n",bytes);
+ timestamp_init(&ts);
+ ssh_scp_accept_request(scp);
+ while(total < bytes){
+ unsigned long toread = bytes - total;
+ if(toread > sizeof(buffer))
+ toread = sizeof(buffer);
+ r=ssh_scp_read(scp,buffer,toread);
+ if(r == SSH_ERROR || r == 0)
+ goto error;
+ total += r;
+ }
+ ms=elapsed_time(&ts);
+ *bps=8000 * (float)bytes / ms;
+ if(args->verbose > 0)
+ fprintf(stdout,"download took %f ms for %lu bytes, at %f bps\n",ms,
+ bytes,*bps);
+ } else {
+ fprintf(stderr,"Expected SSH_SCP_REQUEST_NEWFILE, got %d\n",r);
+ goto error;
+ }
+ ssh_scp_close(scp);
+ ssh_scp_free(scp);
+ return 0;
+error:
+ fprintf(stderr,"Error during scp download : %s\n",ssh_get_error(session));
+ if(scp){
+ ssh_scp_close(scp);
+ ssh_scp_free(scp);
+ }
+ return -1;
+}
diff --git a/tests/benchmarks/bench_sftp.c b/tests/benchmarks/bench_sftp.c
new file mode 100644
index 0000000..915d1b7
--- /dev/null
+++ b/tests/benchmarks/bench_sftp.c
@@ -0,0 +1,152 @@
+/* bench_sftp.c
+ *
+ * This file is part of the SSH Library
+ *
+ * Copyright (c) 2011 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 <libssh/libssh.h>
+#include <libssh/sftp.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#define SFTPDIR "/tmp/"
+#define SFTPFILE "scpbenchmark"
+
+/** @internal
+ * @brief benchmarks a synchronous sftp upload using an
+ * existing SSH session.
+ * @param[in] session Open SSH session
+ * @param[in] args Parsed command line arguments
+ * @param[out] bps The calculated bytes per second obtained via benchmark.
+ * @return 0 on success, -1 on error.
+ */
+int benchmarks_sync_sftp_up (ssh_session session, struct argument_s *args,
+ float *bps){
+ unsigned long bytes=0x1000000;
+ static char buffer[0x10000];
+ struct timestamp_struct ts;
+ float ms=0.0;
+ unsigned long total=0;
+ sftp_session sftp;
+ sftp_file file;
+
+ if(args->data != 0)
+ bytes = args->data * 1024 * 1024;
+ sftp = sftp_new(session);
+ if(sftp == NULL)
+ goto error;
+ if(sftp_init(sftp)==SSH_ERROR)
+ goto error;
+ file = sftp_open(sftp,SFTPDIR SFTPFILE,O_RDWR | O_CREAT | O_TRUNC, 0777);
+ if(!file)
+ goto error;
+ if(args->verbose>0)
+ fprintf(stdout,"Starting upload of %lu bytes now\n",bytes);
+ timestamp_init(&ts);
+ while(total < bytes){
+ unsigned long towrite = bytes - total;
+ int w;
+ if(towrite > 32758)
+ towrite = 32758;
+ w=sftp_write(file,buffer,towrite);
+ if(w == SSH_ERROR)
+ goto error;
+ total += w;
+ }
+ sftp_close(file);
+ ms=elapsed_time(&ts);
+ *bps=8000 * (float)bytes / ms;
+ if(args->verbose > 0)
+ fprintf(stdout,"Upload took %f ms for %lu bytes, at %f bps\n",ms,
+ bytes,*bps);
+ sftp_free(sftp);
+ return 0;
+error:
+ fprintf(stderr,"Error during scp upload : %s\n",ssh_get_error(session));
+ if(file)
+ sftp_close(file);
+ if(sftp)
+ sftp_free(sftp);
+ return -1;
+}
+
+/** @internal
+ * @brief benchmarks a synchronous sftp download using an
+ * existing SSH session.
+ * @param[in] session Open SSH session
+ * @param[in] args Parsed command line arguments
+ * @param[out] bps The calculated bytes per second obtained via benchmark.
+ * @return 0 on success, -1 on error.
+ */
+int benchmarks_sync_sftp_down (ssh_session session, struct argument_s *args,
+ float *bps){
+ unsigned long bytes=0x1000000;
+ static char buffer[0x10000];
+ struct timestamp_struct ts;
+ float ms=0.0;
+ unsigned long total=0;
+ sftp_session sftp;
+ sftp_file file;
+ int r;
+
+ if(args->data != 0)
+ bytes = args->data * 1024 * 1024;
+ sftp = sftp_new(session);
+ if(sftp == NULL)
+ goto error;
+ if(sftp_init(sftp)==SSH_ERROR)
+ goto error;
+ file = sftp_open(sftp,SFTPDIR SFTPFILE,O_RDONLY,0);
+ if(!file)
+ goto error;
+ if(args->verbose>0)
+ fprintf(stdout,"Starting download of %lu bytes now\n",bytes);
+ timestamp_init(&ts);
+ while(total < bytes){
+ unsigned long toread = bytes - total;
+ if(toread > sizeof(buffer))
+ toread = sizeof(buffer);
+ r=sftp_read(file,buffer,toread);
+ if(r == SSH_ERROR)
+ goto error;
+ total += r;
+ /* we had a smaller file */
+ if(r==0){
+ fprintf(stdout,"File smaller than expected : %lu (expected %lu).\n",total,bytes);
+ bytes = total;
+ break;
+ }
+ }
+ sftp_close(file);
+ ms=elapsed_time(&ts);
+ *bps=8000 * (float)bytes / ms;
+ if(args->verbose > 0)
+ fprintf(stdout,"download took %f ms for %lu bytes, at %f bps\n",ms,
+ bytes,*bps);
+ sftp_free(sftp);
+ return 0;
+error:
+ fprintf(stderr,"Error during sftp download : %s\n",ssh_get_error(session));
+ if(file)
+ sftp_close(file);
+ if(sftp)
+ sftp_free(sftp);
+ return -1;
+}
diff --git a/tests/benchmarks/benchmarks.c b/tests/benchmarks/benchmarks.c
index 0dd0d0d..3ee57b0 100644
--- a/tests/benchmarks/benchmarks.c
+++ b/tests/benchmarks/benchmarks.c
@@ -27,15 +27,43 @@
#include <stdlib.h>
#include <stdio.h>
-const char *libssh_benchmarks_names[]={
- "benchmark_raw_upload",
- "benchmark_raw_download"
+struct benchmark benchmarks[]= {
+ {
+ .name="benchmark_raw_upload",
+ .fct=benchmarks_raw_up,
+ .enabled=0
+ },
+ {
+ .name="benchmark_raw_download",
+ .fct=benchmarks_raw_down,
+ .enabled=0
+ },
+ {
+ .name="benchmark_scp_upload",
+ .fct=benchmarks_scp_up,
+ .enabled=0
+ },
+ {
+ .name="benchmark_scp_download",
+ .fct=benchmarks_scp_down,
+ .enabled=0
+ },
+ {
+ .name="benchmark_sync_sftp_upload",
+ .fct=benchmarks_sync_sftp_up,
+ .enabled=0
+ },
+ {
+ .name="benchmark_sync_sftp_download",
+ .fct=benchmarks_sync_sftp_down,
+ .enabled=0
+ }
};
#ifdef HAVE_ARGP_H
#include <argp.h>
-const char *argp_program_version = "libssh benchmarks 2010-12-28";
+const char *argp_program_version = "libssh benchmarks 2011-08-28";
const char *argp_program_bug_address = "Aris Adamantiadis <aris@0xbadc0de.be>";
static char **cmdline;
@@ -71,6 +99,40 @@ static struct argp_option options[] = {
.group = 0
},
{
+ .name = "scp-upload",
+ .key = '3',
+ .arg = NULL,
+ .flags = 0,
+ .doc = "Upload data using SCP",
+ .group = 0
+ },
+ {
+ .name = "scp-download",
+ .key = '4',
+ .arg = NULL,
+ .flags = 0,
+ .doc = "Download data using SCP",
+ .group = 0
+ },
+ {
+ .name = "sync-sftp-upload",
+ .key = '5',
+ .arg = NULL,
+ .flags = 0,
+ .doc = "Upload data using synchronous SFTP",
+ .group = 0
+
+ },
+ {
+ .name = "sync-sftp-download",
+ .key = '6',
+ .arg = NULL,
+ .flags = 0,
+ .doc = "Download data using synchronous SFTP",
+ .group = 0
+
+ },
+ {
.name = "host",
.key = 'h',
.arg = "HOST",
@@ -102,7 +164,11 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) {
switch (key) {
case '1':
case '2':
- arguments->benchmarks[key - '1'] = 1;
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ benchmarks[key - '1'].enabled = 1;
arguments->ntests ++;
break;
case 'v':
@@ -193,7 +259,9 @@ static void do_benchmarks(ssh_session session, struct argument_s *arguments,
float ping_rtt=0.0;
float ssh_rtt=0.0;
float bps=0.0;
+ int i;
int err;
+ struct benchmark *b;
if(arguments->verbose>0)
fprintf(stdout,"Testing ICMP RTT\n");
@@ -205,18 +273,13 @@ static void do_benchmarks(ssh_session session, struct argument_s *arguments,
if(err==0){
fprintf(stdout, "SSH RTT : %f ms\n",ssh_rtt);
}
- if(arguments->benchmarks[BENCHMARK_RAW_UPLOAD]){
- err=benchmarks_raw_up(session,arguments,&bps);
- if(err==0){
- fprintf(stdout, "%s : %s : %s\n",hostname,
- libssh_benchmarks_names[BENCHMARK_RAW_UPLOAD], network_speed(bps));
- }
- }
- if(arguments->benchmarks[BENCHMARK_RAW_DOWNLOAD]){
- err=benchmarks_raw_down(session,arguments,&bps);
- if(err==0){
- fprintf(stdout, "%s : %s : %s\n",hostname,
- libssh_benchmarks_names[BENCHMARK_RAW_DOWNLOAD], network_speed(bps));
+ for (i=0 ; i<BENCHMARK_NUMBER ; ++i){
+ b = &benchmarks[i];
+ if(b->enabled){
+ err=b->fct(session,arguments,&bps);
+ if(err==0){
+ fprintf(stdout, "%s : %s : %s\n",hostname, b->name, network_speed(bps));
+ }
}
}
}
@@ -234,7 +297,7 @@ int main(int argc, char **argv){
}
if (arguments.ntests==0){
for(i=0; i < BENCHMARK_NUMBER ; ++i){
- arguments.benchmarks[i]=1;
+ benchmarks[i].enabled=1;
}
arguments.ntests=BENCHMARK_NUMBER;
}
@@ -245,8 +308,8 @@ int main(int argc, char **argv){
}
fprintf(stdout,"with benchmarks ");
for(i=0;i<BENCHMARK_NUMBER;++i){
- if(arguments.benchmarks[i])
- fprintf(stdout,"\"%s\" ",libssh_benchmarks_names[i]);
+ if(benchmarks[i].enabled)
+ fprintf(stdout,"\"%s\" ",benchmarks[i].name);
}
fprintf(stdout,"\n");
}
@@ -258,7 +321,7 @@ int main(int argc, char **argv){
if(session != NULL && arguments.verbose > 0)
fprintf(stdout,"Success\n");
if(session == NULL){
- fprintf(stderr,"Errors occured, stopping\n");
+ fprintf(stderr,"Errors occurred, stopping\n");
return EXIT_FAILURE;
}
do_benchmarks(session, &arguments, arguments.hosts[i]);
diff --git a/tests/benchmarks/benchmarks.h b/tests/benchmarks/benchmarks.h
index ffa1bfa..4aba143 100644
--- a/tests/benchmarks/benchmarks.h
+++ b/tests/benchmarks/benchmarks.h
@@ -32,18 +32,30 @@
enum libssh_benchmarks {
BENCHMARK_RAW_UPLOAD=0,
BENCHMARK_RAW_DOWNLOAD,
+ BENCHMARK_SCP_UPLOAD,
+ BENCHMARK_SCP_DOWNLOAD,
+ BENCHMARK_SYNC_SFTP_UPLOAD,
+ BENCHMARK_SYNC_SFTP_DOWNLOAD,
BENCHMARK_NUMBER
};
struct argument_s {
const char *hosts[MAX_HOSTS_CONNECT];
- char benchmarks[BENCHMARK_NUMBER];
int verbose;
int nhosts;
int ntests;
int data;
};
+typedef int (*bench_fct)(ssh_session session, struct argument_s *args,
+ float *bps);
+
+struct benchmark {
+ const char *name;
+ bench_fct fct;
+ int enabled;
+};
+
/* latency.c */
struct timestamp_struct {
@@ -63,4 +75,17 @@ int benchmarks_raw_up (ssh_session session, struct argument_s *args,
int benchmarks_raw_down (ssh_session session, struct argument_s *args,
float *bps);
+/* bench_scp.c */
+
+int benchmarks_scp_up (ssh_session session, struct argument_s *args,
+ float *bps);
+int benchmarks_scp_down (ssh_session session, struct argument_s *args,
+ float *bps);
+
+/* bench_sftp.c */
+
+int benchmarks_sync_sftp_up (ssh_session session, struct argument_s *args,
+ float *bps);
+int benchmarks_sync_sftp_down (ssh_session session, struct argument_s *args,
+ float *bps);
#endif /* BENCHMARKS_H_ */