// test_queue_index_compact.cpp - Verify qi_compact_index removes finished/failed tasks // Validates F4 fix: compact_index actually removes tasks with finished/failed status #include #include #include #include #include #include "../queue_index/queue_index.h" int main() { // Create a temporary directory for the queue char tmpdir[] = "/tmp/test_compact_XXXXXX"; if (!mkdtemp(tmpdir)) { printf("FAIL: Could not create temp directory\n"); return 1; } // Open queue index qi_index_t* idx = qi_open(tmpdir); if (!idx) { printf("FAIL: Could not open queue index\n"); return 1; } // Add tasks with different statuses qi_task_t tasks[5]; memset(tasks, 0, sizeof(tasks)); // Task 0: queued strncpy(tasks[0].id, "task_000", sizeof(tasks[0].id)); strncpy(tasks[0].job_name, "job0", sizeof(tasks[0].job_name)); strncpy(tasks[0].status, "queued", sizeof(tasks[0].status)); tasks[0].priority = 100; // Task 1: finished (should be removed) strncpy(tasks[1].id, "task_001", sizeof(tasks[1].id)); strncpy(tasks[1].job_name, "job1", sizeof(tasks[1].job_name)); strncpy(tasks[1].status, "finished", sizeof(tasks[1].status)); tasks[1].priority = 100; // Task 2: failed (should be removed) strncpy(tasks[2].id, "task_002", sizeof(tasks[2].id)); strncpy(tasks[2].job_name, "job2", sizeof(tasks[2].job_name)); strncpy(tasks[2].status, "failed", sizeof(tasks[2].status)); tasks[2].priority = 100; // Task 3: running strncpy(tasks[3].id, "task_003", sizeof(tasks[3].id)); strncpy(tasks[3].job_name, "job3", sizeof(tasks[3].job_name)); strncpy(tasks[3].status, "running", sizeof(tasks[3].status)); tasks[3].priority = 100; // Task 4: queued strncpy(tasks[4].id, "task_004", sizeof(tasks[4].id)); strncpy(tasks[4].job_name, "job4", sizeof(tasks[4].job_name)); strncpy(tasks[4].status, "queued", sizeof(tasks[4].status)); tasks[4].priority = 100; int added = qi_add_tasks(idx, tasks, 5); if (added != 5) { printf("FAIL: Could not add tasks (added %d)\n", added); qi_close(idx); return 1; } printf("Added 5 tasks\n"); // Compact the index (no explicit save needed - happens on close) int removed = qi_compact_index(idx); if (removed != 2) { printf("FAIL: Expected 2 tasks removed, got %d\n", removed); qi_close(idx); return 1; } // Close and reopen to verify persistence qi_close(idx); idx = qi_open(tmpdir); if (!idx) { printf("FAIL: Could not reopen queue index\n"); return 1; } // Get all remaining tasks qi_task_t* remaining_tasks = nullptr; size_t remaining_count = 0; if (qi_get_all_tasks(idx, &remaining_tasks, &remaining_count) != 0) { printf("FAIL: Could not get all tasks\n"); qi_close(idx); return 1; } if (remaining_count != 3) { printf("FAIL: Expected 3 remaining tasks, got %zu\n", remaining_count); qi_free_task_array(remaining_tasks); qi_close(idx); return 1; } // Verify all remaining tasks are not finished/failed for (size_t i = 0; i < remaining_count; i++) { if (strcmp(remaining_tasks[i].status, "finished") == 0 || strcmp(remaining_tasks[i].status, "failed") == 0) { printf("FAIL: Task %zu has status '%s' after compact\n", i, remaining_tasks[i].status); qi_free_task_array(remaining_tasks); qi_close(idx); return 1; } } printf("Remaining %zu tasks have correct statuses\n", remaining_count); // Cleanup qi_free_task_array(remaining_tasks); qi_close(idx); // Remove index file and directory char index_path[256]; snprintf(index_path, sizeof(index_path), "%s/index.bin", tmpdir); unlink(index_path); rmdir(tmpdir); printf("PASS: qi_compact_index removes finished/failed tasks (F4 fix verified)\n"); return 0; }