Skip to content

Commit 7a5f4f8

Browse files
committed
perf(rdb): reuse single shared instance across all benchmarks
1 parent 0d9f489 commit 7a5f4f8

File tree

1 file changed

+121
-69
lines changed

1 file changed

+121
-69
lines changed

internal/namespaces/rdb/v1/custom_benchmark_test.go

Lines changed: 121 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ package rdb_test
33
import (
44
"bytes"
55
"context"
6+
"fmt"
67
"os"
78
"sort"
9+
"sync"
810
"testing"
911
"time"
1012

@@ -31,6 +33,18 @@ const (
3133
instanceReadyTimeout = 3 * time.Minute
3234
)
3335

36+
var (
37+
sharedInstance *rdbSDK.Instance
38+
sharedInstanceMu sync.Mutex
39+
)
40+
41+
// TestMain ensures shared instance cleanup
42+
func TestMain(m *testing.M) {
43+
code := m.Run()
44+
cleanupSharedInstance()
45+
os.Exit(code)
46+
}
47+
3448
func setupBenchmark(b *testing.B) (*scw.Client, core.TestMetadata, func(args []string) any) {
3549
b.Helper()
3650

@@ -151,35 +165,118 @@ func (s *benchmarkStats) report(b *testing.B) {
151165
len(s.timings), minVal, median, mean, p95, maxVal)
152166
}
153167

154-
func BenchmarkInstanceGet(b *testing.B) {
155-
if os.Getenv("CLI_RUN_BENCHMARKS") != "true" {
156-
b.Skip("Skipping benchmark. Set CLI_RUN_BENCHMARKS=true to run.")
157-
}
168+
func getOrCreateSharedInstance(b *testing.B, client *scw.Client, executeCmd func([]string) any, meta core.TestMetadata) *rdbSDK.Instance {
169+
b.Helper()
158170

159-
client, meta, executeCmd := setupBenchmark(b)
171+
sharedInstanceMu.Lock()
172+
defer sharedInstanceMu.Unlock()
173+
174+
if sharedInstance != nil {
175+
b.Log("Reusing existing shared RDB instance")
176+
return sharedInstance
177+
}
160178

179+
b.Log("Creating shared RDB instance for all benchmarks...")
161180
ctx := &core.BeforeFuncCtx{
162181
Client: client,
163182
ExecuteCmd: executeCmd,
164183
Meta: meta,
165184
}
166-
err := createInstanceDirect(engine)(ctx)
167-
if err != nil {
168-
b.Fatalf("Failed to create instance: %v", err)
185+
186+
if err := createInstanceDirect(engine)(ctx); err != nil {
187+
b.Fatalf("Failed to create shared instance: %v", err)
169188
}
170189

171190
instance := meta["Instance"].(rdb.CreateInstanceResult).Instance
191+
sharedInstance = instance
172192

173-
b.Cleanup(func() {
174-
afterCtx := &core.AfterFuncCtx{
175-
Client: client,
176-
ExecuteCmd: executeCmd,
177-
Meta: meta,
193+
b.Logf("Shared RDB instance created: %s", instance.ID)
194+
195+
if err := waitForInstanceReady(executeCmd, instance.ID, instanceReadyTimeout); err != nil {
196+
b.Fatalf("Shared instance not ready: %v", err)
197+
}
198+
199+
b.Log("Shared instance is ready")
200+
return sharedInstance
201+
}
202+
203+
func cleanupSharedInstance() {
204+
sharedInstanceMu.Lock()
205+
defer sharedInstanceMu.Unlock()
206+
207+
if sharedInstance == nil {
208+
return
209+
}
210+
211+
fmt.Printf("Cleaning up shared RDB instance: %s\n", sharedInstance.ID)
212+
213+
client, err := scw.NewClient(
214+
scw.WithDefaultRegion(scw.RegionFrPar),
215+
scw.WithDefaultZone(scw.ZoneFrPar1),
216+
scw.WithEnv(),
217+
)
218+
if err != nil {
219+
fmt.Printf("Error creating client for cleanup: %v\n", err)
220+
return
221+
}
222+
223+
config, err := scw.LoadConfig()
224+
if err == nil {
225+
activeProfile, err := config.GetActiveProfile()
226+
if err == nil {
227+
envProfile := scw.LoadEnvProfile()
228+
profile := scw.MergeProfiles(activeProfile, envProfile)
229+
client, _ = scw.NewClient(
230+
scw.WithDefaultRegion(scw.RegionFrPar),
231+
scw.WithDefaultZone(scw.ZoneFrPar1),
232+
scw.WithProfile(profile),
233+
scw.WithEnv(),
234+
)
178235
}
179-
cleanupWithRetry(b, "instance", instance.ID, func() error {
180-
return deleteInstanceDirect()(afterCtx)
236+
}
237+
238+
executeCmd := func(args []string) any {
239+
_, result, _ := core.Bootstrap(&core.BootstrapConfig{
240+
Args: args,
241+
Commands: rdb.GetCommands().Copy(),
242+
BuildInfo: &core.BuildInfo{},
243+
Client: client,
244+
DisableTelemetry: true,
245+
DisableAliases: true,
246+
OverrideEnv: map[string]string{},
247+
Ctx: context.Background(),
181248
})
182-
})
249+
return result
250+
}
251+
252+
meta := core.TestMetadata{
253+
"Instance": rdb.CreateInstanceResult{Instance: sharedInstance},
254+
}
255+
256+
afterCtx := &core.AfterFuncCtx{
257+
Client: client,
258+
ExecuteCmd: executeCmd,
259+
Meta: meta,
260+
}
261+
262+
if err := deleteInstanceDirect()(afterCtx); err != nil {
263+
fmt.Printf("Error deleting shared instance: %v\n", err)
264+
time.Sleep(2 * time.Second)
265+
if err2 := deleteInstanceDirect()(afterCtx); err2 != nil {
266+
fmt.Printf("Final cleanup failure: %v\n", err2)
267+
}
268+
}
269+
270+
sharedInstance = nil
271+
}
272+
273+
func BenchmarkInstanceGet(b *testing.B) {
274+
if os.Getenv("CLI_RUN_BENCHMARKS") != "true" {
275+
b.Skip("Skipping benchmark. Set CLI_RUN_BENCHMARKS=true to run.")
276+
}
277+
278+
client, meta, executeCmd := setupBenchmark(b)
279+
instance := getOrCreateSharedInstance(b, client, executeCmd, meta)
183280

184281
stats := newBenchmarkStats()
185282
b.ResetTimer()
@@ -215,25 +312,17 @@ func BenchmarkBackupGet(b *testing.B) {
215312
}
216313

217314
client, meta, executeCmd := setupBenchmark(b)
315+
instance := getOrCreateSharedInstance(b, client, executeCmd, meta)
218316

219317
ctx := &core.BeforeFuncCtx{
220318
Client: client,
221319
ExecuteCmd: executeCmd,
222320
Meta: meta,
223321
}
224-
err := createInstanceDirect(engine)(ctx)
225-
if err != nil {
226-
b.Fatalf("Failed to create instance: %v", err)
227-
}
228322

229-
instance := meta["Instance"].(rdb.CreateInstanceResult).Instance
323+
meta["Instance"] = rdb.CreateInstanceResult{Instance: instance}
230324

231-
if err := waitForInstanceReady(executeCmd, instance.ID, instanceReadyTimeout); err != nil {
232-
b.Fatalf("Instance not ready: %v", err)
233-
}
234-
235-
err = createBackupDirect("Backup")(ctx)
236-
if err != nil {
325+
if err := createBackupDirect("Backup")(ctx); err != nil {
237326
b.Fatalf("Failed to create backup: %v", err)
238327
}
239328

@@ -248,9 +337,6 @@ func BenchmarkBackupGet(b *testing.B) {
248337
cleanupWithRetry(b, "backup", backup.ID, func() error {
249338
return deleteBackupDirect("Backup")(afterCtx)
250339
})
251-
cleanupWithRetry(b, "instance", instance.ID, func() error {
252-
return deleteInstanceDirect()(afterCtx)
253-
})
254340
})
255341

256342
stats := newBenchmarkStats()
@@ -287,29 +373,20 @@ func BenchmarkBackupList(b *testing.B) {
287373
}
288374

289375
client, meta, executeCmd := setupBenchmark(b)
376+
instance := getOrCreateSharedInstance(b, client, executeCmd, meta)
290377

291378
ctx := &core.BeforeFuncCtx{
292379
Client: client,
293380
ExecuteCmd: executeCmd,
294381
Meta: meta,
295382
}
296-
err := createInstanceDirect(engine)(ctx)
297-
if err != nil {
298-
b.Fatalf("Failed to create instance: %v", err)
299-
}
300383

301-
instance := meta["Instance"].(rdb.CreateInstanceResult).Instance
384+
meta["Instance"] = rdb.CreateInstanceResult{Instance: instance}
302385

303-
if err := waitForInstanceReady(executeCmd, instance.ID, instanceReadyTimeout); err != nil {
304-
b.Fatalf("Instance not ready: %v", err)
305-
}
306-
307-
err = createBackupDirect("Backup1")(ctx)
308-
if err != nil {
386+
if err := createBackupDirect("Backup1")(ctx); err != nil {
309387
b.Fatalf("Failed to create backup 1: %v", err)
310388
}
311-
err = createBackupDirect("Backup2")(ctx)
312-
if err != nil {
389+
if err := createBackupDirect("Backup2")(ctx); err != nil {
313390
b.Fatalf("Failed to create backup 2: %v", err)
314391
}
315392

@@ -328,9 +405,6 @@ func BenchmarkBackupList(b *testing.B) {
328405
cleanupWithRetry(b, "backup2", backup2.ID, func() error {
329406
return deleteBackupDirect("Backup2")(afterCtx)
330407
})
331-
cleanupWithRetry(b, "instance", instance.ID, func() error {
332-
return deleteInstanceDirect()(afterCtx)
333-
})
334408
})
335409

336410
stats := newBenchmarkStats()
@@ -367,29 +441,7 @@ func BenchmarkDatabaseList(b *testing.B) {
367441
}
368442

369443
client, meta, executeCmd := setupBenchmark(b)
370-
371-
ctx := &core.BeforeFuncCtx{
372-
Client: client,
373-
ExecuteCmd: executeCmd,
374-
Meta: meta,
375-
}
376-
err := createInstanceDirect(engine)(ctx)
377-
if err != nil {
378-
b.Fatalf("Failed to create instance: %v", err)
379-
}
380-
381-
instance := meta["Instance"].(rdb.CreateInstanceResult).Instance
382-
383-
b.Cleanup(func() {
384-
afterCtx := &core.AfterFuncCtx{
385-
Client: client,
386-
ExecuteCmd: executeCmd,
387-
Meta: meta,
388-
}
389-
cleanupWithRetry(b, "instance", instance.ID, func() error {
390-
return deleteInstanceDirect()(afterCtx)
391-
})
392-
})
444+
instance := getOrCreateSharedInstance(b, client, executeCmd, meta)
393445

394446
stats := newBenchmarkStats()
395447
b.ResetTimer()

0 commit comments

Comments
 (0)