fetch_ml/internal/scheduler/port_allocator_test.go
Jeremie Fraeys 74e06017b5
refactor: co-locate scheduler non-hub tests with source code
Move unit tests from tests/unit/scheduler/ to internal/scheduler/ following Go conventions:
- capability_routing_test.go - Worker capability-based job routing tests
- failure_scenarios_test.go - Scheduler failure handling and recovery tests
- heartbeat_test.go - Worker heartbeat monitoring tests
- plugin_quota_test.go - Plugin resource quota enforcement tests
- port_allocator_test.go - Dynamic port allocation for services tests
- priority_queue_test.go - Job priority queue implementation tests
- service_templates_test.go - Service template management tests
- state_store_test.go - Scheduler state persistence tests

Note: orphan_recovery_test.go excluded from this commit - will be handled with hub refactoring due to significant test changes.
2026-03-12 16:36:29 -04:00

91 lines
2.2 KiB
Go

package scheduler_test
import (
"testing"
"github.com/jfraeys/fetch_ml/internal/scheduler"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPortAllocator_BasicAllocation(t *testing.T) {
pa := scheduler.NewPortAllocator(10000, 10010)
// Allocate first port
port1, err := pa.Allocate("service-1")
require.NoError(t, err)
assert.Equal(t, 10000, port1)
// Allocate second port
port2, err := pa.Allocate("service-2")
require.NoError(t, err)
assert.Equal(t, 10001, port2)
}
func TestPortAllocator_Exhaustion(t *testing.T) {
pa := scheduler.NewPortAllocator(10000, 10002) // Only 3 ports available
// Allocate all ports
port1, _ := pa.Allocate("service-1")
assert.Equal(t, 10000, port1)
port2, _ := pa.Allocate("service-2")
assert.Equal(t, 10001, port2)
port3, _ := pa.Allocate("service-3")
assert.Equal(t, 10002, port3)
// Should fail - no ports left
_, err := pa.Allocate("service-4")
assert.Error(t, err)
}
func TestPortAllocator_Release(t *testing.T) {
pa := scheduler.NewPortAllocator(10000, 10005)
// Allocate and release
port, _ := pa.Allocate("service-1")
assert.Equal(t, 10000, port)
pa.Release(port)
// Should be able to allocate again
port2, err := pa.Allocate("service-2")
require.NoError(t, err)
assert.Equal(t, 10000, port2) // Reuses released port
}
func TestPortAllocator_DuplicateServiceID(t *testing.T) {
pa := scheduler.NewPortAllocator(10000, 10010)
// Allocate for service
port1, err := pa.Allocate("service-1")
require.NoError(t, err)
// Allocate again with same service ID - gets new port (current behavior)
port2, err := pa.Allocate("service-1")
require.NoError(t, err)
assert.NotEqual(t, port1, port2) // Each call returns new port
}
func TestPortAllocator_ConcurrentAccess(t *testing.T) {
pa := scheduler.NewPortAllocator(10000, 10100) // 101 ports
done := make(chan bool, 10)
// Concurrent allocations
for i := 0; i < 10; i++ {
go func(id int) {
for j := 0; j < 10; j++ {
pa.Allocate("service-")
}
done <- true
}(i)
}
for i := 0; i < 10; i++ {
<-done
}
// All 100 ports should be allocated
// (10 goroutines * 10 allocations, but only 100 unique service IDs)
}