From fdea1a03c94811360c883398418465c3d800c0c9 Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Wed, 24 Jun 2026 18:08:28 +0300 Subject: [PATCH] tests for file_receive_prepare --- src/components/file_p/file_p.c | 22 +-- test/file_p/CMakeLists.txt | 20 ++- test/file_p/file_receive_prepare.c | 217 +++++++++++++++++++++++++++++ test/file_p/file_send_prepare.c | 4 +- 4 files changed, 252 insertions(+), 11 deletions(-) create mode 100644 test/file_p/file_receive_prepare.c diff --git a/src/components/file_p/file_p.c b/src/components/file_p/file_p.c index f6694c7..ded7114 100644 --- a/src/components/file_p/file_p.c +++ b/src/components/file_p/file_p.c @@ -196,6 +196,8 @@ int32_t file_send_prepare(session *sess, char *line, server_data_t *s_d) { return 0; } +#define ERR_FSV "Can't create a file." + int file_receive_prepare(session *sess, char *line, server_data_t *s_d) { int sd = sess->sd; size_t fsize = 0; @@ -218,18 +220,20 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) { struct statvfs st_str; statvfs(".", &st_str); size_t available_space = st_str.f_bavail * st_str.f_bsize; + if (strlen(sess->file->name) > st_str.f_namemax) { - mes_len = sprintf(mes, "file name is tool long\n"); + mes_len = sprintf(mes, "file name is too long\n"); write(sd, mes, mes_len); sess->state = OP_WAIT; clear_file_from_sess(sess); return -1; } + if (fsize > available_space) { - mes_len = sprintf(mes, "There is no space for such length! (%ld)\n", fsize); + mes_len = sprintf(mes, "There is no space for such size! (%ld)\n", fsize); write(sd, mes, mes_len); clear_file_from_sess(sess); - return -1; + return -2; } char hashed_dir_name[3]; @@ -249,7 +253,11 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) { chdir(STORAGE_FOLDER); if (!directory_exists(hashed_dir_name)) { - mkdir(hashed_dir_name, 0700); + if (mkdir(hashed_dir_name, 0700) != 0) { + write(sd, ERR_FSV, sizeof ERR_FSV - 1); + clear_file_from_sess(sess); + return -4; + } } chdir("../"); @@ -259,12 +267,10 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) { seed++; continue; } - mes_len = sprintf(mes, "Can't create file with such name: \"%s\"\n", - sess->file->name); - write(sd, mes, mes_len); + write(sd, ERR_FSV, sizeof ERR_FSV - 1); clear_file_from_sess(sess); sess->file = NULL; - return -1; + return -3; } break; } diff --git a/test/file_p/CMakeLists.txt b/test/file_p/CMakeLists.txt index 56d5122..2e18164 100644 --- a/test/file_p/CMakeLists.txt +++ b/test/file_p/CMakeLists.txt @@ -63,4 +63,22 @@ target_link_libraries(file_send_prepare target_link_options(file_send_prepare PRIVATE -Wl,--wrap=write,--wrap=print_log,--wrap=lseek,--wrap=open,--wrap=db_get_file) -add_test(NAME file_p_file_send_prepare_test_1 COMMAND file_send_prepare) \ No newline at end of file +add_test(NAME file_p_file_send_prepare_test_1 COMMAND file_send_prepare) + +# ---/ file_receive_prepare /------------------------------------------- + +add_executable(file_receive_prepare + file_receive_prepare.c + utils.c +) + +target_link_libraries(file_receive_prepare + cmocka + file_p + main + utils +) + +target_link_options(file_receive_prepare PRIVATE -Wl,--wrap=stat,--wrap=statvfs,--wrap=print_log,--wrap=open,--wrap=chdir,--wrap=write,--wrap=mkdir) + +add_test(NAME file_p_file_receive_prepare_test_1 COMMAND file_receive_prepare) \ No newline at end of file diff --git a/test/file_p/file_receive_prepare.c b/test/file_p/file_receive_prepare.c new file mode 100644 index 0000000..081a56e --- /dev/null +++ b/test/file_p/file_receive_prepare.c @@ -0,0 +1,217 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include +#include +#include +#include +#include +#include + +#define FSIZE 10233 +#define FSIZE_S "10233" +#define FNAME "Test file" +#define FHASH 211212 +#define FID 19 +#define FID_S "19" +#define ERR_FSV "Can't create a file." +#define STR_LONG \ + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sagittis " \ + "risus et dictum consequat. Cras in fringilla dui. Aenean sed risus eu " \ + "odio pellentesque tincidunt ac id nulla. Duis vel mi ut est finibus " \ + "imperdiet. Praesent auctor convallis metus, quis ultricies dui. Praesent " \ + "sit amet nibh quis elit mattis mollis. Nullam et mattis tortor, eu " \ + "egestas nunc. Sed feugiat porttitor erat quis varius. Curabitur sapien " \ + "est, consectetur consectetur nisi in, tempus gravida leo. Phasellus sit " \ + "amet lorem a erat euismod sagittis eget vel libero. Suspendisse ac est " \ + "aliquam, finibus lacus nec, commodo sapien. Orci varius natoque penatibus " \ + "et magnis dis parturient montes, nascetur ridiculus mus. Aliquam commodo, " \ + "nibh eget laoreet facilisis, nulla sapien mattis massa, ac luctus ex leo " \ + "ut quam. Integer euismod velit in arcu porttitor suscipit. " + +dbuf_t *dbuf; +size_t fs_available = 10; +size_t fs_namemax = 255; +int _errno = 0; + +int __wrap_statvfs(const char *__restrict __file, + struct statvfs *__restrict __buf) { + __buf->f_bavail = fs_available; + __buf->f_bsize = 1024; + __buf->f_namemax = fs_namemax; + return 0; +} + +int __wrap_stat(const char *__restrict __file, struct stat *__restrict __buf) { + return mock_type(int); +} + +int __wrap_mkdir(const char *__path, __mode_t __mode) { return mock_type(int); } + +int __wrap_chdir(const char *__path) { return 0; } + +int __wrap_print_log(FILE *output, enum pl_type type, + const char *format_message, ...) { + return 0; +}; + +ssize_t __wrap_write(int __fd, const void *__buf, size_t __n) __wur { + dbuf_write(__buf, __n, &dbuf); + return __n; +} + +int __wrap_open(const char *__file, int __oflag, ...) { + errno = _errno; + return mock_type(int); +} + +/* CASE: Success */ +void test__file_receive_prepare(void **state) { + dbuf = dbuf_init(INBUFSIZE); + char line[] = "\"" FNAME "\" " FSIZE_S " 1"; + session sess = { + .uname = "user1234", + .sd = 0, + .file = NULL, + }; + int res = 0; + will_return(__wrap_mkdir, 0); + will_return(__wrap_stat, 1); + will_return(__wrap_open, 5); + res = file_receive_prepare(&sess, line, NULL); + assert_int_equal(res, 0); + assert_string_equal("accept", dbuf->ptr); + dbuf_destroy(&dbuf); +} + +/* CASE: File name is too long */ +void test__file_receive_prepare__name_too_long(void **state) { + dbuf = dbuf_init(INBUFSIZE); + char line[] = "\"" STR_LONG "\" " FSIZE_S " 1"; + session sess = { + .uname = "user1234", + .sd = 0, + .file = NULL, + }; + int res = 0; + + res = file_receive_prepare(&sess, line, NULL); + assert_int_equal(res, -1); + assert_string_equal("file name is too long\n", dbuf->ptr); + assert_ptr_equal(sess.file, NULL); + dbuf_destroy(&dbuf); +} + +/* CASE: No enough space */ +void test__file_receive_prepare__no_space(void **state) { + dbuf = dbuf_init(INBUFSIZE); + char line[] = "\"" FNAME "\" " + "20000" + " 1"; + session sess = { + .uname = "user1234", + .sd = 0, + .file = NULL, + }; + int res = 0; + + res = file_receive_prepare(&sess, line, NULL); + assert_int_equal(res, -2); + assert_string_equal("There is no space for such size! (20000)\n", dbuf->ptr); + assert_ptr_equal(sess.file, NULL); + dbuf_destroy(&dbuf); +} + +/* CASE: Can't create directory */ +void test__file_receive_prepare__err_dir(void **state) { + dbuf = dbuf_init(INBUFSIZE); + char line[] = "\"" FNAME "\" " FSIZE_S " 1"; + session sess = { + .uname = "user1234", + .sd = 0, + .file = NULL, + }; + int res = 0; + will_return(__wrap_mkdir, 1); + will_return(__wrap_stat, 1); + res = file_receive_prepare(&sess, line, NULL); + assert_int_equal(res, -4); + assert_ptr_equal(sess.file, NULL); + assert_string_equal(ERR_FSV, dbuf->ptr); + dbuf_destroy(&dbuf); +} + +/* CASE: Error in the file's name */ +void test__file_receive_prepare__name_err(void **state) { + dbuf = dbuf_init(INBUFSIZE); + char line[] = "\"" FNAME "\" " FSIZE_S " 1"; + session sess = { + .uname = "user1234", + .sd = 0, + .file = NULL, + }; + int res = 0; + will_return(__wrap_stat, 1); + will_return(__wrap_mkdir, 0); + will_return(__wrap_open, -1); + _errno = EPERM; + res = file_receive_prepare(&sess, line, NULL); + assert_int_equal(res, -3); + assert_ptr_equal(sess.file, NULL); + assert_string_equal(ERR_FSV, dbuf->ptr); + dbuf_destroy(&dbuf); +} + +/* CASE: File with such name already exist */ +void test__file_receive_prepare__exists(void **state) { + dbuf = dbuf_init(INBUFSIZE); + char line[] = "\"" FNAME "\" " FSIZE_S " 1"; + session sess = { + .uname = "user1234", + .sd = 0, + .file = NULL, + }; + int res = 0; + + /* 1st iteration */ + _errno = EEXIST; + will_return(__wrap_stat, 1); + will_return(__wrap_mkdir, 0); + will_return(__wrap_open, -1); + /* 2nd iteration */ + will_return(__wrap_stat, 1); + will_return(__wrap_mkdir, 0); + will_return(__wrap_open, 5); + + res = file_receive_prepare(&sess, line, NULL); + assert_int_equal(res, 0); + assert_ptr_not_equal(sess.file, NULL); + assert_string_equal("accept", dbuf->ptr); + dbuf_destroy(&dbuf); +} + +int setup(void **state) { return 0; } +int tear_down(void **state) { return 0; } + +int main(int argc, char **argv) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test__file_receive_prepare), + cmocka_unit_test(test__file_receive_prepare__name_too_long), + cmocka_unit_test(test__file_receive_prepare__no_space), + cmocka_unit_test(test__file_receive_prepare__err_dir), + cmocka_unit_test(test__file_receive_prepare__name_err), + cmocka_unit_test(test__file_receive_prepare__exists), + }; + + return cmocka_run_group_tests(tests, setup, tear_down); +} diff --git a/test/file_p/file_send_prepare.c b/test/file_p/file_send_prepare.c index 87d8c92..b84f223 100644 --- a/test/file_p/file_send_prepare.c +++ b/test/file_p/file_send_prepare.c @@ -44,7 +44,7 @@ s_file_t *__wrap_db_get_file(i_get_file_db *arg) { int __wrap_open(const char *__file, int __oflag, ...) { return mock_type(int); } -void test__file_send_prepare(void **state) { +void test__file_receive_prepare(void **state) { s_file_t file = {.name = FNAME, .size = FSIZE, .hash = FHASH, .id = FID}; char line[] = "[" FNAME "]"; session sess = { @@ -128,7 +128,7 @@ int tear_down(void **state) { return 0; } int main(int argc, char **argv) { const struct CMUnitTest tests[] = { - cmocka_unit_test(test__file_send_prepare), + cmocka_unit_test(test__file_receive_prepare), cmocka_unit_test(test__file_send_prepare__no_open), cmocka_unit_test(test__file_send_prepare__db_no_file), cmocka_unit_test(test__file_send_prepare__size_not_correct),