From c4eeffd6a90e814750262b509a6e1924a4d649c7 Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Mon, 29 Jun 2026 16:56:28 +0300 Subject: [PATCH] testing: supplement of file_upload --- src/components/file_p/file_p.c | 27 +++++++++--- test/file_p/file_upload.c | 77 +++++++++++++++++++++++++++++----- 2 files changed, 89 insertions(+), 15 deletions(-) diff --git a/src/components/file_p/file_p.c b/src/components/file_p/file_p.c index b346baf..5f14bee 100644 --- a/src/components/file_p/file_p.c +++ b/src/components/file_p/file_p.c @@ -361,6 +361,23 @@ void file_download(session *sess) { } } +#define file_upload_write(sess, dest_d, buf, len) \ + { \ + int res = write(dest_d, buf, len); \ + if (res == -1) { \ + session_send_string( \ + sess, "There is an error sending the file named \"%s\"\n"); \ + char *err_mes = strerror(errno); \ + print_log(stdout, pl_error, "Error uploading the file \"%s\": %s\n", \ + sess->file->name, err_mes); \ + close(dest_d); \ + unlink(sess->file->path); /* remove file */ \ + clear_file_from_sess(sess); \ + sess->state = OP_WAIT; \ + return; \ + } \ + } + /* upload to the server */ void file_upload(session *sess) { int source_d = sess->sd; @@ -381,8 +398,7 @@ void file_upload(session *sess) { } if (sess->file->package_rest < rlen) { - /* TODO: wrap write function to give a proper response if the write is failed */ - write(dest_d, buf, sess->file->package_rest); + file_upload_write(sess, dest_d, buf, sess->file->package_rest); rlen -= sess->file->package_rest; sess->file->rest -= sess->file->package_rest; if (rlen == 0) @@ -399,8 +415,9 @@ void file_upload(session *sess) { /* TODO: return back the extra data to the buffer in order to process * it */ } - write(dest_d, buf + sess->file->package_rest + sizeof(s_file_pd_t), - rlen); + file_upload_write(sess, dest_d, + buf + sess->file->package_rest + sizeof(s_file_pd_t), + rlen); sess->file->rest -= rlen; } sess->file->package_rest = fpd->package_size - rlen; @@ -419,7 +436,7 @@ void file_upload(session *sess) { break; } } else { - write(dest_d, buf, rlen); + file_upload_write(sess, dest_d, buf, rlen); sess->file->rest -= rlen; sess->file->package_rest -= rlen; } diff --git a/test/file_p/file_upload.c b/test/file_p/file_upload.c index d61e09a..61f55d5 100644 --- a/test/file_p/file_upload.c +++ b/test/file_p/file_upload.c @@ -13,7 +13,7 @@ #define FNAME "Test file" #define ITERATIONS 100 -#define FSIZE PACKAGE_SIZE * ITERATIONS +#define FSIZE PACKAGE_SIZE *ITERATIONS dbuf_t *dbuf = NULL; int read_ret_zero = 0; @@ -30,9 +30,7 @@ void __wrap_session_send_string(struct session *sess, const char *fmt, ...) { assert_string_equal(fmt, str2snd); } -int __wrap_unlink(const char *__name) { - return 0; -} +int __wrap_unlink(const char *__name) { return 0; } ssize_t __wrap_read(int __fd, void *__buf, size_t __nbytes) { if (read_ret_zero) { @@ -67,7 +65,7 @@ ssize_t __wrap_write(int __fd, const void *__buf, size_t __n) { int32_t __wrap_db_save_file(session *s) { return 1; } -void test__file_upload__normal(void **state) { +void test__file_upload__success(void **state) { dbuf = dbuf_init(INBUFSIZE); session sess = {.state = OP_DOWNLOAD}; @@ -78,7 +76,6 @@ void test__file_upload__normal(void **state) { sess.file->path = malloc(sizeof(char) * INBUFSIZE); sess.file->description = malloc(sizeof(char) * INBUFSIZE); strcpy(sess.file->name, FNAME); - char cont_mes[64]; str2snd = "finished\n"; const char *fmt_args[] = {"File %s is uploaded to the server\n", FNAME, NULL}; @@ -102,7 +99,6 @@ void test__file_upload__no_read(void **state) { sess.file->path = malloc(sizeof(char) * INBUFSIZE); sess.file->description = malloc(sizeof(char) * INBUFSIZE); strcpy(sess.file->name, FNAME); - char cont_mes[64]; read_ret_zero = true; const char *fmt_args[] = {"Error uploading file %s!\n", FNAME, NULL}; @@ -126,17 +122,77 @@ void test__file_upload__canceled(void **state) { sess.file->path = malloc(sizeof(char) * INBUFSIZE); sess.file->description = malloc(sizeof(char) * INBUFSIZE); strcpy(sess.file->name, FNAME); - char cont_mes[64]; const char *fmt_args[] = {"Upload of %s is cancelled!\n", FNAME, NULL}; print_str_arr = fmt_args; for (int i = 0; (sess.state != OP_WAIT) && (i < 2000000000); i++) { - if (i == 100) signal = sig_cancel; + if (i == 100) + signal = sig_cancel; file_upload(&sess); } assert_int_equal(sess.state, OP_WAIT); assert_ptr_equal(sess.file, NULL); + signal = sig_continue; +} + +void test__file_upload__no_write_1(void **state) { + dbuf = dbuf_init(INBUFSIZE); + + session sess = {.state = OP_DOWNLOAD}; + sess.file = malloc(sizeof(s_file_t)); + sess.file->name = malloc(sizeof FNAME); + sess.file->size = sess.file->rest = FSIZE; + sess.file->package_rest = package_rest = PACKAGE_SIZE; + sess.file->path = malloc(sizeof(char) * INBUFSIZE); + sess.file->description = malloc(sizeof(char) * INBUFSIZE); + strcpy(sess.file->name, FNAME); + str2snd = "There is an error sending the file named \"%s\"\n"; + + const char *fmt_args[] = {"Error uploading the file \"%s\": %s\n", FNAME, + "No data available", NULL}; + print_str_arr = fmt_args; + + for (int i = 0; (sess.state != OP_WAIT) && (i < 2000000000); i++) { + if (i == 100) { + write_ret_m_1 = true; + errno = ENODATA; + } + file_upload(&sess); + } + + assert_int_equal(sess.state, OP_WAIT); + assert_ptr_equal(sess.file, NULL); +} + +void test__file_upload__no_write_2(void **state) { + dbuf = dbuf_init(INBUFSIZE); + + session sess = {.state = OP_DOWNLOAD}; + sess.file = malloc(sizeof(s_file_t)); + sess.file->name = malloc(sizeof FNAME); + sess.file->size = sess.file->rest = FSIZE; + sess.file->package_rest = package_rest = PACKAGE_SIZE; + sess.file->path = malloc(sizeof(char) * INBUFSIZE); + sess.file->description = malloc(sizeof(char) * INBUFSIZE); + strcpy(sess.file->name, FNAME); + str2snd = "There is an error sending the file named \"%s\"\n"; + + const char *fmt_args[] = {"Error uploading the file \"%s\": %s\n", FNAME, + "No data available", NULL}; + print_str_arr = fmt_args; + + for (int i = 0; (sess.state != OP_WAIT) && (i < 2000000000); i++) { + if (i == 50) { + signal = sig_cancel; + write_ret_m_1 = true; + errno = ENODATA; + } + file_upload(&sess); + } + + assert_int_equal(sess.state, OP_WAIT); + assert_ptr_equal(sess.file, NULL); } int setup(void **state) { return 0; } @@ -144,9 +200,10 @@ int tear_down(void **state) { return 0; } int main(int argc, char **argv) { const struct CMUnitTest tests[] = { - cmocka_unit_test(test__file_upload__normal), + cmocka_unit_test(test__file_upload__success), cmocka_unit_test(test__file_upload__no_read), cmocka_unit_test(test__file_upload__canceled), + cmocka_unit_test(test__file_upload__no_write_1), }; return cmocka_run_group_tests(tests, setup, tear_down);