83 lines
3.2 KiB
C
83 lines
3.2 KiB
C
#include "c_MinPQ.h"
|
|||
|
|
#include <stdlib.h>
|
||
|
|
#include <stdio.h>
|
||
|
|
|
||
|
|
|
||
|
|
#define EXPECT_EQ(val1, val2, msg) \
|
||
|
|
do { \
|
||
|
|
if ((val1) != (val2)) { printf(" [X] Failed: %s (Expected %d, got %d)\n", msg, (int)(val2), (int)(val1)); return false; } \
|
||
|
|
} while(0)
|
||
|
|
|
||
|
|
// Complex element structural payload
|
||
|
|
typedef struct {
|
||
|
|
int packet_id;
|
||
|
|
int latency_ms; // Primary sorting metric (smaller value = higher priority = popped first)
|
||
|
|
} NetworkPacket;
|
||
|
|
|
||
|
|
// Min-Heap comparator: Returns negative if a < b
|
||
|
|
int comparePacketsByLatency(const void* a, const void* b) {
|
||
|
|
return (((NetworkPacket*)a)->latency_ms - ((NetworkPacket*)b)->latency_ms);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validation Pipeline Function
|
||
|
|
bool test_minpq_functional_flow(void) {
|
||
|
|
c_MinPQ_t pq;
|
||
|
|
// Initialize with a tiny capacity of 2 to verify dynamic allocation resize steps
|
||
|
|
EXPECT_EQ(c_MinPQ_Init(&pq, 2, sizeof(NetworkPacket), comparePacketsByLatency), C_ERR_OK, "Initialization failed");
|
||
|
|
|
||
|
|
NetworkPacket packets[] = {
|
||
|
|
{ 7001, 120 }, // High Latency
|
||
|
|
{ 7002, 15 }, // Ultra-low Latency (Should be extracted first!)
|
||
|
|
{ 7003, 45 }, // Mid Latency
|
||
|
|
{ 7004, 80 } // High-mid Latency
|
||
|
|
};
|
||
|
|
|
||
|
|
// 1. Push Operations
|
||
|
|
EXPECT_EQ(c_MinPQ_Push(&pq, &packets[0]), C_ERR_OK, "Push 0 failed");
|
||
|
|
EXPECT_EQ(c_MinPQ_Push(&pq, &packets[1]), C_ERR_OK, "Push 1 failed");
|
||
|
|
EXPECT_EQ(c_MinPQ_Push(&pq, &packets[2]), C_ERR_OK, "Push 2 failed (Triggers automatic resize expansion)");
|
||
|
|
EXPECT_EQ(c_MinPQ_Push(&pq, &packets[3]), C_ERR_OK, "Push 3 failed");
|
||
|
|
EXPECT_EQ(pq.size, 4, "Active queue size layout tracker mismatched");
|
||
|
|
|
||
|
|
// 2. Peek Verification (Must target the absolute minimum latency element)
|
||
|
|
NetworkPacket* peeked = (NetworkPacket*)c_MinPQ_Peek(&pq);
|
||
|
|
EXPECT_EQ(peeked != NULL && peeked->latency_ms == 15, true, "Peek failed to find minimum item root pointer");
|
||
|
|
|
||
|
|
// 3. Sequential Extraction (Pop validation)
|
||
|
|
NetworkPacket out;
|
||
|
|
|
||
|
|
// Pop 1: Latency 15 (ID 7002)
|
||
|
|
EXPECT_EQ(c_MinPQ_Pop(&pq, &out), C_ERR_OK, "Pop 1 crashed");
|
||
|
|
EXPECT_EQ(out.packet_id, 7002, "Min extraction sequence failed at item 1");
|
||
|
|
|
||
|
|
// Pop 2: Latency 45 (ID 7003)
|
||
|
|
EXPECT_EQ(c_MinPQ_Pop(&pq, &out), C_ERR_OK, "Pop 2 crashed");
|
||
|
|
EXPECT_EQ(out.packet_id, 7003, "Min extraction sequence failed at item 2");
|
||
|
|
|
||
|
|
// Pop 3: Latency 80 (ID 7004)
|
||
|
|
EXPECT_EQ(c_MinPQ_Pop(&pq, &out), C_ERR_OK, "Pop 3 crashed");
|
||
|
|
EXPECT_EQ(out.packet_id, 7004, "Min extraction sequence failed at item 3");
|
||
|
|
|
||
|
|
// Pop 4: Latency 120 (ID 7001)
|
||
|
|
EXPECT_EQ(c_MinPQ_Pop(&pq, &out), C_ERR_OK, "Pop 4 crashed");
|
||
|
|
EXPECT_EQ(out.packet_id, 7001, "Min extraction sequence failed at item 4");
|
||
|
|
|
||
|
|
// 4. Empty and Bounds Verification
|
||
|
|
EXPECT_EQ(pq.size, 0, "Queue did not empty out properly");
|
||
|
|
EXPECT_EQ(c_MinPQ_Pop(&pq, &out), C_ERR_EMPTY, "Pop on empty queue did not throw C_ERR_EMPTY");
|
||
|
|
|
||
|
|
c_MinPQ_Destroy(&pq);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(void) {
|
||
|
|
printf("=== Starting Custom Framework Testing for c_MinPQ ===\n");
|
||
|
|
|
||
|
|
if (test_minpq_functional_flow()) {
|
||
|
|
printf(" [PASS] Test: Min-Heap Push/Pop Sifting and Resizing Sequences Verified Successfully\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("=== All Min-Priority Queue Framework Tests Completed ===\n");
|
||
|
|
return 0;
|
||
|
|
}
|