package pdu import ( "sync" "testing" "time" ) func TestRetrieveBufferOfRequestedSize(t *testing.T) { bpm := NewBufferPoolManager() size := 1024 buffer := bpm.Get(size) if buffer == nil { t.Fatalf("Expected buffer, got nil") } if buffer.Cap() != size { t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap()) } } func TestRequestBufferSizeZero(t *testing.T) { bpm := NewBufferPoolManager() size := 0 buffer := bpm.Get(size) if buffer == nil { t.Fatalf("Expected buffer, got nil") } if buffer.Cap() != size { t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap()) } } 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(size) if buffer == nil { t.Errorf("Expected buffer, got nil") } if buffer.Cap() != size { t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap()) } }() } wg.Wait() } func TestGetBufferLockUnlock(t *testing.T) { bpm := NewBufferPoolManager() size := 1024 buffer := bpm.Get(size) if buffer == nil { t.Fatalf("Expected buffer, got nil") } if buffer.Cap() != size { t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap()) } } func TestVerifyPoolCreationForNewSizes(t *testing.T) { bpm := NewBufferPoolManager() size := 512 buffer := bpm.Get(size) if buffer == nil { t.Fatalf("Expected buffer, got nil") } if buffer.Cap() != size { t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap()) } } func TestBufferPoolManagerGetBuffer(t *testing.T) { bpm := NewBufferPoolManager() size := 1024 buffer := bpm.Get(size) if buffer == nil { t.Fatalf("Expected buffer, got nil") } if buffer.Cap() != size { t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap()) } } func TestGetBufferWithMultipleSizes(t *testing.T) { bpm := NewBufferPoolManager() sizes := []int{512, 1024, 2048} for _, size := range sizes { buffer := bpm.Get(size) if buffer == nil { t.Fatalf("Expected buffer for size %d, got nil", size) } if buffer.Cap() != size { t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap()) } } } func TestGetBufferIsAlwaysZero(t *testing.T) { bpm := NewBufferPoolManager() size := 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 buffer.Cap() != size { t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap()) } for _, b := range buffer.Bytes() { if b != 0 { t.Errorf("Expected buffer to be zero, got %d", b) } } bpm.Put(buffer) } } func TestPoolReusesBuffers(t *testing.T) { bpm := NewBufferPoolManager() size := 1024 buffer := bpm.Get(size) initialPtr := buffer bpm.Put(buffer) for i := 0; i < 1000; i++ { buffer = bpm.Get(size) if buffer != initialPtr { t.Errorf("Expected initial buffer (%p) to be reused, got %p", initialPtr, buffer) } bpm.Put(buffer) } } // region benchmark func BenchmarkBufferPoolManager(b *testing.B) { bpm := NewBufferPoolManager() bufSize := 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 := 128 * 1024 // a PDU should not be larger than this... Even this is way 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 := 128 * 1024 // a PDU should not be larger than this... Even this is way too large b.ResetTimer() var i byte buf := bpm.Get(bufSize) b.StopTimer() // Simulate some work time.Sleep(10 * time.Millisecond) for range buf.Bytes() { buf.WriteByte(i % 255) } b.StartTimer() for i := 0; i < b.N; i++ { bpm.Put(buf) buf = bpm.Get(bufSize) } }