79 lines
1.9 KiB
Python
79 lines
1.9 KiB
Python
import random
|
|
from task_scheduler import Task, makespan_exact, makespan_critical_path, _validate
|
|
|
|
|
|
def test_empty():
|
|
assert makespan_exact([]) == 0
|
|
assert makespan_critical_path([]) == 0
|
|
|
|
|
|
def test_single():
|
|
assert makespan_exact([Task("a", 5)]) == 5
|
|
|
|
|
|
def test_chain():
|
|
assert makespan_exact([Task("a", 3), Task("b", 4, {"a"})]) == 7
|
|
|
|
|
|
def test_parallel():
|
|
assert makespan_exact([Task("a", 3), Task("b", 4)]) == 4
|
|
|
|
|
|
def test_diamond():
|
|
tasks = [Task("a", 3), Task("b", 4), Task("c", 2, {"a", "b"})]
|
|
assert makespan_exact(tasks) == 6
|
|
assert makespan_exact(tasks) == makespan_critical_path(tasks)
|
|
|
|
|
|
def test_matches_critical_path_random():
|
|
random.seed(7)
|
|
for trial in range(500):
|
|
n = random.randint(0, 8)
|
|
tids = [f"t{i}" for i in range(n)]
|
|
tasks = []
|
|
for i, tid in enumerate(tids):
|
|
dur = random.randint(1, 6)
|
|
cand = tids[:i]
|
|
preds = set(random.sample(cand, random.randint(0, len(cand))))
|
|
tasks.append(Task(tid, dur, preds))
|
|
a = makespan_exact(tasks)
|
|
b = makespan_critical_path(tasks)
|
|
assert a == b
|
|
|
|
|
|
def test_validation_duplicate():
|
|
try:
|
|
_validate([Task("a", 1), Task("a", 2)])
|
|
except ValueError:
|
|
return
|
|
raise AssertionError("expected ValueError")
|
|
|
|
|
|
def test_validation_unknown_pred():
|
|
try:
|
|
_validate([Task("a", 1, {"z"})])
|
|
except ValueError:
|
|
return
|
|
raise AssertionError("expected ValueError")
|
|
|
|
|
|
def test_validation_self():
|
|
try:
|
|
_validate([Task("a", 1, {"a"})])
|
|
except ValueError:
|
|
return
|
|
raise AssertionError("expected ValueError")
|
|
|
|
|
|
def test_validation_cycle():
|
|
try:
|
|
_validate([Task("a", 1, {"b"}), Task("b", 1, {"a"})])
|
|
except ValueError:
|
|
return
|
|
raise AssertionError("expected ValueError")
|
|
|
|
|
|
def test_zero_duration():
|
|
tasks = [Task("a", 0), Task("b", 2, {"a"})]
|
|
assert makespan_exact(tasks) == 2
|