colla/tests/net_tests.c
alessandro bason a66e58193f .
2025-06-24 17:47:08 +02:00

238 lines
7.3 KiB
C

#include "runner.h"
#include "../net.h"
#include "../arena.h"
#include <stdio.h>
// Initialization Tests
UNIT_TEST(net_init_cleanup) {
net_init();
// Simple test to make sure initialization succeeds
ASSERT(net_get_last_error() == 0);
net_cleanup();
}
// HTTP Method/Status Tests
UNIT_TEST(http_method_strings) {
ASSERT(strcmp(http_get_method_string(HTTP_GET), "GET") == 0);
ASSERT(strcmp(http_get_method_string(HTTP_POST), "POST") == 0);
ASSERT(strcmp(http_get_method_string(HTTP_HEAD), "HEAD") == 0);
ASSERT(strcmp(http_get_method_string(HTTP_PUT), "PUT") == 0);
ASSERT(strcmp(http_get_method_string(HTTP_DELETE), "DELETE") == 0);
}
UNIT_TEST(http_status_strings) {
ASSERT(strcmp(http_get_status_string(200), "OK") == 0);
ASSERT(strcmp(http_get_status_string(404), "NOT FOUND") == 0);
ASSERT(strcmp(http_get_status_string(500), "INTERNAL SERVER ERROR") == 0);
}
// HTTP Headers Tests
UNIT_TEST(http_headers) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
// Parse headers
strview_t header_str = strv_init("Content-Type: application/json\r\nUser-Agent: Colla\r\n");
http_header_t *headers = http_parse_headers(&arena, header_str);
// Check headers were parsed correctly
ASSERT(headers != NULL);
// Headers are parsed in reverse order
ASSERT(strv_equals(headers->key, strv_init("User-Agent")));
ASSERT(strv_equals(headers->value, strv_init("Colla")));
ASSERT(strv_equals(headers->next->key, strv_init("Content-Type")));
ASSERT(strv_equals(headers->next->value, strv_init("application/json")));
// Test header operations
ASSERT(http_has_header(headers, strv_init("Content-Type")));
ASSERT(!http_has_header(headers, strv_init("Accept")));
strview_t content_type = http_get_header(headers, strv_init("Content-Type"));
ASSERT(strv_equals(content_type, strv_init("application/json")));
// Don't try to free headers as they're allocated in the arena
arena_cleanup(&arena);
}
// HTTP Request/Response Parsing Tests
UNIT_TEST(http_request_parsing) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
strview_t req_str = strv_init(
"GET /index.html HTTP/1.1\r\n"
"Host: example.com\r\n"
"User-Agent: Colla\r\n"
"\r\n"
);
http_req_t req = http_parse_req(&arena, req_str);
ASSERT(req.method == HTTP_GET);
ASSERT(req.version.major == 1);
ASSERT(req.version.minor == 1);
ASSERT(strv_equals(req.url, strv("index.html")));
ASSERT(http_has_header(req.headers, strv_init("Host")));
ASSERT(strv_equals(http_get_header(req.headers, strv_init("Host")), strv_init("example.com")));
// Convert back to string
str_t req_out = http_req_to_str(&arena, &req);
ASSERT(!str_is_empty(req_out));
arena_cleanup(&arena);
}
UNIT_TEST(http_response_parsing) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
strview_t res_str = strv_init(
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 13\r\n"
"\r\n"
"Hello, World!"
);
http_res_t res = http_parse_res(&arena, res_str);
ASSERT(res.status_code == 200);
ASSERT(res.version.major == 1);
ASSERT(res.version.minor == 1);
ASSERT(strv_equals(res.body, strv_init("Hello, World!")));
ASSERT(http_has_header(res.headers, strv_init("Content-Type")));
ASSERT(strv_equals(http_get_header(res.headers, strv_init("Content-Type")), strv_init("text/html")));
// Convert back to string
str_t res_out = http_res_to_str(&arena, &res);
ASSERT(!str_is_empty(res_out));
arena_cleanup(&arena);
}
// URL Encoding/Decoding Tests
UNIT_TEST(http_url_encoding) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
strview_t original = strv_init("hello world & special chars: ?=&/");
str_t encoded = http_make_url_safe(&arena, original);
str_t decoded = http_decode_url_safe(&arena, strv_init_str(encoded));
ASSERT(!str_is_empty(encoded));
ASSERT(str_equals(decoded, str_init(&arena, "hello world & special chars: ?=&/")));
arena_cleanup(&arena);
}
UNIT_TEST(http_url_splitting) {
strview_t url = strv_init("http://example.com/path?query=value");
http_url_t split = http_split_url(url);
ASSERT(strv_equals(split.host, strv_init("example.com")));
ASSERT(strv_equals(split.uri, strv_init("/path?query=value")));
}
// HTTP Request Tests
// Note: These tests would actually make network requests, so we should mock them
// for real unit tests. Here we'll just test the setup part.
UNIT_TEST(http_request_setup) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
// Prepare headers
http_header_t headers[2] = {
{ .key = strv_init("Content-Type"), .value = strv_init("application/json"), .next = &headers[1] },
{ .key = strv_init("User-Agent"), .value = strv_init("Colla Test"), .next = NULL }
};
// Setup request descriptor
http_request_desc_t desc = {
.arena = &arena,
.url = strv_init("http://example.com"),
.version = { .major = 1, .minor = 1 },
.request_type = HTTP_GET,
.headers = headers,
.header_count = 2,
.body = strv_init("")
};
// We don't actually make the request, just verify the setup is correct
ASSERT(desc.arena == &arena);
ASSERT(strv_equals(desc.url, strv_init("http://example.com")));
ASSERT(desc.request_type == HTTP_GET);
ASSERT(desc.headers == headers);
ASSERT(desc.header_count == 2);
arena_cleanup(&arena);
}
// Socket Tests
UNIT_TEST(socket_basic) {
net_init();
// Open a socket
socket_t sock = sk_open(SOCK_TCP);
ASSERT(sk_is_valid(sock));
// Close the socket
ASSERT(sk_close(sock));
net_cleanup();
}
// SHA1 Tests
UNIT_TEST(sha1_hash) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
sha1_t ctx = sha1_init();
const char *data = "Hello, World!";
str_t hash = sha1_str(&arena, &ctx, data, strlen(data));
// The SHA1 hash for "Hello, World!" is known
// But we'll just verify it's not empty and has the expected format (40 hex chars)
ASSERT(!str_is_empty(hash));
ASSERT(hash.len == 40);
arena_cleanup(&arena);
}
// Base64 Tests
UNIT_TEST(base64_encoding) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
const char *original = "Hello, World!";
buffer_t input = { (u8*)original, strlen(original) };
// Encode
buffer_t encoded = base64_encode(&arena, input);
ASSERT(encoded.data != NULL);
ASSERT(encoded.len > 0);
// Decode
buffer_t decoded = base64_decode(&arena, encoded);
ASSERT(decoded.data != NULL);
ASSERT(decoded.len == input.len);
ASSERT(memcmp(decoded.data, input.data, input.len) == 0);
arena_cleanup(&arena);
}
// WebSocket Tests
UNIT_TEST(websocket_encoding) {
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
strview_t message = strv_init("Hello, WebSocket!");
// Encode message to WebSocket format
buffer_t encoded = websocket_encode(&arena, message);
ASSERT(encoded.data != NULL);
ASSERT(encoded.len > 0);
// Decode WebSocket message
str_t decoded = websocket_decode(&arena, encoded);
ASSERT(!str_is_empty(decoded));
ASSERT(str_equals(decoded, str_init(&arena, "Hello, WebSocket!")));
arena_cleanup(&arena);
}