Skip to content
Snippets Groups Projects
Select Git revision
  • f98f5b2d74da68c1daf2ba9da202609ac30ce68c
  • master default protected
  • 1.31
  • 4.24.3
  • 4.24.2
  • 4.24.1
  • 4.24.0
  • 4.23.6
  • 4.23.5
  • 4.23.4
  • 4.23.3
  • 4.23.2
  • 4.23.1
  • 4.23.0
  • 4.22.3
  • 4.22.2
  • 4.22.1
  • 4.22.0
  • 4.21.0
  • 4.20.1
  • 4.20.0
  • 4.19.0
  • 4.18.0
23 results

Monster.DOM.Resource.html

Blame
  • queue_test.go 9.40 KiB
    package jobqueue
    
    import (
    	"errors"
    	"fmt"
    	"math/rand"
    	"testing"
    	"time"
    )
    
    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)
    	}
    }
    
    func TestEnqueueDequeue(t *testing.T) {
    	q := NewQueue(nil)
    	job1 := NewJob[DummyResult]("job1", nil)
    	job2 := NewJob[DummyResult]("job2", nil)
    	job3 := NewJob[DummyResult]("job3", nil)
    
    	job2.dependencies = []JobID{"job1"}
    	job3.dependencies = []JobID{"job2"}
    
    	// Enqueue a job with dependencies that haven't been enqueued yet
    	if err := q.Enqueue(job3); err != nil {
    		t.Fatalf("Failed to enqueue job3: %v", err)
    	}
    
    	// Try to dequeue from an empty readyQueue
    	if _, err := q.Dequeue(); !errors.Is(err, ErrQueueEmpty) {
    		t.Fatalf("Expected ErrQueueEmpty, got: %v", err)
    	}
    
    	// Enqueue a job with no dependencies
    	if err := q.Enqueue(job1); err != nil {
    		t.Fatalf("Failed to enqueue job1: %v", err)
    	}
    
    	// Enqueue a job that has its dependencies met
    	if err := q.Enqueue(job2); err != nil {
    		t.Fatalf("Failed to enqueue job2: %v", err)
    	}
    
    	// Try to dequeue jobs in the expected order
    	if job, err := q.Dequeue(); err != nil || job.GetID() != "job1" {
    		t.Fatalf("Expected job1, got: %v, %v", job, err)
    	}
    
    	if job, err := q.Dequeue(); err != nil || job.GetID() != "job2" {
    		t.Fatalf("Expected job2, got: %v, %v", job, err)
    	}
    
    	if job, err := q.Dequeue(); err != nil || job.GetID() != "job3" {
    		t.Fatalf("Expected job3, got: %v, %v", job, err)
    	}
    }
    
    func TestDuplicateEnqueue(t *testing.T) {
    	q := NewQueue(nil)
    	job1 := NewJob[DummyResult]("job1", nil)
    
    	// Enqueue the same job twice
    	if err := q.Enqueue(job1); err != nil {
    		t.Fatalf("Failed to enqueue job1: %v", err)
    	}
    	if err := q.Enqueue(job1); !errors.Is(err, ErrJobAlreadyExists) {
    		t.Fatalf("Expected ErrJobAlreadyExists, got: %v", err)
    	}
    }
    
    func TestCircularDependency(t *testing.T) {
    	q := NewQueue(nil)
    
    	job1 := NewJob[DummyResult]("job1", nil)
    	job2 := NewJob[DummyResult]("job2", nil)
    
    	job1.dependencies = []JobID{"job2"}
    	job2.dependencies = []JobID{"job1"}
    
    	if err := q.Enqueue(job1); err != nil {
    		t.Fatalf("Failed to enqueue job1: %v", err)
    	}
    	// This enqueue should fail if you have logic to detect circular dependencies
    	if err := q.Enqueue(job2); err == nil {
    		t.Fatalf("Expected an error due to circular dependency, got: %v", err)
    	}
    }
    
    // TestFuzzyEnqueueDequeue tests the queue by generating random jobs and
    // you can run it with:
    // go test -v -fuzz TestFuzzyEnqueueDequeue
    // or with a fuzztime of 10 seconds:
    // go test -v -run -fuzz TestFuzzyEnqueueDequeue -fuzztime=10s
    func TestFuzzyEnqueueDequeue(t *testing.T) {
    	rand.Seed(time.Now().UnixNano())
    	q := NewQueue(nil)
    
    	// Generate random jobs
    	jobCount := 1000
    	jobs := make([]GenericJob, jobCount)
    	for i := 0; i < jobCount; i++ {
    		jobID := JobID(fmt.Sprintf("job%d", i))
    		jobs[i] = NewJob[DummyResult](jobID, nil)
    	}
    
    	// Randomly set dependencies for each job
    	for _, job := range jobs {
    		depCount := rand.Intn(5) // up to 5 dependencies
    		deps := make([]JobID, depCount)
    		for i := 0; i < depCount; i++ {
    			depIndex := rand.Intn(jobCount)
    			deps[i] = jobs[depIndex].GetID()
    		}
    		job.(*Job[DummyResult]).dependencies = deps
    	}
    
    	// Randomly enqueue jobs
    	for i := 0; i < jobCount; i++ {
    		index := rand.Intn(len(jobs))
    		job := jobs[index]
    		q.Enqueue(job)
    		jobs = append(jobs[:index], jobs[index+1:]...)
    	}
    
    	// Randomly dequeue jobs, ignoring errors for this fuzzy test
    	for i := 0; i < jobCount; i++ {
    		_, _ = q.Dequeue()
    	}
    
    	// Verify that the queue is empty
    	if _, err := q.Dequeue(); !errors.Is(err, ErrQueueEmpty) {
    		t.Fatalf("Expected ErrQueueEmpty, got: %v", err)
    	}
    }
    
    func TestEnqueueDequeueOrder(t *testing.T) {
    	eventBus := NewEventBus() // Ihre EventBus-Initialisierung
    	q := NewQueue(eventBus)
    
    	job1 := NewJob[DummyResult]("job1", nil)
    	job2 := NewJob[DummyResult]("job2", nil)
    	job3 := NewJob[DummyResult]("job3", nil)
    
    	job2.AddDependency(JobID("job1"))
    	job3.AddDependency(JobID("job2"))
    
    	if err := q.Enqueue(job1); err != nil {
    		t.Fatalf("Failed to enqueue job1: %s", err)
    	}
    
    	if err := q.Enqueue(job3); err != nil {
    		t.Fatalf("Failed to enqueue job3: %s", err)
    	}
    
    	if err := q.Enqueue(job2); err != nil {
    		t.Fatalf("Failed to enqueue job2: %s", err)
    	}
    
    	dequeuedJob, err := q.Dequeue()
    	if err != nil {
    		t.Fatalf("Failed to dequeue: %s", err)
    	}
    
    	if dequeuedJob.GetID() != "job1" {
    		t.Errorf("Expected job1, got %s", dequeuedJob.GetID())
    	}
    
    	dequeuedJob, err = q.Dequeue()
    	if err != nil {
    		t.Fatalf("Failed to dequeue: %s", err)
    	}
    
    	if dequeuedJob.GetID() != "job2" {
    		t.Errorf("Expected job2, got %s", dequeuedJob.GetID())
    	}
    
    	dequeuedJob, err = q.Dequeue()
    	if err != nil {
    		t.Fatalf("Failed to dequeue: %s", err)
    	}
    
    	if dequeuedJob.GetID() != "job3" {
    		t.Errorf("Expected job3, got %s", dequeuedJob.GetID())
    	}
    }