bs-01-scheduling/scheduler_round_robin_test.h

167 lines
4.3 KiB
C
Raw Normal View History

2026-05-22 15:31:47 +02:00
#ifndef SCHEDULER_ROUND_ROBIN_TEST_H
#define SCHEDULER_ROUND_ROBIN_TEST_H
#include <assert.h>
#include "scheduler.h"
void stud_RR_start(struct run_queue *rq, int pid);
void stud_RR_elect(struct run_queue *rq);
void stud_RR_terminate(struct run_queue *rq);
void stud_RR_clock_tick(struct run_queue *rq);
void stud_RR_wait(struct run_queue *rq);
void stud_RR_wake_up(struct run_queue *rq, int pid);
void stud_RR(struct run_queue* rq, enum events event, int pid);
// Mock implementation of the grader's verifier
bool rq_eq(struct run_queue *sol, struct run_queue *stu) {
if (sol->n_tasks != stu->n_tasks) return false;
if (sol->n_tasks == 0) return true;
struct task *c1 = sol->head;
struct task *c2 = stu->head;
int pos = 0;
do {
if (c1->pid != c2->pid || c1->state != c2->state) {
fprintf(stderr, "Task (%d, %s) error at position %d\n",
c2->pid, c2->state == RUNNING ? "running" : "other", pos);
return false;
}
c1 = c1->next;
c2 = c2->next;
pos++;
} while (c1 != sol->head && c2 != stu->head);
return true;
}
// Crash line 73 in your log
void test_RR_start() {
struct run_queue stu = {NULL, 0, 0};
struct run_queue sol = {NULL, 0, 0}; // Mock expected state
// Manually build expected solution queue to compare against
stud_rq_enqueue(&sol, stud_task_create(1, RUNNING));
stud_rq_enqueue(&sol, stud_task_create(2, READY));
stud_rq_enqueue(&sol, stud_task_create(3, READY));
printf("add task 1\n");
stud_RR_start(&stu, 1);
printf("add task 2\n");
stud_RR_start(&stu, 2);
printf("add task 3\n");
stud_RR_start(&stu, 3);
printf("add task 1 again\n");
stud_RR_start(&stu, 1);
print_rq(&stu);
// Line 73
assert(rq_eq(&sol, &stu));
}
// Helper to prepopulate a specific queue state for testing the crash logs
void prepopulate_queue(struct run_queue *rq) {
stud_rq_enqueue(rq, stud_task_create(1, RUNNING));
stud_rq_enqueue(rq, stud_task_create(2, TERMINATED));
stud_rq_enqueue(rq, stud_task_create(3, READY));
stud_rq_enqueue(rq, stud_task_create(4, TERMINATED));
stud_rq_enqueue(rq, stud_task_create(8, READY));
stud_rq_enqueue(rq, stud_task_create(14, BLOCKED));
}
// Crash line 109 in your log
void test_RR_elect_running() {
struct run_queue rq = {NULL, 0, 0};
prepopulate_queue(&rq);
print_rq(&rq);
printf("electing new task...\n");
// Line 109
stud_RR_elect(&rq);
}
// Crash line 127 in your log
void test_RR_elect_blocked() {
struct run_queue rq = {NULL, 0, 0};
prepopulate_queue(&rq);
rq.head->state = BLOCKED; // Change 1 to blocked
print_rq(&rq);
printf("electing new task...\n");
// Line 127
stud_RR_elect(&rq);
}
// Crash line 148 in your log
void test_RR_terminate() {
struct run_queue rq = {NULL, 0, 0};
prepopulate_queue(&rq);
print_rq(&rq);
printf("task terminating...\n");
// Line 148
stud_RR_terminate(&rq);
}
// Crash line 169 in your log
void test_RR_wait() {
struct run_queue rq = {NULL, 0, 0};
prepopulate_queue(&rq);
print_rq(&rq);
printf("task is waiting...\n");
// Line 169
stud_RR_wait(&rq);
}
// Crash line 190 in your log
void test_RR_wake_up() {
struct run_queue rq = {NULL, 0, 0};
prepopulate_queue(&rq);
print_rq(&rq);
printf("task 14 waking up...\n");
// Line 190
stud_RR_wake_up(&rq, 14);
}
// Crash line 216 in your log
void test_RR_clock_tick() {
struct run_queue stu = {NULL, 0, 0};
prepopulate_queue(&stu);
print_rq(&stu);
for(int i=0; i<10; i++) {
printf("running clock tick...\n");
stud_RR_clock_tick(&stu);
}
print_rq(&stu);
struct run_queue sol = {NULL, 0, 0};
// Expected solution queue state omitted for brevity
// Line 216
// assert(rq_eq(&sol, &stu));
}
// Crash line 263 in your log
void test_RR_scripted_1() {
struct run_queue stu = {NULL, 0, 0};
prepopulate_queue(&stu);
print_rq(&stu);
for(int i=0; i<5; i++) {
printf("running clock tick...\n");
stud_RR_clock_tick(&stu);
}
print_rq(&stu);
printf("task is waiting...\n");
// Line 263
stud_RR(&stu, wait, 0);
}
#endif // SCHEDULER_ROUND_ROBIN_TEST_H