From 5564c0ac69c833870b98d879a770c17178202d4d Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Tue, 30 Jun 2026 17:09:12 +0300 Subject: [PATCH] testing: file_receive_prepare / file_send_prepare more reliable line processing --- TODO.md | 3 +- src/components/file_p/file_p.c | 44 +++++++++++++++++++----- test/file_p/CMakeLists.txt | 20 ++++++++++- test/file_p/file_receive_prepare.c | 55 +++++++++++++++++++++++++----- test/file_p/file_send_prepare.c | 42 +++++++++++++++++++++-- 5 files changed, 142 insertions(+), 22 deletions(-) diff --git a/TODO.md b/TODO.md index 46fd7bb..8fc2a82 100644 --- a/TODO.md +++ b/TODO.md @@ -1,7 +1,8 @@ ## Tasks # Testing -- [ ] file_receive_prepare / file_send_prepare more reliable line processing +- [x] file_receive_prepare / file_send_prepare more reliable line processing +- [ ] test empty names # Development plans diff --git a/src/components/file_p/file_p.c b/src/components/file_p/file_p.c index 5f14bee..2eec64a 100644 --- a/src/components/file_p/file_p.c +++ b/src/components/file_p/file_p.c @@ -155,8 +155,21 @@ int32_t file_send_prepare(session *sess, char *line, server_data_t *s_d) { char err_mes[256]; int32_t mlen; - char *name_begin = strchr(line, '[') + 1; + char *name_begin = strchr(line, '['); + if (name_begin == NULL) { + session_send_string(sess, + "Error: can't find starting character \"[\" for the file name"); + clear_file_from_sess(sess); + return -4; + } + name_begin += 1; char *name_end = strrchr(line, ']'); + if (name_end == NULL) { + session_send_string(sess, + "Error: can't find ending character \"]\" for the file name"); + clear_file_from_sess(sess); + return -5; + } int name_len = name_end - name_begin; strncpy(args.name, name_begin, name_len); args.name[name_len] = 0; @@ -202,8 +215,20 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) { int sd = sess->sd; size_t fsize = 0; int perm; - char *name_begin = strchr(line, '"') + 1; - char *name_end = strrchr(line, '"'); + char *name_begin = strchr(line, '"'); + if (name_begin == NULL) { + session_send_string(sess, + "Error: can't find starting character \" for the file name"); + clear_file_from_sess(sess); + return -5; + } + name_begin += 1; + char *name_end = strrchr(name_begin, '"'); + if (name_end == NULL) { + session_send_string(sess, "Error: can't find ending character \" for the file name"); + clear_file_from_sess(sess); + return -6; + } int name_len = name_end - name_begin; sscanf(name_end, "\" %zd %d", &fsize, &perm); sess->file = malloc(sizeof(s_file_t)); @@ -222,16 +247,15 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) { 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 too long\n"); - write(sd, mes, mes_len); + session_send_string(sess, "file name is too long\n"); 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 size! (%ld)\n", fsize); - write(sd, mes, mes_len); + session_send_string(sess, "There is no space for such size! (%ld)\n", + fsize); clear_file_from_sess(sess); return -2; } @@ -254,7 +278,7 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) { if (!directory_exists(hashed_dir_name)) { if (mkdir(hashed_dir_name, 0700) != 0) { - write(sd, ERR_FSV, sizeof ERR_FSV - 1); + session_send_string(sess, ERR_FSV); clear_file_from_sess(sess); return -4; } @@ -267,7 +291,7 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) { seed++; continue; } - write(sd, ERR_FSV, sizeof ERR_FSV - 1); + session_send_string(sess, ERR_FSV); clear_file_from_sess(sess); sess->file = NULL; return -3; @@ -275,6 +299,8 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) { break; } + + mes_len = sprintf(mes, "accept"); sess->fd = file_d; sess->file->size = fsize; diff --git a/test/file_p/CMakeLists.txt b/test/file_p/CMakeLists.txt index 196b871..d246b76 100644 --- a/test/file_p/CMakeLists.txt +++ b/test/file_p/CMakeLists.txt @@ -61,12 +61,30 @@ target_link_libraries(file_send_prepare test_utils ) -target_link_options(file_send_prepare PRIVATE -Wl,--wrap=write,--wrap=print_log,--wrap=lseek,--wrap=open,--wrap=db_get_file) +target_link_options(file_send_prepare PRIVATE -Wl,--wrap=write,--wrap=print_log,--wrap=lseek,--wrap=open,--wrap=db_get_file,--wrap=session_send_string) 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 +) + +target_link_libraries(file_receive_prepare + cmocka + file_p + main + utils + test_utils +) + +target_link_options(file_receive_prepare PRIVATE -Wl,--wrap=statvfs,--wrap=stat,--wrap=mkdir,--wrap=chdir,--wrap=write,--wrap=open,--wrap=session_send_string) + +add_test(NAME file_p_file_receive_prepare_test_1 COMMAND file_receive_prepare) + +# ---/ clear_file_from_sess /------------------------------------------- + add_executable(clear_file_from_sess clear_file_from_sess.c ) diff --git a/test/file_p/file_receive_prepare.c b/test/file_p/file_receive_prepare.c index 3a77571..10e4068 100644 --- a/test/file_p/file_receive_prepare.c +++ b/test/file_p/file_receive_prepare.c @@ -10,14 +10,13 @@ #include #include - #include #include #include #include +#include #include #include -#include #define FSIZE 10233 #define FSIZE_S "10233" @@ -44,6 +43,14 @@ dbuf_t *dbuf; size_t fs_available = 10; size_t fs_namemax = 255; int _errno = 0; +char *str2snd = NULL; + +void __wrap_session_send_string(struct session *sess, const char *fmt, ...) { + if (str2snd != NULL) { + assert_string_equal(fmt, str2snd); + str2snd = NULL; + } +} int __wrap_statvfs(const char *__restrict __file, struct statvfs *__restrict __buf) { @@ -72,7 +79,7 @@ int __wrap_open(const char *__file, int __oflag, ...) { } /* CASE: Success */ -void test__file_receive_prepare(void **state) { +void test__file_receive_prepare__regular(void **state) { dbuf = dbuf_init(INBUFSIZE); char line[] = "\"" FNAME "\" " FSIZE_S " 1"; session sess = { @@ -90,6 +97,34 @@ void test__file_receive_prepare(void **state) { dbuf_destroy(&dbuf); } +/* CASE: Name not correct (start) */ +void test__file_receive_prepare_name_not_correct_start(void **state) { + char line[] = FNAME "\" " FSIZE_S " 1"; + str2snd = "Error: can't find ending character \" for the file name"; + session sess = { + .uname = "user1234", + .sd = 0, + .file = NULL, + }; + int res = 0; + res = file_receive_prepare(&sess, line, NULL); + assert_int_equal(res, -6); +} + +/* CASE: Name not correct (end) */ +void test__file_receive_prepare_name_not_correct_end(void **state) { + char line[] = "\"FNAME " FSIZE_S " 1"; + str2snd = "Error: can't find ending character \" for the file name"; + session sess = { + .uname = "user1234", + .sd = 0, + .file = NULL, + }; + int res = 0; + res = file_receive_prepare(&sess, line, NULL); + assert_int_equal(res, -6); +} + /* CASE: File name is too long */ void test__file_receive_prepare__name_too_long(void **state) { dbuf = dbuf_init(INBUFSIZE); @@ -100,10 +135,10 @@ void test__file_receive_prepare__name_too_long(void **state) { .file = NULL, }; int res = 0; + str2snd = "file name is too long\n"; 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); } @@ -120,10 +155,10 @@ void test__file_receive_prepare__no_space(void **state) { .file = NULL, }; int res = 0; + str2snd = "There is no space for such size! (%ld)\n"; 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); } @@ -138,12 +173,12 @@ void test__file_receive_prepare__err_dir(void **state) { .file = NULL, }; int res = 0; + str2snd = ERR_FSV; 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); } @@ -157,6 +192,7 @@ void test__file_receive_prepare__name_err(void **state) { .file = NULL, }; int res = 0; + str2snd = ERR_FSV; will_return(__wrap_stat, 1); will_return(__wrap_mkdir, 0); will_return(__wrap_open, -1); @@ -164,7 +200,6 @@ void test__file_receive_prepare__name_err(void **state) { 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); } @@ -188,11 +223,11 @@ void test__file_receive_prepare__exists(void **state) { will_return(__wrap_stat, 1); will_return(__wrap_mkdir, 0); will_return(__wrap_open, 5); + str2snd = "accept"; 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); } @@ -201,7 +236,9 @@ 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__regular), + cmocka_unit_test(test__file_receive_prepare_name_not_correct_start), + cmocka_unit_test(test__file_receive_prepare_name_not_correct_end), 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), diff --git a/test/file_p/file_send_prepare.c b/test/file_p/file_send_prepare.c index be84756..029ecd1 100644 --- a/test/file_p/file_send_prepare.c +++ b/test/file_p/file_send_prepare.c @@ -15,6 +15,7 @@ #include #include #include +char *str2snd = NULL; dbuf_t *dbuf; @@ -24,6 +25,11 @@ dbuf_t *dbuf; #define FID 19 #define FID_S "19" +void __wrap_session_send_string(struct session *sess, const char *fmt, ...) { + assert_string_equal(fmt, str2snd); + str2snd = NULL; +} + ssize_t __wrap_write(int __fd, const void *__buf, size_t __n) __wur { dbuf_write(__buf, __n, &dbuf); return __n; @@ -40,7 +46,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_receive_prepare(void **state) { +void test__file_receive_prepare__regular(void **state) { s_file_t file = {.name = FNAME, .size = FSIZE, .hash = FHASH, .id = FID}; char line[] = "[" FNAME "]"; session sess = { @@ -61,6 +67,36 @@ void test__file_receive_prepare(void **state) { assert_string_equal(file.path, "./storage/00/03390c"); } +void test__file_receive_prepare__name_not_correct_start(void **state) { + s_file_t file = {.name = FNAME, .size = FSIZE, .hash = FHASH, .id = FID}; + char line[] = FNAME; + str2snd = "Error: can't find starting character \"[\" for the file name"; + session sess = { + .uname = "user1234", + .sd = 0, + .file = NULL, + }; + int res = 0; + res = file_send_prepare(&sess, line, NULL); + assert_int_equal(res, -4); + assert_ptr_equal(sess.file, NULL); +} + +void test__file_receive_prepare__name_not_correct_end(void **state) { + s_file_t file = {.name = FNAME, .size = FSIZE, .hash = FHASH, .id = FID}; + char line[] = "[" FNAME; + str2snd = "Error: can't find ending character \"]\" for the file name"; + session sess = { + .uname = "user1234", + .sd = 0, + .file = NULL, + }; + int res = 0; + res = file_send_prepare(&sess, line, NULL); + assert_int_equal(res, -5); + assert_ptr_equal(sess.file, NULL); +} + void test__file_send_prepare__db_no_file(void **state) { char line[] = "[" FNAME "]"; session sess = { @@ -124,7 +160,9 @@ 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__regular), + cmocka_unit_test(test__file_receive_prepare__name_not_correct_start), + cmocka_unit_test(test__file_receive_prepare__name_not_correct_end), 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),