#include "unity.h" #include "server.h" #include "config.h" #include #include /* ===== server_create 参数校验 ===== */ void test_create_null_config(void) { TEST_ASSERT_NULL(server_create(NULL)); } void test_create_null_root_dir(void) { cocoon_config_t cfg = {.port = 8080}; /* root_dir 为 NULL,应提前返回 NULL */ TEST_ASSERT_NULL(server_create(&cfg)); } void test_create_empty_root_dir(void) { cocoon_config_t cfg = {.root_dir = "", .port = 30001}; /* 空字符串 root_dir 应该也失败(或成功取决于实现) */ server_context_t *ctx = server_create(&cfg); if (ctx) { server_destroy(ctx); } /* 空字符串可能成功也可能失败,不强制断言 */ TEST_ASSERT_TRUE(1); } /* ===== server_create 配置边界测试 ===== */ void test_create_port_zero(void) { /* port=0 让系统分配随机端口,应该能成功 */ cocoon_config_t cfg = { .root_dir = "/tmp", .port = 0, .threaded = false }; server_context_t *ctx = server_create(&cfg); if (ctx) { server_destroy(ctx); TEST_ASSERT_TRUE(1); } else { TEST_IGNORE_MESSAGE("port 0 create failed, system may restrict"); } } void test_create_high_port(void) { cocoon_config_t cfg = { .root_dir = "/tmp", .port = 65535, .threaded = false }; server_context_t *ctx = server_create(&cfg); if (ctx) { server_destroy(ctx); TEST_ASSERT_TRUE(1); } else { TEST_IGNORE_MESSAGE("port 65535 create failed, possibly in use"); } } void test_create_multithread_config(void) { cocoon_config_t cfg = { .root_dir = "/tmp", .port = 30002, .threaded = true, .num_workers = 2 }; server_context_t *ctx = server_create(&cfg); if (ctx) { server_destroy(ctx); TEST_ASSERT_TRUE(1); } else { TEST_IGNORE_MESSAGE("multithread create failed, possibly port in use"); } } void test_create_zero_workers(void) { /* workers=0 应该自动检测 CPU 核心数 */ cocoon_config_t cfg = { .root_dir = "/tmp", .port = 30003, .threaded = true, .num_workers = 0 }; server_context_t *ctx = server_create(&cfg); if (ctx) { server_destroy(ctx); TEST_ASSERT_TRUE(1); } else { TEST_IGNORE_MESSAGE("zero workers create failed, possibly port in use"); } } void test_create_with_timeout(void) { cocoon_config_t cfg = { .root_dir = "/tmp", .port = 30004, .threaded = false, .timeout_ms = 5000 }; server_context_t *ctx = server_create(&cfg); if (ctx) { server_destroy(ctx); TEST_ASSERT_TRUE(1); } else { TEST_IGNORE_MESSAGE("create with timeout failed, possibly port in use"); } } void test_create_with_max_connections(void) { cocoon_config_t cfg = { .root_dir = "/tmp", .port = 30005, .threaded = false, .max_connections = 100 }; server_context_t *ctx = server_create(&cfg); if (ctx) { server_destroy(ctx); TEST_ASSERT_TRUE(1); } else { TEST_IGNORE_MESSAGE("create with max_connections failed, possibly port in use"); } } void test_create_with_compression_flags(void) { cocoon_config_t cfg = { .root_dir = "/tmp", .port = 30006, .threaded = false, .gzip_enabled = false, .brotli_enabled = false }; server_context_t *ctx = server_create(&cfg); if (ctx) { server_destroy(ctx); TEST_ASSERT_TRUE(1); } else { TEST_IGNORE_MESSAGE("create with compression flags failed, possibly port in use"); } } /* ===== server_stop / server_destroy 安全路径 ===== */ void test_stop_null(void) { /* 不应 crash */ server_stop(NULL); TEST_ASSERT_TRUE(1); } void test_destroy_null(void) { /* 不应 crash */ server_destroy(NULL); TEST_ASSERT_TRUE(1); } void test_stop_then_destroy(void) { cocoon_config_t cfg = { .root_dir = "/tmp", .port = 30007, .threaded = false }; server_context_t *ctx = server_create(&cfg); if (!ctx) { TEST_IGNORE_MESSAGE("server_create failed, possibly port in use"); return; } server_stop(ctx); server_destroy(ctx); TEST_ASSERT_TRUE(1); } void test_double_destroy(void) { /* 测试二次 destroy 的安全性(虽然用户不应这样做,但不应 crash) */ /* 注意:第一次 destroy 后指针已释放,第二次是悬空指针,这个测试有风险 */ /* 暂时跳过,因为 C 中无法安全地 double-free */ TEST_IGNORE_MESSAGE("double destroy test skipped (unsafe in C)"); } /* ===== server_create 成功后销毁 ===== */ void test_create_and_destroy(void) { cocoon_config_t cfg = { .root_dir = "/tmp", .port = 29999, /* 使用高位端口减少冲突 */ .threaded = false }; server_context_t *ctx = server_create(&cfg); /* 高位端口通常可用,但测试环境可能被占用,保守处理 */ if (ctx) { server_stop(ctx); server_destroy(ctx); TEST_ASSERT_TRUE(1); } else { /* 端口被占用等外部原因导致失败,非逻辑错误,标记忽略 */ TEST_IGNORE_MESSAGE("server_create failed, possibly port in use"); } } void test_create_multiple_instances(void) { /* 创建两个不同端口的服务器 */ cocoon_config_t cfg1 = { .root_dir = "/tmp", .port = 30008, .threaded = false }; cocoon_config_t cfg2 = { .root_dir = "/tmp", .port = 30009, .threaded = false }; server_context_t *ctx1 = server_create(&cfg1); server_context_t *ctx2 = server_create(&cfg2); if (ctx1 && ctx2) { server_destroy(ctx2); server_destroy(ctx1); TEST_ASSERT_TRUE(1); } else { if (ctx1) server_destroy(ctx1); if (ctx2) server_destroy(ctx2); TEST_IGNORE_MESSAGE("multiple instances create failed, possibly port in use"); } } /* ===== server_start 参数校验 ===== */ void test_start_null(void) { /* server_start 传入 NULL 应该返回错误 */ int ret = server_start(NULL); TEST_ASSERT_EQUAL_INT(COCOON_ERROR, ret); } void setUp(void) {} void tearDown(void) {} int main(void) { UNITY_BEGIN(); RUN_TEST(test_create_null_config); RUN_TEST(test_create_null_root_dir); RUN_TEST(test_create_empty_root_dir); RUN_TEST(test_create_port_zero); RUN_TEST(test_create_high_port); RUN_TEST(test_create_multithread_config); RUN_TEST(test_create_zero_workers); RUN_TEST(test_create_with_timeout); RUN_TEST(test_create_with_max_connections); RUN_TEST(test_create_with_compression_flags); RUN_TEST(test_stop_null); RUN_TEST(test_destroy_null); RUN_TEST(test_stop_then_destroy); RUN_TEST(test_double_destroy); RUN_TEST(test_create_and_destroy); RUN_TEST(test_create_multiple_instances); RUN_TEST(test_start_null); return UNITY_END(); }