You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
6.0 KiB
195 lines
6.0 KiB
/** |
|
* Unit tests for routing.c |
|
*/ |
|
|
|
#include "routing.h" |
|
#include <stdio.h> |
|
#include <assert.h> |
|
#include <string.h> |
|
#include <stdlib.h> |
|
#include <arpa/inet.h> |
|
|
|
static void test_create_destroy(void) { |
|
routing_table_t *table = routing_table_create(); |
|
assert(table != NULL); |
|
assert(table->count == 0); |
|
assert(table->capacity > 0); |
|
routing_table_destroy(table); |
|
printf("PASS: test_create_destroy\n"); |
|
} |
|
|
|
static void test_insert_lookup(void) { |
|
routing_table_t *table = routing_table_create(); |
|
assert(table != NULL); |
|
|
|
route_entry_t entry = {0}; |
|
entry.network = inet_addr("10.0.0.0"); |
|
entry.prefix_length = 24; |
|
entry.next_hop_ip = inet_addr("192.168.1.1"); |
|
entry.next_hop = NULL; |
|
entry.type = ROUTE_TYPE_STATIC; |
|
entry.flags = ROUTE_FLAG_ACTIVE; |
|
entry.metrics.bandwidth_kbps = 1000; |
|
entry.metrics.latency_ms = 10; |
|
entry.metrics.packet_loss_rate = 50; // 0.5% |
|
entry.metrics.hop_count = 1; |
|
|
|
bool inserted = routing_table_insert(table, &entry); |
|
assert(inserted == true); |
|
assert(table->count == 1); |
|
|
|
route_entry_t found = {0}; |
|
bool found_route = routing_table_lookup(table, inet_addr("10.0.0.5"), &found); |
|
assert(found_route == true); |
|
assert(found.network == entry.network); |
|
assert(found.prefix_length == entry.prefix_length); |
|
assert(found.next_hop_ip == entry.next_hop_ip); |
|
|
|
// Lookup non-existent |
|
found_route = routing_table_lookup(table, inet_addr("192.168.2.1"), &found); |
|
assert(found_route == false); |
|
|
|
routing_table_destroy(table); |
|
printf("PASS: test_insert_lookup\n"); |
|
} |
|
|
|
static void test_validation(void) { |
|
routing_table_t *table = routing_table_create(); |
|
assert(table != NULL); |
|
|
|
// Add allowed dynamic subnet |
|
bool added = routing_add_dynamic_subnet(table, inet_addr("172.16.0.0"), 16); |
|
assert(added == true); |
|
|
|
// Try to insert a dynamic route that matches allowed subnet |
|
route_entry_t entry = {0}; |
|
entry.network = inet_addr("172.16.1.0"); |
|
entry.prefix_length = 24; |
|
entry.next_hop_ip = inet_addr("192.168.1.1"); |
|
entry.type = ROUTE_TYPE_DYNAMIC; |
|
entry.flags = ROUTE_FLAG_ACTIVE; |
|
|
|
bool inserted = routing_table_insert(table, &entry); |
|
assert(inserted == true); |
|
|
|
// Try to insert a dynamic route outside allowed subnet (should fail validation) |
|
route_entry_t entry2 = {0}; |
|
entry2.network = inet_addr("10.0.0.0"); |
|
entry2.prefix_length = 24; |
|
entry2.next_hop_ip = inet_addr("192.168.1.1"); |
|
entry2.type = ROUTE_TYPE_DYNAMIC; |
|
entry2.flags = ROUTE_FLAG_ACTIVE; |
|
|
|
inserted = routing_table_insert(table, &entry2); |
|
assert(inserted == false); // should be rejected |
|
|
|
// Static routes should bypass validation |
|
route_entry_t entry3 = {0}; |
|
entry3.network = inet_addr("10.0.0.0"); |
|
entry3.prefix_length = 24; |
|
entry3.next_hop_ip = inet_addr("192.168.1.1"); |
|
entry3.type = ROUTE_TYPE_STATIC; |
|
entry3.flags = ROUTE_FLAG_ACTIVE; |
|
|
|
inserted = routing_table_insert(table, &entry3); |
|
assert(inserted == true); // static allowed |
|
|
|
routing_table_destroy(table); |
|
printf("PASS: test_validation\n"); |
|
} |
|
|
|
static void test_delete(void) { |
|
routing_table_t *table = routing_table_create(); |
|
assert(table != NULL); |
|
|
|
route_entry_t entry = {0}; |
|
entry.network = inet_addr("10.0.0.0"); |
|
entry.prefix_length = 24; |
|
entry.next_hop_ip = inet_addr("192.168.1.1"); |
|
entry.type = ROUTE_TYPE_STATIC; |
|
entry.flags = ROUTE_FLAG_ACTIVE; |
|
|
|
bool inserted = routing_table_insert(table, &entry); |
|
assert(inserted == true); |
|
assert(table->count == 1); |
|
|
|
bool deleted = routing_table_delete(table, inet_addr("10.0.0.0"), 24, entry.next_hop_ip); |
|
assert(deleted == true); |
|
assert(table->count == 0); |
|
|
|
// Delete non-existent |
|
deleted = routing_table_delete(table, inet_addr("10.0.0.0"), 24, entry.next_hop_ip); |
|
assert(deleted == false); |
|
|
|
routing_table_destroy(table); |
|
printf("PASS: test_delete\n"); |
|
} |
|
|
|
static void test_local_subnets(void) { |
|
routing_table_t *table = routing_table_create(); |
|
assert(table != NULL); |
|
|
|
bool added = routing_add_local_subnet(table, inet_addr("192.168.0.0"), 24); |
|
assert(added == true); |
|
|
|
// Local subnet validation should pass for local routes |
|
route_entry_t entry = {0}; |
|
entry.network = inet_addr("192.168.0.0"); |
|
entry.prefix_length = 24; |
|
entry.next_hop_ip = inet_addr("0.0.0.0"); |
|
entry.type = ROUTE_TYPE_LOCAL; |
|
entry.flags = ROUTE_FLAG_ACTIVE; |
|
|
|
bool inserted = routing_table_insert(table, &entry); |
|
assert(inserted == true); |
|
|
|
routing_table_destroy(table); |
|
printf("PASS: test_local_subnets\n"); |
|
} |
|
|
|
static void test_get_all_routes(void) { |
|
routing_table_t *table = routing_table_create(); |
|
assert(table != NULL); |
|
|
|
// Insert multiple routes for same network |
|
route_entry_t entry1 = {0}; |
|
entry1.network = inet_addr("10.0.0.0"); |
|
entry1.prefix_length = 24; |
|
entry1.next_hop_ip = inet_addr("192.168.1.1"); |
|
entry1.type = ROUTE_TYPE_STATIC; |
|
entry1.flags = ROUTE_FLAG_ACTIVE; |
|
|
|
route_entry_t entry2 = {0}; |
|
entry2.network = inet_addr("10.0.0.0"); |
|
entry2.prefix_length = 24; |
|
entry2.next_hop_ip = inet_addr("192.168.1.2"); |
|
entry2.type = ROUTE_TYPE_STATIC; |
|
entry2.flags = ROUTE_FLAG_ACTIVE; |
|
|
|
assert(routing_table_insert(table, &entry1) == true); |
|
assert(routing_table_insert(table, &entry2) == true); |
|
|
|
route_entry_t *routes = NULL; |
|
size_t count = 0; |
|
bool got = routing_get_all_routes(table, inet_addr("10.0.0.0"), 24, &routes, &count); |
|
assert(got == true); |
|
assert(count == 2); |
|
|
|
// Clean up allocated routes |
|
free(routes); |
|
|
|
routing_table_destroy(table); |
|
printf("PASS: test_get_all_routes\n"); |
|
} |
|
|
|
int main(void) { |
|
printf("Running routing unit tests...\n"); |
|
test_create_destroy(); |
|
test_insert_lookup(); |
|
test_validation(); |
|
test_delete(); |
|
test_local_subnets(); |
|
test_get_all_routes(); |
|
printf("All tests passed!\n"); |
|
return 0; |
|
} |