redis_bench_test.go
1 // Copyright 2026 Alibaba Group Holding Ltd. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package renewintent 16 17 import ( 18 "context" 19 "fmt" 20 "testing" 21 22 "github.com/alibaba/opensandbox/internal/logger" 23 "github.com/alicebob/miniredis/v2" 24 "github.com/redis/go-redis/v9" 25 ) 26 27 type nopLogger struct{} 28 29 func (nopLogger) Debugf(string, ...any) {} 30 func (nopLogger) Infof(string, ...any) {} 31 func (nopLogger) Warnf(string, ...any) {} 32 func (nopLogger) Errorf(string, ...any) {} 33 func (n nopLogger) With(...logger.Field) logger.Logger { return n } 34 func (n nopLogger) Named(string) logger.Logger { return n } 35 func (nopLogger) Sync() error { return nil } 36 37 // Benchmarks use miniredis (in-memory Redis) so timing excludes real network I/O. 38 39 func BenchmarkRedisPublisher_PublishIntent(b *testing.B) { 40 mr, err := miniredis.Run() 41 if err != nil { 42 b.Fatal(err) 43 } 44 defer mr.Close() 45 46 client := redis.NewClient(&redis.Options{Addr: mr.Addr()}) 47 defer client.Close() 48 49 ctx, cancel := context.WithCancel(context.Background()) 50 defer cancel() 51 52 cfg := RedisPublisherConfig{ 53 QueueKey: "opensandbox:renew:intent", 54 QueueMaxLen: 0, 55 MinInterval: 0, 56 Logger: nopLogger{}, 57 } 58 p := NewRedisPublisher(ctx, client, cfg) 59 60 sandboxID := "bench-sandbox" 61 port := 8080 62 requestURI := "/api/health" 63 64 b.ResetTimer() 65 for i := 0; i < b.N; i++ { 66 p.PublishIntent(sandboxID, port, requestURI) 67 } 68 } 69 70 func BenchmarkRedisPublisher_PublishIntent_Throttled(b *testing.B) { 71 mr, err := miniredis.Run() 72 if err != nil { 73 b.Fatal(err) 74 } 75 defer mr.Close() 76 77 client := redis.NewClient(&redis.Options{Addr: mr.Addr()}) 78 defer client.Close() 79 80 ctx, cancel := context.WithCancel(context.Background()) 81 defer cancel() 82 cfg := RedisPublisherConfig{ 83 QueueKey: "opensandbox:renew:intent", 84 QueueMaxLen: 0, 85 MinInterval: 1 << 30, // large so throttle skips most 86 Logger: nopLogger{}, 87 } 88 p := NewRedisPublisher(ctx, client, cfg) 89 90 sandboxID := "bench-sandbox" 91 port := 8080 92 requestURI := "/api/health" 93 94 b.ResetTimer() 95 for i := 0; i < b.N; i++ { 96 p.PublishIntent(sandboxID, port, requestURI) 97 } 98 } 99 100 func BenchmarkRedisPublisher_PublishIntent_ManySandboxes(b *testing.B) { 101 mr, err := miniredis.Run() 102 if err != nil { 103 b.Fatal(err) 104 } 105 defer mr.Close() 106 107 client := redis.NewClient(&redis.Options{Addr: mr.Addr()}) 108 defer client.Close() 109 110 ctx, cancel := context.WithCancel(context.Background()) 111 defer cancel() 112 cfg := RedisPublisherConfig{ 113 QueueKey: "opensandbox:renew:intent", 114 QueueMaxLen: 0, 115 MinInterval: 0, 116 Logger: nopLogger{}, 117 } 118 p := NewRedisPublisher(ctx, client, cfg) 119 120 port := 8080 121 requestURI := "/api/health" 122 123 b.ResetTimer() 124 for i := 0; i < b.N; i++ { 125 sandboxID := fmt.Sprintf("sandbox-%d", i%1000) 126 p.PublishIntent(sandboxID, port, requestURI) 127 } 128 }