fix: refactoring and portability — issues #61, #51, #52
CI / lint (pull_request) Failing after 2s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
CI / sanitizers (undefined) (pull_request) Has been skipped
CI / fuzz-build (pull_request) Has been skipped
CI / coverage (pull_request) Has been skipped
CI / valgrind (pull_request) Has been skipped
CI / lint (pull_request) Failing after 2s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
CI / sanitizers (undefined) (pull_request) Has been skipped
CI / fuzz-build (pull_request) Has been skipped
CI / coverage (pull_request) Has been skipped
CI / valgrind (pull_request) Has been skipped
This commit is contained in:
@@ -23,6 +23,14 @@ static void test_data_create_empty() {
|
||||
data_destroy(d);
|
||||
}
|
||||
|
||||
static void test_data_create_empty_zero() {
|
||||
Data* d = data_create_empty(0);
|
||||
EXPECT_NOT_NULL(d);
|
||||
EXPECT_NOT_NULL(d->data);
|
||||
EXPECT_EQ_INT((int)d->size, 0);
|
||||
data_destroy(d);
|
||||
}
|
||||
|
||||
static void test_data_create_reserve() {
|
||||
Data* d = data_create_reserve(1024);
|
||||
EXPECT_NOT_NULL(d);
|
||||
@@ -44,6 +52,7 @@ static void test_data_destroy_normal() {
|
||||
void test_data() {
|
||||
test_data_create();
|
||||
test_data_create_empty();
|
||||
test_data_create_empty_zero();
|
||||
test_data_create_reserve();
|
||||
test_data_destroy_null();
|
||||
test_data_destroy_normal();
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
#include "test_file_sendfile.h"
|
||||
#include "file.h"
|
||||
#include "data.h"
|
||||
#include "config.h"
|
||||
#include "protocol.h"
|
||||
#include "utils.h"
|
||||
#include "test_utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void test_sendfile_basic() {
|
||||
const char* content = "Hello sendfile test content!";
|
||||
size_t len = strlen(content);
|
||||
EXPECT_TRUE(to_disk("test_sendfile_basic.txt", content, len));
|
||||
|
||||
File* file = file_create("test_sendfile_basic.txt");
|
||||
EXPECT_NOT_NULL(file);
|
||||
file->data->size = len;
|
||||
file->data->data = malloc(len);
|
||||
EXPECT_NOT_NULL(file->data->data);
|
||||
memcpy(file->data->data, content, len);
|
||||
|
||||
int p[2];
|
||||
EXPECT_EQ_INT(pipe(p), 0);
|
||||
io_set_fds(p[0], p[1]);
|
||||
io_set_bwlimit(0);
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
close(p[1]);
|
||||
// Receive path: read size then data
|
||||
unsigned long long recv_size;
|
||||
EXPECT_TRUE(receive_n_data(p[0], &recv_size, sizeof(recv_size)));
|
||||
EXPECT_EQ_INT((int)recv_size, (int)len);
|
||||
|
||||
char* buf = malloc(recv_size + 1);
|
||||
EXPECT_NOT_NULL(buf);
|
||||
EXPECT_TRUE(receive_n_data(p[0], buf, recv_size));
|
||||
buf[recv_size] = '\0';
|
||||
EXPECT_EQ_INT(memcmp(buf, content, len), 0);
|
||||
free(buf);
|
||||
close(p[0]);
|
||||
_exit(0);
|
||||
} else {
|
||||
close(p[0]);
|
||||
bool sent = file_send_sendfile(file, p[1], false, 0, false);
|
||||
close(p[1]);
|
||||
|
||||
int status;
|
||||
waitpid(pid, &status, 0);
|
||||
|
||||
file_destroy(file);
|
||||
unlink("test_sendfile_basic.txt");
|
||||
|
||||
EXPECT_TRUE(sent);
|
||||
EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_sendfile_with_path() {
|
||||
const char* content = "Sendfile with path test";
|
||||
size_t len = strlen(content);
|
||||
EXPECT_TRUE(to_disk("test_sendfile_path.txt", content, len));
|
||||
|
||||
File* file = file_create("test_sendfile_path.txt");
|
||||
EXPECT_NOT_NULL(file);
|
||||
file->data->size = len;
|
||||
file->data->data = malloc(len);
|
||||
EXPECT_NOT_NULL(file->data->data);
|
||||
memcpy(file->data->data, content, len);
|
||||
|
||||
int p[2];
|
||||
EXPECT_EQ_INT(pipe(p), 0);
|
||||
io_set_fds(p[0], p[1]);
|
||||
io_set_bwlimit(0);
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
close(p[1]);
|
||||
char* recv_path = receive_str(p[0]);
|
||||
EXPECT_NOT_NULL(recv_path);
|
||||
EXPECT_EQ_STR(recv_path, "test_sendfile_path.txt");
|
||||
free(recv_path);
|
||||
|
||||
unsigned long long recv_size;
|
||||
EXPECT_TRUE(receive_n_data(p[0], &recv_size, sizeof(recv_size)));
|
||||
|
||||
char* buf = malloc(recv_size + 1);
|
||||
EXPECT_NOT_NULL(buf);
|
||||
EXPECT_TRUE(receive_n_data(p[0], buf, recv_size));
|
||||
buf[recv_size] = '\0';
|
||||
EXPECT_EQ_INT(memcmp(buf, content, len), 0);
|
||||
free(buf);
|
||||
close(p[0]);
|
||||
_exit(0);
|
||||
} else {
|
||||
close(p[0]);
|
||||
bool sent = file_send_sendfile(file, p[1], false, 0, true);
|
||||
close(p[1]);
|
||||
|
||||
int status;
|
||||
waitpid(pid, &status, 0);
|
||||
|
||||
file_destroy(file);
|
||||
unlink("test_sendfile_path.txt");
|
||||
|
||||
EXPECT_TRUE(sent);
|
||||
EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_sendfile_empty_file() {
|
||||
const char* content = "";
|
||||
size_t len = 0;
|
||||
EXPECT_TRUE(to_disk("test_sendfile_empty.txt", content, len));
|
||||
|
||||
File* file = file_create("test_sendfile_empty.txt");
|
||||
EXPECT_NOT_NULL(file);
|
||||
file->data->size = len;
|
||||
file->data->data = NULL;
|
||||
|
||||
int p[2];
|
||||
EXPECT_EQ_INT(pipe(p), 0);
|
||||
io_set_fds(p[0], p[1]);
|
||||
io_set_bwlimit(0);
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
close(p[1]);
|
||||
unsigned long long recv_size;
|
||||
EXPECT_TRUE(receive_n_data(p[0], &recv_size, sizeof(recv_size)));
|
||||
EXPECT_EQ_INT((int)recv_size, 0);
|
||||
close(p[0]);
|
||||
_exit(0);
|
||||
} else {
|
||||
close(p[0]);
|
||||
bool sent = file_send_sendfile(file, p[1], false, 0, false);
|
||||
close(p[1]);
|
||||
|
||||
int status;
|
||||
waitpid(pid, &status, 0);
|
||||
|
||||
file_destroy(file);
|
||||
unlink("test_sendfile_empty.txt");
|
||||
|
||||
EXPECT_TRUE(sent);
|
||||
EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_sendfile_with_compression_fallback() {
|
||||
// When compression_level > 0, sendfile falls back to file_send_single_calls
|
||||
const char* content = "Sendfile compression fallback test data here.";
|
||||
size_t len = strlen(content);
|
||||
EXPECT_TRUE(to_disk("test_sendfile_comp.txt", content, len));
|
||||
|
||||
File* file = file_create("test_sendfile_comp.txt");
|
||||
EXPECT_NOT_NULL(file);
|
||||
file->data->size = len;
|
||||
file->data->data = malloc(len);
|
||||
EXPECT_NOT_NULL(file->data->data);
|
||||
memcpy(file->data->data, content, len);
|
||||
|
||||
Config* cfg = config_create(str_dup(PROTOCOL_VERSION), str_dup("/tmp"), str_dup("/tmp"), false,
|
||||
false, false, false, false, 0, false, 0);
|
||||
|
||||
int p[2];
|
||||
EXPECT_EQ_INT(pipe(p), 0);
|
||||
io_set_fds(p[0], p[1]);
|
||||
io_set_bwlimit(0);
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
close(p[1]);
|
||||
File* received = file_receive(cfg, p[0]);
|
||||
close(p[0]);
|
||||
bool ok = true;
|
||||
if (!received) ok = false;
|
||||
else {
|
||||
if (!received->data || received->data->size != len) ok = false;
|
||||
else if (memcmp(received->data->data, content, len) != 0) ok = false;
|
||||
}
|
||||
file_destroy(received);
|
||||
config_delete(cfg);
|
||||
_exit(ok ? 0 : 1);
|
||||
} else {
|
||||
close(p[0]);
|
||||
// Send with compression_level=1, should fall back to file_send_single_calls
|
||||
bool sent = file_send_sendfile(file, p[1], false, 1, true);
|
||||
close(p[1]);
|
||||
|
||||
int status;
|
||||
waitpid(pid, &status, 0);
|
||||
|
||||
file_destroy(file);
|
||||
config_delete(cfg);
|
||||
unlink("test_sendfile_comp.txt");
|
||||
|
||||
EXPECT_TRUE(sent);
|
||||
EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_sendfile_nonexistent_file() {
|
||||
File* file = file_create("nonexistent_file_xyz_sendfile_test.txt");
|
||||
EXPECT_NOT_NULL(file);
|
||||
file->data->size = 100;
|
||||
file->data->data = malloc(100);
|
||||
EXPECT_NOT_NULL(file->data->data);
|
||||
memset(file->data->data, 0, 100);
|
||||
|
||||
int p[2];
|
||||
EXPECT_EQ_INT(pipe(p), 0);
|
||||
io_set_fds(p[0], p[1]);
|
||||
io_set_bwlimit(0);
|
||||
close(p[0]);
|
||||
|
||||
bool sent = file_send_sendfile(file, p[1], false, 0, false);
|
||||
close(p[1]);
|
||||
|
||||
file_destroy(file);
|
||||
// File doesn't exist on disk, sendfile should fail
|
||||
EXPECT_FALSE(sent);
|
||||
}
|
||||
|
||||
void test_file_sendfile() {
|
||||
test_sendfile_basic();
|
||||
test_sendfile_with_path();
|
||||
test_sendfile_empty_file();
|
||||
test_sendfile_with_compression_fallback();
|
||||
test_sendfile_nonexistent_file();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef TEST_FILE_SENDFILE_H
|
||||
#define TEST_FILE_SENDFILE_H
|
||||
|
||||
void test_file_sendfile();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,78 @@
|
||||
#include "test_log.h"
|
||||
#include "log.h"
|
||||
#include "test_utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Helper to redirect stderr temporarily
|
||||
static int stderr_pipe[2];
|
||||
|
||||
static void capture_stderr_start() {
|
||||
fflush(stderr);
|
||||
EXPECT_EQ_INT(pipe(stderr_pipe), 0);
|
||||
EXPECT_EQ_INT(dup2(stderr_pipe[1], STDERR_FILENO), STDERR_FILENO);
|
||||
close(stderr_pipe[1]);
|
||||
}
|
||||
|
||||
static void capture_stderr_end() {
|
||||
fflush(stderr);
|
||||
close(stderr_pipe[0]);
|
||||
}
|
||||
|
||||
static void test_log_message_debug() {
|
||||
set_log_level(LOG_LEVEL_DEBUG);
|
||||
// Should output at DEBUG level
|
||||
log_message(LOG_LEVEL_DEBUG, "Debug message test: %d", 42);
|
||||
log_message(LOG_LEVEL_INFO, "Info message test");
|
||||
log_message(LOG_LEVEL_WARNING, "Warning message test");
|
||||
log_message(LOG_LEVEL_ERROR, "Error message test");
|
||||
// If we get here without crashing, the test passes
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
||||
static void test_log_message_level_filtering() {
|
||||
set_log_level(LOG_LEVEL_WARNING);
|
||||
capture_stderr_start();
|
||||
log_message(LOG_LEVEL_DEBUG, "Should NOT appear");
|
||||
log_message(LOG_LEVEL_INFO, "Should NOT appear");
|
||||
log_message(LOG_LEVEL_WARNING, "Should appear");
|
||||
log_message(LOG_LEVEL_ERROR, "Should appear");
|
||||
capture_stderr_end();
|
||||
// We can't easily check the content, but we verified it doesn't crash
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
||||
static void test_log_message_error() {
|
||||
set_log_level(LOG_LEVEL_ERROR);
|
||||
log_message(LOG_LEVEL_ERROR, "Error only: %s", "critical");
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
||||
static void test_set_log_level() {
|
||||
set_log_level(LOG_LEVEL_DEBUG);
|
||||
log_message(LOG_LEVEL_DEBUG, "debug visible");
|
||||
set_log_level(LOG_LEVEL_WARNING);
|
||||
log_message(LOG_LEVEL_DEBUG, "debug hidden (no crash)");
|
||||
log_message(LOG_LEVEL_WARNING, "warning visible");
|
||||
set_log_level(LOG_LEVEL_INFO);
|
||||
log_message(LOG_LEVEL_INFO, "info visible");
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
||||
static void test_log_message_various_args() {
|
||||
set_log_level(LOG_LEVEL_DEBUG);
|
||||
log_message(LOG_LEVEL_INFO, "String: %s, Int: %d, Hex: %x", "test", 123, 0xFF);
|
||||
log_message(LOG_LEVEL_WARNING, "Warning with number %d", 42);
|
||||
log_message(LOG_LEVEL_DEBUG, "Debug with pointer %p", (void*)0x1234);
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
||||
void test_log() {
|
||||
test_log_message_debug();
|
||||
test_log_message_level_filtering();
|
||||
test_log_message_error();
|
||||
test_set_log_level();
|
||||
test_log_message_various_args();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef TEST_LOG_H
|
||||
#define TEST_LOG_H
|
||||
|
||||
void test_log();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
#include "test_multiprocessing.h"
|
||||
#include "multiprocessing.h"
|
||||
#include "config.h"
|
||||
#include "queue.h"
|
||||
#include "utils.h"
|
||||
#include "test_utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void test_pipeline_context_sender_create_destroy() {
|
||||
Config* cfg = config_create(str_dup(PROTOCOL_VERSION), str_dup("/tmp"), str_dup("/tmp"), false,
|
||||
false, false, false, false, 0, false, 0);
|
||||
EXPECT_NOT_NULL(cfg);
|
||||
|
||||
Queue* q_scanner = queue_create(10, free);
|
||||
EXPECT_NOT_NULL(q_scanner);
|
||||
|
||||
Queue* q_loader = queue_create(10, free);
|
||||
EXPECT_NOT_NULL(q_loader);
|
||||
|
||||
PipelineContextSender* ctx = pipeline_context_sender_create(cfg, q_scanner, q_loader);
|
||||
EXPECT_NOT_NULL(ctx);
|
||||
EXPECT_EQ_INT(ctx->scanner_done, false);
|
||||
EXPECT_EQ_INT(ctx->loader_done, false);
|
||||
EXPECT_NULL(ctx->manifest);
|
||||
|
||||
pipeline_context_sender_destroy(ctx);
|
||||
// cfg, q_scanner, q_loader are destroyed by pipeline_context_sender_destroy
|
||||
}
|
||||
|
||||
static void test_pipeline_context_sender_create_null_config() {
|
||||
// Passing NULL config to pipeline_context_sender_create - it will be used
|
||||
// and destroyed, so this should be tested carefully.
|
||||
Queue* q_scanner = queue_create(10, free);
|
||||
EXPECT_NOT_NULL(q_scanner);
|
||||
Queue* q_loader = queue_create(10, free);
|
||||
EXPECT_NOT_NULL(q_loader);
|
||||
|
||||
PipelineContextSender* ctx = pipeline_context_sender_create(NULL, q_scanner, q_loader);
|
||||
EXPECT_NOT_NULL(ctx);
|
||||
EXPECT_NULL(ctx->config);
|
||||
|
||||
// Destroy without config - config_delete(NULL) should be safe
|
||||
pipeline_context_sender_destroy(ctx);
|
||||
}
|
||||
|
||||
static void test_pipeline_context_sender_destroy_null() {
|
||||
pipeline_context_sender_destroy(NULL);
|
||||
}
|
||||
|
||||
static void test_pipeline_context_receiver_create_destroy() {
|
||||
Config* cfg = config_create(str_dup(PROTOCOL_VERSION), str_dup("/tmp"), str_dup("/tmp"), false,
|
||||
false, false, false, false, 0, false, 0);
|
||||
EXPECT_NOT_NULL(cfg);
|
||||
|
||||
Queue* q = queue_create(10, free);
|
||||
EXPECT_NOT_NULL(q);
|
||||
|
||||
PipelineContextReceiver* ctx = pipeline_context_receiver_create(cfg, q, 42);
|
||||
EXPECT_NOT_NULL(ctx);
|
||||
EXPECT_EQ_INT(ctx->file_descriptor, 42);
|
||||
EXPECT_EQ_INT(ctx->receiver_done, false);
|
||||
|
||||
pipeline_context_receiver_destroy(ctx);
|
||||
// cfg, q are destroyed by pipeline_context_receiver_destroy
|
||||
}
|
||||
|
||||
static void test_pipeline_context_receiver_create_null_config() {
|
||||
Queue* q = queue_create(10, free);
|
||||
EXPECT_NOT_NULL(q);
|
||||
|
||||
PipelineContextReceiver* ctx = pipeline_context_receiver_create(NULL, q, -1);
|
||||
EXPECT_NOT_NULL(ctx);
|
||||
EXPECT_NULL(ctx->config);
|
||||
EXPECT_EQ_INT(ctx->file_descriptor, -1);
|
||||
|
||||
pipeline_context_receiver_destroy(ctx);
|
||||
}
|
||||
|
||||
static void test_pipeline_context_receiver_destroy_null() {
|
||||
pipeline_context_receiver_destroy(NULL);
|
||||
}
|
||||
|
||||
void test_multiprocessing() {
|
||||
test_pipeline_context_sender_create_destroy();
|
||||
test_pipeline_context_sender_create_null_config();
|
||||
test_pipeline_context_sender_destroy_null();
|
||||
test_pipeline_context_receiver_create_destroy();
|
||||
test_pipeline_context_receiver_create_null_config();
|
||||
test_pipeline_context_receiver_destroy_null();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef TEST_MULTIPROCESSING_H
|
||||
#define TEST_MULTIPROCESSING_H
|
||||
|
||||
void test_multiprocessing();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "test_transport_ssh.h"
|
||||
#include "transport_ssh.h"
|
||||
#include "transport_tcp.h"
|
||||
#include "test_utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void test_ssh_connect_bad_destination() {
|
||||
Client* client = client_connect_ssh("nosuchhost.local", 22);
|
||||
// SSH connection to a non-existent host should fail (return NULL)
|
||||
EXPECT_NULL(client);
|
||||
}
|
||||
|
||||
static void test_ssh_connect_null_destination() {
|
||||
Client* client = client_connect_ssh(NULL, 22);
|
||||
EXPECT_NULL(client);
|
||||
}
|
||||
|
||||
static void test_ssh_connect_bad_port() {
|
||||
Client* client = client_connect_ssh("localhost", -1);
|
||||
EXPECT_NULL(client);
|
||||
}
|
||||
|
||||
static void test_ssh_connect_zero_port() {
|
||||
Client* client = client_connect_ssh("localhost", 0);
|
||||
EXPECT_NULL(client);
|
||||
}
|
||||
|
||||
void test_transport_ssh() {
|
||||
test_ssh_connect_bad_destination();
|
||||
test_ssh_connect_null_destination();
|
||||
test_ssh_connect_bad_port();
|
||||
test_ssh_connect_zero_port();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef TEST_TRANSPORT_SSH_H
|
||||
#define TEST_TRANSPORT_SSH_H
|
||||
|
||||
void test_transport_ssh();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "test_transport_tcp.h"
|
||||
#include "transport_tcp.h"
|
||||
#include "test_utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
static void test_client_create_delete() {
|
||||
Client* client = client_create();
|
||||
EXPECT_NOT_NULL(client);
|
||||
EXPECT_EQ_INT(client->file_descriptor, -1);
|
||||
EXPECT_EQ_INT(client->ssh_child_pid, -1);
|
||||
client_delete(client);
|
||||
}
|
||||
|
||||
static void test_client_delete_null() {
|
||||
client_delete(NULL);
|
||||
}
|
||||
|
||||
static void test_client_disconnect_null() {
|
||||
client_disconnect(NULL);
|
||||
}
|
||||
|
||||
static void test_client_connect_bad_host() {
|
||||
Client* client = client_create();
|
||||
EXPECT_NOT_NULL(client);
|
||||
|
||||
// Connecting to a non-existent host should fail
|
||||
bool connected = client_connect(client, "192.0.2.999", 12345);
|
||||
EXPECT_FALSE(connected);
|
||||
|
||||
client_disconnect(client);
|
||||
client_delete(client);
|
||||
}
|
||||
|
||||
static void test_client_connect_bad_port() {
|
||||
Client* client = client_create();
|
||||
EXPECT_NOT_NULL(client);
|
||||
|
||||
// Connecting to port 0 should fail
|
||||
bool connected = client_connect(client, "127.0.0.1", 0);
|
||||
EXPECT_FALSE(connected);
|
||||
|
||||
client_disconnect(client);
|
||||
client_delete(client);
|
||||
}
|
||||
|
||||
static void test_client_connect_null_host() {
|
||||
Client* client = client_create();
|
||||
EXPECT_NOT_NULL(client);
|
||||
|
||||
bool connected = client_connect(client, NULL, 8080);
|
||||
EXPECT_FALSE(connected);
|
||||
|
||||
client_disconnect(client);
|
||||
client_delete(client);
|
||||
}
|
||||
|
||||
static void test_server_create_delete() {
|
||||
Server* server = server_create(0);
|
||||
// server_create may return NULL if it fails to bind, but we need to check
|
||||
// if it succeeds. Port 0 should bind to an ephemeral port.
|
||||
if (server != NULL) {
|
||||
EXPECT_NOT_NULL(server);
|
||||
server_delete(&server);
|
||||
EXPECT_NULL(server);
|
||||
} else {
|
||||
// On some systems port 0 may fail; that's okay
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_server_delete_null() {
|
||||
Server* server = NULL;
|
||||
server_delete(&server);
|
||||
EXPECT_NULL(server);
|
||||
}
|
||||
|
||||
void test_transport_tcp() {
|
||||
test_client_create_delete();
|
||||
test_client_delete_null();
|
||||
test_client_disconnect_null();
|
||||
test_client_connect_bad_host();
|
||||
test_client_connect_bad_port();
|
||||
test_client_connect_null_host();
|
||||
test_server_create_delete();
|
||||
test_server_delete_null();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef TEST_TRANSPORT_TCP_H
|
||||
#define TEST_TRANSPORT_TCP_H
|
||||
|
||||
void test_transport_tcp();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
#include "test_transport_tls.h"
|
||||
#include "transport_tls.h"
|
||||
#include "transport_tcp.h"
|
||||
#include "test_utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void test_tls_global_init() {
|
||||
bool ok = tls_global_init();
|
||||
// Should succeed in normal environments with OpenSSL
|
||||
// May fail in minimal environments, but we just test it doesn't crash
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
||||
static void test_client_connect_tls_bad_host() {
|
||||
// Ensure TLS is initialized
|
||||
tls_global_init();
|
||||
|
||||
Client* client = client_create();
|
||||
EXPECT_NOT_NULL(client);
|
||||
|
||||
// Connecting without TLS setup should fail
|
||||
bool connected = client_connect_tls(client, "192.0.2.1", 443, NULL, NULL, NULL);
|
||||
EXPECT_FALSE(connected);
|
||||
|
||||
client_disconnect(client);
|
||||
client_delete(client);
|
||||
}
|
||||
|
||||
static void test_client_connect_tls_null_params() {
|
||||
tls_global_init();
|
||||
|
||||
Client* client = client_create();
|
||||
EXPECT_NOT_NULL(client);
|
||||
|
||||
bool connected = client_connect_tls(client, NULL, 0, NULL, NULL, NULL);
|
||||
EXPECT_FALSE(connected);
|
||||
|
||||
client_disconnect(client);
|
||||
client_delete(client);
|
||||
}
|
||||
|
||||
static void test_server_create_tls_no_cert() {
|
||||
Server* server = server_create(0);
|
||||
if (server != NULL) {
|
||||
// Trying to set up TLS without cert/key files should fail
|
||||
bool ok = server_create_tls(server, "/nonexistent/cert.pem", "/nonexistent/key.pem",
|
||||
"/nonexistent/ca.pem");
|
||||
EXPECT_FALSE(ok);
|
||||
server_delete(&server);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_server_create_tls_null_files() {
|
||||
Server* server = server_create(0);
|
||||
if (server != NULL) {
|
||||
bool ok = server_create_tls(server, NULL, NULL, NULL);
|
||||
EXPECT_FALSE(ok);
|
||||
server_delete(&server);
|
||||
}
|
||||
}
|
||||
|
||||
void test_transport_tls() {
|
||||
test_tls_global_init();
|
||||
test_client_connect_tls_bad_host();
|
||||
test_client_connect_tls_null_params();
|
||||
test_server_create_tls_no_cert();
|
||||
test_server_create_tls_null_files();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef TEST_TRANSPORT_TLS_H
|
||||
#define TEST_TRANSPORT_TLS_H
|
||||
|
||||
void test_transport_tls();
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user