package pdu import ( "sync" "testing" "time" ) func TestRetrieveBufferOfRequestedSize(t *testing.T) { bpm := NewBufferPoolManager() size := 1024 buffer := bpm.Get(uint(size)) if buffer == nil { t.Fatalf("Expected buffer, got nil") } if len(*buffer) != size { t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) } } func TestRequestBufferSizeZero(t *testing.T) { bpm := NewBufferPoolManager() size := 0 buffer := bpm.Get(uint(size)) if buffer == nil { t.Fatalf("Expected buffer, got nil") } if len(*buffer) != size { t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) } } func TestConcurrentAccessToBufferPool(t *testing.T) { bpm := NewBufferPoolManager() size := 1024 var wg sync.WaitGroup numRoutines := 100 for i := 0; i < numRoutines; i++ { wg.Add(1) go func() { defer wg.Done() buffer := bpm.Get(uint(size)) if buffer == nil { t.Errorf("Expected buffer, got nil") } if len(*buffer) != size { t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) } }() } wg.Wait() } func TestGetBufferLockUnlock(t *testing.T) { bpm := NewBufferPoolManager() size := 1024 buffer := bpm.Get(uint(size)) if buffer == nil { t.Fatalf("Expected buffer, got nil") } if len(*buffer) != size { t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) } } func TestVerifyPoolCreationForNewSizes(t *testing.T) { bpm := NewBufferPoolManager() size := 512 buffer := bpm.Get(uint(size)) if buffer == nil { t.Fatalf("Expected buffer, got nil") } if len(*buffer) != size { t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) } } func TestBufferPoolManagerGetBuffer(t *testing.T) { bpm := NewBufferPoolManager() size := 1024 buffer := bpm.Get(uint(size)) if buffer == nil { t.Fatalf("Expected buffer, got nil") } if len(*buffer) != size { t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) } } func TestGetBufferWithMultipleSizes(t *testing.T) { bpm := NewBufferPoolManager() sizes := []int{512, 1024, 2048} for _, size := range sizes { buffer := bpm.Get(uint(size)) if buffer == nil { t.Fatalf("Expected buffer for size %d, got nil", size) } if len(*buffer) != size { t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) } } } func TestGetBufferIsAlwaysZero(t *testing.T) { bpm := NewBufferPoolManager() var size uint = 1024 * 64 for i := 0; i < 1000; i++ { buffer := bpm.Get(size) if buffer == nil { t.Fatalf("Expected buffer for size %d, got nil", size) } if uint(len(*buffer)) != size { t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) } for _, b := range *buffer { if b != 0 { t.Errorf("Expected buffer to be zero, got %d", b) } } bpm.Put(buffer) } } func BenchmarkBufferPoolManager(b *testing.B) { bpm := NewBufferPoolManager() bufSize := uint(128 * 1024) // a PDU should not be larger than this... Even this is way too large b.ResetTimer() for i := 0; i < b.N; i++ { // Benchmark Get buf := bpm.Get(bufSize) // Benchmark Put bpm.Put(buf) } } func BenchmarkBufferPoolManager_Concurrent(b *testing.B) { bpm := NewBufferPoolManager() bufSize := uint(128 * 1024) // a PDU should not be larger than this... Even this is vway too large b.ResetTimer() var wg sync.WaitGroup concurrency := 1000 for i := 0; i < concurrency; i++ { wg.Add(1) go func() { defer wg.Done() for j := 0; j < b.N/concurrency; j++ { buf := bpm.Get(bufSize) bpm.Put(buf) } }() } wg.Wait() } func BenchmarkBufferPoolManager_Memory(b *testing.B) { bpm := NewBufferPoolManager() bufSize := uint(128 * 1024) // a PDU should not be larger than this... Even this is vway too large b.ResetTimer() var i uint8 buf := bpm.Get(bufSize) b.StopTimer() // Simulate some work time.Sleep(10 * time.Millisecond) for k := range *buf { (*buf)[k] = i % 255 } b.StartTimer() for i := 0; i < b.N; i++ { bpm.Put(buf) buf = bpm.Get(bufSize) } }