mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 12:20:42 +09:00
torture_sftp_aio.c: Change the tests according to aio api changes
The tests have been changed such that the return value of sftp_aio_begin_*() functions is expected to be a ssize_t which indicates the number of bytes for which the function sent a read/write request or error. Tests for trying to read/write bytes more than the max limit enforced by the API have also been added. The negative tests for reading and writing have also been seperated for the sake of clarity. Signed-off-by: Eshan Kelkar <eshankelkar@galorithm.com> Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
committed by
Jakub Jelen
parent
188a9cf68f
commit
d73a0acef7
@@ -60,13 +60,13 @@ static int session_teardown(void **state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void torture_sftp_aio_read(void **state)
|
||||
static void torture_sftp_aio_read_file(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
struct torture_sftp *t = s->ssh.tsftp;
|
||||
|
||||
struct {
|
||||
char buf[MAX_XFER_BUF_SIZE];
|
||||
char *buf;
|
||||
ssize_t bytes_read;
|
||||
} a = {0}, b = {0};
|
||||
|
||||
@@ -74,17 +74,31 @@ static void torture_sftp_aio_read(void **state)
|
||||
sftp_attributes file_attr = NULL;
|
||||
int fd;
|
||||
|
||||
size_t chunk_size = MAX_XFER_BUF_SIZE;
|
||||
size_t chunk_size;
|
||||
int in_flight_requests = 20;
|
||||
|
||||
sftp_aio aio = NULL;
|
||||
struct ssh_list *aio_queue = NULL;
|
||||
sftp_limits_t li = NULL;
|
||||
|
||||
size_t file_size;
|
||||
size_t bytes_requested;
|
||||
size_t total_bytes_requested;
|
||||
size_t to_read, total_bytes_read;
|
||||
ssize_t bytes_requested;
|
||||
|
||||
int i, rc;
|
||||
|
||||
/* Get the max limit for reading, use it as the chunk size */
|
||||
li = sftp_limits(t->sftp);
|
||||
assert_non_null(li);
|
||||
chunk_size = li->max_read_length;
|
||||
|
||||
a.buf = calloc(chunk_size, 1);
|
||||
assert_non_null(a.buf);
|
||||
|
||||
b.buf = calloc(chunk_size, 1);
|
||||
assert_non_null(b.buf);
|
||||
|
||||
aio_queue = ssh_list_new();
|
||||
assert_non_null(aio_queue);
|
||||
|
||||
@@ -99,18 +113,18 @@ static void torture_sftp_aio_read(void **state)
|
||||
assert_non_null(file_attr);
|
||||
file_size = file_attr->size;
|
||||
|
||||
bytes_requested = 0;
|
||||
total_bytes_requested = 0;
|
||||
for (i = 0;
|
||||
i < in_flight_requests && bytes_requested < file_size;
|
||||
i < in_flight_requests && total_bytes_requested < file_size;
|
||||
++i) {
|
||||
to_read = file_size - bytes_requested;
|
||||
to_read = file_size - total_bytes_requested;
|
||||
if (to_read > chunk_size) {
|
||||
to_read = chunk_size;
|
||||
}
|
||||
|
||||
rc = sftp_aio_begin_read(file, to_read, &aio);
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
bytes_requested += to_read;
|
||||
bytes_requested = sftp_aio_begin_read(file, to_read, &aio);
|
||||
assert_int_equal(bytes_requested, to_read);
|
||||
total_bytes_requested += bytes_requested;
|
||||
|
||||
/* enqueue */
|
||||
rc = ssh_list_append(aio_queue, aio);
|
||||
@@ -119,7 +133,7 @@ static void torture_sftp_aio_read(void **state)
|
||||
|
||||
total_bytes_read = 0;
|
||||
while ((aio = ssh_list_pop_head(sftp_aio, aio_queue)) != NULL) {
|
||||
a.bytes_read = sftp_aio_wait_read(&aio, a.buf, sizeof(a.buf));
|
||||
a.bytes_read = sftp_aio_wait_read(&aio, a.buf, chunk_size);
|
||||
assert_int_not_equal(a.bytes_read, SSH_ERROR);
|
||||
|
||||
total_bytes_read += (size_t)a.bytes_read;
|
||||
@@ -129,9 +143,8 @@ static void torture_sftp_aio_read(void **state)
|
||||
* Failure of this assertion means that a short
|
||||
* read is encountered but we have not reached
|
||||
* the end of file yet. A short read before reaching
|
||||
* the end of file should not occur for disk files
|
||||
* according to the SFTP protocol. (In our code the
|
||||
* file SSH_EXECUTABLE being read is a disk file)
|
||||
* the end of file should not occur for our test where
|
||||
* the chunk size respects the max limit for reading.
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -147,19 +160,19 @@ static void torture_sftp_aio_read(void **state)
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
/* Issue more read requests if needed */
|
||||
if (bytes_requested == file_size) {
|
||||
if (total_bytes_requested == file_size) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* else issue more requests */
|
||||
to_read = file_size - bytes_requested;
|
||||
to_read = file_size - total_bytes_requested;
|
||||
if (to_read > chunk_size) {
|
||||
to_read = chunk_size;
|
||||
}
|
||||
|
||||
rc = sftp_aio_begin_read(file, to_read, &aio);
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
bytes_requested += to_read;
|
||||
bytes_requested = sftp_aio_begin_read(file, to_read, &aio);
|
||||
assert_int_equal(bytes_requested, to_read);
|
||||
total_bytes_requested += bytes_requested;
|
||||
|
||||
/* enqueue */
|
||||
rc = ssh_list_append(aio_queue, aio);
|
||||
@@ -170,20 +183,59 @@ static void torture_sftp_aio_read(void **state)
|
||||
* Check whether sftp server responds with an
|
||||
* eof for more requests.
|
||||
*/
|
||||
rc = sftp_aio_begin_read(file, chunk_size, &aio);
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
bytes_requested = sftp_aio_begin_read(file, chunk_size, &aio);
|
||||
assert_int_equal(bytes_requested, chunk_size);
|
||||
|
||||
a.bytes_read = sftp_aio_wait_read(&aio, a.buf, sizeof(a.buf));
|
||||
a.bytes_read = sftp_aio_wait_read(&aio, a.buf, chunk_size);
|
||||
assert_int_equal(a.bytes_read, 0);
|
||||
|
||||
/* Cleanup */
|
||||
/* Clean up */
|
||||
sftp_attributes_free(file_attr);
|
||||
close(fd);
|
||||
sftp_close(file);
|
||||
ssh_list_free(aio_queue);
|
||||
free(b.buf);
|
||||
free(a.buf);
|
||||
sftp_limits_free(li);
|
||||
}
|
||||
|
||||
static void torture_sftp_aio_write(void **state)
|
||||
static void torture_sftp_aio_read_more_than_cap(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
struct torture_sftp *t = s->ssh.tsftp;
|
||||
|
||||
sftp_limits_t li = NULL;
|
||||
sftp_file file = NULL;
|
||||
sftp_aio aio = NULL;
|
||||
|
||||
char *buf = NULL;
|
||||
ssize_t bytes;
|
||||
|
||||
/* Get the max limit for reading */
|
||||
li = sftp_limits(t->sftp);
|
||||
assert_non_null(li);
|
||||
|
||||
file = sftp_open(t->sftp, SSH_EXECUTABLE, O_RDONLY, 0);
|
||||
assert_non_null(file);
|
||||
|
||||
/* Try reading more than the max limit */
|
||||
bytes = sftp_aio_begin_read(file,
|
||||
li->max_read_length * 2,
|
||||
&aio);
|
||||
assert_int_equal(bytes, li->max_read_length);
|
||||
|
||||
buf = calloc(li->max_read_length, 1);
|
||||
assert_non_null(buf);
|
||||
|
||||
bytes = sftp_aio_wait_read(&aio, buf, li->max_read_length);
|
||||
assert_int_not_equal(bytes, SSH_ERROR);
|
||||
|
||||
free(buf);
|
||||
sftp_close(file);
|
||||
sftp_limits_free(li);
|
||||
}
|
||||
|
||||
static void torture_sftp_aio_write_file(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
struct torture_sftp *t = s->ssh.tsftp;
|
||||
@@ -193,15 +245,29 @@ static void torture_sftp_aio_write(void **state)
|
||||
int fd;
|
||||
|
||||
struct {
|
||||
char buf[MAX_XFER_BUF_SIZE];
|
||||
char *buf;
|
||||
ssize_t bytes;
|
||||
} wr = {0}, rd = {0};
|
||||
|
||||
int in_flight_requests;
|
||||
size_t chunk_size;
|
||||
ssize_t bytes_requested;
|
||||
int in_flight_requests = 2;
|
||||
|
||||
sftp_limits_t li = NULL;
|
||||
sftp_aio *aio_queue = NULL;
|
||||
int rc, i;
|
||||
|
||||
in_flight_requests = 2;
|
||||
/* Get the max limit for writing, use it as the chunk size */
|
||||
li = sftp_limits(t->sftp);
|
||||
assert_non_null(li);
|
||||
chunk_size = li->max_write_length;
|
||||
|
||||
rd.buf = calloc(chunk_size, 1);
|
||||
assert_non_null(rd.buf);
|
||||
|
||||
wr.buf = calloc(chunk_size, 1);
|
||||
assert_non_null(wr.buf);
|
||||
|
||||
aio_queue = malloc(sizeof(sftp_aio) * in_flight_requests);
|
||||
assert_non_null(aio_queue);
|
||||
|
||||
@@ -214,13 +280,16 @@ static void torture_sftp_aio_write(void **state)
|
||||
assert_int_not_equal(fd, -1);
|
||||
|
||||
for (i = 0; i < in_flight_requests; ++i) {
|
||||
rc = sftp_aio_begin_write(file, wr.buf, sizeof(wr.buf), &aio_queue[i]);
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
bytes_requested = sftp_aio_begin_write(file,
|
||||
wr.buf,
|
||||
chunk_size,
|
||||
&aio_queue[i]);
|
||||
assert_int_equal(bytes_requested, chunk_size);
|
||||
}
|
||||
|
||||
for (i = 0; i < in_flight_requests; ++i) {
|
||||
wr.bytes = sftp_aio_wait_write(&aio_queue[i]);
|
||||
assert_int_equal(wr.bytes, sizeof(wr.buf));
|
||||
assert_int_equal(wr.bytes, chunk_size);
|
||||
|
||||
/*
|
||||
* Check whether the bytes written to the file
|
||||
@@ -235,64 +304,121 @@ static void torture_sftp_aio_write(void **state)
|
||||
assert_int_equal(rc, 0);
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
/* Clean up */
|
||||
close(fd);
|
||||
sftp_close(file);
|
||||
free(aio_queue);
|
||||
|
||||
rc = unlink(file_path);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
free(wr.buf);
|
||||
free(rd.buf);
|
||||
sftp_limits_free(li);
|
||||
}
|
||||
|
||||
static void torture_sftp_aio_negative(void **state)
|
||||
static void torture_sftp_aio_write_more_than_cap(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
struct torture_sftp *t = s->ssh.tsftp;
|
||||
|
||||
char buf[MAX_XFER_BUF_SIZE] = {0};
|
||||
sftp_file file = NULL;
|
||||
char file_path[128] = {0};
|
||||
sftp_aio aio = NULL;
|
||||
sftp_limits_t li = NULL;
|
||||
char *buf = NULL;
|
||||
size_t buf_size;
|
||||
|
||||
size_t chunk_size = MAX_XFER_BUF_SIZE;
|
||||
ssize_t bytes_read, bytes_written;
|
||||
char file_path[128] = {0};
|
||||
sftp_file file = NULL;
|
||||
|
||||
sftp_aio aio = NULL;
|
||||
ssize_t bytes;
|
||||
int rc;
|
||||
|
||||
li = sftp_limits(t->sftp);
|
||||
assert_non_null(li);
|
||||
|
||||
buf_size = li->max_write_length * 2;
|
||||
buf = calloc(buf_size, 1);
|
||||
assert_non_null(buf);
|
||||
|
||||
snprintf(file_path, sizeof(file_path),
|
||||
"%s/libssh_sftp_aio_write_test_cap", t->testdir);
|
||||
file = sftp_open(t->sftp, file_path, O_CREAT | O_WRONLY, 0777);
|
||||
assert_non_null(file);
|
||||
|
||||
/* Try writing more than the max limit for writing */
|
||||
bytes = sftp_aio_begin_write(file, buf, buf_size, &aio);
|
||||
assert_int_equal(bytes, li->max_write_length);
|
||||
|
||||
bytes = sftp_aio_wait_write(&aio);
|
||||
assert_int_equal(bytes, li->max_write_length);
|
||||
|
||||
/* Clean up */
|
||||
sftp_close(file);
|
||||
|
||||
rc = unlink(file_path);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
free(buf);
|
||||
sftp_limits_free(li);
|
||||
}
|
||||
|
||||
static void torture_sftp_aio_read_negative(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
struct torture_sftp *t = s->ssh.tsftp;
|
||||
|
||||
char *buf = NULL;
|
||||
sftp_file file = NULL;
|
||||
sftp_aio aio = NULL;
|
||||
sftp_limits_t li = NULL;
|
||||
|
||||
size_t chunk_size;
|
||||
ssize_t bytes;
|
||||
int rc;
|
||||
|
||||
li = sftp_limits(t->sftp);
|
||||
assert_non_null(li);
|
||||
chunk_size = li->max_read_length;
|
||||
|
||||
buf = calloc(chunk_size, 1);
|
||||
assert_non_null(buf);
|
||||
|
||||
/* Open a file for reading */
|
||||
file = sftp_open(t->sftp, SSH_EXECUTABLE, O_RDONLY, 0);
|
||||
assert_non_null(file);
|
||||
|
||||
/* Negative tests for reading start */
|
||||
|
||||
/* Passing NULL as the sftp file handle */
|
||||
rc = sftp_aio_begin_read(NULL, chunk_size, &aio);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
bytes = sftp_aio_begin_read(NULL, chunk_size, &aio);
|
||||
assert_int_equal(bytes, SSH_ERROR);
|
||||
|
||||
/* Passing 0 as the number of bytes to read */
|
||||
rc = sftp_aio_begin_read(file, 0, &aio);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
bytes = sftp_aio_begin_read(file, 0, &aio);
|
||||
assert_int_equal(bytes, SSH_ERROR);
|
||||
|
||||
/* Passing NULL instead of a pointer to a location to store an aio handle */
|
||||
rc = sftp_aio_begin_read(file, chunk_size, NULL);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
/*
|
||||
* Passing NULL instead of a pointer to a location to
|
||||
* store an aio handle.
|
||||
*/
|
||||
bytes = sftp_aio_begin_read(file, chunk_size, NULL);
|
||||
assert_int_equal(bytes, SSH_ERROR);
|
||||
|
||||
/* Passing NULL instead of a pointer to an aio handle */
|
||||
bytes_read = sftp_aio_wait_read(NULL, buf, sizeof(buf));
|
||||
assert_int_equal(bytes_read, SSH_ERROR);
|
||||
bytes = sftp_aio_wait_read(NULL, buf, sizeof(buf));
|
||||
assert_int_equal(bytes, SSH_ERROR);
|
||||
|
||||
/* Passing NULL as the buffer's address */
|
||||
rc = sftp_aio_begin_read(file, chunk_size, &aio);
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
bytes = sftp_aio_begin_read(file, chunk_size, &aio);
|
||||
assert_int_equal(bytes, chunk_size);
|
||||
|
||||
bytes_read = sftp_aio_wait_read(&aio, NULL, sizeof(buf));
|
||||
assert_int_equal(bytes_read, SSH_ERROR);
|
||||
bytes = sftp_aio_wait_read(&aio, NULL, sizeof(buf));
|
||||
assert_int_equal(bytes, SSH_ERROR);
|
||||
|
||||
/* Passing 0 as the buffer size */
|
||||
rc = sftp_aio_begin_read(file, chunk_size, &aio);
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
bytes = sftp_aio_begin_read(file, chunk_size, &aio);
|
||||
assert_int_equal(bytes, chunk_size);
|
||||
|
||||
bytes_read = sftp_aio_wait_read(&aio, buf, 0);
|
||||
assert_int_equal(bytes_read, SSH_ERROR);
|
||||
bytes = sftp_aio_wait_read(&aio, buf, 0);
|
||||
assert_int_equal(bytes, SSH_ERROR);
|
||||
|
||||
/*
|
||||
* Test for the scenario when the number
|
||||
@@ -301,62 +427,101 @@ static void torture_sftp_aio_negative(void **state)
|
||||
rc = sftp_seek(file, 0); /* Seek to the start of file */
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
rc = sftp_aio_begin_read(file, 2, &aio);
|
||||
assert_int_equal(rc, SSH_OK);
|
||||
bytes = sftp_aio_begin_read(file, 2, &aio);
|
||||
assert_int_equal(bytes, 2);
|
||||
|
||||
bytes_read = sftp_aio_wait_read(&aio, buf, 1);
|
||||
assert_int_equal(bytes_read, SSH_ERROR);
|
||||
bytes = sftp_aio_wait_read(&aio, buf, 1);
|
||||
assert_int_equal(bytes, SSH_ERROR);
|
||||
|
||||
sftp_close(file);
|
||||
free(buf);
|
||||
sftp_limits_free(li);
|
||||
}
|
||||
|
||||
static void torture_sftp_aio_write_negative(void **state)
|
||||
{
|
||||
struct torture_state *s = *state;
|
||||
struct torture_sftp *t = s->ssh.tsftp;
|
||||
|
||||
char *buf = NULL;
|
||||
|
||||
char file_path[128] = {0};
|
||||
sftp_file file = NULL;
|
||||
sftp_aio aio = NULL;
|
||||
sftp_limits_t li = NULL;
|
||||
|
||||
size_t chunk_size;
|
||||
ssize_t bytes;
|
||||
int rc;
|
||||
|
||||
li = sftp_limits(t->sftp);
|
||||
assert_non_null(li);
|
||||
chunk_size = li->max_write_length;
|
||||
|
||||
buf = calloc(chunk_size, 1);
|
||||
assert_non_null(buf);
|
||||
|
||||
/* Open a file for writing */
|
||||
snprintf(file_path, sizeof(file_path),
|
||||
"%s/libssh_sftp_aio_write_test", t->testdir);
|
||||
"%s/libssh_sftp_aio_write_test_negative", t->testdir);
|
||||
file = sftp_open(t->sftp, file_path, O_CREAT | O_WRONLY, 0777);
|
||||
assert_non_null(file);
|
||||
|
||||
/* Negative tests for writing start */
|
||||
|
||||
/* Passing NULL as the sftp file handle */
|
||||
rc = sftp_aio_begin_write(NULL, buf, MAX_XFER_BUF_SIZE, &aio);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
bytes = sftp_aio_begin_write(NULL, buf, chunk_size, &aio);
|
||||
assert_int_equal(bytes, SSH_ERROR);
|
||||
|
||||
/* Passing NULL as the buffer's address */
|
||||
rc = sftp_aio_begin_write(file, NULL, MAX_XFER_BUF_SIZE, &aio);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
bytes = sftp_aio_begin_write(file, NULL, chunk_size, &aio);
|
||||
assert_int_equal(bytes, SSH_ERROR);
|
||||
|
||||
/* Passing 0 as the size of buffer */
|
||||
rc = sftp_aio_begin_write(file, buf, 0, &aio);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
bytes = sftp_aio_begin_write(file, buf, 0, &aio);
|
||||
assert_int_equal(bytes, SSH_ERROR);
|
||||
|
||||
/* Passing NULL instead of a pointer to a location to store an aio handle */
|
||||
rc = sftp_aio_begin_write(file, buf, MAX_XFER_BUF_SIZE, NULL);
|
||||
assert_int_equal(rc, SSH_ERROR);
|
||||
bytes = sftp_aio_begin_write(file, buf, chunk_size, NULL);
|
||||
assert_int_equal(bytes, SSH_ERROR);
|
||||
|
||||
/* Passing NULL instead of a pointer to an aio handle */
|
||||
bytes_written = sftp_aio_wait_write(NULL);
|
||||
assert_int_equal(bytes_written, SSH_ERROR);
|
||||
bytes = sftp_aio_wait_write(NULL);
|
||||
assert_int_equal(bytes, SSH_ERROR);
|
||||
|
||||
sftp_close(file);
|
||||
rc = unlink(file_path);
|
||||
assert_int_equal(rc, 0);
|
||||
|
||||
free(buf);
|
||||
sftp_limits_free(li);
|
||||
}
|
||||
|
||||
int torture_run_tests(void)
|
||||
{
|
||||
int rc;
|
||||
struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test_setup_teardown(torture_sftp_aio_read,
|
||||
cmocka_unit_test_setup_teardown(torture_sftp_aio_read_file,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
|
||||
cmocka_unit_test_setup_teardown(torture_sftp_aio_write,
|
||||
cmocka_unit_test_setup_teardown(torture_sftp_aio_read_more_than_cap,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
|
||||
cmocka_unit_test_setup_teardown(torture_sftp_aio_negative,
|
||||
cmocka_unit_test_setup_teardown(torture_sftp_aio_write_file,
|
||||
session_setup,
|
||||
session_teardown)
|
||||
session_teardown),
|
||||
|
||||
cmocka_unit_test_setup_teardown(torture_sftp_aio_write_more_than_cap,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
|
||||
cmocka_unit_test_setup_teardown(torture_sftp_aio_read_negative,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
|
||||
cmocka_unit_test_setup_teardown(torture_sftp_aio_write_negative,
|
||||
session_setup,
|
||||
session_teardown),
|
||||
};
|
||||
|
||||
ssh_init();
|
||||
|
||||
Reference in New Issue
Block a user