Skip to main content
Glama
orneryd

M.I.M.I.R - Multi-agent Intelligent Memory & Insight Repository

by orneryd
pool_test.go10.8 kB
package pool import ( "sync" "testing" ) // ============================================================================= // Configuration Tests // ============================================================================= func TestConfigure(t *testing.T) { // Save original config origConfig := globalConfig defer func() { Configure(origConfig) }() t.Run("enable pooling", func(t *testing.T) { Configure(PoolConfig{Enabled: true, MaxSize: 500}) if !IsEnabled() { t.Error("IsEnabled() = false, want true") } if globalConfig.MaxSize != 500 { t.Errorf("MaxSize = %d, want 500", globalConfig.MaxSize) } }) t.Run("disable pooling", func(t *testing.T) { Configure(PoolConfig{Enabled: false, MaxSize: 1000}) if IsEnabled() { t.Error("IsEnabled() = true, want false") } }) } // ============================================================================= // Row Slice Pool Tests // ============================================================================= func TestRowSlicePool(t *testing.T) { Configure(PoolConfig{Enabled: true, MaxSize: 1000}) t.Run("get returns empty slice", func(t *testing.T) { rows := GetRowSlice() if len(rows) != 0 { t.Errorf("len = %d, want 0", len(rows)) } if cap(rows) == 0 { t.Error("cap should be > 0 (pre-allocated)") } PutRowSlice(rows) }) t.Run("put and reuse", func(t *testing.T) { rows := GetRowSlice() rows = append(rows, []interface{}{"test", 123}) PutRowSlice(rows) // Get again - should be cleared rows2 := GetRowSlice() if len(rows2) != 0 { t.Errorf("reused slice len = %d, want 0", len(rows2)) } PutRowSlice(rows2) }) t.Run("oversized slices not pooled", func(t *testing.T) { Configure(PoolConfig{Enabled: true, MaxSize: 10}) // Create oversized slice rows := make([][]interface{}, 0, 100) PutRowSlice(rows) // Should not panic, just not pool it Configure(PoolConfig{Enabled: true, MaxSize: 1000}) }) t.Run("disabled pooling creates new slices", func(t *testing.T) { Configure(PoolConfig{Enabled: false, MaxSize: 1000}) defer Configure(PoolConfig{Enabled: true, MaxSize: 1000}) rows := GetRowSlice() if rows == nil { t.Error("GetRowSlice returned nil when pooling disabled") } PutRowSlice(rows) // Should not panic }) } // ============================================================================= // Node Slice Pool Tests // ============================================================================= func TestNodeSlicePool(t *testing.T) { Configure(PoolConfig{Enabled: true, MaxSize: 1000}) t.Run("get returns empty slice", func(t *testing.T) { nodes := GetNodeSlice() if len(nodes) != 0 { t.Errorf("len = %d, want 0", len(nodes)) } PutNodeSlice(nodes) }) t.Run("put clears references", func(t *testing.T) { nodes := GetNodeSlice() nodes = append(nodes, &PooledNode{ID: "test"}) PutNodeSlice(nodes) // Slice should be cleared nodes2 := GetNodeSlice() if len(nodes2) != 0 { t.Errorf("reused slice len = %d, want 0", len(nodes2)) } PutNodeSlice(nodes2) }) } // ============================================================================= // String Builder Pool Tests // ============================================================================= func TestStringBuilderPool(t *testing.T) { Configure(PoolConfig{Enabled: true, MaxSize: 1000}) t.Run("basic operations", func(t *testing.T) { b := GetStringBuilder() if b.Len() != 0 { t.Errorf("Len() = %d, want 0", b.Len()) } b.WriteString("hello") b.WriteByte(' ') b.WriteString("world") if b.String() != "hello world" { t.Errorf("String() = %q, want %q", b.String(), "hello world") } if b.Len() != 11 { t.Errorf("Len() = %d, want 11", b.Len()) } PutStringBuilder(b) }) t.Run("reset on reuse", func(t *testing.T) { b := GetStringBuilder() b.WriteString("test") PutStringBuilder(b) b2 := GetStringBuilder() if b2.Len() != 0 { t.Errorf("reused builder Len() = %d, want 0", b2.Len()) } PutStringBuilder(b2) }) t.Run("nil put does not panic", func(t *testing.T) { PutStringBuilder(nil) // Should not panic }) t.Run("oversized buffer not pooled", func(t *testing.T) { b := GetStringBuilder() // Write > 64KB to exceed pool limit for i := 0; i < 70000; i++ { b.WriteByte('x') } PutStringBuilder(b) // Should not panic, just not pool it }) } // ============================================================================= // Byte Buffer Pool Tests // ============================================================================= func TestByteBufferPool(t *testing.T) { Configure(PoolConfig{Enabled: true, MaxSize: 1000}) t.Run("get returns empty buffer", func(t *testing.T) { buf := GetByteBuffer() if len(buf) != 0 { t.Errorf("len = %d, want 0", len(buf)) } if cap(buf) == 0 { t.Error("cap should be > 0") } PutByteBuffer(buf) }) t.Run("reuse", func(t *testing.T) { buf := GetByteBuffer() buf = append(buf, []byte("test data")...) PutByteBuffer(buf) buf2 := GetByteBuffer() if len(buf2) != 0 { t.Errorf("reused buffer len = %d, want 0", len(buf2)) } PutByteBuffer(buf2) }) } // ============================================================================= // Map Pool Tests // ============================================================================= func TestMapPool(t *testing.T) { Configure(PoolConfig{Enabled: true, MaxSize: 1000}) t.Run("get returns empty map", func(t *testing.T) { m := GetMap() if len(m) != 0 { t.Errorf("len = %d, want 0", len(m)) } PutMap(m) }) t.Run("map is cleared on put", func(t *testing.T) { m := GetMap() m["key1"] = "value1" m["key2"] = 123 PutMap(m) m2 := GetMap() if len(m2) != 0 { t.Errorf("reused map len = %d, want 0", len(m2)) } PutMap(m2) }) t.Run("nil put does not panic", func(t *testing.T) { PutMap(nil) // Should not panic }) t.Run("oversized map not pooled", func(t *testing.T) { Configure(PoolConfig{Enabled: true, MaxSize: 10}) defer Configure(PoolConfig{Enabled: true, MaxSize: 1000}) m := GetMap() for i := 0; i < 20; i++ { m[string(rune('a'+i))] = i } PutMap(m) // Should not panic, just not pool it }) } // ============================================================================= // String Slice Pool Tests // ============================================================================= func TestStringSlicePool(t *testing.T) { Configure(PoolConfig{Enabled: true, MaxSize: 1000}) t.Run("get returns empty slice", func(t *testing.T) { s := GetStringSlice() if len(s) != 0 { t.Errorf("len = %d, want 0", len(s)) } PutStringSlice(s) }) t.Run("reuse", func(t *testing.T) { s := GetStringSlice() s = append(s, "hello", "world") PutStringSlice(s) s2 := GetStringSlice() if len(s2) != 0 { t.Errorf("reused slice len = %d, want 0", len(s2)) } PutStringSlice(s2) }) } // ============================================================================= // Interface Slice Pool Tests // ============================================================================= func TestInterfaceSlicePool(t *testing.T) { Configure(PoolConfig{Enabled: true, MaxSize: 1000}) t.Run("get returns empty slice", func(t *testing.T) { s := GetInterfaceSlice() if len(s) != 0 { t.Errorf("len = %d, want 0", len(s)) } PutInterfaceSlice(s) }) t.Run("references cleared on put", func(t *testing.T) { s := GetInterfaceSlice() obj := make(map[string]int) s = append(s, obj, "test", 123) PutInterfaceSlice(s) s2 := GetInterfaceSlice() if len(s2) != 0 { t.Errorf("reused slice len = %d, want 0", len(s2)) } PutInterfaceSlice(s2) }) t.Run("nil put does not panic", func(t *testing.T) { PutInterfaceSlice(nil) // Should not panic }) } // ============================================================================= // Concurrent Access Tests // ============================================================================= func TestConcurrentPoolAccess(t *testing.T) { Configure(PoolConfig{Enabled: true, MaxSize: 1000}) const goroutines = 100 const iterations = 100 t.Run("row slice pool concurrent", func(t *testing.T) { var wg sync.WaitGroup wg.Add(goroutines) for i := 0; i < goroutines; i++ { go func() { defer wg.Done() for j := 0; j < iterations; j++ { rows := GetRowSlice() rows = append(rows, []interface{}{j}) PutRowSlice(rows) } }() } wg.Wait() }) t.Run("map pool concurrent", func(t *testing.T) { var wg sync.WaitGroup wg.Add(goroutines) for i := 0; i < goroutines; i++ { go func(id int) { defer wg.Done() for j := 0; j < iterations; j++ { m := GetMap() m["id"] = id m["iter"] = j PutMap(m) } }(i) } wg.Wait() }) t.Run("string builder pool concurrent", func(t *testing.T) { var wg sync.WaitGroup wg.Add(goroutines) for i := 0; i < goroutines; i++ { go func() { defer wg.Done() for j := 0; j < iterations; j++ { b := GetStringBuilder() b.WriteString("test") _ = b.String() PutStringBuilder(b) } }() } wg.Wait() }) } // ============================================================================= // Benchmarks // ============================================================================= func BenchmarkRowSlicePool(b *testing.B) { Configure(PoolConfig{Enabled: true, MaxSize: 1000}) b.Run("pooled", func(b *testing.B) { for i := 0; i < b.N; i++ { rows := GetRowSlice() rows = append(rows, []interface{}{1, "test"}) PutRowSlice(rows) } }) b.Run("unpooled", func(b *testing.B) { for i := 0; i < b.N; i++ { rows := make([][]interface{}, 0, 64) rows = append(rows, []interface{}{1, "test"}) _ = rows } }) } func BenchmarkMapPool(b *testing.B) { Configure(PoolConfig{Enabled: true, MaxSize: 1000}) b.Run("pooled", func(b *testing.B) { for i := 0; i < b.N; i++ { m := GetMap() m["key"] = "value" PutMap(m) } }) b.Run("unpooled", func(b *testing.B) { for i := 0; i < b.N; i++ { m := make(map[string]interface{}, 8) m["key"] = "value" _ = m } }) } func BenchmarkStringBuilderPool(b *testing.B) { Configure(PoolConfig{Enabled: true, MaxSize: 1000}) b.Run("pooled", func(b *testing.B) { for i := 0; i < b.N; i++ { sb := GetStringBuilder() sb.WriteString("hello world") _ = sb.String() PutStringBuilder(sb) } }) b.Run("unpooled", func(b *testing.B) { for i := 0; i < b.N; i++ { buf := make([]byte, 0, 256) buf = append(buf, "hello world"...) _ = string(buf) } }) } func BenchmarkConcurrentPoolAccess(b *testing.B) { Configure(PoolConfig{Enabled: true, MaxSize: 1000}) b.RunParallel(func(pb *testing.PB) { for pb.Next() { m := GetMap() m["key"] = "value" PutMap(m) } }) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/orneryd/Mimir'

If you have feedback or need assistance with the MCP directory API, please join our Discord server