refactoring; finishing integration of CMocka; several test cases covered

This commit is contained in:
2026-06-12 18:35:33 +03:00
parent 2e33becdbf
commit 814fee67f8
35 changed files with 432 additions and 108 deletions
+1 -1
View File
@@ -41,7 +41,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_subdirectory(src) add_subdirectory(src)
# Testing # Testing
enable_testing() include(CTest)
include(cmake/OptionsCMocka.cmake) include(cmake/OptionsCMocka.cmake)
add_subdirectory(external/cmocka) add_subdirectory(external/cmocka)
add_subdirectory(test) add_subdirectory(test)
+1
View File
@@ -0,0 +1 @@
---
+3
View File
@@ -0,0 +1,3 @@
Start testing: Jun 12 15:32 EEST
----------------------------------------------------------
End testing: Jun 12 15:32 EEST
+11
View File
@@ -10,6 +10,7 @@ target_sources(zbbs-server
) )
add_library(main INTERFACE) add_library(main INTERFACE)
add_library(types INTERFACE)
target_sources(main target_sources(main
PUBLIC PUBLIC
@@ -18,6 +19,13 @@ target_sources(main
main.h main.h
) )
target_sources(types
PUBLIC
FILE_SET HEADERS
FILES
types.h
)
add_subdirectory(libs) add_subdirectory(libs)
add_subdirectory(db) add_subdirectory(db)
@@ -29,6 +37,9 @@ target_link_libraries(zbbs-server
client client
db db
murmur3 murmur3
types
server
utils
OpenSSL::Crypto OpenSSL::Crypto
) )
+4
View File
@@ -1,2 +1,6 @@
add_subdirectory(client) add_subdirectory(client)
add_subdirectory(file_p)
add_subdirectory(session) add_subdirectory(session)
add_subdirectory(server)
add_subdirectory(utils)
add_subdirectory(user)
+3
View File
@@ -4,6 +4,9 @@ target_link_libraries(client
PRIVATE PRIVATE
db db
main main
file_p
session
utils
murmur3 murmur3
OpenSSL::Crypto OpenSSL::Crypto
) )
+4 -4
View File
@@ -1,11 +1,11 @@
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
/* Copyright (c) 2026 Oleksandr Zhylin */ /* Copyright (c) 2026 Oleksandr Zhylin */
#include "client.h" #include <client.h>
#include "file_p.h" #include <file_p.h>
#include <main.h> #include <main.h>
#include "session.h" #include <session.h>
#include "utils.h" #include <utils.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
+20
View File
@@ -0,0 +1,20 @@
add_library(file_p STATIC)
target_link_libraries(file_p
PRIVATE
db
main
murmur3
utils
session
OpenSSL::Crypto
)
target_sources(file_p
PRIVATE
file_p.c
PUBLIC
FILE_SET HEADERS
FILES
file_p.h
)
@@ -1,16 +1,15 @@
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
/* Copyright (c) 2026 Oleksandr Zhylin */ /* Copyright (c) 2026 Oleksandr Zhylin */
#include "file_p.h"
#include "main.h"
#include "session.h"
#include "utils.h"
#include <arpa/inet.h> #include <arpa/inet.h>
#include <db.h> #include <db.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <file_p.h>
#include <main.h>
#include <murmur3.h> #include <murmur3.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <session.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
@@ -26,6 +25,7 @@
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h> #include <unistd.h>
#include <utils.h>
char *extract_second_arg(char *); char *extract_second_arg(char *);
size_t get_file_size(char *, char *); size_t get_file_size(char *, char *);
@@ -3,7 +3,7 @@
#ifndef FILEP_H #ifndef FILEP_H
#define FILEP_H #define FILEP_H
#include "main.h" #include <main.h>
#include <stdint.h> #include <stdint.h>
typedef struct { typedef struct {
+21
View File
@@ -0,0 +1,21 @@
add_library(server STATIC)
target_link_libraries(server
PRIVATE
db
main
utils
file_p
session
murmur3
OpenSSL::Crypto
)
target_sources(server
PRIVATE
server.c
PUBLIC
FILE_SET HEADERS
FILES
server.h
)
@@ -1,11 +1,11 @@
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
/* Copyright (c) 2026 Oleksandr Zhylin */ /* Copyright (c) 2026 Oleksandr Zhylin */
#include "db.h" #include <db.h>
#include "file_p.h" #include <file_p.h>
#include "main.h" #include <main.h>
#include "session.h" #include <session.h>
#include "utils.h" #include <utils.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@@ -3,7 +3,7 @@
#ifndef SERVER_H #ifndef SERVER_H
#define SERVER_H #define SERVER_H
#include "main.h" #include <main.h>
int start_server(void); int start_server(void);
char *get_welcome_mes(void); char *get_welcome_mes(void);
void server_main_loop(server_data_t *); void server_main_loop(server_data_t *);
+5 -1
View File
@@ -2,8 +2,12 @@ add_library(session STATIC)
target_link_libraries(session target_link_libraries(session
PRIVATE PRIVATE
client
db db
user
main
utils
client
file_p
murmur3 murmur3
OpenSSL::Crypto OpenSSL::Crypto
) )
+46 -40
View File
@@ -2,11 +2,11 @@
/* Copyright (c) 2026 Oleksandr Zhylin */ /* Copyright (c) 2026 Oleksandr Zhylin */
#include "session.h" #include "session.h"
#include "../../client.h" #include <client.h>
#include "../../file_p.h" #include <file_p.h>
#include "../../main.h" #include <main.h>
#include "../../user.h" #include <user.h>
#include "../../utils.h" #include <utils.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <db.h> #include <db.h>
#include <fcntl.h> #include <fcntl.h>
@@ -94,45 +94,51 @@ int session_do_read(session *sess, char **read_str) {
return 1; return 1;
} }
int query_extract_from_buf_2(char *buf, ssize_t *buf_used, char **output_line);
int query_extract_from_buf(session *sess, char **output_line) { int query_extract_from_buf(session *sess, char **output_line) {
char *line; // char *line;
int pos = -1; // int pos = -1;
if (sess->buf_used > 0) { // if (sess->buf_used > 0) {
char *cptr = strchr(sess->buf, '\n'); // char *cptr = strchr(sess->buf, '\n');
if (cptr != NULL) // if (cptr != NULL)
pos = cptr - sess->buf; // pos = cptr - sess->buf;
} else { // } else {
return 0; // return 0;
} // }
if (pos == -1) { // if (pos == -1) {
int b_used = sess->buf_used; // int b_used = sess->buf_used;
sess->buf_used = 0; // sess->buf_used = 0;
line = malloc(b_used + 1); // line = malloc(b_used + 1);
strncpy(line, sess->buf, b_used); // strncpy(line, sess->buf, b_used);
line[b_used] = 0; // line[b_used] = 0;
*output_line = line; // *output_line = line;
return b_used; // return b_used;
} else { // } else {
line = malloc(pos + 2); // line = malloc(pos + 2);
strncpy(line, sess->buf, pos + 1); // strncpy(line, sess->buf, pos + 1);
line[++pos] = 0; // line[++pos] = 0;
sess->buf_used -= (pos); // sess->buf_used -= (pos);
if (!pos) // if (!pos)
pos++; // pos++;
memmove(sess->buf, sess->buf + pos, sess->buf_used); // memmove(sess->buf, sess->buf + pos, sess->buf_used);
sess->buf[sess->buf_used] = 0; // sess->buf[sess->buf_used] = 0;
if (line[pos - 2] == '\r') { // if (line[pos - 2] == '\r') {
line[pos - 2] = line[pos - 1]; // line[pos - 2] = line[pos - 1];
pos--; // pos--;
line[pos - 1] = 0; // line[pos] = 0;
} // }
*output_line = line; // *output_line = line;
} // }
return pos + 1; // return pos + 1;
ssize_t buf_used = sess->buf_used;
int ret = query_extract_from_buf_2(sess->buf, &buf_used, output_line);
sess->buf_used = buf_used;
return ret;
} }
int query_extract_from_buf_2(char *buf, ssize_t *buf_used, char **output_line) { int query_extract_from_buf_2(char *buf, ssize_t *buf_used, char **output_line) {
@@ -170,7 +176,7 @@ int query_extract_from_buf_2(char *buf, ssize_t *buf_used, char **output_line) {
if (line[pos - 2] == '\r') { if (line[pos - 2] == '\r') {
line[pos - 2] = line[pos - 1]; line[pos - 2] = line[pos - 1];
pos--; pos--;
line[pos - 1] = 0; line[pos] = 0;
} }
*output_line = line; *output_line = line;
*buf_used = _buf_used; *buf_used = _buf_used;
+1 -1
View File
@@ -3,7 +3,7 @@
#ifndef SESSION_H #ifndef SESSION_H
#define SESSION_H #define SESSION_H
#include "../../main.h" #include <main.h>
#include <stdio.h> #include <stdio.h>
int accept_client(int ls, session *connections[], char *wm); int accept_client(int ls, session *connections[], char *wm);
void session_send_string(struct session *sess, const char *str, ...); void session_send_string(struct session *sess, const char *str, ...);
+20
View File
@@ -0,0 +1,20 @@
add_library(user STATIC)
target_link_libraries(user
PRIVATE
client
db
murmur3
main
session
OpenSSL::Crypto
)
target_sources(user
PRIVATE
user.c
PUBLIC
FILE_SET HEADERS
FILES
user.h
)
+2 -2
View File
@@ -2,8 +2,8 @@
/* Copyright (c) 2026 Oleksandr Zhylin */ /* Copyright (c) 2026 Oleksandr Zhylin */
#include <db.h> #include <db.h>
#include "main.h" #include <main.h>
#include "session.h" #include <session.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -7,4 +7,7 @@
#include "main.h" #include "main.h"
int login(session *sess, char *pass); int login(session *sess, char *pass);
int process_user_name(char *uname, session *sess); int process_user_name(char *uname, session *sess);
/* Testing */
int32_t create_user(session *sess, char *line);
#endif #endif
+18
View File
@@ -0,0 +1,18 @@
add_library(utils STATIC)
target_link_libraries(utils
PRIVATE
client
db
murmur3
OpenSSL::Crypto
)
target_sources(utils
PRIVATE
utils.c
PUBLIC
FILE_SET HEADERS
FILES
utils.h
)
+4
View File
@@ -5,11 +5,15 @@ if (USE_POSTGRESQL)
target_link_libraries(db target_link_libraries(db
PRIVATE PRIVATE
PostgreSQL::PostgreSQL PostgreSQL::PostgreSQL
main
utils
) )
else() else()
target_link_libraries(db target_link_libraries(db
PRIVATE PRIVATE
SQLite3::SQLite3 SQLite3::SQLite3
main
utils
) )
endif() endif()
+2 -2
View File
@@ -1,8 +1,8 @@
/* SPDX-License-Identifier: MIT */ /* SPDX-License-Identifier: MIT */
/* Copyright (c) 2026 Oleksandr Zhylin */ /* Copyright (c) 2026 Oleksandr Zhylin */
#include "../main.h" #include <main.h>
#include "../utils.h" #include <utils.h>
#include "db_common.h" #include "db_common.h"
#include <db.h> #include <db.h>
#include <endian.h> #include <endian.h>
+2 -2
View File
@@ -2,8 +2,8 @@
/* Copyright (c) 2026 Oleksandr Zhylin */ /* Copyright (c) 2026 Oleksandr Zhylin */
#include "main.h" #include "main.h"
#include "server.h" #include <server.h>
#include "utils.h" #include <utils.h>
#include <db.h> #include <db.h>
/* *** MAIN *** */ /* *** MAIN *** */
+1 -1
View File
@@ -5,7 +5,7 @@
#define MAIN_H #define MAIN_H
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "types.h" #include <types.h>
#define PORT 2000 #define PORT 2000
#define MAX_CONNECTIONS 1024 #define MAX_CONNECTIONS 1024
#define INBUFSIZE 1024 #define INBUFSIZE 1024
+1
View File
@@ -1 +1,2 @@
add_subdirectory(session) add_subdirectory(session)
add_subdirectory(user)
+22 -5
View File
@@ -1,12 +1,29 @@
add_executable(session_app # ---/ session_do_read /---------------------------------------------
session.c
add_executable(session_do_read
session_do_read.c
) )
target_link_libraries(session_app target_link_libraries(session_do_read
cmocka cmocka
session session
main
) )
target_link_options(session_app PRIVATE -Wl,--wrap=read) target_link_options(session_do_read PRIVATE -Wl,--wrap=read)
add_test(session_test session_app) add_test(NAME session_test_1 COMMAND session_do_read)
# ---/ query_extract_from_buf /--------------------------------------
add_executable(query_extract_from_buf
query_extract_from_buf.c
)
target_link_libraries(query_extract_from_buf
cmocka
session
main
)
add_test(NAME session_test_2 COMMAND query_extract_from_buf)
+49
View File
@@ -0,0 +1,49 @@
#include <cmocka.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <main.h>
#include <session.h>
#include <string.h>
#define TEST_BUF "First line\nThe second line\r\nThe third line\nFourth line\0"
#define SUBSTR_NUM 4
void test_query_extract_from_buf_filled(void **state) {
session sess = {.buf = TEST_BUF, .buf_used = sizeof TEST_BUF};
char *lines[SUBSTR_NUM];
for (int i = 0; i < SUBSTR_NUM; i++) {
query_extract_from_buf(&sess, &lines[i]);
}
assert_memory_equal("First line\n", lines[0], strlen(lines[0]));
assert_memory_equal("The second line\n", lines[1], strlen(lines[1]));
assert_memory_equal("The third line\n", lines[2], strlen(lines[2]));
assert_memory_equal("Fourth line", lines[3], strlen(lines[3]));
for (int i = 0; i < SUBSTR_NUM; i++) {
free(lines[i]);
}
}
void test_query_extract_from_buf_empty(void **state) {
session sess = {.buf = "", .buf_used = 0};
char *line = NULL;
int ret = query_extract_from_buf(&sess, &line);
assert_null(line);
assert_int_equal(ret, 0);
}
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_query_extract_from_buf_filled),
cmocka_unit_test(test_query_extract_from_buf_empty)
};
return cmocka_run_group_tests(tests, setup, tear_down);
}
-35
View File
@@ -1,35 +0,0 @@
#include <cmocka.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <session.h>
#include "../../src/main.h"
#define TEST_BUF "Hello world!\n"
int __wrap_read(int fd, void *buf, size_t nbytes) {
return sizeof TEST_BUF - 1;
}
void test_session_do_read(void** state) {
session sess = {
.buf = TEST_BUF,
.buf_used = sizeof TEST_BUF,
.sd = 2,
};
char *str;
session_do_read(NULL, &str);
assert_memory_equal(str, TEST_BUF, sizeof (TEST_BUF)-1);
}
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_session_do_read)};
return cmocka_run_group_tests(tests, setup, tear_down);
}
+41
View File
@@ -0,0 +1,41 @@
#include <cmocka.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <main.h>
#include <session.h>
#include <string.h>
#define TEST_BUF_USED "Voluptas voluptate reprehenderit eum voluptatibus.\n"
#define TEST_BUF_UNUSED \
"Impedit et rerum ut aut vel nisi. Animi et vero nihil aut possimus " \
"commodi. Autem dolorem et officia provident.\n"
#define TEST_BUF TEST_BUF_USED TEST_BUF_UNUSED
int __wrap_read(int fd, void *buf, size_t nbytes) {
return sizeof TEST_BUF - 1;
}
void test_session_do_read(void **state) {
session sess = {
.buf = TEST_BUF,
.buf_used = sizeof TEST_BUF,
.sd = 2,
};
char *line;
session_do_read(&sess, &line);
assert_memory_equal(line, TEST_BUF_USED, sizeof(TEST_BUF_USED));
free(line);
}
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_session_do_read)};
return cmocka_run_group_tests(tests, setup, tear_down);
}
+33
View File
@@ -0,0 +1,33 @@
# ---/ create_user /-------------------------------------------------
add_executable(create_user
create_user.c
)
target_link_libraries(create_user
cmocka
user
main
db
)
target_link_options(create_user PRIVATE -Wl,--wrap=db_user_create,--wrap=session_send_string)
add_test(NAME user_test_1 COMMAND create_user)
# ---/ db_user_create /-------------------------------------------------
add_executable(db_user_create
db_user_create.c
)
target_link_libraries(db_user_create
cmocka
user
main
db
)
target_link_options(db_user_create PRIVATE -Wl,--wrap=db_user_create,--wrap=session_send_string)
add_test(NAME user_test_2 COMMAND db_user_create)
+55
View File
@@ -0,0 +1,55 @@
#include <cmocka.h>
#include <db/db.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <main.h>
#include <string.h>
#include <user.h>
#define UNAME "test_user"
#define PASS "1234"
#define EMAIL "test_user@test.com"
int32_t __wrap_db_user_create(i_db_user_create *args) { return mock_type(int); }
void __wrap_session_send_string(struct session *sess, const char *fmt, ...) {}
/* TODO: divide into separate cases and check messages */
void test_create_user(void **state) {
session sess = {};
i_db_user_create p;
int32_t ret = 0;
char line[sizeof "register" + sizeof UNAME + sizeof PASS + sizeof EMAIL + 5];
sprintf(line, "register %s %s %s\n", UNAME, PASS, EMAIL);
/* Case: success */
will_return(__wrap_db_user_create, 123);
ret = create_user(&sess, line);
assert_int_equal(ret, 123);
/* Case: username exist */
will_return(__wrap_db_user_create, -2);
ret = create_user(&sess, line);
assert_int_equal(ret, -2);
/* Case: email exist */
will_return(__wrap_db_user_create, -3);
ret = create_user(&sess, line);
assert_int_equal(ret, -3);
/* Case: error */
will_return(__wrap_db_user_create, -4);
ret = create_user(&sess, line);
assert_int_equal(ret, -4);
}
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_create_user)};
return cmocka_run_group_tests(tests, setup, tear_down);
}
+45
View File
@@ -0,0 +1,45 @@
#include <cmocka.h>
#include <db/db.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <main.h>
#include <string.h>
#include <user.h>
#define UNAME "test_user"
#define PASS "1234"
#define EMAIL "test_user@test.com"
void __wrap_session_send_string(struct session *sess, const char *fmt, ...) {}
int32_t __wrap_db_user_create(i_db_user_create *args) {
assert_memory_equal(args->uname, UNAME, strlen(args->uname));
assert_memory_equal(args->pass, PASS, strlen(args->pass));
assert_memory_equal(args->email, EMAIL, strlen(args->email));
return mock_type(int);
}
void test_create_user(void **state) {
session sess = {};
i_db_user_create p;
int32_t ret = 0;
char line[sizeof "register" + sizeof UNAME + sizeof PASS + sizeof EMAIL + 5];
sprintf(line, "register %s %s %s\n", UNAME, PASS, EMAIL);
will_return(__wrap_db_user_create, 123);
ret = create_user(&sess, line);
assert_int_equal(ret, 123);
}
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_create_user)};
return cmocka_run_group_tests(tests, setup, tear_down);
}