Skip to content

Commit dcdfcc4

Browse files
committed
Add more test cases
Signed-off-by: Hiroshi Hatake <[email protected]>
1 parent 903027a commit dcdfcc4

File tree

2 files changed

+206
-0
lines changed

2 files changed

+206
-0
lines changed

config_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"os"
45
"testing"
56
"time"
67

@@ -129,6 +130,63 @@ func Test_loadConfig_ModeServer(t *testing.T) {
129130
})
130131
}
131132

133+
func Test_loadConfig_InvalidValues(t *testing.T) {
134+
// Test for a bad duration value
135+
t.Run("server mode with invalid reload_interval logs warning and uses default", func(t *testing.T) {
136+
fbit := &plugin.Fluentbit{
137+
Logger: newTestLogger(t),
138+
Conf: mapConfigLoader{
139+
"mode": "server",
140+
"server.endpoint": "jaeger-collector:14250",
141+
"server.service_names": "service1",
142+
"server.reload_interval": "5minutes", // Invalid format
143+
},
144+
}
145+
cfg, err := loadConfig(fbit)
146+
assert.NoError(t, err)
147+
assert.Equal(t, 5*time.Minute, cfg.ServerReloadInterval)
148+
})
149+
150+
t.Run("server mode with both endpoint and strategy_file should fail", func(t *testing.T) {
151+
fbit := &plugin.Fluentbit{
152+
Logger: newTestLogger(t),
153+
Conf: mapConfigLoader{
154+
"mode": "server",
155+
"server.endpoint": "jaeger-collector:14250",
156+
"server.strategy_file": "/path/to/file.json",
157+
},
158+
}
159+
_, err := loadConfig(fbit)
160+
assert.Error(t, err)
161+
assert.Contains(t, err.Error(), "are mutually exclusive")
162+
})
163+
}
164+
165+
func Test_loadTLSConfig_FileErrors(t *testing.T) {
166+
// Test for a non-existent CA file
167+
t.Run("should fail with non-existent CA file", func(t *testing.T) {
168+
cfg := TLSSettings{CAFile: "/tmp/this-file-does-not-exist.ca"}
169+
_, err := loadTLSConfig(cfg)
170+
assert.Error(t, err)
171+
})
172+
173+
// Test for a bad key pair
174+
t.Run("should fail with invalid cert/key pair", func(t *testing.T) {
175+
// Create dummy (but invalid) files
176+
certFile, _ := os.CreateTemp("", "cert")
177+
defer os.Remove(certFile.Name())
178+
keyFile, _ := os.CreateTemp("", "key")
179+
defer os.Remove(keyFile.Name())
180+
181+
certFile.WriteString("not a cert")
182+
keyFile.WriteString("not a key")
183+
184+
cfg := TLSSettings{CertFile: certFile.Name(), KeyFile: keyFile.Name()}
185+
_, err := loadTLSConfig(cfg)
186+
assert.Error(t, err)
187+
})
188+
}
189+
132190
func Test_loadConfig_CORS(t *testing.T) {
133191
testCases := []struct {
134192
name string

jaeger_services_test.go

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,39 @@ func Test_InitServer_FileStrategy(t *testing.T) {
139139
})
140140
}
141141

142+
func Test_InitServer_FileStrategyErrors(t *testing.T) {
143+
t.Run("fails when strategy file does not exist", func(t *testing.T) {
144+
fbit := &plugin.Fluentbit{
145+
Logger: newTestLogger(t),
146+
Conf: mapConfigLoader{"mode": "server", "server.strategy_file": "/tmp/non-existent-file.json"},
147+
}
148+
plug := &jaegerRemotePlugin{}
149+
err := plug.Init(context.Background(), fbit)
150+
assert.Error(t, err)
151+
})
152+
153+
t.Run("fails when strategy file contains invalid json", func(t *testing.T) {
154+
tmpFile, err := os.CreateTemp("", "strategy-*.json")
155+
assert.NoError(t, err)
156+
defer os.Remove(tmpFile.Name())
157+
_, err = tmpFile.Write([]byte(`{ "invalid-json`))
158+
assert.NoError(t, err)
159+
tmpFile.Close()
160+
161+
fbit := &plugin.Fluentbit{
162+
Logger: newTestLogger(t),
163+
Conf: mapConfigLoader{
164+
"mode": "server",
165+
"server.strategy_file": tmpFile.Name(),
166+
},
167+
}
168+
plug := &jaegerRemotePlugin{}
169+
err = plug.Init(context.Background(), fbit)
170+
assert.Error(t, err)
171+
assert.Contains(t, err.Error(), "could not unmarshal")
172+
})
173+
}
174+
142175
func Test_InitClient(t *testing.T) {
143176
t.Run("successfully initializes in client mode", func(t *testing.T) {
144177
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
@@ -258,6 +291,105 @@ func Test_InitServer_EndToEnd(t *testing.T) {
258291
}
259292
}
260293

294+
/* Helper function to mock sampling manager client */
295+
296+
type mockSamplingClient struct {
297+
api_v2.SamplingManagerClient
298+
GetSamplingStrategyFunc func(ctx context.Context, in *api_v2.SamplingStrategyParameters, opts ...grpc.CallOption) (*api_v2.SamplingStrategyResponse, error)
299+
}
300+
301+
func (m *mockSamplingClient) GetSamplingStrategy(ctx context.Context, in *api_v2.SamplingStrategyParameters, opts ...grpc.CallOption) (*api_v2.SamplingStrategyResponse, error) {
302+
if m.GetSamplingStrategyFunc != nil {
303+
return m.GetSamplingStrategyFunc(ctx, in, opts...)
304+
}
305+
return nil, status.Error(codes.Unimplemented, "method GetSamplingStrategy not implemented")
306+
}
307+
308+
func Test_getAndCacheStrategy_Retry(t *testing.T) {
309+
t.Run("should retry on failure and eventually succeed", func(t *testing.T) {
310+
var callCount int
311+
mockSuccessStrategy := &api_v2.SamplingStrategyResponse{StrategyType: api_v2.SamplingStrategyType_PROBABILISTIC}
312+
mockErr := status.Error(codes.Unavailable, "server not ready")
313+
314+
mockClient := &mockSamplingClient{
315+
GetSamplingStrategyFunc: func(ctx context.Context, in *api_v2.SamplingStrategyParameters, opts ...grpc.CallOption) (*api_v2.SamplingStrategyResponse, error) {
316+
callCount++
317+
if callCount > 2 {
318+
return mockSuccessStrategy, nil
319+
}
320+
return nil, mockErr
321+
},
322+
}
323+
324+
plug := &jaegerRemotePlugin{
325+
log: newTestLogger(t),
326+
config: &Config{
327+
ServerRetry: &RetryConfig{
328+
InitialInterval: 10 * time.Millisecond,
329+
MaxInterval: 100 * time.Millisecond,
330+
Multiplier: 1.5,
331+
MaxRetry: 5,
332+
},
333+
},
334+
server: &serverComponent{
335+
cache: &samplingStrategyCache{
336+
strategies: make(map[string]*cacheEntry),
337+
},
338+
sampler: &remoteSampler{
339+
client: mockClient,
340+
},
341+
},
342+
}
343+
344+
strategy, err := plug.getAndCacheStrategy(context.Background(), "test-service")
345+
346+
assert.NoError(t, err)
347+
assert.NotZero(t, strategy)
348+
assert.Equal(t, mockSuccessStrategy, strategy)
349+
assert.Equal(t, 3, callCount, "Expected the client to be called 3 times (2 failures, 1 success)")
350+
})
351+
352+
t.Run("should stop retrying if context is cancelled", func(t *testing.T) {
353+
mockErr := status.Error(codes.Unavailable, "server not ready")
354+
mockClient := &mockSamplingClient{
355+
GetSamplingStrategyFunc: func(ctx context.Context, in *api_v2.SamplingStrategyParameters, opts ...grpc.CallOption) (*api_v2.SamplingStrategyResponse, error) {
356+
return nil, mockErr
357+
},
358+
}
359+
360+
plug := &jaegerRemotePlugin{
361+
log: newTestLogger(t),
362+
config: &Config{
363+
ServerRetry: &RetryConfig{
364+
InitialInterval: 50 * time.Millisecond,
365+
MaxInterval: 200 * time.Millisecond,
366+
Multiplier: 1.5,
367+
MaxRetry: 10,
368+
},
369+
},
370+
server: &serverComponent{
371+
cache: &samplingStrategyCache{
372+
strategies: make(map[string]*cacheEntry),
373+
},
374+
sampler: &remoteSampler{
375+
client: mockClient,
376+
},
377+
},
378+
}
379+
380+
ctx, cancel := context.WithCancel(context.Background())
381+
382+
go func() {
383+
time.Sleep(20 * time.Millisecond)
384+
cancel()
385+
}()
386+
387+
_, err := plug.getAndCacheStrategy(ctx, "test-service")
388+
389+
assert.Error(t, err)
390+
})
391+
}
392+
261393
func Test_InitServer_Failure(t *testing.T) {
262394
t.Run("fails if both http and grpc listen addresses are missing", func(t *testing.T) {
263395
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
@@ -440,6 +572,22 @@ func Test_ServerHandlers(t *testing.T) {
440572

441573
assert.Equal(t, http.StatusNotFound, rr.Code)
442574
})
575+
576+
t.Run("HTTP handler returns 400 Bad Request for missing service", func(t *testing.T) {
577+
req := httptest.NewRequest(http.MethodGet, "/sampling", nil) // No service param
578+
rr := httptest.NewRecorder()
579+
plug.handleSampling(rr, req)
580+
assert.Equal(t, http.StatusBadRequest, rr.Code)
581+
})
582+
583+
t.Run("gRPC handler returns InvalidArgument for missing service name", func(t *testing.T) {
584+
s := &grpcApiServer{plug: plug}
585+
params := &api_v2.SamplingStrategyParameters{ServiceName: ""} // Empty service name
586+
_, err := s.GetSamplingStrategy(context.Background(), params)
587+
st, ok := status.FromError(err)
588+
assert.True(t, ok)
589+
assert.Equal(t, codes.InvalidArgument, st.Code())
590+
})
443591
}
444592

445593
func getFreePort(t *testing.T) string {

0 commit comments

Comments
 (0)