feat: add http implementation test suite
This commit is contained in:
parent
ddbcba3cd6
commit
c8e03e3c3d
@ -2,6 +2,14 @@
|
||||
|
||||
|
||||
|
||||
|
||||
## Version 0.2.0 - 2025-11-05
|
||||
|
||||
Updated documentation files. This includes changes to the project's release notes and a header file.
|
||||
|
||||
**Changes:** 2 files, 103 lines
|
||||
**Languages:** C (93 lines), Markdown (10 lines)
|
||||
|
||||
## Version 0.1.0 - 2025-11-05
|
||||
|
||||
Automated versioning and changelog updates are now available when you commit code. This simplifies release management and ensures accurate changelog entries.
|
||||
|
||||
286
http.c
Normal file
286
http.c
Normal file
@ -0,0 +1,286 @@
|
||||
// HTTP Implementation Test Suite
|
||||
// Copyright (c) 2023 retoor
|
||||
// Licensed under MIT License
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include "http.h"
|
||||
|
||||
double get_current_time_in_milliseconds() {
|
||||
struct timeval time_value;
|
||||
gettimeofday(&time_value, NULL);
|
||||
return (time_value.tv_sec * 1000.0) + (time_value.tv_usec / 1000.0);
|
||||
}
|
||||
|
||||
void print_response_preview(const char *response, size_t maximum_length) {
|
||||
if (!response) {
|
||||
printf("Response: NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t response_length = strlen(response);
|
||||
printf("Response length: %zu bytes\n", response_length);
|
||||
printf("First %zu chars: %.100s%s\n",
|
||||
maximum_length, response, response_length > maximum_length ? "..." : "");
|
||||
}
|
||||
|
||||
void test_https_get() {
|
||||
printf("\n=== Testing HTTPS GET ===\n");
|
||||
|
||||
const char * const test_urls[] = {
|
||||
"https://httpbin.org/get",
|
||||
"https://jsonplaceholder.typicode.com/posts/1",
|
||||
"https://api.github.com/repos/torvalds/linux",
|
||||
"https://www.example.com/",
|
||||
"https://httpbin.org/bytes/1024"
|
||||
};
|
||||
|
||||
size_t number_of_tests = sizeof(test_urls) / sizeof(test_urls[0]);
|
||||
|
||||
for (size_t index = 0; index < number_of_tests; index++) {
|
||||
printf("\nTest %zu: GET %s\n", index + 1, test_urls[index]);
|
||||
|
||||
double start_time = get_current_time_in_milliseconds();
|
||||
char *response = https_get((char *)test_urls[index]);
|
||||
double end_time = get_current_time_in_milliseconds();
|
||||
|
||||
printf("Time taken: %.2f ms\n", end_time - start_time);
|
||||
print_response_preview(response, 100);
|
||||
|
||||
if (response) {
|
||||
free(response);
|
||||
printf("Status: SUCCESS\n");
|
||||
} else {
|
||||
printf("Status: FAILED\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_https_post() {
|
||||
printf("\n=== Testing HTTPS POST ===\n");
|
||||
|
||||
const char * const test_urls[] = {
|
||||
"https://httpbin.org/post",
|
||||
"https://jsonplaceholder.typicode.com/posts",
|
||||
"https://httpbin.org/anything"
|
||||
};
|
||||
|
||||
const char * const test_payloads[] = {
|
||||
"{\"test\": \"data\", \"number\": 123}",
|
||||
"{\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1}",
|
||||
"{\"key1\": \"value1\", \"key2\": [1, 2, 3], \"key3\": {\"nested\": true}}"
|
||||
};
|
||||
|
||||
size_t number_of_tests = sizeof(test_urls) / sizeof(test_urls[0]);
|
||||
|
||||
for (size_t index = 0; index < number_of_tests; index++) {
|
||||
printf("\nTest %zu: POST %s\n", index + 1, test_urls[index]);
|
||||
printf("Payload: %s\n", test_payloads[index]);
|
||||
|
||||
double start_time = get_current_time_in_milliseconds();
|
||||
char *response = https_post((char *)test_urls[index], (char *)test_payloads[index]);
|
||||
double end_time = get_current_time_in_milliseconds();
|
||||
|
||||
printf("Time taken: %.2f ms\n", end_time - start_time);
|
||||
print_response_preview(response, 100);
|
||||
|
||||
if (response) {
|
||||
free(response);
|
||||
printf("Status: SUCCESS\n");
|
||||
} else {
|
||||
printf("Status: FAILED\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_http_get() {
|
||||
printf("\n=== Testing HTTP GET ===\n");
|
||||
|
||||
const char * const test_urls[] = {
|
||||
"http://httpbin.org/get",
|
||||
"http://httpbin.org/headers",
|
||||
"http://httpbin.org/user-agent"
|
||||
};
|
||||
|
||||
size_t number_of_tests = sizeof(test_urls) / sizeof(test_urls[0]);
|
||||
|
||||
for (size_t index = 0; index < number_of_tests; index++) {
|
||||
printf("\nTest %zu: GET %s\n", index + 1, test_urls[index]);
|
||||
|
||||
double start_time = get_current_time_in_milliseconds();
|
||||
char *response = http_get((char *)test_urls[index]);
|
||||
double end_time = get_current_time_in_milliseconds();
|
||||
|
||||
printf("Time taken: %.2f ms\n", end_time - start_time);
|
||||
print_response_preview(response, 100);
|
||||
|
||||
if (response) {
|
||||
free(response);
|
||||
printf("Status: SUCCESS\n");
|
||||
} else {
|
||||
printf("Status: FAILED\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_http_post() {
|
||||
printf("\n=== Testing HTTP POST ===\n");
|
||||
|
||||
const char * const test_urls[] = {
|
||||
"http://httpbin.org/post",
|
||||
"http://httpbin.org/anything"
|
||||
};
|
||||
|
||||
const char * const test_payloads[] = {
|
||||
"{\"message\": \"Hello World\"}",
|
||||
"{\"test\": true, \"count\": 42}"
|
||||
};
|
||||
|
||||
size_t number_of_tests = sizeof(test_urls) / sizeof(test_urls[0]);
|
||||
|
||||
for (size_t index = 0; index < number_of_tests; index++) {
|
||||
printf("\nTest %zu: POST %s\n", index + 1, test_urls[index]);
|
||||
printf("Payload: %s\n", test_payloads[index]);
|
||||
|
||||
double start_time = get_current_time_in_milliseconds();
|
||||
char *response = http_post((char *)test_urls[index], (char *)test_payloads[index]);
|
||||
double end_time = get_current_time_in_milliseconds();
|
||||
|
||||
printf("Time taken: %.2f ms\n", end_time - start_time);
|
||||
print_response_preview(response, 100);
|
||||
|
||||
if (response) {
|
||||
free(response);
|
||||
printf("Status: SUCCESS\n");
|
||||
} else {
|
||||
printf("Status: FAILED\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_chunked_response() {
|
||||
printf("\n=== Testing Chunked Transfer Encoding ===\n");
|
||||
|
||||
const char * const test_urls[] = {
|
||||
"https://httpbin.org/stream/5",
|
||||
"https://httpbin.org/drip?duration=2&numbytes=10&code=200",
|
||||
"http://httpbin.org/stream-bytes/1024"
|
||||
};
|
||||
|
||||
size_t number_of_tests = sizeof(test_urls) / sizeof(test_urls[0]);
|
||||
|
||||
for (size_t index = 0; index < number_of_tests; index++) {
|
||||
printf("\nTest %zu: GET %s\n", index + 1, test_urls[index]);
|
||||
|
||||
double start_time = get_current_time_in_milliseconds();
|
||||
char *response = NULL;
|
||||
|
||||
if (strncmp(test_urls[index], "https://", 8) == 0) {
|
||||
response = https_get((char *)test_urls[index]);
|
||||
} else {
|
||||
response = http_get((char *)test_urls[index]);
|
||||
}
|
||||
|
||||
double end_time = get_current_time_in_milliseconds();
|
||||
|
||||
printf("Time taken: %.2f ms\n", end_time - start_time);
|
||||
print_response_preview(response, 100);
|
||||
|
||||
if (response) {
|
||||
free(response);
|
||||
printf("Status: SUCCESS\n");
|
||||
} else {
|
||||
printf("Status: FAILED\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void benchmark_requests() {
|
||||
printf("\n=== Benchmarking Performance ===\n");
|
||||
|
||||
const char * const benchmark_url = "https://httpbin.org/get";
|
||||
size_t number_of_requests = 10;
|
||||
double total_time = 0.0;
|
||||
size_t successful_requests = 0;
|
||||
|
||||
printf("Benchmarking %zu requests to %s\n", number_of_requests, benchmark_url);
|
||||
|
||||
for (size_t index = 0; index < number_of_requests; index++) {
|
||||
double start_time = get_current_time_in_milliseconds();
|
||||
char *response = https_get((char *)benchmark_url);
|
||||
double end_time = get_current_time_in_milliseconds();
|
||||
|
||||
double request_time = end_time - start_time;
|
||||
total_time += request_time;
|
||||
|
||||
if (response) {
|
||||
successful_requests++;
|
||||
free(response);
|
||||
printf("Request %2zu: %.2f ms\n", index + 1, request_time);
|
||||
} else {
|
||||
printf("Request %2zu: FAILED\n", index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nBenchmark Results:\n");
|
||||
printf("Total requests: %zu\n", number_of_requests);
|
||||
printf("Successful: %zu\n", successful_requests);
|
||||
printf("Failed: %zu\n", number_of_requests - successful_requests);
|
||||
printf("Total time: %.2f ms\n", total_time);
|
||||
printf("Average time per request: %.2f ms\n", total_time / number_of_requests);
|
||||
printf("Success rate: %.1f%%\n", (successful_requests * 100.0) / number_of_requests);
|
||||
}
|
||||
|
||||
void test_large_response() {
|
||||
printf("\n=== Testing Large Response Handling ===\n");
|
||||
|
||||
const char * const test_urls[] = {
|
||||
"https://httpbin.org/bytes/10240", // 10 KB
|
||||
"https://httpbin.org/bytes/102400", // 100 KB
|
||||
"https://httpbin.org/base64/SFRUUEJJTiBpcyBhd2Vzb21l" // Base64 response
|
||||
};
|
||||
|
||||
const char * const size_descriptions[] = {"10 KB", "100 KB", "Base64"};
|
||||
|
||||
size_t number_of_tests = sizeof(test_urls) / sizeof(test_urls[0]);
|
||||
|
||||
for (size_t index = 0; index < number_of_tests; index++) {
|
||||
printf("\nTest %zu: Large response (%s) from %s\n", index + 1, size_descriptions[index], test_urls[index]);
|
||||
|
||||
double start_time = get_current_time_in_milliseconds();
|
||||
char *response = https_get((char *)test_urls[index]);
|
||||
double end_time = get_current_time_in_milliseconds();
|
||||
|
||||
if (response) {
|
||||
size_t response_length = strlen(response);
|
||||
printf("Response size: %zu bytes\n", response_length);
|
||||
printf("Time taken: %.2f ms\n", end_time - start_time);
|
||||
printf("Transfer rate: %.2f KB/s\n", (response_length / 1024.0) / ((end_time - start_time) / 1000.0));
|
||||
free(response);
|
||||
printf("Status: SUCCESS\n");
|
||||
} else {
|
||||
printf("Status: FAILED\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argument_count, char *argument_values[]) {
|
||||
printf("HTTP Implementation Test Suite\n");
|
||||
printf("==============================\n");
|
||||
|
||||
test_https_get();
|
||||
test_https_post();
|
||||
test_http_get();
|
||||
test_http_post();
|
||||
test_chunked_response();
|
||||
test_large_response();
|
||||
benchmark_requests();
|
||||
|
||||
printf("\n\nAll tests completed!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user