package jobqueue import ( "testing" ) func TestEnqueueJobAlreadyExists(t *testing.T) { runner := &DummyRunnable{} job := NewJob[DummyResult](JobID("1"), runner) q := NewQueue(nil) _ = q.Enqueue(job) err := q.Enqueue(job) if err != ErrJobAlreadyExists { t.Fatalf("Expected ErrJobAlreadyExists, got %v", err) } } func TestEnqueueAndDequeue(t *testing.T) { runner := &DummyRunnable{} q := NewQueue(nil) job1 := NewJob[DummyResult](JobID("1"), runner) job1.SetPriority(PriorityHigh) job2 := NewJob[DummyResult](JobID("2"), runner) _ = q.Enqueue(job1) _ = q.Enqueue(job2) dequeuedJob, err := q.Dequeue() if err != nil || dequeuedJob.GetID() != JobID("1") { t.Fatalf("Unexpected dequeue result: jobID %s, err %v", dequeuedJob.GetID(), err) } } func TestEnqueueAndDequeue2(t *testing.T) { runner := &DummyRunnable{} q := NewQueue(nil) job1 := NewJob[DummyResult](JobID("1"), runner) job2 := NewJob[DummyResult](JobID("2"), runner) job2.AddDependency(JobID("1")) _ = q.Enqueue(job1) _ = q.Enqueue(job2) dequeuedJob, err := q.Dequeue() if err != nil { t.Fatalf("Unexpected error: %v", err) } if dequeuedJob.GetID() != JobID("1") { t.Fatalf("Unexpected dequeue result: jobID %s", dequeuedJob.GetID()) } } func TestDependencyResolution(t *testing.T) { runner := &DummyRunnable{} q := NewQueue(nil) job1 := NewJob[DummyResult](JobID("1"), runner) job2 := NewJob[DummyResult](JobID("2"), runner) job3 := NewJob[DummyResult](JobID("3"), runner) _ = q.Enqueue(job3) _ = q.Enqueue(job2) _ = q.Enqueue(job1) contains := func(arr []JobID, id JobID) bool { for _, v := range arr { if v == id { return true } } return false } possibleJobIDs := []JobID{"1", "2", "3"} job, _ := q.Dequeue() if !contains(possibleJobIDs, job.GetID()) { t.Fatalf("Expected jobID in %v, got %s", possibleJobIDs, job.GetID()) } // remove jobID from possibleJobIDs for i, v := range possibleJobIDs { if v == job.GetID() { possibleJobIDs = append(possibleJobIDs[:i], possibleJobIDs[i+1:]...) } } job, _ = q.Dequeue() if !contains(possibleJobIDs, job.GetID()) { t.Fatalf("Expected jobID in %v, got %s", possibleJobIDs, job.GetID()) } // remove jobID from possibleJobIDs for i, v := range possibleJobIDs { if v == job.GetID() { possibleJobIDs = append(possibleJobIDs[:i], possibleJobIDs[i+1:]...) } } job, _ = q.Dequeue() if !contains(possibleJobIDs, job.GetID()) { t.Fatalf("Expected jobID in %v, got %s", possibleJobIDs, job.GetID()) } // remove jobID from possibleJobIDs for i, v := range possibleJobIDs { if v == job.GetID() { possibleJobIDs = append(possibleJobIDs[:i], possibleJobIDs[i+1:]...) } } if len(possibleJobIDs) != 0 { t.Fatalf("Expected no jobIDs left in %v", possibleJobIDs) } } func TestDequeueEmptyQueue(t *testing.T) { q := NewQueue(nil) _, err := q.Dequeue() if err != ErrQueueEmpty { t.Fatalf("Expected ErrQueueEmpty, got %v", err) } } func TestProcessedJobs(t *testing.T) { q := NewQueue(nil) runner := &DummyRunnable{} job1 := NewJob[DummyResult](JobID("1"), runner) job2 := NewJob[DummyResult](JobID("2"), runner) _ = q.Enqueue(job1) _, _ = q.Dequeue() _ = q.Enqueue(job2) _, err := q.Dequeue() if err != nil { t.Fatalf("Dequeue failed: %v", err) } if _, exists := q.processedJobs[job1.GetID()]; !exists { t.Fatalf("Job 1 not marked as processed") } } func TestCyclicDependencies(t *testing.T) { runner := &DummyRunnable{} q := NewQueue(nil) job1 := NewJob[DummyResult](JobID("1"), runner) job2 := NewJob[DummyResult](JobID("2"), runner) job3 := NewJob[DummyResult](JobID("3"), runner) job1.AddDependency(JobID("2")) job2.AddDependency(JobID("3")) job3.AddDependency(JobID("1")) err := q.Enqueue(job1) if err != nil { t.Fatalf("Enqueue failed: %v", err) } err = q.Enqueue(job2) if err != nil { t.Fatalf("Enqueue failed: %v", err) } err = q.Enqueue(job3) if err == nil || err != ErrCycleDetected { t.Fatalf("Expected ErrCyclicDependency, got %v", err) } } func TestDuplicateDependencies(t *testing.T) { runner := &DummyRunnable{} q := NewQueue(nil) job1 := NewJob[DummyResult](JobID("1"), runner) job2 := NewJob[DummyResult](JobID("2"), runner) job2.AddDependency(JobID("1")) job2.AddDependency(JobID("1")) _ = q.Enqueue(job1) err := q.Enqueue(job2) if err != nil { t.Fatalf("Enqueue failed: %v", err) } _, err = q.Dequeue() if err != nil { t.Fatalf("Dequeue failed: %v", err) } _, err = q.Dequeue() if err != nil { t.Fatalf("Dequeue failed: %v", err) } if len(q.processedJobs) != 2 { t.Fatalf("Expected 2 processed jobs, got %d", len(q.processedJobs)) } } func TestJobWithSelfAsDependency(t *testing.T) { runner := &DummyRunnable{} q := NewQueue(nil) job1 := NewJob[DummyResult](JobID("1"), runner) job1.AddDependency(JobID("1")) err := q.Enqueue(job1) if err == nil || err != ErrCycleDetected { t.Fatalf("Expected ErrCycleDetected, got %v", err) } } // Continue with other test cases...