1
1

benchmarks: refactoring + sync sftp tests

no surprise, sync sftp is much slower, even for localhost,
especially for download.
Этот коммит содержится в:
Aris Adamantiadis 2011-08-29 20:13:24 +03:00
родитель faaf334aa3
Коммит b11567ed9b
6 изменённых файлов: 401 добавлений и 27 удалений

Просмотреть файл

@ -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(

Просмотреть файл

@ -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";

Просмотреть файл

@ -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;
}

152
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;
}

Просмотреть файл

@ -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;
@ -70,6 +98,40 @@ static struct argp_option options[] = {
.doc = "Download raw data using channel",
.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',
@ -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]);

Просмотреть файл

@ -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_ */