/ components / ingress / pkg / renewintent / redis_bench_test.go
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  }