.
This commit is contained in:
parent
524ec0d1ce
commit
61c1060a98
16 changed files with 5043 additions and 31 deletions
237
tests/net_tests.c
Normal file
237
tests/net_tests.c
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
#include "runner.h"
|
||||
#include "../colla.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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue