1
+ // Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0
2
+
1
3
package integTest
2
4
3
5
import (
@@ -18,22 +20,21 @@ import (
18
20
)
19
21
20
22
const (
21
- //otelSpanFile = "/tmp/spans.json"
22
23
otelSpanFlushIntervalMs = 100
23
24
otelSpanTimeoutMs = 50000
24
25
validEndpointTraces = "/tmp/spans.json"
25
26
validFileEndpointTraces = "file://" + validEndpointTraces
26
27
validEndpointMetrics = "https://valid-endpoint/v1/metrics"
27
28
)
28
29
29
- type OpenTelemetryIntegrationSuite struct {
30
+ type OpenTelemetryTestSuite struct {
30
31
GlideTestSuite
31
32
}
32
33
33
34
// OpenTelemetry standalone tests
34
35
35
36
// SetupSuite runs once before all tests
36
- func (suite * OpenTelemetryIntegrationSuite ) SetupSuite () {
37
+ func (suite * OpenTelemetryTestSuite ) SetupSuite () {
37
38
// One-time setup for all tests
38
39
suite .GlideTestSuite .SetupSuite ()
39
40
WrongOpenTelemetryConfig (suite )
@@ -53,12 +54,12 @@ func (suite *OpenTelemetryIntegrationSuite) SetupSuite() {
53
54
}
54
55
55
56
// TearDownSuite runs once after all tests
56
- func (suite * OpenTelemetryIntegrationSuite ) TearDownSuite () {
57
+ func (suite * OpenTelemetryTestSuite ) TearDownSuite () {
57
58
// One-time cleanup for all tests
58
59
suite .GlideTestSuite .TearDownSuite ()
59
60
}
60
61
61
- func (suite * OpenTelemetryIntegrationSuite ) TearDownTest () {
62
+ func (suite * OpenTelemetryTestSuite ) TearDownTest () {
62
63
time .Sleep (100 * time .Millisecond )
63
64
// Remove the span file if it exists
64
65
if _ , err := os .Stat (validEndpointTraces ); err == nil {
@@ -70,7 +71,7 @@ func (suite *OpenTelemetryIntegrationSuite) TearDownTest() {
70
71
suite .GlideTestSuite .TearDownTest ()
71
72
}
72
73
73
- func WrongOpenTelemetryConfig (suite * OpenTelemetryIntegrationSuite ) {
74
+ func WrongOpenTelemetryConfig (suite * OpenTelemetryTestSuite ) {
74
75
// Test wrong traces endpoint
75
76
cfg := api.OpenTelemetryConfig {
76
77
Traces : & api.OpenTelemetryTracesConfig {
@@ -185,7 +186,7 @@ func readAndParseSpanFile(path string) (SpanFileData, error) {
185
186
}, nil
186
187
}
187
188
188
- func (suite * OpenTelemetryIntegrationSuite ) TestOpenTelemetry_AutomaticSpanLifecycle () {
189
+ func (suite * OpenTelemetryTestSuite ) TestOpenTelemetry_AutomaticSpanLifecycle () {
189
190
suite .runWithSpecificClients (ClientTypeFlag (StandaloneFlag ), func (client api.BaseClient ) {
190
191
// Force garbage collection
191
192
runtime .GC ()
@@ -213,7 +214,7 @@ func (suite *OpenTelemetryIntegrationSuite) TestOpenTelemetry_AutomaticSpanLifec
213
214
})
214
215
}
215
216
216
- func (suite * OpenTelemetryIntegrationSuite ) TestOpenTelemetry_GlobalConfigNotReinitialize () {
217
+ func (suite * OpenTelemetryTestSuite ) TestOpenTelemetry_GlobalConfigNotReinitialize () {
217
218
suite .runWithSpecificClients (ClientTypeFlag (StandaloneFlag ), func (client api.BaseClient ) {
218
219
// Try to initialize OpenTelemetry with wrong endpoint
219
220
wrongConfig := api.OpenTelemetryConfig {
@@ -239,7 +240,7 @@ func (suite *OpenTelemetryIntegrationSuite) TestOpenTelemetry_GlobalConfigNotRei
239
240
})
240
241
}
241
242
242
- func (suite * OpenTelemetryIntegrationSuite ) TestOpenTelemetry_ConcurrentCommandsSpanLifecycle () {
243
+ func (suite * OpenTelemetryTestSuite ) TestOpenTelemetry_ConcurrentCommandsSpanLifecycle () {
243
244
suite .runWithSpecificClients (ClientTypeFlag (StandaloneFlag ), func (client api.BaseClient ) {
244
245
// Force garbage collection
245
246
runtime .GC ()
@@ -298,6 +299,152 @@ func (suite *OpenTelemetryIntegrationSuite) TestOpenTelemetry_ConcurrentCommands
298
299
})
299
300
}
300
301
301
- func TestOpenTelemetryIntegrationSuite (t * testing.T ) {
302
- suite .Run (t , new (OpenTelemetryIntegrationSuite ))
302
+ // cluster tests
303
+ func (suite * OpenTelemetryTestSuite ) TestOpenTelemetry_ClusterClientMemoryLeak () {
304
+ suite .runWithSpecificClients (ClientTypeFlag (ClusterFlag ), func (client api.BaseClient ) {
305
+ // Force garbage collection
306
+ runtime .GC ()
307
+
308
+ // Get initial memory stats
309
+ var startMem runtime.MemStats
310
+ runtime .ReadMemStats (& startMem )
311
+
312
+ // Execute multiple commands sequentially
313
+ for i := 0 ; i < 100 ; i ++ {
314
+ key := fmt .Sprintf ("test_key_%d" , i )
315
+ _ , err := client .Set (context .Background (), key , fmt .Sprintf ("value_%d" , i ))
316
+ require .NoError (suite .T (), err )
317
+ _ , err = client .Get (context .Background (), key )
318
+ require .NoError (suite .T (), err )
319
+ }
320
+
321
+ // Force garbage collection again
322
+ runtime .GC ()
323
+
324
+ // Get final memory stats
325
+ var endMem runtime.MemStats
326
+ runtime .ReadMemStats (& endMem )
327
+
328
+ // Allow small fluctuations (10% increase)
329
+ maxAllowedMemory := float64 (startMem .HeapAlloc ) * 1.1
330
+ assert .Less (suite .T (), float64 (endMem .HeapAlloc ), maxAllowedMemory ,
331
+ "Memory usage should not increase significantly" )
332
+ })
333
+ }
334
+
335
+ func (suite * OpenTelemetryTestSuite ) TestOpenTelemetry_ClusterClientSamplingPercentage () {
336
+ suite .runWithSpecificClients (ClientTypeFlag (ClusterFlag ), func (client api.BaseClient ) {
337
+ // Set sampling percentage to 0
338
+ err := api .GetInstance ().SetSamplePercentage (0 )
339
+ require .NoError (suite .T (), err )
340
+ assert .Equal (suite .T (), int32 (0 ), api .GetInstance ().GetSamplePercentage ())
341
+
342
+ // Wait for any existing spans to be flushed
343
+ time .Sleep (500 * time .Millisecond )
344
+
345
+ // Remove any existing span file
346
+ if _ , err := os .Stat (validEndpointTraces ); err == nil {
347
+ err = os .Remove (validEndpointTraces )
348
+ require .NoError (suite .T (), err )
349
+ }
350
+
351
+ // Execute commands with 0% sampling
352
+ for i := 0 ; i < 100 ; i ++ {
353
+ _ , err := client .Set (context .Background (), "GlideClusterClient_test_percentage_requests_config" , "value" )
354
+ require .NoError (suite .T (), err )
355
+ }
356
+
357
+ // Wait for spans to be flushed
358
+ time .Sleep (500 * time .Millisecond )
359
+
360
+ // Verify no spans were exported
361
+ _ , err = os .Stat (validEndpointTraces )
362
+ assert .True (suite .T (), os .IsNotExist (err ), "Span file should not exist with 0% sampling" )
363
+
364
+ // Set sampling percentage to 100
365
+ err = api .GetInstance ().SetSamplePercentage (100 )
366
+ require .NoError (suite .T (), err )
367
+
368
+ // Execute commands with 100% sampling
369
+ for i := 0 ; i < 10 ; i ++ {
370
+ key := fmt .Sprintf ("GlideClusterClient_test_percentage_requests_config_%d" , i )
371
+ _ , err := client .Get (context .Background (), key )
372
+ require .NoError (suite .T (), err )
373
+ }
374
+
375
+ // Wait for spans to be flushed
376
+ time .Sleep (5 * time .Second )
377
+
378
+ // Read and verify spans
379
+ spans , err := readAndParseSpanFile (validEndpointTraces )
380
+ require .NoError (suite .T (), err )
381
+
382
+ // Count Get spans
383
+ getSpanCount := 0
384
+ for _ , name := range spans .SpanNames {
385
+ if name == "GET" {
386
+ getSpanCount ++
387
+ }
388
+ }
389
+
390
+ // Verify we have exactly 10 Get spans
391
+ assert .Equal (suite .T (), 10 , getSpanCount , "Should have exactly 10 Get spans" )
392
+ })
393
+ }
394
+
395
+ func (suite * OpenTelemetryTestSuite ) TestOpenTelemetry_ClusterClientGlobalConfigNotReinitialize () {
396
+ suite .runWithSpecificClients (ClientTypeFlag (ClusterFlag ), func (client api.BaseClient ) {
397
+ // Try to initialize OpenTelemetry with wrong endpoint
398
+ wrongConfig := api.OpenTelemetryConfig {
399
+ Traces : & api.OpenTelemetryTracesConfig {
400
+ Endpoint : "wrong.endpoint" ,
401
+ SamplePercentage : 1 ,
402
+ },
403
+ }
404
+
405
+ // The init should not throw error because it can only be initialized once per process
406
+ err := api .GetInstance ().Init (wrongConfig )
407
+ assert .NoError (suite .T (), err , "OpenTelemetry should not throw error on reinitialization" )
408
+
409
+ // Execute a command to verify spans are still being exported
410
+ _ , err = client .Set (context .Background (), "GlideClusterClient_test_otel_global_config" , "value" )
411
+ require .NoError (suite .T (), err )
412
+
413
+ // Wait for spans to be flushed
414
+ time .Sleep (500 * time .Millisecond )
415
+
416
+ // Read spans to verify they're still being exported to the correct endpoint
417
+ spans , err := readAndParseSpanFile (validEndpointTraces )
418
+ require .NoError (suite .T (), err )
419
+ assert .Contains (suite .T (), spans .SpanNames , "SET" , "Should find SET span in exported spans" )
420
+ })
421
+ }
422
+
423
+ func (suite * OpenTelemetryTestSuite ) TestOpenTelemetry_ClusterClientMultipleClients () {
424
+ suite .runWithSpecificClients (ClientTypeFlag (ClusterFlag ), func (client1 api.BaseClient ) {
425
+ // Create a second client with the same configuration
426
+ client2 := suite .clusterClient (suite .defaultClusterClientConfig ())
427
+ defer client2 .Close ()
428
+
429
+ // Execute commands with both clients
430
+ _ , err := client1 .Set (context .Background (), "test_key" , "value" )
431
+ require .NoError (suite .T (), err )
432
+ _ , err = client2 .Get (context .Background (), "test_key" )
433
+ require .NoError (suite .T (), err )
434
+
435
+ // Wait for spans to be flushed
436
+ time .Sleep (5 * time .Second )
437
+
438
+ // Read and verify spans
439
+ spans , err := readAndParseSpanFile (validEndpointTraces )
440
+ require .NoError (suite .T (), err )
441
+
442
+ // Verify both SET and GET spans exist
443
+ assert .Contains (suite .T (), spans .SpanNames , "SET" , "Should find SET span in exported spans" )
444
+ assert .Contains (suite .T (), spans .SpanNames , "GET" , "Should find GET span in exported spans" )
445
+ })
446
+ }
447
+
448
+ func TestOpenTelemetryTestSuite (t * testing.T ) {
449
+ suite .Run (t , new (OpenTelemetryTestSuite ))
303
450
}
0 commit comments