#include "test_framework.h"
#include "../src/types.h"
#include "../src/config.h"
#include <stdio.h>
#include <unistd.h>
static const char *TEST_CONFIG_FILE = "/tmp/test_proxy_config.json";
static void create_test_config(const char *content) {
FILE *f = fopen(TEST_CONFIG_FILE, "w");
if (f) {
fprintf(f, "%s", content);
fclose(f);
}
}
static void cleanup_test_config(void) {
unlink(TEST_CONFIG_FILE);
}
void test_config_load_valid(void) {
TEST_SUITE_BEGIN("Config Load Valid Configuration");
const char *valid_config =
"{\n"
" \"port\": 9090,\n"
" \"reverse_proxy\": [\n"
" {\n"
" \"hostname\": \"test.example.com\",\n"
" \"upstream_host\": \"127.0.0.1\",\n"
" \"upstream_port\": 3000,\n"
" \"use_ssl\": false,\n"
" \"rewrite_host\": true\n"
" },\n"
" {\n"
" \"hostname\": \"api.example.com\",\n"
" \"upstream_host\": \"192.168.1.100\",\n"
" \"upstream_port\": 443,\n"
" \"use_ssl\": true,\n"
" \"rewrite_host\": false\n"
" }\n"
" ]\n"
"}\n";
create_test_config(valid_config);
int result = config_load(TEST_CONFIG_FILE);
TEST_ASSERT_EQ(1, result, "Config loaded successfully");
TEST_ASSERT_EQ(9090, config.port, "Port is 9090");
TEST_ASSERT_EQ(2, config.route_count, "Two routes configured");
route_config_t *route1 = config_find_route("test.example.com");
TEST_ASSERT(route1 != NULL, "Route for test.example.com found");
if (route1) {
TEST_ASSERT_STR_EQ("127.0.0.1", route1->upstream_host, "First route upstream host");
TEST_ASSERT_EQ(3000, route1->upstream_port, "First route upstream port");
TEST_ASSERT_EQ(0, route1->use_ssl, "First route SSL disabled");
TEST_ASSERT_EQ(1, route1->rewrite_host, "First route host rewrite enabled");
}
route_config_t *route2 = config_find_route("api.example.com");
TEST_ASSERT(route2 != NULL, "Route for api.example.com found");
if (route2) {
TEST_ASSERT_STR_EQ("192.168.1.100", route2->upstream_host, "Second route upstream host");
TEST_ASSERT_EQ(443, route2->upstream_port, "Second route upstream port");
TEST_ASSERT_EQ(1, route2->use_ssl, "Second route SSL enabled");
TEST_ASSERT_EQ(0, route2->rewrite_host, "Second route host rewrite disabled");
}
config_free();
cleanup_test_config();
TEST_SUITE_END();
}
void test_config_find_route_case_insensitive(void) {
TEST_SUITE_BEGIN("Config Find Route Case Insensitive");
const char *config_content =
"{\n"
" \"port\": 8080,\n"
" \"reverse_proxy\": [\n"
" {\n"
" \"hostname\": \"Test.Example.COM\",\n"
" \"upstream_host\": \"localhost\",\n"
" \"upstream_port\": 3000,\n"
" \"use_ssl\": false,\n"
" \"rewrite_host\": false\n"
" }\n"
" ]\n"
"}\n";
create_test_config(config_content);
config_load(TEST_CONFIG_FILE);
route_config_t *route1 = config_find_route("test.example.com");
TEST_ASSERT(route1 != NULL, "Lowercase hostname matches");
route_config_t *route2 = config_find_route("TEST.EXAMPLE.COM");
TEST_ASSERT(route2 != NULL, "Uppercase hostname matches");
route_config_t *route3 = config_find_route("TeSt.ExAmPlE.cOm");
TEST_ASSERT(route3 != NULL, "Mixed case hostname matches");
config_free();
cleanup_test_config();
TEST_SUITE_END();
}
void test_config_find_route_nonexistent(void) {
TEST_SUITE_BEGIN("Config Find Nonexistent Route");
const char *config_content =
"{\n"
" \"port\": 8080,\n"
" \"reverse_proxy\": [\n"
" {\n"
" \"hostname\": \"existing.com\",\n"
" \"upstream_host\": \"localhost\",\n"
" \"upstream_port\": 3000,\n"
" \"use_ssl\": false,\n"
" \"rewrite_host\": false\n"
" }\n"
" ]\n"
"}\n";
create_test_config(config_content);
config_load(TEST_CONFIG_FILE);
route_config_t *route = config_find_route("nonexistent.com");
TEST_ASSERT(route == NULL, "Nonexistent route returns NULL");
route = config_find_route(NULL);
TEST_ASSERT(route == NULL, "NULL hostname returns NULL");
config_free();
cleanup_test_config();
TEST_SUITE_END();
}
void test_config_default_port(void) {
TEST_SUITE_BEGIN("Config Default Port");
const char *config_content =
"{\n"
" \"reverse_proxy\": [\n"
" {\n"
" \"hostname\": \"test.com\",\n"
" \"upstream_host\": \"localhost\",\n"
" \"upstream_port\": 3000,\n"
" \"use_ssl\": false,\n"
" \"rewrite_host\": false\n"
" }\n"
" ]\n"
"}\n";
create_test_config(config_content);
config_load(TEST_CONFIG_FILE);
TEST_ASSERT_EQ(8080, config.port, "Default port is 8080 when not specified");
config_free();
cleanup_test_config();
TEST_SUITE_END();
}
void test_config_invalid_json(void) {
TEST_SUITE_BEGIN("Config Invalid JSON");
const char *invalid_config = "{ invalid json }";
create_test_config(invalid_config);
int result = config_load(TEST_CONFIG_FILE);
TEST_ASSERT_EQ(0, result, "Invalid JSON returns 0");
cleanup_test_config();
TEST_SUITE_END();
}
void test_config_missing_file(void) {
TEST_SUITE_BEGIN("Config Missing File");
unlink("/tmp/nonexistent_config.json");
int result = config_load("/tmp/nonexistent_config.json");
TEST_ASSERT_EQ(0, result, "Missing file returns 0");
TEST_SUITE_END();
}
void test_config_ssl_rewrite_host_options(void) {
TEST_SUITE_BEGIN("Config SSL and Rewrite Host Options");
const char *config_content =
"{\n"
" \"port\": 8080,\n"
" \"reverse_proxy\": [\n"
" {\n"
" \"hostname\": \"https-rewrite.com\",\n"
" \"upstream_host\": \"secure.example.com\",\n"
" \"upstream_port\": 443,\n"
" \"use_ssl\": true,\n"
" \"rewrite_host\": true\n"
" },\n"
" {\n"
" \"hostname\": \"http-norewrite.com\",\n"
" \"upstream_host\": \"plain.example.com\",\n"
" \"upstream_port\": 80,\n"
" \"use_ssl\": false,\n"
" \"rewrite_host\": false\n"
" }\n"
" ]\n"
"}\n";
create_test_config(config_content);
config_load(TEST_CONFIG_FILE);
route_config_t *ssl_route = config_find_route("https-rewrite.com");
TEST_ASSERT(ssl_route != NULL, "SSL route found");
if (ssl_route) {
TEST_ASSERT_EQ(1, ssl_route->use_ssl, "SSL enabled for https route");
TEST_ASSERT_EQ(1, ssl_route->rewrite_host, "Host rewrite enabled for https route");
}
route_config_t *plain_route = config_find_route("http-norewrite.com");
TEST_ASSERT(plain_route != NULL, "Plain route found");
if (plain_route) {
TEST_ASSERT_EQ(0, plain_route->use_ssl, "SSL disabled for http route");
TEST_ASSERT_EQ(0, plain_route->rewrite_host, "Host rewrite disabled for http route");
}
config_free();
cleanup_test_config();
TEST_SUITE_END();
}
void run_config_tests(void) {
test_config_load_valid();
test_config_find_route_case_insensitive();
test_config_find_route_nonexistent();
test_config_default_port();
test_config_invalid_json();
test_config_missing_file();
test_config_ssl_rewrite_host_options();
}