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

/**
* 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;
}